mirror of
https://github.com/pret/pokemon-reverse-engineering-tools.git
synced 2026-03-21 17:24:42 -05:00
Merge pull request #103 from eevee/py3
Python 3 compatibility, sort of, maybe
This commit is contained in:
commit
979c98a7c0
|
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import print_function
|
||||
import ply.lex as lex
|
||||
import sys, os
|
||||
|
||||
|
|
@ -466,7 +467,7 @@ class Lexer(object):
|
|||
''' Prints an error msg.
|
||||
'''
|
||||
#print '%s:%i %s' % (FILENAME, self.lex.lineno, str)
|
||||
print '%s:%s %s' % (FILENAME, "?", str)
|
||||
print('%s:%s %s' % (FILENAME, "?", str))
|
||||
|
||||
|
||||
def error(self, str):
|
||||
|
|
@ -490,5 +491,5 @@ if __name__ == '__main__':
|
|||
tmp.input(open(sys.argv[1]).read())
|
||||
tok = tmp.token()
|
||||
while tok:
|
||||
print tok
|
||||
print(tok)
|
||||
tok = tmp.token()
|
||||
|
|
|
|||
|
|
@ -1,5 +1 @@
|
|||
import configuration as config
|
||||
import crystal
|
||||
import preprocessor
|
||||
|
||||
__version__ = "1.6.0"
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
# coding: utf-8
|
||||
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
|
||||
from math import ceil
|
||||
|
||||
from song_names import song_names
|
||||
from sfx_names import sfx_names
|
||||
from cry_names import cry_names
|
||||
from .song_names import song_names
|
||||
from .sfx_names import sfx_names
|
||||
from .cry_names import cry_names
|
||||
|
||||
from gbz80disasm import get_global_address, get_local_address
|
||||
from labels import line_has_label
|
||||
from crystal import music_classes as sound_classes
|
||||
from crystal import (
|
||||
from .gbz80disasm import get_global_address, get_local_address
|
||||
from .labels import line_has_label
|
||||
from .crystal import music_classes as sound_classes
|
||||
from .crystal import (
|
||||
Command,
|
||||
SingleByteParam,
|
||||
MultiByteParam,
|
||||
|
|
@ -22,7 +23,7 @@ from crystal import (
|
|||
rom = load_rom()
|
||||
rom = bytearray(rom)
|
||||
|
||||
import configuration
|
||||
from . import configuration
|
||||
conf = configuration.Config()
|
||||
|
||||
|
||||
|
|
@ -299,7 +300,7 @@ class Channel:
|
|||
self.address / 0x4000 != self.start_address / 0x4000
|
||||
) and not done:
|
||||
done = True
|
||||
raise Exception, self.label + ': reached the end of the bank without finishing!'
|
||||
raise Exception(self.label + ': reached the end of the bank without finishing!')
|
||||
|
||||
self.output += [(self.address, '; %x\n' % self.address, self.address)]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
# coding: utf-8
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
from new import classobj
|
||||
|
||||
import configuration
|
||||
from . import configuration
|
||||
conf = configuration.Config()
|
||||
|
||||
from crystal import (
|
||||
from .crystal import (
|
||||
SingleByteParam,
|
||||
PointerLabelParam,
|
||||
DecimalParam,
|
||||
|
|
@ -15,11 +17,11 @@ from crystal import (
|
|||
load_rom
|
||||
)
|
||||
|
||||
from gbz80disasm import get_local_address, get_global_address
|
||||
from audio import sort_asms
|
||||
from .gbz80disasm import get_local_address, get_global_address
|
||||
from .audio import sort_asms
|
||||
|
||||
|
||||
from wram import read_constants
|
||||
from .wram import read_constants
|
||||
|
||||
rom = bytearray(load_rom())
|
||||
|
||||
|
|
@ -42,7 +44,7 @@ anims = read_constants(os.path.join(conf.path, 'constants/animation_constants.as
|
|||
objs = { k: v for k, v in anims.items() if 'ANIM_OBJ' in v }
|
||||
bgs = { k: v for k, v in anims.items() if 'ANIM_BG' in v }
|
||||
anims = { k: v.replace('ANIM_','') for k, v in anims.items() }
|
||||
from move_constants import moves
|
||||
from .move_constants import moves
|
||||
anims.update(moves)
|
||||
|
||||
class AnimObjParam(SingleByteParam):
|
||||
|
|
@ -320,5 +322,5 @@ def asm_list_to_text(asms):
|
|||
|
||||
if __name__ == '__main__':
|
||||
asms = dump_battle_anims()
|
||||
print asm_list_to_text(asms)
|
||||
print(asm_list_to_text(asms))
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
"""
|
||||
Find shared functions between red/crystal.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
|
||||
from crystal import (
|
||||
from .crystal import (
|
||||
get_label_from_line,
|
||||
get_address_from_line_comment,
|
||||
AsmSection,
|
||||
|
|
@ -11,7 +13,7 @@ from crystal import (
|
|||
direct_load_asm,
|
||||
)
|
||||
|
||||
from romstr import (
|
||||
from .romstr import (
|
||||
RomStr,
|
||||
AsmList,
|
||||
)
|
||||
|
|
@ -53,7 +55,7 @@ class Address(int):
|
|||
instance = int.__new__(cls, int(x, base=16), *args, **kwargs)
|
||||
else:
|
||||
msg = "Address.__new__ doesn't know how to parse this string"
|
||||
raise Exception, msg
|
||||
raise Exception(msg)
|
||||
else:
|
||||
instance = int.__new__(cls, x, *args, **kwargs)
|
||||
|
||||
|
|
@ -157,7 +159,7 @@ class BinaryBlob(object):
|
|||
found_blobs.append(self)
|
||||
|
||||
if self.debug:
|
||||
print self.label + ": found " + str(len(self.locations)) + " matches."
|
||||
print(self.label + ": found " + str(len(self.locations)) + " matches.")
|
||||
|
||||
def find_by_first_bytes(self):
|
||||
"""
|
||||
|
|
@ -181,7 +183,7 @@ class BinaryBlob(object):
|
|||
found_blobs.append(self)
|
||||
|
||||
if self.debug:
|
||||
print self.label + ": found " + str(len(self.locations)) + " matches."
|
||||
print(self.label + ": found " + str(len(self.locations)) + " matches.")
|
||||
|
||||
pokecrystal_rom_path = "../baserom.gbc"
|
||||
pokecrystal_src_path = "../main.asm"
|
||||
|
|
@ -214,14 +216,14 @@ def scan_red_asm(bank_stop=3, debug=True):
|
|||
|
||||
for line in redsrc:
|
||||
if debug and show_lines:
|
||||
print "processing a line from red: " + line
|
||||
print("processing a line from red: " + line)
|
||||
|
||||
if line[0:7] == "SECTION":
|
||||
thing = AsmSection(line)
|
||||
current_bank = thing.bank_id
|
||||
|
||||
if debug:
|
||||
print "scan_red_asm: switching to bank " + str(current_bank)
|
||||
print("scan_red_asm: switching to bank " + str(current_bank))
|
||||
|
||||
elif line[0:6] != "INCBIN":
|
||||
if ":" in line and not ";XXX:" in line and not " ; XXX:" in line:
|
||||
|
|
@ -240,7 +242,7 @@ def scan_red_asm(bank_stop=3, debug=True):
|
|||
line_number=line_number)
|
||||
|
||||
if debug:
|
||||
print "Created a new blob: " + str(blob) + " from line: " + str(latest_line)
|
||||
print("Created a new blob: " + str(blob) + " from line: " + str(latest_line))
|
||||
|
||||
latest_label = current_label
|
||||
latest_start_address = current_start_address
|
||||
|
|
@ -250,18 +252,18 @@ def scan_red_asm(bank_stop=3, debug=True):
|
|||
|
||||
if current_bank == bank_stop:
|
||||
if debug:
|
||||
print "scan_red_asm: stopping because current_bank >= " + \
|
||||
str(bank_stop) + " (bank_stop)"
|
||||
print("scan_red_asm: stopping because current_bank >= " + \
|
||||
str(bank_stop) + " (bank_stop)")
|
||||
|
||||
break
|
||||
|
||||
scan_red_asm(bank_stop=3)
|
||||
|
||||
print "================================"
|
||||
print("================================")
|
||||
|
||||
for blob in found_blobs:
|
||||
print blob
|
||||
print(blob)
|
||||
|
||||
print "Found " + str(len(found_blobs)) + " possibly copied functions."
|
||||
print("Found " + str(len(found_blobs)) + " possibly copied functions.")
|
||||
|
||||
print [hex(x) for x in found_blobs[10].locations]
|
||||
print([hex(x) for x in found_blobs[10].locations])
|
||||
|
|
|
|||
|
|
@ -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
|
||||
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
|
||||
|
||||
import addresses
|
||||
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.
|
||||
|
||||
|
|
|
|||
|
|
@ -274,9 +274,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"?
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@
|
|||
Dump out asm for scripting things in bank $25. This script will modify main.asm
|
||||
and insert all scripting commands.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import crystal
|
||||
import gbz80disasm
|
||||
from . import crystal
|
||||
from . import gbz80disasm
|
||||
|
||||
rom = crystal.load_rom()
|
||||
roml = [ord(x) for x in rom]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
from gfx import *
|
||||
from pokemon_constants import pokemon_constants
|
||||
import trainers
|
||||
import romstr
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from .gfx import *
|
||||
from .pokemon_constants import pokemon_constants
|
||||
from . import trainers
|
||||
from . import romstr
|
||||
|
||||
def load_rom(filename=config.rom_path):
|
||||
rom = romstr.RomStr.load(filename=filename)
|
||||
|
|
@ -357,7 +359,7 @@ def dump_pic_animations(addresses={'bitmasks': 'BitmasksPointers', 'frames': 'Fr
|
|||
tiles = (x for x in frame[1])
|
||||
for j, bit in enumerate(bitmask):
|
||||
if bit:
|
||||
tmap[(i + 1) * length + j] = tiles.next()
|
||||
tmap[(i + 1) * length + j] = next(tiles)
|
||||
|
||||
filename = os.path.join(directory, 'front.{0}x{0}.2bpp.lz'.format(size))
|
||||
tiles = get_tiles(Decompressed(open(filename).read()).output)
|
||||
|
|
@ -495,7 +497,7 @@ def dump_trainer_pals():
|
|||
to_file('../'+dir+filename, pal_data)
|
||||
|
||||
spacing = ' ' * (12 - len(name))
|
||||
print name+'Palette:'+spacing+' INCBIN"'+dir+filename+'"'
|
||||
print(name+'Palette:'+spacing+' INCBIN"'+dir+filename+'"')
|
||||
|
||||
|
||||
def get_uncompressed_gfx(start, num_tiles, filename):
|
||||
|
|
|
|||
|
|
@ -2,13 +2,15 @@
|
|||
"""
|
||||
GBC disassembler
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import argparse
|
||||
from ctypes import c_int8
|
||||
|
||||
import configuration
|
||||
from wram import read_constants
|
||||
from . import configuration
|
||||
from .wram import read_constants
|
||||
|
||||
z80_table = [
|
||||
('nop', 0), # 00
|
||||
|
|
@ -392,20 +394,20 @@ def load_symbols(path):
|
|||
label = symbol['label']
|
||||
|
||||
if 0x0000 <= address < 0x8000:
|
||||
if not sym.has_key(bank):
|
||||
if bank not in sym:
|
||||
sym[bank] = {}
|
||||
|
||||
sym[bank][address] = label
|
||||
reverse_sym[label] = get_global_address(address, bank)
|
||||
|
||||
elif 0xa000 <= address < 0xc000:
|
||||
if not sram_sym.has_key(bank):
|
||||
if bank not in sram_sym:
|
||||
sram_sym[bank] = {}
|
||||
|
||||
sram_sym[bank][address] = label
|
||||
|
||||
elif address < 0xe000:
|
||||
if not wram_sym.has_key(bank):
|
||||
if bank not in wram_sym:
|
||||
wram_sym[bank] = {}
|
||||
|
||||
wram_sym[bank][address] = label
|
||||
|
|
@ -575,7 +577,7 @@ class Disassembler(object):
|
|||
stop_offset = (bank_id + 1) * 0x4000 - 1
|
||||
|
||||
if debug:
|
||||
print "bank id is: " + str(bank_id)
|
||||
print("bank id is: " + str(bank_id))
|
||||
|
||||
rom = self.rom
|
||||
|
||||
|
|
@ -904,7 +906,7 @@ if __name__ == "__main__":
|
|||
|
||||
# suppress output if quiet flag is set
|
||||
if not args.quiet:
|
||||
print output
|
||||
print(output)
|
||||
|
||||
# only write to the output file if the no write flag is unset
|
||||
if not args.no_write:
|
||||
|
|
|
|||
|
|
@ -1,23 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import png
|
||||
from . import png
|
||||
from math import sqrt, floor, ceil
|
||||
import argparse
|
||||
import operator
|
||||
|
||||
import configuration
|
||||
from . import configuration
|
||||
config = configuration.Config()
|
||||
|
||||
from lz import Compressed, Decompressed
|
||||
from .lz import Compressed, Decompressed
|
||||
|
||||
|
||||
def split(list_, interval):
|
||||
"""
|
||||
Split a list by length.
|
||||
"""
|
||||
for i in xrange(0, len(list_), interval):
|
||||
for i in range(0, len(list_), interval):
|
||||
j = min(i + interval, len(list_))
|
||||
yield list_[i:j]
|
||||
|
||||
|
|
@ -69,7 +71,7 @@ def transpose(tiles, width=None):
|
|||
"""
|
||||
if width == None:
|
||||
width = int(sqrt(len(tiles))) # assume square image
|
||||
tiles = sorted(enumerate(tiles), key= lambda (i, tile): i % width)
|
||||
tiles = sorted(enumerate(tiles), key= lambda i_tile: i_tile[0] % width)
|
||||
return [tile for i, tile in tiles]
|
||||
|
||||
def transpose_tiles(image, width=None):
|
||||
|
|
@ -135,7 +137,7 @@ def condense_tiles_to_map(tiles, pic=0):
|
|||
|
||||
# Leave the first frame intact for pics.
|
||||
new_tiles = tiles[:pic]
|
||||
tilemap = range(pic)
|
||||
tilemap = list(range(pic))
|
||||
|
||||
for i, tile in enumerate(tiles[pic:]):
|
||||
if tile not in new_tiles:
|
||||
|
|
@ -175,14 +177,13 @@ def to_file(filename, data):
|
|||
"""
|
||||
Apparently open(filename, 'wb').write(bytearray(data)) won't work.
|
||||
"""
|
||||
file = open(filename, 'wb')
|
||||
for byte in data:
|
||||
file.write('%c' % byte)
|
||||
file.close()
|
||||
with open(filename, 'wb') as f:
|
||||
f.write((bytearray(data)))
|
||||
|
||||
|
||||
def decompress_file(filein, fileout=None):
|
||||
image = bytearray(open(filein).read())
|
||||
with open(filein, 'rb') as f:
|
||||
image = bytearray(f.read())
|
||||
de = Decompressed(image)
|
||||
|
||||
if fileout == None:
|
||||
|
|
@ -191,7 +192,8 @@ def decompress_file(filein, fileout=None):
|
|||
|
||||
|
||||
def compress_file(filein, fileout=None):
|
||||
image = bytearray(open(filein).read())
|
||||
with open(filein, 'rb') as f:
|
||||
image = bytearray(f.read())
|
||||
lz = Compressed(image)
|
||||
|
||||
if fileout == None:
|
||||
|
|
@ -208,7 +210,8 @@ def bin_to_rgb(word):
|
|||
return (red, green, blue)
|
||||
|
||||
def convert_binary_pal_to_text_by_filename(filename):
|
||||
pal = bytearray(open(filename).read())
|
||||
with open(filename, 'rb') as f:
|
||||
pal = bytearray(f.read())
|
||||
return convert_binary_pal_to_text(pal)
|
||||
|
||||
def convert_binary_pal_to_text(pal):
|
||||
|
|
@ -247,7 +250,7 @@ def flatten(planar):
|
|||
bottom = bottom
|
||||
top = top
|
||||
strip = []
|
||||
for i in xrange(7,-1,-1):
|
||||
for i in range(7,-1,-1):
|
||||
color = (
|
||||
(bottom >> i & 1) +
|
||||
(top *2 >> i & 2)
|
||||
|
|
@ -262,14 +265,14 @@ def to_lines(image, width):
|
|||
"""
|
||||
tile_width = 8
|
||||
tile_height = 8
|
||||
num_columns = width / tile_width
|
||||
height = len(image) / width
|
||||
num_columns = width // tile_width
|
||||
height = len(image) // width
|
||||
|
||||
lines = []
|
||||
for cur_line in xrange(height):
|
||||
tile_row = cur_line / tile_height
|
||||
for cur_line in range(height):
|
||||
tile_row = cur_line // tile_height
|
||||
line = []
|
||||
for column in xrange(num_columns):
|
||||
for column in range(num_columns):
|
||||
anchor = (
|
||||
num_columns * tile_row * tile_width * tile_height +
|
||||
column * tile_width * tile_height +
|
||||
|
|
@ -290,7 +293,7 @@ def dmg2rgb(word):
|
|||
value >>= 5
|
||||
word = shift(word)
|
||||
# distribution is less even w/ << 3
|
||||
red, green, blue = [int(color * 8.25) for color in [word.next() for _ in xrange(3)]]
|
||||
red, green, blue = [int(color * 8.25) for color in [next(word) for _ in range(3)]]
|
||||
alpha = 255
|
||||
return (red, green, blue, alpha)
|
||||
|
||||
|
|
@ -299,9 +302,9 @@ def rgb_to_dmg(color):
|
|||
"""
|
||||
For PNGs.
|
||||
"""
|
||||
word = (color['r'] / 8)
|
||||
word += (color['g'] / 8) << 5
|
||||
word += (color['b'] / 8) << 10
|
||||
word = (color['r'] // 8)
|
||||
word += (color['g'] // 8) << 5
|
||||
word += (color['b'] // 8) << 10
|
||||
return word
|
||||
|
||||
|
||||
|
|
@ -332,7 +335,7 @@ def png_to_rgb(palette):
|
|||
"""
|
||||
output = ''
|
||||
for color in palette:
|
||||
r, g, b = [color[c] / 8 for c in 'rgb']
|
||||
r, g, b = [color[c] // 8 for c in 'rgb']
|
||||
output += '\tRGB ' + ', '.join(['%.2d' % hue for hue in (r, g, b)])
|
||||
output += '\n'
|
||||
return output
|
||||
|
|
@ -431,7 +434,7 @@ def convert_2bpp_to_png(image, **kwargs):
|
|||
|
||||
# Width must be specified to interleave.
|
||||
if interleave and width:
|
||||
image = interleave_tiles(image, width / 8)
|
||||
image = interleave_tiles(image, width // 8)
|
||||
|
||||
# Pad the image by a given number of tiles if asked.
|
||||
image += pad_color * 0x10 * tile_padding
|
||||
|
|
@ -446,34 +449,34 @@ def convert_2bpp_to_png(image, **kwargs):
|
|||
trailing = len(image) % pic_length
|
||||
|
||||
pic = []
|
||||
for i in xrange(0, len(image) - trailing, pic_length):
|
||||
for i in range(0, len(image) - trailing, pic_length):
|
||||
pic += transpose_tiles(image[i:i+pic_length], h)
|
||||
image = bytearray(pic) + image[len(image) - trailing:]
|
||||
|
||||
# Pad out trailing lines.
|
||||
image += pad_color * 0x10 * ((w - (len(image) / 0x10) % h) % w)
|
||||
image += pad_color * 0x10 * ((w - (len(image) // 0x10) % h) % w)
|
||||
|
||||
def px_length(img):
|
||||
return len(img) * 4
|
||||
def tile_length(img):
|
||||
return len(img) * 4 / (8*8)
|
||||
return len(img) * 4 // (8*8)
|
||||
|
||||
if width and height:
|
||||
tile_width = width / 8
|
||||
tile_width = width // 8
|
||||
more_tile_padding = (tile_width - (tile_length(image) % tile_width or tile_width))
|
||||
image += pad_color * 0x10 * more_tile_padding
|
||||
|
||||
elif width and not height:
|
||||
tile_width = width / 8
|
||||
tile_width = width // 8
|
||||
more_tile_padding = (tile_width - (tile_length(image) % tile_width or tile_width))
|
||||
image += pad_color * 0x10 * more_tile_padding
|
||||
height = px_length(image) / width
|
||||
height = px_length(image) // width
|
||||
|
||||
elif height and not width:
|
||||
tile_height = height / 8
|
||||
tile_height = height // 8
|
||||
more_tile_padding = (tile_height - (tile_length(image) % tile_height or tile_height))
|
||||
image += pad_color * 0x10 * more_tile_padding
|
||||
width = px_length(image) / height
|
||||
width = px_length(image) // height
|
||||
|
||||
# at least one dimension should be given
|
||||
if width * height != px_length(image):
|
||||
|
|
@ -481,15 +484,15 @@ def convert_2bpp_to_png(image, **kwargs):
|
|||
matches = []
|
||||
# Height need not be divisible by 8, but width must.
|
||||
# See pokered gfx/minimize_pic.1bpp.
|
||||
for w in range(8, px_length(image) / 2 + 1, 8):
|
||||
h = px_length(image) / w
|
||||
for w in range(8, px_length(image) // 2 + 1, 8):
|
||||
h = px_length(image) // w
|
||||
if w * h == px_length(image):
|
||||
matches += [(w, h)]
|
||||
# go for the most square image
|
||||
if len(matches):
|
||||
width, height = sorted(matches, key= lambda (w, h): (h % 8 != 0, w + h))[0] # favor height
|
||||
width, height = sorted(matches, key= lambda w_h: (w_h[1] % 8 != 0, w_h[0] + w_h[1]))[0] # favor height
|
||||
else:
|
||||
raise Exception, 'Image can\'t be divided into tiles (%d px)!' % (px_length(image))
|
||||
raise Exception('Image can\'t be divided into tiles (%d px)!' % (px_length(image)))
|
||||
|
||||
# convert tiles to lines
|
||||
lines = to_lines(flatten(image), width)
|
||||
|
|
@ -520,7 +523,7 @@ def get_pic_animation(tmap, w, h):
|
|||
base = frames.pop(0)
|
||||
bitmasks = []
|
||||
|
||||
for i in xrange(len(frames)):
|
||||
for i in range(len(frames)):
|
||||
frame_text += '\tdw .frame{}\n'.format(i + 1)
|
||||
|
||||
for i, frame in enumerate(frames):
|
||||
|
|
@ -530,7 +533,7 @@ def get_pic_animation(tmap, w, h):
|
|||
which_bitmask = bitmasks.index(bitmask)
|
||||
|
||||
mask = iter(bitmask)
|
||||
masked_frame = filter(lambda _: mask.next(), frame)
|
||||
masked_frame = filter(lambda _: next(mask), frame)
|
||||
|
||||
frame_text += '.frame{}\n'.format(i + 1)
|
||||
frame_text += '\tdb ${:02x} ; bitmask\n'.format(which_bitmask)
|
||||
|
|
@ -607,12 +610,12 @@ def get_image_padding(width, height, wstep=8, hstep=8):
|
|||
}
|
||||
|
||||
if width % wstep and width >= wstep:
|
||||
pad = float(width % wstep) / 2
|
||||
pad = width % wstep / 2
|
||||
padding['left'] = int(ceil(pad))
|
||||
padding['right'] = int(floor(pad))
|
||||
|
||||
if height % hstep and height >= hstep:
|
||||
pad = float(height % hstep) / 2
|
||||
pad = height % hstep / 2
|
||||
padding['top'] = int(ceil(pad))
|
||||
padding['bottom'] = int(floor(pad))
|
||||
|
||||
|
|
@ -636,8 +639,6 @@ def png_to_2bpp(filein, **kwargs):
|
|||
if type(filein) is str:
|
||||
filein = open(filein, 'rb')
|
||||
|
||||
assert type(filein) is file
|
||||
|
||||
width, height, rgba, info = png.Reader(filein).asRGBA8()
|
||||
|
||||
# png.Reader returns flat pixel data. Nested is easier to work with
|
||||
|
|
@ -646,16 +647,16 @@ def png_to_2bpp(filein, **kwargs):
|
|||
palette = []
|
||||
for line in rgba:
|
||||
newline = []
|
||||
for px in xrange(0, len(line), len_px):
|
||||
for px in range(0, len(line), len_px):
|
||||
color = dict(zip('rgba', line[px:px+len_px]))
|
||||
if color not in palette:
|
||||
if len(palette) < 4:
|
||||
palette += [color]
|
||||
else:
|
||||
# TODO Find the nearest match
|
||||
print 'WARNING: %s: Color %s truncated to' % (filein, color),
|
||||
print('WARNING: %s: Color %s truncated to' % (filein, color), end=' ')
|
||||
color = sorted(palette, key=lambda x: sum(x.values()))[0]
|
||||
print color
|
||||
print(color)
|
||||
newline += [color]
|
||||
image += [newline]
|
||||
|
||||
|
|
@ -698,15 +699,15 @@ def png_to_2bpp(filein, **kwargs):
|
|||
# Graphics are stored in tiles instead of lines
|
||||
tile_width = 8
|
||||
tile_height = 8
|
||||
num_columns = max(width, tile_width) / tile_width
|
||||
num_rows = max(height, tile_height) / tile_height
|
||||
num_columns = max(width, tile_width) // tile_width
|
||||
num_rows = max(height, tile_height) // tile_height
|
||||
image = []
|
||||
|
||||
for row in xrange(num_rows):
|
||||
for column in xrange(num_columns):
|
||||
for row in range(num_rows):
|
||||
for column in range(num_columns):
|
||||
|
||||
# Split it up into strips to convert to planar data
|
||||
for strip in xrange(min(tile_height, height)):
|
||||
for strip in range(min(tile_height, height)):
|
||||
anchor = (
|
||||
row * num_columns * tile_width * tile_height +
|
||||
column * tile_width +
|
||||
|
|
@ -716,7 +717,7 @@ def png_to_2bpp(filein, **kwargs):
|
|||
bottom, top = 0, 0
|
||||
for bit, quad in enumerate(line):
|
||||
bottom += (quad & 1) << (7 - bit)
|
||||
top += (quad /2 & 1) << (7 - bit)
|
||||
top += (quad // 2 & 1) << (7 - bit)
|
||||
image += [bottom, top]
|
||||
|
||||
dim = arguments['pic_dimensions']
|
||||
|
|
@ -725,20 +726,20 @@ def png_to_2bpp(filein, **kwargs):
|
|||
w, h = dim
|
||||
else:
|
||||
# infer dimensions based on width.
|
||||
w = width / tile_width
|
||||
h = height / tile_height
|
||||
w = width // tile_width
|
||||
h = height // tile_height
|
||||
if h % w == 0:
|
||||
h = w
|
||||
|
||||
tiles = get_tiles(image)
|
||||
pic_length = w * h
|
||||
tile_width = width / 8
|
||||
tile_width = width // 8
|
||||
trailing = len(tiles) % pic_length
|
||||
new_image = []
|
||||
for block in xrange(len(tiles) / pic_length):
|
||||
offset = (h * tile_width) * ((block * w) / tile_width) + ((block * w) % tile_width)
|
||||
for block in range(len(tiles) // pic_length):
|
||||
offset = (h * tile_width) * ((block * w) // tile_width) + ((block * w) % tile_width)
|
||||
pic = []
|
||||
for row in xrange(h):
|
||||
for row in range(h):
|
||||
index = offset + (row * tile_width)
|
||||
pic += tiles[index:index + w]
|
||||
new_image += transpose(pic, w)
|
||||
|
|
@ -865,7 +866,7 @@ def convert_to_2bpp(filenames=[]):
|
|||
elif extension == '.png':
|
||||
export_png_to_2bpp(filename)
|
||||
else:
|
||||
raise Exception, "Don't know how to convert {} to 2bpp!".format(filename)
|
||||
raise Exception("Don't know how to convert {} to 2bpp!".format(filename))
|
||||
|
||||
def convert_to_1bpp(filenames=[]):
|
||||
for filename in filenames:
|
||||
|
|
@ -877,7 +878,7 @@ def convert_to_1bpp(filenames=[]):
|
|||
elif extension == '.png':
|
||||
export_png_to_1bpp(filename)
|
||||
else:
|
||||
raise Exception, "Don't know how to convert {} to 1bpp!".format(filename)
|
||||
raise Exception("Don't know how to convert {} to 1bpp!".format(filename))
|
||||
|
||||
def convert_to_png(filenames=[]):
|
||||
for filename in filenames:
|
||||
|
|
@ -889,7 +890,7 @@ def convert_to_png(filenames=[]):
|
|||
elif extension == '.png':
|
||||
pass
|
||||
else:
|
||||
raise Exception, "Don't know how to convert {} to png!".format(filename)
|
||||
raise Exception("Don't know how to convert {} to png!".format(filename))
|
||||
|
||||
def compress(filenames=[]):
|
||||
for filename in filenames:
|
||||
|
|
@ -933,7 +934,7 @@ def main():
|
|||
}.get(args.mode, None)
|
||||
|
||||
if method == None:
|
||||
raise Exception, "Unknown conversion method!"
|
||||
raise Exception("Unknown conversion method!")
|
||||
|
||||
method(args.filenames)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
import networkx as nx
|
||||
|
||||
from romstr import (
|
||||
from .romstr import (
|
||||
RomStr,
|
||||
relative_jumps,
|
||||
call_commands,
|
||||
|
|
@ -92,7 +94,7 @@ class RomGraph(nx.DiGraph):
|
|||
# check if there are any nops (probably not a function)
|
||||
nops = 0
|
||||
for (id, command) in func.asm_commands.items():
|
||||
if command.has_key("id") and command["id"] == 0x0:
|
||||
if "id" in command and command["id"] == 0x0:
|
||||
nops += 1
|
||||
|
||||
# skip this function
|
||||
|
|
@ -131,7 +133,7 @@ class RomGraph(nx.DiGraph):
|
|||
Shows some text output describing which nodes point to which other
|
||||
nodes.
|
||||
"""
|
||||
print self.edges()
|
||||
print(self.edges())
|
||||
|
||||
def to_d3(self):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from bisect import bisect_left, bisect_right
|
||||
from itertools import izip
|
||||
try:
|
||||
from future_builtins import zip
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class IntervalMap(object):
|
||||
"""
|
||||
|
|
@ -75,7 +79,7 @@ class IntervalMap(object):
|
|||
((low_bound, high_bound), value)
|
||||
these items are returned in order"""
|
||||
previous_bound = None
|
||||
for (b, v) in izip(self._bounds, self._items):
|
||||
for (b, v) in zip(self._bounds, self._items):
|
||||
if v is not None:
|
||||
yield (previous_bound, b), v
|
||||
previous_bound = b
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@
|
|||
"""
|
||||
Various label/line-related functions.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import json
|
||||
import logging
|
||||
|
||||
import pointers
|
||||
import sym
|
||||
from . import pointers
|
||||
from . import sym
|
||||
|
||||
class Labels(object):
|
||||
"""
|
||||
|
|
@ -31,7 +32,7 @@ class Labels(object):
|
|||
if not os.path.exists(self.path):
|
||||
self.filename = find_symfile_in_dir(self.config.path)
|
||||
if self.filename == None:
|
||||
raise Exception, "Couldn't find any .sym files. Run rgblink -n to create a .sym file."
|
||||
raise Exception("Couldn't find any .sym files. Run rgblink -n to create a .sym file.")
|
||||
self.path = os.path.join(self.config.path, self.filename)
|
||||
|
||||
self.labels = sym.read_symfile(self.path)
|
||||
|
|
@ -178,7 +179,7 @@ def get_address_from_line_comment(line, bank=None):
|
|||
def line_has_label(line):
|
||||
"""returns True if the line has an asm label"""
|
||||
if not isinstance(line, str):
|
||||
raise Exception, "can't check this type of object"
|
||||
raise Exception("can't check this type of object")
|
||||
line = line.rstrip(" ").lstrip(" ")
|
||||
line = remove_quoted_text(line)
|
||||
if ";" in line:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
"""
|
||||
Pokemon Crystal data de/compression.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
"""
|
||||
A rundown of Pokemon Crystal's compression scheme:
|
||||
|
|
@ -44,8 +45,8 @@ lz_end = 0xff
|
|||
|
||||
|
||||
bit_flipped = [
|
||||
sum(((byte >> i) & 1) << (7 - i) for i in xrange(8))
|
||||
for byte in xrange(0x100)
|
||||
sum(((byte >> i) & 1) << (7 - i) for i in range(8))
|
||||
for byte in range(0x100)
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -189,7 +190,7 @@ class Compressed:
|
|||
)
|
||||
for method in self.lookback_methods:
|
||||
min_score = self.min_scores[method]
|
||||
for address in xrange(self.address+1, self.address+best_score):
|
||||
for address in range(self.address+1, self.address+best_score):
|
||||
length, index = self.find_lookback(method, address)
|
||||
if length > max(min_score, best_score):
|
||||
# BUG: lookbacks can reduce themselves. This appears to be a bug in the target also.
|
||||
|
|
@ -211,7 +212,7 @@ class Compressed:
|
|||
|
||||
def find_lookback(self, method, address=None):
|
||||
"""Temporarily stubbed, because the real function doesn't run in polynomial time."""
|
||||
return 0, None
|
||||
return 0, None
|
||||
|
||||
def broken_find_lookback(self, method, address=None):
|
||||
if address is None:
|
||||
|
|
@ -282,7 +283,7 @@ class Compressed:
|
|||
return lookback
|
||||
|
||||
def get_indexes(self, byte):
|
||||
if not self.indexes.has_key(byte):
|
||||
if byte not in self.indexes:
|
||||
self.indexes[byte] = []
|
||||
index = -1
|
||||
while 1:
|
||||
|
|
@ -315,15 +316,15 @@ class Compressed:
|
|||
|
||||
def do_winner(self):
|
||||
winners = filter(
|
||||
lambda (method, score):
|
||||
score
|
||||
> self.min_scores[method] + int(score > lowmax),
|
||||
lambda method_score:
|
||||
method_score[1]
|
||||
> self.min_scores[method_score[0]] + int(method_score[1] > lowmax),
|
||||
self.scores.iteritems()
|
||||
)
|
||||
winners.sort(
|
||||
key = lambda (method, score): (
|
||||
-(score - self.min_scores[method] - int(score > lowmax)),
|
||||
self.preference.index(method)
|
||||
key = lambda method_score1: (
|
||||
-(method_score1[1] - self.min_scores[method_score1[0]] - int(method_score1[1] > lowmax)),
|
||||
self.preference.index(method_score1[0])
|
||||
)
|
||||
)
|
||||
winner, score = winners[0]
|
||||
|
|
@ -368,11 +369,11 @@ class Compressed:
|
|||
output += [offset / 0x100, offset % 0x100] # big endian
|
||||
|
||||
if self.debug:
|
||||
print ' '.join(map(str, [
|
||||
print(' '.join(map(str, [
|
||||
cmd, length, '\t',
|
||||
' '.join(map('{:02x}'.format, output)),
|
||||
self.data[start_address:start_address+length] if cmd in self.lookback_methods else '',
|
||||
]))
|
||||
])))
|
||||
|
||||
self.output += output
|
||||
|
||||
|
|
@ -414,7 +415,7 @@ class Decompressed:
|
|||
if self.lz is not None:
|
||||
self.decompress()
|
||||
|
||||
if self.debug: print self.command_list()
|
||||
if self.debug: print(self.command_list())
|
||||
|
||||
|
||||
def command_list(self):
|
||||
|
|
@ -466,7 +467,7 @@ class Decompressed:
|
|||
self.direction = None
|
||||
|
||||
if (self.byte == lz_end):
|
||||
self.next()
|
||||
next(self)
|
||||
break
|
||||
|
||||
self.cmd = (self.byte & 0b11100000) >> 5
|
||||
|
|
@ -474,11 +475,11 @@ class Decompressed:
|
|||
if self.cmd_name == 'long':
|
||||
# 10-bit length
|
||||
self.cmd = (self.byte & 0b00011100) >> 2
|
||||
self.length = (self.next() & 0b00000011) * 0x100
|
||||
self.length += self.next() + 1
|
||||
self.length = (next(self) & 0b00000011) * 0x100
|
||||
self.length += next(self) + 1
|
||||
else:
|
||||
# 5-bit length
|
||||
self.length = (self.next() & 0b00011111) + 1
|
||||
self.length = (next(self) & 0b00011111) + 1
|
||||
|
||||
self.__class__.__dict__[self.cmd_name](self)
|
||||
|
||||
|
|
@ -515,12 +516,12 @@ class Decompressed:
|
|||
|
||||
if self.byte >= 0x80: # negative
|
||||
# negative
|
||||
offset = self.next() & 0x7f
|
||||
offset = next(self) & 0x7f
|
||||
offset = len(self.output) - offset - 1
|
||||
else:
|
||||
# positive
|
||||
offset = self.next() * 0x100
|
||||
offset += self.next()
|
||||
offset = next(self) * 0x100
|
||||
offset += next(self)
|
||||
|
||||
self.offset = offset
|
||||
|
||||
|
|
@ -536,14 +537,14 @@ class Decompressed:
|
|||
"""
|
||||
Write one byte repeatedly.
|
||||
"""
|
||||
self.output += [self.next()] * self.length
|
||||
self.output += [next(self)] * self.length
|
||||
|
||||
def alternate(self):
|
||||
"""
|
||||
Write alternating bytes.
|
||||
"""
|
||||
alts = [self.next(), self.next()]
|
||||
self.output += [ alts[x & 1] for x in xrange(self.length) ]
|
||||
alts = [next(self), next(self)]
|
||||
self.output += [ alts[x & 1] for x in range(self.length) ]
|
||||
|
||||
def blank(self):
|
||||
"""
|
||||
|
|
@ -575,6 +576,6 @@ class Decompressed:
|
|||
self.get_offset()
|
||||
self.direction = direction
|
||||
# Note: appends must be one at a time (this way, repeats can draw from themselves if required)
|
||||
for i in xrange(self.length):
|
||||
for i in range(self.length):
|
||||
byte = self.output[ self.offset + i * direction ]
|
||||
self.output.append( table[byte] if table else byte )
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import absolute_import
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
|
|
@ -36,10 +37,10 @@ from PIL import (
|
|||
ImageTk,
|
||||
)
|
||||
|
||||
import gfx
|
||||
import wram
|
||||
import preprocessor
|
||||
import configuration
|
||||
from . import gfx
|
||||
from . import wram
|
||||
from . import preprocessor
|
||||
from . import configuration
|
||||
config = configuration.Config()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
"""
|
||||
Map-related graphic functions.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import png
|
||||
from . import png
|
||||
from io import BytesIO
|
||||
|
||||
from PIL import (
|
||||
|
|
@ -11,8 +13,8 @@ from PIL import (
|
|||
ImageDraw,
|
||||
)
|
||||
|
||||
import crystal
|
||||
import gfx
|
||||
from . import crystal
|
||||
from . import gfx
|
||||
|
||||
tile_width = 8
|
||||
tile_height = 8
|
||||
|
|
@ -285,7 +287,7 @@ def draw_map_sprites(map_header, map_image, config=config):
|
|||
other_args = {}
|
||||
|
||||
if sprite_image_id not in sprites.keys() or sprite_image_id > 0x66:
|
||||
print "sprite_image_id {} is not in sprites".format(sprite_image_id)
|
||||
print("sprite_image_id {} is not in sprites".format(sprite_image_id))
|
||||
|
||||
sprite_image = Image.new("RGBA", (16, 16))
|
||||
|
||||
|
|
@ -362,7 +364,7 @@ def save_map(map_group_id, map_id, savedir, show_sprites=True, config=config):
|
|||
|
||||
palettes = read_palettes(config=config)
|
||||
|
||||
print "Drawing {}".format(map_name)
|
||||
print("Drawing {}".format(map_name))
|
||||
map_image = draw_map(map_group_id, map_id, palettes, show_sprites=show_sprites, config=config)
|
||||
map_image.save(filepath)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,21 +5,22 @@ do anything on its own.
|
|||
|
||||
old_parse is a part of the Script class
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
def old_parse(self, *args, **kwargs):
|
||||
"""parses a script-engine script; force=True if you want to re-parse
|
||||
and get the debug information"""
|
||||
print "Script.old_parse address="+hex(self.address)
|
||||
print("Script.old_parse address="+hex(self.address))
|
||||
#can't handle more than one argument
|
||||
if len(args) > 1:
|
||||
raise Exception, "Script.parse_script doesn't know how to handle positional arguments"
|
||||
raise Exception("Script.parse_script doesn't know how to handle positional arguments")
|
||||
#use the first positional argument as the address
|
||||
elif len(args) == 1:
|
||||
self.address = args[0]
|
||||
if type(self.address) == str:
|
||||
self.address = int(self.address, 16)
|
||||
elif type(self.address) != int:
|
||||
raise Exception, "address param is the wrong type"
|
||||
raise Exception("address param is the wrong type")
|
||||
#parse any keyword arguments, first make up the defaults
|
||||
kwargsorig = {"map_group": None, "map_id": None, "force": False, "debug": True, "origin": False}
|
||||
#let the caller override any defaults
|
||||
|
|
@ -48,16 +49,16 @@ def old_parse(self, *args, **kwargs):
|
|||
|
||||
#don't parse these crazy things (battle tower things, some rival things, etc.)
|
||||
if address in stop_points:
|
||||
print "got " + hex(address) + ".. map_group=" + str(map_group) + " map_id=" + str(map_id)
|
||||
print("got " + hex(address) + ".. map_group=" + str(map_group) + " map_id=" + str(map_id))
|
||||
return None
|
||||
#don't parse anything that looks crazy
|
||||
if address < 0x4000 and address not in [0x26ef, 0x114, 0x1108]:
|
||||
print "address is less than 0x4000.. address is: " + hex(address)
|
||||
print("address is less than 0x4000.. address is: " + hex(address))
|
||||
sys.exit()
|
||||
|
||||
#check if work is being repeated
|
||||
if is_script_already_parsed_at(address) and not force:
|
||||
raise Exception, "this script has already been parsed before, please use that instance"
|
||||
raise Exception("this script has already been parsed before, please use that instance")
|
||||
#use the commands from a previously-parsed Script object
|
||||
#self.commands = script_parse_table[address].commands
|
||||
#return True
|
||||
|
|
@ -90,8 +91,8 @@ def old_parse(self, *args, **kwargs):
|
|||
start_address = offset
|
||||
|
||||
if (len(commands.keys()) > max_cmds) and origin != False:
|
||||
print "too many commands in this script? might not be a script (starting at: " +\
|
||||
hex(original_start_address) + ").. called from a script at: " + hex(origin)
|
||||
print("too many commands in this script? might not be a script (starting at: " +\
|
||||
hex(original_start_address) + ").. called from a script at: " + hex(origin))
|
||||
sys.exit()
|
||||
|
||||
#start checking against possible command bytes
|
||||
|
|
@ -107,12 +108,12 @@ def old_parse(self, *args, **kwargs):
|
|||
last_byte_address = offset + size - 1
|
||||
pointer = calculate_pointer_from_bytes_at(start_address+1)
|
||||
if pointer == None:
|
||||
raise Exception, "pointer is None (shouldn't be None pointer on 0x0 script command"
|
||||
raise Exception("pointer is None (shouldn't be None pointer on 0x0 script command")
|
||||
command["pointer"] = pointer
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
|
||||
command["script"] = script
|
||||
elif command_byte == 0x01: #Pointer code [3b+ret]
|
||||
|
|
@ -126,9 +127,9 @@ def old_parse(self, *args, **kwargs):
|
|||
info = "pointer code"
|
||||
pointer = calculate_pointer_from_bytes_at(start_address+1, bank=True)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(pointer, original_start_address, debug)
|
||||
command["pointer"] = pointer
|
||||
command["script"] = script
|
||||
|
|
@ -141,9 +142,9 @@ def old_parse(self, *args, **kwargs):
|
|||
size = 3
|
||||
pointer = calculate_pointer_from_bytes_at(start_address+1)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
|
||||
command["pointer"] = pointer
|
||||
command["script"] = script
|
||||
|
|
@ -157,9 +158,9 @@ def old_parse(self, *args, **kwargs):
|
|||
size = 3
|
||||
pointer = calculate_pointer_from_bytes_at(start_address+1)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
|
||||
command["pointer"] = pointer
|
||||
command["script"] = script
|
||||
|
|
@ -173,9 +174,9 @@ def old_parse(self, *args, **kwargs):
|
|||
size = 4
|
||||
pointer = calculate_pointer_from_bytes_at(start_address+1, bank=True)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
|
||||
command["pointer"] = pointer
|
||||
command["script"] = script
|
||||
|
|
@ -191,9 +192,9 @@ def old_parse(self, *args, **kwargs):
|
|||
command["target_pointer"] = calculate_pointer_from_bytes_at(command["pointer"], bank=True)
|
||||
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(command["target_pointer"])+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(command["target_pointer"], original_start_address, debug=debug)
|
||||
command["script"] = script
|
||||
end = True #according to pksv
|
||||
|
|
@ -207,9 +208,9 @@ def old_parse(self, *args, **kwargs):
|
|||
command["byte"] = ord(rom[start_address+1])
|
||||
pointer = calculate_pointer_from_bytes_at(start_address+2)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
|
||||
command["pointer"] = pointer
|
||||
command["script"] = script
|
||||
|
|
@ -223,9 +224,9 @@ def old_parse(self, *args, **kwargs):
|
|||
command["byte"] = ord(rom[start_address+1])
|
||||
pointer = calculate_pointer_from_bytes_at(start_address+2)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
|
||||
command["pointer"] = pointer
|
||||
command["script"] = script
|
||||
|
|
@ -238,9 +239,9 @@ def old_parse(self, *args, **kwargs):
|
|||
size = 3
|
||||
pointer = calculate_pointer_from_bytes_at(start_address+1)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
|
||||
command["pointer"] = pointer
|
||||
command["script"] = script
|
||||
|
|
@ -253,9 +254,9 @@ def old_parse(self, *args, **kwargs):
|
|||
size = 3
|
||||
pointer = calculate_pointer_from_bytes_at(start_address+1)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
|
||||
command["pointer"] = pointer
|
||||
command["script"] = script
|
||||
|
|
@ -269,9 +270,9 @@ def old_parse(self, *args, **kwargs):
|
|||
command["byte"] = ord(rom[start_address+1])
|
||||
pointer = calculate_pointer_from_bytes_at(start_address+2)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
|
||||
command["pointer"] = pointer
|
||||
command["script"] = script
|
||||
|
|
@ -285,9 +286,9 @@ def old_parse(self, *args, **kwargs):
|
|||
command["byte"] = ord(rom[start_address+1])
|
||||
pointer = calculate_pointer_from_bytes_at(start_address+2)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
|
||||
command["pointer"] = pointer
|
||||
command["script"] = script
|
||||
|
|
@ -1588,9 +1589,9 @@ def old_parse(self, *args, **kwargs):
|
|||
size = 3
|
||||
script_pointer = calculate_pointer_from_bytes_at(start_address+1, bank=False)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(script_pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(script_pointer, original_start_address, debug=debug)
|
||||
command["script_pointer"] = script_pointer
|
||||
command["script"] = script
|
||||
|
|
@ -1612,9 +1613,9 @@ def old_parse(self, *args, **kwargs):
|
|||
size = 3
|
||||
script_pointer = calculate_pointer_from_bytes_at(start_address+1, bank=False)
|
||||
if debug:
|
||||
print "in script starting at "+hex(original_start_address)+\
|
||||
print("in script starting at "+hex(original_start_address)+\
|
||||
" about to parse script at "+hex(script_pointer)+\
|
||||
" called by "+info+" byte="+hex(command_byte)
|
||||
" called by "+info+" byte="+hex(command_byte))
|
||||
script = rec_parse_script_engine_script_at(script_pointer, original_start_address, debug=debug)
|
||||
command["script_pointer"] = script_pointer
|
||||
command["script"] = script
|
||||
|
|
@ -1854,7 +1855,7 @@ def old_parse(self, *args, **kwargs):
|
|||
size = 1
|
||||
#end = True
|
||||
#raise NotImplementedError, "command byte is " + hex(command_byte) + " at " + hex(offset) + " on map " + str(map_group) + "." + str(map_id)
|
||||
print "dunno what this command is: " + hex(command_byte)
|
||||
print("dunno what this command is: " + hex(command_byte))
|
||||
long_info = clean_up_long_info(long_info)
|
||||
|
||||
if command_byte in pksv_crystal.keys():
|
||||
|
|
@ -1867,7 +1868,7 @@ def old_parse(self, *args, **kwargs):
|
|||
pksv_no_names[command_byte] = [address]
|
||||
|
||||
if debug:
|
||||
print command_debug_information(command_byte=command_byte, map_group=map_group, map_id=map_id, address=offset, info=info, long_info=long_info, pksv_name=pksv_name)
|
||||
print(command_debug_information(command_byte=command_byte, map_group=map_group, map_id=map_id, address=offset, info=info, long_info=long_info, pksv_name=pksv_name))
|
||||
|
||||
#store the size of the command
|
||||
command["size"] = size
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
"""
|
||||
An old implementation of TextScript that may not be useful anymore.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import pointers
|
||||
from . import pointers
|
||||
|
||||
class OldTextScript:
|
||||
"a text is a sequence of commands different from a script-engine script"
|
||||
|
|
@ -43,7 +44,7 @@ class OldTextScript:
|
|||
if signpost["func"] in [0, 1, 2, 3, 4]:
|
||||
# dump this into script
|
||||
script = signpost["script"]
|
||||
elif signpost["func"] in [05, 06]:
|
||||
elif signpost["func"] in [0o5, 0o6]:
|
||||
script = signpost["script"]
|
||||
else: continue
|
||||
# skip signposts with no bytes
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import gfx
|
||||
from __future__ import absolute_import
|
||||
from . import gfx
|
||||
|
||||
def rip_sprites_from_bank(bank, offset=0):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
import sys
|
||||
|
||||
import crystal
|
||||
from . import crystal
|
||||
|
||||
rom = crystal.load_rom()
|
||||
|
||||
|
|
@ -16,10 +18,10 @@ for i in range(count):
|
|||
asm = string.to_asm()
|
||||
except Exception as ex:
|
||||
break
|
||||
print label_prefix+str(i)+": ; "+hex(addr)
|
||||
print "\t"+asm
|
||||
print
|
||||
print(label_prefix+str(i)+": ; "+hex(addr))
|
||||
print("\t"+asm)
|
||||
print()
|
||||
addr = string.last_address
|
||||
|
||||
print "; "+hex(addr)
|
||||
print("; "+hex(addr))
|
||||
if ex: raise ex
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
# pcm.py
|
||||
# Converts between .wav files and 1-bit pcm data. (pcm = pulse-code modulation)
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
|
|
@ -72,7 +75,7 @@ def convert_to_pcm(filenames=[]):
|
|||
|
||||
# Pack the 1-bit samples together.
|
||||
packed_samples = bytearray()
|
||||
for i in xrange(0, len(clamped_samples), 8):
|
||||
for i in range(0, len(clamped_samples), 8):
|
||||
# Read 8 pcm values to pack one byte.
|
||||
packed_value = 0
|
||||
for j in range(8):
|
||||
|
|
@ -103,14 +106,14 @@ def get_wav_samples(filename):
|
|||
|
||||
# Unpack the values based on the sample byte width.
|
||||
unpacked_samples = []
|
||||
for i in xrange(0, len(samples), sample_width):
|
||||
for i in range(0, len(samples), sample_width):
|
||||
if sample_width == 1:
|
||||
fmt = 'B'
|
||||
elif sample_width == 2:
|
||||
fmt = 'h'
|
||||
else:
|
||||
# todo: support 3-byte sample width
|
||||
raise Exception, "Unsupported sample width: " + str(sample_width)
|
||||
raise Exception("Unsupported sample width: " + str(sample_width))
|
||||
|
||||
value = struct.unpack(fmt, samples[i:i + sample_width])[0]
|
||||
unpacked_samples.append(value)
|
||||
|
|
@ -122,7 +125,7 @@ def get_wav_samples(filename):
|
|||
# Also find the average amplitude of the samples.
|
||||
resampled_samples = []
|
||||
total_value = 0
|
||||
interval = float(sample_rate) / BASE_SAMPLE_RATE
|
||||
interval = sample_rate / BASE_SAMPLE_RATE
|
||||
index = 0
|
||||
while index < sample_count:
|
||||
sample = unpacked_samples[int(index)]
|
||||
|
|
@ -131,7 +134,7 @@ def get_wav_samples(filename):
|
|||
resampled_samples.append(sample)
|
||||
index += interval
|
||||
|
||||
average_sample = float(total_value) / len(resampled_samples)
|
||||
average_sample = total_value / len(resampled_samples)
|
||||
|
||||
return resampled_samples, average_sample
|
||||
|
||||
|
|
@ -148,7 +151,7 @@ def main():
|
|||
}.get(args.mode, None)
|
||||
|
||||
if method == None:
|
||||
raise Exception, "Unknown conversion method!"
|
||||
raise Exception("Unknown conversion method!")
|
||||
|
||||
method(args.filenames)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@
|
|||
"""
|
||||
A library for use with compressed monster and trainer pics in pokered.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from math import sqrt
|
||||
|
||||
from gfx import transpose_tiles
|
||||
from .gfx import transpose_tiles
|
||||
|
||||
|
||||
def bitflip(x, n):
|
||||
|
|
@ -28,14 +30,14 @@ class Decompressor:
|
|||
Ported to python 2.7 from the python 3 code at https://github.com/magical/pokemon-sprites-rby.
|
||||
"""
|
||||
|
||||
table1 = [(2 << i) - 1 for i in xrange(16)]
|
||||
table1 = [(2 << i) - 1 for i in range(16)]
|
||||
table2 = [
|
||||
[0x0, 0x1, 0x3, 0x2, 0x7, 0x6, 0x4, 0x5, 0xf, 0xe, 0xc, 0xd, 0x8, 0x9, 0xb, 0xa],
|
||||
[0xf, 0xe, 0xc, 0xd, 0x8, 0x9, 0xb, 0xa, 0x0, 0x1, 0x3, 0x2, 0x7, 0x6, 0x4, 0x5], # prev ^ 0xf
|
||||
[0x0, 0x8, 0xc, 0x4, 0xe, 0x6, 0x2, 0xa, 0xf, 0x7, 0x3, 0xb, 0x1, 0x9, 0xd, 0x5],
|
||||
[0xf, 0x7, 0x3, 0xb, 0x1, 0x9, 0xd, 0x5, 0x0, 0x8, 0xc, 0x4, 0xe, 0x6, 0x2, 0xa], # prev ^ 0xf
|
||||
]
|
||||
table3 = [bitflip(i, 4) for i in xrange(16)]
|
||||
table3 = [bitflip(i, 4) for i in range(16)]
|
||||
|
||||
tilesize = 8
|
||||
|
||||
|
|
@ -79,7 +81,7 @@ class Decompressor:
|
|||
self._decode(rams[r1])
|
||||
self._xor(rams[r1], rams[r2])
|
||||
else:
|
||||
raise Exception, "Invalid deinterlace mode!"
|
||||
raise Exception("Invalid deinterlace mode!")
|
||||
|
||||
data = []
|
||||
if self.planar:
|
||||
|
|
@ -117,7 +119,7 @@ class Decompressor:
|
|||
a = self._readint(i + 1)
|
||||
n += a
|
||||
|
||||
for i in xrange(n):
|
||||
for i in range(n):
|
||||
ram.append(0)
|
||||
|
||||
def _read_data_chunk(self, ram, size):
|
||||
|
|
@ -134,9 +136,9 @@ class Decompressor:
|
|||
if mirror is None:
|
||||
mirror = self.mirror
|
||||
|
||||
for x in xrange(self.sizex):
|
||||
for x in range(self.sizex):
|
||||
bit = 0
|
||||
for y in xrange(self.sizey):
|
||||
for y in range(self.sizey):
|
||||
i = y * self.sizex + x
|
||||
a = (ram[i] >> 4) & 0xf
|
||||
b = ram[i] & 0xf
|
||||
|
|
@ -157,7 +159,7 @@ class Decompressor:
|
|||
if mirror is None:
|
||||
mirror = self.mirror
|
||||
|
||||
for i in xrange(len(ram2)):
|
||||
for i in range(len(ram2)):
|
||||
if mirror:
|
||||
a = (ram2[i] >> 4) & 0xf
|
||||
b = ram2[i] & 0xf
|
||||
|
|
@ -169,10 +171,10 @@ class Decompressor:
|
|||
|
||||
def _deinterlace_bitgroups(self, bits):
|
||||
l = []
|
||||
for y in xrange(self.sizey):
|
||||
for x in xrange(self.sizex):
|
||||
for y in range(self.sizey):
|
||||
for x in range(self.sizex):
|
||||
i = 4 * y * self.sizex + x
|
||||
for j in xrange(4):
|
||||
for j in range(4):
|
||||
l.append(bits[i])
|
||||
i += self.sizex
|
||||
return l
|
||||
|
|
@ -192,12 +194,12 @@ def fbitstream(f):
|
|||
break
|
||||
byte = ord(char)
|
||||
|
||||
for i in xrange(7, -1, -1):
|
||||
for i in range(7, -1, -1):
|
||||
yield (byte >> i) & 1
|
||||
|
||||
def bitstream(b):
|
||||
for byte in b:
|
||||
for i in xrange(7, -1, -1):
|
||||
for i in range(7, -1, -1):
|
||||
yield (byte >> i) & 1
|
||||
|
||||
def readint(bs, count):
|
||||
|
|
@ -210,7 +212,7 @@ def readint(bs, count):
|
|||
|
||||
def bitgroups_to_bytes(bits):
|
||||
l = []
|
||||
for i in xrange(0, len(bits) - 3, 4):
|
||||
for i in range(0, len(bits) - 3, 4):
|
||||
n = ((bits[i + 0] << 6)
|
||||
| (bits[i + 1] << 4)
|
||||
| (bits[i + 2] << 2)
|
||||
|
|
@ -230,21 +232,21 @@ class Compressor:
|
|||
Adapted from stag019's C compressor.
|
||||
"""
|
||||
|
||||
table1 = [(2 << i) - 1 for i in xrange(16)]
|
||||
table1 = [(2 << i) - 1 for i in range(16)]
|
||||
table2 = [
|
||||
[0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4, 0xc, 0xd, 0xf, 0xe, 0xa, 0xb, 0x9, 0x8],
|
||||
[0x8, 0x9, 0xb, 0xa, 0xe, 0xf, 0xd, 0xc, 0x4, 0x5, 0x7, 0x6, 0x2, 0x3, 0x1, 0x0], # reverse
|
||||
]
|
||||
table3 = [bitflip(i, 4) for i in xrange(16)]
|
||||
table3 = [bitflip(i, 4) for i in range(16)]
|
||||
|
||||
def __init__(self, image, width=None, height=None):
|
||||
self.image = bytearray(image)
|
||||
self.size = len(self.image)
|
||||
|
||||
planar_tile = 8 * 8 / 4
|
||||
tile_size = self.size / planar_tile
|
||||
if height and not width: width = tile_size / height
|
||||
elif width and not height: height = tile_size / width
|
||||
planar_tile = 8 * 8 // 4
|
||||
tile_size = self.size // planar_tile
|
||||
if height and not width: width = tile_size // height
|
||||
elif width and not height: height = tile_size // width
|
||||
elif not width and not height: width = height = int(sqrt(tile_size))
|
||||
self.width, self.height = width, height
|
||||
|
||||
|
|
@ -256,7 +258,7 @@ class Compressor:
|
|||
rams = [[],[]]
|
||||
datas = []
|
||||
|
||||
for mode in xrange(3):
|
||||
for mode in range(3):
|
||||
|
||||
# Order is redundant for mode 0.
|
||||
|
||||
|
|
@ -269,16 +271,16 @@ class Compressor:
|
|||
|
||||
# Using order 0 instead of 1 breaks this feature.
|
||||
|
||||
for order in xrange(2):
|
||||
for order in range(2):
|
||||
if mode == 0 and order == 0:
|
||||
continue
|
||||
for i in xrange(2):
|
||||
for i in range(2):
|
||||
rams[i] = self.image[i::2]
|
||||
self._interpret_compress(rams, mode, order)
|
||||
datas += [(self.data[:], int(self.which_bit))]
|
||||
|
||||
# Pick the smallest pic, measured in bits.
|
||||
datas = sorted(datas, key=lambda (data, bit): (len(data), -bit))
|
||||
datas = sorted(datas, key=lambda data_bit: (len(data_bit[0]), -data_bit[1]))
|
||||
self.data, self.which_bit = datas[0]
|
||||
|
||||
def _interpret_compress(self, rams, mode, order):
|
||||
|
|
@ -299,7 +301,7 @@ class Compressor:
|
|||
self._encode(rams[r1])
|
||||
self._encode(rams[r2], mirror=False)
|
||||
else:
|
||||
raise Exception, 'invalid interlace mode!'
|
||||
raise Exception('invalid interlace mode!')
|
||||
|
||||
self._writeint(self.height, 4)
|
||||
self._writeint(self.width, 4)
|
||||
|
|
@ -319,10 +321,10 @@ class Compressor:
|
|||
nums = 0
|
||||
bitgroups = []
|
||||
|
||||
for x in xrange(self.width):
|
||||
for bit in xrange(0, 8, 2):
|
||||
for x in range(self.width):
|
||||
for bit in range(0, 8, 2):
|
||||
byte = x * self.height * 8
|
||||
for y in xrange(self.height * 8):
|
||||
for y in range(self.height * 8):
|
||||
bitgroup = (ram[byte] >> (6 - bit)) & 3
|
||||
if bitgroup == 0:
|
||||
if rle == 0:
|
||||
|
|
@ -377,16 +379,16 @@ class Compressor:
|
|||
v >>= 1
|
||||
bitcount += 1
|
||||
|
||||
for j in xrange(bitcount):
|
||||
for j in range(bitcount):
|
||||
self._writebit(1)
|
||||
self._writebit(0)
|
||||
for j in xrange(bitcount, -1, -1):
|
||||
for j in range(bitcount, -1, -1):
|
||||
self._writebit((number >> j) & 1)
|
||||
|
||||
def _encode(self, ram, mirror=None):
|
||||
a = b = 0
|
||||
for i in xrange(len(ram)):
|
||||
j = i / self.height
|
||||
for i in range(len(ram)):
|
||||
j = i // self.height
|
||||
j += i % self.height * self.width * 8
|
||||
if i % self.height == 0:
|
||||
b = 0
|
||||
|
|
@ -402,7 +404,7 @@ class Compressor:
|
|||
ram[j] = (code_1 << 4) | code_2
|
||||
|
||||
def _xor(self, ram1, ram2):
|
||||
for i in xrange(len(ram2)):
|
||||
for i in range(len(ram2)):
|
||||
ram2[i] ^= ram1[i]
|
||||
|
||||
def _writebit(self, bit):
|
||||
|
|
@ -415,7 +417,7 @@ class Compressor:
|
|||
def _writeint(self, num, size=None):
|
||||
bits = []
|
||||
if size:
|
||||
for i in xrange(size):
|
||||
for i in range(size):
|
||||
bits += [num & 1]
|
||||
num >>= 1
|
||||
else:
|
||||
|
|
@ -468,7 +470,7 @@ def compress_file(filename):
|
|||
pic = bytearray(pic)
|
||||
output_filename = os.path.splitext(filename)[0] + '.pic'
|
||||
with open(output_filename, 'wb') as out:
|
||||
out.write(pic)
|
||||
out.write(pic)
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
"""
|
||||
Basic preprocessor for both pokecrystal and pokered.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import exceptions
|
||||
import crystal
|
||||
from . import exceptions
|
||||
from . import crystal
|
||||
|
||||
chars = {
|
||||
"ガ": 0x05,
|
||||
|
|
@ -565,11 +566,11 @@ class Preprocessor(object):
|
|||
if show_original_lines:
|
||||
sys.stdout.write("; original_line: " + original_line)
|
||||
|
||||
# rgbasm can handle other macros too
|
||||
# rgbasm can handle other macros too
|
||||
if "is_rgbasm_macro" in dir(macro):
|
||||
if macro.is_rgbasm_macro:
|
||||
sys.stdout.write(original_line)
|
||||
return
|
||||
return
|
||||
|
||||
# certain macros don't need an initial byte written
|
||||
# do: all scripting macros
|
||||
|
|
|
|||
|
|
@ -1,316 +1,317 @@
|
|||
import configuration
|
||||
config = configuration.Config()
|
||||
rom = bytearray(open(config.rom_path, "r").read())
|
||||
|
||||
songs = [
|
||||
"PalletTown",
|
||||
"Pokecenter",
|
||||
"Gym",
|
||||
"Cities1",
|
||||
"Cities2",
|
||||
"Celadon",
|
||||
"Cinnabar",
|
||||
"Vermilion",
|
||||
"Lavender",
|
||||
"SSAnne",
|
||||
"MeetProfOak",
|
||||
"MeetRival",
|
||||
"MuseumGuy",
|
||||
"SafariZone",
|
||||
"PkmnHealed",
|
||||
"Routes1",
|
||||
"Routes2",
|
||||
"Routes3",
|
||||
"Routes4",
|
||||
"IndigoPlateau",
|
||||
"GymLeaderBattle",
|
||||
"TrainerBattle",
|
||||
"WildBattle",
|
||||
"FinalBattle",
|
||||
"DefeatedTrainer",
|
||||
"DefeatedWildMon",
|
||||
"DefeatedGymLeader",
|
||||
"TitleScreen",
|
||||
"Credits",
|
||||
"HallOfFame",
|
||||
"OaksLab",
|
||||
"JigglypuffSong",
|
||||
"BikeRiding",
|
||||
"Surfing",
|
||||
"GameCorner",
|
||||
"IntroBattle",
|
||||
"Dungeon1",
|
||||
"Dungeon2",
|
||||
"Dungeon3",
|
||||
"CinnabarMansion",
|
||||
"PokemonTower",
|
||||
"SilphCo",
|
||||
"MeetEvilTrainer",
|
||||
"MeetFemaleTrainer",
|
||||
"MeetMaleTrainer",
|
||||
"UnusedSong",
|
||||
]
|
||||
"""
|
||||
songs = [
|
||||
"YellowIntro",
|
||||
"SurfingPikachu",
|
||||
"MeetJessieJames",
|
||||
"YellowUnusedSong",
|
||||
]
|
||||
"""
|
||||
music_commands = {
|
||||
0xd0: ["notetype", {"type": "nibble"}, 2],
|
||||
0xe0: ["octave", 1],
|
||||
0xe8: ["toggleperfectpitch", 1],
|
||||
0xea: ["vibrato", {"type": "byte"}, {"type": "nibble"}, 3],
|
||||
0xeb: ["pitchbend", {"type": "byte"}, {"type": "byte"}, 3],
|
||||
0xec: ["duty", {"type": "byte"}, 2],
|
||||
0xed: ["tempo", {"type": "word"}, 3],
|
||||
0xee: ["stereopanning", {"type": "byte"}, 2],
|
||||
0xf0: ["volume", {"type": "nibble"}, 2],
|
||||
0xf8: ["executemusic", 1],
|
||||
0xfc: ["dutycycle", {"type": "byte"}, 2],
|
||||
0xfd: ["callchannel", {"type": "label"}, 3],
|
||||
0xfe: ["loopchannel", {"type": "byte"}, {"type": "label"}, 4],
|
||||
0xff: ["endchannel", 1],
|
||||
}
|
||||
|
||||
param_lengths = {
|
||||
"nibble": 1,
|
||||
"byte": 1,
|
||||
"word": 2,
|
||||
"label": 2,
|
||||
}
|
||||
|
||||
music_notes = {
|
||||
0x0: "C_",
|
||||
0x1: "C#",
|
||||
0x2: "D_",
|
||||
0x3: "D#",
|
||||
0x4: "E_",
|
||||
0x5: "F_",
|
||||
0x6: "F#",
|
||||
0x7: "G_",
|
||||
0x8: "G#",
|
||||
0x9: "A_",
|
||||
0xa: "A#",
|
||||
0xb: "B_",
|
||||
}
|
||||
|
||||
def printnoisechannel(songname, songfile, startingaddress, bank, output):
|
||||
noise_commands = {
|
||||
0xfd: ["callchannel", {"type": "label"}, 3],
|
||||
0xfe: ["loopchannel", {"type": "byte"}, {"type": "label"}, 4],
|
||||
0xff: ["endchannel", 1],
|
||||
}
|
||||
|
||||
noise_instruments = {
|
||||
0x01: "snare1",
|
||||
0x02: "snare2",
|
||||
0x03: "snare3",
|
||||
0x04: "snare4",
|
||||
0x05: "snare5",
|
||||
0x06: "triangle1",
|
||||
0x07: "triangle2",
|
||||
0x08: "snare6",
|
||||
0x09: "snare7",
|
||||
0x0a: "snare8",
|
||||
0x0b: "snare9",
|
||||
0x0c: "cymbal1",
|
||||
0x0d: "cymbal2",
|
||||
0x0e: "cymbal3",
|
||||
0x0f: "mutedsnare1",
|
||||
0x10: "triangle3",
|
||||
0x11: "mutedsnare2",
|
||||
0x12: "mutedsnare3",
|
||||
0x13: "mutedsnare4",
|
||||
}
|
||||
|
||||
# pass 1, build a list of all addresses pointed to by calls and loops
|
||||
address = startingaddress
|
||||
labels = []
|
||||
labelsleft= []
|
||||
while 1:
|
||||
byte = rom[address]
|
||||
if byte < 0xc0:
|
||||
command_length = 2
|
||||
elif byte < 0xe0:
|
||||
command_length = 1
|
||||
else:
|
||||
command_length = noise_commands[byte][-1]
|
||||
if byte == 0xfd or byte == 0xfe:
|
||||
label = rom[address + command_length - 1] * 0x100 + rom[address + command_length - 2]
|
||||
labels.append(label)
|
||||
if label > address % 0x4000 + 0x4000: labelsleft.append(label)
|
||||
address += command_length
|
||||
if len(labelsleft) == 0 and (byte == 0xfe and rom[address - command_length + 1] == 0 and rom[address - 1] * 0x100 + rom[address - 2] < address % 0x4000 + 0x4000 or byte == 0xff): break
|
||||
while address % 0x4000 + 0x4000 in labelsleft: labelsleft.remove(address % 0x4000 + 0x4000)
|
||||
# once the loop ends, start over from first address
|
||||
if rom[address] == 0xff: address += 1
|
||||
end = address
|
||||
address = startingaddress
|
||||
byte = rom[address]
|
||||
output += "Music_{}_Ch4:: ; {:02x} ({:0x}:{:02x})\n".format(songname, address, bank, address % 0x4000 + 0x4000)
|
||||
# pass 2, print commands and labels for addresses that are in labels
|
||||
while address != end:
|
||||
if address % 0x4000 + 0x4000 in labels and address != startingaddress:
|
||||
output += "\nMusic_{}_branch_{:02x}::\n".format(songname, address)
|
||||
if byte < 0xc0:
|
||||
output += "\t{} {}".format(noise_instruments[rom[address + 1]], byte % 0x10 + 1)
|
||||
command_length = 2
|
||||
elif byte < 0xd0:
|
||||
output += "\trest {}".format(byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
elif byte < 0xe0:
|
||||
output += "\tdspeed {}".format(byte % 0x10)
|
||||
command_length = 1
|
||||
else:
|
||||
command = noise_commands[byte]
|
||||
output += "\t{}".format(command[0])
|
||||
command_length = 1
|
||||
params = 1
|
||||
# print all params for current command
|
||||
while params != len(noise_commands[byte]) - 1:
|
||||
param_type = noise_commands[byte][params]["type"]
|
||||
address += command_length
|
||||
command_length = param_lengths[param_type]
|
||||
param = rom[address]
|
||||
if param_type == "byte":
|
||||
output += " {}".format(param)
|
||||
else:
|
||||
param += rom[address + 1] * 0x100 - 0x4000 + (bank * 0x4000)
|
||||
if param == startingaddress: output += " Music_{}_Ch4".format(songname)
|
||||
else: output += " Music_{}_branch_{:02x}".format(songname, param)
|
||||
params += 1
|
||||
if params != len(noise_commands[byte]) - 1: output += ","
|
||||
output += "\n"
|
||||
address += command_length
|
||||
byte = rom[address]
|
||||
output += "; {}\n".format(hex(address))
|
||||
songfile.write(output)
|
||||
|
||||
for i, songname in enumerate(songs):
|
||||
songfile = open("music/" + songname.lower() + ".asm", 'a')
|
||||
if songname == "PalletTown": header = 0x822e
|
||||
if songname == "GymLeaderBattle": header = 0x202be
|
||||
if songname == "TitleScreen": header = 0x7c249
|
||||
if songname == "YellowIntro": header = 0x7c294
|
||||
if songname == "SurfingPikachu": header = 0x801cb
|
||||
bank = header / 0x4000
|
||||
startingaddress = rom[header + 2] * 0x100 + rom[header + 1] - 0x4000 + (0x4000 * bank)
|
||||
curchannel = 1
|
||||
lastchannel = (rom[header] >> 6) + 1
|
||||
exception = False
|
||||
if songname == "MeetRival" or songname == "Cities1":
|
||||
startingaddress -= 7
|
||||
exception = True
|
||||
if songname == "UnusedSong":
|
||||
bank = 2
|
||||
startingaddress = 0xa913
|
||||
lastchannel = 2
|
||||
output = ''
|
||||
while 1:
|
||||
# pass 1, build a list of all addresses pointed to by calls and loops
|
||||
address = startingaddress
|
||||
labels = []
|
||||
labelsleft = []
|
||||
if songname == "MeetRival":
|
||||
if curchannel == 1:
|
||||
labels.append(0x719b)
|
||||
labelsleft.append(0x719b)
|
||||
labels.append(0x71a2)
|
||||
labelsleft.append(0x71a2)
|
||||
if curchannel == 2:
|
||||
labels.append(0x721d)
|
||||
labelsleft.append(0x721d)
|
||||
if curchannel == 3:
|
||||
labels.append(0x72b5)
|
||||
labelsleft.append(0x72b5)
|
||||
while 1:
|
||||
byte = rom[address]
|
||||
if byte < 0xd0:
|
||||
command_length = 1
|
||||
elif byte < 0xe0:
|
||||
command_length = 2
|
||||
elif byte < 0xe8:
|
||||
command_length = 1
|
||||
else:
|
||||
command_length = music_commands[byte][-1]
|
||||
if byte == 0xfd or byte == 0xfe:
|
||||
label = rom[address + command_length - 1] * 0x100 + rom[address + command_length - 2]
|
||||
labels.append(label)
|
||||
if label > address % 0x4000 + 0x4000: labelsleft.append(label)
|
||||
address += command_length
|
||||
if len(labelsleft) == 0 and (exception == False or address > startingaddress + 7) and (byte == 0xfe and rom[address - command_length + 1] == 0 and rom[address - 1] * 0x100 + rom[address - 2] < address % 0x4000 + 0x4000 or byte == 0xff): break
|
||||
while address % 0x4000 + 0x4000 in labelsleft: labelsleft.remove(address % 0x4000 + 0x4000)
|
||||
# once the loop breaks, start over from first address
|
||||
if rom[address] == 0xff: address += 1
|
||||
end = address
|
||||
if curchannel != lastchannel and songname != "UnusedSong": end = rom[header + 5] * 0x100 + rom[header + 4] + (0x4000 * (bank - 1))
|
||||
address = startingaddress
|
||||
byte = rom[address]
|
||||
# if song has an alternate start to channel 1, print a label and set startingaddress to true channel start
|
||||
if exception:
|
||||
output += "Music_{}_branch_{:02x}::\n".format(songname, address)
|
||||
startingaddress += 7
|
||||
# pass 2, print commands and labels for addresses that are in labels
|
||||
while address != end:
|
||||
if address == startingaddress:
|
||||
if exception: output += "\n"
|
||||
output += "Music_{}_Ch{}:: ; {:02x} ({:0x}:{:02x})\n".format(songname, curchannel, address, bank, address % 0x4000 + 0x4000)
|
||||
elif address % 0x4000 + 0x4000 in labels:
|
||||
output += "\nMusic_{}_branch_{:02x}::\n".format(songname, address)
|
||||
if byte < 0xc0:
|
||||
output += "\t{} {}".format(music_notes[byte >> 4], byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
elif byte < 0xd0:
|
||||
output += "\trest {}".format(byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
else:
|
||||
if byte < 0xe0:
|
||||
command = music_commands[0xd0]
|
||||
output += "\t{} {},".format(command[0], byte % 0x10)
|
||||
byte = 0xd0
|
||||
elif byte < 0xe8:
|
||||
command = music_commands[0xe0]
|
||||
output += "\t{} {}".format(command[0], 0xe8 - byte)
|
||||
byte = 0xe0
|
||||
else:
|
||||
command = music_commands[byte]
|
||||
output += "\t{}".format(command[0])
|
||||
command_length = 1
|
||||
params = 1
|
||||
# print all params for current command
|
||||
while params != len(music_commands[byte]) - 1:
|
||||
param_type = music_commands[byte][params]["type"]
|
||||
address += command_length
|
||||
command_length = param_lengths[param_type]
|
||||
param = rom[address]
|
||||
if param_type == "nibble":
|
||||
output += " {}, {}".format(param >> 4, param % 0x10)
|
||||
elif param_type == "byte":
|
||||
output += " {}".format(param)
|
||||
elif param_type == "word":
|
||||
output += " {}".format(param * 0x100 + rom[address + 1])
|
||||
else:
|
||||
param += rom[address + 1] * 0x100 - 0x4000 + (bank * 0x4000)
|
||||
if param == startingaddress: output += " Music_{}_Ch{}".format(songname, curchannel)
|
||||
else: output += " Music_{}_branch_{:02x}".format(songname, param)
|
||||
params += 1
|
||||
if params != len(music_commands[byte]) - 1: output += ","
|
||||
output += "\n"
|
||||
address += command_length
|
||||
byte = rom[address]
|
||||
header += 3
|
||||
if curchannel == lastchannel:
|
||||
output += "; {}\n".format(hex(address))
|
||||
songfile.write(output)
|
||||
break
|
||||
curchannel += 1
|
||||
output += "\n\n"
|
||||
startingaddress = end
|
||||
exception = False
|
||||
if curchannel == 4:
|
||||
printnoisechannel(songname, songfile, startingaddress, bank, output)
|
||||
header += 3
|
||||
from __future__ import absolute_import
|
||||
from . import configuration
|
||||
config = configuration.Config()
|
||||
rom = bytearray(open(config.rom_path, "r").read())
|
||||
|
||||
songs = [
|
||||
"PalletTown",
|
||||
"Pokecenter",
|
||||
"Gym",
|
||||
"Cities1",
|
||||
"Cities2",
|
||||
"Celadon",
|
||||
"Cinnabar",
|
||||
"Vermilion",
|
||||
"Lavender",
|
||||
"SSAnne",
|
||||
"MeetProfOak",
|
||||
"MeetRival",
|
||||
"MuseumGuy",
|
||||
"SafariZone",
|
||||
"PkmnHealed",
|
||||
"Routes1",
|
||||
"Routes2",
|
||||
"Routes3",
|
||||
"Routes4",
|
||||
"IndigoPlateau",
|
||||
"GymLeaderBattle",
|
||||
"TrainerBattle",
|
||||
"WildBattle",
|
||||
"FinalBattle",
|
||||
"DefeatedTrainer",
|
||||
"DefeatedWildMon",
|
||||
"DefeatedGymLeader",
|
||||
"TitleScreen",
|
||||
"Credits",
|
||||
"HallOfFame",
|
||||
"OaksLab",
|
||||
"JigglypuffSong",
|
||||
"BikeRiding",
|
||||
"Surfing",
|
||||
"GameCorner",
|
||||
"IntroBattle",
|
||||
"Dungeon1",
|
||||
"Dungeon2",
|
||||
"Dungeon3",
|
||||
"CinnabarMansion",
|
||||
"PokemonTower",
|
||||
"SilphCo",
|
||||
"MeetEvilTrainer",
|
||||
"MeetFemaleTrainer",
|
||||
"MeetMaleTrainer",
|
||||
"UnusedSong",
|
||||
]
|
||||
"""
|
||||
songs = [
|
||||
"YellowIntro",
|
||||
"SurfingPikachu",
|
||||
"MeetJessieJames",
|
||||
"YellowUnusedSong",
|
||||
]
|
||||
"""
|
||||
music_commands = {
|
||||
0xd0: ["notetype", {"type": "nibble"}, 2],
|
||||
0xe0: ["octave", 1],
|
||||
0xe8: ["toggleperfectpitch", 1],
|
||||
0xea: ["vibrato", {"type": "byte"}, {"type": "nibble"}, 3],
|
||||
0xeb: ["pitchbend", {"type": "byte"}, {"type": "byte"}, 3],
|
||||
0xec: ["duty", {"type": "byte"}, 2],
|
||||
0xed: ["tempo", {"type": "word"}, 3],
|
||||
0xee: ["stereopanning", {"type": "byte"}, 2],
|
||||
0xf0: ["volume", {"type": "nibble"}, 2],
|
||||
0xf8: ["executemusic", 1],
|
||||
0xfc: ["dutycycle", {"type": "byte"}, 2],
|
||||
0xfd: ["callchannel", {"type": "label"}, 3],
|
||||
0xfe: ["loopchannel", {"type": "byte"}, {"type": "label"}, 4],
|
||||
0xff: ["endchannel", 1],
|
||||
}
|
||||
|
||||
param_lengths = {
|
||||
"nibble": 1,
|
||||
"byte": 1,
|
||||
"word": 2,
|
||||
"label": 2,
|
||||
}
|
||||
|
||||
music_notes = {
|
||||
0x0: "C_",
|
||||
0x1: "C#",
|
||||
0x2: "D_",
|
||||
0x3: "D#",
|
||||
0x4: "E_",
|
||||
0x5: "F_",
|
||||
0x6: "F#",
|
||||
0x7: "G_",
|
||||
0x8: "G#",
|
||||
0x9: "A_",
|
||||
0xa: "A#",
|
||||
0xb: "B_",
|
||||
}
|
||||
|
||||
def printnoisechannel(songname, songfile, startingaddress, bank, output):
|
||||
noise_commands = {
|
||||
0xfd: ["callchannel", {"type": "label"}, 3],
|
||||
0xfe: ["loopchannel", {"type": "byte"}, {"type": "label"}, 4],
|
||||
0xff: ["endchannel", 1],
|
||||
}
|
||||
|
||||
noise_instruments = {
|
||||
0x01: "snare1",
|
||||
0x02: "snare2",
|
||||
0x03: "snare3",
|
||||
0x04: "snare4",
|
||||
0x05: "snare5",
|
||||
0x06: "triangle1",
|
||||
0x07: "triangle2",
|
||||
0x08: "snare6",
|
||||
0x09: "snare7",
|
||||
0x0a: "snare8",
|
||||
0x0b: "snare9",
|
||||
0x0c: "cymbal1",
|
||||
0x0d: "cymbal2",
|
||||
0x0e: "cymbal3",
|
||||
0x0f: "mutedsnare1",
|
||||
0x10: "triangle3",
|
||||
0x11: "mutedsnare2",
|
||||
0x12: "mutedsnare3",
|
||||
0x13: "mutedsnare4",
|
||||
}
|
||||
|
||||
# pass 1, build a list of all addresses pointed to by calls and loops
|
||||
address = startingaddress
|
||||
labels = []
|
||||
labelsleft= []
|
||||
while 1:
|
||||
byte = rom[address]
|
||||
if byte < 0xc0:
|
||||
command_length = 2
|
||||
elif byte < 0xe0:
|
||||
command_length = 1
|
||||
else:
|
||||
command_length = noise_commands[byte][-1]
|
||||
if byte == 0xfd or byte == 0xfe:
|
||||
label = rom[address + command_length - 1] * 0x100 + rom[address + command_length - 2]
|
||||
labels.append(label)
|
||||
if label > address % 0x4000 + 0x4000: labelsleft.append(label)
|
||||
address += command_length
|
||||
if len(labelsleft) == 0 and (byte == 0xfe and rom[address - command_length + 1] == 0 and rom[address - 1] * 0x100 + rom[address - 2] < address % 0x4000 + 0x4000 or byte == 0xff): break
|
||||
while address % 0x4000 + 0x4000 in labelsleft: labelsleft.remove(address % 0x4000 + 0x4000)
|
||||
# once the loop ends, start over from first address
|
||||
if rom[address] == 0xff: address += 1
|
||||
end = address
|
||||
address = startingaddress
|
||||
byte = rom[address]
|
||||
output += "Music_{}_Ch4:: ; {:02x} ({:0x}:{:02x})\n".format(songname, address, bank, address % 0x4000 + 0x4000)
|
||||
# pass 2, print commands and labels for addresses that are in labels
|
||||
while address != end:
|
||||
if address % 0x4000 + 0x4000 in labels and address != startingaddress:
|
||||
output += "\nMusic_{}_branch_{:02x}::\n".format(songname, address)
|
||||
if byte < 0xc0:
|
||||
output += "\t{} {}".format(noise_instruments[rom[address + 1]], byte % 0x10 + 1)
|
||||
command_length = 2
|
||||
elif byte < 0xd0:
|
||||
output += "\trest {}".format(byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
elif byte < 0xe0:
|
||||
output += "\tdspeed {}".format(byte % 0x10)
|
||||
command_length = 1
|
||||
else:
|
||||
command = noise_commands[byte]
|
||||
output += "\t{}".format(command[0])
|
||||
command_length = 1
|
||||
params = 1
|
||||
# print all params for current command
|
||||
while params != len(noise_commands[byte]) - 1:
|
||||
param_type = noise_commands[byte][params]["type"]
|
||||
address += command_length
|
||||
command_length = param_lengths[param_type]
|
||||
param = rom[address]
|
||||
if param_type == "byte":
|
||||
output += " {}".format(param)
|
||||
else:
|
||||
param += rom[address + 1] * 0x100 - 0x4000 + (bank * 0x4000)
|
||||
if param == startingaddress: output += " Music_{}_Ch4".format(songname)
|
||||
else: output += " Music_{}_branch_{:02x}".format(songname, param)
|
||||
params += 1
|
||||
if params != len(noise_commands[byte]) - 1: output += ","
|
||||
output += "\n"
|
||||
address += command_length
|
||||
byte = rom[address]
|
||||
output += "; {}\n".format(hex(address))
|
||||
songfile.write(output)
|
||||
|
||||
for i, songname in enumerate(songs):
|
||||
songfile = open("music/" + songname.lower() + ".asm", 'a')
|
||||
if songname == "PalletTown": header = 0x822e
|
||||
if songname == "GymLeaderBattle": header = 0x202be
|
||||
if songname == "TitleScreen": header = 0x7c249
|
||||
if songname == "YellowIntro": header = 0x7c294
|
||||
if songname == "SurfingPikachu": header = 0x801cb
|
||||
bank = header / 0x4000
|
||||
startingaddress = rom[header + 2] * 0x100 + rom[header + 1] - 0x4000 + (0x4000 * bank)
|
||||
curchannel = 1
|
||||
lastchannel = (rom[header] >> 6) + 1
|
||||
exception = False
|
||||
if songname == "MeetRival" or songname == "Cities1":
|
||||
startingaddress -= 7
|
||||
exception = True
|
||||
if songname == "UnusedSong":
|
||||
bank = 2
|
||||
startingaddress = 0xa913
|
||||
lastchannel = 2
|
||||
output = ''
|
||||
while 1:
|
||||
# pass 1, build a list of all addresses pointed to by calls and loops
|
||||
address = startingaddress
|
||||
labels = []
|
||||
labelsleft = []
|
||||
if songname == "MeetRival":
|
||||
if curchannel == 1:
|
||||
labels.append(0x719b)
|
||||
labelsleft.append(0x719b)
|
||||
labels.append(0x71a2)
|
||||
labelsleft.append(0x71a2)
|
||||
if curchannel == 2:
|
||||
labels.append(0x721d)
|
||||
labelsleft.append(0x721d)
|
||||
if curchannel == 3:
|
||||
labels.append(0x72b5)
|
||||
labelsleft.append(0x72b5)
|
||||
while 1:
|
||||
byte = rom[address]
|
||||
if byte < 0xd0:
|
||||
command_length = 1
|
||||
elif byte < 0xe0:
|
||||
command_length = 2
|
||||
elif byte < 0xe8:
|
||||
command_length = 1
|
||||
else:
|
||||
command_length = music_commands[byte][-1]
|
||||
if byte == 0xfd or byte == 0xfe:
|
||||
label = rom[address + command_length - 1] * 0x100 + rom[address + command_length - 2]
|
||||
labels.append(label)
|
||||
if label > address % 0x4000 + 0x4000: labelsleft.append(label)
|
||||
address += command_length
|
||||
if len(labelsleft) == 0 and (exception == False or address > startingaddress + 7) and (byte == 0xfe and rom[address - command_length + 1] == 0 and rom[address - 1] * 0x100 + rom[address - 2] < address % 0x4000 + 0x4000 or byte == 0xff): break
|
||||
while address % 0x4000 + 0x4000 in labelsleft: labelsleft.remove(address % 0x4000 + 0x4000)
|
||||
# once the loop breaks, start over from first address
|
||||
if rom[address] == 0xff: address += 1
|
||||
end = address
|
||||
if curchannel != lastchannel and songname != "UnusedSong": end = rom[header + 5] * 0x100 + rom[header + 4] + (0x4000 * (bank - 1))
|
||||
address = startingaddress
|
||||
byte = rom[address]
|
||||
# if song has an alternate start to channel 1, print a label and set startingaddress to true channel start
|
||||
if exception:
|
||||
output += "Music_{}_branch_{:02x}::\n".format(songname, address)
|
||||
startingaddress += 7
|
||||
# pass 2, print commands and labels for addresses that are in labels
|
||||
while address != end:
|
||||
if address == startingaddress:
|
||||
if exception: output += "\n"
|
||||
output += "Music_{}_Ch{}:: ; {:02x} ({:0x}:{:02x})\n".format(songname, curchannel, address, bank, address % 0x4000 + 0x4000)
|
||||
elif address % 0x4000 + 0x4000 in labels:
|
||||
output += "\nMusic_{}_branch_{:02x}::\n".format(songname, address)
|
||||
if byte < 0xc0:
|
||||
output += "\t{} {}".format(music_notes[byte >> 4], byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
elif byte < 0xd0:
|
||||
output += "\trest {}".format(byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
else:
|
||||
if byte < 0xe0:
|
||||
command = music_commands[0xd0]
|
||||
output += "\t{} {},".format(command[0], byte % 0x10)
|
||||
byte = 0xd0
|
||||
elif byte < 0xe8:
|
||||
command = music_commands[0xe0]
|
||||
output += "\t{} {}".format(command[0], 0xe8 - byte)
|
||||
byte = 0xe0
|
||||
else:
|
||||
command = music_commands[byte]
|
||||
output += "\t{}".format(command[0])
|
||||
command_length = 1
|
||||
params = 1
|
||||
# print all params for current command
|
||||
while params != len(music_commands[byte]) - 1:
|
||||
param_type = music_commands[byte][params]["type"]
|
||||
address += command_length
|
||||
command_length = param_lengths[param_type]
|
||||
param = rom[address]
|
||||
if param_type == "nibble":
|
||||
output += " {}, {}".format(param >> 4, param % 0x10)
|
||||
elif param_type == "byte":
|
||||
output += " {}".format(param)
|
||||
elif param_type == "word":
|
||||
output += " {}".format(param * 0x100 + rom[address + 1])
|
||||
else:
|
||||
param += rom[address + 1] * 0x100 - 0x4000 + (bank * 0x4000)
|
||||
if param == startingaddress: output += " Music_{}_Ch{}".format(songname, curchannel)
|
||||
else: output += " Music_{}_branch_{:02x}".format(songname, param)
|
||||
params += 1
|
||||
if params != len(music_commands[byte]) - 1: output += ","
|
||||
output += "\n"
|
||||
address += command_length
|
||||
byte = rom[address]
|
||||
header += 3
|
||||
if curchannel == lastchannel:
|
||||
output += "; {}\n".format(hex(address))
|
||||
songfile.write(output)
|
||||
break
|
||||
curchannel += 1
|
||||
output += "\n\n"
|
||||
startingaddress = end
|
||||
exception = False
|
||||
if curchannel == 4:
|
||||
printnoisechannel(songname, songfile, startingaddress, bank, output)
|
||||
header += 3
|
||||
break
|
||||
|
|
@ -1,454 +1,456 @@
|
|||
import configuration
|
||||
config = configuration.Config()
|
||||
rom = bytearray(open(config.rom_path, "r").read())
|
||||
|
||||
sfx_names = [
|
||||
"Snare1_2",
|
||||
"Snare2_2",
|
||||
"Snare3_2",
|
||||
"Snare4_2",
|
||||
"Snare5_2",
|
||||
"Triangle1_2",
|
||||
"Triangle2_2",
|
||||
"Snare6_2",
|
||||
"Snare7_2",
|
||||
"Snare8_2",
|
||||
"Snare9_2",
|
||||
"Cymbal1_2",
|
||||
"Cymbal2_2",
|
||||
"Cymbal3_2",
|
||||
"Muted_Snare1_2",
|
||||
"Triangle3_2",
|
||||
"Muted_Snare2_2",
|
||||
"Muted_Snare3_2",
|
||||
"Muted_Snare4_2",
|
||||
"Cry00_2",
|
||||
"Cry01_2",
|
||||
"Cry02_2",
|
||||
"Cry03_2",
|
||||
"Cry04_2",
|
||||
"Cry05_2",
|
||||
"Cry06_2",
|
||||
"Cry07_2",
|
||||
"Cry08_2",
|
||||
"Cry09_2",
|
||||
"Cry0A_2",
|
||||
"Cry0B_2",
|
||||
"Cry0C_2",
|
||||
"Cry0D_2",
|
||||
"Cry0E_2",
|
||||
"Cry0F_2",
|
||||
"Cry10_2",
|
||||
"Cry11_2",
|
||||
"Cry12_2",
|
||||
"Cry13_2",
|
||||
"Cry14_2",
|
||||
"Cry15_2",
|
||||
"Cry16_2",
|
||||
"Cry17_2",
|
||||
"Cry18_2",
|
||||
"Cry19_2",
|
||||
"Cry1A_2",
|
||||
"Cry1B_2",
|
||||
"Cry1C_2",
|
||||
"Cry1D_2",
|
||||
"Cry1E_2",
|
||||
"Cry1F_2",
|
||||
"Cry20_2",
|
||||
"Cry21_2",
|
||||
"Cry22_2",
|
||||
"Cry23_2",
|
||||
"Cry24_2",
|
||||
"Cry25_2",
|
||||
"Level_Up",
|
||||
"Get_Item2_2",
|
||||
"Tink_2",
|
||||
"Heal_HP_2",
|
||||
"Heal_Ailment_2",
|
||||
"Start_Menu_2",
|
||||
"Press_AB_2",
|
||||
"Ball_Toss",
|
||||
"Ball_Poof",
|
||||
"Faint_Thud",
|
||||
"Run",
|
||||
"Dex_Page_Added",
|
||||
"Caught_Mon",
|
||||
"Peck",
|
||||
"Faint_Fall",
|
||||
"Battle_09",
|
||||
"Pound",
|
||||
"Battle_0B",
|
||||
"Battle_0C",
|
||||
"Battle_0D",
|
||||
"Battle_0E",
|
||||
"Battle_0F",
|
||||
"Damage",
|
||||
"Not_Very_Effective",
|
||||
"Battle_12",
|
||||
"Battle_13",
|
||||
"Battle_14",
|
||||
"Vine_Whip",
|
||||
"Battle_16",
|
||||
"Battle_17",
|
||||
"Battle_18",
|
||||
"Battle_19",
|
||||
"Super_Effective",
|
||||
"Battle_1B",
|
||||
"Battle_1C",
|
||||
"Doubleslap",
|
||||
"Battle_1E",
|
||||
"Horn_Drill",
|
||||
"Battle_20",
|
||||
"Battle_21",
|
||||
"Battle_22",
|
||||
"Battle_23",
|
||||
"Battle_24",
|
||||
"Battle_25",
|
||||
"Battle_26",
|
||||
"Battle_27",
|
||||
"Battle_28",
|
||||
"Battle_29",
|
||||
"Battle_2A",
|
||||
"Battle_2B",
|
||||
"Battle_2C",
|
||||
"Psybeam",
|
||||
"Battle_2E",
|
||||
"Battle_2F",
|
||||
"Psychic_M",
|
||||
"Battle_31",
|
||||
"Battle_32",
|
||||
"Battle_33",
|
||||
"Battle_34",
|
||||
"Battle_35",
|
||||
"Battle_36",
|
||||
"Silph_Scope",
|
||||
"Snare1_1",
|
||||
"Snare2_1",
|
||||
"Snare3_1",
|
||||
"Snare4_1",
|
||||
"Snare5_1",
|
||||
"Triangle1_1",
|
||||
"Triangle2_1",
|
||||
"Snare6_1",
|
||||
"Snare7_1",
|
||||
"Snare8_1",
|
||||
"Snare9_1",
|
||||
"Cymbal1_1",
|
||||
"Cymbal2_1",
|
||||
"Cymbal3_1",
|
||||
"Muted_Snare1_1",
|
||||
"Triangle3_1",
|
||||
"Muted_Snare2_1",
|
||||
"Muted_Snare3_1",
|
||||
"Muted_Snare4_1",
|
||||
"Cry00_1",
|
||||
"Cry01_1",
|
||||
"Cry02_1",
|
||||
"Cry03_1",
|
||||
"Cry04_1",
|
||||
"Cry05_1",
|
||||
"Cry06_1",
|
||||
"Cry07_1",
|
||||
"Cry08_1",
|
||||
"Cry09_1",
|
||||
"Cry0A_1",
|
||||
"Cry0B_1",
|
||||
"Cry0C_1",
|
||||
"Cry0D_1",
|
||||
"Cry0E_1",
|
||||
"Cry0F_1",
|
||||
"Cry10_1",
|
||||
"Cry11_1",
|
||||
"Cry12_1",
|
||||
"Cry13_1",
|
||||
"Cry14_1",
|
||||
"Cry15_1",
|
||||
"Cry16_1",
|
||||
"Cry17_1",
|
||||
"Cry18_1",
|
||||
"Cry19_1",
|
||||
"Cry1A_1",
|
||||
"Cry1B_1",
|
||||
"Cry1C_1",
|
||||
"Cry1D_1",
|
||||
"Cry1E_1",
|
||||
"Cry1F_1",
|
||||
"Cry20_1",
|
||||
"Cry21_1",
|
||||
"Cry22_1",
|
||||
"Cry23_1",
|
||||
"Cry24_1",
|
||||
"Cry25_1",
|
||||
"Get_Item1_1",
|
||||
"Get_Item2_1",
|
||||
"Tink_1",
|
||||
"Heal_HP_1",
|
||||
"Heal_Ailment_1",
|
||||
"Start_Menu_1",
|
||||
"Press_AB_1",
|
||||
"Pokedex_Rating_1",
|
||||
"Get_Key_Item_1",
|
||||
"Poisoned_1",
|
||||
"Trade_Machine_1",
|
||||
"Turn_On_PC_1",
|
||||
"Turn_Off_PC_1",
|
||||
"Enter_PC_1",
|
||||
"Shrink_1",
|
||||
"Switch_1",
|
||||
"Healing_Machine_1",
|
||||
"Teleport_Exit1_1",
|
||||
"Teleport_Enter1_1",
|
||||
"Teleport_Exit2_1",
|
||||
"Ledge_1",
|
||||
"Teleport_Enter2_1",
|
||||
"Fly_1",
|
||||
"Denied_1",
|
||||
"Arrow_Tiles_1",
|
||||
"Push_Boulder_1",
|
||||
"SS_Anne_Horn_1",
|
||||
"Withdraw_Deposit_1",
|
||||
"Cut_1",
|
||||
"Go_Inside_1",
|
||||
"Swap_1",
|
||||
"59_1",
|
||||
"Purchase_1",
|
||||
"Collision_1",
|
||||
"Go_Outside_1",
|
||||
"Save_1",
|
||||
"Pokeflute",
|
||||
"Safari_Zone_PA",
|
||||
"Snare1_3",
|
||||
"Snare2_3",
|
||||
"Snare3_3",
|
||||
"Snare4_3",
|
||||
"Snare5_3",
|
||||
"Triangle1_3",
|
||||
"Triangle2_3",
|
||||
"Snare6_3",
|
||||
"Snare7_3",
|
||||
"Snare8_3",
|
||||
"Snare9_3",
|
||||
"Cymbal1_3",
|
||||
"Cymbal2_3",
|
||||
"Cymbal3_3",
|
||||
"Muted_Snare1_3",
|
||||
"Triangle3_3",
|
||||
"Muted_Snare2_3",
|
||||
"Muted_Snare3_3",
|
||||
"Muted_Snare4_3",
|
||||
"Cry00_3",
|
||||
"Cry01_3",
|
||||
"Cry02_3",
|
||||
"Cry03_3",
|
||||
"Cry04_3",
|
||||
"Cry05_3",
|
||||
"Cry06_3",
|
||||
"Cry07_3",
|
||||
"Cry08_3",
|
||||
"Cry09_3",
|
||||
"Cry0A_3",
|
||||
"Cry0B_3",
|
||||
"Cry0C_3",
|
||||
"Cry0D_3",
|
||||
"Cry0E_3",
|
||||
"Cry0F_3",
|
||||
"Cry10_3",
|
||||
"Cry11_3",
|
||||
"Cry12_3",
|
||||
"Cry13_3",
|
||||
"Cry14_3",
|
||||
"Cry15_3",
|
||||
"Cry16_3",
|
||||
"Cry17_3",
|
||||
"Cry18_3",
|
||||
"Cry19_3",
|
||||
"Cry1A_3",
|
||||
"Cry1B_3",
|
||||
"Cry1C_3",
|
||||
"Cry1D_3",
|
||||
"Cry1E_3",
|
||||
"Cry1F_3",
|
||||
"Cry20_3",
|
||||
"Cry21_3",
|
||||
"Cry22_3",
|
||||
"Cry23_3",
|
||||
"Cry24_3",
|
||||
"Cry25_3",
|
||||
"Get_Item1_3",
|
||||
"Get_Item2_3",
|
||||
"Tink_3",
|
||||
"Heal_HP_3",
|
||||
"Heal_Ailment_3",
|
||||
"Start_Menu_3",
|
||||
"Press_AB_3",
|
||||
"Pokedex_Rating_3",
|
||||
"Get_Key_Item_3",
|
||||
"Poisoned_3",
|
||||
"Trade_Machine_3",
|
||||
"Turn_On_PC_3",
|
||||
"Turn_Off_PC_3",
|
||||
"Enter_PC_3",
|
||||
"Shrink_3",
|
||||
"Switch_3",
|
||||
"Healing_Machine_3",
|
||||
"Teleport_Exit1_3",
|
||||
"Teleport_Enter1_3",
|
||||
"Teleport_Exit2_3",
|
||||
"Ledge_3",
|
||||
"Teleport_Enter2_3",
|
||||
"Fly_3",
|
||||
"Denied_3",
|
||||
"Arrow_Tiles_3",
|
||||
"Push_Boulder_3",
|
||||
"SS_Anne_Horn_3",
|
||||
"Withdraw_Deposit_3",
|
||||
"Cut_3",
|
||||
"Go_Inside_3",
|
||||
"Swap_3",
|
||||
"59_3",
|
||||
"Purchase_3",
|
||||
"Collision_3",
|
||||
"Go_Outside_3",
|
||||
"Save_3",
|
||||
"Intro_Lunge",
|
||||
"Intro_Hip",
|
||||
"Intro_Hop",
|
||||
"Intro_Raise",
|
||||
"Intro_Crash",
|
||||
"Intro_Whoosh",
|
||||
"Slots_Stop_Wheel",
|
||||
"Slots_Reward",
|
||||
"Slots_New_Spin",
|
||||
"Shooting_Star",
|
||||
]
|
||||
|
||||
banks = {
|
||||
0x02: 0x60,
|
||||
0x08: 0x78,
|
||||
0x1f: 0x68,
|
||||
}
|
||||
|
||||
music_commands = {
|
||||
0xd0: ["notetype", {"type": "nibble"}, 2],
|
||||
0xe0: ["octave", 1],
|
||||
0xe8: ["toggleperfectpitch", 1],
|
||||
0xea: ["vibrato", {"type": "byte"}, {"type": "nibble"}, 3],
|
||||
0xec: ["duty", {"type": "byte"}, 2],
|
||||
0xed: ["tempo", {"type": "word"}, 3],
|
||||
0xf0: ["volume", {"type": "nibble"}, 2],
|
||||
0xf8: ["executemusic", 1],
|
||||
0xfc: ["dutycycle", {"type": "byte"}, 2],
|
||||
0xfe: ["loopchannel", {"type": "byte"}, {"type": "label"}, 4],
|
||||
0xff: ["endchannel", 1],
|
||||
}
|
||||
|
||||
param_lengths = {
|
||||
"nibble": 1,
|
||||
"byte": 1,
|
||||
"word": 2,
|
||||
"label": 2,
|
||||
}
|
||||
|
||||
music_notes = {
|
||||
0x0: "C_",
|
||||
0x1: "C#",
|
||||
0x2: "D_",
|
||||
0x3: "D#",
|
||||
0x4: "E_",
|
||||
0x5: "F_",
|
||||
0x6: "F#",
|
||||
0x7: "G_",
|
||||
0x8: "G#",
|
||||
0x9: "A_",
|
||||
0xa: "A#",
|
||||
0xb: "B_",
|
||||
}
|
||||
|
||||
sfxnum = 0
|
||||
|
||||
for bank in banks:
|
||||
print bank
|
||||
header = bank * 0x4000 + 3
|
||||
for sfx in range(1,banks[bank]):
|
||||
sfxname = sfx_names[sfxnum]
|
||||
sfxfile = open("music/sfx/" + sfx_names[sfxnum].lower() + ".asm", 'w')
|
||||
sfxname = "SFX_" + sfxname
|
||||
startingaddress = rom[header + 2] * 0x100 + rom[header + 1] + (0x4000 * (bank - 1))
|
||||
end = 0
|
||||
curchannel = 1
|
||||
lastchannel = (rom[header] >> 6) + 1
|
||||
channelnumber = rom[header] % 0x10
|
||||
output = ''
|
||||
while 1:
|
||||
address = startingaddress
|
||||
if curchannel != lastchannel:
|
||||
end = rom[header + 5] * 0x100 + rom[header + 4] + (0x4000 * (bank - 1))
|
||||
byte = rom[address]
|
||||
if byte == 0xf8 or (bank == 2 and sfx == 0x5e): executemusic = True
|
||||
else: executemusic = False
|
||||
output += "{}_Ch{}: ; {:02x} ({:0x}:{:02x})\n".format(sfxname, curchannel, address, bank, address % 0x4000 + 0x4000)
|
||||
while 1:
|
||||
if address == 0x2062a or address == 0x2063d or address == 0x20930:
|
||||
output += "\n{}_branch_{:02x}:\n".format(sfxname, address)
|
||||
if byte == 0x10 and not executemusic:
|
||||
output += "\tunknownsfx0x{:02x} {}".format(byte, rom[address + 1])
|
||||
command_length = 2
|
||||
elif byte < 0x30 and not executemusic:
|
||||
if channelnumber == 7:
|
||||
output += "\tunknownnoise0x20 {}, {}, {}".format(byte % 0x10, rom[address + 1], rom[address + 2])
|
||||
command_length = 3
|
||||
else:
|
||||
output += "\tunknownsfx0x20 {}, {}, {}, {}".format(byte % 0x10, rom[address + 1], rom[address + 2], rom[address + 3])
|
||||
command_length = 4
|
||||
elif byte < 0xc0:
|
||||
output += "\t{} {}".format(music_notes[byte >> 4], byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
elif byte < 0xd0:
|
||||
output += "\trest {}".format(byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
else:
|
||||
if byte < 0xe0:
|
||||
command = music_commands[0xd0]
|
||||
output += "\t{} {},".format(command[0], byte % 0x10)
|
||||
byte = 0xd0
|
||||
elif byte < 0xe8:
|
||||
command = music_commands[0xe0]
|
||||
output += "\t{} {}".format(command[0], 0xe8 - byte)
|
||||
byte = 0xe0
|
||||
else:
|
||||
command = music_commands[byte]
|
||||
output += "\t{}".format(command[0])
|
||||
command_length = 1
|
||||
params = 1
|
||||
# print all params for current command
|
||||
while params != len(music_commands[byte]) - 1:
|
||||
param_type = music_commands[byte][params]["type"]
|
||||
address += command_length
|
||||
command_length = param_lengths[param_type]
|
||||
param = rom[address]
|
||||
if param_type == "nibble":
|
||||
output += " {}, {}".format(param >> 4, param % 0x10)
|
||||
elif param_type == "byte":
|
||||
output += " {}".format(param)
|
||||
elif param_type == "word":
|
||||
output += " {}".format(param * 0x100 + rom[address + 1])
|
||||
else:
|
||||
param += rom[address + 1] * 0x100 - 0x4000 + (bank * 0x4000)
|
||||
if param == startingaddress: output += " {}_Ch{}".format(sfxname, curchannel)
|
||||
else: output += " {}_branch_{:02x}".format(sfxname, param)
|
||||
params += 1
|
||||
if params != len(music_commands[byte]) - 1: output += ","
|
||||
output += "\n"
|
||||
address += command_length
|
||||
if byte == 0xff or address == end: break
|
||||
byte = rom[address]
|
||||
header += 3
|
||||
channelnumber = rom[header]
|
||||
if curchannel == lastchannel:
|
||||
# output += "; {}".format(hex(address))
|
||||
sfxfile.write(output)
|
||||
break
|
||||
output += "\n\n"
|
||||
startingaddress = address
|
||||
curchannel += 1
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from . import configuration
|
||||
config = configuration.Config()
|
||||
rom = bytearray(open(config.rom_path, "r").read())
|
||||
|
||||
sfx_names = [
|
||||
"Snare1_2",
|
||||
"Snare2_2",
|
||||
"Snare3_2",
|
||||
"Snare4_2",
|
||||
"Snare5_2",
|
||||
"Triangle1_2",
|
||||
"Triangle2_2",
|
||||
"Snare6_2",
|
||||
"Snare7_2",
|
||||
"Snare8_2",
|
||||
"Snare9_2",
|
||||
"Cymbal1_2",
|
||||
"Cymbal2_2",
|
||||
"Cymbal3_2",
|
||||
"Muted_Snare1_2",
|
||||
"Triangle3_2",
|
||||
"Muted_Snare2_2",
|
||||
"Muted_Snare3_2",
|
||||
"Muted_Snare4_2",
|
||||
"Cry00_2",
|
||||
"Cry01_2",
|
||||
"Cry02_2",
|
||||
"Cry03_2",
|
||||
"Cry04_2",
|
||||
"Cry05_2",
|
||||
"Cry06_2",
|
||||
"Cry07_2",
|
||||
"Cry08_2",
|
||||
"Cry09_2",
|
||||
"Cry0A_2",
|
||||
"Cry0B_2",
|
||||
"Cry0C_2",
|
||||
"Cry0D_2",
|
||||
"Cry0E_2",
|
||||
"Cry0F_2",
|
||||
"Cry10_2",
|
||||
"Cry11_2",
|
||||
"Cry12_2",
|
||||
"Cry13_2",
|
||||
"Cry14_2",
|
||||
"Cry15_2",
|
||||
"Cry16_2",
|
||||
"Cry17_2",
|
||||
"Cry18_2",
|
||||
"Cry19_2",
|
||||
"Cry1A_2",
|
||||
"Cry1B_2",
|
||||
"Cry1C_2",
|
||||
"Cry1D_2",
|
||||
"Cry1E_2",
|
||||
"Cry1F_2",
|
||||
"Cry20_2",
|
||||
"Cry21_2",
|
||||
"Cry22_2",
|
||||
"Cry23_2",
|
||||
"Cry24_2",
|
||||
"Cry25_2",
|
||||
"Level_Up",
|
||||
"Get_Item2_2",
|
||||
"Tink_2",
|
||||
"Heal_HP_2",
|
||||
"Heal_Ailment_2",
|
||||
"Start_Menu_2",
|
||||
"Press_AB_2",
|
||||
"Ball_Toss",
|
||||
"Ball_Poof",
|
||||
"Faint_Thud",
|
||||
"Run",
|
||||
"Dex_Page_Added",
|
||||
"Caught_Mon",
|
||||
"Peck",
|
||||
"Faint_Fall",
|
||||
"Battle_09",
|
||||
"Pound",
|
||||
"Battle_0B",
|
||||
"Battle_0C",
|
||||
"Battle_0D",
|
||||
"Battle_0E",
|
||||
"Battle_0F",
|
||||
"Damage",
|
||||
"Not_Very_Effective",
|
||||
"Battle_12",
|
||||
"Battle_13",
|
||||
"Battle_14",
|
||||
"Vine_Whip",
|
||||
"Battle_16",
|
||||
"Battle_17",
|
||||
"Battle_18",
|
||||
"Battle_19",
|
||||
"Super_Effective",
|
||||
"Battle_1B",
|
||||
"Battle_1C",
|
||||
"Doubleslap",
|
||||
"Battle_1E",
|
||||
"Horn_Drill",
|
||||
"Battle_20",
|
||||
"Battle_21",
|
||||
"Battle_22",
|
||||
"Battle_23",
|
||||
"Battle_24",
|
||||
"Battle_25",
|
||||
"Battle_26",
|
||||
"Battle_27",
|
||||
"Battle_28",
|
||||
"Battle_29",
|
||||
"Battle_2A",
|
||||
"Battle_2B",
|
||||
"Battle_2C",
|
||||
"Psybeam",
|
||||
"Battle_2E",
|
||||
"Battle_2F",
|
||||
"Psychic_M",
|
||||
"Battle_31",
|
||||
"Battle_32",
|
||||
"Battle_33",
|
||||
"Battle_34",
|
||||
"Battle_35",
|
||||
"Battle_36",
|
||||
"Silph_Scope",
|
||||
"Snare1_1",
|
||||
"Snare2_1",
|
||||
"Snare3_1",
|
||||
"Snare4_1",
|
||||
"Snare5_1",
|
||||
"Triangle1_1",
|
||||
"Triangle2_1",
|
||||
"Snare6_1",
|
||||
"Snare7_1",
|
||||
"Snare8_1",
|
||||
"Snare9_1",
|
||||
"Cymbal1_1",
|
||||
"Cymbal2_1",
|
||||
"Cymbal3_1",
|
||||
"Muted_Snare1_1",
|
||||
"Triangle3_1",
|
||||
"Muted_Snare2_1",
|
||||
"Muted_Snare3_1",
|
||||
"Muted_Snare4_1",
|
||||
"Cry00_1",
|
||||
"Cry01_1",
|
||||
"Cry02_1",
|
||||
"Cry03_1",
|
||||
"Cry04_1",
|
||||
"Cry05_1",
|
||||
"Cry06_1",
|
||||
"Cry07_1",
|
||||
"Cry08_1",
|
||||
"Cry09_1",
|
||||
"Cry0A_1",
|
||||
"Cry0B_1",
|
||||
"Cry0C_1",
|
||||
"Cry0D_1",
|
||||
"Cry0E_1",
|
||||
"Cry0F_1",
|
||||
"Cry10_1",
|
||||
"Cry11_1",
|
||||
"Cry12_1",
|
||||
"Cry13_1",
|
||||
"Cry14_1",
|
||||
"Cry15_1",
|
||||
"Cry16_1",
|
||||
"Cry17_1",
|
||||
"Cry18_1",
|
||||
"Cry19_1",
|
||||
"Cry1A_1",
|
||||
"Cry1B_1",
|
||||
"Cry1C_1",
|
||||
"Cry1D_1",
|
||||
"Cry1E_1",
|
||||
"Cry1F_1",
|
||||
"Cry20_1",
|
||||
"Cry21_1",
|
||||
"Cry22_1",
|
||||
"Cry23_1",
|
||||
"Cry24_1",
|
||||
"Cry25_1",
|
||||
"Get_Item1_1",
|
||||
"Get_Item2_1",
|
||||
"Tink_1",
|
||||
"Heal_HP_1",
|
||||
"Heal_Ailment_1",
|
||||
"Start_Menu_1",
|
||||
"Press_AB_1",
|
||||
"Pokedex_Rating_1",
|
||||
"Get_Key_Item_1",
|
||||
"Poisoned_1",
|
||||
"Trade_Machine_1",
|
||||
"Turn_On_PC_1",
|
||||
"Turn_Off_PC_1",
|
||||
"Enter_PC_1",
|
||||
"Shrink_1",
|
||||
"Switch_1",
|
||||
"Healing_Machine_1",
|
||||
"Teleport_Exit1_1",
|
||||
"Teleport_Enter1_1",
|
||||
"Teleport_Exit2_1",
|
||||
"Ledge_1",
|
||||
"Teleport_Enter2_1",
|
||||
"Fly_1",
|
||||
"Denied_1",
|
||||
"Arrow_Tiles_1",
|
||||
"Push_Boulder_1",
|
||||
"SS_Anne_Horn_1",
|
||||
"Withdraw_Deposit_1",
|
||||
"Cut_1",
|
||||
"Go_Inside_1",
|
||||
"Swap_1",
|
||||
"59_1",
|
||||
"Purchase_1",
|
||||
"Collision_1",
|
||||
"Go_Outside_1",
|
||||
"Save_1",
|
||||
"Pokeflute",
|
||||
"Safari_Zone_PA",
|
||||
"Snare1_3",
|
||||
"Snare2_3",
|
||||
"Snare3_3",
|
||||
"Snare4_3",
|
||||
"Snare5_3",
|
||||
"Triangle1_3",
|
||||
"Triangle2_3",
|
||||
"Snare6_3",
|
||||
"Snare7_3",
|
||||
"Snare8_3",
|
||||
"Snare9_3",
|
||||
"Cymbal1_3",
|
||||
"Cymbal2_3",
|
||||
"Cymbal3_3",
|
||||
"Muted_Snare1_3",
|
||||
"Triangle3_3",
|
||||
"Muted_Snare2_3",
|
||||
"Muted_Snare3_3",
|
||||
"Muted_Snare4_3",
|
||||
"Cry00_3",
|
||||
"Cry01_3",
|
||||
"Cry02_3",
|
||||
"Cry03_3",
|
||||
"Cry04_3",
|
||||
"Cry05_3",
|
||||
"Cry06_3",
|
||||
"Cry07_3",
|
||||
"Cry08_3",
|
||||
"Cry09_3",
|
||||
"Cry0A_3",
|
||||
"Cry0B_3",
|
||||
"Cry0C_3",
|
||||
"Cry0D_3",
|
||||
"Cry0E_3",
|
||||
"Cry0F_3",
|
||||
"Cry10_3",
|
||||
"Cry11_3",
|
||||
"Cry12_3",
|
||||
"Cry13_3",
|
||||
"Cry14_3",
|
||||
"Cry15_3",
|
||||
"Cry16_3",
|
||||
"Cry17_3",
|
||||
"Cry18_3",
|
||||
"Cry19_3",
|
||||
"Cry1A_3",
|
||||
"Cry1B_3",
|
||||
"Cry1C_3",
|
||||
"Cry1D_3",
|
||||
"Cry1E_3",
|
||||
"Cry1F_3",
|
||||
"Cry20_3",
|
||||
"Cry21_3",
|
||||
"Cry22_3",
|
||||
"Cry23_3",
|
||||
"Cry24_3",
|
||||
"Cry25_3",
|
||||
"Get_Item1_3",
|
||||
"Get_Item2_3",
|
||||
"Tink_3",
|
||||
"Heal_HP_3",
|
||||
"Heal_Ailment_3",
|
||||
"Start_Menu_3",
|
||||
"Press_AB_3",
|
||||
"Pokedex_Rating_3",
|
||||
"Get_Key_Item_3",
|
||||
"Poisoned_3",
|
||||
"Trade_Machine_3",
|
||||
"Turn_On_PC_3",
|
||||
"Turn_Off_PC_3",
|
||||
"Enter_PC_3",
|
||||
"Shrink_3",
|
||||
"Switch_3",
|
||||
"Healing_Machine_3",
|
||||
"Teleport_Exit1_3",
|
||||
"Teleport_Enter1_3",
|
||||
"Teleport_Exit2_3",
|
||||
"Ledge_3",
|
||||
"Teleport_Enter2_3",
|
||||
"Fly_3",
|
||||
"Denied_3",
|
||||
"Arrow_Tiles_3",
|
||||
"Push_Boulder_3",
|
||||
"SS_Anne_Horn_3",
|
||||
"Withdraw_Deposit_3",
|
||||
"Cut_3",
|
||||
"Go_Inside_3",
|
||||
"Swap_3",
|
||||
"59_3",
|
||||
"Purchase_3",
|
||||
"Collision_3",
|
||||
"Go_Outside_3",
|
||||
"Save_3",
|
||||
"Intro_Lunge",
|
||||
"Intro_Hip",
|
||||
"Intro_Hop",
|
||||
"Intro_Raise",
|
||||
"Intro_Crash",
|
||||
"Intro_Whoosh",
|
||||
"Slots_Stop_Wheel",
|
||||
"Slots_Reward",
|
||||
"Slots_New_Spin",
|
||||
"Shooting_Star",
|
||||
]
|
||||
|
||||
banks = {
|
||||
0x02: 0x60,
|
||||
0x08: 0x78,
|
||||
0x1f: 0x68,
|
||||
}
|
||||
|
||||
music_commands = {
|
||||
0xd0: ["notetype", {"type": "nibble"}, 2],
|
||||
0xe0: ["octave", 1],
|
||||
0xe8: ["toggleperfectpitch", 1],
|
||||
0xea: ["vibrato", {"type": "byte"}, {"type": "nibble"}, 3],
|
||||
0xec: ["duty", {"type": "byte"}, 2],
|
||||
0xed: ["tempo", {"type": "word"}, 3],
|
||||
0xf0: ["volume", {"type": "nibble"}, 2],
|
||||
0xf8: ["executemusic", 1],
|
||||
0xfc: ["dutycycle", {"type": "byte"}, 2],
|
||||
0xfe: ["loopchannel", {"type": "byte"}, {"type": "label"}, 4],
|
||||
0xff: ["endchannel", 1],
|
||||
}
|
||||
|
||||
param_lengths = {
|
||||
"nibble": 1,
|
||||
"byte": 1,
|
||||
"word": 2,
|
||||
"label": 2,
|
||||
}
|
||||
|
||||
music_notes = {
|
||||
0x0: "C_",
|
||||
0x1: "C#",
|
||||
0x2: "D_",
|
||||
0x3: "D#",
|
||||
0x4: "E_",
|
||||
0x5: "F_",
|
||||
0x6: "F#",
|
||||
0x7: "G_",
|
||||
0x8: "G#",
|
||||
0x9: "A_",
|
||||
0xa: "A#",
|
||||
0xb: "B_",
|
||||
}
|
||||
|
||||
sfxnum = 0
|
||||
|
||||
for bank in banks:
|
||||
print(bank)
|
||||
header = bank * 0x4000 + 3
|
||||
for sfx in range(1,banks[bank]):
|
||||
sfxname = sfx_names[sfxnum]
|
||||
sfxfile = open("music/sfx/" + sfx_names[sfxnum].lower() + ".asm", 'w')
|
||||
sfxname = "SFX_" + sfxname
|
||||
startingaddress = rom[header + 2] * 0x100 + rom[header + 1] + (0x4000 * (bank - 1))
|
||||
end = 0
|
||||
curchannel = 1
|
||||
lastchannel = (rom[header] >> 6) + 1
|
||||
channelnumber = rom[header] % 0x10
|
||||
output = ''
|
||||
while 1:
|
||||
address = startingaddress
|
||||
if curchannel != lastchannel:
|
||||
end = rom[header + 5] * 0x100 + rom[header + 4] + (0x4000 * (bank - 1))
|
||||
byte = rom[address]
|
||||
if byte == 0xf8 or (bank == 2 and sfx == 0x5e): executemusic = True
|
||||
else: executemusic = False
|
||||
output += "{}_Ch{}: ; {:02x} ({:0x}:{:02x})\n".format(sfxname, curchannel, address, bank, address % 0x4000 + 0x4000)
|
||||
while 1:
|
||||
if address == 0x2062a or address == 0x2063d or address == 0x20930:
|
||||
output += "\n{}_branch_{:02x}:\n".format(sfxname, address)
|
||||
if byte == 0x10 and not executemusic:
|
||||
output += "\tunknownsfx0x{:02x} {}".format(byte, rom[address + 1])
|
||||
command_length = 2
|
||||
elif byte < 0x30 and not executemusic:
|
||||
if channelnumber == 7:
|
||||
output += "\tunknownnoise0x20 {}, {}, {}".format(byte % 0x10, rom[address + 1], rom[address + 2])
|
||||
command_length = 3
|
||||
else:
|
||||
output += "\tunknownsfx0x20 {}, {}, {}, {}".format(byte % 0x10, rom[address + 1], rom[address + 2], rom[address + 3])
|
||||
command_length = 4
|
||||
elif byte < 0xc0:
|
||||
output += "\t{} {}".format(music_notes[byte >> 4], byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
elif byte < 0xd0:
|
||||
output += "\trest {}".format(byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
else:
|
||||
if byte < 0xe0:
|
||||
command = music_commands[0xd0]
|
||||
output += "\t{} {},".format(command[0], byte % 0x10)
|
||||
byte = 0xd0
|
||||
elif byte < 0xe8:
|
||||
command = music_commands[0xe0]
|
||||
output += "\t{} {}".format(command[0], 0xe8 - byte)
|
||||
byte = 0xe0
|
||||
else:
|
||||
command = music_commands[byte]
|
||||
output += "\t{}".format(command[0])
|
||||
command_length = 1
|
||||
params = 1
|
||||
# print all params for current command
|
||||
while params != len(music_commands[byte]) - 1:
|
||||
param_type = music_commands[byte][params]["type"]
|
||||
address += command_length
|
||||
command_length = param_lengths[param_type]
|
||||
param = rom[address]
|
||||
if param_type == "nibble":
|
||||
output += " {}, {}".format(param >> 4, param % 0x10)
|
||||
elif param_type == "byte":
|
||||
output += " {}".format(param)
|
||||
elif param_type == "word":
|
||||
output += " {}".format(param * 0x100 + rom[address + 1])
|
||||
else:
|
||||
param += rom[address + 1] * 0x100 - 0x4000 + (bank * 0x4000)
|
||||
if param == startingaddress: output += " {}_Ch{}".format(sfxname, curchannel)
|
||||
else: output += " {}_branch_{:02x}".format(sfxname, param)
|
||||
params += 1
|
||||
if params != len(music_commands[byte]) - 1: output += ","
|
||||
output += "\n"
|
||||
address += command_length
|
||||
if byte == 0xff or address == end: break
|
||||
byte = rom[address]
|
||||
header += 3
|
||||
channelnumber = rom[header]
|
||||
if curchannel == lastchannel:
|
||||
# output += "; {}".format(hex(address))
|
||||
sfxfile.write(output)
|
||||
break
|
||||
output += "\n\n"
|
||||
startingaddress = address
|
||||
curchannel += 1
|
||||
sfxnum += 1
|
||||
|
|
@ -1,359 +1,360 @@
|
|||
import configuration
|
||||
config = configuration.Config()
|
||||
rom = bytearray(open(config.rom_path, "r").read())
|
||||
|
||||
sfx_names = [
|
||||
"Snare1_1",
|
||||
"Snare2_1",
|
||||
"Snare3_1",
|
||||
"Snare4_1",
|
||||
"Snare5_1",
|
||||
"Triangle1_1",
|
||||
"Triangle2_1",
|
||||
"Snare6_1",
|
||||
"Snare7_1",
|
||||
"Snare8_1",
|
||||
"Snare9_1",
|
||||
"Cymbal1_1",
|
||||
"Cymbal2_1",
|
||||
"Cymbal3_1",
|
||||
"Muted_Snare1_1",
|
||||
"Triangle3_1",
|
||||
"Muted_Snare2_1",
|
||||
"Muted_Snare3_1",
|
||||
"Muted_Snare4_1",
|
||||
"Cry00_1",
|
||||
"Cry01_1",
|
||||
"Cry02_1",
|
||||
"Cry03_1",
|
||||
"Cry04_1",
|
||||
"Cry05_1",
|
||||
"Cry06_1",
|
||||
"Cry07_1",
|
||||
"Cry08_1",
|
||||
"Cry09_1",
|
||||
"Cry0A_1",
|
||||
"Cry0B_1",
|
||||
"Cry0C_1",
|
||||
"Cry0D_1",
|
||||
"Cry0E_1",
|
||||
"Cry0F_1",
|
||||
"Cry10_1",
|
||||
"Cry11_1",
|
||||
"Cry12_1",
|
||||
"Cry13_1",
|
||||
"Cry14_1",
|
||||
"Cry15_1",
|
||||
"Cry16_1",
|
||||
"Cry17_1",
|
||||
"Cry18_1",
|
||||
"Cry19_1",
|
||||
"Cry1A_1",
|
||||
"Cry1B_1",
|
||||
"Cry1C_1",
|
||||
"Cry1D_1",
|
||||
"Cry1E_1",
|
||||
"Cry1F_1",
|
||||
"Cry20_1",
|
||||
"Cry21_1",
|
||||
"Cry22_1",
|
||||
"Cry23_1",
|
||||
"Cry24_1",
|
||||
"Cry25_1",
|
||||
"Get_Item1_1",
|
||||
"Get_Item2_1",
|
||||
"Tink_1",
|
||||
"Heal_HP_1",
|
||||
"Heal_Ailment_1",
|
||||
"Start_Menu_1",
|
||||
"Press_AB_1",
|
||||
"Pokedex_Rating_1",
|
||||
"Get_Key_Item_1",
|
||||
"Poisoned_1",
|
||||
"Trade_Machine_1",
|
||||
"Turn_On_PC_1",
|
||||
"Turn_Off_PC_1",
|
||||
"Enter_PC_1",
|
||||
"Shrink_1",
|
||||
"Switch_1",
|
||||
"Healing_Machine_1",
|
||||
"Teleport_Exit1_1",
|
||||
"Teleport_Enter1_1",
|
||||
"Teleport_Exit2_1",
|
||||
"Ledge_1",
|
||||
"Teleport_Enter2_1",
|
||||
"Fly_1",
|
||||
"Denied_1",
|
||||
"Arrow_Tiles_1",
|
||||
"Push_Boulder_1",
|
||||
"SS_Anne_Horn_1",
|
||||
"Withdraw_Deposit_1",
|
||||
"Cut_1",
|
||||
"Go_Inside_1",
|
||||
"Swap_1",
|
||||
"59_1",
|
||||
"Purchase_1",
|
||||
"Collision_1",
|
||||
"Go_Outside_1",
|
||||
"Save_1",
|
||||
"Pokeflute",
|
||||
"Safari_Zone_PA",
|
||||
"Snare1_2",
|
||||
"Snare2_2",
|
||||
"Snare3_2",
|
||||
"Snare4_2",
|
||||
"Snare5_2",
|
||||
"Triangle1_2",
|
||||
"Triangle2_2",
|
||||
"Snare6_2",
|
||||
"Snare7_2",
|
||||
"Snare8_2",
|
||||
"Snare9_2",
|
||||
"Cymbal1_2",
|
||||
"Cymbal2_2",
|
||||
"Cymbal3_2",
|
||||
"Muted_Snare1_2",
|
||||
"Triangle3_2",
|
||||
"Muted_Snare2_2",
|
||||
"Muted_Snare3_2",
|
||||
"Muted_Snare4_2",
|
||||
"Cry00_2",
|
||||
"Cry01_2",
|
||||
"Cry02_2",
|
||||
"Cry03_2",
|
||||
"Cry04_2",
|
||||
"Cry05_2",
|
||||
"Cry06_2",
|
||||
"Cry07_2",
|
||||
"Cry08_2",
|
||||
"Cry09_2",
|
||||
"Cry0A_2",
|
||||
"Cry0B_2",
|
||||
"Cry0C_2",
|
||||
"Cry0D_2",
|
||||
"Cry0E_2",
|
||||
"Cry0F_2",
|
||||
"Cry10_2",
|
||||
"Cry11_2",
|
||||
"Cry12_2",
|
||||
"Cry13_2",
|
||||
"Cry14_2",
|
||||
"Cry15_2",
|
||||
"Cry16_2",
|
||||
"Cry17_2",
|
||||
"Cry18_2",
|
||||
"Cry19_2",
|
||||
"Cry1A_2",
|
||||
"Cry1B_2",
|
||||
"Cry1C_2",
|
||||
"Cry1D_2",
|
||||
"Cry1E_2",
|
||||
"Cry1F_2",
|
||||
"Cry20_2",
|
||||
"Cry21_2",
|
||||
"Cry22_2",
|
||||
"Cry23_2",
|
||||
"Cry24_2",
|
||||
"Cry25_2",
|
||||
"Level_Up",
|
||||
"Get_Item2_2",
|
||||
"Tink_2",
|
||||
"Heal_HP_2",
|
||||
"Heal_Ailment_2",
|
||||
"Start_Menu_2",
|
||||
"Press_AB_2",
|
||||
"Ball_Toss",
|
||||
"Ball_Poof",
|
||||
"Faint_Thud",
|
||||
"Run",
|
||||
"Dex_Page_Added",
|
||||
"Caught_Mon",
|
||||
"Peck",
|
||||
"Faint_Fall",
|
||||
"Battle_09",
|
||||
"Pound",
|
||||
"Battle_0B",
|
||||
"Battle_0C",
|
||||
"Battle_0D",
|
||||
"Battle_0E",
|
||||
"Battle_0F",
|
||||
"Damage",
|
||||
"Not_Very_Effective",
|
||||
"Battle_12",
|
||||
"Battle_13",
|
||||
"Battle_14",
|
||||
"Vine_Whip",
|
||||
"Battle_16",
|
||||
"Battle_17",
|
||||
"Battle_18",
|
||||
"Battle_19",
|
||||
"Super_Effective",
|
||||
"Battle_1B",
|
||||
"Battle_1C",
|
||||
"Doubleslap",
|
||||
"Battle_1E",
|
||||
"Horn_Drill",
|
||||
"Battle_20",
|
||||
"Battle_21",
|
||||
"Battle_22",
|
||||
"Battle_23",
|
||||
"Battle_24",
|
||||
"Battle_25",
|
||||
"Battle_26",
|
||||
"Battle_27",
|
||||
"Battle_28",
|
||||
"Battle_29",
|
||||
"Battle_2A",
|
||||
"Battle_2B",
|
||||
"Battle_2C",
|
||||
"Psybeam",
|
||||
"Battle_2E",
|
||||
"Battle_2F",
|
||||
"Psychic_M",
|
||||
"Battle_31",
|
||||
"Battle_32",
|
||||
"Battle_33",
|
||||
"Battle_34",
|
||||
"Battle_35",
|
||||
"Battle_36",
|
||||
"Silph_Scope",
|
||||
"Snare1_3",
|
||||
"Snare2_3",
|
||||
"Snare3_3",
|
||||
"Snare4_3",
|
||||
"Snare5_3",
|
||||
"Triangle1_3",
|
||||
"Triangle2_3",
|
||||
"Snare6_3",
|
||||
"Snare7_3",
|
||||
"Snare8_3",
|
||||
"Snare9_3",
|
||||
"Cymbal1_3",
|
||||
"Cymbal2_3",
|
||||
"Cymbal3_3",
|
||||
"Muted_Snare1_3",
|
||||
"Triangle3_3",
|
||||
"Muted_Snare2_3",
|
||||
"Muted_Snare3_3",
|
||||
"Muted_Snare4_3",
|
||||
"Cry00_3",
|
||||
"Cry01_3",
|
||||
"Cry02_3",
|
||||
"Cry03_3",
|
||||
"Cry04_3",
|
||||
"Cry05_3",
|
||||
"Cry06_3",
|
||||
"Cry07_3",
|
||||
"Cry08_3",
|
||||
"Cry09_3",
|
||||
"Cry0A_3",
|
||||
"Cry0B_3",
|
||||
"Cry0C_3",
|
||||
"Cry0D_3",
|
||||
"Cry0E_3",
|
||||
"Cry0F_3",
|
||||
"Cry10_3",
|
||||
"Cry11_3",
|
||||
"Cry12_3",
|
||||
"Cry13_3",
|
||||
"Cry14_3",
|
||||
"Cry15_3",
|
||||
"Cry16_3",
|
||||
"Cry17_3",
|
||||
"Cry18_3",
|
||||
"Cry19_3",
|
||||
"Cry1A_3",
|
||||
"Cry1B_3",
|
||||
"Cry1C_3",
|
||||
"Cry1D_3",
|
||||
"Cry1E_3",
|
||||
"Cry1F_3",
|
||||
"Cry20_3",
|
||||
"Cry21_3",
|
||||
"Cry22_3",
|
||||
"Cry23_3",
|
||||
"Cry24_3",
|
||||
"Cry25_3",
|
||||
"Get_Item1_3",
|
||||
"Get_Item2_3",
|
||||
"Tink_3",
|
||||
"Heal_HP_3",
|
||||
"Heal_Ailment_3",
|
||||
"Start_Menu_3",
|
||||
"Press_AB_3",
|
||||
"Pokedex_Rating_3",
|
||||
"Get_Key_Item_3",
|
||||
"Poisoned_3",
|
||||
"Trade_Machine_3",
|
||||
"Turn_On_PC_3",
|
||||
"Turn_Off_PC_3",
|
||||
"Enter_PC_3",
|
||||
"Shrink_3",
|
||||
"Switch_3",
|
||||
"Healing_Machine_3",
|
||||
"Teleport_Exit1_3",
|
||||
"Teleport_Enter1_3",
|
||||
"Teleport_Exit2_3",
|
||||
"Ledge_3",
|
||||
"Teleport_Enter2_3",
|
||||
"Fly_3",
|
||||
"Denied_3",
|
||||
"Arrow_Tiles_3",
|
||||
"Push_Boulder_3",
|
||||
"SS_Anne_Horn_3",
|
||||
"Withdraw_Deposit_3",
|
||||
"Cut_3",
|
||||
"Go_Inside_3",
|
||||
"Swap_3",
|
||||
"59_3",
|
||||
"Purchase_3",
|
||||
"Collision_3",
|
||||
"Go_Outside_3",
|
||||
"Save_3",
|
||||
"Intro_Lunge",
|
||||
"Intro_Hip",
|
||||
"Intro_Hop",
|
||||
"Intro_Raise",
|
||||
"Intro_Crash",
|
||||
"Intro_Whoosh",
|
||||
"Slots_Stop_Wheel",
|
||||
"Slots_Reward",
|
||||
"Slots_New_Spin",
|
||||
"Shooting_Star",
|
||||
]
|
||||
|
||||
headerlist = (
|
||||
["sfxheaders02.asm", 0x8003, 0x822e],
|
||||
["sfxheaders08.asm", 0x20003, 0x202be],
|
||||
["sfxheaders1f.asm", 0x7c003, 0x7c249],
|
||||
)
|
||||
|
||||
def printsfxheaders(filename, address, end, sfxnum):
|
||||
file = open(filename, 'w')
|
||||
bank = address / 0x4000
|
||||
byte = rom[address]
|
||||
sfx = 1
|
||||
channel = 1
|
||||
file.write("SFX_Headers_{:02x}::\n".format(bank))
|
||||
file.write("\tdb $ff, $ff, $ff ; padding\n")
|
||||
while address != end:
|
||||
left = (byte >> 6) + 1
|
||||
file.write("\nSFX_{}:: ; {:02x} ({:0x}:{:02x})\n".format(sfx_names[sfxnum], address, bank, address % 0x4000 + 0x4000))
|
||||
while left != 0:
|
||||
pointer = rom[address + 2] * 0x100 + rom[address + 1]
|
||||
if byte >> 4 != 0: file.write(" db ( ${:0x}0 | CH{:0x} )\n".format(byte >> 4, byte % 0x10))
|
||||
else: file.write("\tdb CH{:0x}\n".format(byte))
|
||||
file.write("\tdw SFX_{}_Ch{}\n".format(sfx_names[sfxnum], channel))
|
||||
address += 3
|
||||
byte = rom[address]
|
||||
channel += 1
|
||||
left -= 1
|
||||
channel = 1
|
||||
sfx += 1
|
||||
sfxnum += 1
|
||||
#file.write("\n; {}".format(hex(address)))
|
||||
return sfxnum
|
||||
|
||||
sfxnum = 0
|
||||
for header in headerlist:
|
||||
from __future__ import absolute_import
|
||||
from . import configuration
|
||||
config = configuration.Config()
|
||||
rom = bytearray(open(config.rom_path, "r").read())
|
||||
|
||||
sfx_names = [
|
||||
"Snare1_1",
|
||||
"Snare2_1",
|
||||
"Snare3_1",
|
||||
"Snare4_1",
|
||||
"Snare5_1",
|
||||
"Triangle1_1",
|
||||
"Triangle2_1",
|
||||
"Snare6_1",
|
||||
"Snare7_1",
|
||||
"Snare8_1",
|
||||
"Snare9_1",
|
||||
"Cymbal1_1",
|
||||
"Cymbal2_1",
|
||||
"Cymbal3_1",
|
||||
"Muted_Snare1_1",
|
||||
"Triangle3_1",
|
||||
"Muted_Snare2_1",
|
||||
"Muted_Snare3_1",
|
||||
"Muted_Snare4_1",
|
||||
"Cry00_1",
|
||||
"Cry01_1",
|
||||
"Cry02_1",
|
||||
"Cry03_1",
|
||||
"Cry04_1",
|
||||
"Cry05_1",
|
||||
"Cry06_1",
|
||||
"Cry07_1",
|
||||
"Cry08_1",
|
||||
"Cry09_1",
|
||||
"Cry0A_1",
|
||||
"Cry0B_1",
|
||||
"Cry0C_1",
|
||||
"Cry0D_1",
|
||||
"Cry0E_1",
|
||||
"Cry0F_1",
|
||||
"Cry10_1",
|
||||
"Cry11_1",
|
||||
"Cry12_1",
|
||||
"Cry13_1",
|
||||
"Cry14_1",
|
||||
"Cry15_1",
|
||||
"Cry16_1",
|
||||
"Cry17_1",
|
||||
"Cry18_1",
|
||||
"Cry19_1",
|
||||
"Cry1A_1",
|
||||
"Cry1B_1",
|
||||
"Cry1C_1",
|
||||
"Cry1D_1",
|
||||
"Cry1E_1",
|
||||
"Cry1F_1",
|
||||
"Cry20_1",
|
||||
"Cry21_1",
|
||||
"Cry22_1",
|
||||
"Cry23_1",
|
||||
"Cry24_1",
|
||||
"Cry25_1",
|
||||
"Get_Item1_1",
|
||||
"Get_Item2_1",
|
||||
"Tink_1",
|
||||
"Heal_HP_1",
|
||||
"Heal_Ailment_1",
|
||||
"Start_Menu_1",
|
||||
"Press_AB_1",
|
||||
"Pokedex_Rating_1",
|
||||
"Get_Key_Item_1",
|
||||
"Poisoned_1",
|
||||
"Trade_Machine_1",
|
||||
"Turn_On_PC_1",
|
||||
"Turn_Off_PC_1",
|
||||
"Enter_PC_1",
|
||||
"Shrink_1",
|
||||
"Switch_1",
|
||||
"Healing_Machine_1",
|
||||
"Teleport_Exit1_1",
|
||||
"Teleport_Enter1_1",
|
||||
"Teleport_Exit2_1",
|
||||
"Ledge_1",
|
||||
"Teleport_Enter2_1",
|
||||
"Fly_1",
|
||||
"Denied_1",
|
||||
"Arrow_Tiles_1",
|
||||
"Push_Boulder_1",
|
||||
"SS_Anne_Horn_1",
|
||||
"Withdraw_Deposit_1",
|
||||
"Cut_1",
|
||||
"Go_Inside_1",
|
||||
"Swap_1",
|
||||
"59_1",
|
||||
"Purchase_1",
|
||||
"Collision_1",
|
||||
"Go_Outside_1",
|
||||
"Save_1",
|
||||
"Pokeflute",
|
||||
"Safari_Zone_PA",
|
||||
"Snare1_2",
|
||||
"Snare2_2",
|
||||
"Snare3_2",
|
||||
"Snare4_2",
|
||||
"Snare5_2",
|
||||
"Triangle1_2",
|
||||
"Triangle2_2",
|
||||
"Snare6_2",
|
||||
"Snare7_2",
|
||||
"Snare8_2",
|
||||
"Snare9_2",
|
||||
"Cymbal1_2",
|
||||
"Cymbal2_2",
|
||||
"Cymbal3_2",
|
||||
"Muted_Snare1_2",
|
||||
"Triangle3_2",
|
||||
"Muted_Snare2_2",
|
||||
"Muted_Snare3_2",
|
||||
"Muted_Snare4_2",
|
||||
"Cry00_2",
|
||||
"Cry01_2",
|
||||
"Cry02_2",
|
||||
"Cry03_2",
|
||||
"Cry04_2",
|
||||
"Cry05_2",
|
||||
"Cry06_2",
|
||||
"Cry07_2",
|
||||
"Cry08_2",
|
||||
"Cry09_2",
|
||||
"Cry0A_2",
|
||||
"Cry0B_2",
|
||||
"Cry0C_2",
|
||||
"Cry0D_2",
|
||||
"Cry0E_2",
|
||||
"Cry0F_2",
|
||||
"Cry10_2",
|
||||
"Cry11_2",
|
||||
"Cry12_2",
|
||||
"Cry13_2",
|
||||
"Cry14_2",
|
||||
"Cry15_2",
|
||||
"Cry16_2",
|
||||
"Cry17_2",
|
||||
"Cry18_2",
|
||||
"Cry19_2",
|
||||
"Cry1A_2",
|
||||
"Cry1B_2",
|
||||
"Cry1C_2",
|
||||
"Cry1D_2",
|
||||
"Cry1E_2",
|
||||
"Cry1F_2",
|
||||
"Cry20_2",
|
||||
"Cry21_2",
|
||||
"Cry22_2",
|
||||
"Cry23_2",
|
||||
"Cry24_2",
|
||||
"Cry25_2",
|
||||
"Level_Up",
|
||||
"Get_Item2_2",
|
||||
"Tink_2",
|
||||
"Heal_HP_2",
|
||||
"Heal_Ailment_2",
|
||||
"Start_Menu_2",
|
||||
"Press_AB_2",
|
||||
"Ball_Toss",
|
||||
"Ball_Poof",
|
||||
"Faint_Thud",
|
||||
"Run",
|
||||
"Dex_Page_Added",
|
||||
"Caught_Mon",
|
||||
"Peck",
|
||||
"Faint_Fall",
|
||||
"Battle_09",
|
||||
"Pound",
|
||||
"Battle_0B",
|
||||
"Battle_0C",
|
||||
"Battle_0D",
|
||||
"Battle_0E",
|
||||
"Battle_0F",
|
||||
"Damage",
|
||||
"Not_Very_Effective",
|
||||
"Battle_12",
|
||||
"Battle_13",
|
||||
"Battle_14",
|
||||
"Vine_Whip",
|
||||
"Battle_16",
|
||||
"Battle_17",
|
||||
"Battle_18",
|
||||
"Battle_19",
|
||||
"Super_Effective",
|
||||
"Battle_1B",
|
||||
"Battle_1C",
|
||||
"Doubleslap",
|
||||
"Battle_1E",
|
||||
"Horn_Drill",
|
||||
"Battle_20",
|
||||
"Battle_21",
|
||||
"Battle_22",
|
||||
"Battle_23",
|
||||
"Battle_24",
|
||||
"Battle_25",
|
||||
"Battle_26",
|
||||
"Battle_27",
|
||||
"Battle_28",
|
||||
"Battle_29",
|
||||
"Battle_2A",
|
||||
"Battle_2B",
|
||||
"Battle_2C",
|
||||
"Psybeam",
|
||||
"Battle_2E",
|
||||
"Battle_2F",
|
||||
"Psychic_M",
|
||||
"Battle_31",
|
||||
"Battle_32",
|
||||
"Battle_33",
|
||||
"Battle_34",
|
||||
"Battle_35",
|
||||
"Battle_36",
|
||||
"Silph_Scope",
|
||||
"Snare1_3",
|
||||
"Snare2_3",
|
||||
"Snare3_3",
|
||||
"Snare4_3",
|
||||
"Snare5_3",
|
||||
"Triangle1_3",
|
||||
"Triangle2_3",
|
||||
"Snare6_3",
|
||||
"Snare7_3",
|
||||
"Snare8_3",
|
||||
"Snare9_3",
|
||||
"Cymbal1_3",
|
||||
"Cymbal2_3",
|
||||
"Cymbal3_3",
|
||||
"Muted_Snare1_3",
|
||||
"Triangle3_3",
|
||||
"Muted_Snare2_3",
|
||||
"Muted_Snare3_3",
|
||||
"Muted_Snare4_3",
|
||||
"Cry00_3",
|
||||
"Cry01_3",
|
||||
"Cry02_3",
|
||||
"Cry03_3",
|
||||
"Cry04_3",
|
||||
"Cry05_3",
|
||||
"Cry06_3",
|
||||
"Cry07_3",
|
||||
"Cry08_3",
|
||||
"Cry09_3",
|
||||
"Cry0A_3",
|
||||
"Cry0B_3",
|
||||
"Cry0C_3",
|
||||
"Cry0D_3",
|
||||
"Cry0E_3",
|
||||
"Cry0F_3",
|
||||
"Cry10_3",
|
||||
"Cry11_3",
|
||||
"Cry12_3",
|
||||
"Cry13_3",
|
||||
"Cry14_3",
|
||||
"Cry15_3",
|
||||
"Cry16_3",
|
||||
"Cry17_3",
|
||||
"Cry18_3",
|
||||
"Cry19_3",
|
||||
"Cry1A_3",
|
||||
"Cry1B_3",
|
||||
"Cry1C_3",
|
||||
"Cry1D_3",
|
||||
"Cry1E_3",
|
||||
"Cry1F_3",
|
||||
"Cry20_3",
|
||||
"Cry21_3",
|
||||
"Cry22_3",
|
||||
"Cry23_3",
|
||||
"Cry24_3",
|
||||
"Cry25_3",
|
||||
"Get_Item1_3",
|
||||
"Get_Item2_3",
|
||||
"Tink_3",
|
||||
"Heal_HP_3",
|
||||
"Heal_Ailment_3",
|
||||
"Start_Menu_3",
|
||||
"Press_AB_3",
|
||||
"Pokedex_Rating_3",
|
||||
"Get_Key_Item_3",
|
||||
"Poisoned_3",
|
||||
"Trade_Machine_3",
|
||||
"Turn_On_PC_3",
|
||||
"Turn_Off_PC_3",
|
||||
"Enter_PC_3",
|
||||
"Shrink_3",
|
||||
"Switch_3",
|
||||
"Healing_Machine_3",
|
||||
"Teleport_Exit1_3",
|
||||
"Teleport_Enter1_3",
|
||||
"Teleport_Exit2_3",
|
||||
"Ledge_3",
|
||||
"Teleport_Enter2_3",
|
||||
"Fly_3",
|
||||
"Denied_3",
|
||||
"Arrow_Tiles_3",
|
||||
"Push_Boulder_3",
|
||||
"SS_Anne_Horn_3",
|
||||
"Withdraw_Deposit_3",
|
||||
"Cut_3",
|
||||
"Go_Inside_3",
|
||||
"Swap_3",
|
||||
"59_3",
|
||||
"Purchase_3",
|
||||
"Collision_3",
|
||||
"Go_Outside_3",
|
||||
"Save_3",
|
||||
"Intro_Lunge",
|
||||
"Intro_Hip",
|
||||
"Intro_Hop",
|
||||
"Intro_Raise",
|
||||
"Intro_Crash",
|
||||
"Intro_Whoosh",
|
||||
"Slots_Stop_Wheel",
|
||||
"Slots_Reward",
|
||||
"Slots_New_Spin",
|
||||
"Shooting_Star",
|
||||
]
|
||||
|
||||
headerlist = (
|
||||
["sfxheaders02.asm", 0x8003, 0x822e],
|
||||
["sfxheaders08.asm", 0x20003, 0x202be],
|
||||
["sfxheaders1f.asm", 0x7c003, 0x7c249],
|
||||
)
|
||||
|
||||
def printsfxheaders(filename, address, end, sfxnum):
|
||||
file = open(filename, 'w')
|
||||
bank = address / 0x4000
|
||||
byte = rom[address]
|
||||
sfx = 1
|
||||
channel = 1
|
||||
file.write("SFX_Headers_{:02x}::\n".format(bank))
|
||||
file.write("\tdb $ff, $ff, $ff ; padding\n")
|
||||
while address != end:
|
||||
left = (byte >> 6) + 1
|
||||
file.write("\nSFX_{}:: ; {:02x} ({:0x}:{:02x})\n".format(sfx_names[sfxnum], address, bank, address % 0x4000 + 0x4000))
|
||||
while left != 0:
|
||||
pointer = rom[address + 2] * 0x100 + rom[address + 1]
|
||||
if byte >> 4 != 0: file.write(" db ( ${:0x}0 | CH{:0x} )\n".format(byte >> 4, byte % 0x10))
|
||||
else: file.write("\tdb CH{:0x}\n".format(byte))
|
||||
file.write("\tdw SFX_{}_Ch{}\n".format(sfx_names[sfxnum], channel))
|
||||
address += 3
|
||||
byte = rom[address]
|
||||
channel += 1
|
||||
left -= 1
|
||||
channel = 1
|
||||
sfx += 1
|
||||
sfxnum += 1
|
||||
#file.write("\n; {}".format(hex(address)))
|
||||
return sfxnum
|
||||
|
||||
sfxnum = 0
|
||||
for header in headerlist:
|
||||
sfxnum = printsfxheaders(header[0], header[1], header[2], sfxnum)
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
|
|
@ -12,7 +14,7 @@ import json
|
|||
if not hasattr(json, "read"):
|
||||
json.read = json.loads
|
||||
|
||||
from labels import (
|
||||
from .labels import (
|
||||
get_label_from_line,
|
||||
get_address_from_line_comment,
|
||||
)
|
||||
|
|
@ -170,7 +172,7 @@ class RomStr(str):
|
|||
start_address = address
|
||||
|
||||
if start_address == None:
|
||||
raise Exception, "address must be given"
|
||||
raise Exception("address must be given")
|
||||
|
||||
if debug == None:
|
||||
if not hasattr(self, "debug"):
|
||||
|
|
@ -180,9 +182,9 @@ class RomStr(str):
|
|||
|
||||
# this is probably a terrible idea.. why am i doing this?
|
||||
if size != None and max_size < size:
|
||||
raise Exception, "max_size must be greater than or equal to size"
|
||||
raise Exception("max_size must be greater than or equal to size")
|
||||
elif end_address != None and (end_address - start_address) > max_size:
|
||||
raise Exception, "end_address is out of bounds"
|
||||
raise Exception("end_address is out of bounds")
|
||||
elif end_address != None and size != None:
|
||||
if (end_address - start_address) >= size:
|
||||
size = end_address - start_address
|
||||
|
|
@ -216,4 +218,4 @@ class AsmList(list):
|
|||
if __name__ == "__main__":
|
||||
cryrom = RomStr(open("../pokecrystal.gbc", "r").read());
|
||||
asm = cryrom.to_asm(sys.argv[1])
|
||||
print asm
|
||||
print(asm)
|
||||
|
|
|
|||
|
|
@ -4,40 +4,48 @@
|
|||
"""
|
||||
Recursively scan an asm file for dependencies.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import os.path
|
||||
|
||||
includes = set()
|
||||
|
||||
def scan_file(filename):
|
||||
for line in open(filename):
|
||||
if 'INC' not in line:
|
||||
continue
|
||||
line = line.split(';')[0]
|
||||
if 'INCLUDE' in line:
|
||||
include = line.split('"')[1]
|
||||
if os.path.exists("src/"):
|
||||
includes.add("src/" + include)
|
||||
scan_file("src/" + include)
|
||||
else:
|
||||
includes.add(include)
|
||||
scan_file(include)
|
||||
elif 'INCBIN' in line:
|
||||
include = line.split('"')[1]
|
||||
if 'baserom.gbc' not in line and os.path.exists("src/"):
|
||||
includes.add("src/" + include)
|
||||
else:
|
||||
includes.add(include)
|
||||
with open(filename) as f:
|
||||
for line in f:
|
||||
if 'INC' not in line:
|
||||
continue
|
||||
line = line.split(';')[0]
|
||||
if 'INCLUDE' in line:
|
||||
include = line.split('"')[1]
|
||||
if os.path.exists("src/"):
|
||||
yield "src/" + include
|
||||
for inc in scan_file("src/" + include):
|
||||
yield inc
|
||||
else:
|
||||
yield include
|
||||
for inc in scan_file(include):
|
||||
yield inc
|
||||
elif 'INCBIN' in line:
|
||||
include = line.split('"')[1]
|
||||
if 'baserom.gbc' not in line and os.path.exists("src/"):
|
||||
yield "src/" + include
|
||||
else:
|
||||
yield include
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('filenames', nargs='*')
|
||||
args = ap.parse_args()
|
||||
for filename in set(args.filenames):
|
||||
scan_file(filename)
|
||||
sys.stdout.write(' '.join(includes))
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('filenames', nargs='*')
|
||||
args = ap.parse_args()
|
||||
includes = set()
|
||||
for filename in set(args.filenames):
|
||||
includes.update(scan_file(filename))
|
||||
sys.stdout.write(' '.join(sorted(includes)))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
"""
|
||||
GBC disassembler, specialized for TCG macros
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
|
@ -10,9 +12,9 @@ from ctypes import c_int8
|
|||
import random
|
||||
import json
|
||||
|
||||
import configuration
|
||||
import labels
|
||||
import wram
|
||||
from . import configuration
|
||||
from . import labels
|
||||
from . import wram
|
||||
|
||||
# New versions of json don't have read anymore.
|
||||
if not hasattr(json, "read"):
|
||||
|
|
@ -663,7 +665,7 @@ class Disassembler(object):
|
|||
"""
|
||||
|
||||
bank_id = original_offset / 0x4000
|
||||
if debug: print "bank id is: " + str(bank_id)
|
||||
if debug: print("bank id is: " + str(bank_id))
|
||||
|
||||
last_hl_address = None #for when we're scanning the main map script
|
||||
last_a_address = None
|
||||
|
|
@ -995,4 +997,4 @@ if __name__ == "__main__":
|
|||
else:
|
||||
output = "Func_{:02x}: ; {:02x} ({:0x}:{:02x})\n".format(addr, addr, addr / 0x4000, addr % 0x4000 + 0x4000)
|
||||
output += disasm.output_bank_opcodes(addr)[0]
|
||||
print output
|
||||
print(output)
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
"""
|
||||
Programmatic speedrun of Pokémon Crystal
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
|
||||
import pokemontools.configuration as configuration
|
||||
|
||||
# bring in the emulator and basic tools
|
||||
import vba as _vba
|
||||
from . import vba as _vba
|
||||
|
||||
def skippable(func):
|
||||
"""
|
||||
|
|
@ -394,13 +396,13 @@ class SpeedRunner(Runner):
|
|||
self.cry.text_wait()
|
||||
|
||||
hp = self.cry.get_enemy_hp()
|
||||
print "enemy hp is: " + str(hp)
|
||||
print("enemy hp is: " + str(hp))
|
||||
|
||||
if hp == 0:
|
||||
print "enemy hp is zero, exiting"
|
||||
print("enemy hp is zero, exiting")
|
||||
break
|
||||
else:
|
||||
print "enemy hp is: " + str(hp)
|
||||
print("enemy hp is: " + str(hp))
|
||||
|
||||
attacks = attacks - 1
|
||||
|
||||
|
|
@ -417,7 +419,7 @@ class SpeedRunner(Runner):
|
|||
# happens.
|
||||
self.cry.text_wait(max_wait=30, debug=True)
|
||||
|
||||
print "okay, back in the overworld"
|
||||
print("okay, back in the overworld")
|
||||
|
||||
cur_hp = ((self.cry.vba.memory[0xdd01] << 8) | self.cry.vba.memory[0xdd02])
|
||||
move_pp = self.cry.vba.memory[0xdcf6] # move 1 pp
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
This file constructs a networkx.DiGraph object called graph, which can be used
|
||||
to find the shortest path of keypresses on the keyboard to type a word.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import itertools
|
||||
|
|
@ -44,7 +45,7 @@ def convert_nodes_to_button_press(node1, node2):
|
|||
"""
|
||||
Determines the button necessary to switch from node1 to node2.
|
||||
"""
|
||||
print "getting button press for state transition: " + node1 + " -> " + node2
|
||||
print("getting button press for state transition: " + node1 + " -> " + node2)
|
||||
return graph.get_edge_data(node1, node2)["key"]
|
||||
|
||||
def plan_typing(text, current="A"):
|
||||
|
|
@ -56,7 +57,7 @@ def plan_typing(text, current="A"):
|
|||
if target == current:
|
||||
buttons.append("a")
|
||||
else:
|
||||
print "Finding the shortest path between " + current + " and " + target
|
||||
print("Finding the shortest path between " + current + " and " + target)
|
||||
more_buttons = shortest_path(current, target)
|
||||
buttons.extend(more_buttons)
|
||||
buttons.append("a")
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
"""
|
||||
VBA automation
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
|
@ -18,7 +20,7 @@ from pokemontools.map_names import (
|
|||
map_names,
|
||||
)
|
||||
|
||||
import keyboard
|
||||
from . import keyboard
|
||||
|
||||
# just use a default config for now until the globals are removed completely
|
||||
import pokemontools.configuration as configuration
|
||||
|
|
@ -183,9 +185,9 @@ class crystal(object):
|
|||
self.vba.write_memory_at(self.registers.sp + 1, value >> 8)
|
||||
self.vba.write_memory_at(self.registers.sp, value & 0xFF)
|
||||
if list(self.vba.memory[self.registers.sp : self.registers.sp + 2]) != [value & 0xFF, value >> 8]:
|
||||
print "desired memory values: " + str([value & 0xFF, value >> 8] )
|
||||
print "actual memory values: " + str(list(self.vba.memory[self.registers.sp : self.registers.sp + 2]))
|
||||
print "wrong value at " + hex(self.registers.sp) + " expected " + hex(value) + " but got " + hex(self.vba.read_memory_at(self.registers.sp))
|
||||
print("desired memory values: " + str([value & 0xFF, value >> 8] ))
|
||||
print("actual memory values: " + str(list(self.vba.memory[self.registers.sp : self.registers.sp + 2])))
|
||||
print("wrong value at " + hex(self.registers.sp) + " expected " + hex(value) + " but got " + hex(self.vba.read_memory_at(self.registers.sp)))
|
||||
|
||||
def get_stack(self):
|
||||
"""
|
||||
|
|
@ -426,7 +428,7 @@ class crystal(object):
|
|||
address = ((hi << 8) | lo)
|
||||
|
||||
if address in range(0xa1b, 0xa46) + range(0xaaf, 0xaf5): # 0xaef:
|
||||
print "pressing, then breaking.. address is: " + str(hex(address))
|
||||
print("pressing, then breaking.. address is: " + str(hex(address)))
|
||||
|
||||
# set CurSFX
|
||||
self.vba.write_memory_at(0xc2bf, 0)
|
||||
|
|
@ -436,19 +438,19 @@ class crystal(object):
|
|||
# check if CurSFX is SFX_READ_TEXT_2
|
||||
if self.vba.read_memory_at(0xc2bf) == 0x8:
|
||||
if "CANCEL Which" in self.get_text():
|
||||
print "probably the 'switch pokemon' menu"
|
||||
print("probably the 'switch pokemon' menu")
|
||||
return
|
||||
else:
|
||||
print "cursfx is set to SFX_READ_TEXT_2, looping.."
|
||||
print self.get_text()
|
||||
print("cursfx is set to SFX_READ_TEXT_2, looping..")
|
||||
print(self.get_text())
|
||||
return self.text_wait(step_size=step_size, max_wait=max_wait, debug=debug, callback=callback, sfx_limit=sfx_limit)
|
||||
else:
|
||||
if sfx_limit > 0:
|
||||
sfx_limit = sfx_limit - 1
|
||||
print "decreasing sfx_limit"
|
||||
print("decreasing sfx_limit")
|
||||
else:
|
||||
# probably the last textbox in a sequence
|
||||
print "cursfx is not set to SFX_READ_TEXT_2, so: breaking"
|
||||
print("cursfx is not set to SFX_READ_TEXT_2, so: breaking")
|
||||
|
||||
break
|
||||
else:
|
||||
|
|
@ -456,19 +458,19 @@ class crystal(object):
|
|||
|
||||
# yes/no box or the name selection box
|
||||
if address in range(0xa46, 0xaaf):
|
||||
print "probably at a yes/no box.. exiting."
|
||||
print("probably at a yes/no box.. exiting.")
|
||||
break
|
||||
|
||||
# date/time box (day choice)
|
||||
# 0x47ab is the one from the intro, 0x49ab is the one from mom.
|
||||
elif 0x47ab in stack or 0x49ab in stack: # was any([x in stack for x in range(0x46EE, 0x47AB)])
|
||||
if not self.is_in_battle():
|
||||
print "probably at a date/time box ? exiting."
|
||||
print("probably at a date/time box ? exiting.")
|
||||
break
|
||||
|
||||
# "How many minutes?" selection box
|
||||
elif 0x4826 in stack:
|
||||
print "probably at a \"How many minutes?\" box ? exiting."
|
||||
print("probably at a \"How many minutes?\" box ? exiting.")
|
||||
break
|
||||
|
||||
self.vba.step(count=step_size)
|
||||
|
|
@ -482,7 +484,7 @@ class crystal(object):
|
|||
if callback != None:
|
||||
result = callback()
|
||||
if result == True:
|
||||
print "callback returned True, exiting"
|
||||
print("callback returned True, exiting")
|
||||
return
|
||||
|
||||
# only useful when debugging. When this is left on, text that
|
||||
|
|
@ -492,7 +494,7 @@ class crystal(object):
|
|||
max_wait = max_wait - 1
|
||||
|
||||
if max_wait == 0:
|
||||
print "max_wait was hit"
|
||||
print("max_wait was hit")
|
||||
|
||||
def walk_through_walls_slow(self):
|
||||
memory = self.vba.memory
|
||||
|
|
@ -852,7 +854,7 @@ class crystal(object):
|
|||
"""
|
||||
while limit > 0:
|
||||
if self.vba.read_memory_at(0xd438) != 255:
|
||||
print "script is done executing"
|
||||
print("script is done executing")
|
||||
return
|
||||
else:
|
||||
self.vba.step()
|
||||
|
|
@ -861,7 +863,7 @@ class crystal(object):
|
|||
limit = limit - 1
|
||||
|
||||
if limit == 0:
|
||||
print "limit ran out"
|
||||
print("limit ran out")
|
||||
|
||||
def move(self, cmd):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ class BSSReader:
|
|||
# rgbasm allows labels without :, but prefer convention
|
||||
label = line[:line.find(':')]
|
||||
if '\\' in label:
|
||||
raise Exception, line + ' ' + label
|
||||
raise Exception(line + ' ' + label)
|
||||
if ';' not in label:
|
||||
section_label = {
|
||||
'label': label,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-03
|
||||
#purpose: map which addresses are left
|
||||
|
|
@ -6,11 +8,11 @@ import sys, os
|
|||
from copy import copy, deepcopy
|
||||
import subprocess
|
||||
import json
|
||||
from extract_maps import rom, assert_rom, load_rom, calculate_pointer, load_map_pointers, read_all_map_headers, map_headers
|
||||
from pokered_dir import pokered_dir
|
||||
from .extract_maps import rom, assert_rom, load_rom, calculate_pointer, load_map_pointers, read_all_map_headers, map_headers
|
||||
from .pokered_dir import pokered_dir
|
||||
|
||||
try:
|
||||
from pretty_map_headers import map_header_pretty_printer, map_name_cleaner
|
||||
from .pretty_map_headers import map_header_pretty_printer, map_name_cleaner
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
|
@ -183,9 +185,9 @@ def generate_diff_insert(line_number, newline):
|
|||
diffcontent = subprocess.check_output(
|
||||
"diff -u {0} {1}".format(os.path.join(pokered_dir, "main.asm"), newfile_filename),
|
||||
shell=True)
|
||||
except AttributeError, exc:
|
||||
except AttributeError as exc:
|
||||
raise exc
|
||||
except Exception, exc:
|
||||
except Exception as exc:
|
||||
diffcontent = exc.output
|
||||
|
||||
os.system("rm " + original_filename)
|
||||
|
|
@ -197,7 +199,7 @@ def insert_map_header_asm(map_id):
|
|||
map = map_headers[map_id]
|
||||
line_number = find_incbin_to_replace_for(map["address"])
|
||||
if line_number == None: # or map_name_cleaner(map["name"], 0) in "\n".join(line for line in asm):
|
||||
print "i think map id=" + str(map_id) + " has previously been added."
|
||||
print("i think map id=" + str(map_id) + " has previously been added.")
|
||||
return #this map has already been added i bet
|
||||
newlines = split_incbin_line_into_three(line_number, map["address"], 12 + (11 * len(map["connections"])))
|
||||
|
||||
|
|
@ -213,8 +215,8 @@ def insert_map_header_asm(map_id):
|
|||
|
||||
diff = generate_diff_insert(line_number, newlines)
|
||||
|
||||
print diff
|
||||
print "... Applying diff."
|
||||
print(diff)
|
||||
print("... Applying diff.")
|
||||
|
||||
#write the diff to a file
|
||||
fh = open("temp.patch", "w")
|
||||
|
|
@ -236,7 +238,7 @@ def wrapper_insert_map_header_asm(map_id):
|
|||
|
||||
def dump_all_remaining_maps():
|
||||
for map_id in map_headers:
|
||||
print "Inserting map id=" + str(map_id)
|
||||
print("Inserting map id=" + str(map_id))
|
||||
wrapper_insert_map_header_asm(map_id)
|
||||
|
||||
def reset_incbins():
|
||||
|
|
@ -249,7 +251,7 @@ def reset_incbins():
|
|||
process_incbins()
|
||||
|
||||
def apply_diff(diff, try_fixing=True, do_compile=True):
|
||||
print "... Applying diff."
|
||||
print("... Applying diff.")
|
||||
|
||||
#write the diff to a file
|
||||
fh = open("temp.patch", "w")
|
||||
|
|
@ -272,7 +274,7 @@ def apply_diff(diff, try_fixing=True, do_compile=True):
|
|||
try:
|
||||
subprocess.check_call("cd {0}; make clean; LC_CTYPE=C make".format(pokered_dir), shell=True)
|
||||
return True
|
||||
except Exception, exc:
|
||||
except Exception as exc:
|
||||
if try_fixing:
|
||||
os.system("mv {0} {1}".format(
|
||||
os.path.join(pokered_dir, "main1.asm"),
|
||||
|
|
@ -390,7 +392,7 @@ def get_labels_between(start_line_id, end_line_id, bank_id):
|
|||
else:
|
||||
local_pointer = hex((address % 0x4000) + 0x4000).replace("0x", "$")
|
||||
|
||||
print line_label + " is at " + hex(address)
|
||||
print(line_label + " is at " + hex(address))
|
||||
|
||||
label = {
|
||||
"line_number": line_id,
|
||||
|
|
@ -438,7 +440,7 @@ def scan_for_predefined_labels():
|
|||
else:
|
||||
end_line_id = len(asm) - 1
|
||||
|
||||
print "bank" + abbreviation + " starts at " + str(start_line_id) + " to " + str(end_line_id)
|
||||
print("bank" + abbreviation + " starts at " + str(start_line_id) + " to " + str(end_line_id))
|
||||
|
||||
bank_intervals[bank_id] = {
|
||||
"start": start_line_id,
|
||||
|
|
@ -502,6 +504,6 @@ if __name__ == "__main__":
|
|||
#dump_all_remaining_maps()
|
||||
|
||||
scan_for_predefined_labels()
|
||||
print "Errors:"
|
||||
print label_errors
|
||||
print("Errors:")
|
||||
print(label_errors)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-06
|
||||
#analyze texts, how many commands are unknown?
|
||||
import extract_maps
|
||||
import analyze_incbins #for asm
|
||||
from . import extract_maps
|
||||
from . import analyze_incbins #for asm
|
||||
try:
|
||||
from pretty_map_headers import map_name_cleaner, txt_bytes, spacing, constant_abbreviation_bytes
|
||||
except Exception, exc: pass
|
||||
from .pretty_map_headers import map_name_cleaner, txt_bytes, spacing, constant_abbreviation_bytes
|
||||
except Exception as exc: pass
|
||||
from operator import itemgetter
|
||||
import sys
|
||||
debug = False #set to True to increase logging output
|
||||
|
|
@ -31,7 +33,7 @@ def how_many_until(byte, starting):
|
|||
|
||||
def print_command_debug_info(command_byte, text_id, text_pointer, map_id):
|
||||
if debug:
|
||||
print "byte is " + str(command_byte) + " on text #" + str(text_id) + " at " + hex(text_pointer) + " on map " + str(map_id) + " (" + extract_maps.map_headers[map_id]["name"] + ")"
|
||||
print("byte is " + str(command_byte) + " on text #" + str(text_id) + " at " + hex(text_pointer) + " on map " + str(map_id) + " (" + extract_maps.map_headers[map_id]["name"] + ")")
|
||||
|
||||
def add_command_byte_to_totals(byte):
|
||||
global totals
|
||||
|
|
@ -155,7 +157,7 @@ def parse_text_script(text_pointer, text_id, map_id, txfar=False):
|
|||
|
||||
#use this to look at the surrounding bytes
|
||||
if debug:
|
||||
print "next command is: " + hex(ord(extract_maps.rom[offset])) + " ... we are at command number: " + str(command_counter) + " near " + hex(offset) + " on map_id=" + str(map_id) + " for text_id=" + str(text_id) + " and txfar(recursion)=" + str(txfar)
|
||||
print("next command is: " + hex(ord(extract_maps.rom[offset])) + " ... we are at command number: " + str(command_counter) + " near " + hex(offset) + " on map_id=" + str(map_id) + " for text_id=" + str(text_id) + " and txfar(recursion)=" + str(txfar))
|
||||
elif command_byte == 0x7:
|
||||
#07 = shift texts 1 row above (2nd line becomes 1st line); address for next text = 2nd line. [07]
|
||||
size = 1
|
||||
|
|
@ -317,7 +319,7 @@ def parse_text_script(text_pointer, text_id, map_id, txfar=False):
|
|||
#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(extract_maps.rom[offset])) + " on map_id=" + str(map_id) + " text_id=" + str(text_id)
|
||||
print("Unknown text command at " + hex(offset) + " - command: " + hex(ord(extract_maps.rom[offset])) + " on map_id=" + str(map_id) + " text_id=" + str(text_id))
|
||||
|
||||
#end at the first unknown command
|
||||
end = True
|
||||
|
|
@ -359,7 +361,7 @@ def analyze_texts():
|
|||
if debug:
|
||||
if len(TX_FAR.keys()) > 0:
|
||||
#print "TX_FAR object: " + str(TX_FAR)
|
||||
print "processing a TX_FAR at " + hex(commands[command_id]["pointer"]) + "... first byte is: " + str(ord(extract_maps.rom[commands[command_id]["pointer"]])) + " .. offset: " + hex(commands[command_id]["pointer"])
|
||||
print("processing a TX_FAR at " + hex(commands[command_id]["pointer"]) + "... first byte is: " + str(ord(extract_maps.rom[commands[command_id]["pointer"]])) + " .. offset: " + hex(commands[command_id]["pointer"]))
|
||||
##sys.exit(0)
|
||||
|
||||
commands[command_id]["TX_FAR"] = TX_FAR
|
||||
|
|
@ -382,7 +384,7 @@ def find_missing_08s(all_texts):
|
|||
if "type" in current_line.keys():
|
||||
if current_line["type"] == 0x8:
|
||||
missing_08s += 1
|
||||
print "missing $08 on map_id=" + str(map_id) + " text_id=" + str(text_id) + " line_id=" + str(line_id) + " at " + hex(current_line["start_address"])
|
||||
print("missing $08 on map_id=" + str(map_id) + " text_id=" + str(text_id) + " line_id=" + str(line_id) + " at " + hex(current_line["start_address"]))
|
||||
return missing_08s
|
||||
|
||||
def text_pretty_printer_at(start_address, label="SomeLabel"):
|
||||
|
|
@ -412,7 +414,7 @@ def text_pretty_printer_at(start_address, label="SomeLabel"):
|
|||
if not "lines" in commands[this_command].keys():
|
||||
command = commands[this_command]
|
||||
if not "type" in command.keys():
|
||||
print "ERROR in command: " + str(command)
|
||||
print("ERROR in command: " + str(command))
|
||||
continue #dunno what to do here?
|
||||
|
||||
if command["type"] == 0x1: #TX_RAM
|
||||
|
|
@ -501,7 +503,7 @@ def text_pretty_printer_at(start_address, label="SomeLabel"):
|
|||
byte_count += 1
|
||||
had_db_last = True
|
||||
else:
|
||||
print "ERROR in command: " + hex(command["type"])
|
||||
print("ERROR in command: " + hex(command["type"]))
|
||||
had_db_last = False
|
||||
|
||||
#everything else is for $0s, really
|
||||
|
|
@ -585,7 +587,7 @@ def text_pretty_printer_at(start_address, label="SomeLabel"):
|
|||
if len(output)!=0 and output[-1] == "\n":
|
||||
include_newline = ""
|
||||
output += include_newline + "; " + hex(start_address) + " + " + str(byte_count) + " bytes = " + hex(start_address + byte_count)
|
||||
print output
|
||||
print(output)
|
||||
return (output, byte_count)
|
||||
|
||||
def is_label_in_asm(label):
|
||||
|
|
@ -619,16 +621,16 @@ def find_undone_texts():
|
|||
address = extract_maps.map_headers[map_id]["texts"][text_id][1]["start_address"]
|
||||
|
||||
if not is_label_in_asm(label):
|
||||
print label + " map_id=" + str(map_id) + " text_id=" + str(text_id) + " at " + hex(address) + " byte is: " + hex(ord(extract_maps.rom[address]))
|
||||
print(label + " map_id=" + str(map_id) + " text_id=" + str(text_id) + " at " + hex(address) + " byte is: " + hex(ord(extract_maps.rom[address])))
|
||||
if not address in usable_table.keys():
|
||||
usable_table[address] = 1
|
||||
else:
|
||||
usable_table[address] += 1
|
||||
|
||||
print "\n\n which ones are priority?"
|
||||
print("\n\n which ones are priority?")
|
||||
sorted_results = sorted(usable_table.iteritems(), key=itemgetter(1), reverse=True)
|
||||
for result in sorted_results:
|
||||
print str(result[1]) + " times: " + hex(result[0])
|
||||
print(str(result[1]) + " times: " + hex(result[0]))
|
||||
|
||||
def scan_rom_for_tx_fars(printer=True):
|
||||
"""find TX_FARs
|
||||
|
|
@ -675,14 +677,14 @@ def scan_rom_for_tx_fars(printer=True):
|
|||
if address_bundle[0] in pre_handled:
|
||||
continue #already did this
|
||||
|
||||
print "-------"
|
||||
print "TX_FAR is at: " + hex(address_bundle[1])
|
||||
print("-------")
|
||||
print("TX_FAR is at: " + hex(address_bundle[1]))
|
||||
|
||||
#let's try printing out the TX_FAR?
|
||||
text_pretty_printer_at(address_bundle[1], "blah")
|
||||
|
||||
text_pretty_printer_at(address_bundle[0], "_blah")
|
||||
print "-------"
|
||||
print("-------")
|
||||
pre_handled.append(address_bundle[0])
|
||||
return possible_tx_far_targets
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-15
|
||||
#help with connection math
|
||||
import extract_maps
|
||||
from pretty_map_headers import map_constants, map_name_cleaner, offset_to_pointer
|
||||
from . import extract_maps
|
||||
from .pretty_map_headers import map_constants, map_name_cleaner, offset_to_pointer
|
||||
|
||||
def print_connections(map_id, in_connection_id=None, do_output=False):
|
||||
map1 = extract_maps.map_headers[map_id]
|
||||
|
|
@ -101,4 +103,4 @@ if __name__ == "__main__":
|
|||
|
||||
for map_id in extract_maps.map_headers.keys():
|
||||
if map_id not in extract_maps.bad_maps:
|
||||
print print_connections(map_id, do_output=True)
|
||||
print(print_connections(map_id, do_output=True))
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-14
|
||||
#split out blocksets into binary data files
|
||||
|
|
@ -5,7 +7,7 @@
|
|||
# but it's too many lines and will probably crash rgbasm.
|
||||
|
||||
import sys
|
||||
import extract_maps
|
||||
from . import extract_maps
|
||||
extract_maps.load_rom()
|
||||
spacing = " "
|
||||
|
||||
|
|
@ -77,7 +79,7 @@ for tileblock_id in tileblocks.keys():
|
|||
fh.write(main_data)
|
||||
fh.close()
|
||||
|
||||
print output
|
||||
print(output)
|
||||
|
||||
"""
|
||||
Tset00_Block:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-14
|
||||
#throw tilesets into separate files
|
||||
import extract_maps
|
||||
from . import extract_maps
|
||||
extract_maps.load_rom()
|
||||
|
||||
locations = {
|
||||
|
|
@ -29,9 +31,9 @@ locations = {
|
|||
for tileset_id in locations.keys():
|
||||
tileset = locations[tileset_id]
|
||||
|
||||
print "writing ../gfx/tilesets/" + tileset[2] + ".2bpp"
|
||||
print("writing ../gfx/tilesets/" + tileset[2] + ".2bpp")
|
||||
fh = open("../gfx/tilesets/" + tileset[2] + ".2bpp", "w")
|
||||
fh.write(extract_maps.rom[tileset[0]:tileset[1]])
|
||||
fh.close()
|
||||
|
||||
print "Done."
|
||||
print("Done.")
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-27
|
||||
#fix trainer header labels to not suck so much
|
||||
import analyze_incbins
|
||||
from . import analyze_incbins
|
||||
|
||||
def replace_trainer_header_labels(debug=False):
|
||||
"""trainer header labels could be better"""
|
||||
asm = analyze_incbins.asm
|
||||
if debug: print str(type(asm))
|
||||
if debug: print(str(type(asm)))
|
||||
single_asm = "\n".join(asm)
|
||||
current_map_name = "asdjkl;"
|
||||
line_id = 0
|
||||
|
|
@ -31,8 +33,8 @@ def replace_trainer_header_labels(debug=False):
|
|||
new_label = current_map_name + "TH" + str(trainer_header_counter) #trainer_header_name
|
||||
single_asm = single_asm.replace(old_label + ":", new_label + ":")
|
||||
single_asm = single_asm.replace(old_label + "\n", new_label + "\n")
|
||||
if debug: print "old_label = " + old_label
|
||||
if debug: print "new_label = " + new_label
|
||||
if debug: print("old_label = " + old_label)
|
||||
if debug: print("new_label = " + new_label)
|
||||
|
||||
trainer_header_counter += 1
|
||||
|
||||
|
|
@ -50,8 +52,8 @@ def replace_trainer_header_labels(debug=False):
|
|||
single_asm = single_asm.replace(old_label + ":", new_label + ":")
|
||||
single_asm = single_asm.replace(old_label + "\n", new_label + "\n")
|
||||
single_asm = single_asm.replace(old_label + " ;", new_label + " ;")
|
||||
if debug: print "old_label = " + old_label
|
||||
if debug: print "new_label = " + new_label
|
||||
if debug: print("old_label = " + old_label)
|
||||
if debug: print("new_label = " + new_label)
|
||||
#replace a text label
|
||||
elif " TextAfterBattle" in line and not current_map_name in line:
|
||||
old_label = line.split("dw ")[1].split(" ;")[0]
|
||||
|
|
@ -59,8 +61,8 @@ def replace_trainer_header_labels(debug=False):
|
|||
single_asm = single_asm.replace(old_label + ":", new_label + ":")
|
||||
single_asm = single_asm.replace(old_label + "\n", new_label + "\n")
|
||||
single_asm = single_asm.replace(old_label + " ;", new_label + " ;")
|
||||
if debug: print "old_label = " + old_label
|
||||
if debug: print "new_label = " + new_label
|
||||
if debug: print("old_label = " + old_label)
|
||||
if debug: print("new_label = " + new_label)
|
||||
#replace a text label
|
||||
elif " TextEndBattle" in line and not current_map_name in line:
|
||||
old_label = line.split("dw ")[1].split(" ;")[0]
|
||||
|
|
@ -68,12 +70,12 @@ def replace_trainer_header_labels(debug=False):
|
|||
single_asm = single_asm.replace(old_label + ":", new_label + ":")
|
||||
single_asm = single_asm.replace(old_label + "\n", new_label + "\n")
|
||||
single_asm = single_asm.replace(old_label + " ;", new_label + " ;")
|
||||
if debug: print "old_label = " + old_label
|
||||
if debug: print "new_label = " + new_label
|
||||
if debug: print("old_label = " + old_label)
|
||||
if debug: print("new_label = " + new_label)
|
||||
|
||||
line_id += 1
|
||||
|
||||
print single_asm
|
||||
print(single_asm)
|
||||
|
||||
if __name__ == "__main__":
|
||||
analyze_incbins.load_asm()
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-09
|
||||
import extract_maps
|
||||
from . import extract_maps
|
||||
import os
|
||||
import json
|
||||
from copy import copy, deepcopy
|
||||
from pretty_map_headers import random_hash, map_name_cleaner
|
||||
from .pretty_map_headers import random_hash, map_name_cleaner
|
||||
from ctypes import c_int8
|
||||
import sys
|
||||
|
||||
|
|
@ -530,7 +532,7 @@ temp_opt_table = [
|
|||
conflict_table = {}
|
||||
for line in temp_opt_table:
|
||||
if line[1] in conflict_table.keys():
|
||||
print "CONFLICT: " + line[0] + " ($" + hex(line[1])[2:] + ") .... " + conflict_table[line[1]]
|
||||
print("CONFLICT: " + line[0] + " ($" + hex(line[1])[2:] + ") .... " + conflict_table[line[1]])
|
||||
else:
|
||||
conflict_table[line[1]] = line[0]
|
||||
|
||||
|
|
@ -562,8 +564,8 @@ def load_labels(filename="labels.json"):
|
|||
if os.path.exists(filename):
|
||||
all_labels = json.loads(open(filename, "r").read())
|
||||
else:
|
||||
print "You must run analyze_incbins.scan_for_predefined_labels() to create \"labels.json\". Trying..."
|
||||
import analyze_incbins
|
||||
print("You must run analyze_incbins.scan_for_predefined_labels() to create \"labels.json\". Trying...")
|
||||
from . import analyze_incbins
|
||||
analyze_incbins.scan_for_predefined_labels()
|
||||
load_labels()
|
||||
|
||||
|
|
@ -607,7 +609,7 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000):
|
|||
bank_id = 0
|
||||
if original_offset > 0x8000:
|
||||
bank_id = original_offset / 0x4000
|
||||
print "bank id is: " + str(bank_id)
|
||||
print("bank id is: " + str(bank_id))
|
||||
|
||||
last_hl_address = None #for when we're scanning the main map script
|
||||
last_a_address = None
|
||||
|
|
@ -849,4 +851,4 @@ if __name__ == "__main__":
|
|||
extract_maps.load_map_pointers()
|
||||
extract_maps.read_all_map_headers()
|
||||
|
||||
print output_bank_opcodes(int(sys.argv[1], 16))[0]
|
||||
print(output_bank_opcodes(int(sys.argv[1], 16))[0])
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import absolute_import
|
||||
import json
|
||||
|
||||
import analyze_incbins
|
||||
from . import analyze_incbins
|
||||
analyze_incbins.scan_for_predefined_labels()
|
||||
|
||||
with open('../pokered.sym', 'w') as sym:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-05
|
||||
#insert object data into pokered.asm
|
||||
import extract_maps
|
||||
from pretty_map_headers import map_name_cleaner, object_data_pretty_printer, make_object_label_name, make_text_label, map_constants
|
||||
from analyze_incbins import asm, offset_to_pointer, find_incbin_to_replace_for, split_incbin_line_into_three, generate_diff_insert, load_asm, isolate_incbins, process_incbins
|
||||
import analyze_incbins
|
||||
from . import extract_maps
|
||||
from .pretty_map_headers import map_name_cleaner, object_data_pretty_printer, make_object_label_name, make_text_label, map_constants
|
||||
from .analyze_incbins import asm, offset_to_pointer, find_incbin_to_replace_for, split_incbin_line_into_three, generate_diff_insert, load_asm, isolate_incbins, process_incbins
|
||||
from . import analyze_incbins
|
||||
import os, sys
|
||||
import subprocess
|
||||
spacing = " "
|
||||
|
|
@ -17,7 +19,7 @@ def insert_object(map_id):
|
|||
|
||||
line_number = find_incbin_to_replace_for(address)
|
||||
if line_number == None:
|
||||
print "skipping object data for map " + str(map["id"]) + " at " + map["object_data_pointer"] + " for " + str(size) + " bytes."
|
||||
print("skipping object data for map " + str(map["id"]) + " at " + map["object_data_pointer"] + " for " + str(size) + " bytes.")
|
||||
return
|
||||
|
||||
newlines = split_incbin_line_into_three(line_number, address, size)
|
||||
|
|
@ -36,9 +38,9 @@ def insert_object(map_id):
|
|||
newlines = "\n".join(line for line in newlines)
|
||||
|
||||
diff = generate_diff_insert(line_number, newlines)
|
||||
print diff
|
||||
print(diff)
|
||||
|
||||
print "... Applying diff."
|
||||
print("... Applying diff.")
|
||||
|
||||
#write the diff to a file
|
||||
fh = open("temp.patch", "w")
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-07, 2012-01-17, 2012-01-27
|
||||
#insert TX_FAR targets into pokered.asm
|
||||
#and other insertion tasks
|
||||
import extract_maps
|
||||
from analyze_texts import analyze_texts, text_pretty_printer_at, scan_rom_for_tx_fars
|
||||
from pretty_map_headers import map_name_cleaner, make_text_label, map_constants, find_all_tx_fars, tx_far_pretty_printer, tx_far_label_maker
|
||||
import pretty_map_headers
|
||||
from analyze_incbins import asm, offset_to_pointer, find_incbin_to_replace_for, split_incbin_line_into_three, generate_diff_insert, load_asm, isolate_incbins, process_incbins, reset_incbins, apply_diff
|
||||
import analyze_incbins
|
||||
from gbz80disasm import text_asm_pretty_printer, output_bank_opcodes, load_labels, find_label
|
||||
from . import extract_maps
|
||||
from .analyze_texts import analyze_texts, text_pretty_printer_at, scan_rom_for_tx_fars
|
||||
from .pretty_map_headers import map_name_cleaner, make_text_label, map_constants, find_all_tx_fars, tx_far_pretty_printer, tx_far_label_maker
|
||||
from . import pretty_map_headers
|
||||
from .analyze_incbins import asm, offset_to_pointer, find_incbin_to_replace_for, split_incbin_line_into_three, generate_diff_insert, load_asm, isolate_incbins, process_incbins, reset_incbins, apply_diff
|
||||
from . import analyze_incbins
|
||||
from .gbz80disasm import text_asm_pretty_printer, output_bank_opcodes, load_labels, find_label
|
||||
import os, sys
|
||||
import subprocess
|
||||
spacing = " "
|
||||
|
|
@ -66,13 +68,13 @@ def insert_tx_far(map_id, text_id, tx_far_line=None):
|
|||
|
||||
line_number = find_incbin_to_replace_for(start_address)
|
||||
if line_number == None:
|
||||
print "skipping tx_far for map_id=" + str(map_id) + " text_id=" + str(text_id) + " text_pointer=" + hex(text_pointer) + " tx_far_start_address=" + hex(start_address)
|
||||
print("skipping tx_far for map_id=" + str(map_id) + " text_id=" + str(text_id) + " text_pointer=" + hex(text_pointer) + " tx_far_start_address=" + hex(start_address))
|
||||
return
|
||||
|
||||
#also do a name check
|
||||
label = tx_far_label_maker(extract_maps.map_headers[map_id]["name"], text_id)
|
||||
if (label + ":") in "\n".join(analyze_incbins.asm):
|
||||
print "skipping tx_far for map_id=" + str(map_id) + " text_id=" + str(text_id) + " text_pointer=" + hex(text_pointer) + " tx_far_start_address=" + hex(start_address)
|
||||
print("skipping tx_far for map_id=" + str(map_id) + " text_id=" + str(text_id) + " text_pointer=" + hex(text_pointer) + " tx_far_start_address=" + hex(start_address))
|
||||
return
|
||||
|
||||
newlines = split_incbin_line_into_three(line_number, start_address, end_address - start_address)
|
||||
|
|
@ -105,8 +107,8 @@ def insert_tx_far(map_id, text_id, tx_far_line=None):
|
|||
newlines = newlines.replace("Char52", "$52")
|
||||
|
||||
diff = generate_diff_insert(line_number, newlines)
|
||||
print "working on map_id=" + str(map_id) + " text_id=" + str(text_id)
|
||||
print diff
|
||||
print("working on map_id=" + str(map_id) + " text_id=" + str(text_id))
|
||||
print(diff)
|
||||
apply_diff(diff)
|
||||
|
||||
def insert_all_tx_far_targets():
|
||||
|
|
@ -184,12 +186,12 @@ def insert_texts_label(map_id):
|
|||
|
||||
line_number = find_incbin_to_replace_for(texts_pointer)
|
||||
if line_number == None:
|
||||
print "skipping texts label for map_id=" + str(map_id) + " texts_pointer=" + hex(texts_pointer) + " because the address is taken"
|
||||
print("skipping texts label for map_id=" + str(map_id) + " texts_pointer=" + hex(texts_pointer) + " because the address is taken")
|
||||
return
|
||||
|
||||
#also do a name check
|
||||
if (label + ":") in "\n".join(analyze_incbins.asm):
|
||||
print "skipping texts label for map_id=" + str(map_id) + " texts_pointer=" + hex(texts_pointer) + " because the label is already used"
|
||||
print("skipping texts label for map_id=" + str(map_id) + " texts_pointer=" + hex(texts_pointer) + " because the label is already used")
|
||||
return
|
||||
|
||||
newlines = split_incbin_line_into_three(line_number, texts_pointer, len(map2["referenced_texts"])*2 )
|
||||
|
|
@ -208,8 +210,8 @@ def insert_texts_label(map_id):
|
|||
newlines = newlines.replace("$x", "$")
|
||||
|
||||
diff = generate_diff_insert(line_number, newlines)
|
||||
print "working on map_id=" + str(map_id) + " texts_pointer=" + hex(texts_pointer)
|
||||
print diff
|
||||
print("working on map_id=" + str(map_id) + " texts_pointer=" + hex(texts_pointer))
|
||||
print(diff)
|
||||
apply_diff(diff)
|
||||
|
||||
#untested as of 2012-01-07
|
||||
|
|
@ -241,7 +243,7 @@ def txt_to_tx_far_pretty_printer(address, label, target_label, include_byte=Fals
|
|||
|
||||
def insert_text_label_tx_far(map_id, text_id):
|
||||
if map_id in extract_maps.bad_maps:
|
||||
print "bad map id=" + str(map_id)
|
||||
print("bad map id=" + str(map_id))
|
||||
return
|
||||
map2 = extract_maps.map_headers[map_id]
|
||||
if map2["texts"][text_id] == {0: {}}: return None
|
||||
|
|
@ -253,7 +255,7 @@ def insert_text_label_tx_far(map_id, text_id):
|
|||
if 0x4000 <= start_address <= 0x7fff:
|
||||
start_address = extract_maps.calculate_pointer(start_address, int(map2["bank"],16))
|
||||
include_byte = False
|
||||
print map2["texts"][text_id]
|
||||
print(map2["texts"][text_id])
|
||||
if "type" in map2["texts"][text_id][1].keys():
|
||||
if map2["texts"][text_id][1]["type"] == 0x50:
|
||||
include_byte = True
|
||||
|
|
@ -261,12 +263,12 @@ def insert_text_label_tx_far(map_id, text_id):
|
|||
|
||||
line_number = find_incbin_to_replace_for(start_address)
|
||||
if line_number == None:
|
||||
print "skipping text label that calls TX_FAR for map_id=" + str(map_id) + " text_id=" + str(text_id) + " because the address is taken " + hex(start_address)
|
||||
print("skipping text label that calls TX_FAR for map_id=" + str(map_id) + " text_id=" + str(text_id) + " because the address is taken " + hex(start_address))
|
||||
return
|
||||
|
||||
#also do a name check
|
||||
if 1 < ("\n".join(analyze_incbins.asm)).count("\n" + label + ":"):
|
||||
print "skipping text label that calls TX_FAR for map_id=" + str(map_id) + " text_id" + str(text_id) + " because the label is already used (" + label + ":)"
|
||||
print("skipping text label that calls TX_FAR for map_id=" + str(map_id) + " text_id" + str(text_id) + " because the label is already used (" + label + ":)")
|
||||
return
|
||||
|
||||
extra = 0
|
||||
|
|
@ -288,8 +290,8 @@ def insert_text_label_tx_far(map_id, text_id):
|
|||
newlines = newlines.replace("$x", "$")
|
||||
|
||||
diff = generate_diff_insert(line_number, newlines)
|
||||
print "working on map_id=" + str(map_id) + " text_id=" + str(text_id)
|
||||
print diff
|
||||
print("working on map_id=" + str(map_id) + " text_id=" + str(text_id))
|
||||
print(diff)
|
||||
apply_diff(diff)
|
||||
|
||||
def insert_all_text_labels():
|
||||
|
|
@ -321,17 +323,17 @@ def insert_08_asm(map_id, text_id, line_id=0):
|
|||
start_address = all_texts[map_id][text_id][line_id]["start_address"]
|
||||
|
||||
(text_asm, end_address) = text_asm_pretty_printer(label, start_address)
|
||||
print "end address is: " + hex(end_address)
|
||||
print("end address is: " + hex(end_address))
|
||||
|
||||
#find where to insert the assembly
|
||||
line_number = find_incbin_to_replace_for(start_address)
|
||||
if line_number == None:
|
||||
print "skipping text label for a $08 on map_id=" + str(map_id) + " text_id=" + str(text_id) + " because the address is taken"
|
||||
print("skipping text label for a $08 on map_id=" + str(map_id) + " text_id=" + str(text_id) + " because the address is taken")
|
||||
return
|
||||
|
||||
#also do a name check
|
||||
if 1 <= ("\n".join(analyze_incbins.asm)).count("\n" + label + ":"):
|
||||
print "skipping text label for a $08 on map_id=" + str(map_id) + " text_id=" + str(text_id) + " because the label is already taken (" + label + ":)"
|
||||
print("skipping text label for a $08 on map_id=" + str(map_id) + " text_id=" + str(text_id) + " because the label is already taken (" + label + ":)")
|
||||
return
|
||||
|
||||
newlines = split_incbin_line_into_three(line_number, start_address, end_address - start_address )
|
||||
|
|
@ -351,8 +353,8 @@ def insert_08_asm(map_id, text_id, line_id=0):
|
|||
newlines = newlines.replace("$x", "$")
|
||||
|
||||
diff = generate_diff_insert(line_number, newlines)
|
||||
print "working on map_id=" + str(map_id) + " text_id=" + str(text_id)
|
||||
print diff
|
||||
print("working on map_id=" + str(map_id) + " text_id=" + str(text_id))
|
||||
print(diff)
|
||||
result = apply_diff(diff)
|
||||
|
||||
if result == False:
|
||||
|
|
@ -376,7 +378,7 @@ def insert_all_08s():
|
|||
text_id = the_08_line[1]
|
||||
line_id = the_08_line[2]
|
||||
|
||||
print "processing map_id=" + str(map_id) + " text_id=" + str(text_id)
|
||||
print("processing map_id=" + str(map_id) + " text_id=" + str(text_id))
|
||||
insert_08_asm(map_id, text_id, line_id)
|
||||
|
||||
#reset everything
|
||||
|
|
@ -396,17 +398,17 @@ def insert_all_08s():
|
|||
def insert_asm(start_address, label, text_asm=None, end_address=None):
|
||||
if text_asm == None and end_address == None:
|
||||
(text_asm, end_address) = text_asm_pretty_printer(label, start_address, include_08=False)
|
||||
print "end address is: " + hex(end_address)
|
||||
print("end address is: " + hex(end_address))
|
||||
|
||||
#find where to insert the assembly
|
||||
line_number = find_incbin_to_replace_for(start_address)
|
||||
if line_number == None:
|
||||
print "skipping asm because the address is taken"
|
||||
print("skipping asm because the address is taken")
|
||||
return False
|
||||
|
||||
#name check
|
||||
if (label + ":") in "\n".join(analyze_incbins.asm):
|
||||
print "skipping asm because the label is taken"
|
||||
print("skipping asm because the label is taken")
|
||||
return False
|
||||
|
||||
newlines = split_incbin_line_into_three(line_number, start_address, end_address - start_address )
|
||||
|
|
@ -426,7 +428,7 @@ def insert_asm(start_address, label, text_asm=None, end_address=None):
|
|||
newlines = newlines.replace("$x", "$")
|
||||
|
||||
diff = generate_diff_insert(line_number, newlines)
|
||||
print diff
|
||||
print(diff)
|
||||
result = apply_diff(diff, try_fixing=True)
|
||||
return True
|
||||
|
||||
|
|
@ -436,13 +438,13 @@ def insert_text(address, label, apply=False, try_fixing=True):
|
|||
|
||||
line_number = find_incbin_to_replace_for(start_address)
|
||||
if line_number == None:
|
||||
print "skipping text at " + hex(start_address) + " with address " + label
|
||||
print("skipping text at " + hex(start_address) + " with address " + label)
|
||||
return "skip"
|
||||
|
||||
#another reason to skip is if the interval is 0
|
||||
processed_incbin = analyze_incbins.processed_incbins[line_number]
|
||||
if processed_incbin["interval"] == 0:
|
||||
print "skipping text at " + hex(start_address) + " with address " + label + " because the interval is 0"
|
||||
print("skipping text at " + hex(start_address) + " with address " + label + " because the interval is 0")
|
||||
return "skip"
|
||||
|
||||
text_asm, byte_count = text_pretty_printer_at(start_address, label)
|
||||
|
|
@ -466,7 +468,7 @@ def insert_text(address, label, apply=False, try_fixing=True):
|
|||
newlines = newlines.replace("Char52", "$52")
|
||||
|
||||
diff = generate_diff_insert(line_number, newlines)
|
||||
print diff
|
||||
print(diff)
|
||||
if apply:
|
||||
return apply_diff(diff, try_fixing=try_fixing)
|
||||
else: #simulate a successful insertion
|
||||
|
|
@ -560,16 +562,16 @@ def scan_for_map_scripts_pointer():
|
|||
isolate_incbins()
|
||||
process_incbins()
|
||||
|
||||
print "map_id=" + str(map_id) + " scripts are: " + str(script_pointers)
|
||||
print("map_id=" + str(map_id) + " scripts are: " + str(script_pointers))
|
||||
|
||||
if last_hl_address == None: last_hl_address = "None"
|
||||
else: last_hl_address = hex(last_hl_address)
|
||||
|
||||
if hl_pointer != None and hl_pointer != "None": hl_pointer = hex(hl_pointer)
|
||||
|
||||
print "map_id=" + str(map_id) + " " + map2["name"] + " script_pointer=" + hex(script_pointer) + " script_pointers=" + hl_pointer + first_script_text
|
||||
print main_asm_output
|
||||
print "\n\n"
|
||||
print("map_id=" + str(map_id) + " " + map2["name"] + " script_pointer=" + hex(script_pointer) + " script_pointers=" + hl_pointer + first_script_text)
|
||||
print(main_asm_output)
|
||||
print("\n\n")
|
||||
|
||||
#insert asm for the main script
|
||||
result = insert_asm(script_pointer, map_name_cleaner(map2["name"], None)[:-2] + "Script")
|
||||
|
|
@ -625,8 +627,8 @@ def scan_for_map_scripts_pointer():
|
|||
isolate_incbins()
|
||||
process_incbins()
|
||||
else:
|
||||
print "trouble inserting map script pointer list"
|
||||
print script_asm
|
||||
print("trouble inserting map script pointer list")
|
||||
print(script_asm)
|
||||
sys.exit(0)
|
||||
|
||||
def scan_rom_for_tx_fars_and_insert():
|
||||
|
|
@ -647,7 +649,7 @@ def scan_rom_for_tx_fars_and_insert():
|
|||
|
||||
#let's also do a quick check if it might be in the file already
|
||||
if not (": ; " + hex(tx_far_address) in analyze_incbins.asm):
|
||||
print "inserting text at " + hex(tx_far_address)
|
||||
print("inserting text at " + hex(tx_far_address))
|
||||
result = insert_text(tx_far_target_address, tx_far_target_label, apply=True)
|
||||
else:
|
||||
#we can't just pretend like it worked, because we don't know what label was used
|
||||
|
|
@ -662,7 +664,7 @@ def scan_rom_for_tx_fars_and_insert():
|
|||
result2 = insert_text(tx_far_address, tx_far_label, apply=True)
|
||||
local_reset_incbins()
|
||||
elif result == "skip":
|
||||
print "skipping " + hex(tx_far_address)
|
||||
print("skipping " + hex(tx_far_address))
|
||||
# result2 = insert_text(tx_far_address, tx_far_label, apply=True)
|
||||
# local_reset_incbins()
|
||||
|
||||
|
|
@ -787,12 +789,12 @@ def insert_base_stats(id):
|
|||
line_number = find_incbin_to_replace_for(address)
|
||||
label = get_mon_name(id).title() + "BaseStats"
|
||||
if line_number == None:
|
||||
print "skipping, already inserted at " + hex(address)
|
||||
print("skipping, already inserted at " + hex(address))
|
||||
return
|
||||
|
||||
#also do a name check
|
||||
if (label + ":") in "\n".join(analyze_incbins.asm):
|
||||
print "skipping " + label + " because it is already in use.."
|
||||
print("skipping " + label + " because it is already in use..")
|
||||
return
|
||||
|
||||
newlines = split_incbin_line_into_three(line_number, address, 28 )
|
||||
|
|
@ -811,7 +813,7 @@ def insert_base_stats(id):
|
|||
newlines = newlines.replace("$x", "$")
|
||||
|
||||
diff = generate_diff_insert(line_number, newlines)
|
||||
print diff
|
||||
print(diff)
|
||||
apply_diff(diff, try_fixing=False, do_compile=False)
|
||||
|
||||
def insert_all_base_stats():
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-15
|
||||
#dump map height/width constants
|
||||
import extract_maps
|
||||
from pretty_map_headers import map_name_cleaner, map_constants
|
||||
from . import extract_maps
|
||||
from .pretty_map_headers import map_name_cleaner, map_constants
|
||||
|
||||
def get_map_size_constants(do_sed=False):
|
||||
output = ""
|
||||
|
|
@ -34,4 +36,4 @@ if __name__ == "__main__":
|
|||
extract_maps.load_rom()
|
||||
extract_maps.load_map_pointers()
|
||||
extract_maps.read_all_map_headers()
|
||||
print get_map_size_constants(do_sed=True)
|
||||
print(get_map_size_constants(do_sed=True))
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-03
|
||||
#purpose: extract .blk files from baserom.gbc
|
||||
#note: use python2.7 because of subprocess in analyze_incbins
|
||||
import extract_maps #rom, assert_rom, load_rom, calculate_pointer, load_map_pointers, read_all_map_headers, map_headers
|
||||
from pretty_map_headers import map_name_cleaner
|
||||
from analyze_incbins import asm, offset_to_pointer, find_incbin_to_replace_for, split_incbin_line_into_three, generate_diff_insert, load_asm, isolate_incbins, process_incbins
|
||||
import analyze_incbins
|
||||
from . import extract_maps #rom, assert_rom, load_rom, calculate_pointer, load_map_pointers, read_all_map_headers, map_headers
|
||||
from .pretty_map_headers import map_name_cleaner
|
||||
from .analyze_incbins import asm, offset_to_pointer, find_incbin_to_replace_for, split_incbin_line_into_three, generate_diff_insert, load_asm, isolate_incbins, process_incbins
|
||||
from . import analyze_incbins
|
||||
import os, sys
|
||||
import subprocess
|
||||
spacing = " "
|
||||
|
|
@ -32,7 +34,7 @@ def extract_map_block_data(map_id, savefile=False):
|
|||
full_filepath = "maps/" + filename + ".blk"
|
||||
|
||||
if savefile:
|
||||
print "Saving ../maps/" + filename + ".blk for map id=" + str(map_id)
|
||||
print("Saving ../maps/" + filename + ".blk for map id=" + str(map_id))
|
||||
fh = open("../maps/" + filename + ".blk", "w")
|
||||
fh.write(blocksdata)
|
||||
fh.close()
|
||||
|
|
@ -61,12 +63,12 @@ def insert_map_block_label(map_id):
|
|||
x = int(map["x"], 16)
|
||||
size = x*y
|
||||
|
||||
print "map name: " + map["name"]
|
||||
print "map address: " + map["map_pointer"]
|
||||
print("map name: " + map["name"])
|
||||
print("map address: " + map["map_pointer"])
|
||||
|
||||
line_number = find_incbin_to_replace_for(address)
|
||||
if line_number == None:
|
||||
print "skipping map id=" + str(map_id) + " probably because it was already done."
|
||||
print("skipping map id=" + str(map_id) + " probably because it was already done.")
|
||||
used_map_pointers.append(map["map_pointer"])
|
||||
return
|
||||
|
||||
|
|
@ -90,8 +92,8 @@ def insert_map_block_label(map_id):
|
|||
newlines = newlines.replace("$x", "$")
|
||||
|
||||
diff = generate_diff_insert(line_number, newlines)
|
||||
print diff
|
||||
print "... Applying diff."
|
||||
print(diff)
|
||||
print("... Applying diff.")
|
||||
|
||||
#write the diff to a file
|
||||
fh = open("temp.patch", "w")
|
||||
|
|
@ -141,14 +143,14 @@ def insert_all_labels():
|
|||
#check if this label is already in there
|
||||
cleaned_name, label_text, filename, full_filepath = make_labels(mapmap["name"])
|
||||
if label_text in "\n".join(line for line in analyze_incbins.asm):
|
||||
print "skipping (found label text in asm already)"
|
||||
print("skipping (found label text in asm already)")
|
||||
used_map_pointers.append(mapmap["map_pointer"])
|
||||
continue #skip this one
|
||||
|
||||
isolate_incbins()
|
||||
process_incbins()
|
||||
|
||||
print "XYZ|" + mapmap["name"]
|
||||
print("XYZ|" + mapmap["name"])
|
||||
insert_map_block_label(map)
|
||||
|
||||
used_map_pointers.append(mapmap["map_pointer"])
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-02
|
||||
#purpose: dump asm for each map header
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
import json
|
||||
import extract_maps
|
||||
import sprite_helper
|
||||
from . import extract_maps
|
||||
from . import sprite_helper
|
||||
import random
|
||||
import string
|
||||
import analyze_texts #hopefully not a dependency loop
|
||||
from . import analyze_texts #hopefully not a dependency loop
|
||||
|
||||
base = 16
|
||||
spacing = " "
|
||||
|
|
@ -395,7 +397,7 @@ def write_connections(north, south, west, east):
|
|||
if not north and south and not west and east: return "SOUTH | EAST"
|
||||
if north and not south and west and not east: return "NORTH | WEST"
|
||||
if north and not south and not west and east: return "NORTH | EAST"
|
||||
raise Exception, "unpredicted outcome on write_connections"
|
||||
raise Exception("unpredicted outcome on write_connections")
|
||||
|
||||
#TODO: make this elegant
|
||||
def connection_line(byte):
|
||||
|
|
@ -551,7 +553,7 @@ def object_data_pretty_printer(map_id):
|
|||
|
||||
try:
|
||||
warp_to_map_constant = map_constants[warp_to_map_id]
|
||||
except Exception, exc:
|
||||
except Exception as exc:
|
||||
warp_to_map_constant = "$" + hex(warp_to_map_id)[2:]
|
||||
|
||||
output += spacing + "db $" + hex(int(y))[2:] + ", $" + hex(int(x))[2:] + ", $" + hex(int(warp_to_point))[2:] + ", " + warp_to_map_constant + "\n"
|
||||
|
|
@ -606,7 +608,7 @@ def object_data_pretty_printer(map_id):
|
|||
try:
|
||||
previous_location = map_constants[object["warps"][warp_to_id]["warp_to_map_id"]]
|
||||
comment = " ; " + previous_location
|
||||
except Exception, exc:
|
||||
except Exception as exc:
|
||||
comment = ""
|
||||
|
||||
output += spacing + "EVENT_DISP $" + map_width[2:] + ", $" + warp_to_y + ", $" + warp_to_x + comment + "\n"
|
||||
|
|
@ -727,7 +729,7 @@ def print_all_headers():
|
|||
|
||||
for map in maps:
|
||||
output = map_header_pretty_printer(map)
|
||||
if output != "": print output
|
||||
if output != "": print(output)
|
||||
|
||||
if __name__ == "__main__":
|
||||
#read binary data from file
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-16
|
||||
from optparse import OptionParser
|
||||
from analyze_texts import text_pretty_printer_at
|
||||
from .analyze_texts import text_pretty_printer_at
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog address label"
|
||||
parser = OptionParser(usage)
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) == 1:
|
||||
print "usage: python pretty_text.py address label"
|
||||
print("usage: python pretty_text.py address label")
|
||||
args.append("UnnamedText_" + (args[0].replace("0x", "")))
|
||||
elif len(args) != 2:
|
||||
parser.error("we need both an address and a label")
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-24
|
||||
from optparse import OptionParser
|
||||
from gbz80disasm import load_labels, find_label
|
||||
from extract_maps import calculate_pointer
|
||||
from .gbz80disasm import load_labels, find_label
|
||||
from .extract_maps import calculate_pointer
|
||||
import sys
|
||||
spacing = "\t"
|
||||
rom = None
|
||||
|
|
@ -46,8 +48,8 @@ def pretty_print_trainer_header(address, label=None):
|
|||
partial_pointer = (pointer_byte1 + (pointer_byte2 << 8))
|
||||
label = find_label(partial_pointer, bank_id)
|
||||
if label == None:
|
||||
print "label not found for (TextBeforeBattle) " + hex(calculate_pointer(partial_pointer, bank_id))
|
||||
print ""
|
||||
print("label not found for (TextBeforeBattle) " + hex(calculate_pointer(partial_pointer, bank_id)))
|
||||
print("")
|
||||
label = "$" + hex(partial_pointer)[2:]
|
||||
#sys.exit(0)
|
||||
|
||||
|
|
@ -59,8 +61,8 @@ def pretty_print_trainer_header(address, label=None):
|
|||
partial_pointer = (pointer_byte1 + (pointer_byte2 << 8))
|
||||
label = find_label(partial_pointer, bank_id)
|
||||
if label == None:
|
||||
print "label not found for (TextAfterBattle) " + hex(calculate_pointer(partial_pointer, bank_id))
|
||||
print ""
|
||||
print("label not found for (TextAfterBattle) " + hex(calculate_pointer(partial_pointer, bank_id)))
|
||||
print("")
|
||||
label = "$" + hex(partial_pointer)[2:]
|
||||
#sys.exit(0)
|
||||
|
||||
|
|
@ -72,8 +74,8 @@ def pretty_print_trainer_header(address, label=None):
|
|||
partial_pointer = (pointer_byte1 + (pointer_byte2 << 8))
|
||||
label = find_label(partial_pointer, bank_id)
|
||||
if label == None:
|
||||
print "label not found for (TextEndBattle) " + hex(calculate_pointer(partial_pointer, bank_id))
|
||||
print ""
|
||||
print("label not found for (TextEndBattle) " + hex(calculate_pointer(partial_pointer, bank_id)))
|
||||
print("")
|
||||
label = "$" + hex(partial_pointer)[2:]
|
||||
#sys.exit(0)
|
||||
|
||||
|
|
@ -85,8 +87,8 @@ def pretty_print_trainer_header(address, label=None):
|
|||
partial_pointer = (pointer_byte1 + (pointer_byte2 << 8))
|
||||
label = find_label(partial_pointer, bank_id)
|
||||
if label == None:
|
||||
print "label not found for (TextEndBattle) " + hex(calculate_pointer(partial_pointer, bank_id))
|
||||
print ""
|
||||
print("label not found for (TextEndBattle) " + hex(calculate_pointer(partial_pointer, bank_id)))
|
||||
print("")
|
||||
label = "$" + hex(partial_pointer)[2:]
|
||||
#sys.exit(0)
|
||||
|
||||
|
|
@ -99,7 +101,7 @@ def pretty_print_trainer_header(address, label=None):
|
|||
def all_trainer_headers_at(address):
|
||||
i = 0
|
||||
while ord(rom[address + (i*12)]) != 0xff:
|
||||
print pretty_print_trainer_header(address + (i*12))
|
||||
print(pretty_print_trainer_header(address + (i*12)))
|
||||
i += 1
|
||||
|
||||
def main():
|
||||
|
|
@ -109,7 +111,7 @@ def main():
|
|||
parser = OptionParser(usage)
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) == 1:
|
||||
print "usage: python pretty_trainer_headers.py address label\n"
|
||||
print("usage: python pretty_trainer_headers.py address label\n")
|
||||
args.append("TrainerHeader_" + (args[0].replace("0x", "")))
|
||||
elif len(args) != 2:
|
||||
parser.error("we need both an address and a label")
|
||||
|
|
@ -120,7 +122,7 @@ def main():
|
|||
rom = open("../baserom.gbc", "r").read()
|
||||
|
||||
#print pretty_print_trainer_header(address, label)
|
||||
print all_trainer_headers_at(address)
|
||||
print(all_trainer_headers_at(address))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-15
|
||||
#replace dimensions with constants
|
||||
import sys #for non-newline-terminated output :/
|
||||
from add_map_labels_to_map_headers import find_with_start_of_line
|
||||
from pretty_map_headers import map_name_cleaner, spacing, offset_to_pointer, map_constants
|
||||
from connection_helper import print_connections
|
||||
from .add_map_labels_to_map_headers import find_with_start_of_line
|
||||
from .pretty_map_headers import map_name_cleaner, spacing, offset_to_pointer, map_constants
|
||||
from .connection_helper import print_connections
|
||||
from ctypes import c_int8
|
||||
|
||||
# X/Y_Movement_Of_Connection
|
||||
|
|
@ -234,7 +235,7 @@ def replace_values():
|
|||
connection_offset += 6
|
||||
|
||||
if __name__ == "__main__":
|
||||
import extract_maps
|
||||
from . import extract_maps
|
||||
extract_maps.load_rom()
|
||||
extract_maps.load_map_pointers()
|
||||
extract_maps.read_all_map_headers()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import print_function
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-13
|
||||
import os
|
||||
|
|
@ -7,7 +8,7 @@ changeset_numbers = range(1145, 1149)
|
|||
def take_snapshot_image(changeset_number):
|
||||
"turn main.asm into an image at a certain version"
|
||||
|
||||
print "reverting main.asm to r" + str(changeset_number)
|
||||
print("reverting main.asm to r" + str(changeset_number))
|
||||
|
||||
#revert the file (it used to be common.asm)
|
||||
os.system("rm ../main.asm; rm ../common.asm; rm ../pokered.asm")
|
||||
|
|
@ -15,7 +16,7 @@ def take_snapshot_image(changeset_number):
|
|||
os.system("hg revert ../common.asm -r" + str(changeset_number))
|
||||
os.system("hg revert ../pokered.asm -r" + str(changeset_number))
|
||||
|
||||
print "generating the image.."
|
||||
print("generating the image..")
|
||||
|
||||
#draw the image
|
||||
os.system("python romviz.py")
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-10
|
||||
#show me an image
|
||||
import Image
|
||||
from math import floor
|
||||
import extract_maps
|
||||
import analyze_incbins
|
||||
from . import extract_maps
|
||||
from . import analyze_incbins
|
||||
|
||||
print "loading rom.."
|
||||
print("loading rom..")
|
||||
extract_maps.load_rom()
|
||||
#extract_maps.load_map_pointers()
|
||||
#extract_maps.read_all_map_headers()
|
||||
|
||||
print "analyzing incbins.."
|
||||
print("analyzing incbins..")
|
||||
analyze_incbins.load_asm()
|
||||
analyze_incbins.isolate_incbins()
|
||||
analyze_incbins.process_incbins()
|
||||
|
|
@ -26,7 +28,7 @@ im.putpalette([
|
|||
126, 30, 156,
|
||||
])
|
||||
|
||||
print "drawing incbins..."
|
||||
print("drawing incbins...")
|
||||
for incbin_key in analyze_incbins.processed_incbins:
|
||||
incbin = analyze_incbins.processed_incbins[incbin_key]
|
||||
start = incbin["start"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import extract_maps
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from . import extract_maps
|
||||
spacing = "\t"
|
||||
|
||||
#provided by sawakita
|
||||
|
|
@ -172,7 +174,7 @@ def load_icons():
|
|||
pic = thing["picture_number"]
|
||||
unique_icons.add(pic)
|
||||
|
||||
if not icons.has_key(pic): icons[pic] = []
|
||||
if pic not in icons: icons[pic] = []
|
||||
|
||||
alerter = None
|
||||
if int(thing["y"])-4 > int(map["y"], 16)*2: alerter = True
|
||||
|
|
@ -199,7 +201,7 @@ def print_appearances():
|
|||
output += spacing + ".. in " + appearance[0] + " at (" + str(appearance[1]) + ", " + str(appearance[2]) + ")" + outside_alert + "\n"
|
||||
output += "\n"
|
||||
|
||||
print output
|
||||
print(output)
|
||||
|
||||
def insert_todo_sprites():
|
||||
load_icons()
|
||||
|
|
@ -251,7 +253,7 @@ def sprite_printer():
|
|||
value = hex(key)[2:]
|
||||
if len(value) == 1: value = "0" + value
|
||||
|
||||
print sprites[key] + extra + " EQU $" + value
|
||||
print(sprites[key] + extra + " EQU $" + value)
|
||||
|
||||
def parse_sprite_sheet_pointer_table():
|
||||
"""parses the bytes making up the pointer table
|
||||
|
|
@ -321,7 +323,7 @@ def parse_sprite_sheet_pointer_table():
|
|||
data_entry["byte_count"] += 64
|
||||
setter3 = True
|
||||
|
||||
print ("$%.2x " % (sprite_id)) + sprite_name + " has $%.2x bytes" % (byte_count) + " pointing to 0x%.x" % (pointer) + " bank is $%.2x" % (bank) + " with pose_count=" + str(data_entry["poses"])
|
||||
print(("$%.2x " % (sprite_id)) + sprite_name + " has $%.2x bytes" % (byte_count) + " pointing to 0x%.x" % (pointer) + " bank is $%.2x" % (bank) + " with pose_count=" + str(data_entry["poses"]))
|
||||
|
||||
ptable_sheet_data[sprite_id] = data_entry
|
||||
return ptable_sheet_data
|
||||
|
|
@ -398,5 +400,5 @@ if __name__ == "__main__":
|
|||
#sprite_printer()
|
||||
|
||||
ptable_sheet_data = parse_sprite_sheet_pointer_table()
|
||||
print pretty_print_sheet_incbins(ptable_sheet_data)
|
||||
print pretty_print_sheet_data(ptable_sheet_data)
|
||||
print(pretty_print_sheet_incbins(ptable_sheet_data))
|
||||
print(pretty_print_sheet_data(ptable_sheet_data))
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-03
|
||||
#utilities for working with text pointers
|
||||
import extract_maps #rom, assert_rom, load_rom, calculate_pointer, load_map_pointers, read_all_map_headers, map_headers
|
||||
from pretty_map_headers import map_name_cleaner
|
||||
from . import extract_maps #rom, assert_rom, load_rom, calculate_pointer, load_map_pointers, read_all_map_headers, map_headers
|
||||
from .pretty_map_headers import map_name_cleaner
|
||||
#import analyze_incbins #asm, offset_to_pointer, find_incbin_to_replace_for, split_incbin_line_into_three, generate_diff_insert, load_asm, isolate_incbins, process_incbins
|
||||
spacing = " "
|
||||
|
||||
|
|
@ -39,10 +41,10 @@ def test_first_text_pointer_bytes(range=20): #30 for viridian city, 34 for cerul
|
|||
first_text_pointer = extract_maps.calculate_pointer(partial_pointer, bank)
|
||||
|
||||
#if (first_text_pointer <= (text_list_pointer+range)):
|
||||
print "map " + map["name"] + " (" + str(map["id"]) + ")"
|
||||
print spacing + "text_pointer (list) = " + hex(text_list_pointer)
|
||||
print spacing + "first_text_pointer (first text) = " + hex(first_text_pointer)
|
||||
print spacing + "difference = " + str(first_text_pointer - text_list_pointer)
|
||||
print("map " + map["name"] + " (" + str(map["id"]) + ")")
|
||||
print(spacing + "text_pointer (list) = " + hex(text_list_pointer))
|
||||
print(spacing + "first_text_pointer (first text) = " + hex(first_text_pointer))
|
||||
print(spacing + "difference = " + str(first_text_pointer - text_list_pointer))
|
||||
#return False
|
||||
|
||||
return True
|
||||
|
|
@ -52,4 +54,4 @@ if __name__ == "__main__":
|
|||
extract_maps.load_map_pointers()
|
||||
extract_maps.read_all_map_headers()
|
||||
|
||||
print test_first_text_pointer_bytes()
|
||||
print(test_first_text_pointer_bytes())
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Functions to bootstrap the emulator state
|
||||
"""
|
||||
|
||||
from setup_vba import (
|
||||
from tests.setup_vba import (
|
||||
vba,
|
||||
autoplayer,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -99,7 +99,11 @@ from pokemontools.crystal import (
|
|||
import pokemontools.wram
|
||||
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
try:
|
||||
import unittest.mock as mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
class BasicTestCase(unittest.TestCase):
|
||||
"this is where i cram all of my unit tests together"
|
||||
|
|
@ -151,6 +155,9 @@ class BasicTestCase(unittest.TestCase):
|
|||
rom_segment = self.rom[0x112116:0x112116+8]
|
||||
self.assertEqual(rom_segment, "HTTP/1.0")
|
||||
|
||||
def test_rom_text_at(self):
|
||||
self.assertEquals(rom_text_at(0x112116, 8), b"HTTP/1.0")
|
||||
|
||||
def test_rom_interval(self):
|
||||
address = 0x100
|
||||
interval = 10
|
||||
|
|
@ -182,9 +189,6 @@ class BasicTestCase(unittest.TestCase):
|
|||
addr2 = calculate_pointer_from_bytes_at(0x100, bank=True)
|
||||
self.assertEqual(addr2, 0x2ec3)
|
||||
|
||||
def test_rom_text_at(self):
|
||||
self.assertEquals(rom_text_at(0x112116, 8), "HTTP/1.0")
|
||||
|
||||
class TestRomStr(unittest.TestCase):
|
||||
sample_text = "hello world!"
|
||||
sample = None
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
"""
|
||||
Tests for VBA automation tools
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import unittest
|
||||
|
||||
from setup_vba import (
|
||||
from tests.setup_vba import (
|
||||
vba,
|
||||
autoplayer,
|
||||
keyboard,
|
||||
)
|
||||
|
||||
from bootstrapping import (
|
||||
from tests.bootstrapping import (
|
||||
bootstrap,
|
||||
bootstrap_trainer_battle,
|
||||
)
|
||||
|
|
@ -267,13 +268,13 @@ class VbaTests(unittest.TestCase):
|
|||
start_state = self.cry.vba.state
|
||||
|
||||
for name in names:
|
||||
print "Writing name: " + name
|
||||
print("Writing name: " + name)
|
||||
|
||||
self.cry.vba.state = start_state
|
||||
|
||||
sequence = self.cry.write(name)
|
||||
|
||||
print "sequence is: " + str(sequence)
|
||||
print("sequence is: " + str(sequence))
|
||||
|
||||
# save this selection
|
||||
self.cry.vba.press("start", hold=20)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Tests for the battle controller
|
|||
|
||||
import unittest
|
||||
|
||||
from setup_vba import (
|
||||
from tests.setup_vba import (
|
||||
vba,
|
||||
autoplayer,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -95,7 +95,11 @@ from pokemontools.crystal import (
|
|||
)
|
||||
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
try:
|
||||
import unittest.mock as mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
class TestCram(unittest.TestCase):
|
||||
"this is where i cram all of my unit tests together"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user