diff --git a/webserial/src/editor/Monaco.svelte b/webserial/src/editor/Monaco.svelte
index f19343f..13307da 100644
--- a/webserial/src/editor/Monaco.svelte
+++ b/webserial/src/editor/Monaco.svelte
@@ -7,12 +7,13 @@
import defaultCode from "./defaultCode.ts?raw";
import defaultEnv from "./defaultEnv.d.ts?raw";
import { code } from "./code";
+ import tsOptions from "../eval/tsOptions";
let divEl: HTMLDivElement = null;
let editor: monaco.editor.IStandaloneCodeEditor;
let value = defaultCode;
- $: $code = TS.transpile(value, { strict: true });
+ $: $code = TS.transpile(value, tsOptions);
onMount(async () => {
// @ts-ignore
@@ -30,7 +31,10 @@
language: "typescript",
});
- let lib = monaco.languages.typescript.typescriptDefaults.addExtraLib(defaultEnv);
+ let lib =
+ monaco.languages.typescript.typescriptDefaults.addExtraLib(
+ defaultEnv
+ );
editor.onKeyUp((_e) => (value = editor.getValue()));
diff --git a/webserial/src/editor/code.ts b/webserial/src/editor/code.ts
index 2b329af..d8f486c 100644
--- a/webserial/src/editor/code.ts
+++ b/webserial/src/editor/code.ts
@@ -1,6 +1,7 @@
import { writable } from "svelte/store";
import defaultCode from "./defaultCode.ts?raw";
import TS from "typescript";
+import tsOptions from "../eval/tsOptions";
/** the transpiled JavaScript code */
-export const code = writable(TS.transpile(defaultCode, {strict: true}));
\ No newline at end of file
+export const code = writable(TS.transpile(defaultCode, tsOptions));
\ No newline at end of file
diff --git a/webserial/src/editor/defaultCode.ts b/webserial/src/editor/defaultCode.ts
index 9c5bd09..ed40918 100644
--- a/webserial/src/editor/defaultCode.ts
+++ b/webserial/src/editor/defaultCode.ts
@@ -1,4 +1,101 @@
-// ayaya ayaya
+// Connect the interface with the button below and modify the code here.
+// The output should update in real time as you type :)
-ctx.set(1, 255);
-ctx.set(2, 255);
\ No newline at end of file
+// Fixtures library. TODO move this into a separate file
+
+class Fixture {
+ address: number
+ ctx: Context
+
+ constructor(address: number, ctx: Context) {
+ this.address = address;
+ this.ctx = ctx;
+ }
+}
+
+interface GenericRGBW {
+ /**
+ * Set the brightness
+ *
+ * @param value between 0 and 1
+ * @param strobe enable strobe (turn off if unsupported)
+ */
+ setBrightness(value: number, strobe?: boolean): void
+ setRGBW(rgb: [number, number, number], w?: number): void
+}
+
+class Par extends Fixture implements GenericRGBW {
+ setBrightness(value: number, strobe?: boolean) {
+ if (strobe || false) {
+ this.ctx.set(this.address, 255);
+ this.ctx.set(this.address + 7, value * 255);
+ } else {
+ this.ctx.set(this.address, value * 255);
+ this.ctx.set(this.address + 7, 0);
+ }
+ }
+
+ setRGBW(rgb: [number, number, number], w?: number) {
+ let [r, g, b] = rgb;
+ this.ctx.set(this.address + 1, r);
+ this.ctx.set(this.address + 2, g);
+ this.ctx.set(this.address + 3, b);
+ this.ctx.set(this.address + 4, w || 0);
+ }
+
+ setAUV(a: number, uv: number) {
+ this.ctx.set(this.address + 5, a);
+ this.ctx.set(this.address + 6, uv);
+ }
+}
+
+class MovingHead extends Fixture implements GenericRGBW {
+ setBrightness(value: number, strobe?: boolean) {
+ let out = (strobe || false)
+ ? 135 + (239 - 135) * value
+ : 8 + (134 - 8) * value;
+ this.ctx.set(this.address + 5, out);
+ }
+
+ setRGBW(rgb: [number, number, number], w?: number) {
+ let [r, g, b] = rgb;
+ this.ctx.set(this.address + 6, r);
+ this.ctx.set(this.address + 7, g);
+ this.ctx.set(this.address + 8, b);
+ this.ctx.set(this.address + 9, w || 0);
+ }
+
+ /**
+ * Rotate the moving head. Pan and tilt are in radians.
+ * @param pan between -1.5pi and 1.5pi
+ * @param tilt between -0.5pi and 0.5pi
+ * @param speed between 0 (fast) and 255 (slow)
+ */
+ setPanTilt(pan: number, tilt: number, speed?: number) {
+ let panRough = (pan + 3 * Math.PI / 2) / (Math.PI * 3) * 256
+ panRough = Math.max(0, Math.min(255, panRough))
+
+ let tiltRough = (tilt + Math.PI / 2) / (Math.PI) * 256
+ tiltRough = Math.max(0, Math.min(255, tiltRough))
+
+ // TODO
+ let panFine = 0
+ let tiltFine = 0
+
+ this.ctx.set(this.address + 0, panRough);
+ this.ctx.set(this.address + 1, panFine);
+ this.ctx.set(this.address + 2, tiltRough);
+ this.ctx.set(this.address + 3, tiltFine);
+ this.ctx.set(this.address + 4, speed || 0);
+ }
+}
+
+// ******************
+// * CODE GOES HERE *
+// ******************
+
+let color = lib.hsl2rgb(360 * t, 100, 50);
+
+let par = new Par(1, ctx);
+par.setBrightness(1);
+par.setRGBW(color);
\ No newline at end of file
diff --git a/webserial/src/editor/defaultEnv.d.ts b/webserial/src/editor/defaultEnv.d.ts
index 1d43a76..9d7cbfd 100644
--- a/webserial/src/editor/defaultEnv.d.ts
+++ b/webserial/src/editor/defaultEnv.d.ts
@@ -1,9 +1,30 @@
type Context = {
+ /**
+ * Set DMX address `address` to `value`
+ * @param address between 1 and 511
+ * @param value between 0 and 255
+ */
set(address: number, value: number): void,
};
-/** the global Context object */
+/** The global Context object */
declare const ctx: Context;
-/** the current time (in seconds, e.g. 1.25 after 1250 milliseconds) */
-declare const t: number;
\ No newline at end of file
+/** The current time (in seconds, e.g. 1.25 after 1250 milliseconds) */
+declare const t: number;
+
+type Lib = {
+ /**
+ * Converts from the HSL color space to RGB
+ *
+ * Outputs [r, g, b] between 0 and 255 each
+ *
+ * @param h in degrees, i.e. 0 to 360
+ * @param s between 0 and 100
+ * @param l between 0 and 100
+ */
+ hsl2rgb(h: number, s: number, l: number): [number, number, number]
+}
+
+/** The standard library */
+declare const lib: Lib;
\ No newline at end of file
diff --git a/webserial/src/eval/EvalLoop.svelte b/webserial/src/eval/EvalLoop.svelte
index bedba0d..b902bd3 100644
--- a/webserial/src/eval/EvalLoop.svelte
+++ b/webserial/src/eval/EvalLoop.svelte
@@ -3,14 +3,16 @@
import { onMount } from "svelte";
import { code } from "../editor/code";
import { dmxData } from "../dmx/store";
+ import { lib } from "./lib";
let startTime: number;
let payload = new Uint8Array(512);
let ctx: Context = {
set(address: number, value: number) {
- payload[address - 1] = value;
- }
- }
+ let rounded = Math.round(value);
+ payload[address - 1] = Math.max(0, Math.min(255, rounded));
+ },
+ };
let result: string;
@@ -18,7 +20,7 @@
payload = new Uint8Array(512);
const t = (performance.now() - startTime) / 1000;
try {
- let ret = Function("ctx", "t", $code).call({}, ctx, t);
+ let ret = Function("ctx", "t", "lib", $code).call({}, ctx, t, lib);
result = JSON.stringify(ret);
} catch (err) {
result = JSON.stringify(err);
@@ -36,8 +38,8 @@
return () => {
clearInterval(int);
- }
- })
+ };
+ });
-
\ No newline at end of file
+
diff --git a/webserial/src/eval/lib.ts b/webserial/src/eval/lib.ts
new file mode 100644
index 0000000..6f1f18b
--- /dev/null
+++ b/webserial/src/eval/lib.ts
@@ -0,0 +1,16 @@
+///
Serial available 🚀
- {#if port !== null} -Serial available 🚀
+ {#if port !== null} +Looks like your browser does not support WebSerial 😢
++ Check here for a list of compatible browsers +
{/if} -{:else} -Looks like your browser does not support WebSerial 😢
-Check here for a list of compatible browsers
-{/if}