gfx.py automatically converts tilesets to 128-px wide pngs

This commit is contained in:
pikalaxalt 2016-05-17 23:01:43 -04:00
parent 98f443f70c
commit 87368a08a2
1 changed files with 128 additions and 122 deletions

250
gfx.py
View File

@ -8,164 +8,170 @@ from extras.pokemontools import gfx, lz
# Graphics with inverted tilemaps that aren't covered by filepath_rules. # Graphics with inverted tilemaps that aren't covered by filepath_rules.
pics = [ pics = [
'gfx/shrink1', 'gfx/shrink1',
'gfx/shrink2', 'gfx/shrink2',
] ]
def recursive_read(filename): def recursive_read(filename):
def recurse(filename_): def recurse(filename_):
lines = [] lines = []
for line in open(filename_): for line in open(filename_):
if 'include "' in line.lower(): if 'include "' in line.lower():
lines += recurse(line.split('"')[1]) lines += recurse(line.split('"')[1])
else: else:
lines += [line] lines += [line]
return lines return lines
lines = recurse(filename) lines = recurse(filename)
return ''.join(lines) return ''.join(lines)
base_stats = None base_stats = None
def get_base_stats(): def get_base_stats():
global base_stats global base_stats
if not base_stats: if not base_stats:
base_stats = recursive_read('data/base_stats.asm') base_stats = recursive_read('data/base_stats.asm')
return base_stats return base_stats
def get_pokemon_dimensions(name): def get_pokemon_dimensions(name):
try: try:
if name == 'egg': if name == 'egg':
return 5, 5 return 5, 5
if name == 'questionmark': if name == 'questionmark':
return 7, 7 return 7, 7
if name.startswith('unown_'): if name.startswith('unown_'):
name = 'unown' name = 'unown'
base_stats = get_base_stats() base_stats = get_base_stats()
start = base_stats.find('\tdb ' + name.upper()) start = base_stats.find('\tdb ' + name.upper())
start = base_stats.find('\tdn ', start) start = base_stats.find('\tdn ', start)
end = base_stats.find('\n', start) end = base_stats.find('\n', start)
line = base_stats[start:end].replace(',', ' ') line = base_stats[start:end].replace(',', ' ')
w, h = map(int, line.split()[1:3]) w, h = map(int, line.split()[1:3])
return w, h return w, h
except: except:
return 7, 7 return 7, 7
def filepath_rules(filepath): def filepath_rules(filepath):
"""Infer attributes of certain graphics by their location in the filesystem.""" """Infer attributes of certain graphics by their location in the filesystem."""
args = {} args = {}
filedir, filename = os.path.split(filepath) filedir, filename = os.path.split(filepath)
if filedir.startswith('./'): if filedir.startswith('./'):
filedir = filedir[2:] filedir = filedir[2:]
name, ext = os.path.splitext(filename) name, ext = os.path.splitext(filename)
if ext == '.lz': if ext == '.lz':
name, ext = os.path.splitext(name) name, ext = os.path.splitext(name)
pokemon_name = '' pokemon_name = ''
if 'gfx/pics/' in filedir: if 'gfx/pics/' in filedir:
pokemon_name = filedir.split('/')[-1] pokemon_name = filedir.split('/')[-1]
if pokemon_name.startswith('unown_'): if pokemon_name.startswith('unown_'):
index = filedir.find(pokemon_name) index = filedir.find(pokemon_name)
if index != -1: if index != -1:
filedir = filedir[:index + len('unown')] + filedir[index + len('unown_a'):] filedir = filedir[:index + len('unown')] + filedir[index + len('unown_a'):]
if name == 'front': if name == 'front':
args['pal_file'] = os.path.join(filedir, 'normal.pal') args['pal_file'] = os.path.join(filedir, 'normal.pal')
args['pic'] = True args['pic'] = True
args['animate'] = True args['animate'] = True
elif name == 'back': elif name == 'back':
args['pal_file'] = os.path.join(filedir, 'shiny.pal') args['pal_file'] = os.path.join(filedir, 'shiny.pal')
args['pic'] = True args['pic'] = True
elif 'gfx/trainers' in filedir: elif 'gfx/trainers' in filedir:
args['pic'] = True args['pic'] = True
elif os.path.join(filedir, name) in pics: elif os.path.join(filedir, name) in pics:
args['pic'] = True args['pic'] = True
if args.get('pal_file'): elif filedir == 'gfx/tilesets':
if os.path.exists(args['pal_file']): args['tileset'] = True
args['palout'] = args['pal_file']
else:
del args['pal_file']
if args.get('pic'): if args.get('pal_file'):
if ext == '.png': if os.path.exists(args['pal_file']):
w, h = gfx.png.Reader(filepath).asRGBA8()[:2] args['palout'] = args['pal_file']
w = min(w/8, h/8) else:
args['pic_dimensions'] = w, w del args['pal_file']
elif ext == '.2bpp':
if pokemon_name and name == 'front': if args.get('pic'):
w, h = get_pokemon_dimensions(pokemon_name) if ext == '.png':
args['pic_dimensions'] = w, w w, h = gfx.png.Reader(filepath).asRGBA8()[:2]
elif pokemon_name and name == 'back': w = min(w/8, h/8)
args['pic_dimensions'] = 6, 6 args['pic_dimensions'] = w, w
else: elif ext == '.2bpp':
args['pic_dimensions'] = 7, 7 if pokemon_name and name == 'front':
return args w, h = get_pokemon_dimensions(pokemon_name)
args['pic_dimensions'] = w, w
elif pokemon_name and name == 'back':
args['pic_dimensions'] = 6, 6
else:
args['pic_dimensions'] = 7, 7
if args.get('tileset'):
args['width'] = 128
return args
def to_1bpp(filename, **kwargs): def to_1bpp(filename, **kwargs):
name, ext = os.path.splitext(filename) name, ext = os.path.splitext(filename)
if ext == '.1bpp': pass if ext == '.1bpp': pass
elif ext == '.2bpp': gfx.export_2bpp_to_1bpp(filename, **kwargs) elif ext == '.2bpp': gfx.export_2bpp_to_1bpp(filename, **kwargs)
elif ext == '.png': gfx.export_png_to_1bpp(filename, **kwargs) elif ext == '.png': gfx.export_png_to_1bpp(filename, **kwargs)
elif ext == '.lz': elif ext == '.lz':
decompress(filename, **kwargs) decompress(filename, **kwargs)
to_1bpp(name, **kwargs) to_1bpp(name, **kwargs)
def to_2bpp(filename, **kwargs): def to_2bpp(filename, **kwargs):
name, ext = os.path.splitext(filename) name, ext = os.path.splitext(filename)
if ext == '.1bpp': gfx.export_1bpp_to_2bpp(filename, **kwargs) if ext == '.1bpp': gfx.export_1bpp_to_2bpp(filename, **kwargs)
elif ext == '.2bpp': pass elif ext == '.2bpp': pass
elif ext == '.png': gfx.export_png_to_2bpp(filename, **kwargs) elif ext == '.png': gfx.export_png_to_2bpp(filename, **kwargs)
elif ext == '.lz': elif ext == '.lz':
decompress(filename, **kwargs) decompress(filename, **kwargs)
to_2bpp(name, **kwargs) to_2bpp(name, **kwargs)
def to_png(filename, **kwargs): def to_png(filename, **kwargs):
name, ext = os.path.splitext(filename) name, ext = os.path.splitext(filename)
if ext == '.1bpp': gfx.export_1bpp_to_png(filename, **kwargs) if ext == '.1bpp': gfx.export_1bpp_to_png(filename, **kwargs)
elif ext == '.2bpp': gfx.export_2bpp_to_png(filename, **kwargs) elif ext == '.2bpp': gfx.export_2bpp_to_png(filename, **kwargs)
elif ext == '.png': pass elif ext == '.png': pass
elif ext == '.lz': elif ext == '.lz':
decompress(filename, **kwargs) decompress(filename, **kwargs)
to_png(name, **kwargs) to_png(name, **kwargs)
def compress(filename, **kwargs): def compress(filename, **kwargs):
data = open(filename, 'rb').read() data = open(filename, 'rb').read()
lz_data = lz.Compressed(data).output lz_data = lz.Compressed(data).output
open(filename + '.lz', 'wb').write(bytearray(lz_data)) open(filename + '.lz', 'wb').write(bytearray(lz_data))
def decompress(filename, **kwargs): def decompress(filename, **kwargs):
lz_data = open(filename, 'rb').read() lz_data = open(filename, 'rb').read()
data = lz.Decompressed(lz_data).output data = lz.Decompressed(lz_data).output
name, ext = os.path.splitext(filename) name, ext = os.path.splitext(filename)
open(name, 'wb').write(bytearray(data)) open(name, 'wb').write(bytearray(data))
methods = { methods = {
'2bpp': to_2bpp, '2bpp': to_2bpp,
'1bpp': to_1bpp, '1bpp': to_1bpp,
'png': to_png, 'png': to_png,
'lz': compress, 'lz': compress,
'unlz': decompress, 'unlz': decompress,
} }
def main(method_name, filenames=None): def main(method_name, filenames=None):
if filenames is None: filenames = [] if filenames is None: filenames = []
for filename in filenames: for filename in filenames:
args = filepath_rules(filename) args = filepath_rules(filename)
method = methods.get(method_name) method = methods.get(method_name)
if method: if method:
method(filename, **args) method(filename, **args)
def get_args(): def get_args():
ap = argparse.ArgumentParser() ap = argparse.ArgumentParser()
ap.add_argument('method_name') ap.add_argument('method_name')
ap.add_argument('filenames', nargs='*') ap.add_argument('filenames', nargs='*')
args = ap.parse_args() args = ap.parse_args()
return args return args
if __name__ == '__main__': if __name__ == '__main__':
main(**get_args().__dict__) main(**get_args().__dict__)