blob: 100c963aa2989b7ee32fefc1e7bafb271051d2f2 [file] [log] [blame] [edit]
#!/usr/bin/env python3
import argparse
import sys
import pathlib
import subprocess
import os
def command_tiled2csv(args):
# Try to find tiled in a number of popular binary holiday resorts
tool_paths = [
pathlib.Path("C:\\Program Files\\Tiled\\tiled.exe"),
pathlib.Path("/mnt/c/Program Files/Tiled/tiled.exe"),
pathlib.Path("/usr/bin/tiled")
]
tool_path = None
for tool in tool_paths:
if tool.is_file():
print(f"Found tiled at {tool}")
tool_path = tool
break
if args.out.is_file() and not args.force:
print(f'Refusing to write to {args.out} (File exists!)')
elif tool_path is not None:
print(f"Writing {args.out}")
tool_path = str(tool_path)
source = args.file
dest = args.out
if tool_path == str(tool_paths[1]):
# Tiled.exe invoked from WSL requires relative paths
# This hack rewrites the source/dest path to be relative to the working directory
tool_path = tool_path.replace(" ", "\\ ")
rel_path = pathlib.Path(os.getcwd())
source = os.path.relpath(source, rel_path)
dest = os.path.relpath(dest, rel_path)
if tool_path == str(tool_paths[0]):
# Tiled.exe invoked from Windows needs a "" quoted path to handle spaces
tool_path = f"\"{tool_path}\""
subprocess.run(f"{tool_path} --export-map {source} {dest}", shell=True, check=True)
return True
return False
def command_csv2bin(args):
# csv2bin mode is handy for converting comma-separated file types into binary format for using as assets
# In particular this mode was written to take the csv output of Tiled editor and convert it
# You can convert a Tiled map in WSL '/mnt/c/Program\ Files/Tiled/tiled.exe --export-map level.tmx level.csv'
# Or, in Linux native, 'tiled --export-map level.tmx level.csv'
# If you don't use asset embedding you should try: https://github.com/HeadBoffin/32blit-Tiled
# Open and strip whitespace from the file contents
source = open(args.file, 'r').read().strip()
# Replace '1, 2, 3' to '1,2,3', might as well do it here
source = source.replace(' ', '')
# Split out into rows on linebreak
source = source.split('\n')
# Split every row into columns on the comma
source = [row.split(',') for row in source]
# Count number of rows and cols
rows = len(source)
cols = len(source[0])
print(f'Read {rows} rows and {cols} cols')
# Flatten our rows/cols 2d array into a 1d array of bytes
# Might as well do the int conversion here, to save another loop
source = [int(col, args.base) for row in source for col in row]
# Convert the list of ints to a bytearray
source = bytearray(source)
# And write the result to our output binary file
if args.out is not None:
if args.out.is_file() and not args.force:
print(f'Refusing to write to {args.out} (File exists!)')
else:
print(f'Writing binary file to {args.out} ({cols}x{rows} - {len(source)} bytes)')
with open(args.out, 'wb') as file:
file.write(source)
def default_args(parser):
parser.add_argument('--out', type=pathlib.Path, help='set output filename (default <inputfile>.blit)', default=None)
parser.add_argument('--force', action='store_true', help='force output file overwrite', default=False)
parser.add_argument('file', type=pathlib.Path, help='input file')
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--nowarn', action='store_true', help='Suppress deprecation warning')
subparsers = parser.add_subparsers(help='Commands', dest='command')
parser_csv2bin = subparsers.add_parser('csv2bin', help='Process a CSV file of numbers into a bin file')
parser_tiled2bin = subparsers.add_parser('tiled2bin', help='Process a tiled .tmx file into a bin file')
default_args(parser_csv2bin)
parser_csv2bin.add_argument('--base', type=int, help='set input number base (default 10, or decimal)', default=10)
default_args(parser_tiled2bin)
parser_tiled2bin.add_argument('--base', type=int, help='set input number base (default 10, or decimal)', default=10)
args = parser.parse_args()
if not args.nowarn:
print('''
This tool has been deprecated in favour of https://github.com/pimoroni/32blit-tools
Run with --nowarn to hide this message.
''')
if args.command == 'csv2bin':
command_csv2bin(args)
if args.command == 'tiled2bin':
# Save out unmangled output path
output_file = args.out
# Mangle the output path into a temporary filename with ONLY ONE EXTENSION
# Tiled gets confused if you give it more than one, since it uses the
# extension to figure out which format to export.
args.out = pathlib.Path(args.out.with_name(args.out.name.replace(".", "-") + ".csv"))
if command_tiled2csv(args):
args.file = args.out
args.out = output_file
command_csv2bin(args)
else:
print(f'''Usage: {sys.argv[0]} <command> <args>
- csv2bin - convert a CSV separated file of numerical values into a raw binary''')