import sys, os import argparse from datetime import datetime import xml.etree.ElementTree as ET # Check if the script is run with the correct arguments parser = argparse.ArgumentParser(description="Generate chunk header files") parser.add_argument('--output', required=True, help='Dir to output headers') parser.add_argument('--input', required=True, help='Input XML file from tiled') args = parser.parse_args() # Ensure outdir exists outputDir = args.output os.makedirs(outputDir, exist_ok=True) # Create world directory if it does not exist worldDir = os.path.join(outputDir, "world") os.makedirs(worldDir, exist_ok=True) # Some vars used during printing now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # Read the input JSON file inputFile = args.input if not os.path.isfile(inputFile): print(f"Error: Input file '{inputFile}' does not exist.") sys.exit(1) with open(inputFile, 'r') as f: data = f.read() # Parse the XML data try: root = ET.fromstring(data) except ET.ParseError as e: print(f"Error parsing XML: {e}") sys.exit(1) if root.tag != 'tileset': print("Error: Input file is not a valid Tiled XML file.") sys.exit(1) if 'tilewidth' not in root.attrib or 'tileheight' not in root.attrib: print("Error: Missing tilewidth or tileheight attributes in the tileset.") sys.exit(1) if 'tilecount' not in root.attrib or 'columns' not in root.attrib: print("Error: Missing tilecount or columns attributes in the tileset.") sys.exit(1) tileWidth = int(root.get('tilewidth', 0)) tileHeight = int(root.get('tileheight', 0)) tileCount = int(root.get('tilecount', 0)) + 1 # +1 because maps are 1 indexed columns = int(root.get('columns', 0)) tilesById = {} for tile in root.findall('tile'): if 'id' not in tile.attrib: print("Error: Tile element missing 'id' attribute.") continue tileId = int(tile.get('id', -1)) + 1 # +1 because maps are 1 indexed if tileId < 0 or tileId >= tileCount: print(f"Error: Invalid tile ID {tileId} in tile element.") continue tilesById[tileId] = tile # Create the header file headerFile = os.path.join(worldDir, "tiledata.h") with open(headerFile, 'w') as f: f.write(f"// Generated on {now}\n") f.write(f"#include \"world/tile.h\"\n\n") f.write(f"#define TILE_WIDTH {tileWidth}\n") f.write(f"#define TILE_HEIGHT {tileHeight}\n") f.write(f"#define TILE_WIDTH_HEIGHT {tileWidth}\n") f.write(f"#define TILE_COUNT {tileCount}\n") f.write("static const tilemetadata_t TILE_META_DATA[TILE_COUNT] = {\n") for tileId in range(tileCount): tile = tilesById.get(tileId, None) if tile is None: f.write(f" {{ 0 }},\n") continue properties = tile.find('properties') if properties is None: f.write(f" {{ 0 }},\n") continue def findProp(name, expectedType=''): for prop in properties.findall('property'): if prop.get('name') == name: if len(expectedType) > 0: if 'type' in prop.attrib and prop.get('type') != expectedType: continue if 'propertytype' in prop.attrib and prop.get('propertytype') != expectedType: continue return prop.get('value', '') return None f.write(f" {{\n") propSolid = findProp('solidType', 'tileSolidType') if propSolid is not None: f.write(f" .solidType = {propSolid},\n") f.write(f" }},\n") f.write("};\n\n")