Last active
July 5, 2024 05:30
-
-
Save Desdaemon/cd673411c05aab976f5ee0e9144bf7a8 to your computer and use it in GitHub Desktop.
Tool to read map width/height from RM2K LMU maps
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
def read_map(path): | |
with open(path, 'rb') as file: | |
header = read_slice(file) | |
if header != b"LcfMapUnit": | |
return | |
width = None | |
height = None | |
while not (width and height): | |
field = read_byte(file) | |
data = read_slice(file) | |
if field == 0x02: # width | |
width = read_int(data) | |
elif field == 0x03: # height | |
height = read_int(data) | |
elif field == 0x51: # events, should not get here | |
width = width or 20 | |
height = height or 15 | |
return width, height | |
def read_byte(file): | |
try: | |
return file.read(1)[0] | |
except IndexError as err: | |
raise ValueError('Expected a byte, got EOF') from err | |
def read_slice(file): | |
length = read_byte(file) | |
return file.read(length) | |
def read_int(data): | |
value = 0 | |
for nibble in data: | |
value = value << 7 | |
value = value | nibble & 0x7f; | |
if not (nibble & 0x80): | |
break | |
return value | |
if __name__ == "__main__": | |
from argparse import ArgumentParser | |
parser = ArgumentParser( | |
prog='lmusize', | |
description='Get the width/height of an LMU map', | |
) | |
parser.add_argument('maps', metavar='MAP.lmu', nargs='+', help='Path to .lmu file(s) (RM2K map file)') | |
parser.add_argument('-s', '--silent', action='store_true', help='Ignore warnings for invalid files') | |
args = parser.parse_args() | |
maps = args.maps | |
silent = args.silent | |
if len(maps) == 1: | |
map = maps[0] | |
if info := read_map(map): | |
width, height = info | |
print(f'{width=} {height=}') | |
exit() | |
print(f'{map=} is not a RM2K map file.') | |
exit(1) | |
for map in maps: | |
try: | |
if info := read_map(map): | |
width, height = info | |
print(f"{map=} {width=} {height=}") | |
except ValueError: | |
if not silent: | |
print(f'{map=} does not have enough data; skipping') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment