Permalink
Browse files

-Change: tools/extractsprites.py: move decode_format80() and save_pbm…

…() functions to specific .py file
  • Loading branch information...
miniupnp committed Apr 11, 2018
1 parent 80f88ed commit 7faf22b83c46d53d43d564e68b504f5bcd98f4d9
Showing with 107 additions and 59 deletions.
  1. +1 −0 .gitignore
  2. +4 −59 tools/extractsprites.py
  3. +18 −0 tools/save_pictures.py
  4. +84 −0 tools/westwood_codecs.py
View
@@ -27,5 +27,6 @@ projects/*
src/rev.c
.DS_Store
tools/*.o
tools/*.pyc
tools/amigaMXextract
tools/extractpak
View
@@ -1,10 +1,12 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4 noexpandtab
#
# Format to extract sprites from SHP
# extract sprites from SHP files (Westwood studios games)
from struct import *
import sys
from westwood_codecs import *
from save_pictures import *
palette = None
@@ -15,63 +17,6 @@ def load_palette(filename):
with open(filename, 'rb') as pal_file:
palette = ''.join(map(lambda c: chr((ord(c) << 2) + (ord(c) >> 6)), list(pal_file.read())))
def save_pbm(filename, width, height, pixels):
if (width & 1) != 0:
pixels = ''.join([line + chr(0) for line in split_string(pixels, width)])
with open(filename, 'wb') as pbm_file:
bmhd_chunk = 'BMHD' + pack('>LHHHHBBBBHBBHH', 20, width, height, 0, 0, 8, 2, 0, 0, 0, 10, 10, width, height);
cmap_chunk = '' if not palette else 'CMAP' + pack('>L', len(palette)) + palette
body_chunk = 'BODY' + pack('>L', len(pixels)) + pixels
size = 4 + len(body_chunk) + len(bmhd_chunk) + len(cmap_chunk)
form = 'FORM' + pack('>L', size) + 'PBM ' + bmhd_chunk + cmap_chunk + body_chunk
pbm_file.write(form)
print filename, "written"
def decode_format80(data):
dest = ''
i = 0
while i < len(data) and ord(data[i]) != 0x80:
cmd = ord(data[i])
i += 1
if cmd == 254: # 1111 1110 SS SS : long set
size = ord(data[i]) + (ord(data[i+1]) << 8)
#print cmd, 'long set', size, data[i+2].encode('hex')
dest += (data[i+2] * size)
i += 3
elif cmd == 255: # 1111 1111 SS SS OO OO : long absolute move
size = ord(data[i]) + (ord(data[i+1]) << 8)
offset = ord(data[i+2]) + (ord(data[i+3]) << 8)
#print cmd, 'long absolute move', offset, size
while size > 0:
dest += dest[offset]
offset += 1
size -= 1
i += 4
elif (cmd & 128) == 0: # 0sss oooo OO : short relative move
size = (cmd >> 4) + 3
offset = ((cmd & 15) << 8) + ord(data[i])
i += 1
#print cmd, 'short relative move', offset, size
while size > 0:
dest += dest[-offset]
size -= 1
elif (cmd & 64) != 0: # 11ss ssss OO OO : short absolute move
size = (cmd & 63) + 3
offset = ord(data[i]) + (ord(data[i+1]) << 8)
#print cmd, 'short absolute move', offset, size
while size > 0:
dest += dest[offset]
offset += 1
size -= 1
i += 2
else: # 10ss ssss : short copy
size = cmd & 63
#print cmd, 'short copy', size
dest += data[i:i+size]
i += size
return dest
def decode_sprite_data(data, palette):
# RLE 00 nn = nn transparent pixels (00)
dest = ''
@@ -121,7 +66,7 @@ def extract_shp(filename):
offsets.append(offset)
for i in range(count):
#print ' ', i, offsets[i]
save_pbm(*("%s_%03d.pbm" % (filename, i),) + decode_sprite(shp[offsets[i]:offsets[i+1]]))
save_pbm(*("%s_%03d.pbm" % (filename, i),) + decode_sprite(shp[offsets[i]:offsets[i+1]]) + (palette,))
if len(sys.argv) <= 1:
print "usage : %s [-p palette.PAL] file.shp" % sys.argv[0]
View
@@ -0,0 +1,18 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4 noexpandtab
#
from struct import pack
def save_pbm(filename, width, height, pixels, palette):
if (width & 1) != 0:
pixels = ''.join([line + chr(0) for line in split_string(pixels, width)])
with open(filename, 'wb') as pbm_file:
bmhd_chunk = 'BMHD' + pack('>LHHHHBBBBHBBHH', 20, width, height, 0, 0, 8, 2, 0, 0, 0, 10, 10, width, height);
cmap_chunk = '' if not palette else 'CMAP' + pack('>L', len(palette)) + palette
body_chunk = 'BODY' + pack('>L', len(pixels)) + pixels
size = 4 + len(body_chunk) + len(bmhd_chunk) + len(cmap_chunk)
form = 'FORM' + pack('>L', size) + 'PBM ' + bmhd_chunk + cmap_chunk + body_chunk
pbm_file.write(form)
print filename, "written"
View
@@ -0,0 +1,84 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4 noexpandtab
def decode_format80(data):
dest = ''
i = 0
while i < len(data) and ord(data[i]) != 0x80:
cmd = ord(data[i])
i += 1
if cmd == 254: # 1111 1110 SS SS : long set
size = ord(data[i]) + (ord(data[i+1]) << 8)
#print cmd, 'long set', size, data[i+2].encode('hex')
dest += (data[i+2] * size)
i += 3
elif cmd == 255: # 1111 1111 SS SS OO OO : long absolute move
size = ord(data[i]) + (ord(data[i+1]) << 8)
offset = ord(data[i+2]) + (ord(data[i+3]) << 8)
#print cmd, 'long absolute move', offset, size
while size > 0:
dest += dest[offset]
offset += 1
size -= 1
i += 4
elif (cmd & 128) == 0: # 0sss oooo OO : short relative move
size = (cmd >> 4) + 3
offset = ((cmd & 15) << 8) + ord(data[i])
i += 1
#print cmd, 'short relative move', offset, size
while size > 0:
dest += dest[-offset]
size -= 1
elif (cmd & 64) != 0: # 11ss ssss OO OO : short absolute move
size = (cmd & 63) + 3
offset = ord(data[i]) + (ord(data[i+1]) << 8)
#print cmd, 'short absolute move', offset, size
while size > 0:
dest += dest[offset]
offset += 1
size -= 1
i += 2
else: # 10ss ssss : short copy
size = cmd & 63
#print cmd, 'short copy', size
dest += data[i:i+size]
i += size
return dest
def decode_format40(data):
dest = ''
i = 0
while i < len(data):
cmd = ord(data[i])
i += 1
if cmd == 0:
# RLE
dest += (data[i+1] * ord(data[i]))
i += 2
elif (cmd & 0x80) == 0:
# copy
dest += data[i:i+cmd]
i += cmd
elif cmd == 0x80:
# 16 bit command
cmd = ord(data[i]) + (ord(data[i+1]) << 8)
i += 2
if cmd == 0:
# end
break
elif (cmd & 0x8000) == 0:
# skip
dest += (chr(0) * cmd)
elif (cmd & 0x4000) == 0:
count = cmd & 0x3fff
dest += data[i:i+count]
i += count
else:
count = cmd & 0x3fff
dest += (data[i] * count)
i += 1
else:
# skip
dest += (chr(0) * (cmd & 0x7f))
return dest

0 comments on commit 7faf22b

Please sign in to comment.