const PNG = require('pngjs').PNG; const path = require('path'); const fs = require('fs'); const { arrayToString } = require('./util'); const { TILE_WIDTH, TILE_HEIGHT } = require('./common'); const getPixelValue = (pixel) => { if(pixel.g === 188) return 0; if(pixel.g === 172) return 1; if(pixel.g === 98) return 2; if(pixel.g === 56) return 3; throw new Error(); } const png2gb = (fileIn, dirOut, name) => { const data = fs.readFileSync(fileIn); const png = PNG.sync.read(data); // Convert PNG pixels into 0x00-0x03 const pixels = []; for(let y = 0; y < png.height; y++) { for(let x = 0; x < png.width; x++) { const id = x + (y * png.width); const idx = id << 2; const r = png.data[idx]; const g = png.data[idx+1]; const b = png.data[idx+2]; const value = getPixelValue({ r, g, b }); pixels.push(value); } } // Now take these raw pixels and extract the tiles themselves let rearranged = []; const columns = (png.width / TILE_WIDTH); const rows = (png.height / TILE_HEIGHT); let n = 0; for(let i = 0; i < columns * rows; i++) { const tileX = i % columns; const tileY = Math.floor(i / columns) % rows; for(let y = 0; y < TILE_HEIGHT; y++) { for(let x = 0; x < TILE_WIDTH; x++) { const px = (tileX * TILE_WIDTH) + x; const py = (tileY * TILE_HEIGHT) + y; const pi = (py * png.width) + px; rearranged[n++] = pixels[pi]; } } } // Now turn into a tileset const bits = []; for(let i = 0; i < rearranged.length; i += TILE_WIDTH) { let lowBits = 0x00; let highBits = 0x00; for(let j = 0; j < TILE_WIDTH; j++) { const pixel = rearranged[i + j]; lowBits = lowBits | ((pixel & 0x01) << (7-j)); highBits = highBits | ((pixel & 0x02) >> 1 << (7-j)); } bits.push(lowBits, highBits); } let outH = ''; outH += `#include "libs.h"\n\n` outH += `#define ${name}_IMAGE_WIDTH ${png.width}\n`; outH += `#define ${name}_IMAGE_HEIGHT ${png.height}\n`; outH += `#define ${name}_IMAGE_COLUMNS ${png.width / TILE_WIDTH}\n`; outH += `#define ${name}_IMAGE_ROWS ${png.height / TILE_HEIGHT}\n`; outH += `#define ${name}_IMAGE_TILES ${columns * rows}\n`; outH += `extern const uint8_t ${name}_IMAGE[];`; let outC = `#include "${name}.h"\n`; outC += `\nconst uint8_t ${name}_IMAGE[] = {\n${arrayToString(bits)}};`; const fileH = path.join(dirOut, name + '.h'); const fileC = path.join(dirOut, name + '.c'); fs.writeFileSync(fileH, outH); fs.writeFileSync(fileC, outC); return { fileH, fileC }; } module.exports = { png2gb } // convert('images/sm.png', 'out.c', 'PENNY');