import sys, os import argparse from datetime import datetime import math from inputParser import parseInputFile from mapParser import parseMap from chunkParser import parseChunk from constants import CHUNK_WIDTH, CHUNK_HEIGHT, TILE_WIDTH_HEIGHT # 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 JSON 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) # Create chunks directory if it does not exist chunksDir = os.path.join(worldDir, "chunk") os.makedirs(chunksDir, exist_ok=True) # Some vars used during printing now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # Read the input JSON file data = parseInputFile(args.input) mapData = parseMap(data) # For each output chunk. worldWidth = 0 worldHeight = 0 chunksDone = set() for chunkY in range(mapData['mapHeightInRealChunks']): for chunkX in range(mapData['mapWidthInRealChunks']): chunkData = parseChunk(chunkX, chunkY, mapData) if chunkData is None: continue # This is a valid chunk. worldWidth = max(worldWidth, chunkX + 1) worldHeight = max(worldHeight, chunkY + 1) chunksDone.add((chunkX, chunkY)) chunkHeaderPath = os.path.join(chunksDir, f"chunk_{chunkX}_{chunkY}.h") with open(chunkHeaderPath, 'w') as f: f.write(f"// Generated chunk header for chunk at position ({chunkX}, {chunkY})\n") f.write(f"// Generated at {now}\n") f.write("#pragma once\n") f.write("#include \"world/chunkdata.h\"\n\n") f.write(f"static const chunkdata_t CHUNK_{chunkX}_{chunkY} = {{\n") f.write(f" .layerBase = {{\n") for y in range(CHUNK_HEIGHT): f.write(f" ") for x in range(CHUNK_WIDTH): i = y * CHUNK_WIDTH + x byte = chunkData['layerBaseData'][i] f.write(f"0x{byte:02x}, ") f.write(f"\n") f.write(" },\n\n") f.write(" .layerBaseOverlay = {\n") if chunkData['layerBaseOverlay'] is not None: for y in range(CHUNK_HEIGHT): f.write(f" ") for x in range(CHUNK_WIDTH): i = y * CHUNK_WIDTH + x byte = chunkData['layerBaseOverlayData'][i] f.write(f"0x{byte:02x}, ") f.write(f"\n") f.write(" },\n\n") f.write(f" .entities = {{\n") for entity in chunkData['entities']: f.write(" {\n") f.write(f" .id = {entity['id']},\n") f.write(f" .type = {entity['type']},\n") f.write(f" .x = {round(entity['x'] / TILE_WIDTH_HEIGHT)},\n") f.write(f" .y = {round(entity['y'] / TILE_WIDTH_HEIGHT)},\n") if 'dir' in entity: f.write(f" .dir = {entity['dir']},\n") def printRecurse(obj, tabs = " "): for key, value in obj: if isinstance(value, dict): f.write(f"{tabs}.{key} = {{\n") printRecurse(value.items(), tabs + " ") f.write(f"{tabs}}},\n") elif isinstance(value, list): f.write(f"{tabs}.{key} = {{\n") for item in value: f.write(f"{tabs} {item},\n") f.write(f"{tabs}}},\n") else: f.write(f"{tabs}.{key} = {value},\n") if 'data' in entity: printRecurse(entity['data'].items()) f.write(" },\n") f.write(f" }},\n") f.write("};\n\n") # Output header file. headerPath = os.path.join(worldDir, "world.h") with open(headerPath, 'w') as f: f.write(f"// Generated chunks file. Generated at {now}\n\n") f.write("#pragma once\n") f.write("#include \"dusk.h\"\n") # Now, for each chunk, include its header file for (x, y) in chunksDone: f.write(f"#include \"world/chunk/chunk_{x}_{y}.h\"\n") f.write("\n") f.write(f"#define WORLD_WIDTH {worldWidth}\n") f.write(f"#define WORLD_HEIGHT {worldHeight}\n") # Write out other global variables. f.write(f"#define WORLD_PLAYER_SPAWN_X ({round(mapData['playerSpawnX'] / TILE_WIDTH_HEIGHT)})\n") f.write(f"#define WORLD_PLAYER_SPAWN_Y ({round(mapData['playerSpawnY'] / TILE_WIDTH_HEIGHT)})\n") f.write("\n") f.write(f"static const chunkdata_t* WORLD_CHUNKS[] = {{\n") for i in range(worldHeight): f.write(" ") for j in range(worldWidth): if(j, i) in chunksDone: f.write(f"&CHUNK_{j}_{i}, ") else: f.write("NULL, ") f.write("\n") f.write("};\n\n") print(f"chunks.h generated at: {headerPath}")