summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRangi <remy.oukaour+rangi42@gmail.com>2020-06-14 18:08:43 -0400
committerRangi <remy.oukaour+rangi42@gmail.com>2020-06-14 18:08:43 -0400
commit94a70b63cf7f1a9dbfc14fcee8e390791fc17a1b (patch)
treed1b2bb44621d8c2ebae4a613669eb75e37e507ad
parent7f6bc3d3826fe7727bdc8714aa0295a712a548c3 (diff)
Sync tools with pokecrystal (fixes warnings when building lzcomp)
palette.c and png_dimensions.c will be synced when they are used.
-rw-r--r--Makefile37
-rw-r--r--gfx/pics_silver.asm2
-rw-r--r--tools/free_space.awk70
-rw-r--r--tools/free_space.py73
-rw-r--r--tools/gfx.c12
-rw-r--r--tools/gfx.py417
-rw-r--r--tools/lz/nullcomp.c2
-rw-r--r--tools/lz/output.c12
-rw-r--r--tools/lz/packing.c1
-rw-r--r--tools/lz/repcomp.c2
-rw-r--r--tools/lz/spcomp.c6
-rw-r--r--tools/lz/uncomp.c4
-rw-r--r--tools/pokemontools/gfx.py170
-rw-r--r--tools/pokemontools/lz.py30
-rw-r--r--tools/pokemontools/png.py6
-rwxr-xr-xtools/unnamed.py16
-rw-r--r--tools/used_space.py2
17 files changed, 381 insertions, 481 deletions
diff --git a/Makefile b/Makefile
index 63c1364b..f31b1ce0 100644
--- a/Makefile
+++ b/Makefile
@@ -38,20 +38,17 @@ RGBFIX ?= $(RGBDS)rgbfix
RGBGFX ?= $(RGBDS)rgbgfx
RGBLINK ?= $(RGBDS)rgblink
-PYTHON := python
-gfx := $(PYTHON) tools/gfx.py
-
### Build targets
.SUFFIXES:
-.PHONY: all gold silver clean tidy pngs compare tools
+.PHONY: all gold silver clean tidy compare tools
.SECONDEXPANSION:
.PRECIOUS:
.SECONDARY:
all: $(roms)
-gold: pokegold.gbc
+gold: pokegold.gbc
silver: pokesilver.gbc
clean:
@@ -110,11 +107,11 @@ endif
pokegold.gbc: $(gold_obj) layout.link
$(RGBLINK) -n pokegold.sym -m pokegold.map -l layout.link -o $@ $(gold_obj)
- $(RGBFIX) -cjsv -i AAUE -k 01 -l 0x33 -m 0x10 -p 0 -r 3 -t "POKEMON_GLD" $@
+ $(RGBFIX) -cjsv -t POKEMON_GLD -i AAUE -k 01 -l 0x33 -m 0x10 -r 3 -p 0 $@
pokesilver.gbc: $(silver_obj) layout.link
$(RGBLINK) -n pokesilver.sym -m pokesilver.map -l layout.link -o $@ $(silver_obj)
- $(RGBFIX) -cjsv -i AAXE -k 01 -l 0x33 -m 0x10 -p 0 -r 3 -t "POKEMON_SLV" $@
+ $(RGBFIX) -cjsv -t POKEMON_SLV -i AAXE -k 01 -l 0x33 -m 0x10 -r 3 -p 0 $@
### LZ compression rules
@@ -136,6 +133,16 @@ gfx/pokemon/%/back.2bpp: rgbgfx += -h
gfx/pokemon/%/back_gold.2bpp: rgbgfx += -h
gfx/pokemon/%/back_silver.2bpp: rgbgfx += -h
+gfx/pokemon/%/back_gold.2bpp: gfx/pokemon/%/back.png
+ $(RGBGFX) $(rgbgfx) -o $@ $<
+ $(if $(tools/gfx),\
+ tools/gfx $(tools/gfx) -o $@ $@)
+
+gfx/pokemon/%/back_silver.2bpp: gfx/pokemon/%/back.png
+ $(RGBGFX) $(rgbgfx) -o $@ $<
+ $(if $(tools/gfx),\
+ tools/gfx $(tools/gfx) -o $@ $@)
+
gfx/trainers/%.2bpp: rgbgfx += -h
gfx/new_game/shrink1.2bpp: rgbgfx += -h
@@ -205,16 +212,6 @@ gfx/sgb/silver_border.2bpp: tools/gfx += --trim-whitespace
### Catch-all graphics rules
-gfx/pokemon/%/back_gold.2bpp: gfx/pokemon/%/back.png
- $(RGBGFX) $(rgbgfx) -o $@ $<
- $(if $(tools/gfx),\
- tools/gfx $(tools/gfx) -o $@ $@)
-
-gfx/pokemon/%/back_silver.2bpp: gfx/pokemon/%/back.png
- $(RGBGFX) $(rgbgfx) -o $@ $<
- $(if $(tools/gfx),\
- tools/gfx $(tools/gfx) -o $@ $@)
-
%.2bpp: %.png
$(RGBGFX) $(rgbgfx) -o $@ $<
$(if $(tools/gfx),\
@@ -224,9 +221,3 @@ gfx/pokemon/%/back_silver.2bpp: gfx/pokemon/%/back.png
$(RGBGFX) $(rgbgfx) -d1 -o $@ $<
$(if $(tools/gfx),\
tools/gfx $(tools/gfx) -d1 -o $@ $@)
-
-pngs:
- find gfx -iname "*.lz" -exec $(gfx) unlz {} +
- find gfx -iname "*.[12]bpp" -exec $(gfx) png {} +
- find gfx -iname "*.[12]bpp" -exec touch {} +
- find gfx -iname "*.lz" -exec touch {} +
diff --git a/gfx/pics_silver.asm b/gfx/pics_silver.asm
index b3bed876..e8140f5a 100644
--- a/gfx/pics_silver.asm
+++ b/gfx/pics_silver.asm
@@ -2,7 +2,7 @@ INCLUDE "constants.asm"
; PokemonPicPointers and UnownPicPointers are assumed to start at the same
-; address, but in different banks. This is enforced in pokesilver.link.
+; address, but in different banks. This is enforced in layout.link.
SECTION "Pic Pointers", ROMX
diff --git a/tools/free_space.awk b/tools/free_space.awk
new file mode 100644
index 00000000..45984ca7
--- /dev/null
+++ b/tools/free_space.awk
@@ -0,0 +1,70 @@
+#!/usr/bin/gawk -f
+
+# Usage: tools/free_space.awk [BANK=<bank_spec>] pokegold.map
+
+# The BANK argument allows printing free space in one, all, or none of the ROM's banks.
+# Valid arguments are numbers (in decimal "42" or hexadecimal "0x2a"), "all" or "none".
+# If not specified, defaults to "none".
+# The `BANK` argument MUST be before the map file name, otherwise it has no effect!
+# Yes: tools/free_space.awk BANK=all pokegold.map
+# No: tools/free_space.awk pokegold.map BANK=42
+
+# Copyright (c) 2020, Eldred Habert.
+# SPDX-License-Identifier: MIT
+
+BEGIN {
+ nb_banks = 0
+ free = 0
+ rom_bank = 0 # Safety net for malformed files
+
+ # Default settings
+ # Variables assigned via the command-line (except through `-v`) are *after* `BEGIN`
+ BANK="none"
+}
+
+# Only accept ROM banks, ignore everything else
+toupper($0) ~ /^[ \t]*ROM[0X][ \t]+BANK[ \t]+#/ {
+ nb_banks++
+ rom_bank = 1
+ split($0, fields, /[ \t]/)
+ bank_num = strtonum(substr(fields[3], 2))
+}
+
+function register_bank(amount) {
+ free += amount
+ rom_bank = 0 # Reject upcoming banks by default
+
+ if (BANK ~ /all/ || BANK == bank_num) {
+ printf "Bank %3d: %5d/16384 (%.2f%%)\n", bank_num, amount, amount * 100 / 16384
+ }
+}
+
+rom_bank && toupper($0) ~ /^[ \t]*EMPTY/ {
+ # Empty bank
+ register_bank(16384)
+}
+rom_bank && toupper($0) ~ /^[ \t]*SLACK:[ \t]/ {
+ if ($2 ~ /\$[0-9A-F]+/) {
+ register_bank(strtonum("0x" substr($2, 2)))
+ } else {
+ printf "Malformed slack line? \"%s\" does not start with '$'\n", $2
+ }
+}
+
+END {
+ # Determine number of banks, by rounding to upper power of 2
+ total_banks = 2 # Smallest size is 2 banks
+ while (total_banks < nb_banks) {
+ total_banks *= 2
+ }
+
+ # RGBLINK omits "trailing" ROM banks, so fake them
+ bank_num = nb_banks
+ while (bank_num < total_banks) {
+ register_bank(16384)
+ bank_num++
+ }
+
+ total = total_banks * 16384
+ printf "Free space: %5d/%5d (%.2f%%)\n", free, total, free * 100 / total
+}
diff --git a/tools/free_space.py b/tools/free_space.py
new file mode 100644
index 00000000..d6af522f
--- /dev/null
+++ b/tools/free_space.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+"""
+Usage: python3 free_space.py [BANK=none] [pokegold.map]
+
+Calculate the free space in the ROM or its individual banks.
+
+The BANK argument allows printing free space in one, all, or none of the ROM's banks.
+Valid arguments are numbers (in decimal "42" or hexadecimal "0x2A"), "all" or "none".
+If not specified, defaults to "none".
+"""
+
+import sys
+
+from mapreader import MapReader
+
+def main():
+ print_bank = 'none'
+ mapfile = 'pokegold.map'
+
+ if len(sys.argv) >= 2 and sys.argv[1].startswith('BANK='):
+ print_bank = sys.argv[1].split('=', 1)[-1]
+ if len(sys.argv) >= 3:
+ mapfile = sys.argv[2]
+ elif len(sys.argv) >= 3 and sys.argv[2].startswith('BANK='):
+ print_bank = sys.argv[2].split('=', 1)[-1]
+ mapfile = sys.argv[1]
+
+ if print_bank not in {'all', 'none'}:
+ try:
+ if print_bank.startswith('0x') or print_bank.startswith('0X'):
+ print_bank = int(print_bank[2:], 16)
+ else:
+ print_bank = int(print_bank)
+ except ValueError:
+ error = 'Error: invalid BANK: %s' % print_bank
+ if print_bank.isalnum():
+ error += ' (did you mean: 0x%s?)' % print_bank
+ print(error, file=sys.stderr)
+ sys.exit(1)
+
+ num_banks = 0x80
+ bank_size = 0x4000 # bytes
+ total_size = num_banks * bank_size
+
+ r = MapReader()
+ with open(mapfile, 'r', encoding='utf-8') as f:
+ l = f.readlines()
+ r.read_map_data(l)
+
+ free_space = 0
+ per_bank = []
+ default_bank_data = {'sections': [], 'used': 0, 'slack': bank_size}
+ for bank in range(num_banks):
+ bank_data = r.bank_data['ROM0 bank'] if bank == 0 else r.bank_data['ROMX bank']
+ data = bank_data.get(bank, default_bank_data)
+ used = data['used']
+ slack = data['slack']
+ per_bank.append((used, slack))
+ free_space += slack
+
+ print('Free space: %d/%d (%.2f%%)' % (free_space, total_size, free_space * 100.0 / total_size))
+ if print_bank != 'none':
+ print()
+ print('bank, used, free')
+ for bank in range(num_banks):
+ used, slack = per_bank[bank]
+ if print_bank in {'all', bank}:
+ print('$%02X, %d, %d' % (bank, used, slack))
+
+if __name__ == '__main__':
+ main()
diff --git a/tools/gfx.c b/tools/gfx.c
index d7be9a81..6dad2f1a 100644
--- a/tools/gfx.c
+++ b/tools/gfx.c
@@ -132,10 +132,10 @@ void trim_whitespace(struct Graphic *graphic) {
void remove_whitespace(struct Graphic *graphic) {
int tile_size = Options.depth * 8;
if (Options.interleave) tile_size *= 2;
-
+
// Make sure we have a whole number of tiles, round down if required
graphic->size &= ~(tile_size - 1);
-
+
int i = 0;
for (int j = 0, d = 0; i < graphic->size && j < graphic->size; i += tile_size, j += tile_size) {
while (j < graphic->size && is_whitespace(&graphic->data[j], tile_size) && !is_preserved(j / tile_size - d)) {
@@ -172,10 +172,10 @@ void remove_duplicates(struct Graphic *graphic) {
int tile_size = Options.depth * 8;
if (Options.interleave) tile_size *= 2;
int num_tiles = 0;
-
+
// Make sure we have a whole number of tiles, round down if required
graphic->size &= ~(tile_size - 1);
-
+
for (int i = 0, j = 0, d = 0; i < graphic->size && j < graphic->size; i += tile_size, j += tile_size) {
while (j < graphic->size && tile_exists(&graphic->data[j], graphic->data, tile_size, num_tiles)) {
if ((Options.keep_whitespace && is_whitespace(&graphic->data[j], tile_size)) || is_preserved(j / tile_size - d)) {
@@ -226,10 +226,10 @@ void remove_flip(struct Graphic *graphic, bool xflip, bool yflip) {
int tile_size = Options.depth * 8;
if (Options.interleave) tile_size *= 2;
int num_tiles = 0;
-
+
// Make sure we have a whole number of tiles, round down if required
graphic->size &= ~(tile_size - 1);
-
+
for (int i = 0, j = 0, d = 0; i < graphic->size && j < graphic->size; i += tile_size, j += tile_size) {
while (j < graphic->size && flip_exists(&graphic->data[j], graphic->data, tile_size, num_tiles, xflip, yflip)) {
if ((Options.keep_whitespace && is_whitespace(&graphic->data[j], tile_size)) || is_preserved(j / tile_size - d)) {
diff --git a/tools/gfx.py b/tools/gfx.py
index 7007d37e..a3d95562 100644
--- a/tools/gfx.py
+++ b/tools/gfx.py
@@ -1,6 +1,9 @@
+#!/usr/bin/env python2
+# -*- coding: utf-8 -*-
+
"""Supplementary scripts for graphics conversion."""
-import os, re
+import os
import argparse
from pokemontools import gfx, lz
@@ -28,42 +31,109 @@ base_stats = None
def get_base_stats():
global base_stats
if not base_stats:
- base_stats = recursive_read('data/pokemon/base_stats.asm')
+ base_stats = recursive_read('data/base_stats.asm')
return base_stats
-def get_pokemon_dimensions(name):
+def get_pokemon_dimensions(path):
try:
- if name == 'egg':
- return 5, 5
- if name == 'questionmark':
- return 7, 7
- if name.startswith('unown_'):
- name = 'unown'
- base_stats = get_base_stats()
- # hack for pidgeot/mew (previously caught by being substrings of pidgeotto/mewtwo)
- pattern = re.compile('\s+db {0}\s+'.format(name.upper()))
- start = pattern.search(base_stats).start()
- start = base_stats.find('\tdn ', start)
- end = base_stats.find('\n', start)
- line = base_stats[start:end].replace(',', ' ')
- w, h = map(int, line.split()[1:3])
- return w, h
+ byte = bytearray(open(path, 'rb').read())[0]
+ width = byte & 0xf
+ height = (byte >> 8) & 0xf
+ return width, height
except:
- return 7, 7
-
-mail_px8 = ['eon_mail_border_2', 'grass', 'lovely_mail_border', 'lovely_mail_underline',
- 'morph_mail_border', 'morph_mail_divider', 'portrail_mail_border',
- 'portraitmail_border', 'portraitmail_underline', 'small_heart', 'small_note',
- 'small_pokeball', 'small_triangle', 'wave']
-mail_px16 = ['eon_mail_border_1', 'flower_1', 'flower_2', 'large_circle', 'large_heart',
- 'large_pokeball', 'large_triangle', 'morph_mail_corner','music_mail_border', 'oddish',
- 'sentret', 'unused_grass']
-mail_px24 = ['cloud', 'ditto', 'dratini', 'eevee', 'lapras', 'mew', 'natu', 'poliwag']
-mail_border_stretch = ['surf_mail_border', 'flower_mail_border', 'litebluemail_border']
-
-overworld_px8 = ['boulder_dust', 'fishing_rod', 'grass_rustle', 'heal_machine', 'shadow',
- 'trainer_battle_pokeball_tiles']
-overworld_px16 = ['chris_fish', 'cut_grass', 'cut_tree', 'headbutt_tree']
+ return None
+
+
+def get_animation_frames(path=None, w=7, h=7, bitmask_path=None, frame_path=None):
+ """Retrieve animation frame tilemaps from generated frame/bitmask data."""
+ if not path:
+ path = bitmask_path
+ if not path:
+ path = frame_path
+ if not path:
+ raise Exception("need at least one of path, bitmask_path or frame_path")
+
+ if not bitmask_path:
+ bitmask_path = os.path.join(os.path.split(path)[0], 'bitmask.asm')
+ if not frame_path:
+ frame_path = os.path.join(os.path.split(path)[0], 'frames.asm')
+ bitmask_lines = open(bitmask_path).readlines()
+ frame_lines = open(frame_path).readlines()
+
+ bitmask_length = w * h
+
+ bitmasks = []
+ bitmask = []
+ for line in bitmask_lines:
+ if '\tdb ' in line:
+ value = line.split('\tdb ')[1].strip().replace('%', '0b')
+ value = int(value, 0)
+ #print line.strip(), value, len(bitmasks), len(bitmask)
+ for bit in xrange(8):
+ bitmask += [(value >> bit) & 1]
+ if len(bitmask) >= bitmask_length:
+ bitmasks += [bitmask]
+ bitmask = []
+ break
+ if bitmask:
+ bitmasks += [bitmask]
+
+ frames = []
+ frame_labels = []
+ i = 0
+ for line in frame_lines:
+ if '\tdw ' in line:
+ frame_labels += [line.split('\tdw ')[1].strip()]
+ else:
+ for part in line.split():
+ part = part.strip()
+ if part in frame_labels:
+ frames += [(part, i)]
+ i += 1
+
+ results = []
+
+ for label, i in frames:
+ result = []
+
+ # get the bitmask and tile ids for each frame
+ # don't care if we read past bounds, so just read the rest of the file
+ values = []
+ for line in frame_lines[i:]:
+ if '\tdb ' in line:
+ values += line.split('\tdb ')[1].split(';')[0].split(',')
+
+ #print bitmasks
+ #print values[0]
+ #print int(values[0].replace('$', '0x'), 0)
+ bitmask = bitmasks[int(values[0].replace('$', '0x'), 0)]
+ tiles = values[1:]
+ k = 0
+ j = 0
+ for bit in bitmask:
+ if bit:
+ result += [int(tiles[k].replace('$', '0x'), 0)]
+ k += 1
+ else:
+ result += [j]
+ j += 1
+
+ results += [result]
+
+ return results
+
+def get_animated_graphics(path, w=7, h=7, bitmask_path=None, frame_path=None):
+ frames = get_animation_frames(path, w, h, bitmask_path, frame_path)
+ new_path = path.replace('.animated.2bpp', '.2bpp')
+ tiles = gfx.get_tiles(bytearray(open(path, 'rb').read()))
+ new_tiles = tiles[:w * h]
+ for frame in frames:
+ for tile in frame:
+ new_tiles += [tiles[tile]]
+ new_graphic = gfx.connect(new_tiles)
+ print new_path, list(new_graphic)
+ open(new_path, 'wb').write(bytearray(new_graphic))
+ return new_path
def filepath_rules(filepath):
"""Infer attributes of certain graphics by their location in the filesystem."""
@@ -85,251 +155,23 @@ def filepath_rules(filepath):
index = filedir.find(pokemon_name)
if index != -1:
filedir = filedir[:index + len('unown')] + filedir[index + len('unown_a'):]
- # startswith to handle front_gold / front_silver
- if name.startswith('front'):
+ if name == 'front' or name == 'front.animated':
args['pal_file'] = os.path.join(filedir, 'normal.pal')
args['pic'] = True
- # TODO: way to handle Crystal and Gold/Silver simultaneously?
- # args['animate'] = True
- # startswith to handle back_gold / back_silver
- elif name.startswith('back'):
+ args['animate'] = True
+ elif name == 'back':
args['pal_file'] = os.path.join(filedir, 'normal.pal')
args['pic'] = True
elif 'gfx/trainers' in filedir:
- trainer_name = filedir.split('/')[-1]
- args['pal_file'] = os.path.join(filedir, name + '.pal')
args['pic'] = True
- elif 'gfx/battle' in filedir:
- if name == 'dude':
- args['pic_dimensions'] = 6, 6
- elif name in ['balls', 'enemy_hp_bar_border']:
- args['width'] = 32
- elif name == 'expbar':
- args['width'] = 72
- elif name == 'hp_exp_bar_border':
- args['width'] = 48
-
- elif 'gfx/card_flip' in filedir:
- if name == 'card_flip_1':
- args['width'] = 128
- elif name == 'card_flip_2':
- args['width'] = 24
- args['rows'] = [
- (0, 2), (0, 2), (0, 2), (0, 2), (0, 2), (0, 2), (0, 2), (0, 2),
- (0, 3), (0, 3), (0, 3), (0, 3), (0, 3), (0, 3), (0, 3), (0, 3), (0, 3), (0, 3), (0, 3), (0, 3)
- ]
-
- elif 'gfx/credits' in filedir:
- if name in ['bellossom', 'togepi', 'elekid', 'sentret']:
- args['width'] = 32
- elif name == 'theend':
- args['width'] = 64
- elif name == 'border':
- args['width'] = 72
-
- elif 'gfx/debug' in filedir:
- if name == 'color_test':
- args['width'] = 176
-
- elif 'gfx/diploma' in filedir:
- if name == 'diploma':
- args['width'] = 128
-
- elif 'gfx/dummy_game' in filedir:
- if name == 'dummy_game':
- args['width'] = 16
-
- elif 'gfx/font' in filedir:
- if name in ['font', 'font_inversed', 'font_battle_extra', 'font_extra']:
- args['width'] = 128
- elif name == 'unused_bold_font':
- args['width'] = 256
-
- elif 'gfx/frames' in filedir:
- args['width'] = 24
-
- elif 'gfx/icons' in filedir:
- if name == 'mail_big':
- args['width'] = 16
-
- elif 'gfx/intro' in filedir:
- if name == 'logo_star':
- args['width'] = 8
- elif name in ['gamefreak_logo', 'logo_sparkle']:
- args['width'] = 24
- elif name == 'gamefreak_presents':
- args['width'] = 104
- elif name == 'copyright':
- args['width'] = 240
- elif name == 'charizard1':
- args['width'] = 72
- args['rows'] = [
- (1, 8), (1, 8), (1, 8), (1, 8), (1, 8), (1, 8), (1, 8), (1, 8),
- (0, 9), (0, 9), (0, 9), (0, 9), (0, 9), (0, 9), (0, 9)
- ]
- elif name == 'charizard2':
- args['width'] = 72
- args['pad_indices'] = [0]
- elif name == 'charizard3':
- args['width'] = 64
- args['rows'] = [
- (0, 8), (0, 8), (0, 0), (1, 6), (1, 6), (1, 6), (1, 6), (1, 6), (1, 6),
- (1, 6), (1, 6), (1, 6), (1, 6), (1, 6), (1, 6), (1, 6), (1, 6)
- ]
- elif name in ['grass1', 'grass2', 'water1', 'water2']:
- args['width'] = 128
-
- elif 'gfx/mail' in filedir:
- if name in mail_px8:
- args['width'] = 8
- elif name in mail_px16:
- args['width'] = 16
- elif name in mail_px24:
- args['width'] = 24
- elif name in mail_border_stretch:
- args['width'] = 24
- args['pad_indices'] = [4]
- elif name == 'large_note':
- args['width'] = 16
- args['rows'] = [(1, 1), (0, 2)]
- elif name == 'dragonite':
- args['width'] = 56
- args['rows'] = [(0, 6), (1, 6), (2, 6)]
-
- elif 'gfx/naming_screen' in filedir:
- args['width'] = 8
-
- elif 'gfx/new_game' in filedir:
- if name in ['shrink1', 'shrink2']:
- args['width'] = 56
- args['pic_dimensions'] = 7, 7
-
- elif 'gfx/overworld' in filedir:
- if name == 'heal_machine':
- args['width'] = 8
- elif name in overworld_px8:
- args['width'] = 8
- elif name in overworld_px16:
- args['width'] = 16
-
- elif 'gfx/pack' in filedir:
- if name == 'pack':
- args['width'] = 40
- elif name == 'pack_menu':
- args['width'] = 128
-
- elif 'gfx/player' in filedir:
- if name == 'chris_back':
- args['pic_dimensions'] = 6, 6
-
- elif 'gfx/pokedex' in filedir:
- if name in ['slowpoke', 'pokedex', 'pokedex_sgb']:
- args['width'] = 128
-
- elif name == 'question_mark':
- args['width'] = 56
- args['pic_dimensions'] = 7, 7
-
- elif 'gfx/pokegear' in filedir:
- if name == 'pokegear_sprites':
- args['width'] = 16
-
- elif name in ['pokegear', 'town_map']:
- args['width'] = 128
-
- elif 'gfx/mystery_gift' in filedir:
- if name == 'mystery_gift':
- args['width'] = 128
- args['rows'] = [(0, 15), (0, 15), (0, 2)]
- elif name == 'mystery_gift_2':
- args['width'] = 128
- # TODO: this is incomplete
- elif name == 'question_mark':
- args['width'] = 40
- args['rows'] = [(1, 4), (0, 0), (0, 0), (2, 3), (2, 1)]
- elif name == 'border':
- args['width'] = 56
-
- elif 'gfx/sgb' in filedir:
- args['width'] = 128
- #args['pal_file'] = os.path.join(filedir, name + '.pal')
-
- elif 'gfx/slots' in filedir:
- if name == 'slots_1':
- args['width'] = 16
- elif name == 'slots_2':
- args['width'] = 16
- args['pic_dimensions'] = 2, 2
- # TODO: this is incomplete
- elif name == 'slots_3':
- args['width'] = 24
-
- elif 'gfx/sprites' in filedir:
- # TODO: this is incomplete
- if name == 'big_onix':
- args['width'] = 32
- args['rows'] = [(0, 4), (0, 4), (1, 2), (1, 2)]
- else:
- args['width'] = 16
-
- elif 'gfx/stats' in filedir:
- if name == 'stats_tiles':
- args['width'] = 136
-
- elif 'gfx/tilesets' in filedir:
- if filedir == 'gfx/tilesets/roofs':
- args['width'] = 24
- elif filedir != 'gfx/tilesets':
- args['width'] = 8
- else:
- args['tileset'] = True
-
- elif 'gfx/title' in filedir:
- if name in ['logo_bottom_gold', 'logo_bottom_silver', 'logo_top_gold', 'logo_top_silver']:
- args['width'] = 160
- elif name == 'lugia_silver':
- args['width'] = 64
- args['pic_dimensions'] = 8, 4
- elif name == 'hooh_gold':
- args['width'] = 64
- args['pic_dimensions'] = 8, 6
- elif name in ['title_trail_gold', 'title_trail_silver']:
- args['width'] = 32
-
- elif 'gfx/trainer_card' in filedir:
- if name in ['badges', 'trainer_card']:
- args['width'] = 16
- elif name == 'card_status':
- args['width'] = 48
- elif name == 'chris_card':
- args['width'] = 40
- elif name == 'leaders':
- args['width'] = 80
-
- elif 'gfx/trade' in filedir:
- if name in ['arrow_left', 'arrow_right', 'cable']:
- args['width'] = 8
- elif name in ['bubble', 'poof']:
- args['width'] = 16
- elif name == 'ball':
- args['width'] = 16
- args['rows'] = [(0, 1), (0, 1), (0, 2), (0, 2)]
- elif name == 'border_tiles':
- args['width'] = 24
- elif name == 'game_boy':
- args['width'] = 56
-
- elif 'gfx/unown_puzzle' in filedir:
- if name == 'start_cancel':
- args['width'] = 152
- elif name == 'tile_borders':
- args['width'] = 64
-
elif os.path.join(filedir, name) in pics:
args['pic'] = True
+ elif filedir == 'gfx/tilesets':
+ args['tileset'] = True
+
if args.get('pal_file'):
if os.path.exists(args['pal_file']):
args['palout'] = args['pal_file']
@@ -342,12 +184,10 @@ def filepath_rules(filepath):
w = min(w/8, h/8)
args['pic_dimensions'] = w, w
elif ext == '.2bpp':
- # startswith to handle front_gold / front_silver
- if pokemon_name and name.startswith('front'):
- w, h = get_pokemon_dimensions(pokemon_name)
+ if pokemon_name and name == 'front' or name == 'front.animated':
+ w, h = get_pokemon_dimensions(filepath.replace(ext, '.dimensions')) or (7, 7)
args['pic_dimensions'] = w, w
- # startswith to handle back_gold / back_silver
- elif pokemon_name and name.startswith('back'):
+ elif pokemon_name and name == 'back':
args['pic_dimensions'] = 6, 6
else:
args['pic_dimensions'] = 7, 7
@@ -377,31 +217,12 @@ def to_2bpp(filename, **kwargs):
def to_png(filename, **kwargs):
name, ext = os.path.splitext(filename)
- if ext == '.1bpp':
- basedir, basename = os.path.split(filename)
- name, ext = os.path.splitext(basename)
- # Ignoring these for convenience only
- if basedir in ['gfx/footprints', 'gfx/font']:
- return
- # Ignoring these for convenience only
- if name in ['hp_exp_bar_border']:
- return
- gfx.export_1bpp_to_png(filename, **kwargs)
- elif ext == '.2bpp':
- basedir, basename = os.path.split(filename)
- name, ext = os.path.splitext(basename)
- # TODO: how to actually make big_onix/slots_3 pngs (reusing one from pokecrystal for now)
- if name in ['big_onix', 'slots_3']:
- return
- # TODO: same question for most/all battle anims
- if basedir == 'gfx/battle_anims':
- return
- # Ignoring these for convenience only
- if basedir == 'gfx/font':
- return
- if name in ['back_gold', 'back_silver']:
- kwargs['fileout'] = os.path.join(basedir, 'back.png')
- gfx.export_2bpp_to_png(filename, **kwargs)
+ if ext == '.1bpp': gfx.export_1bpp_to_png(filename, **kwargs)
+ elif ext == '.2bpp' and name.endswith('.animated'):
+ w, h = kwargs.get('pic_dimensions') or (7, 7)
+ new_path = get_animated_graphics(filename, w=w, h=h)
+ return to_png(new_path, **kwargs)
+ elif ext == '.2bpp': gfx.export_2bpp_to_png(filename, **kwargs)
elif ext == '.png': pass
elif ext == '.lz':
decompress(filename, **kwargs)
@@ -415,8 +236,6 @@ def compress(filename, **kwargs):
def decompress(filename, **kwargs):
lz_data = open(filename, 'rb').read()
data = lz.Decompressed(lz_data).output
- # hack to work for Alakazam's silver backsprite; needs to be multiple of 8 anyway
- data = data[:len(data)//8*8]
name, ext = os.path.splitext(filename)
open(name, 'wb').write(bytearray(data))
diff --git a/tools/lz/nullcomp.c b/tools/lz/nullcomp.c
index 33d0b726..d4535bd3 100644
--- a/tools/lz/nullcomp.c
+++ b/tools/lz/nullcomp.c
@@ -6,7 +6,7 @@
Flags values: 0 = split a trailing 33-to-64-byte block at the end into two short blocks; 1 = don't
*/
-struct command * store_uncompressed (const unsigned char * data, const unsigned char * bitflipped, unsigned short * size, unsigned flags) {
+struct command * store_uncompressed (__attribute__((unused)) const unsigned char * data, __attribute__((unused)) const unsigned char * bitflipped, unsigned short * size, unsigned flags) {
unsigned short position, block, remainder = *size;
struct command * result = NULL;
*size = 0;
diff --git a/tools/lz/output.c b/tools/lz/output.c
index 484a9516..43e7ba92 100644
--- a/tools/lz/output.c
+++ b/tools/lz/output.c
@@ -28,16 +28,8 @@ void write_commands_and_padding_to_textfile (const char * file, const struct com
if (fputs("\tlzend\n", fp) < 0) error_exit(1, "could not write terminator to compressed output");
if (padding_size) {
input_stream += padding_offset;
- int rv = 0;
- unsigned pos;
- const char * prefix = "\tdb";
- for (pos = 0; (rv >= 0) && (pos < padding_size); pos ++) {
- if (input_stream[pos])
- rv = fprintf(fp, "%s $%02hhx", prefix, input_stream[pos]);
- else
- rv = fprintf(fp, "%s 0", prefix);
- prefix = ",";
- }
+ int rv = fprintf(fp, "\tdb $%02hhx", *(input_stream ++));
+ while ((rv >= 0) && (-- padding_size)) rv = fprintf(fp, ", $%02hhx", *(input_stream ++));
if (rv >= 0) rv = -(putc('\n', fp) == EOF);
if (rv < 0) error_exit(1, "could not write padding to compressed output");
}
diff --git a/tools/lz/packing.c b/tools/lz/packing.c
index 3623be96..0cb9fae9 100644
--- a/tools/lz/packing.c
+++ b/tools/lz/packing.c
@@ -31,6 +31,7 @@ void optimize (struct command * commands, unsigned short count) {
break;
case 1:
if (commands -> value != next -> value) break;
+ // fallthrough
case 3:
if ((commands -> count + next -> count) <= MAX_COMMAND_COUNT) {
commands -> count += next -> count;
diff --git a/tools/lz/repcomp.c b/tools/lz/repcomp.c
index 754529e8..f2bbad8a 100644
--- a/tools/lz/repcomp.c
+++ b/tools/lz/repcomp.c
@@ -7,7 +7,7 @@
(lowest bit to highest: repeat single byte (1), repeat two bytes (2), repeat zeros (3)).
*/
-struct command * try_compress_repetitions (const unsigned char * data, const unsigned char * bitflipped, unsigned short * size, unsigned flags) {
+struct command * try_compress_repetitions (const unsigned char * data, __attribute__((unused)) const unsigned char * bitflipped, unsigned short * size, unsigned flags) {
unsigned short pos = 0, skipped = 0;
struct command * result = malloc(*size * sizeof(struct command));
struct command * current = result;
diff --git a/tools/lz/spcomp.c b/tools/lz/spcomp.c
index ab33dbbc..b6184836 100644
--- a/tools/lz/spcomp.c
+++ b/tools/lz/spcomp.c
@@ -62,11 +62,11 @@ struct command find_best_copy (const unsigned char * data, unsigned short positi
struct command simple = {.command = 7};
struct command flipped = simple, backwards = simple;
short count, offset;
- if (count = scan_forwards(data + position, length - position, data, position, &offset))
+ if ((count = scan_forwards(data + position, length - position, data, position, &offset)))
simple = (struct command) {.command = 4, .count = count, .value = offset};
- if (count = scan_forwards(data + position, length - position, bitflipped, position, &offset))
+ if ((count = scan_forwards(data + position, length - position, bitflipped, position, &offset)))
flipped = (struct command) {.command = 5, .count = count, .value = offset};
- if (count = scan_backwards(data, length - position, position, &offset))
+ if ((count = scan_backwards(data, length - position, position, &offset)))
backwards = (struct command) {.command = 6, .count = count, .value = offset};
struct command command;
switch (flags / 24) {
diff --git a/tools/lz/uncomp.c b/tools/lz/uncomp.c
index b22fc75f..3544cd93 100644
--- a/tools/lz/uncomp.c
+++ b/tools/lz/uncomp.c
@@ -49,7 +49,7 @@ struct command * get_commands_from_file (const unsigned char * data, unsigned sh
}
if (slack) *slack = *size - (rp - data);
*size = current - result;
- return realloc(result, (*size ? *size : 1) * sizeof(struct command));
+ return realloc(result, *size * sizeof(struct command));
error:
free(result);
return NULL;
@@ -88,5 +88,5 @@ unsigned char * get_uncompressed_data (const struct command * commands, const un
}
}
*size = current - result;
- return realloc(result, *size ? *size : 1);
+ return result;
}
diff --git a/tools/pokemontools/gfx.py b/tools/pokemontools/gfx.py
index f4f2ae3e..2979b5a7 100644
--- a/tools/pokemontools/gfx.py
+++ b/tools/pokemontools/gfx.py
@@ -2,20 +2,19 @@
import os
import sys
-import io
-from . import png
+import png
from math import sqrt, floor, ceil
import argparse
import operator
-from .lz import Compressed, Decompressed
+from lz import Compressed, Decompressed
def split(list_, interval):
"""
Split a list by length.
"""
- for i in range(0, len(list_), interval):
+ for i in xrange(0, len(list_), interval):
j = min(i + interval, len(list_))
yield list_[i:j]
@@ -67,7 +66,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_tile[0] % width)
+ tiles = sorted(enumerate(tiles), key= lambda (i, tile): i % width)
return [tile for i, tile in tiles]
def transpose_tiles(image, width=None):
@@ -90,7 +89,7 @@ def interleave(tiles, width):
def deinterleave(tiles, width):
"""
- 00 02 04 06 08 0a 00 01 02 03 04 05
+ 00 02 04 06 08 0a 00 01 02 03 04 05
01 03 05 07 09 0b 06 07 08 09 0a 0b
0c 0e 10 12 14 16 --> 0c 0d 0e 0f 10 11
0d 0f 11 13 15 17 12 13 14 15 16 17
@@ -171,16 +170,16 @@ def test_condense_tiles_to_map():
def to_file(filename, data):
"""
- Apparently io.open(filename, 'wb').write(bytearray(data)) won't work.
+ Apparently open(filename, 'wb').write(bytearray(data)) won't work.
"""
- file = io.open(filename, 'wb')
+ file = open(filename, 'wb')
for byte in data:
file.write('%c' % byte)
file.close()
def decompress_file(filein, fileout=None):
- image = bytearray(io.open(filein).read())
+ image = bytearray(open(filein).read())
de = Decompressed(image)
if fileout == None:
@@ -189,7 +188,7 @@ def decompress_file(filein, fileout=None):
def compress_file(filein, fileout=None):
- image = bytearray(io.open(filein).read())
+ image = bytearray(open(filein).read())
lz = Compressed(image)
if fileout == None:
@@ -206,7 +205,7 @@ def bin_to_rgb(word):
return (red, green, blue)
def convert_binary_pal_to_text_by_filename(filename):
- pal = bytearray(io.open(filename).read())
+ pal = bytearray(open(filename).read())
return convert_binary_pal_to_text(pal)
def convert_binary_pal_to_text(pal):
@@ -232,7 +231,7 @@ def read_rgb_macros(lines):
def rewrite_binary_pals_to_text(filenames):
for filename in filenames:
pal_text = convert_binary_pal_to_text_by_filename(filename)
- with io.open(filename, 'w') as out:
+ with open(filename, 'w') as out:
out.write(pal_text)
@@ -245,7 +244,7 @@ def flatten(planar):
bottom = bottom
top = top
strip = []
- for i in range(7,-1,-1):
+ for i in xrange(7,-1,-1):
color = (
(bottom >> i & 1) +
(top *2 >> i & 2)
@@ -260,14 +259,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 range(height):
- tile_row = cur_line // tile_height
+ for cur_line in xrange(height):
+ tile_row = cur_line / tile_height
line = []
- for column in range(num_columns):
+ for column in xrange(num_columns):
anchor = (
num_columns * tile_row * tile_width * tile_height +
column * tile_width * tile_height +
@@ -288,7 +287,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 range(3)]]
+ red, green, blue = [int(color * 8.25) for color in [word.next() for _ in xrange(3)]]
alpha = 255
return (red, green, blue, alpha)
@@ -307,7 +306,7 @@ def pal_to_png(filename):
"""
Interpret a .pal file as a png palette.
"""
- with io.open(filename) as rgbs:
+ with open(filename) as rgbs:
colors = read_rgb_macros(rgbs.readlines())
a = 255
palette = []
@@ -381,7 +380,7 @@ def export_2bpp_to_png(filein, fileout=None, pal_file=None, height=0, width=0, t
if fileout == None:
fileout = os.path.splitext(filein)[0] + '.png'
- image = io.open(filein, 'rb').read()
+ image = open(filein, 'rb').read()
arguments = {
'width': width,
@@ -389,14 +388,12 @@ def export_2bpp_to_png(filein, fileout=None, pal_file=None, height=0, width=0, t
'pal_file': pal_file,
'tile_padding': tile_padding,
'pic_dimensions': pic_dimensions,
- 'pad_indices': kwargs.get('pad_indices', None),
- 'rows': kwargs.get('rows', None)
}
arguments.update(read_filename_arguments(filein))
- #if pal_file == None:
- # if os.path.exists(os.path.splitext(fileout)[0]+'.pal'):
- # arguments['pal_file'] = os.path.splitext(fileout)[0]+'.pal'
+ if pal_file == None:
+ if os.path.exists(os.path.splitext(fileout)[0]+'.pal'):
+ arguments['pal_file'] = os.path.splitext(fileout)[0]+'.pal'
result = convert_2bpp_to_png(image, **arguments)
width, height, palette, greyscale, bitdepth, px_map = result
@@ -409,7 +406,7 @@ def export_2bpp_to_png(filein, fileout=None, pal_file=None, height=0, width=0, t
greyscale=greyscale,
bitdepth=bitdepth
)
- with io.open(fileout, 'wb') as f:
+ with open(fileout, 'wb') as f:
w.write(f, px_map)
@@ -428,12 +425,10 @@ def convert_2bpp_to_png(image, **kwargs):
pic_dimensions = kwargs.get('pic_dimensions', None)
pal_file = kwargs.get('pal_file', None)
interleave = kwargs.get('interleave', False)
- pad_indices = kwargs.get('pad_indices', None)
- rows = kwargs.get('rows', None)
# 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
@@ -448,66 +443,34 @@ def convert_2bpp_to_png(image, **kwargs):
trailing = len(image) % pic_length
pic = []
- for i in range(0, len(image) - trailing, pic_length):
+ for i in xrange(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
- # Manually define at which tile indices padding tiles should be inserted
- elif width and pad_indices:
- padding = pad_color * 0x10
- cur_offset = 0
- cur_idx = 0
- for idx in pad_indices:
- next_offset = cur_offset + 0x10 * (idx - cur_idx)
- image = image[cur_offset:next_offset] + padding + image[next_offset:]
- cur_offset = next_offset + 0x10
- cur_idx = idx
-
- # Define width in pixels, and an array of (left_offset, tile_width) pairs
- elif width and rows:
- newimage = bytearray([])
- padding = pad_color * 0x10
- height = len(rows) * 8
- cur_index = 0
- for left_offset, tile_width in rows:
- # add padding if the row is offset from the leftmost tile
- newimage += padding * left_offset
-
- # add number of tiles to place horizontally, from base image
- next_index = min(len(image), cur_index + 0x10 * tile_width)
- newimage += image[cur_index:next_index]
- cur_index = next_index
-
- # add padding if there are more tiles in the row
- right_offset = max(0, width//8 - left_offset - tile_width)
- newimage += padding * right_offset
-
- image = newimage
-
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):
@@ -515,15 +478,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: (w_h[1] % 8 != 0, w_h[1] + w_h[0]))[0] # favor height
+ width, height = sorted(matches, key= lambda (w, h): (h % 8 != 0, w + h))[0] # favor height
else:
- raise Exception('Image can\'t be divided into tiles ({} px)!'.format(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)
@@ -554,7 +517,7 @@ def get_pic_animation(tmap, w, h):
base = frames.pop(0)
bitmasks = []
- for i in range(len(frames)):
+ for i in xrange(len(frames)):
frame_text += '\tdw .frame{}\n'.format(i + 1)
for i, frame in enumerate(frames):
@@ -606,7 +569,7 @@ def export_png_to_2bpp(filein, fileout=None, palout=None, **kwargs):
frame_text, bitmask_text = get_pic_animation(tmap, *arguments['pic_dimensions'])
frames_path = os.path.join(os.path.split(fileout)[0], 'frames.asm')
- with io.open(frames_path, 'w') as out:
+ with open(frames_path, 'w') as out:
out.write(frame_text)
bitmask_path = os.path.join(os.path.split(fileout)[0], 'bitmask.asm')
@@ -618,7 +581,7 @@ def export_png_to_2bpp(filein, fileout=None, palout=None, **kwargs):
bitmasks[-1] = bitmasks[-1].replace('1', '0')
bitmask_text = ';'.join(bitmasks)
- with io.open(bitmask_path, 'w') as out:
+ with open(bitmask_path, 'w') as out:
out.write(bitmask_text)
elif tmap != None and arguments.get('tilemap', False):
@@ -668,9 +631,9 @@ def png_to_2bpp(filein, **kwargs):
arguments.update(kwargs)
if type(filein) is str:
- filein = io.open(filein)
+ filein = open(filein)
- assert hasattr(filein, 'read')
+ assert type(filein) is file
width, height, rgba, info = png.Reader(filein).asRGBA8()
@@ -680,16 +643,16 @@ def png_to_2bpp(filein, **kwargs):
palette = []
for line in rgba:
newline = []
- for px in range(0, len(line), len_px):
+ for px in xrange(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),
color = sorted(palette, key=lambda x: sum(x.values()))[0]
- print(color)
+ print color
newline += [color]
image += [newline]
@@ -736,11 +699,11 @@ def png_to_2bpp(filein, **kwargs):
num_rows = max(height, tile_height) / tile_height
image = []
- for row in range(num_rows):
- for column in range(num_columns):
+ for row in xrange(num_rows):
+ for column in xrange(num_columns):
# Split it up into strips to convert to planar data
- for strip in range(min(tile_height, height)):
+ for strip in xrange(min(tile_height, height)):
anchor = (
row * num_columns * tile_width * tile_height +
column * tile_width +
@@ -766,13 +729,13 @@ def png_to_2bpp(filein, **kwargs):
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 range(len(tiles) // pic_length):
- offset = (h * tile_width) * ((block * w) // tile_width) + ((block * w) % tile_width)
+ for block in xrange(len(tiles) / pic_length):
+ offset = (h * tile_width) * ((block * w) / tile_width) + ((block * w) % tile_width)
pic = []
- for row in range(h):
+ for row in xrange(h):
index = offset + (row * tile_width)
pic += tiles[index:index + w]
new_image += transpose(pic, w)
@@ -807,7 +770,7 @@ def export_palette(palette, filename):
if os.path.exists(filename):
# Pic palettes are 2 colors (black/white are added later).
- with io.open(filename) as rgbs:
+ with open(filename) as rgbs:
colors = read_rgb_macros(rgbs.readlines())
if len(colors) == 2:
@@ -823,7 +786,7 @@ def png_to_lz(filein):
name = os.path.splitext(filein)[0]
export_png_to_2bpp(filein)
- image = io.open(name+'.2bpp', 'rb').read()
+ image = open(name+'.2bpp', 'rb').read()
to_file(name+'.2bpp'+'.lz', Compressed(image).output)
@@ -845,33 +808,32 @@ def convert_1bpp_to_2bpp(data):
def export_2bpp_to_1bpp(filename):
name, extension = os.path.splitext(filename)
- image = io.open(filename, 'rb').read()
+ image = open(filename, 'rb').read()
image = convert_2bpp_to_1bpp(image)
to_file(name + '.1bpp', image)
def export_1bpp_to_2bpp(filename):
name, extension = os.path.splitext(filename)
- image = io.open(filename, 'rb').read()
+ image = open(filename, 'rb').read()
image = convert_1bpp_to_2bpp(image)
to_file(name + '.2bpp', image)
-def export_1bpp_to_png(filename, fileout=None, **arguments):
+def export_1bpp_to_png(filename, fileout=None):
if fileout == None:
fileout = os.path.splitext(filename)[0] + '.png'
- if arguments is None :
- arguments = read_filename_arguments(filename)
+ arguments = read_filename_arguments(filename)
- image = io.open(filename, 'rb').read()
+ image = open(filename, 'rb').read()
image = convert_1bpp_to_2bpp(image)
result = convert_2bpp_to_png(image, **arguments)
width, height, palette, greyscale, bitdepth, px_map = result
w = png.Writer(width, height, palette=palette, compression=9, greyscale=greyscale, bitdepth=bitdepth)
- with io.open(fileout, 'wb') as f:
+ with open(fileout, 'wb') as f:
w.write(f, px_map)
@@ -900,7 +862,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:
@@ -912,7 +874,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:
@@ -924,18 +886,18 @@ 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:
- data = io.open(filename, 'rb').read()
+ data = open(filename, 'rb').read()
lz_data = Compressed(data).output
to_file(filename + '.lz', lz_data)
def decompress(filenames=[]):
for filename in filenames:
name, extension = os.path.splitext(filename)
- lz_data = io.open(filename, 'rb').read()
+ lz_data = open(filename, 'rb').read()
data = Decompressed(lz_data).output
to_file(name, data)
@@ -968,7 +930,7 @@ def main():
}.get(args.mode, None)
if method == None:
- raise Exception("Unknown conversion method!")
+ raise Exception, "Unknown conversion method!"
method(args.filenames)
diff --git a/tools/pokemontools/lz.py b/tools/pokemontools/lz.py
index f48be45c..aef5c641 100644
--- a/tools/pokemontools/lz.py
+++ b/tools/pokemontools/lz.py
@@ -44,8 +44,8 @@ lz_end = 0xff
bit_flipped = [
- sum(((byte >> i) & 1) << (7 - i) for i in range(8))
- for byte in range(0x100)
+ sum(((byte >> i) & 1) << (7 - i) for i in xrange(8))
+ for byte in xrange(0x100)
]
@@ -189,7 +189,7 @@ class Compressed:
)
for method in self.lookback_methods:
min_score = self.min_scores[method]
- for address in range(self.address+1, self.address+best_score):
+ for address in xrange(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 +211,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:
@@ -315,15 +315,15 @@ class Compressed:
def do_winner(self):
winners = filter(
- lambda method_score:
- method_score[1]
- > self.min_scores[method_score[0]] + int(method_score[1] > lowmax),
+ lambda (method, score):
+ score
+ > self.min_scores[method] + int(score > lowmax),
self.scores.iteritems()
)
winners.sort(
- key = lambda method_score: (
- -(method_score[1] - self.min_scores[method_score[0]] - int(method_score[1] > lowmax)),
- self.preference.index(method_score[0])
+ key = lambda (method, score): (
+ -(score - self.min_scores[method] - int(score > lowmax)),
+ self.preference.index(method)
)
)
winner, score = winners[0]
@@ -368,11 +368,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 +414,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):
@@ -543,7 +543,7 @@ class Decompressed:
Write alternating bytes.
"""
alts = [self.next(), self.next()]
- self.output += [ alts[x & 1] for x in range(self.length) ]
+ self.output += [ alts[x & 1] for x in xrange(self.length) ]
def blank(self):
"""
@@ -575,6 +575,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 range(self.length):
+ for i in xrange(self.length):
byte = self.output[ self.offset + i * direction ]
self.output.append( table[byte] if table else byte )
diff --git a/tools/pokemontools/png.py b/tools/pokemontools/png.py
index 3d6934a9..db6da128 100644
--- a/tools/pokemontools/png.py
+++ b/tools/pokemontools/png.py
@@ -646,9 +646,9 @@ class Writer:
# http://www.w3.org/TR/PNG/#11IHDR
write_chunk(outfile, b'IHDR',
- struct.pack("!2I5B", int(self.width), int(self.height),
- self.bitdepth, int(self.color_type),
- 0, 0, int(self.interlace)))
+ struct.pack("!2I5B", self.width, self.height,
+ self.bitdepth, self.color_type,
+ 0, 0, self.interlace))
# See :chunk:order
# http://www.w3.org/TR/PNG/#11gAMA
diff --git a/tools/unnamed.py b/tools/unnamed.py
index 1c66a36d..54a1473f 100755
--- a/tools/unnamed.py
+++ b/tools/unnamed.py
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
-import os, re
from sys import stderr, exit
from subprocess import Popen, PIPE
from struct import unpack, calcsize
@@ -31,25 +30,18 @@ signal(SIGPIPE,SIG_DFL)
import argparse
parser = argparse.ArgumentParser(description="Parse the symfile to find unnamed symbols")
-parser.add_argument('symfile', type=str, help="the filename with the list of symbols")
+parser.add_argument('symfile', type=argparse.FileType('r'), help="the list of symbols")
parser.add_argument('-r', '--rootdir', type=str, help="scan the output files to obtain a list of files with unnamed symbols (NOTE: will rebuild objects as necessary)")
args = parser.parse_args()
# Get list of object files
objects = None
-obj_suffix = '_obj := '
-m = re.match('poke(.*)\.sym', args.symfile)
-sym_game = m.group(1)
-def match_obj(game, line):
- return (sym_game == game) and line.startswith(game + obj_suffix)
if args.rootdir:
for line in Popen(["make", "-C", args.rootdir, "-s", "-p"],
stdout=PIPE).stdout.read().decode().split("\n"):
- if match_obj('gold', line) or match_obj('silver', line):
- offset = len(sym_game) + len(obj_suffix)
- objects = line[offset:].strip().split()
+ if line.startswith("crystal_obj := "):
+ objects = line[15:].strip().split()
break
-
else:
print("Error: Object files not found!", file=stderr)
exit(1)
@@ -57,7 +49,7 @@ if args.rootdir:
# Scan all unnamed symbols from the symfile
symbols_total = 0
symbols = set()
-for line in open(args.symfile, 'r'):
+for line in args.symfile:
line = line.split(";")[0].strip()
split = line.split(" ")
if len(split) < 2:
diff --git a/tools/used_space.py b/tools/used_space.py
index 73ece93d..6d313cf6 100644
--- a/tools/used_space.py
+++ b/tools/used_space.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""
-Usage: python3 used_space.py [pokecrystal.map] [used_space.png]
+Usage: python3 used_space.py [pokegold.map] [used_space.png]
Generate a PNG visualizing the space used by each bank in the ROM.
"""