Merge pull request #108 from yenatch/master

png->lz and palettes
This commit is contained in:
Bryan Bishop 2013-02-11 17:40:54 -08:00
commit b62d644d93
1261 changed files with 2081 additions and 216 deletions

View File

@ -1,4 +1,4 @@
.SUFFIXES: .asm .tx .o .gbc
.SUFFIXES: .asm .tx .o .gbc .png .2bpp .lz
TEXTFILES = text/sweethoney.tx \
text/phone/bill.tx \
@ -7,8 +7,25 @@ TEXTFILES = text/sweethoney.tx \
text/phone/trainers1.tx \
main.tx
VERTGFX = gfx/pics/%.png \
gfx/trainers/%.png
HORIZGFX = $(filter-out gfx/%.png, $(VERTGFX))
# uncomment this build target to enable png import:
#all: lzs
# the recompressed graphics may be larger than the originals,
# so take care to reorganize accordingly
all: pokecrystal.gbc
clean:
rm -f main.tx pokecrystal.o pokecrystal.gbc ${TEXTFILES}
pokecrystal.o: pokecrystal.asm constants.asm wram.asm ${TEXTFILES}
rgbasm -o pokecrystal.o pokecrystal.asm
@ -20,5 +37,19 @@ pokecrystal.gbc: pokecrystal.o
rgbfix -Cjv -i BYTE -k 01 -l 0x33 -m 0x10 -p 0 -r 3 -t PM_CRYSTAL $@
cmp baserom.gbc $@
clean:
rm -f main.tx pokecrystal.o pokecrystal.gbc ${TEXTFILES}
@lzs: ${VERTGFX} ${HORIZGFX}
@pngs:
cd extras; python gfx.py mass-decompress; python gfx.py dump-pngs
@front.png: tiles.png
cd extras; python gfx.py png-to-lz --front $@ $(OBJECT_DIRECTORY)/tiles.2bpp
@tiles.png:
cd extras; python gfx.py png-to-2bpp $@
@.png: ${VERTGFX}
cd extras; python gfx.py png-to-lz --vert $@
@.png: ${HORIZGFX}
cd extras; python gfx.py png-to-lz $@

1507
audio/cry_headers.asm Normal file

File diff suppressed because it is too large Load Diff

View File

