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
- # 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 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({'id': id, 'count': count, 'start': start})
- else:
- states[-1].setdefault('overlays', {}).setdefault(id[-2], []).append({'count': count, 'start': 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:
- basestate_fname = '{}_{}'.format(arg_basename, s['id'])
- 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 (overlay, l) in s['overlays'].items():
- overlay_images[overlay] = []
- for (i, x) in enumerate(l):
- overlay_images[overlay].append((i, empty_im.copy()))
- s_im = overlay_images[overlay][-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 = basestate_fname
- for (overlay, (num, overlay_im)) in zip(s['overlays'].keys(), overlays):
- s_fname += overlay + str(num)
- 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