Initial commit

moved from private version control
This commit is contained in:
2025-10-19 21:12:41 +11:00
parent 5e84773bbe
commit e64f3e881e
187 changed files with 25372 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Applies a camera offset to subsequent draw calls.
*/
export const cameraNode = createNodeModule(
{
id: "graphics_camera",
title: "Add Camera Offset",
category: "Graphics",
description: "Shift the draw origin by the specified camera offset.",
searchTags: ["camera", "offset", "scroll", "view"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{ id: "x", name: "X", direction: "input", kind: "number" },
{ id: "y", name: "Y", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const x = resolveValueInput("x", OMIT);
const y = resolveValueInput("y", OMIT);
let call = "camera()";
if (x !== OMIT) {
call = `camera(${x}, ${y === OMIT ? "0" : y})`;
}
const lines = [`${indent(indentLevel)}${call}`];
lines.push(...emitNextExec("exec_out"));
return lines;
},
}
);

View File

@@ -0,0 +1,57 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws an outlined circle.
*/
export const circNode = createNodeModule(
{
id: "graphics_circ",
title: "Draw Circle",
category: "Graphics",
description: "Render an outlined circle at the specified position.",
searchTags: ["circle", "outline", "shape", "draw"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "x",
name: "X",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y",
name: "Y",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "radius",
name: "Radius",
direction: "input",
kind: "number",
defaultValue: 4,
},
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const x = resolveValueInput("x", "0");
const y = resolveValueInput("y", "0");
const radius = resolveValueInput("radius", "4");
const color = resolveValueInput("color", "__pg_omit__");
const args = [x, y, radius];
if (color !== "__pg_omit__") {
args.push(color);
}
const line = `${indent(indentLevel)}circ(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,57 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws a filled circle.
*/
export const circfillNode = createNodeModule(
{
id: "graphics_circfill",
title: "Draw Filled Circle",
category: "Graphics",
description: "Render a filled circle at the specified position.",
searchTags: ["circle", "filled", "shape", "draw"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "x",
name: "X",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y",
name: "Y",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "radius",
name: "Radius",
direction: "input",
kind: "number",
defaultValue: 4,
},
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const x = resolveValueInput("x", "0");
const y = resolveValueInput("y", "0");
const radius = resolveValueInput("radius", "4");
const color = resolveValueInput("color", "__pg_omit__");
const args = [x, y, radius];
if (color !== "__pg_omit__") {
args.push(color);
}
const line = `${indent(indentLevel)}circfill(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,63 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Adjusts the active clipping rectangle for subsequent draw calls.
*/
export const clipNode = createNodeModule(
{
id: "graphics_clip",
title: "Set Clipping Rectangle",
category: "Graphics",
description:
"Set or reset the clipping rectangle that constrains all draw operations.",
searchTags: ["clip", "clipping", "graphics", "viewport"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{ id: "x", name: "X", direction: "input", kind: "number" },
{ id: "y", name: "Y", direction: "input", kind: "number" },
{ id: "w", name: "Width", direction: "input", kind: "number" },
{ id: "h", name: "Height", direction: "input", kind: "number" },
{
id: "clip_previous",
name: "Clip Previous",
direction: "input",
kind: "boolean",
defaultValue: false,
},
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const x = resolveValueInput("x", OMIT);
const y = resolveValueInput("y", OMIT);
const w = resolveValueInput("w", OMIT);
const h = resolveValueInput("h", OMIT);
const clipPrevious = resolveValueInput("clip_previous", OMIT);
let call;
if (x === OMIT && y === OMIT && w === OMIT && h === OMIT) {
call = "clip()";
} else {
const args = [
x === OMIT ? "0" : x,
y === OMIT ? "0" : y,
w === OMIT ? "128" : w,
h === OMIT ? "128" : h,
];
if (clipPrevious !== OMIT) {
args.push(clipPrevious);
}
call = `clip(${args.join(", ")})`;
}
const lines = [`${indent(indentLevel)}${call}`];
lines.push(...emitNextExec("exec_out"));
return lines;
},
}
);

View File

@@ -0,0 +1,32 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Clears the screen and resets clipping.
*/
export const clsNode = createNodeModule(
{
id: "graphics_cls",
title: "Clear Screen",
category: "Graphics",
description: "Clear the display, optionally filling with a specific color.",
searchTags: ["cls", "clear", "screen", "background"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const color = resolveValueInput("color", OMIT);
const call = color === OMIT ? "cls()" : `cls(${color})`;
const lines = [`${indent(indentLevel)}${call}`];
lines.push(...emitNextExec("exec_out"));
return lines;
},
}
);

View File

@@ -0,0 +1,32 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Updates the current draw color.
*/
export const colorNode = createNodeModule(
{
id: "graphics_color",
title: "Set Active Color",
category: "Graphics",
description: "Set the active draw color used by subsequent graphics calls.",
searchTags: ["color", "color", "ink", "draw"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const color = resolveValueInput("color", OMIT);
const call = color === OMIT ? "color()" : `color(${color})`;
const lines = [`${indent(indentLevel)}${call}`];
lines.push(...emitNextExec("exec_out"));
return lines;
},
}
);

View File

@@ -0,0 +1,46 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Positions the print cursor and optionally sets the draw color.
*/
export const cursorNode = createNodeModule(
{
id: "graphics_cursor",
title: "Set Cursor",
category: "Graphics",
description:
"Move the print cursor and optionally change the active color.",
searchTags: ["cursor", "print", "text", "position"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{ id: "x", name: "X", direction: "input", kind: "number" },
{ id: "y", name: "Y", direction: "input", kind: "number" },
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const x = resolveValueInput("x", OMIT);
const y = resolveValueInput("y", OMIT);
const color = resolveValueInput("color", OMIT);
let call = "cursor()";
if (x !== OMIT) {
const args = [x, y === OMIT ? "0" : y];
if (color !== OMIT) {
args.push(color);
}
call = `cursor(${args.join(", ")})`;
}
const lines = [`${indent(indentLevel)}${call}`];
lines.push(...emitNextExec("exec_out"));
return lines;
},
}
);

View File

@@ -0,0 +1,39 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Reads sprite flag data.
*/
export const fgetNode = createNodeModule(
{
id: "graphics_fget",
title: "Get Sprite Flag",
category: "Graphics",
description: "Retrieve the bitfield or specific flag value for a sprite.",
searchTags: ["fget", "flag", "sprite", "meta"],
inputs: [
{
id: "sprite",
name: "Sprite",
direction: "input",
kind: "number",
defaultValue: 0,
},
{ id: "flag", name: "Flag", direction: "input", kind: "number" },
],
outputs: [
{ id: "value", name: "Value", direction: "output", kind: "number" },
],
properties: [],
},
{
evaluateValue: ({ resolveValueInput }) => {
const OMIT = "__pg_omit__";
const sprite = resolveValueInput("sprite", "0");
const flag = resolveValueInput("flag", OMIT);
if (flag === OMIT) {
return `fget(${sprite})`;
}
return `fget(${sprite}, ${flag})`;
},
}
);

View File

@@ -0,0 +1,31 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Configures the active fill pattern.
*/
export const fillpNode = createNodeModule(
{
id: "graphics_fillp",
title: "Set Fill Pattern",
category: "Graphics",
description: "Set the 4x4 fill pattern bitfield used by many draw calls.",
searchTags: ["fillp", "pattern", "fill", "hatch"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{ id: "pattern", name: "Pattern", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const pattern = resolveValueInput("pattern", "__pg_omit__");
const call = pattern === "__pg_omit__" ? "fillp()" : `fillp(${pattern})`;
const lines = [`${indent(indentLevel)}${call}`];
lines.push(...emitNextExec("exec_out"));
return lines;
},
}
);

View File

@@ -0,0 +1,52 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Updates sprite flag values.
*/
export const fsetNode = createNodeModule(
{
id: "graphics_fset",
title: "Set Sprite Flag",
category: "Graphics",
description: "Set a sprite's flag bitfield or a specific flag value.",
searchTags: ["fset", "flag", "sprite", "meta"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "sprite",
name: "Sprite",
direction: "input",
kind: "number",
defaultValue: 0,
},
{ id: "flag", name: "Flag", direction: "input", kind: "number" },
{
id: "value",
name: "Value",
direction: "input",
kind: "any",
defaultValue: true,
},
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const sprite = resolveValueInput("sprite", "0");
const flag = resolveValueInput("flag", OMIT);
const value = resolveValueInput("value", "false");
const args = [sprite];
if (flag === OMIT) {
args.push(value);
} else {
args.push(flag, value);
}
const line = `${indent(indentLevel)}fset(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,88 @@
import { clipNode } from "./clip.js";
import { psetNode } from "./pset.js";
import { pgetNode } from "./pget.js";
import { sgetNode } from "./sget.js";
import { ssetNode } from "./sset.js";
import { fgetNode } from "./fget.js";
import { fsetNode } from "./fset.js";
import { cursorNode } from "./cursor.js";
import { colorNode } from "./color.js";
import { clsNode } from "./cls.js";
import { cameraNode } from "./camera.js";
import { circNode } from "./circ.js";
import { circfillNode } from "./circfill.js";
import { ovalNode } from "./oval.js";
import { ovalfillNode } from "./ovalfill.js";
import { lineNode } from "./line.js";
import { rectNode } from "./rect.js";
import { rectfillNode } from "./rectfill.js";
import { rrectNode } from "./rrect.js";
import { rrectfillNode } from "./rrectfill.js";
import { palNode } from "./pal.js";
import { paltNode } from "./palt.js";
import { sprNode } from "./spr.js";
import { ssprNode } from "./sspr.js";
import { fillpNode } from "./fillp.js";
/**
* All graphics related node modules backed by PICO-8 draw helpers.
*/
export const graphicsNodes = [
clipNode,
psetNode,
pgetNode,
sgetNode,
ssetNode,
fgetNode,
fsetNode,
cursorNode,
colorNode,
clsNode,
cameraNode,
circNode,
circfillNode,
ovalNode,
ovalfillNode,
lineNode,
rectNode,
rectfillNode,
rrectNode,
rrectfillNode,
palNode,
paltNode,
sprNode,
ssprNode,
fillpNode,
];
/**
* Checklist tracking coverage of documented graphics helpers.
* @type {Array<{ function: string, nodeId: string, implemented: boolean }>}
*/
export const graphicsFunctionChecklist = [
{ function: "CLIP", nodeId: "graphics_clip", implemented: true },
{ function: "PSET", nodeId: "graphics_pset", implemented: true },
{ function: "PGET", nodeId: "graphics_pget", implemented: true },
{ function: "SGET", nodeId: "graphics_sget", implemented: true },
{ function: "SSET", nodeId: "graphics_sset", implemented: true },
{ function: "FGET", nodeId: "graphics_fget", implemented: true },
{ function: "FSET", nodeId: "graphics_fset", implemented: true },
{ function: "CURSOR", nodeId: "graphics_cursor", implemented: true },
{ function: "COLOR", nodeId: "graphics_color", implemented: true },
{ function: "CLS", nodeId: "graphics_cls", implemented: true },
{ function: "CAMERA", nodeId: "graphics_camera", implemented: true },
{ function: "CIRC", nodeId: "graphics_circ", implemented: true },
{ function: "CIRCFILL", nodeId: "graphics_circfill", implemented: true },
{ function: "OVAL", nodeId: "graphics_oval", implemented: true },
{ function: "OVALFILL", nodeId: "graphics_ovalfill", implemented: true },
{ function: "LINE", nodeId: "graphics_line", implemented: true },
{ function: "RECT", nodeId: "graphics_rect", implemented: true },
{ function: "RECTFILL", nodeId: "graphics_rectfill", implemented: true },
{ function: "RRECT", nodeId: "graphics_rrect", implemented: true },
{ function: "RRECTFILL", nodeId: "graphics_rrectfill", implemented: true },
{ function: "PAL", nodeId: "graphics_pal", implemented: true },
{ function: "PALT", nodeId: "graphics_palt", implemented: true },
{ function: "SPR", nodeId: "graphics_spr", implemented: true },
{ function: "SSPR", nodeId: "graphics_sspr", implemented: true },
{ function: "FILLP", nodeId: "graphics_fillp", implemented: true },
];

View File

@@ -0,0 +1,60 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws a line segment.
*/
export const lineNode = createNodeModule(
{
id: "graphics_line",
title: "Draw Line",
category: "Graphics",
description:
"Draw a line between two points or update the current pen position.",
searchTags: ["line", "draw", "segment", "stroke"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "x0",
name: "X0",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y0",
name: "Y0",
direction: "input",
kind: "number",
defaultValue: 0,
},
{ id: "x1", name: "X1", direction: "input", kind: "number" },
{ id: "y1", name: "Y1", direction: "input", kind: "number" },
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const x0 = resolveValueInput("x0", "0");
const y0 = resolveValueInput("y0", "0");
const x1 = resolveValueInput("x1", OMIT);
const y1 = resolveValueInput("y1", OMIT);
const color = resolveValueInput("color", OMIT);
const args = [x0, y0];
if (x1 !== OMIT && y1 !== OMIT) {
args.push(x1, y1);
if (color !== OMIT) {
args.push(color);
}
}
const line = `${indent(indentLevel)}line(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,65 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws an outlined oval.
*/
export const ovalNode = createNodeModule(
{
id: "graphics_oval",
title: "Draw Oval",
category: "Graphics",
description: "Render an ellipse using the provided bounding box.",
searchTags: ["oval", "ellipse", "shape", "outline"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "x0",
name: "X0",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y0",
name: "Y0",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "x1",
name: "X1",
direction: "input",
kind: "number",
defaultValue: 8,
},
{
id: "y1",
name: "Y1",
direction: "input",
kind: "number",
defaultValue: 8,
},
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const x0 = resolveValueInput("x0", "0");
const y0 = resolveValueInput("y0", "0");
const x1 = resolveValueInput("x1", "8");
const y1 = resolveValueInput("y1", "8");
const color = resolveValueInput("color", "__pg_omit__");
const args = [x0, y0, x1, y1];
if (color !== "__pg_omit__") {
args.push(color);
}
const line = `${indent(indentLevel)}oval(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,65 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws a filled oval.
*/
export const ovalfillNode = createNodeModule(
{
id: "graphics_ovalfill",
title: "Draw Filled Oval",
category: "Graphics",
description: "Render a filled ellipse using the provided bounding box.",
searchTags: ["oval", "ellipse", "filled", "shape"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "x0",
name: "X0",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y0",
name: "Y0",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "x1",
name: "X1",
direction: "input",
kind: "number",
defaultValue: 8,
},
{
id: "y1",
name: "Y1",
direction: "input",
kind: "number",
defaultValue: 8,
},
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const x0 = resolveValueInput("x0", "0");
const y0 = resolveValueInput("y0", "0");
const x1 = resolveValueInput("x1", "8");
const y1 = resolveValueInput("y1", "8");
const color = resolveValueInput("color", "__pg_omit__");
const args = [x0, y0, x1, y1];
if (color !== "__pg_omit__") {
args.push(color);
}
const line = `${indent(indentLevel)}ovalfill(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,51 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Remaps palette colors.
*/
export const palNode = createNodeModule(
{
id: "graphics_pal",
title: "Remap Palette Color",
category: "Graphics",
description: "Swap one palette color for another or reset the palette.",
searchTags: ["pal", "palette", "color", "remap"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{ id: "c0", name: "Color 0", direction: "input", kind: "number" },
{
id: "c1",
name: "Color 1",
direction: "input",
kind: "number",
defaultValue: 0,
},
{ id: "p", name: "Palette", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const c0 = resolveValueInput("c0", OMIT);
const c1 = resolveValueInput("c1", "0");
const p = resolveValueInput("p", OMIT);
let call = "pal()";
if (c0 !== OMIT) {
const args = [c0, c1];
if (p !== OMIT) {
args.push(p);
}
call = `pal(${args.join(", ")})`;
}
const lines = [`${indent(indentLevel)}${call}`];
lines.push(...emitNextExec("exec_out"));
return lines;
},
}
);

View File

@@ -0,0 +1,47 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Adjusts sprite transparency settings.
*/
export const paltNode = createNodeModule(
{
id: "graphics_palt",
title: "Set Sprite Transparency",
category: "Graphics",
description: "Set or reset sprite transparency flags.",
searchTags: ["palt", "transparency", "palette", "sprite"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{ id: "color", name: "Color", direction: "input", kind: "number" },
{
id: "transparent",
name: "Transparent",
direction: "input",
kind: "boolean",
},
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const color = resolveValueInput("color", OMIT);
const transparent = resolveValueInput("transparent", OMIT);
let call = "palt()";
if (color !== OMIT) {
if (transparent === OMIT) {
call = `palt(${color})`;
} else {
call = `palt(${color}, ${transparent})`;
}
}
const lines = [`${indent(indentLevel)}${call}`];
lines.push(...emitNextExec("exec_out"));
return lines;
},
}
);

View File

@@ -0,0 +1,41 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Reads the color of a screen pixel.
*/
export const pgetNode = createNodeModule(
{
id: "graphics_pget",
title: "Get Pixel Color",
category: "Graphics",
description: "Fetch the color index at the given screen coordinate.",
searchTags: ["pget", "pixel", "read", "sample"],
inputs: [
{
id: "x",
name: "X",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y",
name: "Y",
direction: "input",
kind: "number",
defaultValue: 0,
},
],
outputs: [
{ id: "value", name: "Color", direction: "output", kind: "number" },
],
properties: [],
},
{
evaluateValue: ({ resolveValueInput }) => {
const x = resolveValueInput("x", "0");
const y = resolveValueInput("y", "0");
return `pget(${x}, ${y})`;
},
}
);

View File

@@ -0,0 +1,50 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws a single pixel using the current or specified color.
*/
export const psetNode = createNodeModule(
{
id: "graphics_pset",
title: "Set Pixel Color",
category: "Graphics",
description: "Set a pixel on screen to a color index.",
searchTags: ["pset", "pixel", "draw", "plot"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "x",
name: "X",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y",
name: "Y",
direction: "input",
kind: "number",
defaultValue: 0,
},
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const x = resolveValueInput("x", "0");
const y = resolveValueInput("y", "0");
const color = resolveValueInput("color", OMIT);
const args = [x, y];
if (color !== OMIT) {
args.push(color);
}
const line = `${indent(indentLevel)}pset(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,65 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws an outlined rectangle.
*/
export const rectNode = createNodeModule(
{
id: "graphics_rect",
title: "Draw Rectangle",
category: "Graphics",
description: "Render a rectangle outline defined by two corners.",
searchTags: ["rect", "rectangle", "outline", "shape"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "x0",
name: "X0",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y0",
name: "Y0",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "x1",
name: "X1",
direction: "input",
kind: "number",
defaultValue: 8,
},
{
id: "y1",
name: "Y1",
direction: "input",
kind: "number",
defaultValue: 8,
},
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const x0 = resolveValueInput("x0", "0");
const y0 = resolveValueInput("y0", "0");
const x1 = resolveValueInput("x1", "8");
const y1 = resolveValueInput("y1", "8");
const color = resolveValueInput("color", "__pg_omit__");
const args = [x0, y0, x1, y1];
if (color !== "__pg_omit__") {
args.push(color);
}
const line = `${indent(indentLevel)}rect(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,65 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws a filled rectangle.
*/
export const rectfillNode = createNodeModule(
{
id: "graphics_rectfill",
title: "Draw Filled Rectangle",
category: "Graphics",
description: "Render a filled rectangle defined by two corners.",
searchTags: ["rect", "rectangle", "filled", "shape"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "x0",
name: "X0",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y0",
name: "Y0",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "x1",
name: "X1",
direction: "input",
kind: "number",
defaultValue: 8,
},
{
id: "y1",
name: "Y1",
direction: "input",
kind: "number",
defaultValue: 8,
},
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const x0 = resolveValueInput("x0", "0");
const y0 = resolveValueInput("y0", "0");
const x1 = resolveValueInput("x1", "8");
const y1 = resolveValueInput("y1", "8");
const color = resolveValueInput("color", "__pg_omit__");
const args = [x0, y0, x1, y1];
if (color !== "__pg_omit__") {
args.push(color);
}
const line = `${indent(indentLevel)}rectfill(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,73 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws an outlined rounded rectangle.
*/
export const rrectNode = createNodeModule(
{
id: "graphics_rrect",
title: "Draw Rounded Rectangle",
category: "Graphics",
description: "Render a rounded rectangle outline with the supplied radius.",
searchTags: ["rounded", "rectangle", "outline", "shape"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "x",
name: "X",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y",
name: "Y",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "w",
name: "Width",
direction: "input",
kind: "number",
defaultValue: 8,
},
{
id: "h",
name: "Height",
direction: "input",
kind: "number",
defaultValue: 8,
},
{
id: "r",
name: "Radius",
direction: "input",
kind: "number",
defaultValue: 2,
},
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const x = resolveValueInput("x", "0");
const y = resolveValueInput("y", "0");
const w = resolveValueInput("w", "8");
const h = resolveValueInput("h", "8");
const r = resolveValueInput("r", "2");
const color = resolveValueInput("color", "__pg_omit__");
const args = [x, y, w, h, r];
if (color !== "__pg_omit__") {
args.push(color);
}
const line = `${indent(indentLevel)}rrect(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,73 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws a filled rounded rectangle.
*/
export const rrectfillNode = createNodeModule(
{
id: "graphics_rrectfill",
title: "Draw Filled Rounded Rectangle",
category: "Graphics",
description: "Render a filled rounded rectangle with the supplied radius.",
searchTags: ["rounded", "rectangle", "filled", "shape"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "x",
name: "X",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y",
name: "Y",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "w",
name: "Width",
direction: "input",
kind: "number",
defaultValue: 8,
},
{
id: "h",
name: "Height",
direction: "input",
kind: "number",
defaultValue: 8,
},
{
id: "r",
name: "Radius",
direction: "input",
kind: "number",
defaultValue: 2,
},
{ id: "color", name: "Color", direction: "input", kind: "number" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const x = resolveValueInput("x", "0");
const y = resolveValueInput("y", "0");
const w = resolveValueInput("w", "8");
const h = resolveValueInput("h", "8");
const r = resolveValueInput("r", "2");
const color = resolveValueInput("color", "__pg_omit__");
const args = [x, y, w, h, r];
if (color !== "__pg_omit__") {
args.push(color);
}
const line = `${indent(indentLevel)}rrectfill(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,42 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Reads a pixel from the sprite sheet.
*/
export const sgetNode = createNodeModule(
{
id: "graphics_sget",
title: "Get Sprite Pixel",
category: "Graphics",
description:
"Retrieve the color index from the sprite sheet at the given coordinate.",
searchTags: ["sget", "sprite", "sheet", "read"],
inputs: [
{
id: "x",
name: "X",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y",
name: "Y",
direction: "input",
kind: "number",
defaultValue: 0,
},
],
outputs: [
{ id: "value", name: "Color", direction: "output", kind: "number" },
],
properties: [],
},
{
evaluateValue: ({ resolveValueInput }) => {
const x = resolveValueInput("x", "0");
const y = resolveValueInput("y", "0");
return `sget(${x}, ${y})`;
},
}
);

View File

@@ -0,0 +1,76 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws sprites from the sprite sheet.
*/
export const sprNode = createNodeModule(
{
id: "graphics_spr",
title: "Draw Sprite",
category: "Graphics",
description: "Blit one or more sprites at the given screen position.",
searchTags: ["spr", "sprite", "draw", "blit"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "sprite",
name: "Sprite",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "x",
name: "X",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y",
name: "Y",
direction: "input",
kind: "number",
defaultValue: 0,
},
{ id: "w", name: "Width", direction: "input", kind: "number" },
{ id: "h", name: "Height", direction: "input", kind: "number" },
{ id: "flip_x", name: "Flip X", direction: "input", kind: "boolean" },
{ id: "flip_y", name: "Flip Y", direction: "input", kind: "boolean" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const sprite = resolveValueInput("sprite", "0");
const x = resolveValueInput("x", "0");
const y = resolveValueInput("y", "0");
const w = resolveValueInput("w", OMIT);
const h = resolveValueInput("h", OMIT);
const flipX = resolveValueInput("flip_x", OMIT);
const flipY = resolveValueInput("flip_y", OMIT);
const args = [sprite, x, y];
const includeSize =
w !== OMIT || h !== OMIT || flipX !== OMIT || flipY !== OMIT;
if (includeSize) {
args.push(w === OMIT ? "1" : w, h === OMIT ? "1" : h);
}
if (flipX !== OMIT || flipY !== OMIT) {
args.push(
flipX === OMIT ? "false" : flipX,
flipY === OMIT ? "false" : flipY
);
}
const line = `${indent(indentLevel)}spr(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,51 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Writes a pixel to the sprite sheet.
*/
export const ssetNode = createNodeModule(
{
id: "graphics_sset",
title: "Set Sprite Pixel",
category: "Graphics",
description: "Assign a color to the sprite sheet at the given coordinate.",
searchTags: ["sset", "sprite", "sheet", "write"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "x",
name: "X",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "y",
name: "Y",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "color",
name: "Color",
direction: "input",
kind: "number",
defaultValue: 0,
},
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const x = resolveValueInput("x", "0");
const y = resolveValueInput("y", "0");
const color = resolveValueInput("color", "0");
const line = `${indent(indentLevel)}sset(${x}, ${y}, ${color})`;
return [line, ...emitNextExec("exec_out")];
},
}
);

View File

@@ -0,0 +1,100 @@
import { createNodeModule } from "../../nodeTypes.js";
/**
* Draws a rectangular region of the sprite sheet with scaling support.
*/
export const ssprNode = createNodeModule(
{
id: "graphics_sspr",
title: "Draw Scaled Sprite",
category: "Graphics",
description: "Stretch or flip a sprite sheet region to the screen.",
searchTags: ["sspr", "sprite", "scale", "blit"],
inputs: [
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
{
id: "sx",
name: "SX",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "sy",
name: "SY",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "sw",
name: "SW",
direction: "input",
kind: "number",
defaultValue: 8,
},
{
id: "sh",
name: "SH",
direction: "input",
kind: "number",
defaultValue: 8,
},
{
id: "dx",
name: "DX",
direction: "input",
kind: "number",
defaultValue: 0,
},
{
id: "dy",
name: "DY",
direction: "input",
kind: "number",
defaultValue: 0,
},
{ id: "dw", name: "DW", direction: "input", kind: "number" },
{ id: "dh", name: "DH", direction: "input", kind: "number" },
{ id: "flip_x", name: "Flip X", direction: "input", kind: "boolean" },
{ id: "flip_y", name: "Flip Y", direction: "input", kind: "boolean" },
],
outputs: [
{ id: "exec_out", name: "Exec", direction: "output", kind: "exec" },
],
properties: [],
},
{
emitExec: ({ indent, indentLevel, resolveValueInput, emitNextExec }) => {
const OMIT = "__pg_omit__";
const sx = resolveValueInput("sx", "0");
const sy = resolveValueInput("sy", "0");
const sw = resolveValueInput("sw", "8");
const sh = resolveValueInput("sh", "8");
const dx = resolveValueInput("dx", "0");
const dy = resolveValueInput("dy", "0");
const dw = resolveValueInput("dw", OMIT);
const dh = resolveValueInput("dh", OMIT);
const flipX = resolveValueInput("flip_x", OMIT);
const flipY = resolveValueInput("flip_y", OMIT);
const args = [sx, sy, sw, sh, dx, dy];
const includeDestSize =
dw !== OMIT || dh !== OMIT || flipX !== OMIT || flipY !== OMIT;
if (includeDestSize) {
args.push(dw === OMIT ? sw : dw, dh === OMIT ? sh : dh);
}
if (flipX !== OMIT || flipY !== OMIT) {
args.push(
flipX === OMIT ? "false" : flipX,
flipY === OMIT ? "false" : flipY
);
}
const line = `${indent(indentLevel)}sspr(${args.join(", ")})`;
return [line, ...emitNextExec("exec_out")];
},
}
);