-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
allow yalp work with fpp config
- Loading branch information
Showing
10 changed files
with
685 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#!/usr/bin/env node | ||
//YALP stand-alone prop animation | ||
|
||
"use strict"; //find bugs + typos easier | ||
//imports(); //hoist | ||
const assert = require('assert').strict; //https://nodejs.org/api/assert.html; CAUTION: SLOW; don't use in big loops! | ||
const {PAL} = require("../incl/color-mgmt22"); | ||
const {Model, Rect, ZZ, flip} = require("../models/model22"); | ||
const {debug, TODO, srcline, replace_prop} = require("../incl/utils22"); | ||
|
||
my_exports({/*mini_test: mini_test(),*/ dev_panel: dev_panel(), dev_strip: dev_strip(), Blank}); //NOTE: exporting singletons, not ctors | ||
|
||
//const dev_panel = new Model( //can't hoist const | ||
function dev_panel(opts) { return Object.assign(/*{}, opts || {},*/ new Model( | ||
{ | ||
maxbr: 1/100, //for eye pain | ||
order: "RGB", | ||
SQSIZE: 16, | ||
get num_wired() { return this.SQSIZE ** 2; }, | ||
name: "devpanel-32x8", | ||
// get width() { return SQSIZE * 2, height: SQSIZE / 2; }, | ||
mini: Rect({X: 16-2, Y: 3, W: 5, H: 4}), | ||
get width() { return replace_prop.call(this, this.SQSIZE * 2); }, get height() { return replace_prop.call(this, this.SQSIZE / 2); }, | ||
draw: function() //default texture | ||
{ | ||
this.fill(PAL.RED.dim(1)); | ||
this.fill(PAL.GREEN.dim(1), this.mini); | ||
}, | ||
get numpx() | ||
{ | ||
let numpx = 0; | ||
const [W, H] = [this.width, this.height]; | ||
//debug("getting numpx", W, H, this.width, this.height, this.maxbr, this.order, srcline(+1)); | ||
//TODO: use ZZ() | ||
// let (y = 0; y < H; ++y) | ||
// let (x = 0; x < W; ++x) | ||
// ZZ(x, W / 2) | ||
// const [cycle, step] = [Math.floor(val / limit), val % limit]; | ||
// return (cycle & 1)? flip(step, limit): step; //limit - step - 1: step; | ||
//left: ZZ L2RB2T, right: ZZ R2LT2B | ||
for (let y = 0; y < H * 2; ++y) //half height | ||
for (let x = 0; x < W / 2; ++x) //double width | ||
{ | ||
const xofs = (y < H)? 0: W / 2; //left vs. right half | ||
const xZZ = ((y & 1) ^ (y < H))? x: flip(x, W / 2); //horiz ZZ; top half reversed | ||
const yZZ = (y < H)? y: flip(y, 2 * H); | ||
// nodes2D[ynew][xnew] = numpx++; | ||
//debug(x, y, numpx, this.nodes2D.length, this.nodes2D[0].length); | ||
this.nodes2D[xofs + xZZ][yZZ] = numpx++; //=> outnodes[pxnum] | ||
//debug("here1"); | ||
//if (!y || !x || (y == H * 2 - 1) || (x == W / 2 - 1)) debug(`(${x}/${W / 2}, ${y}/${H * 2}) => (${xnew}, ${ynew}):`, nodes2D[xnew][ynew]); //debug edges | ||
} | ||
assert(numpx == this.SQSIZE ** 2, `numpx ${numpx} != sq^s ${this.SQSIZE ** 2}`.brightRed); //check all nodes mapped | ||
return numpx; | ||
}, | ||
}), opts || {}); } | ||
if (!module.parent) setImmediate(async () => await module.exports.dev_panel.unit_test()); //unit-test; run after inline init | ||
if (!module.parent) setImmediate(async () => await module.exports.dev_panel.mini.unit_test()); //unit-test; run after inline init | ||
/* | ||
function mini_test(opts) { return Object.assign(/-*{}, opts || {},*-/ new Model( | ||
{ | ||
maxbr: 1/100, //for eye pain | ||
order: "RGB", | ||
width: 4, height: 3, | ||
num_wired: 12, | ||
name: "mini-test-4x3", | ||
get numpx() | ||
{ | ||
let numpx = 0; | ||
const [W, H] = [this.width, this.height]; | ||
//debug("getting numpx", W, H, this.width, this.height, this.maxbr, this.order, srcline(+1)); | ||
for (let xy = 0; xy < W * H; ++xy) | ||
this.nodes2D[ZZ(xy, W)][ZZ.cycle] = numpx++; //=> outnodes[pxnum] | ||
assert(numpx == 3 * 4, `numpx ${numpx} != ${3 * 4}`.brightRed); //check all nodes mapped | ||
return numpx; | ||
}, | ||
}), opts || {}); } | ||
*/ | ||
|
||
|
||
//const dev_strip = new Model( //can't hoist const | ||
function dev_strip(opts) { return Object.assign(/*{}, opts || {},*/ new Model( | ||
{ | ||
maxbr: 1/100, //70/100, //for eye pain | ||
order: "GRB", | ||
name: "devstrip-32", | ||
width: 32, //height: 1, //horizontal | ||
num_wired: 32, | ||
get numpx() //{ return replace_prop.call(this, () => //222); }, | ||
{ | ||
let numpx = 0; | ||
for (let x = 0; x < this.width; ++x) | ||
this.nodes2D[flip(x, this.width)][0] = numpx++; | ||
assert(numpx == 32 * 1, `numpx ${numpx} != 32`.brightRed); | ||
return numpx; | ||
}, | ||
}), opts || {}); } | ||
if (!module.parent) setImmediate(async () => await module.exports.dev_strip.unit_test()); //unit-test; run after inline init | ||
|
||
|
||
//blank canvas: | ||
//mainly for RLE debug | ||
function Blank(opts) { return Object.assign(new Model( | ||
{ | ||
// maxbr: 1/100, //for eye pain | ||
order: "RGB", | ||
name: "blank", | ||
width: (opts || {}).width || 16, | ||
height: (opts || {}).height || 16, | ||
get num_wired() { return this.width * this.height; }, | ||
get numpx() | ||
{ | ||
//broken this.mapall(); | ||
let numpx = 0; | ||
for (let x = 0; x < this.width; ++x) | ||
for (let y = 0; y < this.height; ++y) | ||
this.nodes2D[x][y] = numpx++; | ||
return numpx; //this.width * this.height; | ||
}, | ||
}), opts || {}); } | ||
|
||
|
||
function my_exports(things) { return Object.assign(module.exports, things); } //{[entpt.name]: entpt}); } | ||
|
||
//eof |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#!/usr/bin/env node | ||
//ESOL silhouette fence 2021 | ||
|
||
"use strict"; //find bugs + typos easier | ||
//imports(); //hoist | ||
const assert = require('assert').strict; //https://nodejs.org/api/assert.html; CAUTION: SLOW; don't use in big loops! | ||
const {PAL} = require("../incl/color-mgmt22"); | ||
const {Model, Rect, ZZ, flip} = require("../models/model22"); | ||
const {debug, TODO, srcline, replace_prop} = require("../incl/utils22"); | ||
|
||
|
||
//my_exports({mary: NatFig("Mary: NAT"), joseph: Natfig("Joseph: NAT"), Natfig}); //NOTE: exporting instances + ctor | ||
my_exports({fence: Fence(), Fence}); //NOTE: exporting instances + ctor | ||
|
||
//silhouette fence: | ||
function Fence(opts) { return Object.assign(/*{}, opts || {},*/ new Model( | ||
{ | ||
maxbr: 25/100, //4A supply (12V) | ||
order: "RGB", | ||
name: "Fence: YARD, prop", | ||
num_wired: 2*50 +26, //2 5m strips for fence + ~ 1/2 for pole; 3 LED/pixel (12V) | ||
//TODO: make sub-models? | ||
segments: //R2L | ||
{ | ||
RCandle: 5, | ||
RBell: 7, | ||
XAndel: 7, | ||
RK_camel: 7, | ||
K_camel_star: 6, | ||
LCandle: 4, | ||
RAngel: 6, | ||
|
||
K_camel_kneel: 7, | ||
MJB_star: 7, | ||
Shep2_kneel: 7, | ||
LAngel: 6, | ||
City: 7, | ||
Sheps2_star: 7, | ||
LShep: 6, | ||
LBell: 5, | ||
Joy: 7, | ||
|
||
pole: 25, //neighborhood contest add-on | ||
}, | ||
get width() { return Object.values(this.segments).reduce((total, w) => total + w, 0); }, | ||
height: 1, | ||
draw: function() //default texture | ||
{ | ||
Object.values(this.segments).reduce((X, W, inx) => (this.fill((inx & 1)? PAL.RED.dim(25): PAL.GREEN.dim(25), Rect({X, W, Y: 0, H: 1})), X + W), 0); | ||
}, | ||
get numpx() //CAUTION: nodes must be in wiring order | ||
{ | ||
let numpx = 0; | ||
|
||
//segments R2L | ||
// debug(this.nodes2D.length); | ||
// debug(this.nodes2D[0].length); | ||
const parent = this; | ||
Object.values(this.segments).reduce((X, W) => (/*debug({X, W, width: this.width}),*/ Array.from({length: W}, (_, x) => this.nodes2D[flip(X + x, parent.width)][0] = numpx++), X + W), 0); | ||
|
||
assert(numpx == this.width); //check all nodes mapped | ||
assert(numpx == this.num_wired); | ||
return numpx; | ||
}, | ||
}), opts || {}); } | ||
if (!module.parent) setImmediate(async () => await module.exports.fence.unit_test()); //unit-test; run after inline init | ||
|
||
//wisemen[0].csv(); | ||
//run(); | ||
|
||
|
||
function my_exports(things) { return Object.assign(module.exports, things); } //{[entpt.name]: entpt}); } | ||
|
||
//eof |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#!/usr/bin/env node | ||
//ESOL Gdoor v2.1 2022 | ||
|
||
"use strict"; //find bugs + typos easier | ||
//imports(); //hoist | ||
const assert = require('assert').strict; //https://nodejs.org/api/assert.html; CAUTION: SLOW; don't use in big loops! | ||
const {PAL} = require("../incl/color-mgmt22"); | ||
const {Model, Rect, ZZ, flip} = require("../models/model22"); | ||
const {debug, TODO, srcline, replace_prop} = require("../incl/utils22"); | ||
|
||
|
||
//my_exports({gdoor: Gdoor(), Gdoor}); //NOTE: exporting singleton + ctor | ||
my_exports({gdoor: Object.entries({L: -1, M: 0, U: +1}).map(([key, dir]) => Gdoor({name: `gdoor_${key}: HOUSE`, dir})), Gdoor}); //NOTE: exporting instances + ctor | ||
TODO("use 2 gdoor panels instead of 3? interleave?"); | ||
|
||
|
||
//gdoor: | ||
//24x150/2: M2TL2R2L ZZ upper, M2BL2R2L ZZ lower | ||
function Gdoor(opts) { return Object.assign(/*{}, opts || {},*/ new Model( | ||
{ | ||
maxbr: 25/100, //half of px can be @50%, 20A x 3 power supply | ||
order: "RGB", | ||
name: "Gdoor: HOUSE, prop", //"gdoor2-66x24", //"gdoor-75x24", | ||
// num_wired: 24 * (150 - 13 - 5)/2, //24 strips of 5m 30/m, double-spaced | ||
num_wired: 24/3 * 150, | ||
// get width() { return SQSIZE * 2, height: SQSIZE / 2; }, | ||
// get width() { return Math.max(this.upper.W, this.middle.W, this.lower.W); }, //: 66 | ||
// get height() { return this.lower.H + this.middle.H + this.upper.H; }, //24 | ||
// get upper() { const parent = this; return Rect({X: 0, Y: parent.middle.topE, W: (150 - 13) / 2, H: 8}); }, //parent.width, H: 10}); }, //parent.height / 3}); }, | ||
// get middle() { const parent = this; return Rect({X: 0, Y: parent.lower.topE, W: (150 - 13) / 2, H: 8}); }, //parent.width, H: parent.height / 3}); }, | ||
// get lower() { const parent = this; return Rect({X: 0, Y: 0, W: (150 - 13) / 2, H: 8}); }, //parent.width, H: 10}); }, //parent.height / 3}); }, | ||
width: 150, height: 8, //(150 - 13) / 2, height: 8, | ||
get numpx() | ||
{ | ||
let numpx = 0; | ||
|
||
for (let y = 0; y < this.height; ++y) | ||
{ | ||
const pad = (opts.dir || y != this.height / 2)? 6: 7; | ||
numpx += pad; | ||
for (let x = 0; x < this.width; ++x) | ||
{ | ||
const ydir = (opts.dir < 0)? flip(y, this.height): (opts.dir > 0)? y: (y < this.height / 2)? (y + this.height / 2): flip(y, this.height); // % this.height; | ||
const xZZ = (y & 1)? x: flip(x, this.width); //horiz ZZ | ||
this.nodes2D[/*this.upper.X +*/ xZZ][/*this.upper.Y +*/ ydir] = numpx++; | ||
++numpx; | ||
} | ||
numpx += 13 - pad; | ||
} | ||
|
||
/* | ||
/upper: L2R2LB2T ZZ | ||
for (let y = 0; y < this.upper.H; ++y) //upper third | ||
for (let x = 0; x < this.upper.W; ++x) | ||
{ | ||
const xZZ = (y & 1)? x: flip(x, this.upper.W); //horiz ZZ | ||
this.nodes2D[this.upper.X + xZZ][this.upper.Y + y] = numpx++; | ||
} | ||
//middle: L2R2L outward from middle ZZ | ||
for (let y = 0; y < this.middle.H; ++y) //middle | ||
for (let x = 0; x < this.middle.W; ++x) | ||
{ | ||
const youtward = (y < this.middle.H / 2)? y + this.middle.H / 2: flip(y, this.middle.H); | ||
const xZZ = (y & 1)? flip(x, this.middle.W): x; //horiz ZZ | ||
this.nodes2D[this.middle.X + xZZ][this.middle.Y + youtward] = numpx++; | ||
} | ||
//lower: L2R2LT2B ZZ | ||
for (let y = 0; y < this.lower.H; ++y) //lower half | ||
for (let x = 0; x < this.lower.W; ++x) | ||
{ | ||
const yflip = flip(y, this.lower.H); | ||
const xZZ = (yflip & 1)? x: flip(x, this.lower.W); //horiz ZZ | ||
this.nodes2D[this.lower.X + xZZ][this.lower.Y + yflip] = numpx++; | ||
} | ||
*/ | ||
|
||
assert(numpx == this.width * this.height, `numpx ${numpx} != ${this.width * this.height}`.brightRed); //check all nodes mapped | ||
assert(numpx == this.num_wired, `numpx ${numpx} != #wired ${this.num_wired}`); | ||
return numpx; | ||
}, | ||
get numpx_OLD() | ||
{ | ||
let numpx = 0; | ||
//upper: B2TL2R2L ZZ | ||
for (let y = this.height / 2; y < this.height; ++y) //upper half | ||
for (let x = 0; x < this.width; ++x) | ||
{ | ||
const xZZ = !(y & 1)? x: flip(x, this.width); //horiz ZZ | ||
this.nodes2D[xZZ][y] = numpx++; | ||
} | ||
//lower: T2BL2R2L ZZ | ||
for (let y = 0; y < this.height / 2; ++y) //lower half | ||
for (let x = 0; x < this.width; ++x) | ||
{ | ||
const yflip = flip(y, this.height / 2); | ||
const xZZ = (yflip & 1)? x: flip(x, this.width); //horiz ZZ | ||
this.nodes2D[xZZ][yflip] = numpx++; | ||
} | ||
|
||
assert(numpx == this.width * this.height, `numpx ${numpx} != ${this.width * this.height}`.brightRed); //check all nodes mapped | ||
return numpx; | ||
}, | ||
}), opts || {}); } | ||
if (!module.parent) setImmediate(async () => await module.exports.gdoor.unit_test()); //unit-test; run after inline init | ||
|
||
|
||
function my_exports(things) { return Object.assign(module.exports, things); } //{[entpt.name]: entpt}); } | ||
|
||
//eof |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#!/usr/bin/env node | ||
//ESOL bow | ||
|
||
"use strict"; //find bugs + typos easier | ||
//imports(); //hoist | ||
const assert = require('assert').strict; //https://nodejs.org/api/assert.html; CAUTION: SLOW; don't use in big loops! | ||
const {PAL} = require("../incl/color-mgmt22"); | ||
const {Model, Rect, ZZ, flip} = require("../models/model22"); | ||
const {debug, TODO, srcline, replace_prop} = require("../incl/utils22"); | ||
|
||
|
||
//my_exports({mary: NatFig("Mary: NAT"), joseph: Natfig("Joseph: NAT"), Natfig}); //NOTE: exporting instances + ctor | ||
my_exports({bow: Bow(), Bow}); //NOTE: exporting instances + ctor | ||
|
||
//bow: | ||
function Bow(opts) { return Object.assign(/*{}, opts || {},*/ new Model( | ||
{ | ||
maxbr: 75/100, //for 20A supply | ||
order: "RGB", | ||
name: "Bow: YARD, prop", | ||
WHOOPS: 2, //ended up with a couple extra pixels in middle row of prop :( | ||
get num_wired() { return 5 * 80 + this.WHOOPS; }, | ||
get loop() { const parent = this; return Rect({X: 0, Y: 0, W: 60, H: parent.height}); }, | ||
get tail() { const parent = this; return Rect({X: parent.loop.rightE, Y: parent.loop.Y, W: 20 /*+ parent.WHOOPS*/, H: parent.height}); }, | ||
get width() { return this.loop.W + this.tail.W; }, | ||
height: 5, | ||
draw: function() //default texture | ||
{ | ||
this.fill(PAL.MAGENTA.dim(20)); | ||
}, | ||
get numpx() //CAUTION: nodes must be in wiring order | ||
{ | ||
let numpx = 0; | ||
|
||
//loop L2R2LF2B ZZ | ||
// retval.body = {x: (W - bodyW) / 2, y: 0, w: bodyW, h: bodyH}; | ||
for (let y = 0; y < this.loop.H; ++y) | ||
{ | ||
// for (let x = 0, xshorten = (y != 2)? this.WHOOPS: 0; x < this.loop.W - xshorten; ++x) | ||
for (let x = 0; x < this.loop.W; ++x) | ||
{ | ||
const xZZ = !(y & 1)? flip(x, this.loop.W): x; // - xshorten): x); | ||
// if (xZZ > 1 || y == 2) | ||
this.nodes2D[this.loop.X + xZZ][this.loop.Y + y] = numpx++; | ||
} | ||
if (y == 2) numpx += this.WHOOPS; | ||
} | ||
|
||
//tail L2R2LB2F ZZ | ||
// retval.hood = {x: (W - hoodW) / 2, y: bodyH, w: hoodW, h: hoodH}; | ||
for (let y = 0; y < this.tail.H; ++y) | ||
for (let x = 0; x < this.tail.W; ++x) | ||
{ | ||
const yflip = flip(y, this.tail.H); | ||
const xZZ = (y & 1)? flip(x, this.tail.W): x; | ||
this.nodes2D[this.tail.X + xZZ][this.tail.Y + yflip] = numpx++; | ||
} | ||
|
||
assert(numpx == this.loop.numpx + this.tail.numpx + this.WHOOPS, `numpx ${numpx} != loop ${this.loop.area} + tail ${this.tail.area} + ${this.WHOOPS} = ${this.loop.numpx + this.tail.numpx + this.WHOOPS}`); //check all nodes mapped | ||
assert(numpx == this.num_wired); | ||
return numpx; | ||
}, | ||
}), opts || {}); } | ||
if (!module.parent) setImmediate(async () => await module.exports.bow.unit_test()); //unit-test; run after inline init | ||
|
||
//wisemen[0].csv(); | ||
//run(); | ||
|
||
|
||
function my_exports(things) { return Object.assign(module.exports, things); } //{[entpt.name]: entpt}); } | ||
|
||
//eof |
Oops, something went wrong.