Did some tweaks to the CMakeLists
This commit is contained in:
@ -1,12 +0,0 @@
|
||||
const args = process.argv.splice(2).reduce((x,y) => {
|
||||
const bits = y.split('=');
|
||||
const name = bits[0].replace('--', '');
|
||||
const val = bits[1];
|
||||
|
||||
x[name] = val;
|
||||
return x;
|
||||
}, {});
|
||||
|
||||
module.exports = {
|
||||
args
|
||||
};
|
@ -1,103 +0,0 @@
|
||||
const { PNG } = require("pngjs");
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
/**
|
||||
* Loads an image into memory.
|
||||
* @param image Image to load
|
||||
* @returns A promise that resolves to the loaded image.
|
||||
*/
|
||||
const imageLoad = (image) => new Promise(resolve => {
|
||||
fs.createReadStream(image)
|
||||
.pipe(new PNG({ filterType: 4 }))
|
||||
.on("parsed", function () {
|
||||
// Normalize
|
||||
const pixels = [];
|
||||
for(let y = 0; y < this.height; y++) {
|
||||
for(let x = 0; x < this.width; x++) {
|
||||
const idx = (this.width * y + x) << 2;
|
||||
const r = this.data[idx];
|
||||
const g = this.data[idx + 1];
|
||||
const b = this.data[idx + 2];
|
||||
const a = this.data[idx + 3];
|
||||
|
||||
pixels.push({ r, g, b, a });
|
||||
}
|
||||
}
|
||||
resolve({ pixels, width: this.width, height: this.height });
|
||||
})
|
||||
;
|
||||
});
|
||||
|
||||
/**
|
||||
* Writes an image to an output file.
|
||||
* @param image Image to write.
|
||||
* @param file File to write to.
|
||||
* @returns A promise that, when resolved, has saved the image.
|
||||
*/
|
||||
const imageWrite = (image, file) => new Promise(resolve => {
|
||||
const png = new PNG({ width: image.width, height: image.height });
|
||||
png.width = image.width;
|
||||
png.height = image.height;
|
||||
|
||||
for(let y = 0; y < image.height; y++) {
|
||||
for(let x = 0; x < image.width; x++) {
|
||||
const i = (image.width * y + x);
|
||||
const idx = i << 2;
|
||||
|
||||
const pixel = image.pixels[i];
|
||||
png.data[idx] = pixel.r;
|
||||
png.data[idx + 1] = pixel.g;
|
||||
png.data[idx + 2] = pixel.b;
|
||||
png.data[idx + 3] = pixel.a;
|
||||
}
|
||||
}
|
||||
|
||||
png.pack().pipe(fs.createWriteStream(file))
|
||||
.on('close', () => resolve(true))
|
||||
;
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates a blank image
|
||||
* @param width Width of the image.
|
||||
* @param height Height of the image.
|
||||
* @param fill Optional pixel to fill with, defaults to 0,0,0,0
|
||||
* @returns The newly created image.
|
||||
*/
|
||||
const imageCreate = (width, height, pixel) => {
|
||||
if(!pixel || !pixel.r) pixel = { r:0, g:0, b:0, a:0 };
|
||||
const pixels = [];
|
||||
for(let i = 0; i < width * height; i++) pixels.push({ ...pixel });
|
||||
return { pixels, width, height };
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies an area of a source image into a target image.
|
||||
* @param target Target image to copy into.
|
||||
* @param source Source image to copy from.
|
||||
* @param tx Target X position to copy into
|
||||
* @param ty Target Y position to copy into
|
||||
* @param sub Optional source area to use, defined as { x, y, width, height }.
|
||||
*/
|
||||
const imageCopy = (target, source, tx, ty, sub) => {
|
||||
if(!sub) sub = { x: 0, y: 0, width: source.width, height: source.height };
|
||||
|
||||
for(let x = sub.x; x < sub.x+sub.width; x++) {
|
||||
for(let y = sub.y; y < sub.y+sub.height; y++) {
|
||||
let absX = x - sub.x + tx;
|
||||
let absY = y - sub.y + ty;
|
||||
if(absX > target.width || absY > target.height) continue;
|
||||
let ti = absY * target.width + absX;
|
||||
let si = y * source.width + x;
|
||||
target.pixels[ti] = { ...source.pixels[si] };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
imageWrite,
|
||||
imageCreate,
|
||||
imageLoad,
|
||||
imageCopy
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
const path = require('path');
|
||||
const { imageCreate, imageWrite, imageLoad, imageCopy } = require('./../utils/image');
|
||||
const fs = require('fs');
|
||||
const xml = require('xml-js');
|
||||
const { args } = require('./../utils/args');
|
||||
|
||||
// Parse Args
|
||||
if(!args.in) throw new Error(`Missing in argument`);
|
||||
if(!args.out) throw new Error(`Missing out argument`);
|
||||
if(!args.in.endsWith('xml')) throw new Error(`Invalid in XML`);
|
||||
if(!args.out.endsWith('png')) throw new Error(`Invalid out PNG`);
|
||||
|
||||
// Determine in and out.
|
||||
const file = path.resolve(args.in);
|
||||
const outFile = path.resolve(args.out);
|
||||
if(fs.existsSync(outFile)) return;
|
||||
|
||||
// Load XML
|
||||
const data = xml.xml2js(fs.readFileSync(file, 'utf-8'));
|
||||
const [ character ] = data.elements;
|
||||
|
||||
// Validate file.
|
||||
if(!character.attributes.context) throw new Error(`Missing context`)
|
||||
const dir = path.resolve('.', 'assets', character.attributes.context);
|
||||
|
||||
// Parse base and layers
|
||||
const base = character.elements.find(e => e.name == 'base').attributes;
|
||||
if(!base) throw new Error(`Failed to find base`);
|
||||
const layers = character.elements
|
||||
.filter(e => e.name == 'layer')
|
||||
.map(e => e.attributes)
|
||||
.map(e => ({
|
||||
...e,
|
||||
x: parseInt(e.x),
|
||||
y: parseInt(e.y),
|
||||
width: parseInt(e.width),
|
||||
height: parseInt(e.height)
|
||||
}))
|
||||
;
|
||||
|
||||
(async () => {
|
||||
// Load the base
|
||||
const baseImage = await imageLoad(path.join(dir, base.file));
|
||||
|
||||
let columnsMax = 0;
|
||||
let widthMax = 0;
|
||||
layers.forEach((layer,row) => {
|
||||
if(!layer.width || !layer.height || !layer.x || !layer.y) {
|
||||
throw new Error(`Missing layer info`);
|
||||
}
|
||||
|
||||
const layerDir = path.join(dir, layer.directory);
|
||||
const scan = fs.readdirSync(layerDir);
|
||||
columnsMax = Math.max(scan.length, columnsMax);
|
||||
widthMax = Math.max(widthMax, layer.width);
|
||||
});
|
||||
|
||||
// Create the output buffer
|
||||
const out = imageCreate(
|
||||
baseImage.width + (columnsMax * widthMax),
|
||||
baseImage.height
|
||||
);
|
||||
|
||||
// Copy the base
|
||||
imageCopy(out, baseImage, 0, 0);
|
||||
|
||||
// Now begin copying the children, row is defined by the directory
|
||||
let y = 0;
|
||||
for(let row = 0; row < layers.length; row++) {
|
||||
const layer = layers[row];
|
||||
const layerDir = path.join(dir, layer.directory);
|
||||
const scan = fs.readdirSync(layerDir);
|
||||
|
||||
// Column defined by the file index
|
||||
for(let col = 0; col < scan.length; col++) {
|
||||
const img = await imageLoad(path.join(layerDir, scan[col]));
|
||||
console.log('Copying', scan[col]);
|
||||
imageCopy(out, img,
|
||||
baseImage.width+(col*layer.width), y,
|
||||
layer
|
||||
);
|
||||
}
|
||||
|
||||
y += layer.height;
|
||||
}
|
||||
|
||||
await imageWrite(out, outFile);
|
||||
})().catch(console.error);
|
12
tools/vn/character-sheet-maker.c
Normal file
12
tools/vn/character-sheet-maker.c
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "character-sheet-maker.h"
|
||||
|
||||
int32_t main(int32_t argc, char *argv[]) {
|
||||
|
||||
}
|
9
tools/vn/character-sheet-maker.h
Normal file
9
tools/vn/character-sheet-maker.h
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <libs.h>
|
Reference in New Issue
Block a user