From ba6ecf9006e6b7678aea0d64684b6953d1f902cc Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Mon, 16 Jun 2025 12:49:51 -0500 Subject: [PATCH] Add base overlay --- data/map project.tiled-session | 28 +++--- data/map.tmj | 91 ++++++++++++++++--- data/overworld.tsx | 2 +- data/tilemap.png | Bin 1515 -> 2813 bytes data/tilemap.pxo | Bin 2422 -> 3099 bytes src/dusk/world/chunk.c | 15 +++- src/dusk/world/chunk.h | 3 +- src/dusk/world/chunkdata.h | 2 +- src/duskraylib/display/draw/drawoverworld.c | 36 +++++--- tools/mapcompile/mapcompile.py | 95 ++++++++++++-------- 10 files changed, 192 insertions(+), 80 deletions(-) diff --git a/data/map project.tiled-session b/data/map project.tiled-session index 367c074..0cc20a5 100644 --- a/data/map project.tiled-session +++ b/data/map project.tiled-session @@ -1,33 +1,41 @@ { - "activeFile": "map.tmj", + "activeFile": "overworld.tsx", "expandedProjectPaths": [ - "templates", - "." + ".", + "templates" ], "fileStates": { + "entities.tsx": { + "scaleInDock": 1, + "scaleInEditor": 1 + }, "map.tmj": { - "scale": 1.5, - "selectedLayer": 0, + "scale": 4, + "selectedLayer": 1, "viewCenter": { - "x": 669.3333333333334, - "y": 305 + "x": 6622.75, + "y": 6689.625 } }, "overworld.tsx": { "scaleInDock": 1, - "scaleInEditor": 1 + "scaleInEditor": 8 } }, + "last.externalTilesetPath": "/home/yourwishes/htdocs/dusk/data", "last.imagePath": "/home/yourwishes/htdocs/dusk/data", "last.objectTemplatePath": "/home/yourwishes/htdocs/dusk/data/templates", "openFiles": [ - "map.tmj" + "map.tmj", + "overworld.tsx" ], "project": "map project.tiled-project", "recentFiles": [ + "map.tmj", "overworld.tsx", - "map.tmj" + "entities.tsx" ], + "tileset.lastUsedFilter": "Tiled tileset files (*.tsx *.xml)", "tileset.lastUsedFormat": "tsx", "tileset.tileSize": { "height": 16, diff --git a/data/map.tmj b/data/map.tmj index 1e39f4c..b639e2b 100644 --- a/data/map.tmj +++ b/data/map.tmj @@ -27,13 +27,13 @@ "y":416 }, { - "data":[1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -54,8 +54,8 @@ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -281,6 +281,65 @@ "x":0, "y":0 }, + { + "chunks":[ + { + "data":[0, 0, 0, 2, 3, 3, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 11, 11, 11, 11, 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 11, 11, 11, 11, 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 11, 11, 11, 11, 6, 3, 3, 3, 3, 3, 3, 3, + 0, 0, 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 0, 0, 0, 10, 11, 11, 11, 11, 14, 19, 19, 19, 19, 19, 19, 19, + 0, 0, 0, 10, 11, 11, 11, 11, 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 11, 11, 11, 11, 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 11, 11, 11, 11, 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 11, 11, 11, 11, 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 18, 19, 19, 19, 19, 20, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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":400, + "y":416 + }, + { + "data":[0, 0, 10, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 3, 5, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11, 11, 11, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 13, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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":416, + "y":416 + }], + "height":32, + "id":5, + "locked":true, + "name":"Overlay Base Layer", + "opacity":1, + "startx":400, + "starty":400, + "type":"tilelayer", + "visible":true, + "width":32, + "x":0, + "y":0 + }, { "draworder":"topdown", "id":3, @@ -289,14 +348,14 @@ { "id":3, "template":"templates\/NPC.tx", - "x":6527.97727272727, - "y":6736.13636363636 + "x":6434.3106060606, + "y":6672.13636363636 }, { "id":4, "template":"templates\/NPC.tx", - "x":6726, - "y":6713.25 + "x":6737, + "y":6672.91666666667 }], "opacity":1, "type":"objectgroup", @@ -304,7 +363,7 @@ "x":0, "y":0 }], - "nextlayerid":5, + "nextlayerid":6, "nextobjectid":5, "orientation":"orthogonal", "renderorder":"right-down", @@ -318,6 +377,10 @@ { "firstgid":65, "source":"entities.tsx" + }, + { + "firstgid":129, + "source":":\/automap-tiles.tsx" }], "tilewidth":16, "type":"map", diff --git a/data/overworld.tsx b/data/overworld.tsx index 22f7090..7109f0e 100644 --- a/data/overworld.tsx +++ b/data/overworld.tsx @@ -1,4 +1,4 @@ - + diff --git a/data/tilemap.png b/data/tilemap.png index 17cc71ab554b010e8b638dde7a4867be84e16336..51b33913cbc4caccd66df44d853d13f381bba6b2 100644 GIT binary patch literal 2813 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 GhVU;Od%0o& diff --git a/data/tilemap.pxo b/data/tilemap.pxo index f89df41d2c4bef1c4fc69711c8fab91d274407a3..bd4b351a6a0c0598fe2689a51992e51a2e9384df 100644 GIT binary patch delta 2457 zcmb7Gdpy$%8z+*aIz_pkbweGLT%wy%M!8OM91A;ScqvhgO#9)42vZc2trLn|mbq7~ z3v-!EQN%2@9k*|zm)KlGOCyno3_{6NPr@P?k^#_sh5AS2`8UyoP z6%{pn?G)GNA%YyS$n)npjaiKhKb=1>AUtq|Y4}25y6BqP;f!a2^`=H@0tsULQAV$) z6;C#Qwg05oQP*QC4`gTH^QRGnq|A7Ql*LIb$fhmI zEfpnvW`yk8f6<;vMf;CrYg-m?BNfQ5o*g8r0_$(uX z)cHr;3GMcQ=|RMh?g`zoRK|_;-wJwYBCbwk9p7mD`>G1t5zH2E0_-k8h2PG%hr!QIAR<)9anfW?Jj~gtyGER=*=SjT-d?`Bp8| zUXef_BDaHRF~9TV3V(jLRP-jG_aQSZ->PwJQ1af)>i#7()hZ`*&SZ`YqAA`aL15T% zqRW#}(v8Xx&rmqv$eoKFg)HjV*Ri{sW3g&e4!N9Fv|l$(G7KHWP4CFc8r!Y*=`>z< z=2Pv3Xq)$j7j2hK;Ctig6CX?P7a$f^&v66BWX9ZMFzj&^({@%1sGn}~M;~fpK=HqX z`xNS&rMXjrzuavxW3K2&5WoB`nt0oA4tFELw7IXX(E?DKqIm{om$5rKRL41=HFITk z-KsYk;T|+wV<8L$SV)>TNw=u9Q$1Io$$(gL)vRH{nF?21{OzRVVa0v(;&oilojn*P znIkNz_Y)`CsQ1KmZKLkuu#GJ@yp8dm{Dw3OHoR+U-sn2@HrO}6VSzRaFk~XBQ$=g4 zO%5LL93f^u4FJy_Ar^09iPwj48=fEjij{p6&L7azvn17hk5-&hdrn1L%rBPUd)wzD z)Fkm5BOuG_Vi5EwfG3Z5Y7hOYaNTgP065Mg2YqyfLb;G(gREdIvR-r~My#>;9pzWsD{)yA=om=5ju8`8Ce^yeBB##DRZp*@xR*;@bbrpg1sONg9FT<=4({n8 z=%sH%2qr3L0~hm?=}xaW4f|JL`T%iJ?z1!XzRHgrSk1mZbiTHJTlo7szsv!^z0h&% zh#u5eM`k$;hXa!vyXC$+LH!;G@5m6kf22|EC{_TCikacoi8;{B5eZ|&7XmrJda`} zP_su;iV)GcQ%ZT9JTT=N$ur^i_DZu^EGJ@oNt048?V zDadhe#ddxWgA2KiNjtOr3P=alVHK+6nw@8S3zB`bAb$Qeu8b$*VY^=)cw;24?05dL zBNvJofkgnknz1{juptaD|LV9csycK1C_^MH=qgtu*-imSu!#y!+_NZhLPhK99`^Xm zIo-n1@Dbcut!zA*OU3#|`-~mWx!GA#QJ~|uoJ91`iGtrrmM9cqOk5fyGoOmU>qq^5 z^2V7sNqNDt4;-fFv14}WGNIGB_dy)4qH4MfDBjLHtBQLj|spKZ|Z&)0m!zMI0r z#wdmE@)q7aN!eOn_cez=5i~Ij7PGk;bi9=j&r1SRz4Yd^mc+fk^4cAX@mVp-|EY=a z12TgNCrm<=^fylP+~)B zSF*{g5ZDbTrh3F2Ded2|7wCto(FQ}2FL5PIP+Y-fu}d?y=G`6{T8cN`JW+q?^}D3% zf_p6sz6rY~VSSnV*m$bceJXve=Pl6xBP?u;#DQ4 delta 1811 zcmcJQ>sQhV8pm}ovBA;Gyqn~-c~3M_BrmA#j;Aq)Jg!qXW!@$|Y8qOCO8!PkEtRyT zqosJMakBMTg64%#aYInckxX+W$QubM2r`U9f&Mo4#qRtA`+4^~FTT%<=X=hl-ez;3 z>FEfF(S8F16B7ej2*Z?OxK9@HDt6_)@sDIJLOW#JdMmNM5gSaDNFO%%JadNn`d3uHk_mnt*`pnGaLL~7&}bgnsrrd zG(VWHc#Ajp;yUcV0szJys!b8rtHY%1WlZcZtUBBX;*JtDTm+2 z=#45>vQvlI?2It?y~Dycfey|Q>v`ZwPeS9+_kqzWY}fBV94v-xR{p@MRB_;hwx+}* z+U%M1T55x8k=IXth_^qZWnP^K^Hqmg@(YuvEA$_t^u3Z!6;U4@SRYuHWp#o`HCe0= zK#MF&h`t4mSQjLn{ryjXS;Me+61$!(xA5%I?<(+c;$nVHE8XflE^q0cfX~VkiM7bwamG5PN zO>9+d$Z;)J5TegDJK@b!83?1x^r)Y#k%octfcx53oUWZbgM)iv&!)!H5ZG*U??GQq zB?`EBLBmva*mPbFnmFgZ(%d#5x=~F5M(KPCxJ|xMKaUbiRoC<4(?2=n*5)tcnl}0H&;!5lwuhLuLFy z8|u0leYR@ba;&Jz5(JKUB(e#E@5(%;g73@)*U8+83iYgvfcRJqOp%XIS$LyNJ3dVU zBmCnDGw41mOdV+U4@yK^|HzcsNJAur+jD;D_rWLT@Zb(k+524+y4y|aA=aC(Q9TM4G)8Xj zF4E{UFBv%~`4b<_E+L_~9H_Ibj}2aEPMR!}iJ(VvXtG)1J#`a*;PjsE>Kx9+$jh%d zY9LEdV&`w)IIt?MTv#Xzzp7P)9yWu|#1noo=~zlZ%dDTNP|8iz3nr#bq!H3~$I-Fg z>AA{fJltsKLj&g>a{!kd5==U@Z}VziL!43U5y@84XomXhE-o!^rudhn4~bc`qK3Om04AWjSNvZ{1_&HU diff --git a/src/dusk/world/chunk.c b/src/dusk/world/chunk.c index 994309f..a7e2363 100644 --- a/src/dusk/world/chunk.c +++ b/src/dusk/world/chunk.c @@ -181,23 +181,30 @@ void chunkLoad(chunk_t *chunk, const uint16_t x, const uint16_t y) { // Only load data if the chunk is within bounds. if(x >= WORLD_WIDTH || y >= WORLD_HEIGHT) { - memorySet(chunk->tiles, 0, sizeof(chunk->tiles)); + memorySet(chunk->tilesBase, 0, sizeof(chunk->tilesBase)); + memorySet(chunk->tilesBaseOverlay, 0, sizeof(chunk->tilesBaseOverlay)); return; } // Is chunk data defined? const chunkdata_t *chunkData = WORLD_CHUNKS[y * WORLD_WIDTH + x]; if(chunkData == NULL) { - memorySet(chunk->tiles, 0, sizeof(chunk->tiles)); + memorySet(chunk->tilesBase, 0, sizeof(chunk->tilesBase)); + memorySet(chunk->tilesBaseOverlay, 0, sizeof(chunk->tilesBaseOverlay)); return; } // Load tile data into chunk printf("Loading chunk at (%u, %u)\n", x, y); memoryCopy( - chunk->tiles, + chunk->tilesBase, chunkData->layerBase, - sizeof(chunk->tiles) + sizeof(chunk->tilesBase) + ); + memoryCopy( + chunk->tilesBaseOverlay, + chunkData->layerBaseOverlay, + sizeof(chunk->tilesBaseOverlay) ); // Load chunk entities diff --git a/src/dusk/world/chunk.h b/src/dusk/world/chunk.h index 928544c..30b0f3a 100644 --- a/src/dusk/world/chunk.h +++ b/src/dusk/world/chunk.h @@ -19,7 +19,8 @@ typedef struct { uint16_t x, y; - tile_t tiles[CHUNK_TILE_COUNT]; + tile_t tilesBase[CHUNK_TILE_COUNT]; + tile_t tilesBaseOverlay[CHUNK_TILE_COUNT]; uint32_t entityIDs[CHUNK_ENTITY_COUNT_MAX]; uint8_t entityCount; } chunk_t; diff --git a/src/dusk/world/chunkdata.h b/src/dusk/world/chunkdata.h index a477bd3..42b054c 100644 --- a/src/dusk/world/chunkdata.h +++ b/src/dusk/world/chunkdata.h @@ -18,6 +18,6 @@ typedef struct { typedef struct { uint8_t layerBase[CHUNK_TILE_COUNT]; - uint8_t layerOverlay[CHUNK_TILE_COUNT]; + uint8_t layerBaseOverlay[CHUNK_TILE_COUNT]; chunkentity_t entities[CHUNK_ENTITY_COUNT_MAX]; } chunkdata_t; \ No newline at end of file diff --git a/src/duskraylib/display/draw/drawoverworld.c b/src/duskraylib/display/draw/drawoverworld.c index 9c5c6e1..3f1f7b7 100644 --- a/src/duskraylib/display/draw/drawoverworld.c +++ b/src/duskraylib/display/draw/drawoverworld.c @@ -48,8 +48,33 @@ void drawOverworldDraw(void) { uint8_t colorCount = sizeof(colors) / sizeof(Color); do { + // Base layer for(uint8_t i = 0; i < CHUNK_TILE_COUNT; i++) { - tile_t tile = chunk->tiles[i]; + tile_t tile = chunk->tilesBase[i]; + if(tile == 0) continue; // Skip empty tiles + + uint32_t tilemapIndex = tile - 1; // Convert to zero-based index + 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; + uint32_t tilemapX = (tilemapIndex % (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH)) * TILE_WIDTH; + uint32_t tilemapY = (tilemapIndex / (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH)) * TILE_HEIGHT; + + DrawTextureRec( + RENDER_TILEMAP_TEXTURE, + (Rectangle){ + tilemapX, + tilemapY, + TILE_WIDTH, + TILE_HEIGHT + }, + (Vector2){ x, y }, + WHITE + ); + } + + // Base overlay layer + for(uint8_t i = 0; i < CHUNK_TILE_COUNT; i++) { + tile_t tile = chunk->tilesBaseOverlay[i]; if(tile == 0) continue; // Skip empty tiles uint32_t tilemapIndex = tile - 1; // Convert to zero-based index @@ -69,17 +94,8 @@ void drawOverworldDraw(void) { (Vector2){ x, y }, WHITE ); - - // 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 44e6ee1..dceab99 100644 --- a/tools/mapcompile/mapcompile.py +++ b/tools/mapcompile/mapcompile.py @@ -172,9 +172,6 @@ print(f"Input map lowest Y: {inputMapLowestY}, highest Y: {inputMapHighestY}") # We now offset all chunks by the lowest X/Y values to make them start at (0, 0). for layerIndex, layer in enumerate(tileLayers): - if layer['startx'] != inputMapLowestX or layer['starty'] != inputMapLowestY: - continue - for chunkIndex, chunk in enumerate(layer['chunks']): chunk['x'] -= inputMapLowestX chunk['y'] -= inputMapLowestY @@ -208,7 +205,6 @@ mapWidthInTiles = inputMapHighestX - inputMapLowestX mapHeightInTiles = inputMapHighestY - inputMapLowestY mapWidthInRealChunks = math.ceil(float(mapWidthInTiles) / float(CHUNK_WIDTH)) mapHeightInRealChunks = math.ceil(float(mapHeightInTiles) / float(CHUNK_HEIGHT)) -print(f"Map width in chunks: {mapWidthInRealChunks}, height in chunks: {mapHeightInRealChunks}") 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}.") @@ -231,52 +227,46 @@ for chunkY in range(mapHeightInRealChunks): # Get the layers for this chunk. chunkLayers = [] - for layerIndex, layer in enumerate(tileLayers): + for layer in tileLayers: foundChunk = None + if 'chunks' not in layer or not isinstance(layer['chunks'], list): - print(f"Error: Layer {layerIndex} in '{inputFile}' does not contain 'chunks' key.") + print(f"Error: Layer '{layer['name']}' does not contain 'chunks' key or it is not a list.") sys.exit(1) - # Find the chunk in this layer that matches the output chunk coordinates. - chunks = layer['chunks'] - for chunk in chunks: + for chunk in layer['chunks']: if 'x' not in chunk or 'y' not in chunk: - print(f"Error: Chunk in layer {layerIndex} does not contain 'x' or 'y' key.") + print(f"Error: Chunk in layer '{layer['name']}' does not contain 'x' or 'y' key.") sys.exit(1) - if chunk['x'] == inputTopLeftTileX and chunk['y'] == inputTopLeftTileY: - foundChunk = chunk - break - - # If we did not find a chunk for this layer, append None. + # Check if this chunk is within the bounds of the top left tile. + if chunk['x'] != inputTopLeftTileX or chunk['y'] != inputTopLeftTileY: + continue + + foundChunk = chunk + break + if foundChunk is None: chunkLayers.append(None) continue - - # Is this chunk layer just empty? + + # Is layer empty? layerEmpty = True - for tile in foundChunk.get('data', []): + for tile in foundChunk['data']: if tile == 0: continue layerEmpty = False break - + if layerEmpty: chunkLayers.append(None) - continue - - # Append the found chunk to the chunkLayers list. - chunkLayers.append(foundChunk) - + else: + 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: continue - # If we have more than 2 layers, we cannot handle this (yet). - if len(chunkLayers) > 2: - print(f"Error: Expected 2 layers for chunk at ({chunkX}, {chunkY}), found {len(chunkLayers)}.") - sys.exit(1) - entities = [] for ob in objectLayer['objects']: if 'x' not in ob or 'y' not in ob: @@ -302,23 +292,43 @@ for chunkY in range(mapHeightInRealChunks): def getInputLocalTileY(absoluteTileY): return absoluteTileY % inputLayerHeightInTiles - # Determine base layer data. + def getInputTileIndex(localX, localY): + absoluteTileX = topLeftTileX + localX + absoluteTileY = topLeftTileY + localY + inputLocalTileX = getInputLocalTileX(absoluteTileX) + inputLocalTileY = getInputLocalTileY(absoluteTileY) + return inputLocalTileY * inputLayerWidthInTiles + inputLocalTileX + + def getOutputTileIndex(localX, localY): + return localY * CHUNK_WIDTH + localX + + # Determine the layer base. layerBase = chunkLayers[0] + layerBaseOverlay = None + if len(chunkLayers) > 1: + layerBaseOverlay = chunkLayers[1] + + # Determine base layer data. layerBaseData = [] 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 + inputTileIndex = getInputTileIndex(x, y) + outputTileIndex = getOutputTileIndex(x, y) 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) + # Layer base overlay. + layerOverlayData = [] + if layerBaseOverlay is not None: + for y in range(CHUNK_HEIGHT): + for x in range(CHUNK_WIDTH): + inputTileIndex = getInputTileIndex(x, y) + outputTileIndex = getOutputTileIndex(x, y) + layerOverlayData.append(layerBaseOverlay['data'][inputTileIndex]) + # This is a valid chunk. worldWidth = max(worldWidth, chunkX + 1) worldHeight = max(worldHeight, chunkY + 1) @@ -341,7 +351,16 @@ for chunkY in range(mapHeightInRealChunks): f.write(f"\n") f.write(" },\n\n") - f.write(f" .layerOverlay = {{}},\n") + f.write(" .layerBaseOverlay = {\n") + if 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 = layerOverlayData[i] + f.write(f"0x{byte:02x}, ") + f.write(f"\n") + f.write(" },\n\n") f.write(f" .entities = {{\n") for entity in entities: @@ -349,8 +368,6 @@ for chunkY in range(mapHeightInRealChunks): localX = entity['x'] - (topLeftTileX * TILE_WIDTH) localY = entity['y'] - (topLeftTileY * TILE_HEIGHT) - print(f"Entity at ({entity['x']}, {entity['y']}) in chunk ({chunkX}, {chunkY}) is at local position ({localX}, {localY})") - f.write(" {\n") f.write(f" .id = {entity['id']},\n") f.write(f" .type = ENTITY_TYPE_NPC,\n")