mirror of
https://github.com/litruv/picoGraph.git
synced 2026-07-24 02:36:04 +10:00
Add initial Pico-8 cartridges for testing
- Created test_cart.p8 with basic drawing functionality and a print statement. - Created test_unix.p8 with a simple initialization function.
This commit is contained in:
@@ -1,15 +1,10 @@
|
||||
import { getLiteralNodeModules } from "../../core/lua/LuaLiteralTypes.js";
|
||||
import { eventInitNode } from "./eventStart.js";
|
||||
import { eventUpdateNode } from "./eventUpdate.js";
|
||||
import { eventDrawNode } from "./eventDraw.js";
|
||||
import { printNode } from "./print.js";
|
||||
import { setVariableNode } from "./setVariable.js";
|
||||
import { getVariableNode } from "./getVariable.js";
|
||||
import { numberLiteralNode } from "./numberLiteral.js";
|
||||
import { stringLiteralNode } from "./stringLiteral.js";
|
||||
import { booleanLiteralNode } from "./booleanLiteral.js";
|
||||
import { colorLiteralNode } from "./colorLiteral.js";
|
||||
import { addNumberNode } from "./addNumber.js";
|
||||
import { multiplyNumberNode } from "./multiplyNumber.js";
|
||||
import { compareNode } from "./compare.js";
|
||||
import { sequenceNode } from "./sequence.js";
|
||||
import { ifNode } from "./ifNode.js";
|
||||
@@ -33,20 +28,16 @@ import { devkitNodes, devkitFunctionChecklist } from "./devkit/index.js";
|
||||
import { luaNodes, luaFunctionChecklist } from "./lua/index.js";
|
||||
import { localVariableNodes } from "./localVariables.js";
|
||||
import { converterNodes } from "./converters/index.js";
|
||||
import { rerouteNode, rerouteExecNode } from "./reroute.js";
|
||||
|
||||
export const nodeModules = [
|
||||
...getLiteralNodeModules(),
|
||||
eventInitNode,
|
||||
eventUpdateNode,
|
||||
eventDrawNode,
|
||||
printNode,
|
||||
setVariableNode,
|
||||
getVariableNode,
|
||||
numberLiteralNode,
|
||||
stringLiteralNode,
|
||||
booleanLiteralNode,
|
||||
colorLiteralNode,
|
||||
addNumberNode,
|
||||
multiplyNumberNode,
|
||||
compareNode,
|
||||
sequenceNode,
|
||||
ifNode,
|
||||
@@ -55,6 +46,8 @@ export const nodeModules = [
|
||||
callCustomEventNode,
|
||||
...localVariableNodes,
|
||||
...converterNodes,
|
||||
rerouteNode,
|
||||
rerouteExecNode,
|
||||
...graphicsNodes,
|
||||
...systemNodes,
|
||||
...tableNodes,
|
||||
|
||||
@@ -90,6 +90,8 @@ export const controllerButtonsNode = createNodeModule(
|
||||
name: "Button",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: DEFAULT_BUTTON_VALUE,
|
||||
options: BUTTON_OPTIONS,
|
||||
description: "Optional button index override",
|
||||
},
|
||||
{
|
||||
@@ -97,6 +99,8 @@ export const controllerButtonsNode = createNodeModule(
|
||||
name: "Player",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: DEFAULT_PLAYER_VALUE,
|
||||
options: PLAYER_OPTIONS,
|
||||
description: "Optional player index override",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
import { createNodeModule } from "../nodeTypes.js";
|
||||
import {
|
||||
getLocalVariableTypeOptions,
|
||||
variablePropertyKey,
|
||||
localVariableDefault,
|
||||
LOCAL_VARIABLE_TYPE_IDS,
|
||||
} from "../../types/TypeRegistry.js";
|
||||
|
||||
const LOCAL_TYPES = [
|
||||
{ value: "number", label: "Number" },
|
||||
{ value: "string", label: "String" },
|
||||
{ value: "boolean", label: "Boolean" },
|
||||
{ value: "table", label: "Table" },
|
||||
];
|
||||
|
||||
const LOCAL_TYPES = getLocalVariableTypeOptions();
|
||||
const DEFAULT_LOCAL_TYPE = LOCAL_TYPES[0]?.value ?? "number";
|
||||
|
||||
const sanitizeType = (raw) => {
|
||||
const candidate = typeof raw === "string" ? raw.toLowerCase() : DEFAULT_LOCAL_TYPE;
|
||||
return LOCAL_TYPES.some((entry) => entry.value === candidate)
|
||||
? candidate
|
||||
: DEFAULT_LOCAL_TYPE;
|
||||
const candidate = typeof raw === "string" ? raw.trim().toLowerCase() : "";
|
||||
return LOCAL_VARIABLE_TYPE_IDS.has(candidate) ? candidate : DEFAULT_LOCAL_TYPE;
|
||||
};
|
||||
|
||||
const ensureName = (raw, fallback = "localVar") => {
|
||||
@@ -21,33 +19,10 @@ const ensureName = (raw, fallback = "localVar") => {
|
||||
return value.length ? value : fallback;
|
||||
};
|
||||
|
||||
const resolveValuePropertyKey = (type) => {
|
||||
switch (type) {
|
||||
case "string":
|
||||
return "valueString";
|
||||
case "boolean":
|
||||
return "valueBoolean";
|
||||
case "table":
|
||||
return "valueTable";
|
||||
case "number":
|
||||
default:
|
||||
return "valueNumber";
|
||||
}
|
||||
};
|
||||
const resolveValuePropertyKey = variablePropertyKey;
|
||||
|
||||
const defaultValueForType = localVariableDefault;
|
||||
|
||||
const defaultValueForType = (type) => {
|
||||
switch (type) {
|
||||
case "string":
|
||||
return "";
|
||||
case "boolean":
|
||||
return false;
|
||||
case "table":
|
||||
return "{}";
|
||||
case "number":
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
const initializeLocalProperties = (properties, { includeValue }) => {
|
||||
const type = sanitizeType(properties.variableType);
|
||||
@@ -68,6 +43,15 @@ const initializeLocalProperties = (properties, { includeValue }) => {
|
||||
if (typeof properties.valueTable !== "string") {
|
||||
properties.valueTable = String(properties.valueTable ?? "{}");
|
||||
}
|
||||
if (
|
||||
typeof properties.valueColor !== "number" ||
|
||||
!Number.isFinite(properties.valueColor)
|
||||
) {
|
||||
const n = Number(properties.valueColor);
|
||||
properties.valueColor = Number.isFinite(n)
|
||||
? Math.max(0, Math.min(15, Math.round(n)))
|
||||
: 7;
|
||||
}
|
||||
|
||||
if (includeValue) {
|
||||
const key = resolveValuePropertyKey(type);
|
||||
|
||||
41
scripts/nodes/library/math/add.js
Normal file
41
scripts/nodes/library/math/add.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { createNodeModule } from "../../nodeTypes.js";
|
||||
|
||||
/**
|
||||
* Adds two numeric values.
|
||||
*/
|
||||
export const mathAddNode = createNodeModule(
|
||||
{
|
||||
id: "math_add",
|
||||
title: "Add",
|
||||
category: "Math",
|
||||
description: "Add two numbers.",
|
||||
searchTags: ["add", "math", "sum", "plus", "number", "+"],
|
||||
inputs: [
|
||||
{
|
||||
id: "a",
|
||||
name: "A",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: 0,
|
||||
},
|
||||
{
|
||||
id: "b",
|
||||
name: "B",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: 0,
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{ id: "res", name: "Result", direction: "output", kind: "number" },
|
||||
],
|
||||
properties: [],
|
||||
},
|
||||
{
|
||||
evaluateValue: ({ resolveValueInput }) => {
|
||||
const a = resolveValueInput("a", "0");
|
||||
const b = resolveValueInput("b", "0");
|
||||
return `(${a}) + (${b})`;
|
||||
},
|
||||
}
|
||||
);
|
||||
41
scripts/nodes/library/math/divide.js
Normal file
41
scripts/nodes/library/math/divide.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { createNodeModule } from "../../nodeTypes.js";
|
||||
|
||||
/**
|
||||
* Divides one numeric value by another.
|
||||
*/
|
||||
export const mathDivideNode = createNodeModule(
|
||||
{
|
||||
id: "math_divide",
|
||||
title: "Divide",
|
||||
category: "Math",
|
||||
description: "Divide one number by another (floating point division).",
|
||||
searchTags: ["divide", "division", "math", "slash", "number", "/"],
|
||||
inputs: [
|
||||
{
|
||||
id: "a",
|
||||
name: "A",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: 0,
|
||||
},
|
||||
{
|
||||
id: "b",
|
||||
name: "B",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: 1,
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{ id: "res", name: "Result", direction: "output", kind: "number" },
|
||||
],
|
||||
properties: [],
|
||||
},
|
||||
{
|
||||
evaluateValue: ({ resolveValueInput }) => {
|
||||
const a = resolveValueInput("a", "0");
|
||||
const b = resolveValueInput("b", "1");
|
||||
return `(${a}) / (${b})`;
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -1,3 +1,7 @@
|
||||
import { mathAddNode } from "./add.js";
|
||||
import { mathSubtractNode } from "./subtract.js";
|
||||
import { mathMultiplyNode } from "./multiply.js";
|
||||
import { mathDivideNode } from "./divide.js";
|
||||
import { mathMaxNode } from "./max.js";
|
||||
import { mathMinNode } from "./min.js";
|
||||
import { mathMidNode } from "./mid.js";
|
||||
@@ -25,6 +29,10 @@ import { mathDivNode } from "./div.js";
|
||||
* All math-related node modules backed by PICO-8 helpers.
|
||||
*/
|
||||
export const mathNodes = [
|
||||
mathAddNode,
|
||||
mathSubtractNode,
|
||||
mathMultiplyNode,
|
||||
mathDivideNode,
|
||||
mathMaxNode,
|
||||
mathMinNode,
|
||||
mathMidNode,
|
||||
@@ -54,6 +62,10 @@ export const mathNodes = [
|
||||
* @type {Array<{ function: string, nodeId: string, implemented: boolean }>}
|
||||
*/
|
||||
export const mathFunctionChecklist = [
|
||||
{ function: "+", nodeId: "math_add", implemented: true },
|
||||
{ function: "-", nodeId: "math_subtract", implemented: true },
|
||||
{ function: "*", nodeId: "math_multiply", implemented: true },
|
||||
{ function: "/", nodeId: "math_divide", implemented: true },
|
||||
{ function: "MAX", nodeId: "math_max", implemented: true },
|
||||
{ function: "MIN", nodeId: "math_min", implemented: true },
|
||||
{ function: "MID", nodeId: "math_mid", implemented: true },
|
||||
|
||||
41
scripts/nodes/library/math/multiply.js
Normal file
41
scripts/nodes/library/math/multiply.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { createNodeModule } from "../../nodeTypes.js";
|
||||
|
||||
/**
|
||||
* Multiplies two numeric values.
|
||||
*/
|
||||
export const mathMultiplyNode = createNodeModule(
|
||||
{
|
||||
id: "math_multiply",
|
||||
title: "Multiply",
|
||||
category: "Math",
|
||||
description: "Multiply two numbers.",
|
||||
searchTags: ["multiply", "product", "math", "times", "*"],
|
||||
inputs: [
|
||||
{
|
||||
id: "a",
|
||||
name: "A",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: 0,
|
||||
},
|
||||
{
|
||||
id: "b",
|
||||
name: "B",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: 0,
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{ id: "res", name: "Result", direction: "output", kind: "number" },
|
||||
],
|
||||
properties: [],
|
||||
},
|
||||
{
|
||||
evaluateValue: ({ resolveValueInput }) => {
|
||||
const a = resolveValueInput("a", "0");
|
||||
const b = resolveValueInput("b", "0");
|
||||
return `(${a}) * (${b})`;
|
||||
},
|
||||
}
|
||||
);
|
||||
41
scripts/nodes/library/math/subtract.js
Normal file
41
scripts/nodes/library/math/subtract.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { createNodeModule } from "../../nodeTypes.js";
|
||||
|
||||
/**
|
||||
* Subtracts one numeric value from another.
|
||||
*/
|
||||
export const mathSubtractNode = createNodeModule(
|
||||
{
|
||||
id: "math_subtract",
|
||||
title: "Subtract",
|
||||
category: "Math",
|
||||
description: "Subtract one number from another.",
|
||||
searchTags: ["subtract", "math", "minus", "difference", "-"],
|
||||
inputs: [
|
||||
{
|
||||
id: "a",
|
||||
name: "A",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: 0,
|
||||
},
|
||||
{
|
||||
id: "b",
|
||||
name: "B",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: 0,
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{ id: "res", name: "Result", direction: "output", kind: "number" },
|
||||
],
|
||||
properties: [],
|
||||
},
|
||||
{
|
||||
evaluateValue: ({ resolveValueInput }) => {
|
||||
const a = resolveValueInput("a", "0");
|
||||
const b = resolveValueInput("b", "0");
|
||||
return `(${a}) - (${b})`;
|
||||
},
|
||||
}
|
||||
);
|
||||
53
scripts/nodes/library/reroute.js
Normal file
53
scripts/nodes/library/reroute.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import { createNodeModule } from "../nodeTypes.js";
|
||||
|
||||
/**
|
||||
* A transparent pass-through node for redirecting data wires.
|
||||
* Emits no code on its own — the value resolves directly through the input.
|
||||
*/
|
||||
export const rerouteNode = createNodeModule(
|
||||
{
|
||||
id: "reroute",
|
||||
title: "Reroute",
|
||||
category: "Utility",
|
||||
description: "Redirects a data wire without affecting the value.",
|
||||
searchTags: ["reroute", "redirect", "wire", "relay", "pass", "through"],
|
||||
inputs: [
|
||||
{ id: "value", name: "", direction: "input", kind: "any" },
|
||||
],
|
||||
outputs: [
|
||||
{ id: "value", name: "", direction: "output", kind: "any" },
|
||||
],
|
||||
properties: [],
|
||||
},
|
||||
{
|
||||
evaluateValue: ({ resolveValueInput }) => {
|
||||
return resolveValueInput("value", "nil");
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* A transparent pass-through node for redirecting exec wires.
|
||||
* Emits no code on its own — execution continues directly to the next node.
|
||||
*/
|
||||
export const rerouteExecNode = createNodeModule(
|
||||
{
|
||||
id: "reroute_exec",
|
||||
title: "Reroute",
|
||||
category: "Utility",
|
||||
description: "Redirects an exec wire without generating any code.",
|
||||
searchTags: ["reroute", "redirect", "exec", "wire", "relay", "pass", "through"],
|
||||
inputs: [
|
||||
{ id: "exec_in", name: "", direction: "input", kind: "exec" },
|
||||
],
|
||||
outputs: [
|
||||
{ id: "exec_out", name: "", direction: "output", kind: "exec" },
|
||||
],
|
||||
properties: [],
|
||||
},
|
||||
{
|
||||
emitExec: ({ emitNextExec }) => {
|
||||
return emitNextExec("exec_out");
|
||||
},
|
||||
}
|
||||
);
|
||||
41
scripts/nodes/library/subtractNumber.js
Normal file
41
scripts/nodes/library/subtractNumber.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { createNodeModule } from "../nodeTypes.js";
|
||||
|
||||
/**
|
||||
* Subtracts one numeric value from another.
|
||||
*/
|
||||
export const subtractNumberNode = createNodeModule(
|
||||
{
|
||||
id: "subtract_number",
|
||||
title: "Subtract",
|
||||
category: "Math",
|
||||
description: "Subtract one number from another.",
|
||||
searchTags: ["subtract", "math", "minus", "difference", "number"],
|
||||
inputs: [
|
||||
{
|
||||
id: "a",
|
||||
name: "A",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: 0,
|
||||
},
|
||||
{
|
||||
id: "b",
|
||||
name: "B",
|
||||
direction: "input",
|
||||
kind: "number",
|
||||
defaultValue: 0,
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{ id: "res", name: "Result", direction: "output", kind: "number" },
|
||||
],
|
||||
properties: [],
|
||||
},
|
||||
{
|
||||
evaluateValue: ({ resolveValueInput }) => {
|
||||
const a = resolveValueInput("a", "0");
|
||||
const b = resolveValueInput("b", "0");
|
||||
return `(${a}) - (${b})`;
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -41,7 +41,7 @@ export const extcmdNode = createNodeModule(
|
||||
],
|
||||
inputs: [
|
||||
{ id: "exec_in", name: "Exec", direction: "input", kind: "exec" },
|
||||
{ id: "command", name: "Command", direction: "input", kind: "string" },
|
||||
{ id: "command", name: "Command", direction: "input", kind: "string", defaultValue: EXT_CMD_DEFAULT, options: EXT_CMD_OPTIONS },
|
||||
{ id: "param1", name: "Param 1", direction: "input", kind: "number" },
|
||||
{ id: "param2", name: "Param 2", direction: "input", kind: "number" },
|
||||
],
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* @property {('exec'|'number'|'boolean'|'string'|'table'|'any'|'color')} kind Blueprint connection kind.
|
||||
* @property {string} [description] Optional tooltip text.
|
||||
* @property {unknown} [defaultValue] Default literal for data pins.
|
||||
* @property {Array<{label: string, value: string}>} [options] Renders an inline select dropdown when the pin is unconnected.
|
||||
* @property {boolean} [spawnLiteralNode] Whether dragging off this pin offers the default literal node. Defaults to the handler's spawnableByDefault.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user