From 72ee2e7bc0623490d70d521063e348197f643c6a Mon Sep 17 00:00:00 2001 From: Lucas Scharenbroich Date: Thu, 5 Aug 2021 21:19:02 -0500 Subject: [PATCH] First version of Tiled Map import tool --- package.json | 3 +- tools/tiled2iigs.js | 91 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 tools/tiled2iigs.js diff --git a/package.json b/package.json index 9ff996d..68b3085 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "build:assets-plant": "node ./tools/png2iigs.js ./assets/plant.png ./emu/bg1a.bin --start-index 6 && node ./tools/pngtoiigs.js ./assets/woz-shifted.png ./emu/bg1b.bin --start-index 6 && node ./tools/pngtoiigs.js ./assets/donut-plains-1-6-color.png ./emu/fg1.bin", "build:assets-woz": "node ./tools/png2iigs.js ./assets/woz.png ./emu/bg1a.bin --start-index 6 && node ./tools/pngtoiigs.js ./assets/woz-shifted.png ./emu/bg1b.bin --start-index 6 && node ./tools/pngtoiigs.js ./assets/donut-plains-1-6-color.png ./emu/fg1.bin", "build:assets-woz-fatbits": "node ./tools/png2iigs.js ./assets/woz-pixelated.png ./emu/bg1a.bin --start-index 6 && node ./tools/pngtoiigs.js ./assets/woz-shifted.png ./emu/bg1b.bin --start-index 6 && node ./tools/pngtoiigs.js ./assets/donut-plains-1-6-color.png ./emu/fg1.bin", - "build:assets-color-cycle": "node ./tools/png2iigs.js ./assets/rotopattern.png ./emu/bg1a.bin --start-index 6 && node ./tools/pngtoiigs.js ./assets/woz-shifted.png ./emu/bg1b.bin --start-index 6 && node ./tools/pngtoiigs.js ./assets/donut-plains-1-6-color.png ./emu/fg1.bin" + "build:assets-color-cycle": "node ./tools/png2iigs.js ./assets/rotopattern.png ./emu/bg1a.bin --start-index 6 && node ./tools/pngtoiigs.js ./assets/woz-shifted.png ./emu/bg1b.bin --start-index 6 && node ./tools/pngtoiigs.js ./assets/donut-plains-1-6-color.png ./emu/fg1.bin", + "build:map": "node ./tools/tiled2iigs.js ./assets/tiled/world_1-1.json > ./src/Level.s" }, "repository": { "type": "git", diff --git a/tools/tiled2iigs.js b/tools/tiled2iigs.js new file mode 100644 index 0000000..7556ffa --- /dev/null +++ b/tools/tiled2iigs.js @@ -0,0 +1,91 @@ +/** + * Read an exported Tiled project in JSON format and produce Merlin32 output files with + * GTE-compatible setup code wrapped around it. + */ + const fs = require('fs').promises; + const process = require('process'); + const { Buffer } = require('buffer'); + + main(process.argv.slice(2)).then( + () => process.exit(0), + (e) => { + console.error(e); + process.exit(1); + } +); + +function emitHeader() { + console.log('; Tiled Map Export'); + console.log(';'); + console.log('; This is a generated file. Do not modify.'); +} + +async function main(argv) { + // Read in the JSON data + const doc = JSON.parse(await fs.readFile(argv[0])); + + // Make sure it's a map format we can handle + if (doc.infinite) { + throw new Error('Cannot import infinite maps.'); + } + + // Require 8x8 tiles + if (doc.tileheight !== 8 || doc.tilewidth !== 8) { + throw new Error('Only 8x8 tiles are supported'); + } + + // The total map size must be less than 32768 tiles because we limit the map to one data bank + // and the tiles are stored in GTE as 16-bit values. + if (doc.height * doc.width >= 32768) { + throw new Error('The tile map must have less than 32,768 tiles'); + } + + // Look at the tile layers. We support a maximum of two tile layers. + const tileLayers = doc.layers.filter(l => l.type === 'tilelayer'); + if (tileLayers.length === 0) { + throw new Error('There must be at least one tile layer defined for the map'); + } + + if (tileLayers.length > 2) { + throw new Error('The map cannot have more than two tile layers'); + } + + // Sort the tile layers by ID. The lower ID is considered to be the "front" layer + tileLayers.sort((first, second) => first.id <= second.id); + + // Ok, looks good. Write out the source code + emitHeader(); + emitBG0Layer(tileLayers[0]); + if (tileLayers.length > 1) { + emigBG1Layer(tileLayers[1]); + } +} + +function emitBG0Layer(layer) { + const label = layer.name.split(' ').join('_'); + const initCode = ` +BG0SetUp + lda #${layer.width} + sta TileMapWidth + lda #${layer.height} + sta TileMapHeight + lda #${label} + sta TileMapPtr + lda #^${label} + sta TileMapPtr+2 + rts + `; + console.log(initCode); + console.log(`${label}`); + + // Print out the data in groups of N + const N = 16; + const chunks = []; + const tileIDs = layer.data; + for (let i = 0; i < tileIDs.length; i += N) { + chunks.push(tileIDs.slice(i, i + N)) + } + for (const chunk of chunks) { + console.log(' dw ' + chunk.join(',')); + } +} \ No newline at end of file