fantasy-console/window.ts

165 lines
4.0 KiB
TypeScript
Raw Normal View History

2023-04-29 15:16:35 -07:00
import {
createWindow,
getProcAddress,
gl,
} from "./deps.ts";
export {mainloop} from "./deps.ts";
2023-05-05 11:52:08 -07:00
import { palette } from "./colors.ts";
2023-04-29 15:16:35 -07:00
2023-05-05 16:02:23 -07:00
export const gameWindow = createWindow({
2023-04-29 15:16:35 -07:00
title: "Faux",
width: 1024,
height: 1024,
resizable: false,
glVersion: [3, 2],
gles: true,
});
gl.load(getProcAddress);
function loadShader(type: number, src: string) {
const shader = gl.CreateShader(type);
gl.ShaderSource(
shader,
1,
new Uint8Array(
new BigUint64Array([
BigInt(
Deno.UnsafePointer.value(
Deno.UnsafePointer.of(new TextEncoder().encode(src)),
),
),
]).buffer,
),
new Int32Array([src.length]),
);
gl.CompileShader(shader);
const status = new Int32Array(1);
gl.GetShaderiv(shader, gl.COMPILE_STATUS, status);
if (status[0] === gl.FALSE) {
const logLength = new Int32Array(1);
gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, logLength);
const log = new Uint8Array(logLength[0]);
gl.GetShaderInfoLog(shader, logLength[0], logLength, log);
console.log(new TextDecoder().decode(log));
gl.DeleteShader(shader);
return 0;
}
return shader;
}
const vShaderSrc = `
attribute vec4 vPosition;
attribute vec4 vCol;
varying vec4 color;
void main() {
gl_Position = vPosition;
color = vCol;
}
`;
const fShaderSrc = `
precision mediump float;
varying vec4 color;
void main() {
gl_FragColor = color;
}
`;
const vShader = loadShader(gl.VERTEX_SHADER, vShaderSrc);
const fShader = loadShader(gl.FRAGMENT_SHADER, fShaderSrc);
const program = gl.CreateProgram();
gl.AttachShader(program, vShader);
gl.AttachShader(program, fShader);
gl.BindAttribLocation(program, 0, new TextEncoder().encode("vPosition\0"));
gl.BindAttribLocation(program, 1, new TextEncoder().encode("vCol\0"));
gl.LinkProgram(program);
const status = new Int32Array(1);
gl.GetProgramiv(program, gl.LINK_STATUS, status);
if (status[0] === gl.FALSE) {
const logLength = new Int32Array(1);
gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, logLength);
const log = new Uint8Array(logLength[0]);
gl.GetProgramInfoLog(program, logLength[0], logLength, log);
console.log(new TextDecoder().decode(log));
gl.DeleteProgram(program);
Deno.exit(1);
}
gl.ClearColor(0.0, 0.0, 0.0, 1.0);
addEventListener("resize", (event) => {
gl.Viewport(0, 0, event.width, event.height);
});
const pixelsPerRow = 128;
const top = 1;
const left = -1;
const cell = 2/pixelsPerRow;
const px = (x: number, y: number) => {
// deno-fmt-ignore
return [
left + x*cell, top - y*cell, 0,
left + (x+1)*cell, top - y*cell, 0,
left + x*cell, top - (y+1)*cell, 0,
left + (x+1)*cell, top - y*cell, 0,
left + x*cell, top - (y+1)*cell, 0,
left + (x+1)*cell, top - (y+1)*cell, 0,
];
}
const paletteX6 = palette.map(rgba => [...rgba, ...rgba, ...rgba, ...rgba, ...rgba, ...rgba]);
const c = (n: number) => {
return paletteX6[n];
}
const allPixelTriangles = new Float32Array(
Array(pixelsPerRow*pixelsPerRow).fill(null).flatMap((_, i) => px(i%pixelsPerRow,Math.floor(i/pixelsPerRow)))
)
const allPixelColors = new Float32Array(
Array(pixelsPerRow*pixelsPerRow).fill(null).flatMap(() => c(1))
)
export const setPixelColor = (x: number, y: number, color: number) => {
2023-05-01 11:12:08 -07:00
if (x < 0 || y < 0 || x > 127 || y > 127) {
return;
}
2023-04-29 20:07:06 -07:00
if (color !== 0) {
const col = c(color);
allPixelColors.set(col, 4*6*(128*y+x));
}
2023-04-29 15:16:35 -07:00
}
export const setPixelsInRect = (x: number, y: number, w: number, pixels: Array<number>) => {
for (let i = 0; i < pixels.length; i++) {
setPixelColor(x+i%w, y+Math.floor(i/w), pixels[i]);
}
}
2023-05-04 20:14:48 -07:00
export const fillRect = (x: number, y: number, w: number, h: number, color: number) => {
setPixelsInRect(x, y, w, Array(w*h).fill(color));
}
2023-04-29 15:16:35 -07:00
export const clearScreen = () => {
allPixelColors.fill(0);
}
export const frame = () => {
gl.Clear(gl.COLOR_BUFFER_BIT);
gl.UseProgram(program);
gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, allPixelTriangles);
gl.VertexAttribPointer(1, 4, gl.FLOAT, gl.FALSE, 0, allPixelColors);
gl.EnableVertexAttribArray(0);
gl.EnableVertexAttribArray(1);
gl.DrawArrays(gl.TRIANGLES, 0, 6*pixelsPerRow*pixelsPerRow);
2023-05-05 16:02:23 -07:00
gameWindow.swapBuffers();
2023-04-29 15:16:35 -07:00
}