@ -8,10 +8,11 @@ from math import sqrt, floor, ceil
from crystal import load_rom
from pokemon_constants import pokemon_constants
from trainers import trainer_group_names
rom = load_rom()
if __name__ != "__main__":
rom = load_rom()
def mkdir_p(path):
@ -953,17 +954,6 @@ def decompress_misc():
def decompress_all(debug = False):
"""decompress all known compressed data in baserom"""
#mkdir_p('../gfx/')
#mkdir_p('../gfx/frontpics/')
#mkdir_p('../gfx/anim/')
#mkdir_p('../gfx/backpics/')
#mkdir_p('../gfx/trainers/')
#mkdir_p('../gfx/fx/')
#mkdir_p('../gfx/intro/')
#mkdir_p('../gfx/title/')
#mkdir_p('../gfx/tilesets/')
#mkdir_p('../gfx/misc/')
if debug: print 'fronts'
decompress_monsters(front)
if debug: print 'backs'
@ -1032,7 +1022,7 @@ def compress_monster_frontpic(id, fileout):
anim = open(fanim, 'rb').read()
image = pic + anim
lz = Compressed(image, mode, 5)
lz = Compressed(image, mode, sizes[id-1])
out = '../gfx/pics/' + str(id).zfill(3) + '/front.lz'
@ -1081,6 +1071,8 @@ def grab_palettes(address, length = 0x80):
def dump_monster_pals():
rom = load_rom()
pals = 0xa8d6
pal_length = 0x4
for mon in range(251):
@ -1116,6 +1108,31 @@ def dump_monster_pals():
#print name+'ShinyPalette:'+spacing+' INCBIN "'+dir+filename+'"'
def dump_trainer_pals():
rom = load_rom()
pals = 0xb0d2
pal_length = 0x4
for trainer in range(67):
name = trainer_group_names[trainer+1]['constant'].title().replace('_','')
num = str(trainer).zfill(3)
dir = 'gfx/trainers/'
address = pals + trainer*pal_length
pal_data = []
for byte in range(pal_length):
pal_data.append(ord(rom[address]))
address += 1
filename = num+'.pal'
to_file('../'+dir+filename, pal_data)
spacing = ' ' * (12 - len(name))
print name+'Palette:'+spacing+' INCBIN"'+dir+filename+'"'
def flatten(planar):
"""
@ -1184,22 +1201,58 @@ def to_png(filein, fileout=None, pal_file=None, height=None, width=None):
Takes a planar 2bpp graphics file and converts it to png.
"""
if fileout == None: fileout = ''.join(filein.split('.')[:-1]) + '.png'
if fileout == None: fileout = '.'.join(filein.split('.')[:-1]) + '.png'
image = open(filein, 'rb').read()
num_pixels = len(image) * 4
if num_pixels == 0: return 'empty image!'
# unless the pic is square, at least one dimension should be given
if height == None and width == None:
height = int(sqrt(len(image)*4))
width = height
if width == None and height == None:
width = int(sqrt(num_pixels))
height = width
elif height == None: height = len(image)*4 / width
elif height == None:
height = num_pixels / width
elif width == None: width = len(image)*4 / height
elif width == None:
width = num_pixels / height
assert height * width == len(image)*4, 'Please specify dimensions for non-square image!'
# but try to see if it can be made rectangular
if width * height != num_pixels:
# look for possible combos of width/height that would form a rectangle
matches = []
# this is pretty inefficient, and there is probably a simpler way
for width in range(8,256+1,8): # we only want dimensions that fit in tiles
height = num_pixels / width
if height % 8 == 0:
matches.append((width, height))
# go for the most square image
width, height = sorted(matches, key=lambda (x,y): x+y)[0] # favors height
# if it can't, the only option is a width of 1 tile
if width * height != num_pixels:
width = 8
height = num_pixels / width
# if this still isn't rectangular, then the image isn't made of tiles
# for now we'll just spit out a warning
if width * height != num_pixels:
print 'Warning! ' + fileout + ' is ' + width + 'x' + height + '(' + width*height + ' pixels),\n' +\
'but ' + filein + ' is ' + num_pixels + ' pixels!'
# map it out
@ -1233,7 +1286,7 @@ def to_2bpp(filein, fileout=None, palout=None):
Takes a png and converts it to planar 2bpp.
"""
if fileout == None: fileout = ''.join(filein.split('.')[:-1]) + '.2bpp'
if fileout == None: fileout = '.'.join(filein.split('.')[:-1]) + '.2bpp'
with open(filein, 'rb') as file:
@ -1355,6 +1408,87 @@ def to_2bpp(filein, fileout=None, palout=None):
to_file(fileout, image)
def png_to_lz(filein):
name = os.path.splitext(filein)[0]
to_2bpp(filein)
image = open(name+'.2bpp', 'rb').read()
to_file(name+'.lz', Compressed(image).output)
def mass_to_png(debug=False):
# greyscale
for root, dirs, files in os.walk('../gfx/'):
for name in files:
if debug: print os.path.splitext(name), os.path.join(root, name)
if os.path.splitext(name)[1] == '.2bpp':
to_png(os.path.join(root, name))
def mass_to_colored_png(debug=False):
# greyscale
for root, dirs, files in os.walk('../gfx/'):
if 'pics' not in root and 'trainers' not in root:
for name in files:
if debug: print os.path.splitext(name), os.path.join(root, name)
if os.path.splitext(name)[1] == '.2bpp':
to_png(os.path.join(root, name))
# only monster and trainer pics for now
for root, dirs, files in os.walk('../gfx/pics/'):
for name in files:
if debug: print os.path.splitext(name), os.path.join(root, name)
if os.path.splitext(name)[1] == '.2bpp':
if 'normal.pal' in files:
to_png(os.path.join(root, name), None, os.path.join(root, 'normal.pal'))
else:
to_png(os.path.join(root, name))
for root, dirs, files in os.walk('../gfx/trainers/'):
for name in files:
if debug: print os.path.splitext(name), os.path.join(root, name)
if os.path.splitext(name)[1] == '.2bpp':
to_png(os.path.join(root, name), None, os.path.join(root, name[:-5] + '.pal'))
def mass_decompress(debug=False):
for root, dirs, files in os.walk('../gfx/'):
for file in files:
if 'lz' in file:
if '/pics' in root:
if 'front' in file:
id = root.split('pics/')[1][:3]
if id != 'egg':
with open(root+'/'+file, 'rb') as lz: de = Decompressed(lz.read(), 'vert', sizes[int(id)-1])
else:
with open(root+'/'+file, 'rb') as lz: de = Decompressed(lz.read(), 'vert', 4)
to_file(root+'/'+'front.2bpp', de.pic)
to_file(root+'/'+'tiles.2bpp', de.animtiles)
elif 'back' in file:
with open(root+'/'+file, 'rb') as lz: de = Decompressed(lz.read(), 'vert')
to_file(root+'/'+'back.2bpp', de.output)
elif '/trainers' in root or '/fx' in root:
with open(root+'/'+file, 'rb') as lz: de = Decompressed(lz.read(), 'vert')
to_file(root+'/'+file[:-3]+'.2bpp', de.output)
else:
with open(root+'/'+file, 'rb') as lz: de = Decompressed(lz.read())
to_file(root+file[:-3]+'.2bpp', de.output)
def append_terminator_to_lzs(directory):
# fix lzs that were extracted with a missing terminator
for root, dirs, files in os.walk(directory):
for file in files:
if '.lz' in file:
data = open(root+file,'rb').read()
if data[-1] != chr(0xff):
data += chr(0xff)
new = open(root+file,'wb')
new.write(data)
new.close()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
@ -1362,12 +1496,60 @@ if __name__ == "__main__":
parser.add_argument('arg1', nargs='?', metavar='arg1', type=str)
parser.add_argument('arg2', nargs='?', metavar='arg2', type=str)
parser.add_argument('arg3', nargs='?', metavar='arg3', type=str)
parser.add_argument('arg4', nargs='?', metavar='arg4', type=str)
parser.add_argument('arg5', nargs='?', metavar='arg5', type=str)
args = parser.parse_args()
debug = True
debug = False
if args.cmd == 'de':
if args.cmd == 'dump-pngs':
mass_to_colored_png()
elif args.cmd == 'png-to-lz':
# python gfx.py png-to-lz [--front anim(2bpp) | --vert] [png]
# python gfx.py png-to-lz --front [anim(2bpp)] [png]
if args.arg1 == '--front':
# front.png and tiles.png are combined before compression,
# so we have to pass in things like anim file and pic size
name = os.path.splitext(args.arg3)[0]
to_2bpp(name+'.png', name+'.2bpp')
pic = open(name+'.2bpp', 'rb').read()
anim = open(args.arg2, 'rb').read()
size = int(sqrt(len(pic)/16)) # assume square pic
to_file(name+'.lz', Compressed(pic + anim, 'vert', size).output)
# python gfx.py png-to-lz --vert [png]
elif args.arg1 == '--vert':
# others are vertically oriented (frontpics are always vertical)
name = os.path.splitext(args.arg2)[0]
to_2bpp(name+'.png', name+'.2bpp')
pic = open(name+'.2bpp', 'rb').read()
to_file(name+'.lz', Compressed(pic + anim, 'vert').output)
# python gfx.py png-to-lz [png]
else:
# standard usage
png_to_lz(args.arg1)
elif args.cmd == 'png-to-2bpp':
to_2bpp(args.arg1)
elif args.cmd == 'de':
# python gfx.py de [addr] [fileout] [mode]
rom = load_rom()
addr = int(args.arg1,16)
fileout = args.arg2
mode = args.arg3
@ -1388,10 +1570,12 @@ if __name__ == "__main__":
elif args.cmd == 'un':
# python gfx.py un [address] [num_tiles] [filename]
rom = load_rom()
get_uncompressed_gfx(int(args.arg1,16), int(args.arg2), args.arg3)
elif args.cmd == 'pal':
# python gfx.py pal [address] [length]
rom = load_rom()
print grab_palettes(int(args.arg1,16), int(args.arg2))
elif args.cmd == 'png':
@ -1405,8 +1589,8 @@ if __name__ == "__main__":
elif '.png' in args.arg1:
to_2bpp(args.arg1, args.arg2)
#else:
## python gfx.py
#decompress_all()
#if debug: print 'decompressed known gfx to ../gfx/!'
elif args.cmd == 'mass-decompress':
mass_decompress()
if debug: print 'decompressed known gfx to pokecrystal/gfx/!'

View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More