diff options
Diffstat (limited to 'pokemontools')
| -rw-r--r-- | pokemontools/crystal.py | 62 | ||||
| -rw-r--r-- | pokemontools/map_editor.py | 78 | 
2 files changed, 102 insertions, 38 deletions
| diff --git a/pokemontools/crystal.py b/pokemontools/crystal.py index c76d006..7acb160 100644 --- a/pokemontools/crystal.py +++ b/pokemontools/crystal.py @@ -67,6 +67,9 @@ is_valid_address = addresses.is_valid_address  import old_text_script  OldTextScript = old_text_script +import config +conf = config.Config() +  from map_names import map_names  # ---- script_parse_table explanation ---- @@ -112,16 +115,22 @@ def map_name_cleaner(input):  rom = romstr.RomStr(None) -def direct_load_rom(filename="../baserom.gbc"): +def direct_load_rom(filename=None):      """loads bytes into memory""" +    if filename == None: +        filename = os.path.join(conf.path, "baserom.gbc") +    global rom      file_handler = open(filename, "rb")      rom = romstr.RomStr(file_handler.read())      file_handler.close()      return rom -def load_rom(filename="../baserom.gbc"): +def load_rom(filename=None):      """checks that the loaded rom matches the path      and then loads the rom if necessary.""" +    if filename == None: +        filename = os.path.join(conf.path, "baserom.gbc") +    global rom      if rom != romstr.RomStr(None) and rom != None:          return rom      if not isinstance(rom, romstr.RomStr): @@ -129,14 +138,19 @@ def load_rom(filename="../baserom.gbc"):      elif os.lstat(filename).st_size != len(rom):          return direct_load_rom(filename) -def direct_load_asm(filename="../main.asm"): +def direct_load_asm(filename=None): +    if filename == None: +        filename = os.path.join(conf.path, "main.asm")      """returns asm source code (AsmList) from a file"""      asm = open(filename, "r").read().split("\n")      asm = romstr.AsmList(asm)      return asm -def load_asm(filename="../main.asm"): +def load_asm(filename=None):      """returns asm source code (AsmList) from a file (uses a global)""" +    if filename == None: +        filename = os.path.join(conf.path, "main.asm") +    global asm      asm = direct_load_asm(filename=filename)      return asm @@ -2654,7 +2668,9 @@ effect_classes = create_effect_command_classes() -def generate_macros(filename="../script_macros.asm"): +def generate_macros(filename=None): +    if filename == None: +        filename = os.path.join(conf.path, "script_macros.asm")      """generates all macros based on commands      this is dumped into script_macros.asm"""      output  = "; This file is generated by generate_macros.\n" @@ -5278,7 +5294,7 @@ def parse_second_map_header_at(address, map_group=None, map_id=None, debug=True)  class MapBlockData:      base_label = "MapBlockData_" -    maps_path = os.path.realpath(os.path.join(os.path.realpath("."), "../maps")) +    maps_path = os.path.realpath(os.path.join(conf.path, "maps"))      def __init__(self, address, map_group=None, map_id=None, debug=True, bank=None, label=None, width=None, height=None):          self.address = address @@ -5922,9 +5938,11 @@ def reset_incbins():      isolate_incbins(asm=asm)      process_incbins() -def find_incbin_to_replace_for(address, debug=False, rom_file="../baserom.gbc"): +def find_incbin_to_replace_for(address, debug=False, rom_file=None):      """returns a line number for which incbin to edit      if you were to insert bytes into main.asm""" +    if rom_file == None: +        rom_file = os.path.join(conf.path, "baserom.gbc")      if type(address) == str: address = int(address, 16)      if not (0 <= address <= os.lstat(rom_file).st_size):          raise IndexError("address is out of bounds") @@ -5952,7 +5970,7 @@ def find_incbin_to_replace_for(address, debug=False, rom_file="../baserom.gbc"):              return incbin_key      return None -def split_incbin_line_into_three(line, start_address, byte_count, rom_file="../baserom.gbc"): +def split_incbin_line_into_three(line, start_address, byte_count, rom_file=None):      """      splits an incbin line into three pieces.      you can replace the middle one with the new content of length bytecount @@ -5960,6 +5978,8 @@ def split_incbin_line_into_three(line, start_address, byte_count, rom_file="../b      start_address: where you want to start inserting bytes      byte_count: how many bytes you will be inserting      """ +    if rom_file == None: +        rom_file = os.path.join(conf.path, "baserom.gbc")      if type(start_address) == str: start_address = int(start_address, 16)      if not (0 <= start_address <= os.lstat(rom_file).st_size):          raise IndexError("start_address is out of bounds") @@ -6019,9 +6039,9 @@ def generate_diff_insert(line_number, newline, debug=False):          CalledProcessError = None      try: -        diffcontent = subprocess.check_output("diff -u ../main.asm " + newfile_filename, shell=True) +        diffcontent = subprocess.check_output("diff -u " + os.path.join(conf.path, "main.asm") + " " + newfile_filename, shell=True)      except (AttributeError, CalledProcessError): -        p = subprocess.Popen(["diff", "-u", "../main.asm", newfile_filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE) +        p = subprocess.Popen(["diff", "-u", os.path.join(conf.path, "main.asm"), newfile_filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE)          out, err = p.communicate()          diffcontent = out @@ -6041,8 +6061,8 @@ def apply_diff(diff, try_fixing=True, do_compile=True):      fh.close()      # apply the patch -    os.system("cp ../main.asm ../main1.asm") -    os.system("patch ../main.asm temp.patch") +    os.system("cp " + os.path.join(conf.path, "main.asm") + " " + os.path.join(conf.path, "main1.asm")) +    os.system("patch " + os.path.join(conf.path, "main.asm") + " " + "temp.patch")      # remove the patch      os.system("rm temp.patch") @@ -6050,11 +6070,11 @@ def apply_diff(diff, try_fixing=True, do_compile=True):      # confirm it's working      if do_compile:          try: -            subprocess.check_call("cd ../; make clean; make", shell=True) +            subprocess.check_call("cd " + conf.path + "; make clean; make", shell=True)              return True          except Exception, exc:              if try_fixing: -                os.system("mv ../main1.asm ../main.asm") +                os.system("mv " + os.path.join(conf.path, "main1.asm") + " " + os.path.join(conf.path, "main.asm"))              return False  import crystalparts.asmline @@ -6179,9 +6199,21 @@ class AsmSection:      def to_asm(self):          return self.line +new_asm = None +def load_asm2(filename=None, force=False): +    """loads the asm source code into memory""" +    if filename == None: +        filename = os.path.join(conf.path, "main.asm") +    global new_asm +    if new_asm == None or force: +        new_asm = Asm(filename=filename) +    return new_asm +  class Asm:      """controls the overall asm output""" -    def __init__(self, filename="../main.asm", debug=True): +    def __init__(self, filename=None, debug=True): +        if filename == None: +            filename = os.path.join(conf.path, "main.asm")          self.parts = []          self.labels = []          self.filename = filename diff --git a/pokemontools/map_editor.py b/pokemontools/map_editor.py index d4b5047..4c0bec5 100644 --- a/pokemontools/map_editor.py +++ b/pokemontools/map_editor.py @@ -6,12 +6,12 @@ from ttk import Frame, Style  import PIL  from PIL import Image, ImageTk -import configuration -conf = configuration.Config() +import config +conf = config.Config() -version = 'crystal' -#version = 'red' +#version = 'crystal' +version = 'red'  if version == 'crystal':  	map_dir = os.path.join(conf.path, 'maps/') @@ -317,12 +317,15 @@ class Map:  		# Draw one block (4x4 tiles)  		block = self.blockdata[block_y * self.width + block_x]  		for j, tile in enumerate(self.tileset.blocks[block]): -			# Tile gfx are split in half to make vram mapping easier -			if tile >= 0x80: -				tile -= 0x20 -			tile_x = block_x * 32 + (j % 4) * 8 -			tile_y = block_y * 32 + (j / 4) * 8 -			self.canvas.create_image(index + tile_x, indey + tile_y, image=self.tileset.tiles[tile]) +			try: +				# Tile gfx are split in half to make vram mapping easier +				if tile >= 0x80: +					tile -= 0x20 +				tile_x = block_x * 32 + (j % 4) * 8 +				tile_y = block_y * 32 + (j / 4) * 8 +				self.canvas.create_image(index + tile_x, indey + tile_y, image=self.tileset.tiles[tile]) +			except: +				pass  class Tileset: @@ -343,11 +346,30 @@ class Tileset:  		self.get_blocks()  		self.get_tiles() +	def get_tileset_gfx_filename(self): +		filename = None + +		if version == 'red': +			tileset_defs = open(os.path.join(conf.path, 'main.asm'), 'r').read() +			incbin = asm_at_label(tileset_defs, 'Tset%.2X_GFX' % self.id) +			print incbin +			filename = read_header_macros(incbin, ['filename'], ['INCBIN'])[0][0].replace('"','').replace('.2bpp','.png') +			filename = os.path.join(conf.path, filename) +			print filename + +		if not filename: +			filename = os.path.join( +				gfx_dir, +				to_gfx_name(self.id) + '.png' +			) + +		return filename +  	def get_tiles(self): -		filename = os.path.join( -			gfx_dir, -			to_gfx_name(self.id) + '.png' -		) +		filename = self.get_tileset_gfx_filename() +		if not os.path.exists(filename): +			import gfx +			gfx.to_png(filename.replace('.png','.2bpp'), filename)  		self.img = Image.open(filename)  		self.img.width, self.img.height = self.img.size  		self.tiles = [] @@ -452,7 +474,7 @@ def map_header(name):  		headers = open(os.path.join(header_dir, 'map_headers.asm'), 'r').read()  		label = name + '_MapHeader'  		header = asm_at_label(headers, label) -		macros = [ 'db', 'dw', 'db' ] +		macros = [ 'db', 'db', 'db', 'dw', 'db', 'db', 'db', 'db' ]  		attributes = [  			'bank',  			'tileset_id', @@ -478,7 +500,7 @@ def map_header(name):  		label = headers[i:i+len(lower_label)]  		header = asm_at_label(headers, label) -		macros = [ 'db', 'db', 'dw', 'db' ] +		macros = [ 'db', 'db', 'db', 'dw', 'dw', 'dw', 'db' ]  		attributes = [  			'tileset_id',  			'height', @@ -509,7 +531,7 @@ def second_map_header(name):  		headers = open(os.path.join(header_dir, 'second_map_headers.asm'), 'r').read()  		label = name + '_SecondMapHeader'  		header = asm_at_label(headers, label) -		macros = [ 'db', 'db', 'dbw', 'dbw', 'dw', 'db' ] +		macros = [ 'db', 'db', 'db', 'db', 'dw', 'db', 'dw', 'dw', 'db' ]  		attributes = [  			'border_block',  			'height', @@ -531,19 +553,21 @@ def second_map_header(name):  def connections(which_connections, header, l=0):  	directions = { 'north': {}, 'south': {}, 'west': {}, 'east': {} } -	macros = [ 'db', 'dw', 'dw', 'db', 'db', 'dw' ]  	if version == 'crystal': +		macros = [ 'db', 'db' ]   		attributes = [  			'map_group',  			'map_no',  		]  	elif version == 'red': +		macros = [ 'db' ]  		attributes = [  			'map_id',  		] +	macros += [ 'dw', 'dw', 'db', 'db', 'db', 'db', 'dw' ]  	attributes += [  		'strip_pointer',  		'strip_destination', @@ -570,8 +594,9 @@ def read_header_macros(header, attributes, macros):  	l = 0  	for l, (asm, comment) in enumerate(header):  		if asm.strip() != '': -			values += macro_values(asm, macros[i]) -			i += 1 +			mvalues = macro_values(asm, macros[i]) +			values += mvalues +			i += len(mvalues)  		if len(values) >= len(attributes):  			l += 1  			break @@ -587,7 +612,10 @@ def script_header(asm, name):  def macro_values(line, macro):  	values = line[line.find(macro) + len(macro):].split(',') -	return [v.replace('$','0x').strip() for v in values] +	values = [v.replace('$','0x').strip() for v in values] +	if values[0] == 'w': # dbw +		values = values[1:] +	return values  def db_value(line):  	macro = 'db' @@ -602,8 +630,12 @@ from preprocessor import separate_comment  def asm_at_label(asm, label):  	label_def = label + ':' -	start = asm.find(label_def) + len(label_def) -	lines = asm[start:].split('\n') +	lines = asm.split('\n') +	for line in lines: +		if line.startswith(label_def): +			lines = lines[lines.index(line):] +			lines[0] = lines[0][len(label_def):] +			break  	# go until the next label  	content = []  	for line in lines: | 
