Skip to content

Instantly share code, notes, and snippets.

@Desdaemon
Last active July 5, 2024 05:30
Show Gist options
  • Save Desdaemon/cd673411c05aab976f5ee0e9144bf7a8 to your computer and use it in GitHub Desktop.
Save Desdaemon/cd673411c05aab976f5ee0e9144bf7a8 to your computer and use it in GitHub Desktop.
Tool to read map width/height from RM2K LMU maps
#!/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