Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # With much code copying from Nimms <nimms@ya.ru> and anon
- import sys
- import glob
- import os
- import struct
- import codecs
- from PIL import Image
- from itertools import product
- class state:
- def __init__(self, id, count, start):
- self.id = id
- self.count = count
- self.start = start
- self.overlays = {}
- class overlay:
- def __init__(self, count, start):
- self.count = count
- self.start = start
- SKIP_CGS = True
- # endianness, depends on target platform (> = big, < = little)
- BYTE_ORDER = '<'
- BLOCK_SIZE = 32
- if len(sys.argv) == 1:
- print("No files given.", file=sys.stderr)
- exit(1)
- args = sys.argv[1:]
- if len(sys.argv) == 0:
- args = glob.glob('*.mvl')
- else:
- for i, arg in enumerate(args):
- if '*' in arg:
- args = args[:i] + glob.glob(arg) + args[i+1:]
- for arg in args:
- arg = os.path.abspath(os.path.splitext(arg)[0])
- if arg[-1] == '_':
- arg = arg[:-1]
- arg_basename = os.path.basename(arg)
- if SKIP_CGS and any(c.isdigit() for c in arg_basename):
- continue
- if not os.path.exists(arg_basename):
- os.mkdir(arg_basename)
- os.chdir(arg_basename)
- print(arg_basename)
- records_count = 0
- map_count = 0
- states = []
- records = []
- map = []
- map_start = None
- with open(arg + '_.mvl', 'rb') as f:
- # 4 chars: MVL1
- f.read(4)
- # uint32: count of states
- states_count = struct.unpack(BYTE_ORDER + 'I', f.read(4))[0]
- #print(states_count)
- # uint32: input width
- INPUT_WIDTH = struct.unpack(BYTE_ORDER + 'I', f.read(4))[0]
- #print(INPUT_WIDTH)
- # 20 zeros
- f.read(20)
- # 64 characters
- shit = str(f.read(64), encoding='ascii').strip('\0')
- #print(shit)
- for i in range(states_count):
- # uint32: output width
- SCREEN_WIDTH = struct.unpack(BYTE_ORDER + 'I', f.read(4))[0]
- # uint32: output height
- SCREEN_HEIGHT = struct.unpack(BYTE_ORDER + 'I', f.read(4))[0]
- # uint32: idk
- idk = struct.unpack(BYTE_ORDER + 'I', f.read(4))[0]
- # 4 zeros
- f.read(4)
- # uint32: count of coordinates records
- records_count = struct.unpack(BYTE_ORDER + 'I', f.read(4))[0]
- # uint32: beginning of coordinates records
- records_start = struct.unpack(BYTE_ORDER + 'I', f.read(4))[0]
- # uint32: count of records to read
- count = struct.unpack(BYTE_ORDER + 'I', f.read(4))[0]
- # uint32: beginning of records to read
- start = struct.unpack(BYTE_ORDER + 'I', f.read(4))[0]
- # 32 chars: state name
- id = str(f.read(32), encoding='ascii').strip('\0')
- if map_start == None:
- map_start = start
- start = (start - map_start) // 2
- count
- map_count += count
- if len(id) == 9:
- states.append(state(id, count, start))
- else:
- states[-1].overlays.setdefault(id[-2], []).append(overlay(count, start))
- #print(id, count, start, sep='\t')
- #print()
- #print(output_width, output_height)
- #print()
- #print(records_count)
- for i in range(records_count):
- # float32: block position on the screen, X
- x1 = int(struct.unpack(BYTE_ORDER + 'f', f.read(4))[0])# + 1
- # float32: block position on the screen, Y
- y1 = int(struct.unpack(BYTE_ORDER + 'f', f.read(4))[0])# + 1
- # 4 zeros
- f.read(4)
- # float32: block position in the image, X
- x2 = struct.unpack(BYTE_ORDER + 'f', f.read(4))[0]# - 1
- # float32: block position in the image, Y
- y2 = struct.unpack(BYTE_ORDER + 'f', f.read(4))[0]# - 1
- #print(x1, y1, x2, y2)
- records.append((x1, y1, x2, y2))
- #print()
- #print(map_count)
- for i in range(map_count):
- (idx,) = struct.unpack(BYTE_ORDER + 'H', f.read(2))
- map.append(idx)
- with Image.open(arg + '.png') as image:
- # empty image
- empty_im = Image.new('RGBA', (SCREEN_WIDTH, SCREEN_HEIGHT), (0, 0, 0, 0))
- for s in states:
- print(s.id)
- s_im = basestate_im = empty_im.copy()
- for i in range(s.start, s.start + s.count, 6):
- c = records[map[i]]
- in_box = (int(c[2] * image.size[0]) + 1, int(c[3] * image.size[1]) + 1, int(c[2] * image.size[0]) + BLOCK_SIZE - 1, int(c[3] * image.size[1]) + BLOCK_SIZE - 1)
- out_box = (SCREEN_WIDTH//2 + c[0], SCREEN_HEIGHT//2 + c[1])
- region = image.crop(in_box)
- s_im.paste(region, out_box, region)
- overlay_images = {}
- for (o, l) in s.overlays.items():
- overlay_images[o] = []
- for (i, x) in enumerate(l):
- overlay_images[o].append((i, empty_im.copy()))
- s_im = overlay_images[o][-1][1]
- for j in range(x.start, x.start + x.count, 6):
- c = records[map[j]]
- in_box = (int(c[2] * image.size[0]) + 1, int(c[3] * image.size[1]) + 1, int(c[2] * image.size[0]) + BLOCK_SIZE - 1, int(c[3] * image.size[1]) + BLOCK_SIZE - 1)
- out_box = (SCREEN_WIDTH//2 + c[0], SCREEN_HEIGHT//2 + c[1])
- region = image.crop(in_box)
- s_im.paste(region, out_box, region)
- for overlays in product(*overlay_images.values()):
- s_im = basestate_im.copy()
- s_fname = s.id
- for (o, (num, overlay_im)) in zip(s.overlays.keys(), overlays):
- s_fname += o + str(num + 1)
- if os.path.isfile(s_fname):
- continue
- for (num, overlay_im) in overlays:
- s_im.paste(overlay_im, mask=overlay_im)
- s_im.save(s_fname + '.png')
- s_im.close()
- basestate_im.close()
- for l in overlay_images.values():
- for (num, im) in l:
- im.close()
- print()
- os.chdir('..')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement