mirror of https://github.com/espruino/BangleApps
add geiss clock
parent
186f6c6180
commit
993f909335
24
apps.json
24
apps.json
|
@ -269,6 +269,30 @@
|
||||||
{"name":"clock2x3.img","url":"clock2x3-icon.js","evaluate":true}
|
{"name":"clock2x3.img","url":"clock2x3-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{ "id": "geissclk",
|
||||||
|
"name": "Geiss Clock",
|
||||||
|
"icon": "clock.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "7 segment clock with animated background in the style of Ryan Geiss' music visualisation. NOTE: The first run will take ~1 minute to do some precalculation",
|
||||||
|
"tags": "clock",
|
||||||
|
"type":"clock",
|
||||||
|
"storage": [
|
||||||
|
{"name":"geissclk.app.js","url":"clock.js"},
|
||||||
|
{"name":"geissclk.precompute.js","url":"precompute.js"},
|
||||||
|
{"name":"geissclk.img","url":"clock-icon.js","evaluate":true}
|
||||||
|
],
|
||||||
|
"data": [
|
||||||
|
{"name":"geissclk.0.map"},
|
||||||
|
{"name":"geissclk.1.map"},
|
||||||
|
{"name":"geissclk.2.map"},
|
||||||
|
{"name":"geissclk.3.map"},
|
||||||
|
{"name":"geissclk.4.map"},
|
||||||
|
{"name":"geissclk.5.map"},
|
||||||
|
{"name":"geissclk.0.pal"},
|
||||||
|
{"name":"geissclk.1.pal"},
|
||||||
|
{"name":"geissclk.2.pal"}
|
||||||
|
]
|
||||||
|
},
|
||||||
{ "id": "trex",
|
{ "id": "trex",
|
||||||
"name": "T-Rex",
|
"name": "T-Rex",
|
||||||
"icon": "trex.png",
|
"icon": "trex.png",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: New App!
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEw4X/AoMF/3G/2m/wOCmoaKmtAAgVQBYsFoECwALMAA0JBZQABBYIbBBaVUBYMVBYkBIIILDgEKGYUBqkA6oLB6sAlQLDqsAioLBCAOq4AkCqtAivCBYMC1YwDitQgtCwNUhWsOwlUBYVQlWwJAlVgtSxNQFwnwGANBqWFqQuE1QwBqNewtKFwgLBGANWytq2EFWoU6gWBqoLBFwNVYIZZBqtXyurioLF1W1q/W1tVPIIxE1NV72VqpTDDAleEIgADnWq3qgBTIYADvQuBAAVUBYla1XVBYYbDyt632qd40Fqulquq0ALFOwO16t6BYpxBvWX6tW0aoDXwNU1XXNQMD1T7CAwPC1abBegPqFodQdQILCO4hxBlWxq2FoqaFBYOBcYNxQggLCToOBqAwBTgwLCiqoGgtCJ4L0BBYsVBYRmBBY0CwEUJ4IwFBYkVBYsMBYI0CJAwLDAA4L2A="))
|
|
@ -0,0 +1,148 @@
|
||||||
|
var W = 79, H = 64;
|
||||||
|
/*var compiled = E.compiledC(`
|
||||||
|
// void transl(int, int, int )
|
||||||
|
int transl(unsigned char *map, unsigned char *imgfrom, unsigned char *imgto) {
|
||||||
|
int n = 0;
|
||||||
|
const int W = 79;
|
||||||
|
const int H = 64;
|
||||||
|
for (int y=0;y<H;y++)
|
||||||
|
for (int x=0;x<W;x++) {
|
||||||
|
int d = map[n];
|
||||||
|
int nx = (x<<3) + ((d )&0x0F) - 8;
|
||||||
|
int ny = (y<<3) + ((d>>4)&0x0F) - 8;
|
||||||
|
int ax = nx&7;
|
||||||
|
int ay = ny&7;
|
||||||
|
int a = (nx>>3) + ((ny>>3)*W);
|
||||||
|
int c = 0;
|
||||||
|
if (a>=0 && a<(W*H-(W+1))) {
|
||||||
|
c = imgfrom[a]*(8-ax)*(8-ay) +
|
||||||
|
imgfrom[a+1]*(ax)*(8-ay) +
|
||||||
|
imgfrom[a+W]*(8-ax)*(ay) +
|
||||||
|
imgfrom[a+W+1]*(ax)*(ay);
|
||||||
|
c = (c>>6) - 4;
|
||||||
|
if (c<0) c=0;
|
||||||
|
}
|
||||||
|
imgto[n] = c;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`);*/
|
||||||
|
var compiled = (function(){
|
||||||
|
var bin=atob("Len3TwAnT/BPCPsAAJMI+wfzAOsDCdMYAZMAJhn4BkAAnQTwDwMD68YDBesUFAg7CDzdEE/q5AoI+wpaQfJvNapFItgB6woOA/AHAxH4CsCe+AGww/EIBQX7DPwD+wvMnvhPsATwBwQF+wv1ZUPE8QgKCvsMXJ74UFBrQwT7A8SkEQQ8JOrkdADgACQBm5xVATZPLsLRATdAL7bRA7C96PCPAAA=");
|
||||||
|
return {
|
||||||
|
transl:E.nativeCall(1, "void(int, int, int )", bin),
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
require("Font7x11Numeric7Seg").add(Graphics);
|
||||||
|
|
||||||
|
// Allocate the data
|
||||||
|
var dataa = new Uint8Array(W*H);
|
||||||
|
var datab = new Uint8Array(W*H);
|
||||||
|
var map = new Uint8Array(W*H);
|
||||||
|
var pal = new Uint16Array(256);
|
||||||
|
var PALETTES = 3;
|
||||||
|
var MAPS = 6;
|
||||||
|
|
||||||
|
// If we're missing any maps, compute them!
|
||||||
|
(function() {
|
||||||
|
var files = require("Storage").list(/^geissclk/);
|
||||||
|
var allOk = true;
|
||||||
|
for (var n=0;n<PALETTES;n++)
|
||||||
|
if (!files.includes("geissclk."+n+".pal"))
|
||||||
|
allOk = false;
|
||||||
|
for (var n=0;n<MAPS;n++)
|
||||||
|
if (!files.includes("geissclk."+n+".map"))
|
||||||
|
allOk = false;
|
||||||
|
if (!allOk)
|
||||||
|
eval(require("Storage").read("geissclk.precompute.js"));
|
||||||
|
})();
|
||||||
|
|
||||||
|
function randomPalette() {
|
||||||
|
var n = (0|Math.random()*200000) % PALETTES;
|
||||||
|
var p = new Uint8Array(pal.buffer);
|
||||||
|
p.set(require("Storage").readArrayBuffer("geissclk."+n+".pal"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function randomMap() {
|
||||||
|
var n = (0|Math.random()*200000) % MAPS;
|
||||||
|
map.set(require("Storage").readArrayBuffer("geissclk."+n+".map"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
randomPalette();
|
||||||
|
randomMap();
|
||||||
|
|
||||||
|
// Get the address
|
||||||
|
var addra = E.getAddressOf(dataa,true);
|
||||||
|
if (!addra) throw new Error("Not a Flat String");
|
||||||
|
var addrb = E.getAddressOf(datab,true);
|
||||||
|
if (!addrb) throw new Error("Not a Flat String");
|
||||||
|
var addrmap = E.getAddressOf(map,true);
|
||||||
|
if (!addrmap) throw new Error("Not a Flat String");
|
||||||
|
var gfx = Graphics.createArrayBuffer(W,H,8);
|
||||||
|
gfx.buffer = dataa.buffer;
|
||||||
|
|
||||||
|
var im = {
|
||||||
|
width:W, height:H, bpp:8,
|
||||||
|
palette: pal,
|
||||||
|
buffer : dataa.buffer
|
||||||
|
};
|
||||||
|
Bangle.setLCDPower(1);Bangle.setLCDTimeout(0);
|
||||||
|
g.clear();
|
||||||
|
|
||||||
|
|
||||||
|
var lastSeconds = -1;
|
||||||
|
|
||||||
|
function iterate() { "ram"
|
||||||
|
var d = new Date();
|
||||||
|
var time = d.getHours().toString().padStart(2," ")+":"+d.getMinutes().toString().padStart(2,0);
|
||||||
|
var seconds = d.getSeconds().toString().padStart(2,0);
|
||||||
|
t = addra; addra = addrb; addrb = t;
|
||||||
|
t = dataa; dataa = datab; datab = t;
|
||||||
|
if (seconds!=lastSeconds) {
|
||||||
|
lastSeconds = seconds;
|
||||||
|
im.buffer = datab.buffer;
|
||||||
|
gfx.buffer = datab.buffer;
|
||||||
|
} else {
|
||||||
|
im.buffer = dataa.buffer;
|
||||||
|
gfx.buffer = dataa.buffer;
|
||||||
|
}
|
||||||
|
var x,y,n,t = getTime()/10;
|
||||||
|
var amt = 100*Bangle.getAccel().diff;
|
||||||
|
for (var i=0;i<amt;i++) {
|
||||||
|
//x = Math.round((W/2) + 20*Math.sin(t));
|
||||||
|
//y = Math.round((H/2) + 20*Math.cos(t));
|
||||||
|
//t += 0.628;
|
||||||
|
x = 1+(Math.random()*(W-2))|0;
|
||||||
|
y = 1+(Math.random()*(H-2))|0;
|
||||||
|
dataa[x + y*W] = 240;
|
||||||
|
}
|
||||||
|
compiled.transl(addrmap, addra, addrb);
|
||||||
|
|
||||||
|
|
||||||
|
gfx.setFont("7x11Numeric7Seg",2);
|
||||||
|
gfx.drawString(time, -5, 20);
|
||||||
|
gfx.setFont("7x11Numeric7Seg");
|
||||||
|
gfx.drawString(seconds, 62, 30);
|
||||||
|
// firmwares pre-2v09 wouldn't accelerate a 3x blit if it went right to the RHS - hence we're 79px not 80
|
||||||
|
g.drawImage(im,1,24,{scale:3});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Bangle.on('lcdPower',function(on) {
|
||||||
|
if (animInterval) {
|
||||||
|
clearInterval(animInterval);
|
||||||
|
animInterval = undefined;
|
||||||
|
}
|
||||||
|
if (on) {
|
||||||
|
randomMap();
|
||||||
|
randomPalette();
|
||||||
|
iterate();
|
||||||
|
animInterval = setInterval(iterate, 50);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
iterate();
|
||||||
|
animInterval = setInterval(iterate, 50);
|
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,108 @@
|
||||||
|
// PALETTES ---------------------------
|
||||||
|
E.showMessage("Precomputing\npalettes\n\nPlease wait...\n0 / 3");
|
||||||
|
(function() { // fire
|
||||||
|
for (var i=0;i<256;i++) {
|
||||||
|
var r = Math.min(i*6,240);
|
||||||
|
var g = Math.min(i*3,240);
|
||||||
|
var b = E.clip((i-192)*8,0,240);
|
||||||
|
pal[i] = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);
|
||||||
|
}pal[255] = 65535;
|
||||||
|
})()
|
||||||
|
require("Storage").write("geissclk.0.pal",pal.buffer);
|
||||||
|
E.showMessage("Precomputing\npalettes\n\nPlease wait...\n1 / 3");
|
||||||
|
(function() { // gunge
|
||||||
|
for (var i=0;i<256;i++) {
|
||||||
|
var r = 0;
|
||||||
|
var g = Math.min(i*3,255);
|
||||||
|
var b = Math.min(i,255);
|
||||||
|
pal[i] = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);
|
||||||
|
}pal[255] = 65535;
|
||||||
|
})()
|
||||||
|
require("Storage").write("geissclk.1.pal",pal.buffer);
|
||||||
|
E.showMessage("Precomputing\npalettes\n\nPlease wait...\n2 / 3");
|
||||||
|
(function() { // rainbow
|
||||||
|
for (var i=0;i<256;i++) {
|
||||||
|
var cl = E.HSBtoRGB((48+i)/128,1,Math.min(i/16,0.9),true);
|
||||||
|
var r = cl[0];
|
||||||
|
var g = cl[1];
|
||||||
|
var b = cl[2];
|
||||||
|
pal[i] = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);
|
||||||
|
}pal[255] = 65535;pal[255] = 65535;
|
||||||
|
})()
|
||||||
|
require("Storage").write("geissclk.2.pal",pal.buffer);
|
||||||
|
|
||||||
|
|
||||||
|
// MAPS ----------------------------------------------
|
||||||
|
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n0");
|
||||||
|
// straight out
|
||||||
|
(function() { "ram"; var n = 0; for (var y=0;y<H;y++) {
|
||||||
|
for (var x=0;x<W;x++) {
|
||||||
|
var dx = x-(W/2);
|
||||||
|
var dy = y-(H/2);
|
||||||
|
var d = Math.sqrt(dx*dx + dy*dy);
|
||||||
|
var s = -2 + Math.sin(d*0.5);
|
||||||
|
dx = dx*s/d;
|
||||||
|
dy = dy*s/d;
|
||||||
|
map[n++] = ((dx*2 + 8) & 0x0F) | (((dy*2 + 8) & 0x0F)<<4);
|
||||||
|
}
|
||||||
|
}})();
|
||||||
|
require("Storage").write("geissclk.0.map",map);
|
||||||
|
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n1 / 5");
|
||||||
|
// ripple out
|
||||||
|
(function() { "ram"; var n = 0; for (var y=0;y<H;y++) {
|
||||||
|
for (var x=0;x<W;x++) {
|
||||||
|
var dx = x-(W/2);
|
||||||
|
var dy = y-(H/2);
|
||||||
|
var d = Math.sqrt(dx*dx + dy*dy);
|
||||||
|
var s = -2 + Math.sin(d*0.5)/2;
|
||||||
|
dx = dx*s/d;
|
||||||
|
dy = dy*s/d;
|
||||||
|
map[n++] = ((dx*3 + 8) & 0x0F) | (((dy*3 + 8) & 0x0F)<<4);
|
||||||
|
}
|
||||||
|
}})();
|
||||||
|
require("Storage").write("geissclk.1.map",map);
|
||||||
|
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n2 / 5");
|
||||||
|
// twisty outwards
|
||||||
|
(function() { "ram"; var n = 0; for (var y=0;y<H;y++) {
|
||||||
|
for (var x=0;x<W;x++) {
|
||||||
|
var dx = x-(W/2);
|
||||||
|
var dy = y-(H/2);
|
||||||
|
var d = Math.sqrt(dx*dx + dy*dy);
|
||||||
|
dx = (-dx/d) + (((y&7)>3)?0.5:-0.5);
|
||||||
|
dy = (-dy/d) + (((x&7)>3)?0.5:-0.5);
|
||||||
|
map[n++] = ((dx*3 + 8) & 0x0F) | (((dy*3 + 8) & 0x0F)<<4);
|
||||||
|
}
|
||||||
|
}})()
|
||||||
|
require("Storage").write("geissclk.2.map",map);
|
||||||
|
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n3 / 5");
|
||||||
|
// spiral
|
||||||
|
(function() { "ram"; var n = 0; for (var y=0;y<H;y++) {
|
||||||
|
for (var x=0;x<W;x++) {
|
||||||
|
var dx = x-(W/2);
|
||||||
|
var dy = y-(H/2);
|
||||||
|
var d = Math.sqrt(dx*dx + dy*dy);
|
||||||
|
var cx = (2*dy-dx)/(2*d);
|
||||||
|
var cy = (-2*dx-dy)/(2*d);
|
||||||
|
map[n++] = ((cx*3 + 8) & 0x0F) | (((cy*3 + 8) & 0x0F)<<4);
|
||||||
|
}
|
||||||
|
}})();
|
||||||
|
require("Storage").write("geissclk.3.map",map);
|
||||||
|
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n4 / 5");
|
||||||
|
// blur down
|
||||||
|
(function() { "ram"; var n=0; for (var y=0;y<H;y++) {
|
||||||
|
for (var x=0;x<W;x++) {
|
||||||
|
map[n++] = 136 - 6*16 + (y&1)*8-4;
|
||||||
|
}
|
||||||
|
}})()
|
||||||
|
require("Storage").write("geissclk.4.map",map);
|
||||||
|
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n5 / 5");
|
||||||
|
// twisty
|
||||||
|
(function() { "ram"; var n=0; for (var y=0;y<H;y++) {
|
||||||
|
for (var x=0;x<W;x++) {
|
||||||
|
dx = Math.sin(y*0.2);
|
||||||
|
dy = Math.cos(x*0.2);
|
||||||
|
map[n++] = ((dx*6 + 8) & 0x0F) | (((dy*6 + 8) & 0x0F)<<4);
|
||||||
|
}
|
||||||
|
}})()
|
||||||
|
require("Storage").write("geissclk.5.map",map)
|
||||||
|
E.showMessage("Finished!");
|
Loading…
Reference in New Issue