mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2024-12-01 23:51:12 +00:00
92 lines
2.7 KiB
JavaScript
92 lines
2.7 KiB
JavaScript
/**
|
|
* 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))
|
|
}
|
|
// Tiled starts numbering its tiles at 1, swtich to a more sane approach... :)
|
|
for (const chunk of chunks) {
|
|
console.log(' dw ' + chunk.map(t => t - 1).join(','));
|
|
}
|
|
} |