diff --git a/api/thumbnail/[name].js b/api/thumbnail/[name].js index 8d08cb5d1..c56082065 100644 --- a/api/thumbnail/[name].js +++ b/api/thumbnail/[name].js @@ -1,83 +1,96 @@ -import * as gridEngine from "../../engine/engine.js"; import { palette } from "../../palette.js"; -// import fetch from 'node-fetch'; import { readFileSync } from 'fs'; import path from 'path'; -async function drawGame(game) { +function drawGame(name) { - // const url = `https://raw.githubusercontent.com/hackclub/sprig/main/games/${game}.js`; - // const src = await fetch(url).then(x => x.text()); + const url = `https://raw.githubusercontent.com/hackclub/sprig/main/games/${name}.js`; - const file = path.join(process.cwd(), 'games', `${game}.js`); + const file = path.join(process.cwd(), '../../games', `${name}.js`); const src = readFileSync(file, 'utf8'); - let screen, bitmaps; - const setScreenSize = (w, h) => screen = { - data: new Uint8Array(w*h*4), - width: w - }; - const { api, state } = gridEngine.init({ - palette, - setBitmaps: bm => bitmaps = bm, - setScreenSize, - drawText: () => {} - }); - api.setScreenSize = setScreenSize; - api.afterInput = () => {}; - api.onInput = () => {}; - - try { - new Function(...Object.keys(api), src)(...Object.values(api)); - - if (!screen) throw new Error("never set screen size"); - if (!bitmaps) throw new Error("never set legend"); - } catch(e) { - console.error(`couldn't run ${game}: ${e}`); - return {}; - } + // have src - screen.data.fill(255); - drawTiles(state, api, screen, bitmaps); - - return { name: game, image: screen, url }; + // get legend + let legend = src.match(/setLegend\(([\s\S]*?)\)/)[1]; + // const getVariable = name => legend.match(/name(.*?)['"](.*?)['"]/)[2]; - function blitSprite(screen, sprite, tx, ty) { - const [_, { imageData: { data: bitmap } }] = sprite; - for (let x = 0; x < 16; x++) - for (let y = 0; y < 16; y++) { - const sx = tx*16 + x; - const sy = ty*16 + y; + const reconstructedLegend = {}; - if (bitmap[(y*16 + x)*4 + 3] < 255) continue; + // for (let i = 0; i < legend.length; i++) { + + // } - screen.data[(sy*screen.width + sx)*4 + 0] = bitmap[(y*16 + x)*4 + 0]; - screen.data[(sy*screen.width + sx)*4 + 1] = bitmap[(y*16 + x)*4 + 1]; - screen.data[(sy*screen.width + sx)*4 + 2] = bitmap[(y*16 + x)*4 + 2]; - screen.data[(sy*screen.width + sx)*4 + 3] = bitmap[(y*16 + x)*4 + 3]; - } - } + let lastKey = ""; + legend.split(",").forEach(x => { + console.log(x); + if (x.includes("[")) { + lastKey = x.replace("[", "").trim(); + } else { + const value = x.match(/bitmap`([\s\S]*?)`/); + console.log(value); + if (value) reconstructedLegend[lastKey] = value; + } + }) - function drawTiles(state, api, screen, bitmaps) { - const { dimensions, legend } = state; - const { width, height, maxTileDim } = dimensions; + console.log(reconstructedLegend); - const grid = api.getGrid(); + // replace every [ thing , + // with const | let thing = "newThing" | 'newThing' - for (const cell of grid) { - const zOrder = legend.map(x => x[0]); - cell.sort((a, b) => zOrder.indexOf(a.type) - zOrder.indexOf(b.type)); + // console.log(legend); + // get first map + const firstMap = src.match(/[^t]map`([\s\S]*?)`/)[1]; + // draw first map + // console.log(firstMap); - for (const { x, y, type } of cell) { - blitSprite(screen, bitmaps.find(x => x[0] == type), x, y); - } - } - } + const image = { + data: new Uint8Array(120*168), + width: 128 + }; + + return { name, image, url }; } +const test = drawGame("tolls"); +console.log(test); + export default async function handler(request, response) { const { name } = request.query; - const data = await drawGame(name); + const data = drawGame(name); return response.status(200).json(data); +} + + +function blitSprite(screen, sprite, tx, ty) { + const [_, { imageData: { data: bitmap } }] = sprite; + for (let x = 0; x < 16; x++) + for (let y = 0; y < 16; y++) { + const sx = tx*16 + x; + const sy = ty*16 + y; + + if (bitmap[(y*16 + x)*4 + 3] < 255) continue; + + screen.data[(sy*screen.width + sx)*4 + 0] = bitmap[(y*16 + x)*4 + 0]; + screen.data[(sy*screen.width + sx)*4 + 1] = bitmap[(y*16 + x)*4 + 1]; + screen.data[(sy*screen.width + sx)*4 + 2] = bitmap[(y*16 + x)*4 + 2]; + screen.data[(sy*screen.width + sx)*4 + 3] = bitmap[(y*16 + x)*4 + 3]; + } +} + +function drawTiles(state, api, screen, bitmaps) { + const { dimensions, legend } = state; + const { width, height, maxTileDim } = dimensions; + + const grid = api.getGrid(); + + for (const cell of grid) { + const zOrder = legend.map(x => x[0]); + cell.sort((a, b) => zOrder.indexOf(a.type) - zOrder.indexOf(b.type)); + + for (const { x, y, type } of cell) { + blitSprite(screen, bitmaps.find(x => x[0] == type), x, y); + } + } } \ No newline at end of file diff --git a/engine/engine.js b/engine/engine.js index 52c30b28b..d6df36a23 100644 --- a/engine/engine.js +++ b/engine/engine.js @@ -488,7 +488,12 @@ export function init({ palette, setBitmaps, setScreenSize, drawText }) { } function getTile(x, y) { - return getGrid()[state.dimensions.width*y+x] || []; + return y >= 0 + && y < state.dimensions.height + && x >= 0 + && y < state.dimensions.width + ? (getGrid()[state.dimensions.width*y+x] || []) + : []; } function hasDuplicates(array) { @@ -545,7 +550,7 @@ export function init({ palette, setBitmaps, setScreenSize, drawText }) { setSolids, setPushables, map: _makeTag(text => text), // No-op for now, here for editor support - bitmap: _makeTag(text => ({ + bitmap: _makeTag(text => ({ // TODO: make this no-op and store bitmap somewhere else text, imageData: bitmapTextToImageData(text, palette) })), diff --git a/package.json b/package.json index ba2e1254d..b0903afa2 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "type": "module", "scripts": { "dev": "vite", "build": "vite build",