From 1e75471f5af1ff90105626bdef794101b1e7a65c Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Sun, 15 Jun 2025 09:49:02 -0500 Subject: [PATCH] Map generator done --- data/map.tmj | 102 ++++++++++++++++---- src/duskraylib/display/draw/drawoverworld.c | 32 ++++-- tools/mapcompile/mapcompile.py | 64 ++++++------ 3 files changed, 145 insertions(+), 53 deletions(-) diff --git a/data/map.tmj b/data/map.tmj index f0fe1c6..c63268e 100644 --- a/data/map.tmj +++ b/data/map.tmj @@ -5,21 +5,21 @@ { "chunks":[ { - "data":[1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "data":[1, 2, 3, 4, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 52, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "height":16, "width":16, @@ -39,22 +39,44 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25], "height":16, "width":16, "x":16, "y":0 }, + { + "data":[0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 25, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 28, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 18, 19, 20, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, + 26, 27, 28, 0, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0], + "height":16, + "width":16, + "x":32, + "y":0 + }, { "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -80,10 +102,10 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 17, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 25, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], @@ -113,6 +135,50 @@ "width":16, "x":16, "y":16 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 28, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 25, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 12, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 28], + "height":16, + "width":16, + "x":32, + "y":16 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 28, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":16, + "width":16, + "x":48, + "y":16 }], "height":32, "id":1, diff --git a/src/duskraylib/display/draw/drawoverworld.c b/src/duskraylib/display/draw/drawoverworld.c index 84189bc..5854d2b 100644 --- a/src/duskraylib/display/draw/drawoverworld.c +++ b/src/duskraylib/display/draw/drawoverworld.c @@ -39,14 +39,32 @@ void drawOverworldDraw(void) { // Bottom layer chunk_t *chunk = CHUNK_MAP.chunks; + + Color colors[] = { + RED, GREEN, BLUE, YELLOW, PURPLE, ORANGE, PINK, BROWN, + DARKGRAY, LIGHTGRAY, DARKBLUE, DARKGREEN, DARKPURPLE, + DARKBROWN + }; + uint8_t colorCount = sizeof(colors) / sizeof(Color); + do { - DrawRectangle( - ((int32_t)chunk->x) * CHUNK_WIDTH * TILE_WIDTH, - ((int32_t)chunk->y) * CHUNK_HEIGHT * TILE_HEIGHT, - CHUNK_WIDTH * TILE_WIDTH, - CHUNK_HEIGHT * TILE_HEIGHT, - (chunk->tiles[0] == 0) ? RED : GREEN - ); + for(uint8_t i = 0; i < CHUNK_TILE_COUNT; i++) { + tile_t tile = chunk->tiles[i]; + if(tile == 0) continue; // Skip empty tiles + + uint32_t x = (uint32_t)chunk->x * CHUNK_WIDTH * TILE_WIDTH + (i % CHUNK_WIDTH) * TILE_WIDTH; + uint32_t y = (uint32_t)chunk->y * CHUNK_HEIGHT * TILE_HEIGHT + (i / CHUNK_WIDTH) * TILE_HEIGHT; + + DrawRectangle(x, y, TILE_WIDTH, TILE_HEIGHT, colors[tile % colorCount]); + } + + // DrawRectangle( + // ((int32_t)chunk->x) * CHUNK_WIDTH * TILE_WIDTH, + // ((int32_t)chunk->y) * CHUNK_HEIGHT * TILE_HEIGHT, + // CHUNK_WIDTH * TILE_WIDTH, + // CHUNK_HEIGHT * TILE_HEIGHT, + // (chunk->tiles[0] == 0) ? RED : GREEN + // ); chunk++; } while(chunk < CHUNK_MAP.chunks + CHUNK_MAP_COUNT); diff --git a/tools/mapcompile/mapcompile.py b/tools/mapcompile/mapcompile.py index 453ffb5..9689dfc 100644 --- a/tools/mapcompile/mapcompile.py +++ b/tools/mapcompile/mapcompile.py @@ -87,12 +87,8 @@ inputLayerWidthInTiles = firstLayerFirstChunk['width'] inputLayerHeightInTiles = firstLayerFirstChunk['height'] mapWidthInTiles = firstLayer['width'] mapHeightInTiles = firstLayer['height'] -mapWidthInRealTiles = math.ceil(float(mapWidthInTiles) / float(CHUNK_WIDTH)) -mapHeightInRealTiles = math.ceil(float(mapHeightInTiles) / float(CHUNK_HEIGHT)) - -print(f"Input Layer Size: {inputLayerWidthInTiles}x{inputLayerHeightInTiles} tiles") -print(f"Map Size: {mapWidthInTiles}x{mapHeightInTiles} tiles") -print(f"Map Real Size: {mapWidthInRealTiles}x{mapHeightInRealTiles} chunks") +mapWidthInRealChunks = math.ceil(float(mapWidthInTiles) / float(CHUNK_WIDTH)) +mapHeightInRealChunks = math.ceil(float(mapHeightInTiles) / float(CHUNK_HEIGHT)) if inputLayerWidthInTiles < CHUNK_WIDTH or inputLayerHeightInTiles < CHUNK_HEIGHT: print(f"Error: Input layer size {inputLayerWidthInTiles}x{inputLayerHeightInTiles} is smaller than chunk size {CHUNK_WIDTH}x{CHUNK_HEIGHT}.") @@ -103,8 +99,8 @@ worldWidth = 0 worldHeight = 0 chunksDone = set() -for chunkY in range(mapHeightInRealTiles): - for chunkX in range(mapWidthInRealTiles): +for chunkY in range(mapHeightInRealChunks): + for chunkX in range(mapWidthInRealChunks): # Top left X/Y based on real chunk size topLeftTileX = chunkX * CHUNK_WIDTH topLeftTileY = chunkY * CHUNK_HEIGHT @@ -128,7 +124,7 @@ for chunkY in range(mapHeightInRealTiles): print(f"Error: Chunk in layer {layerIndex} does not contain 'x' or 'y' key.") sys.exit(1) - if chunk['x'] == topLeftTileX and chunk['y'] == topLeftTileY: + if chunk['x'] == inputTopLeftTileX and chunk['y'] == inputTopLeftTileY: foundChunk = chunk break @@ -147,29 +143,38 @@ for chunkY in range(mapHeightInRealTiles): if layerEmpty: chunkLayers.append(None) continue - + chunkLayers.append(foundChunk) # Now we have a chunkLayers list with the found chunks for each layer. if all(chunk is None for chunk in chunkLayers) or len(chunkLayers) == 0: - print(f"Warning: No valid chunks found for chunk at ({chunkX}, {chunkY}). Skipping.") continue - + if len(chunkLayers) > 2: print(f"Error: Expected 2 layers for chunk at ({chunkX}, {chunkY}), found {len(chunkLayers)}.") sys.exit(1) + + def getInputLocalTileX(absoluteTileX): + return absoluteTileX % inputLayerWidthInTiles + + def getInputLocalTileY(absoluteTileY): + return absoluteTileY % inputLayerHeightInTiles layerBase = chunkLayers[0] layerBaseData = [] - # for y in range(CHUNK_HEIGHT): - # for x in range(CHUNK_WIDTH): - # # Calculate the tile index in the chunk - # tileIndex = y * CHUNK_WIDTH + x - # if layerBase is not None and tileIndex < len(layerBase.get('data', [])): - # tileId = layerBase['data'][tileIndex] - # layerBaseData.append(tileId) - # else: - # layerBaseData.append(0) + for y in range(CHUNK_HEIGHT): + for x in range(CHUNK_WIDTH): + absoluteTileX = topLeftTileX + x + absoluteTileY = topLeftTileY + y + inputLocalTileX = getInputLocalTileX(absoluteTileX) + inputLocalTileY = getInputLocalTileY(absoluteTileY) + inputTileIndex = inputLocalTileY * inputLayerWidthInTiles + inputLocalTileX + outputTileIndex = y * CHUNK_WIDTH + x + layerBaseData.append(layerBase['data'][inputTileIndex]) + + if len(layerBaseData) != CHUNK_TILE_COUNT: + print(f"Error: Layer base data length {len(layerBaseData)} does not match expected chunk tile count {CHUNK_TILE_COUNT}.") + sys.exit(1) # This is a valid chunk. worldWidth = max(worldWidth, chunkX + 1) @@ -184,8 +189,13 @@ for chunkY in range(mapHeightInRealTiles): 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 byte in layerBase.get('data', []): - f.write(f" 0x{byte:02x}, \n") + for y in range(CHUNK_HEIGHT): + f.write(f" ") + for x in range(CHUNK_WIDTH): + i = y * CHUNK_WIDTH + x + byte = layerBaseData[i] + f.write(f"0x{byte:02x}, ") + f.write(f"\n") f.write(" },\n\n") f.write(f" .layerOverlay = {{}},\n") f.write(f" .entities = {{}},\n") @@ -220,11 +230,9 @@ for chunkY in range(mapHeightInRealTiles): # f.write("};\n\n") # pass - - # Output header file. -header_path = os.path.join(worldDir, "world.h") -with open(header_path, 'w') as f: +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") @@ -248,4 +256,4 @@ with open(header_path, 'w') as f: f.write("\n") f.write("};\n\n") -print(f"chunks.h generated at: {header_path}") \ No newline at end of file +print(f"chunks.h generated at: {headerPath}") \ No newline at end of file