From 0fdb4db1d91fe33531148a2e0811c290a4cca377 Mon Sep 17 00:00:00 2001 From: Robert Kaiser Date: Sat, 2 Apr 2022 02:57:24 +0200 Subject: [PATCH 01/21] add stardate clock --- apps/stardateclock/ChangeLog | 1 + apps/stardateclock/README.md | 23 ++ apps/stardateclock/app-icon.js | 1 + apps/stardateclock/app.js | 362 +++++++++++++++++++++++++++++ apps/stardateclock/app.png | Bin 0 -> 594 bytes apps/stardateclock/metadata.json | 23 ++ apps/stardateclock/screenshot1.png | Bin 0 -> 3431 bytes apps/stardateclock/screenshot2.png | Bin 0 -> 2354 bytes apps/stardateclock/screenshot3.png | Bin 0 -> 4017 bytes apps/stardateclock/screenshot4.png | Bin 0 -> 5287 bytes 10 files changed, 410 insertions(+) create mode 100644 apps/stardateclock/ChangeLog create mode 100644 apps/stardateclock/README.md create mode 100644 apps/stardateclock/app-icon.js create mode 100644 apps/stardateclock/app.js create mode 100644 apps/stardateclock/app.png create mode 100644 apps/stardateclock/metadata.json create mode 100644 apps/stardateclock/screenshot1.png create mode 100644 apps/stardateclock/screenshot2.png create mode 100644 apps/stardateclock/screenshot3.png create mode 100644 apps/stardateclock/screenshot4.png diff --git a/apps/stardateclock/ChangeLog b/apps/stardateclock/ChangeLog new file mode 100644 index 000000000..7ebdc317a --- /dev/null +++ b/apps/stardateclock/ChangeLog @@ -0,0 +1 @@ +1.0: Initial release on the app repository for Bangle.js 1 and 2 diff --git a/apps/stardateclock/README.md b/apps/stardateclock/README.md new file mode 100644 index 000000000..2b5da3a41 --- /dev/null +++ b/apps/stardateclock/README.md @@ -0,0 +1,23 @@ +# Stardate Clock + +A clock face displaying a stardate along with a "standard" digital/analog clock +in LCARS design. + +That design has been made popular by various Star Trek shows. Credits for the +original LCARS designs go to Michael Okuda, copyrights are owned by Paramount Global, +usage of that type of design is permitted freely for non-profit use cases. +The Bangle.js version has been created by Robert Kaiser . + +The stardate concept used leans on the shows released from the late 80s onward +by using 1000 units per Earth year, but to apply this more cleanly, this split +is applied exactly. Also, to give more relationship to the shows and +incidentally make values look similar to those depicted there, the zero point +is set to the first airing of the original 'Star Trek' series in the US on +Thursday, September 8, 1966, at 8:30 p.m. Eastern Time. + +The clock face supports Bangle.js 1 and 2 with some compromises (e.g. the +colors will look best on Bangle.js 1, the font sizes will look best on +Bangle.js 2). + +Any tap on the diaply while unlocked switches the "standard" Earth-style clock +between digital and analog display. diff --git a/apps/stardateclock/app-icon.js b/apps/stardateclock/app-icon.js new file mode 100644 index 000000000..d38013a98 --- /dev/null +++ b/apps/stardateclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgkiAA0gDRwX/C/4X/C5MO9wBDgnkAIMAAQQXKAItehwECAQIXK8gBEIQIeDC5YAF8EAAIIECC48hE4oYCAogXIkQvHDIgCBiQXHiCPFAIaaCgECJBChDAIsOU4RIJbJwwIDIVEABIYBMJAXOAC8SmYAHmHdABJfBCxAXNCpEyRxoWVgETC46+OkYXHRpxGWC5EwBQMBkQDBiK4DKQMBiAXKNQMggQ2CgI7CkcgC5UjicwkYXCgUxmakBC5kCmERC4MiAoMjgMTC50AC4KYCkcAgYXRPgJFBC6YABgYEBC6iQBC6cRgMgL6ikBR4IXOiR3EX4IXPAgTXDBgIXNgUiiClCAAMikIKBC5YAMC64AXogAGoAX/C6w")) \ No newline at end of file diff --git a/apps/stardateclock/app.js b/apps/stardateclock/app.js new file mode 100644 index 000000000..70f1070fc --- /dev/null +++ b/apps/stardateclock/app.js @@ -0,0 +1,362 @@ +// Stardate clock face, by KaiRo.at, 2021-2022 + +var redrawClock = true; +var clockface = "digital"; + +// note: Bangle.js 1 has 240x240x16, 2 has 176x176x3 screen +var bpp = g.getBPP ? g.getBPP() : 16; + +// Load fonts +Graphics.prototype.setFontAntonio27 = function(scale) { + // Actual height 23 (23 - 1) + g.setFontCustom(atob("AAAAAAGAAAAwAAAGAAAAwAAAGAAAAwAAAAAAAAAAAAAAAAAADAAAA4AAAHAAAAAAAAAAAAAAAAAAAAAA4AAB/AAD/4AH/4AP/wAf/gAD/AAAeAAAAAAAAAAAAA///AP//+D///4eAAPDgAA4cAAHD///4P//+A///gAAAAAAAAAAAAAAYAAAHAAAA4AAAOAAAD///4f///D///4AAAAAAAAAAAAAAAAAAAAAAA/gD4P8B/D/g/4cAfzDgP4Yf/8DD/+AYP/ADAGAAAAAAAAAAAAHwD8B+AfwfwD/DgMA4cDgHDgeA4f///B/3/wH8P8AAAAAAAAAAAAOAAAPwAAP+AAP/wAf8OAf4BwD///4f///D///4AABwAAAGAAAAAAAAAAAAAAD/4Pwf/h/D/4P4cMAHDjgA4cf//Dh//4cH/8AAAAAAAAAAAAAAH//8B///wf///Dg4A4cHAHDg4A4f3//B+f/wHh/8AAAAAAAAAAAAAAcAAADgAA4cAD/DgH/4cH//Dv/4Af/gAD/gAAfAAADgAAAAAAAAAAAAH4f8B///wf///Dg8A4cDAHDg8A4f///B///wH8/8AAAAAAAAAAAAAAH/h4B/+Pwf/5/DgHA4cA4HDgHA4f///B///wH//8AAAAAAAAAAAAAAAAAAAHgeAA8DwAHgeAAAAAAAAAA"), 45, atob("CQcKDAsMDAwMDAwMDAc="), 27+(scale<<8)+(1<<16)); +}; +Graphics.prototype.setFontAntonio42 = function(scale) { + // Actual height 36 (36 - 1) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAAAAHgAAAAAHgAAAAAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAfgAAAAH/gAAAB//gAAAf//gAAH//4AAB//+AAAf//gAAH//4AAAf/+AAAAf/gAAAAf4AAAAAeAAAAAAAAAAAAAAAAAAAAAAAAAAAA////gAH////+AP/////Af/////gf/////gfAAAAPgeAAAAHgeAAAAHgfAAAAPgf/////gf/////gP/////AH////+AB////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4AAAAAB4AAAAAB4AAAAADwAAAAAHwAAAAAP/////gf/////gf/////gf/////gf/////gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8AAPgH/8AD/gP/8AP/gP/8A//gf/8B//gfAAH/ngeAAf+HgeAB/4HgfAH/gHgf//+AHgP//4AHgH//wAHgD/+AAHgAPgAAAAAAAAAAAAAAAAAAAAAAAAAA+AAfwAH+AAf+AP+AAf/AP+AAf/Af+AAf/gfADwAPgeADwAHgeADwAHgfAH4APgf///h/gf/////AP/+///AH/+f/+AB/4H/4AAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAA/gAAAAH/gAAAB//gAAAP//gAAB//HgAAf/wHgAD/8AHgAf/AAHgAf/////gf/////gf/////gf/////gf/////gAAAAHgAAAAAHgAAAAAHAAAAAAAAAAAAAAAAAAAAAAAf//gP8Af//gP+Af//gP/Af//gP/gf/+AAfgeB8AAHgeB4AAHgeB8AAHgeB////geB////geA////AeAf//+AAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf///gAD////8AH/////AP/////Af/////gfAPgAfgeAPAAHgeAPAAHgeAPAAHgf+PgAPgf+P///gP+H///AH+H//+AB+B//8AAAAD8AAAAAAAAAAAAAAAAAAAAAAAeAAAAAAeAAAAAAeAAAAPgeAAAP/geAAD//geAA///geAH///geB///+AeP//4AAe//8AAAf//AAAAf/wAAAAf+AAAAAfwAAAAAeAAAAAAAAAAAAAAAAAAAAAAAAAAAB/wH/4AH/8f/+AP/////Af/////gf/////geAH4APgeADgAHgeADgAHgeAHwAHgf/////gf/////gP/////AH/8//+AB/wH/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//gPgAH//4P+AP//8P/Af//+P/AfwB+P/geAAeAPgeAAeAHgeAAeAHgfAAeAPgf/////gP/////AP/////AH////8AA////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4APgAAH4AfgAAH4AfgAAH4AfgAAH4AfgAAD4APgAAAAAAAAAAAAAAA="), 45, atob("DgsPEhESEhISEhISEgo="), 42+(scale<<8)+(1<<16)); +}; +const fontName = "Antonio27"; +const fontNameLarge = "Antonio42"; +const fontSize = 1; +const fontSizeLarge = 1; +const fontHeightLarge = 42 * fontSizeLarge; + +// LCARS dimensions +if (g.getWidth() < 200) { // Bangle.js 2 + const baseUnit1 = 3; + const baseUnit2 = 2; + const baseUnit3 = 7; +} +else { + const baseUnit1 = 5; + const baseUnit2 = 3; + const baseUnit3 = 10; +} +const widgetsHeight = 24; +const sbarWid = baseUnit3 * 5; +const hbarHt = baseUnit1; +const outRad = baseUnit1 * 5; +const inRad = outRad - hbarHt; +const gap = baseUnit2; +const divisionPos = baseUnit3 * 8; +const sbarGapPos = baseUnit3 * 15; +const lowerTop = divisionPos+gap+1; + +// Star Trek famously premiered on Thursday, September 8, 1966, at 8:30 p.m. +// See http://www.startrek.com/article/what-if-the-original-star-trek-had-debuted-on-friday-nights +const gSDBase = new Date("September 8, 1966 20:30:00 EST"); +const sdatePosBottom = divisionPos - hbarHt - 1; +const sdatePosRight = g.getWidth() - baseUnit2; +const sdateDecimals = 1; +const secondsPerYear = 86400 * 365.2425; +const sdateDecFactor = Math.pow(10, sdateDecimals); + +const clockAreaLeft = sbarWid + inRad / 2; +const clockAreaTop = lowerTop + hbarHt + inRad / 2; +const clockWid = g.getWidth() - clockAreaLeft; +const clockHt = g.getHeight() - clockAreaTop; + +const ctimePosTop = clockAreaTop + baseUnit1 * 5; +const ctimePosCenter = clockAreaLeft + clockWid / 2; +const cdatePosTop = ctimePosTop + fontHeightLarge; +const cdatePosCenter = clockAreaLeft + clockWid / 2; + +const clockCtrX = Math.floor(clockAreaLeft + clockWid / 2); +const clockCtrY = Math.floor(clockAreaTop + clockHt / 2); +const analogRad = Math.floor(Math.min(clockWid, clockHt) / 2); + +const analogMainLineLength = baseUnit1 * 2; +const analogSubLineLength = baseUnit1; + +const analogHourHandLength = analogRad / 2; +const analogMinuteHandLength = analogRad - analogMainLineLength / 2; + +const colorBg = "#000000"; +const colorTime = "#9C9CFF"; +const colorDate = "#A09090"; +const colorStardate = "#FFCF00"; +// On low-bpp devices (Bangle.js 2), use basic colors for analog clock. +const colorHours = bpp > 3 ? "#9C9CFF" : "#00FF00"; +const colorSeconds = bpp > 3 ? "#E7ADE7" : "#FFFF00"; +const colorHands = bpp > 3 ? "#A09090" : "#00FFFF"; +const colorLCARSGray = "#A09090"; +const colorLCARSOrange = "#FF9F00"; +const colorLCARSPink = "#E7ADE7"; +const colorLCARSPurple = "#A06060"; +const colorLCARSBrown = "#C09070"; +// More colors: teal #008484, yellow FFCF00, purple #6050B0 + +var lastSDateString; +var lastTimeStringToMin; +var lastTimeStringSec; +var lastDateString; +var lastAnalogDate; + +function updateStardate() { + var curDate = new Date(); + + // Note that the millisecond division and the 1000-unit multiplier cancel each other out. + var sdateval = (curDate - gSDBase) / secondsPerYear; + + var sdatestring = (Math.floor(sdateval * sdateDecFactor) / sdateDecFactor).toFixed(sdateDecimals); + + // Reset the state of the graphics library. + g.reset(); + g.setBgColor(colorBg); + // Set Font + g.setFont(fontName, fontSize); + if (lastSDateString) { + // Clear the area where we want to draw the time. + //g.setBgColor("#FF6600"); // for debugging + g.clearRect(sdatePosRight - g.stringWidth(lastSDateString) - 1, + sdatePosBottom - g.getFontHeight(), + sdatePosRight, + sdatePosBottom); + } + // Draw the current stardate. + g.setColor(colorStardate); + g.setFontAlign(1, 1, 0); // Align following string to bottom right. + g.drawString(sdatestring, sdatePosRight, sdatePosBottom); + lastSDateString = sdatestring; + + // Schedule next when an update to the last decimal is due. + var mstonextUpdate = (Math.ceil(sdateval * sdateDecFactor) / sdateDecFactor - sdateval) * secondsPerYear; + if (redrawClock) { + setTimeout(updateStardate, mstonextUpdate); + } +} + +function updateConventionalTime() { + var curDate = new Date(); + + if (clockface == "digital") { + drawDigitalClock(curDate); + } + else { + drawAnalogClock(curDate); + } + + // Schedule next when an update to the last second is due. + var mstonextUpdate = Math.ceil(curDate / 1000) * 1000 - curDate; + if (redrawClock) { + setTimeout(updateConventionalTime, mstonextUpdate); + } +} + +function drawDigitalClock(curDate) { + var timestringToMin = ("0" + curDate.getHours()).substr(-2) + ":" + + ("0" + curDate.getMinutes()).substr(-2) + ":"; + var timestringSec = ("0" + curDate.getSeconds()).substr(-2); + var datestring = "" + curDate.getFullYear() + "-" + + ("0" + (curDate.getMonth() + 1)).substr(-2) + "-" + + ("0" + curDate.getDate()).substr(-2); + + // Reset the state of the graphics library. + g.reset(); + g.setBgColor(colorBg); + // Set Font + g.setFont(fontNameLarge, fontSizeLarge); + var ctimePosLeft = ctimePosCenter - g.stringWidth("12:34:56") / 2; + if (ctimePosLeft + g.stringWidth("00:00:00") > g.getWidth()) { + ctimePosLeft = g.getWidth() - g.stringWidth("00:00:00"); + } + g.setColor(colorTime); + if (timestringToMin != lastTimeStringToMin) { + if (lastTimeStringToMin) { + // Clear the area where we want to draw the time. + //g.setBgColor("#FF6600"); // for debugging + g.clearRect(ctimePosLeft, + ctimePosTop, + ctimePosLeft + g.stringWidth(lastTimeStringToMin) + 1, + ctimePosTop + g.getFontHeight()); + } + // Draw the current time. + g.drawString(timestringToMin, ctimePosLeft, ctimePosTop); + lastTimeStringToMin = timestringToMin; + } + var ctimePosLeftSec = ctimePosLeft + g.stringWidth(timestringToMin); + if (lastTimeStringSec) { + // Clear the area where we want to draw the seconds. + //g.setBgColor("#FF6600"); // for debugging + g.clearRect(ctimePosLeftSec, + ctimePosTop, + ctimePosLeftSec + g.stringWidth(lastTimeStringSec) + 1, + ctimePosTop + g.getFontHeight()); + } + // Draw the current seconds. + g.drawString(timestringSec, ctimePosLeftSec, ctimePosTop); + lastTimeStringSec = timestringSec; + + if (datestring != lastDateString) { + // Set Font + g.setFont(fontName, fontSize); + var cdatePosLeft = cdatePosCenter - g.stringWidth("1234-56-78") / 2; + if (lastDateString) { + // Clear the area where we want to draw the time. + //g.setBgColor("#FF6600"); // for debugging + g.clearRect(cdatePosLeft, + cdatePosTop, + cdatePosLeft + g.stringWidth(lastDateString) + 1, + cdatePosTop + g.getFontHeight()); + } + // Draw the current date. + g.setColor(colorDate); + //g.setFontAlign(0, -1, 0); // Align following string to bottom right. + g.drawString(datestring, cdatePosLeft, cdatePosTop); + lastDateString = datestring; + } +} + +function drawLine(x1, y1, x2, y2, color) { + g.setColor(color); + // On high-bpp devices, use anti-aliasing. Low-bpp (Bangle.js 2) doesn't clear nicely with AA. + if (bpp > 3 && g.drawLineAA) { + g.drawLineAA(x1, y1, x2, y2); + } + else { + g.drawLine(x1, y1, x2, y2); + } +} + +function clearLine(x1, y1, x2, y2) { + drawLine(x1, y1, x2, y2, colorBg); +} + +function drawAnalogClock(curDate) { + // Reset the state of the graphics library. + g.reset(); + g.setBgColor(colorBg); + // Init variables for drawing any seconds we have not drawn. + // If minute changed, we'll set for the full wheel below. + var firstDrawSecond = lastAnalogDate ? lastAnalogDate.getSeconds() + 1 : curDate.getSeconds(); + var lastDrawSecond = curDate.getSeconds(); + if (!lastAnalogDate || curDate.getMinutes() != lastAnalogDate.getMinutes()) { + // Draw the main hour lines. + //g.setColor("#9C9CFF"); + //g.drawCircle(clockCtrX, clockCtrY, analogRad); + for (let i = 0; i < 60; i = i + 15) { + let edgeX = clockCtrX + analogRad * Math.sin(i * Math.PI / 30); + let edgeY = clockCtrY - analogRad * Math.cos(i * Math.PI / 30); + let innerX = clockCtrX + (analogRad - analogMainLineLength) * Math.sin(i * Math.PI / 30); + let innerY = clockCtrY - (analogRad - analogMainLineLength) * Math.cos(i * Math.PI / 30); + drawLine(edgeX, edgeY, innerX, innerY, colorHours); + } + // Set for drawing the full second wheel. + firstDrawSecond = 0; + lastDrawSecond = 59; + } + // Draw the second wheel, or the parts of it that we haven't done yet. + for (let i = firstDrawSecond; i <= lastDrawSecond; i++) { + let edgeX = clockCtrX + analogRad * Math.sin(i * Math.PI / 30); + let edgeY = clockCtrY - analogRad * Math.cos(i * Math.PI / 30); + let innerX = clockCtrX + (analogRad - analogSubLineLength) * Math.sin(i * Math.PI / 30); + let innerY = clockCtrY - (analogRad - analogSubLineLength) * Math.cos(i * Math.PI / 30); + if (i <= curDate.getSeconds()) { + drawLine(edgeX, edgeY, innerX, innerY, colorSeconds); + } + else if (i % 5 == 0) { + drawLine(edgeX, edgeY, innerX, innerY, colorHours); + } + else { + clearLine(edgeX, edgeY, innerX, innerY); + } + } + if (lastAnalogDate) { + // Clear previous hands. + if (curDate.getMinutes() != lastAnalogDate.getMinutes()) { + // Clear hour hand. + let HhAngle = (lastAnalogDate.getHours() + lastAnalogDate.getMinutes() / 60) * Math.PI / 6; + let HhEdgeX = clockCtrX + analogHourHandLength * Math.sin(HhAngle); + let HhEdgeY = clockCtrY - analogHourHandLength * Math.cos(HhAngle); + clearLine(HhEdgeX, HhEdgeY, clockCtrX, clockCtrY); + // Clear minute hand. + let MhEdgeX = clockCtrX + analogMinuteHandLength * Math.sin(lastAnalogDate.getMinutes() * Math.PI / 30); + let MhEdgeY = clockCtrY - analogMinuteHandLength * Math.cos(lastAnalogDate.getMinutes() * Math.PI / 30); + clearLine(MhEdgeX, MhEdgeY, clockCtrX, clockCtrY); + } + } + if (!lastAnalogDate || curDate.getMinutes() != lastAnalogDate.getMinutes()) { + // Draw hour hand. + let HhAngle = (curDate.getHours() + curDate.getMinutes() / 60) * Math.PI / 6; + let HhEdgeX = clockCtrX + analogHourHandLength * Math.sin(HhAngle); + let HhEdgeY = clockCtrY - analogHourHandLength * Math.cos(HhAngle); + drawLine(HhEdgeX, HhEdgeY, clockCtrX, clockCtrY, colorHands); + // Draw minute hand. + let MhEdgeX = clockCtrX + analogMinuteHandLength * Math.sin(curDate.getMinutes() * Math.PI / 30); + let MhEdgeY = clockCtrY - analogMinuteHandLength * Math.cos(curDate.getMinutes() * Math.PI / 30); + drawLine(MhEdgeX, MhEdgeY, clockCtrX, clockCtrY, colorHands); + } + lastAnalogDate = curDate; +} + +function switchClockface() { + if (clockface == "digital") { + clockface = "analog"; + } + else { + clockface = "digital"; + } + // Clear whole lower area. + g.clearRect(clockAreaLeft,clockAreaTop,g.getWidth(),g.getHeight()); + lastTimeStringToMin = undefined; + lastTimeStringSec = undefined; + lastDateString = undefined; + lastAnalogDate = undefined; +} + +// Clear the screen once, at startup. +g.setBgColor(colorBg); +g.clear(); +// Draw LCARS borders. +// Upper section: rounded corner. +g.setColor(colorLCARSGray); +g.fillCircle(outRad, divisionPos - outRad, outRad); +g.fillRect(outRad, divisionPos - outRad, sbarWid + inRad, divisionPos); +g.fillRect(outRad, divisionPos - hbarHt, sbarWid + outRad, divisionPos); // div bar stub +g.fillRect(0, 0, sbarWid, divisionPos - outRad); // side bar +g.setColor(colorBg); // blocked out areas of corner +g.fillCircle(sbarWid + inRad + 1, divisionPos - hbarHt - inRad - 1, inRad); +g.fillRect(sbarWid + 1, divisionPos - outRad * 2, sbarWid + outRad, divisionPos - hbarHt - inRad); +// upper division bar +g.setColor(colorLCARSPurple); +g.fillRect(sbarWid + outRad + gap + 1, divisionPos - hbarHt, g.getWidth(), divisionPos); +// Lower section: rounded corner. +g.setColor(colorLCARSPink); +g.fillCircle(outRad, lowerTop + outRad, outRad); +g.fillRect(outRad, lowerTop, sbarWid + inRad, lowerTop + outRad); +g.fillRect(outRad, lowerTop, sbarWid + outRad, lowerTop + hbarHt); // div bar stub +g.fillRect(0, lowerTop + outRad, sbarWid, sbarGapPos); // side bar +g.setColor(colorBg); // blocked out areas of corner +g.fillCircle(sbarWid + inRad + 1, lowerTop + hbarHt + inRad + 1, inRad); +g.fillRect(sbarWid + 1, lowerTop + hbarHt + inRad, sbarWid + outRad, lowerTop + outRad * 2); +// lower division bar +g.setColor(colorLCARSOrange); +g.fillRect(sbarWid + outRad + gap + 1, lowerTop, g.getWidth(), lowerTop + hbarHt); +// second color of side bar +g.setColor(colorLCARSBrown); +g.fillRect(0, sbarGapPos + gap + 1, sbarWid, g.getHeight()); +// Draw immediately at first. +updateStardate(); +updateConventionalTime(); +// Make sure widgets can be shown. +//g.setColor("#FF0000"); g.fillRect(0, 0, g.getWidth(), widgetsHeight); // debug +Bangle.loadWidgets(); +Bangle.drawWidgets(); +// Show launcher on button press as usual for a clock face +Bangle.setUI("clock", Bangle.showLauncher); +// Stop updates when LCD is off, restart when on +Bangle.on('lcdPower', on => { + if (on) { + redrawClock = true; + // Draw immediately to kick things off. + updateStardate(); + updateConventionalTime(); + } + else { + redrawClock = false; + } +}); +Bangle.on('touch', button => { + // button == 1 is left, 2 is right + switchClockface(); +}); diff --git a/apps/stardateclock/app.png b/apps/stardateclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..86426721b8492f302a1609de5246bed582b59689 GIT binary patch literal 594 zcmV-Y04Po1Q`WL9dB_KkEu?x$?kx_MMGC zmt+N$Qo#(x=+0(sSP$8=0N_9TPG2j(XcjWYpau}JAh|s$00-iBmPxNJXl@694uAy! zB1*3`OyXe}kgBA1S%D*p2sNXW>6X0jd)QL}07R5D@S-I&j$^Vf zou;W66N!}UQ!?LE5jyAj&08(YY8X8TRegFN4KjZA7!5QnDZAYe*g4P;R zN=PXeL_tK*S|e1xTYR$u0D#No0su2n#LSv4zS)mej4_KIF~-b+@gd6TJjPd)ZaP=< zTI+?~&uplt)_esjku@fZDYt3>tYzH=|B9xoK3e2WTr~in_mxs0qJK?XbqTq~G{$V& zkBAbP{j`Z=d_}3ue$vD-z9J{9_=AbR^Sr9dj2dVitH#JW{=>Px#07*qoM6N<$g0k`Wr2qf` literal 0 HcmV?d00001 diff --git a/apps/stardateclock/metadata.json b/apps/stardateclock/metadata.json new file mode 100644 index 000000000..8be981038 --- /dev/null +++ b/apps/stardateclock/metadata.json @@ -0,0 +1,23 @@ +{ + "id": "stardateclock", + "name":"Stardate Clock", + "shortName":"Stardate Clock", + "description": "A clock displaying a stardate along with a 'standard' digital/analog clock in LCARS design", + "version":"1.0", + "icon": "app.png", + "type":"clock", + "tags": "clock", + "supports": ["BANGLEJS", "BANGLEJS2"], + "allow_emulator": true, + "readme": "README.md", + "storage": [ + {"name": "stardateclock.app.js","url": "app.js"}, + {"name": "stardateclock.img","url": "app-icon.js","evaluate": true} + ], + "screenshots": [ + {"url": "screenshot1.png"}, + {"url": "screenshot2.png"}, + {"url": "screenshot3.png"}, + {"url": "screenshot4.png"} + ] +} diff --git a/apps/stardateclock/screenshot1.png b/apps/stardateclock/screenshot1.png new file mode 100644 index 0000000000000000000000000000000000000000..98bd0cea3f25eccbdeced27f9b765b45ae467d72 GIT binary patch literal 3431 zcmd6q`B&0QAIBB7P_x7}yQPImVq6icBZcy@J*sBqd|EQA5YlfcQaMKsAxc5e2ttOAx~({*IM;4q zM6^lebrk!8NR@xZIIAWJyx%}G?Sa#2$r^et`VT1-El}+uG9LsrgcW7{FV>kxRH`l~ zii}#vZoe!V;ZgM3FRaD}!^?e{A-09%?Zl|sUocR1z0KbYGv9(nWZWzPuIyx>{_N-T zg_k`jpQmF3d$YCm=6g|}_N89J7Iv?f=$aoy(Tq%N;?CFKl@F;RE_6+hXF#}pRVT;B zkAR%3j}0JTT31Nq$DQp7wqpe54{lU@k}TutlIFiY))myo{#%7kN{uM06 zL9)j7W(L}!STH;8DzwIC6EsxwhX|lUJP4@hmpm{yrnOK&TvZR6wfOMK&vT0qs`+21 z;u3}K%XiL1%}=`kaqAstBlAhrU%vc*okCKPCi^l80RhA7791w=vFS|D^;xK)Yw)!U zJNGG*JDCJ?urj3XJ8LYha~|SV8(Wd)$uj_H z93>jYHXL_D56iE(b!p6cY`B~C}tjHGV2x%1MxixOm|tQ-#ohbRK%2K$IaVoESG z3&vcGT~%MJG&5d72Fr-6j7{AT&8sw_W3pg|A*`&C$2$TO;UN6gl4L<vG#1~H4NS*m*3J+`RQt1rnvDGZDl^6oE46@@Hm{5GAhjg zs{orhFH{d%ZPqIw;L9Ja{ET%n)NAJ$2<9qyt9<+lwg6NNQUZ*MUgmz-ErNz~ZA z#cki&BUL(6__-JVosxPBExR@weYYnf`;?#2k9O1U+OCF|>itWWZ}n-51cP!ginb1B z9O(O2-jQ;TtIFy4st?+vzw*PSJ2DoWQx@r;6@vk|MUVXS;Ar5*YUIZE?+b5l8D_)e;dt2O9Z zY-NGXmsnhQ%=F4}3iQ0j*yeyiabS)aby#uH?w4GChU`6sERr5g*5&*Y`LndsLl<dyZf6{eR(*=I$_N8x@0JPrfKdR zzi6;z(^5b{3DwLSqRhgE$y$=Uv>3RBeZE1?bu^nv^!u3>2DfNj!>qIC420XxF>vYw zJZ`--iBz{Y7UFppfDOW>2#ej&m4(6V4u9XJl>_ty&h0o5-@z|?wA5Rkm^=9{TZ8SL z&TFfU>8a8B>0p~*RabXSx;szyuqW~TUjmjS48ShfNp7!oRkQr+@E^KI zE4_F9>xxb#MRz%ew`^$Kf;N?$@%|C-92)jxlj&Mkj3?(Dnr2jP$CMjly)__{8}CL^ zjf*E)a#>dmzxng?Qu-&B13XnD+t>o^XnGsf%giw18}f14VDfG!@TJmpRr~MCC-xnW zmKS#t8hyPrq4fG=(fQrBKKkW2h32)(f(&R=FDCRVw5iemYxH3(a3^<|QT+~gIeql7 zNah)uw0K-G@#-=FjGlb7AF{?is61{;sUBW#&_xaEN}k(GmVrGCA5^)kdWlj3;!i6y zVrUL#hL3AGmb*qOfXPGYSSW!yn+Q z*U)?(c~cRPkndnFQyq`F(U~yhKyU9+2*ME17-Hw8C}*>3iSf;dOTx)lRIiy{H}Z~% z8nd>^ajmwnm@9x6VDp+y-yBEq1X94<*c==$fUGr- zusD_USz%UMnn9bZKduY;con>h`-rkmHYA)XP3ceAIyku6Z-(D0mZ%M9)%6~r3ktK( zL~qmK%AepnTnKHl^?bL*_uxO&8|w_sUu=XjER4Tyl5gm1XxP2p9cfxPp>a|PFt^>S zgq__@th}c!&<9nb(@CxTQ^dDf`}xxRFVHvECVD6ET9)$=U^Ef}{67}W<7nft!ORSd&wLt05$m!C*??%4C9=4r=PN}kfW|^pw>vTf<&wpx+}v@JqxSg* zd$iz>+;qiBY&tzoRp*M@t8DZ8qRbq?Z!7sOaC~(@$nr>_y@HtIx=#| z%qgf*V zl&NWG1!ZLbD$U;?z~{#A?kC3Fr!!V1adORNqsGv4rLV{7P1irxx^vSy64@9tM2*BO z=Nqo}prLl*^BXQc`#|L4{V#?@eBqhop7jy^KS)Ct1A9QC8=IpK5^-dwLzV?c+2amr z{jh`nrRR<{vBnkK!mKSSKAydW?G511nr5}!IB{Z43Ol^f&2pvhxKBF?*d@17zhIE3|72oV4j3l0tTD64iBK=sCH#_jq;rHz zKUqmJI%#i5%im=x?F6dn8yZ@iGC#ecJqgCbQ&rB`p%awCzS@7Zp#6S}b4zqGFLFT6 zTg`l{$n;n*q}QiaCQ%SeZ?#_PM;C^DR+&@jOExbEg}>LNk3Wl}6H+qe5!_k7Y$Y=F zO%3r|J2dtSN@eX8vvT`5!i%JxSn}XEd<n|K(ENVHV3 zG1m&~te7t(E2`d4ylEg)%uV;OT7@u-Pxw&`VduH6S}D@>MB0N+MfYjeMUeW5DDEfU zU=WthwWi%<32;hr1{D=mT#Vg~|AycUt{GhBUI~#k z8u8Or4hlL&c@=iQyHP^(#G6Boe6!(qqj_!z3KxNkXbm2Qmj+uFW6#oY#VG zdSx&rQEP=+YBW3`u)pFc^o%zHzr_u_uyXVo{qt7|!tFTgpw}JJqU-VC2fRXcHimoW z1@3aY<-|gHst3_-yM_r6HQjshmO#BU(khLR2E+PPC&-DOhsi3EsrOmJ@zJ!2iZ-Y* j=X;R5F6jR*<7p&XEk0nX)J=(sB{7?`4yXnTpF95n;O?h% literal 0 HcmV?d00001 diff --git a/apps/stardateclock/screenshot2.png b/apps/stardateclock/screenshot2.png new file mode 100644 index 0000000000000000000000000000000000000000..8a70c3f522117d08bc8c9671bdd6a01eba2a4a5f GIT binary patch literal 2354 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 Nz~0)~s?L&}{7+|NPYwV8 literal 0 HcmV?d00001 diff --git a/apps/stardateclock/screenshot3.png b/apps/stardateclock/screenshot3.png new file mode 100644 index 0000000000000000000000000000000000000000..7acb91d0a6a0abce308ccf2adbf0e81a5f4edabf GIT binary patch literal 4017 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 literal 0 HcmV?d00001 From 6435c684fdedac4f8c4b554bed145940590f82d2 Mon Sep 17 00:00:00 2001 From: Danny <31635744+DDDanny@users.noreply.github.com> Date: Sat, 2 Apr 2022 11:51:59 +0200 Subject: [PATCH 02/21] replaced substr(ing) by slice --- apps/antonclk/app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/antonclk/app.js b/apps/antonclk/app.js index 7b40d8eb5..6197d66aa 100644 --- a/apps/antonclk/app.js +++ b/apps/antonclk/app.js @@ -99,7 +99,7 @@ function updateState() { } function isoStr(date) { - return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).substr(-2) + "-" + ("0" + date.getDate()).substr(-2); + return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).substr(-2); } var calWeekBuffer = [false,false,false]; //buffer tz, date, week no (once calculated until other tz or date is requested) @@ -140,7 +140,7 @@ function draw() { g.setFontAlign(0, 0).setFont("Anton").drawString(timeStr, x, y); // draw time if (secondsScreen) { y += 65; - var secStr = (secondsWithColon ? ":" : "") + ("0" + date.getSeconds()).substr(-2); + var secStr = (secondsWithColon ? ":" : "") + ("0" + date.getSeconds()).slice(-2); if (doColor()) g.setColor(0, 0, 1); g.setFont("AntonSmall"); @@ -193,7 +193,7 @@ function draw() { if (calWeek || weekDay) { var dowcwStr = ""; if (calWeek) - dowcwStr = " #" + ("0" + ISO8601calWeek(date)).substring(-2); + dowcwStr = " #" + ("0" + ISO8601calWeek(date)).slice(-2); if (weekDay) dowcwStr = require("locale").dow(date, calWeek ? 1 : 0) + dowcwStr; //weekDay e.g. Monday or weekDayShort # e.g. Mon #01 else //week #01 From 42c6f3b1b96404e0ef99fbc36453b3eb310a54b5 Mon Sep 17 00:00:00 2001 From: Danny <31635744+DDDanny@users.noreply.github.com> Date: Sat, 2 Apr 2022 11:52:53 +0200 Subject: [PATCH 03/21] replaced substr by slice --- apps/antonclk/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/antonclk/app.js b/apps/antonclk/app.js index 6197d66aa..4b1e71bda 100644 --- a/apps/antonclk/app.js +++ b/apps/antonclk/app.js @@ -99,7 +99,7 @@ function updateState() { } function isoStr(date) { - return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).substr(-2); + return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2); } var calWeekBuffer = [false,false,false]; //buffer tz, date, week no (once calculated until other tz or date is requested) From 290dcfec3b306ea9c704cb39919c8a27171a2a2b Mon Sep 17 00:00:00 2001 From: Danny <31635744+DDDanny@users.noreply.github.com> Date: Sat, 2 Apr 2022 12:05:33 +0200 Subject: [PATCH 04/21] changed to v0.08 --- apps/antonclk/ChangeLog | 3 ++- apps/antonclk/metadata.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/antonclk/ChangeLog b/apps/antonclk/ChangeLog index ac49dcbd7..73a63f7c7 100644 --- a/apps/antonclk/ChangeLog +++ b/apps/antonclk/ChangeLog @@ -8,4 +8,5 @@ 0.06: fixes #1271 - wrong settings name when weekday name and calendar weeknumber are on then display is # week is buffered until date or timezone changes -0.07: align default settings with app.js (otherwise the initial displayed settings will be confusing to users) \ No newline at end of file +0.07: align default settings with app.js (otherwise the initial displayed settings will be confusing to users) +0.08: fixed calendar weeknumber not shortened to two digits \ No newline at end of file diff --git a/apps/antonclk/metadata.json b/apps/antonclk/metadata.json index 4d26dd0c7..c58ee2a1b 100644 --- a/apps/antonclk/metadata.json +++ b/apps/antonclk/metadata.json @@ -1,7 +1,7 @@ { "id": "antonclk", "name": "Anton Clock", - "version": "0.07", + "version": "0.08", "description": "A clock using the bold Anton font, optionally showing seconds and date in ISO-8601 format.", "readme":"README.md", "icon": "app.png", From 6b55faae979849359138854bc858c2c530eef37e Mon Sep 17 00:00:00 2001 From: xxpasixx <62435140+xxpasixx@users.noreply.github.com> Date: Sat, 2 Apr 2022 13:49:14 +0200 Subject: [PATCH 05/21] Add new Icons Add new Icons (Youtube, Twitch, MS TODO, Teams, Snapchat, Signal, Post & DHL, Nina, Lieferando, Kalender, Discord, Corona Warn, Bibel) --- apps/messages/ChangeLog | 1 + apps/messages/app.js | 44 ++++++++++++++++++++++++++++--------- apps/messages/metadata.json | 2 +- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index ec5a85a8b..092a38eb6 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -42,3 +42,4 @@ 0.27: Add 'mark all read' option to popup menu (fix #1624) 0.28: Option to auto-unlock the watch when a new message arrives 0.29: Fix message list overwrites on Bangle.js 1 (fix #1642) +0.30: Add new Icons (Youtube, Twitch, MS TODO, Teams, Snapchat, Signal, Post & DHL, Nina, Lieferando, Kalender, Discord, Corona Warn, Bibel) diff --git a/apps/messages/app.js b/apps/messages/app.js index 6d37b5192..821813108 100644 --- a/apps/messages/app.js +++ b/apps/messages/app.js @@ -82,31 +82,45 @@ function getNegImage() { return atob("FhaBADAAMeAB78AP/4B/fwP4/h/B/P4D//AH/4AP/AAf4AB/gAP/AB/+AP/8B/P4P4fx/A/v4B//AD94AHjAAMA="); } /* -* icons should be 24x24px with 1bpp colors and transparancy +* icons should be 24x24px with 1bpp colors and 'Transparency to Color' +* http://www.espruino.com/Image+Converter */ function getMessageImage(msg) { if (msg.img) return atob(msg.img); var s = (msg.src||"").toLowerCase(); - if (s=="alarm" || s =="alarmclockreceiver") return atob("GBjBAP////8AAAAAAAACAEAHAOAefng5/5wTgcgHAOAOGHAMGDAYGBgYGBgYGBgYGBgYDhgYBxgMATAOAHAHAOADgcAB/4AAfgAAAAAAAAA="); + if (s=="alarm" || s =="alarmclockreceiver") return atob("GBjBAP////8AAAAAAAACAEAHAOAefng5/5wTgcgHAOAOGHAMGDAYGBgYGBgYGBgYGBgYDhgYBxgMATAOAHAHAOADgcAB/4AAfgAAAAAAAAA="); + if (s=="bibel") return atob("GBgBAAAAA//wD//4D//4H//4H/f4H/f4H+P4H4D4H4D4H/f4H/f4H/f4H/f4H/f4H//4H//4H//4GAAAEAAAEAAACAAAB//4AAAA"); if (s=="calendar") return atob("GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgAGB//+B//+B//+B9m2B//+B//+Btm2B//+B//+Btm+B//+B//+A//8AAAAAAAAAAAAA=="); + if (s=="corona-warn") return atob("GBgBAAAAABwAAP+AAf/gA//wB/PwD/PgDzvAHzuAP8EAP8AAPAAAPMAAP8AAH8AAHzsADzuAB/PAB/PgA//wAP/gAH+AAAwAAAAA"); + if (s=="discord") return atob("GBgBAAAAAAAAAAAAAIEABwDgDP8wH//4H//4P//8P//8P//8Pjx8fhh+fzz+f//+f//+e//ePH48HwD4AgBAAAAAAAAAAAAAAAAA"); if (s=="facebook") return getFBIcon(); + if (s=="gmail") return getNotificationImage(); + if (s=="google home") return atob("GBiCAAAAAAAAAAAAAAAAAAAAAoAAAAAACqAAAAAAKqwAAAAAqroAAAACquqAAAAKq+qgAAAqr/qoAACqv/6qAAKq//+qgA6r///qsAqr///6sAqv///6sAqv///6sAqv///6sA6v///6sA6v///qsA6qqqqqsA6qqqqqsA6qqqqqsAP7///vwAAAAAAAAAAAAAAAAA=="); if (s=="hangouts") return atob("FBaBAAH4AH/gD/8B//g//8P//H5n58Y+fGPnxj5+d+fmfj//4//8H//B//gH/4A/8AA+AAHAABgAAAA="); if (s=="home assistant") return atob("FhaBAAAAAADAAAeAAD8AAf4AD/3AfP8D7fwft/D/P8ec572zbzbNsOEhw+AfD8D8P4fw/z/D/P8P8/w/z/AAAAA="); if (s=="instagram") return atob("GBiBAAAAAAAAAAAAAAAAAAP/wAYAYAwAMAgAkAh+EAjDEAiBEAiBEAiBEAiBEAjDEAh+EAgAEAwAMAYAYAP/wAAAAAAAAAAAAAAAAA=="); - if (s=="gmail") return getNotificationImage(); - if (s=="google home") return atob("GBiCAAAAAAAAAAAAAAAAAAAAAoAAAAAACqAAAAAAKqwAAAAAqroAAAACquqAAAAKq+qgAAAqr/qoAACqv/6qAAKq//+qgA6r///qsAqr///6sAqv///6sAqv///6sAqv///6sA6v///6sA6v///qsA6qqqqqsA6qqqqqsA6qqqqqsAP7///vwAAAAAAAAAAAAAAAAA=="); + if (s=="kalender") return atob("GBgBBgBgBQCgff++RQCiRgBiQAACf//+QAACQAACR//iRJkiRIEiR//iRNsiRIEiRJkiR//iRIEiRIEiR//iQAACQAACf//+AAAA"); + if (s=="lieferando") return atob("GBgBABgAAH5wAP9wAf/4A//4B//4D//4H//4P/88fV8+fV4//V4//Vw/HVw4HVw4HBg4HBg4HBg4HDg4Hjw4Hj84Hj44Hj44Hj44"); if (s=="mail") return getNotificationImage(); if (s=="messenger") return getFBIcon(); - if (s=="outlook mail") return getNotificationImage(); + if (s=="nina") return atob("GBgBAAAABAAQCAAICAAIEAAEEgAkJAgSJBwSKRxKSj4pUn8lVP+VVP+VUgAlSgApKQBKJAASJAASEgAkEAAECAAICAAIBAAQAAAA"); + if (s=="outlook mail") return atob("HBwBAAAAAAAAAAAIAAAfwAAP/gAB/+AAP/5/A//v/D/+/8P/7/g+Pv8Dye/gPd74w5znHDnOB8Oc4Pw8nv/Dwe/8Pj7/w//v/D/+/8P/7/gf/gAA/+AAAfwAAACAAAAAAAAAAAA="); if (s=="phone") return atob("FxeBABgAAPgAAfAAB/AAD+AAH+AAP8AAP4AAfgAA/AAA+AAA+AAA+AAB+AAB+AAB+OAB//AB//gB//gA//AA/8AAf4AAPAA="); + if (s=="post & dhl") return atob("GBgBAPgAE/5wMwZ8NgN8NgP4NgP4HgP4HgPwDwfgD//AB/+AAf8AAAAABs7AHcdgG4MwAAAAGESAFESAEkSAEnyAEkSAFESAGETw"); + if (s=="signal") return atob("GBgBAAAAAGwAAQGAAhggCP8QE//AB//oJ//kL//wD//0D//wT//wD//wL//0J//kB//oA//ICf8ABfxgBYBAADoABMAABAAAAAAA"); if (s=="skype") return atob("GhoBB8AAB//AA//+Af//wH//+D///w/8D+P8Afz/DD8/j4/H4fP5/A/+f4B/n/gP5//B+fj8fj4/H8+DB/PwA/x/A/8P///B///gP//4B//8AD/+AAA+AA=="); if (s=="slack") return atob("GBiBAAAAAAAAAABAAAHvAAHvAADvAAAPAB/PMB/veD/veB/mcAAAABzH8B3v+B3v+B3n8AHgAAHuAAHvAAHvAADGAAAAAAAAAAAAAA=="); if (s=="sms message") return getNotificationImage(); - if (s=="threema") return atob("GBjB/4Yx//8AAAAAAAAAAAAAfgAB/4AD/8AH/+AH/+AP//AP2/APw/APw/AHw+AH/+AH/8AH/4AH/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="); - if (s=="twitter") return atob("GhYBAABgAAB+JgA/8cAf/ngH/5+B/8P8f+D///h///4f//+D///g///wD//8B//+AP//gD//wAP/8AB/+AB/+AH//AAf/AAAYAAA"); + if (s=="snapchat") return atob("GBgBAAAAAAAAAH4AAf+AAf+AA//AA//AA//AA//AA//AH//4D//wB//gA//AB//gD//wH//4f//+P//8D//wAf+AAH4AAAAAAAAA"); + if (s=="teams") return atob("GBgBAAAAAAAAAAQAAB4AAD8IAA8cP/M+f/scf/gIeDgAfvvefvvffvvffvvffvvff/vff/veP/PeAA/cAH/AAD+AAD8AAAQAAAAA"); if (s=="telegram") return atob("GBiBAAAAAAAAAAAAAAAAAwAAHwAA/wAD/wAf3gD/Pgf+fh/4/v/z/P/H/D8P/Acf/AM//AF/+AF/+AH/+ADz+ADh+ADAcAAAMAAAAA=="); + if (s=="threema") return atob("GBjB/4Yx//8AAAAAAAAAAAAAfgAB/4AD/8AH/+AH/+AP//AP2/APw/APw/AHw+AH/+AH/8AH/4AH/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="); + if (s=="to do") return atob("GBgBAAAAAAAAAAAwAAB4AAD8AAH+AAP/DAf/Hg//Px/+f7/8///4///wf//gP//AH/+AD/8AB/4AA/wAAfgAAPAAAGAAAAAAAAAA"); + if (s=="twitch") return atob("GBgBH//+P//+P//+eAAGeAAGeAAGeDGGeDOGeDOGeDOGeDOGeDOGeDOGeAAOeAAOeAAcf4/4f5/wf7/gf//Af/+AA/AAA+AAAcAA"); + if (s=="twitter") return atob("GhYBAABgAAB+JgA/8cAf/ngH/5+B/8P8f+D///h///4f//+D///g///wD//8B//+AP//gD//wAP/8AB/+AB/+AH//AAf/AAAYAAA"); if (s=="whatsapp") return atob("GBiBAAB+AAP/wAf/4A//8B//+D///H9//n5//nw//vw///x///5///4///8e//+EP3/APn/wPn/+/j///H//+H//8H//4H//wMB+AA=="); if (s=="wordfeud") return atob("GBgCWqqqqqqlf//////9v//////+v/////++v/////++v8///Lu+v8///L++v8///P/+v8v//P/+v9v//P/+v+fx/P/+v+Pk+P/+v/PN+f/+v/POuv/+v/Ofdv/+v/NvM//+v/I/Y//+v/k/k//+v/i/w//+v/7/6//+v//////+v//////+f//////9Wqqqqqql"); + if (s=="youtube") return atob("GBgBAAAAAAAAAAAAAAAAAf8AH//4P//4P//8P//8P5/8P4/8f4P8f4P8P4/8P5/8P//8P//8P//4H//4Af8AAAAAAAAAAAAAAAAA"); if (msg.id=="music") return atob("FhaBAH//+/////////////h/+AH/4Af/gB/+H3/7/f/v9/+/3/7+f/vB/w8H+Dwf4PD/x/////////////3//+A="); if (msg.id=="back") return getBackImage(); return getNotificationImage(); @@ -115,28 +129,38 @@ function getMessageImageCol(msg,def) { return { // generic colors, using B2-safe colors "alarm": "#fff", - "calendar": "#f00", "mail": "#ff0", "music": "#f0f", "phone": "#0f0", "sms message": "#0ff", // brands, according to https://www.schemecolor.com/?s (picking one for multicolored logos) // all dithered on B2, but we only use the color for the icons. (Could maybe pick the closest 3-bit color for B2?) + "bibel": "#54342c", + "discord": "#738adb", "facebook": "#4267b2", "gmail": "#ea4335", "google home": "#fbbc05", - "home assistant": "#fff", // ha-blue is #41bdf5, but that's the background "hangouts": "#1ba261", + "home assistant": "#fff", // ha-blue is #41bdf5, but that's the background "instagram": "#dd2a7b", + "liferando": "#ee5c00", "messenger": "#0078ff", + "nina": "#e57004", "outlook mail": "#0072c6", + "post & dhl": "#f2c101", + "signal": "#00f", "skype": "#00aff0", "slack": "#e51670", - "threema": "#000", + "snapchat": "#ff0", + "teams": "#464eb8", "telegram": "#0088cc", + "threema": "#000", + "to do": "#3999e5", + "twitch": "#6441A4", "twitter": "#1da1f2", "whatsapp": "#4fce5d", "wordfeud": "#e7d3c7", + "youtube": "#f00", }[(msg.src||"").toLowerCase()]||(def !== undefined?def:g.theme.fg); } diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index edc072714..dfeedaef7 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,7 +1,7 @@ { "id": "messages", "name": "Messages", - "version": "0.29", + "version": "0.30", "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", From 2aac234b42b827de1fb976a11dca3029ec65b9cb Mon Sep 17 00:00:00 2001 From: hughbarney Date: Sat, 2 Apr 2022 14:25:41 +0100 Subject: [PATCH 06/21] Daisy 0.06 changed Steps to STEPS, enahnced contrast when using light theme --- apps/daisy/ChangeLog | 1 + apps/daisy/README.md | 3 ++- apps/daisy/app.js | 25 ++++++++++++++++--------- apps/daisy/metadata.json | 4 ++-- apps/daisy/screenshot_daisy2.jpg | Bin 4775 -> 0 bytes apps/daisy/screenshot_daisy2.png | Bin 0 -> 1246 bytes apps/daisy/screenshot_daisy3.png | Bin 0 -> 3265 bytes 7 files changed, 21 insertions(+), 12 deletions(-) delete mode 100644 apps/daisy/screenshot_daisy2.jpg create mode 100644 apps/daisy/screenshot_daisy2.png create mode 100644 apps/daisy/screenshot_daisy3.png diff --git a/apps/daisy/ChangeLog b/apps/daisy/ChangeLog index 26396b75c..d1778dde9 100644 --- a/apps/daisy/ChangeLog +++ b/apps/daisy/ChangeLog @@ -3,3 +3,4 @@ 0.03: fix metadata.json to allow setting as clock 0.04: added heart rate which is switched on when cycled to it through up/down touch on rhs 0.05: changed text to uppercase, just looks better, removed colons on text +0.06: better contrast for light theme, use fg color of dithered ring color diff --git a/apps/daisy/README.md b/apps/daisy/README.md index 12a55ddfd..491ed697f 100644 --- a/apps/daisy/README.md +++ b/apps/daisy/README.md @@ -28,5 +28,6 @@ See [#1248](https://github.com/espruino/BangleApps/issues/1248) ## Screenshots ![](screenshot_daisy1.png) +![](screenshot_daisy3.png) -It is worth looking at the real thing though as the screenshot does not do it justice. +It is worth looking at the real thing though as the screenshots do not do it justice. diff --git a/apps/daisy/app.js b/apps/daisy/app.js index cf0287616..7c513726f 100644 --- a/apps/daisy/app.js +++ b/apps/daisy/app.js @@ -41,10 +41,17 @@ Graphics.prototype.setFontRoboto20 = function(scale) { }; function assignPalettes() { - // palette for 0-40% - pal1 = new Uint16Array([g.theme.bg, g.toColor(settings.gy), g.toColor(settings.fg), g.toColor("#00f")]); - // palette for 50-100% - pal2 = new Uint16Array([g.theme.bg, g.toColor(settings.fg), g.toColor(settings.gy), g.toColor("#00f")]); + if (g.theme.dark) { + // palette for 0-40% + pal1 = new Uint16Array([g.theme.bg, g.toColor(settings.gy), g.toColor(settings.fg), g.toColor("#00f")]); + // palette for 50-100% + pal2 = new Uint16Array([g.theme.bg, g.toColor(settings.fg), g.toColor(settings.gy), g.toColor("#00f")]); + } else { + // palette for 0-40% + pal1 = new Uint16Array([g.theme.bg, g.theme.fg, g.toColor(settings.fg), g.toColor("#00f")]); + // palette for 50-100% + pal2 = new Uint16Array([g.theme.bg, g.toColor(settings.fg), g.theme.fg, g.toColor("#00f")]); + } } function setSmallFont20() { @@ -109,10 +116,10 @@ function updateSunRiseSunSet(now, lat, lon, line){ const infoData = { ID_DATE: { calc: () => {var d = (new Date()).toString().split(" "); return d[2] + ' ' + d[1] + ' ' + d[3];} }, ID_DAY: { calc: () => {var d = require("locale").dow(new Date()).toLowerCase(); return d[0].toUpperCase() + d.substring(1);} }, - ID_SR: { calc: () => 'Sunrise ' + sunRise }, - ID_SS: { calc: () => 'Sunset ' + sunSet }, - ID_STEP: { calc: () => 'Steps ' + getSteps() }, - ID_BATT: { calc: () => 'Battery ' + E.getBattery() + '%' }, + ID_SR: { calc: () => 'SUNRISE ' + sunRise }, + ID_SS: { calc: () => 'SUNSET ' + sunSet }, + ID_STEP: { calc: () => 'STEPS ' + getSteps() }, + ID_BATT: { calc: () => 'BATTERY ' + E.getBattery() + '%' }, ID_HRM: { calc: () => hrmCurrent } }; @@ -225,7 +232,7 @@ function drawSteps() { setSmallFont(); g.setFontAlign(0,0); g.setColor(g.theme.fg); - g.drawString('Steps ' + getSteps(), w/2, (3*h/4) - 4); + g.drawString('STEPS ' + getSteps(), w/2, (3*h/4) - 4); drawingSteps = false; } diff --git a/apps/daisy/metadata.json b/apps/daisy/metadata.json index 15a24592c..6225db055 100644 --- a/apps/daisy/metadata.json +++ b/apps/daisy/metadata.json @@ -1,13 +1,13 @@ { "id": "daisy", "name": "Daisy", - "version":"0.05", + "version":"0.06", "dependencies": {"mylocation":"app"}, "description": "A clock based on the Pastel clock with large ring guage for steps", "icon": "app.png", "type": "clock", "tags": "clock", "supports" : ["BANGLEJS2"], - "screenshots": [{"url":"screenshot_daisy2.jpg"}], + "screenshots": [{"url":"screenshot_daisy2.png"}], "readme": "README.md", "storage": [ {"name":"daisy.app.js","url":"app.js"}, diff --git a/apps/daisy/screenshot_daisy2.jpg b/apps/daisy/screenshot_daisy2.jpg deleted file mode 100644 index fec6a4c7b82c9dd40f3993017eb3edaa1a457b1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4775 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 diff --git a/apps/daisy/screenshot_daisy2.png b/apps/daisy/screenshot_daisy2.png new file mode 100644 index 0000000000000000000000000000000000000000..3636f376652628060fe0dedd8b4d631bfc44c7f5 GIT binary patch literal 1246 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 Date: Sat, 2 Apr 2022 14:43:10 +0100 Subject: [PATCH 07/21] Daisy 0.06 changed Steps to STEPS, enhanced contrast when using light theme --- apps/daisy/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/daisy/metadata.json b/apps/daisy/metadata.json index 6225db055..85cefeaf2 100644 --- a/apps/daisy/metadata.json +++ b/apps/daisy/metadata.json @@ -7,7 +7,7 @@ "type": "clock", "tags": "clock", "supports" : ["BANGLEJS2"], - "screenshots": [{"url":"screenshot_daisy2.png"}], + "screenshots": [{"url":"screenshot_daisy3.png"}], "readme": "README.md", "storage": [ {"name":"daisy.app.js","url":"app.js"}, From b28478f1d9f087f67923d731181994885f03f96d Mon Sep 17 00:00:00 2001 From: hughbarney Date: Sat, 2 Apr 2022 14:56:54 +0100 Subject: [PATCH 08/21] Daisy 0.06 changed Steps to STEPS, enhanced contrast when using light theme --- apps/daisy/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/daisy/metadata.json b/apps/daisy/metadata.json index 85cefeaf2..5073db603 100644 --- a/apps/daisy/metadata.json +++ b/apps/daisy/metadata.json @@ -2,7 +2,7 @@ "name": "Daisy", "version":"0.06", "dependencies": {"mylocation":"app"}, - "description": "A clock based on the Pastel clock with large ring guage for steps", + "description": "A beautiful digital clock with large ring guage, idle timer and a cyclic information line that includes, day, date, steps, battery, sunrise and sunset times", "icon": "app.png", "type": "clock", "tags": "clock", From 43a052374c4542019785e34fea17d66f45bd43bc Mon Sep 17 00:00:00 2001 From: hughbarney Date: Sat, 2 Apr 2022 15:00:27 +0100 Subject: [PATCH 09/21] Daisy 0.06 changed Steps to STEPS, enhanced contrast when using light theme --- apps/daisy/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/daisy/ChangeLog b/apps/daisy/ChangeLog index d1778dde9..d5844c62b 100644 --- a/apps/daisy/ChangeLog +++ b/apps/daisy/ChangeLog @@ -3,4 +3,4 @@ 0.03: fix metadata.json to allow setting as clock 0.04: added heart rate which is switched on when cycled to it through up/down touch on rhs 0.05: changed text to uppercase, just looks better, removed colons on text -0.06: better contrast for light theme, use fg color of dithered ring color +0.06: better contrast for light theme, use fg color instead of dithered for ring From 6fe1a7e1d94e881ff921de94704099a64b033796 Mon Sep 17 00:00:00 2001 From: marko Date: Sat, 2 Apr 2022 15:59:39 -0400 Subject: [PATCH 10/21] New app 'bee', add game statistics to 'bordle' app. --- apps/bee/README.md | 34 + apps/bee/app-icon.js | 1 + apps/bee/app.png | Bin 0 -> 2145 bytes apps/bee/bee.app.js | 192 + apps/bee/bee_lindex.json | 1 + apps/bee/bee_screenshot.png | Bin 0 -> 1338 bytes apps/bee/bee_words_2of12 | 74578 ++++++++++++++++++++++++++++++++++ apps/bee/metadata.json | 16 + apps/bordle/bordle.app.js | 46 +- 9 files changed, 74861 insertions(+), 7 deletions(-) create mode 100644 apps/bee/README.md create mode 100644 apps/bee/app-icon.js create mode 100644 apps/bee/app.png create mode 100644 apps/bee/bee.app.js create mode 100644 apps/bee/bee_lindex.json create mode 100644 apps/bee/bee_screenshot.png create mode 100644 apps/bee/bee_words_2of12 create mode 100644 apps/bee/metadata.json diff --git a/apps/bee/README.md b/apps/bee/README.md new file mode 100644 index 000000000..1beece1af --- /dev/null +++ b/apps/bee/README.md @@ -0,0 +1,34 @@ + +# Spelling bee game + +Word finding game inspired by the NYT spelling bee. Find as many words with 4 or more letters (must include the +letter at the center of the 'hive'). + + +Usage: + - tap on letters to type out word + - swipe left to delete last letter + - swipe right to enter; the word will turn blue while is being checked against the internal dictionary; once + checked, it will turn red if the word is invalid, does not contain the central letter or has been guessed before or + green if it is a valid word; in the latter case, points will be awarded + - swipe down to shuffle the 6 outer letters + - swipe up to view a list of already guessed words; tap on any of them to return to the regular game. + + +Scoring: +The number of correctly guessed words is displayed on the bottom left, the score on the bottom right. A single point +is awarded for a 4 letter word, or the number of letters if longer. A pangram is a word that contains all 7 letters at +least once and yields an additional 7 points. Each game contains at least one pangram. + + +Technical remarks: +The game uses an internal dictionary consisting of a newline separated list of English words ('bee.words'). The dictionary is fairly +large (~700kB of flash space) and thus requires appropriate space on the watch and will make installing the app somewhat +slow. Because of its size it cannot be compressed (heatshrink needs to hold the compressed/uncompressed data in memory). +In order to make checking for the validity of a guessed word faster, an index file ('bee_lindex.json') is installed with +the app that facilitates faster word lookups. This index file is specific to the dictionary file used. If one were to +replace the dictionary file with a different version (e.g. a different language) the index file has to be regenerated. The easiest +way to do so is to delete (via the Web IDE or the fileman app on the watch) the file 'bee_lindex.json' - it will be regenerated (and saved, +i.e. it only happens once) on app startup automatically, a process that takes roughly 30 seconds. + +![Screenshot](./bee_screenshot.png) diff --git a/apps/bee/app-icon.js b/apps/bee/app-icon.js new file mode 100644 index 000000000..f3bf5dbb2 --- /dev/null +++ b/apps/bee/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AE2JAAIKHnc7DyNPp4vRGAwuBGB4sBAAQvSGIovPFqYvHGAYvDGBYsGGhwvGGIQvEGBQnDMYhkNGBAvOvQABqyRTF5GJr4wLFwQACX6IwLsowJLYMrldVGAQvTsoADGBITD0YvDldPF6n+F4gyGGAdP5nMF4KKBGDJZDGI7EBcoOiGAK7DGAQvYRogxEr1Pp9VMAiSBBILBWeJIxCromBMAQwDAAZfTGBQyCxOCGAIvBGIV/F7AwMAAOIp95GAYACFqoyQMAIwGF7QADEQd5FgIADqvGF8DnEAAIvFGIWjF8CFE0QwHAAQudAAK0EGBQuecw3GqpemYIxiCGIa8cF4wwHdTwvJp9/F82jGA9VMQovf5jkHGIwvg4wvIAAgvg5miF9wwNF8QABF9QwF0YuoF4oxCqoulGBAAB42i0QvjGBPMF0gwIFswwHF1IA/AH4A/AH4AL")) diff --git a/apps/bee/app.png b/apps/bee/app.png new file mode 100644 index 0000000000000000000000000000000000000000..ed16c44b17415aba02d261f0a2b607713201f147 GIT binary patch literal 2145 zcmV-n2%h(eP)Wa%1m3q4yG15t;Mn9*n%jcZND%+5bH=Cs(m=LHV;Hh0tzBfAWDSr2!Vt=xJm9g z_ng%aF-XGA&5gNEXFB=MoDXO3|61$6_C9CtwKoi77{eF_!0oTA`M-!Ou{xir32y*y z0A2`NzSTd!PTHgKO8yj@FD`#Z<(aa(lYW7Sepx|F=FRiBb~fFlDz_utBtw%;8DNNx^Hbwc-cdR{?~gkR7GCxTn!pPboq@NJ1K(|gB9JS!giYDM7AG0apI(9 zMQ#I*09B&;ftq|^y4Hs;R_tyWR005NYr3{7a(ygL#8q~kayfaf&*Gyr7{2h-ckW1U z?Q8SYlKYn;y0&k7IBfAr-QhOZ3QdS6xG!S=1Aw^3BS0h;$72Yy#+u}(8@)$F$ad|( zFZ=SJT)a3H(I=XkTlo7s?^3p{hPtCCP*wbXANiL~ZnR``*4pFmfFRtt2@p^L41)S1^Bml6i(En>g^sR_05myP>&=^uaX>mE!>~N+-aop}? zE=d-yA8!)$o;UY-A}znUr?{xhvgK`Hb#_|Q4*{|=(;1VMah}+4x{199Kk0cbT~)ep zL_!h(C@_-lye!>lEXXjN$!P|cBnzYbf+{qGTn;uX4IvlHffS!Gcf3hfP(U@5_2xr! zTqxOjVAOtqtkkm@;v&G+Gp3P~opnCWk@}NFA`U>hVSB%oump}k#5BZb7-9xILVA+H zxDshx#@b5N79?T+XLwJuRP&2iRPeZ386v!_1s~007f8m^EV> zb7sw8!nm243YkG+(kO!|874umaJ=2+=-Ro~wMjBU4%V+x3$%x43`sLg}x&~E2&VS_b z?b_ws2#oL7p+L|pqy>b4M`*WQ%(3~TU3xif`?eW7K2EBickSs+L(~|Tb&8pJ2T4zE zLshUMKJ3Wn<(crFVNklIYFB40O#|)&eewK0O}0YTdVxCzV`n=MX+FmORd+FCN^AMU zch{9f7bq9r5@bbOJqidZ%@zxOxksxq@V?G6o0&0TU|&T(66%>KZ`| zQvjT<5W63p2f!71t(D6b)Xj~mLHLo(4gc{gO&}T`xcTZke*ehcH6D+f)6@3i-*Weq z?MS~IF%Z*4BVW`U8L9UBEAFiwJ37sp*xQpXmm93##uGDPr>F%bMZa?*^7Qm6?I$u) zt<0YGsT0qQ-tvCdNylX*uG`C|Gi;9kXH}MW$No|8`8*sQHPW^NJ~dF@e(XhOXFPEe zG6Rcln7u?rp9Q!wzqR70chwbN*njv~u;sD!d0us8z>Nv$^tf*R3tM;8#}j+VGjMlt z(KvxO5xf8m&4ILe*PM=cJnHM=q@~z_{M?SS+xMhJ6bZ!kDC=LUta&xw_;K$8{X3AA z2*I9rRZ^eYIO)T_yn;#XV^%FaAQ_|Vz5RRBzb1{eA0ABnA$>yKXW8aPgp|HY?!Wcu zj=5Jh7e=$&eK4i=FO}I%#~PC|ElUg)4jQ7bOe(K=Z6&zTZ2H5H5_o*k^luzG8vIv3 z-JMJBtUGXZL2ImXz{U0CNJ*&S%W4?XC$wT=ZLZ(z9_^<)Y29mI%iml+W?RhoVn^N3 z;>C~>F#YbBTZ>Pf?w240H&=|ku5@id)rm8KBhfjM6SX}~4DBa&<=p&hPhFLk64@P# z*4XTuy?ou&am&|Tw!Qp=jOwni`9+bY8jN8&Acpi0Xr=FaAa9&$^`0($y1;Q&qTNtL zgY7Z&xXvvFE_Bd$#B=<-ajJ(_fA zV0!-;@=mOk{#sx%z~SQ~4nDqqa?o+4-*USTj&G=_9uIu!yVN0XWQd%f{z*BZ{I$#W zC8dsxRL5njtY-+~ArT2UyZ~4|uPMoq%yp%Ei|(0U|E_6h^p&R@Exv$p(Y?@Mk&t3e zEB(&{Kfb74vA2DcQN6irj5M|R^7Mk6W)JeCBqo9Kk(n6QN5CbqXs6EjKWhzn zyIR}Kvcd-&A528-gdJ$KJW!0GTL51y8n6a$_*XKAm}lL1kMM|4O0dcyv4Is)-$>VGLs!|7Z9w XLWm}&-3OsD00000NkvXXu0mjfj8ZL+ literal 0 HcmV?d00001 diff --git a/apps/bee/bee.app.js b/apps/bee/bee.app.js new file mode 100644 index 000000000..4989296e0 --- /dev/null +++ b/apps/bee/bee.app.js @@ -0,0 +1,192 @@ + +const S = require("Storage"); +var letters = []; +var letterIdx = []; + +var centers = []; + +var word = ''; + +var foundWords = []; +var score = 0; + +var intervalID = -1; + +function prepareLetterIdx () { + "compile" + var li = [0]; + if (S.read("bee_lindex.json")!==undefined) li = S.readJSON("bee_lindex.json"); // check for cached index + else { + for (var i=1; i<26; ++i) { + var prefix = String.fromCharCode(97+i%26); + console.log(prefix); + li.push(words.indexOf("\n"+prefix, li[i-1])+1); + } + li.push(words.length); + S.writeJSON("bee_lindex.json", li); + } + for (var i=0; i<26; ++i) letterIdx[i] = S.read("bee.words", li[i], li[i+1]-li[i]); +} + +function findWord (w) { + "compile" + var ci = w.charCodeAt(0)-97; + var f = letterIdx[ci].indexOf(w); + if (f>=0 && letterIdx[ci][f+w.length]=="\n") return true; + return false; +} + +function isPangram(w) { + var ltrs = ''; + for (var i=0; i=0) return false; // already found + if (findWord(w)) { + foundWords.push(w); + if (w.length==4) score++; + else score += w.length; + if (isPangram(w)) score += 7; + return true; + } + return false; +} + +function getHexPoly(cx, cy, r, a) { + var p = []; + for (var i=0; i<6; ++i) p.push(cx+r*Math.sin((i+a)/3*Math.PI), cy+r*Math.cos((i+a)/3*Math.PI)); + return p; +} + +function drawHive() { + w = g.getWidth(); + h = g.getHeight(); + const R = w/3.3; + centers = getHexPoly(w/2, h/2+10, R, 0); + centers.push(w/2, h/2+10); + g.clear(); + g.setFont("Vector", w/7).setFontAlign(0, 0, 0); + g.setColor(g.theme.fg); + for (var i=0; i<6; ++i) { + g.drawPoly(getHexPoly(centers[2*i], centers[2*i+1], 0.9*R/Math.sqrt(3), 0.5), {closed:true}); + g.drawString(String.fromCharCode(65+letters[i+1]), centers[2*i]+2, centers[2*i+1]+2); + } + g.setColor(1, 1, 0).fillPoly(getHexPoly(w/2, h/2+10, 0.9*R/Math.sqrt(3), 0.5)); + g.setColor(0).drawString(String.fromCharCode(65+letters[0]), w/2+2, h/2+10+2); +} + +function shuffleLetters(qAll) { + for (var i=letters.length-1; i > 0; i--) { + var j = (1-qAll) + Math.floor(Math.random()*(i+qAll)); + var temp = letters[i]; + letters[i] = letters[j]; + letters[j] = temp; + } +} + +function pickLetters() { + var ltrs = ""; + while (ltrs.length!==7) { + ltrs = []; + var j = Math.floor(26*Math.random()); + var i = Math.floor((letterIdx[j].length-10)*Math.random()); + while (letterIdx[j][i]!="\n" && i0) { + word = word.slice(0, -1); + drawWord(g.theme.fg); + } + if (d==1 && word.length>=4) { + drawWord("#00f"); + drawWord((checkWord(word.toLowerCase()) ? "#0f0" : "#f00")); + if (intervalID===-1) intervalID = setInterval(wordFound, 800); + } + if (e===1) { + shuffleLetters(0); + drawHive(); + drawScore(); + drawWord(g.theme.fg); + } + if (e===-1 && foundWords.length>0) showWordList(); +} + +function showWordList() { + Bangle.removeListener("touch", touchHandler); + Bangle.removeListener("swipe", swipeHandler); + E.showScroller({ + h : 20, c : foundWords.length, + draw : (idx, r) => { + g.clearRect(r.x,r.y,r.x+r.w-1,r.y+r.h-1); + g.setFont("6x8:2").drawString(foundWords[idx].toUpperCase(),r.x+10,r.y+4); + }, + select : (idx) => { + setInterval(()=> { + E.showScroller(); + drawHive(); + drawScore(); + Bangle.on("touch", touchHandler); + Bangle.on("swipe", swipeHandler); + clearInterval(); + }, 100); + } + }); +} + +prepareLetterIdx(); +pickLetters(); +drawHive(); +drawScore(); +Bangle.on("touch", touchHandler); +Bangle.on("swipe", swipeHandler); diff --git a/apps/bee/bee_lindex.json b/apps/bee/bee_lindex.json new file mode 100644 index 000000000..e4fa13037 --- /dev/null +++ b/apps/bee/bee_lindex.json @@ -0,0 +1 @@ +[0,41048,80445,152390,198606,228714,257919,279071,303726,337982,343582,348026,367246,404452,419780,438696,496250,499697,544600,624304,659085,680996,691270,708186,708341,709916,710883] \ No newline at end of file diff --git a/apps/bee/bee_screenshot.png b/apps/bee/bee_screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..cd173b9978f4c906fb63e4957e41793a70da8350 GIT binary patch literal 1338 zcmV-A1;zS_P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00009 zP)t-s00030|NsC00A6}Z?f?J)0b)x>L;?Q-E#3eC00(qQO+^Rh1Of{l24Xi!e*gdk zE=fc|R9M5+nK7>1AP|OOWj9;7cEfy7MH_Z5 z=U_Dk|F3DbK8(yj&uTJI}*LlcS)t}I_#fTL;fk? zs7P=>ssZ%HsSeW>sSc-BB!y{qMGQ(vmi-<~8%e#IST=*5pZQ6h z!{{cguL!65;I*(XPjxu$g8{Z2UI?7J1zj~RWMbV?1deiqw*t(4Y7~aqf$)Oy2DFUu zQir+vIXp2q+m2lbD`Z$%XNFQa!c&A_qQ87aHfUGCbbJWhU2<;;-s>>&DGJwDev*4n@bd)5Wy+p&G zQ|>*%&u;Y9pM#fX_oa2?(u#CxtxK&)3e)V07$fU5eeA9LVNWq!yPfY#3|{NIRRQBZ zs6@FB76FxyzAWyJ8&l5Y+8u4+ZB)4(XWAXjYp_K-hubh zxjTd16k8kc!YT{!*m~H`@)kyfeQ9H*Bul^Iw2n$(+Lq&C0(`xRO*TytAhf z&Ee8FtO(Z_l}{wDBo-D)WxvgI30^XDJ_nzF5&I2s0{&02e=r6B001R)MObuXVRU6W zV{&C-bY%cCFfuYNFf=VNGE^}&Ix{djFg7hPG&(RaZ!PlY0000bbVXQnWMOn=I&E)c wX=Zr0 && b==2) inp = inp.slice(0,-1); + if (keyStateIdx==6 && b==5) { + wordle.drawStats(); + return; + } layout.input.label = inp; } layout = getKeyLayout(inp); @@ -82,6 +87,7 @@ class Wordle { this.word = this.words.slice(i, i+5).toUpperCase(); } console.log(this.word); + this.stats = require("Storage").readJSON("bordlestats.json") || {'1':0, '2':0, '3':0, '4':0, '5':0, '6':0, 'p':0, 'w':0, 's':0, 'ms':0}; } render(clear) { h = g.getHeight(); @@ -109,7 +115,7 @@ class Wordle { layout = getKeyLayout(""); wordle.render(true); }); - return 3; + return 1; } this.guesses.push(w); this.nGuesses++; @@ -130,13 +136,39 @@ class Wordle { this.guessColors[this.nGuesses].push(col); } if (correct==5) { - E.showAlert("The word is\n"+this.word, "You won in "+(this.nGuesses+1)+" guesses!").then(function(){load();}); - return 1; - } - if (this.nGuesses==5) { - E.showAlert("The word was\n"+this.word, "You lost!").then(function(){load();}); + E.showAlert("The word is\n"+this.word, "You won in "+(this.nGuesses+1)+" guesses!").then(function(){ + wordle.stats['p']++; wordle.stats['w']++; wordle.stats['s']++; wordle.stats[wordle.nGuesses+1]++; + if (wordle.stats['s']>wordle.stats['ms']) wordle.stats['ms'] = wordle.stats['s']; + require("Storage").writeJSON("bordlestats.json", wordle.stats); + wordle.drawStats(); + }); return 2; } + if (this.nGuesses==5) { + E.showAlert("The word was\n"+this.word, "You lost!").then(function(){ + wordle.stats['p']++; wordle.stats['s'] = 0; + require("Storage").writeJSON("bordlestats.json", wordle.stats); + wordle.drawStats(); + }); + return 3; + } + } + drawStats() { + E.showMessage(" ", "Statistics"); + var max = 1; + for (i=1; i<=6; ++i) if (max20 ? 25 : 25+tw, 52+(i-0.5)*(h-52)/6); + } + g.setFontVector((h-40)/9).setColor("#fff").drawString("P:"+this.stats["p"]+" W:"+this.stats["w"]+" S:"+this.stats["s"]+" M:"+this.stats["ms"], 4, 34); + Bangle.setUI(); + Bangle.on("touch", (e) => { load(); }); } } From 5b93e7f6e54f6c2154b63d08cc8b631cf8df77db Mon Sep 17 00:00:00 2001 From: marko Date: Sat, 2 Apr 2022 16:08:21 -0400 Subject: [PATCH 11/21] Edits of README.md, fix small filename bug in app. --- apps/bee/README.md | 12 +++++++----- apps/bee/bee.app.js | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/bee/README.md b/apps/bee/README.md index 1beece1af..f065d45a6 100644 --- a/apps/bee/README.md +++ b/apps/bee/README.md @@ -5,7 +5,8 @@ Word finding game inspired by the NYT spelling bee. Find as many words with 4 or letter at the center of the 'hive'). -Usage: +## Usage + - tap on letters to type out word - swipe left to delete last letter - swipe right to enter; the word will turn blue while is being checked against the internal dictionary; once @@ -15,15 +16,16 @@ Usage: - swipe up to view a list of already guessed words; tap on any of them to return to the regular game. -Scoring: +## Scoring + The number of correctly guessed words is displayed on the bottom left, the score on the bottom right. A single point is awarded for a 4 letter word, or the number of letters if longer. A pangram is a word that contains all 7 letters at least once and yields an additional 7 points. Each game contains at least one pangram. -Technical remarks: -The game uses an internal dictionary consisting of a newline separated list of English words ('bee.words'). The dictionary is fairly -large (~700kB of flash space) and thus requires appropriate space on the watch and will make installing the app somewhat +## Technical remarks +The game uses an internal dictionary consisting of a newline separated list of English words ('bee.words', using the '2of12inf' word list). +The dictionary is fairly large (~700kB of flash space) and thus requires appropriate space on the watch and will make installing the app somewhat slow. Because of its size it cannot be compressed (heatshrink needs to hold the compressed/uncompressed data in memory). In order to make checking for the validity of a guessed word faster, an index file ('bee_lindex.json') is installed with the app that facilitates faster word lookups. This index file is specific to the dictionary file used. If one were to diff --git a/apps/bee/bee.app.js b/apps/bee/bee.app.js index 4989296e0..7be7c83ce 100644 --- a/apps/bee/bee.app.js +++ b/apps/bee/bee.app.js @@ -22,7 +22,7 @@ function prepareLetterIdx () { console.log(prefix); li.push(words.indexOf("\n"+prefix, li[i-1])+1); } - li.push(words.length); + li.push(require("Storage").read('bee.words').length); S.writeJSON("bee_lindex.json", li); } for (var i=0; i<26; ++i) letterIdx[i] = S.read("bee.words", li[i], li[i+1]-li[i]); From c19b876820f0516e577843788910b73569c8ea12 Mon Sep 17 00:00:00 2001 From: marko Date: Sat, 2 Apr 2022 17:23:42 -0400 Subject: [PATCH 12/21] Fix some typos. --- apps/bee/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/bee/README.md b/apps/bee/README.md index f065d45a6..c6461fb8e 100644 --- a/apps/bee/README.md +++ b/apps/bee/README.md @@ -2,16 +2,16 @@ # Spelling bee game Word finding game inspired by the NYT spelling bee. Find as many words with 4 or more letters (must include the -letter at the center of the 'hive'). +letter at the center of the 'hive') as you can. ## Usage - tap on letters to type out word - swipe left to delete last letter - - swipe right to enter; the word will turn blue while is being checked against the internal dictionary; once + - swipe right to enter; the word will turn blue while it is being checked against the internal dictionary; once checked, it will turn red if the word is invalid, does not contain the central letter or has been guessed before or - green if it is a valid word; in the latter case, points will be awarded + will turn green if it is a valid word; in the latter case, points will be awarded - swipe down to shuffle the 6 outer letters - swipe up to view a list of already guessed words; tap on any of them to return to the regular game. @@ -27,7 +27,7 @@ least once and yields an additional 7 points. Each game contains at least one pa The game uses an internal dictionary consisting of a newline separated list of English words ('bee.words', using the '2of12inf' word list). The dictionary is fairly large (~700kB of flash space) and thus requires appropriate space on the watch and will make installing the app somewhat slow. Because of its size it cannot be compressed (heatshrink needs to hold the compressed/uncompressed data in memory). -In order to make checking for the validity of a guessed word faster, an index file ('bee_lindex.json') is installed with +In order to make checking the validity of a guessed word faster an index file ('bee_lindex.json') is installed with the app that facilitates faster word lookups. This index file is specific to the dictionary file used. If one were to replace the dictionary file with a different version (e.g. a different language) the index file has to be regenerated. The easiest way to do so is to delete (via the Web IDE or the fileman app on the watch) the file 'bee_lindex.json' - it will be regenerated (and saved, From 2d042ee380227e7dfe281170346a258e48e8d7a4 Mon Sep 17 00:00:00 2001 From: marko Date: Sat, 2 Apr 2022 17:34:18 -0400 Subject: [PATCH 13/21] Restore word display on return from word list view. --- apps/bee/bee.app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/bee/bee.app.js b/apps/bee/bee.app.js index 7be7c83ce..f0ae5badd 100644 --- a/apps/bee/bee.app.js +++ b/apps/bee/bee.app.js @@ -22,7 +22,7 @@ function prepareLetterIdx () { console.log(prefix); li.push(words.indexOf("\n"+prefix, li[i-1])+1); } - li.push(require("Storage").read('bee.words').length); + li.push(S.read('bee.words').length); S.writeJSON("bee_lindex.json", li); } for (var i=0; i<26; ++i) letterIdx[i] = S.read("bee.words", li[i], li[i+1]-li[i]); @@ -176,6 +176,7 @@ function showWordList() { E.showScroller(); drawHive(); drawScore(); + drawWord(g.theme.fg); Bangle.on("touch", touchHandler); Bangle.on("swipe", swipeHandler); clearInterval(); From 164683fce5e077af0482290f785becf5c4f57d8d Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Sun, 3 Apr 2022 15:51:01 +0200 Subject: [PATCH 14/21] v0.09 added settings menu, removed symbols button, added highscore reset, clockmode optional --- apps/game1024/ChangeLog | 3 +- apps/game1024/app.js | 69 ++++++++++++++++++------------------ apps/game1024/metadata.json | 3 +- apps/game1024/settings.js | 70 +++++++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 37 deletions(-) create mode 100644 apps/game1024/settings.js diff --git a/apps/game1024/ChangeLog b/apps/game1024/ChangeLog index c917bb90c..29838413e 100644 --- a/apps/game1024/ChangeLog +++ b/apps/game1024/ChangeLog @@ -5,4 +5,5 @@ 0.05: Chevron marker on the randomly added square 0.06: Fixed issue 1609 added a message popup state handler to control unwanted screen redraw 0.07: Optimized the mover algorithm for efficiency (work in progress) -0.08: Bug fix at end of the game with victorious splash and glorious orchestra \ No newline at end of file +0.08: Bug fix at end of the game with victorious splash and glorious orchestra +0.09: Added settings menu, removed symbol selection button (*), added highscore reset \ No newline at end of file diff --git a/apps/game1024/app.js b/apps/game1024/app.js index 13430ff2d..a70db76c8 100644 --- a/apps/game1024/app.js +++ b/apps/game1024/app.js @@ -1,7 +1,21 @@ -const debugMode = 'off'; // valid values are: off, test, production, development +let settings = Object.assign({ + // default values + maxUndoLevels: 4, + charIndex: 0, + clockMode: true, + debugMode: false, +}, require('Storage').readJSON("game1024.settings.json", true) || {}); + +const clockMode = settings.clockMode!==undefined ? settings.clockMode : true; +const debugMode = settings.debugMode!==undefined ? settings.debugMode : false; // #settings -- valid values are: true or false +const maxUndoLevels = settings.maxUndoLevels!==undefined ? settings.maxUndoLevels : 4; // #settings +const charIndex = settings.charIndex!==undefined ? settings.charIndex : 0; // #settings -- plain numbers on the grid + +delete settings; // remove unneeded settings from memory + const middle = {x:Math.floor(g.getWidth()/2)-20, y: Math.floor(g.getHeight()/2)}; -const rows = 4, cols = 4; -const borderWidth = 6; +const rows = 4, cols = 4; // #settings +const borderWidth = 6; const sqWidth = (Math.floor(Bangle.appRect.w - 48) / rows) - borderWidth; const cellColors = [{bg:'#00FFFF', fg: '#000000'}, {bg:'#FF00FF', fg: '#000000'}, {bg:'#808000', fg: '#FFFFFF'}, {bg:'#0000FF', fg: '#FFFFFF'}, {bg:'#008000', fg: '#FFFFFF'}, @@ -13,12 +27,8 @@ const cellChars = [ ['0','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], ['0','I', 'II', 'III', 'IV', 'V', 'VI', 'VII','VIII', 'IX', 'X'] ]; -// const numInitialCells = 2; -const maxUndoLevels = 4; -const noExceptions = true; -let charIndex = 0; // plain numbers on the grid -const themeBg = g.theme.bg; +const themeBg = g.theme.bg; const scores = { currentScore: 0, @@ -78,12 +88,12 @@ const snapshot = { updCounter: function() { this.counter = ++this.counter > this.interval ? 0 : this.counter; }, - dump: {gridsize: rows * cols, expVals: [], score: 0, highScore: 0, charIndex: charIndex}, + dump: {gridsize: rows * cols, expVals: [], score: 0, highScore: 0}, write: function() { require("Storage").writeJSON(this.snFileName, this.dump); }, read: function () { - let sn = require("Storage").readJSON(this.snFileName, noExceptions); + let sn = require("Storage").readJSON(this.snFileName, true); if ((typeof sn == "undefined") || (sn.gridsize !== rows * cols)) { require("Storage").writeJSON(this.snFileName, this.dump); return false; @@ -101,7 +111,6 @@ const snapshot = { }); this.dump.score = scores.currentScore; this.dump.highScore = scores.highScore; - this.dump.charIndex = charIndex; }, make: function () { this.updCounter(); @@ -118,7 +127,7 @@ const snapshot = { }); scores.currentScore = this.dump.score ? this.dump.score : 0; scores.highScore = this.dump.highScore ? this.dump.highScore : 0 ; - charIndex = this.dump.charIndex ? this.dump.charIndex : 0 ; + if (this.dump.hasOwnProperty('charIndex')) delete this.dump.charIndex; // depricated in v0.09 } }, reset: function () { @@ -129,12 +138,11 @@ const snapshot = { } this.dump.score = 0; this.dump.highScore = scores.highScore; - this.dump.charIndex = charIndex; this.write(); debug(() => console.log("reset D U M P E D!", this.dump)); } }; -const btnAtribs = {x: 134, w: 42, h: 42, fg:'#C0C0C0', bg:'#800000'}; +const btnAtribs = {x: 134, w: 42, h: 50, fg:'#C0C0C0', bg:'#800000'}; const buttons = { all: [], draw: function () { @@ -314,7 +322,7 @@ class Cell { } drawBg() { debug(()=>console.log("Drawbg!!")); - if (this.isRndm == true) { + if (this.isRndm) { debug(()=>console.log('Random: (ax)', this.ax)); g.setColor(this.getColor(this.expVal).bg) .fillRect(this.x0, this.y0, this.x1, this.y1) @@ -365,7 +373,7 @@ class Cell { this.isRndm = true; } drawRndmIndicator(){ - if (this.isRndm == true) { + if (this.isRndm) { debug(()=>console.log('Random: (ax)', this.ax)); g.setColor(this.getColor(0).bg) .fillPoly(this.ax,this.ay,this.bx,this.by,this.cx,this.cy); @@ -374,8 +382,9 @@ class Cell { } function undoGame() { - g.clear(); + if (scores.lastScores.length > 0) { + g.clear(); allSquares.forEach(sq => { sq.popFromUndo(); sq.drawBg(); @@ -386,9 +395,9 @@ function undoGame() { buttons.draw(); updUndoLvlIndex(); snapshot.make(); - } - Bangle.loadWidgets(); + Bangle.loadWidgets(); Bangle.drawWidgets(); + } } function addToUndo() { allSquares.forEach(sq => { @@ -487,8 +496,8 @@ function initGame() { drawGrid(); scores.draw(); buttons.draw(); - // Clock mode allows short-press on button to exit - Bangle.setUI("clock"); + // #settings Clock mode allows short-press on button to exit + if(clockMode) Bangle.setUI("clock"); // Load widgets Bangle.loadWidgets(); Bangle.drawWidgets(); @@ -560,14 +569,8 @@ function resetGame() { * @param {function} func function to call like console.log() */ const debug = (func) => { - switch (debugMode) { - case "development": - if (typeof func === 'function') { - func(); - } - break; - case "off": - default: break; + if (debugMode) { + if (typeof func === 'function') func(); } }; @@ -690,13 +693,9 @@ function updUndoLvlIndex() { .drawString(scores.lastScores.length, x, y); } } -function incrCharIndex() { - charIndex++; - if (charIndex >= cellChars.length) charIndex = 0; - drawGrid(); -} + buttons.add(new Button('undo', btnAtribs.x, 25, btnAtribs.w, btnAtribs.h, 'U', btnAtribs.fg, btnAtribs.bg, undoGame, true)); -buttons.add(new Button('chars', btnAtribs.x, 71, btnAtribs.w, 31, '*', btnAtribs.fg, btnAtribs.bg, function(){incrCharIndex();}, true)); + buttons.add(new Button('restart', btnAtribs.x, 106, btnAtribs.w, btnAtribs.h, 'R', btnAtribs.fg, btnAtribs.bg, function(){drawPopUp('Do you want\nto restart?',handlePopUpClicks);}, true)); initGame(); diff --git a/apps/game1024/metadata.json b/apps/game1024/metadata.json index dd350d2b9..e2c4bdb3e 100644 --- a/apps/game1024/metadata.json +++ b/apps/game1024/metadata.json @@ -1,7 +1,7 @@ { "id": "game1024", "name": "1024 Game", "shortName" : "1024 Game", - "version": "0.08", + "version": "0.09", "icon": "game1024.png", "screenshots": [ {"url":"screenshot.png" } ], "readme":"README.md", @@ -12,6 +12,7 @@ "supports" : ["BANGLEJS2"], "storage": [ {"name":"game1024.app.js","url":"app.js"}, + {"name":"game1024.settings.js","url":"settings.js"}, {"name":"game1024.img","url":"app-icon.js","evaluate":true} ] } diff --git a/apps/game1024/settings.js b/apps/game1024/settings.js new file mode 100644 index 000000000..c8e393663 --- /dev/null +++ b/apps/game1024/settings.js @@ -0,0 +1,70 @@ +(function(back) { + var FILE = "game1024.settings.json"; + var scoreFile = "game1024.json"; + // Load settings + var settings = Object.assign({ + maxUndoLevels: 5, + charIndex: 0, + clockMode: true, + debugMode: false, + }, require('Storage').readJSON(FILE, true) || {}); + + function writeSettings() { + require('Storage').writeJSON(FILE, settings); + } + var symbols = ["1 2 3 ...", "A B C ...", "I II III..."]; + var settingsMenu = { + "" : { "title" : "1024 Game" }, + "< Back" : () => back(), + "Symbols": { + value: 0|settings.charIndex, + min:0,max:symbols.length-1, + format: v=>symbols[v], + onchange: v=> { settings.charIndex=v; writeSettings();} + } + , + "Undo levels:": { + value: 0|settings.maxUndoLevels, // 0| converts undefined to 0 + min: 0, max: 9, + onchange: v => { + settings.maxUndoLevels = v; + writeSettings(); + } + }, + "Exit press:": { + value: !settings.debugMode, // ! converts undefined to true + format: v => v?"short":"long", + onchange: v => { + settings.debugMode = v; + writeSettings(); + }, + }, + "Debug mode:": { + value: !!settings.debugMode, // !! converts undefined to false + format: v => v?"On":"Off", + onchange: v => { + settings.debugMode = v; + writeSettings(); + } + }, + "Reset Highscore": () => { + E.showPrompt('Reset Highscore?').then((v) => { + let delay = 50; + if (v) { + delay = 500; + let sF = require("Storage").readJSON(scoreFile, true); + if (typeof sF !== "undefined") { + E.showMessage('Resetting'); + sF.highScore = 0; + require("Storage").writeJSON(scoreFile, sF); + } else { + E.showMessage('No highscore!'); + } + } + setTimeout(() => E.showMenu(settingsMenu), delay); + }); + } + } + // Show the menu + E.showMenu(settingsMenu); + }) \ No newline at end of file From d0c9de691929cdb1182f9174d66f9e3a9ce046c1 Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Sun, 3 Apr 2022 16:55:16 +0200 Subject: [PATCH 15/21] bug fix undoGame levels --- apps/game1024/app.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/game1024/app.js b/apps/game1024/app.js index a70db76c8..a82db4352 100644 --- a/apps/game1024/app.js +++ b/apps/game1024/app.js @@ -383,7 +383,7 @@ class Cell { function undoGame() { - if (scores.lastScores.length > 0) { + if (scores.lastScores.length) { g.clear(); allSquares.forEach(sq => { sq.popFromUndo(); @@ -396,7 +396,7 @@ function undoGame() { updUndoLvlIndex(); snapshot.make(); Bangle.loadWidgets(); - Bangle.drawWidgets(); + Bangle.drawWidgets(); } } function addToUndo() { @@ -516,8 +516,8 @@ function drawPopUp(message,cb) { rDims.x+10, rDims.y2-40 ]); buttons.all.forEach(btn => {btn.disable();}); - const btnYes = new Button('yes', rDims.x+16, rDims.y2-80, 54, btnAtribs.h, 'YES', btnAtribs.fg, btnAtribs.bg, cb, true); - const btnNo = new Button('no', rDims.x2-80, rDims.y2-80, 54, btnAtribs.h, 'NO', btnAtribs.fg, btnAtribs.bg, cb, true); + const btnYes = new Button('yes', rDims.x+16, rDims.y2-88, 54, btnAtribs.h, 'YES', btnAtribs.fg, btnAtribs.bg, cb, true); + const btnNo = new Button('no', rDims.x2-80, rDims.y2-88, 54, btnAtribs.h, 'NO', btnAtribs.fg, btnAtribs.bg, cb, true); btnYes.draw(); btnNo.draw(); g.setColor('#000000'); From 84db9a14fd0d5a48d8954dfaa2586588c80bdd91 Mon Sep 17 00:00:00 2001 From: marko Date: Sun, 3 Apr 2022 21:40:58 -0400 Subject: [PATCH 16/21] Mark pangrams green in word list. --- apps/bee/bee.app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/bee/bee.app.js b/apps/bee/bee.app.js index f0ae5badd..d06177ab3 100644 --- a/apps/bee/bee.app.js +++ b/apps/bee/bee.app.js @@ -168,8 +168,8 @@ function showWordList() { E.showScroller({ h : 20, c : foundWords.length, draw : (idx, r) => { - g.clearRect(r.x,r.y,r.x+r.w-1,r.y+r.h-1); - g.setFont("6x8:2").drawString(foundWords[idx].toUpperCase(),r.x+10,r.y+4); + g.clearRect(r.x,r.y,r.x+r.w-1,r.y+r.h-1).setFont("6x8:2"); + g.setColor(isPangram(foundWords[idx])?'#0f0':g.theme.fg).drawString(foundWords[idx].toUpperCase(),r.x+10,r.y+4); }, select : (idx) => { setInterval(()=> { From 96d77312568d9567230908a278eeedb3d5597411 Mon Sep 17 00:00:00 2001 From: marko Date: Sun, 3 Apr 2022 22:52:07 -0400 Subject: [PATCH 17/21] variable 'words' no longer defined --- apps/bee/bee.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bee/bee.app.js b/apps/bee/bee.app.js index d06177ab3..a12ca7820 100644 --- a/apps/bee/bee.app.js +++ b/apps/bee/bee.app.js @@ -20,7 +20,7 @@ function prepareLetterIdx () { for (var i=1; i<26; ++i) { var prefix = String.fromCharCode(97+i%26); console.log(prefix); - li.push(words.indexOf("\n"+prefix, li[i-1])+1); + li.push(S.read('bee.words').indexOf("\n"+prefix, li[i-1])+1); } li.push(S.read('bee.words').length); S.writeJSON("bee_lindex.json", li); From 4d352b791504607801a743ec156c175706ba4ad0 Mon Sep 17 00:00:00 2001 From: Romek Date: Mon, 4 Apr 2022 09:43:48 +0200 Subject: [PATCH 18/21] Add README.md to metadata.json if exists --- apps/aclock/metadata.json | 1 + apps/berlinc/metadata.json | 1 + apps/calculator/metadata.json | 1 + apps/cliock/metadata.json | 1 + apps/ffcniftyb/metadata.json | 1 + apps/floralclk/metadata.json | 1 + apps/hcclock/metadata.json | 1 + apps/impwclock/metadata.json | 1 + apps/intclock/metadata.json | 1 + apps/intervals/metadata.json | 1 + apps/ios/metadata.json | 1 + apps/numerals/metadata.json | 1 + apps/pipboy/metadata.json | 1 + apps/promenu/metadata.json | 1 + apps/score/metadata.json | 1 + apps/showimg/metadata.json | 1 + apps/sunclock/metadata.json | 1 + apps/supmariodark/metadata.json | 1 + apps/touchmenu/metadata.json | 1 + apps/waveclk/metadata.json | 1 + 20 files changed, 20 insertions(+) diff --git a/apps/aclock/metadata.json b/apps/aclock/metadata.json index c483a4e8c..5e4b4b680 100644 --- a/apps/aclock/metadata.json +++ b/apps/aclock/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"aclock.app.js","url":"clock-analog.js"}, diff --git a/apps/berlinc/metadata.json b/apps/berlinc/metadata.json index 49601cbd3..85c42fc47 100644 --- a/apps/berlinc/metadata.json +++ b/apps/berlinc/metadata.json @@ -7,6 +7,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "screenshots": [{"url":"berlin-clock-screenshot.png"}], "storage": [ diff --git a/apps/calculator/metadata.json b/apps/calculator/metadata.json index 3d1310859..e78e4d54f 100644 --- a/apps/calculator/metadata.json +++ b/apps/calculator/metadata.json @@ -8,6 +8,7 @@ "screenshots": [{"url":"screenshot_calculator.png"}], "tags": "app,tool", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "storage": [ {"name":"calculator.app.js","url":"app.js"}, {"name":"calculator.img","url":"calculator-icon.js","evaluate":true} diff --git a/apps/cliock/metadata.json b/apps/cliock/metadata.json index c5d3fa49e..2df48892e 100644 --- a/apps/cliock/metadata.json +++ b/apps/cliock/metadata.json @@ -9,6 +9,7 @@ "type": "clock", "tags": "clock,cli,command,bash,shell", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"cliock.app.js","url":"app.js"}, diff --git a/apps/ffcniftyb/metadata.json b/apps/ffcniftyb/metadata.json index e4e099a51..73f93ed36 100644 --- a/apps/ffcniftyb/metadata.json +++ b/apps/ffcniftyb/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"ffcniftyb.app.js","url":"app.js"}, diff --git a/apps/floralclk/metadata.json b/apps/floralclk/metadata.json index d4848b0d8..33ab6b8ae 100644 --- a/apps/floralclk/metadata.json +++ b/apps/floralclk/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"floralclk.app.js","url":"app.js"}, diff --git a/apps/hcclock/metadata.json b/apps/hcclock/metadata.json index e372a0a2c..0d4cbe0cd 100644 --- a/apps/hcclock/metadata.json +++ b/apps/hcclock/metadata.json @@ -8,6 +8,7 @@ "tags": "clock", "screenshots": [{"url":"bangle1-high-contrast-clock-screenshot.png"}], "supports": ["BANGLEJS"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"hcclock.app.js","url":"hcclock.app.js"}, diff --git a/apps/impwclock/metadata.json b/apps/impwclock/metadata.json index 120fbe795..733dbb957 100644 --- a/apps/impwclock/metadata.json +++ b/apps/impwclock/metadata.json @@ -7,6 +7,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "screenshots": [{"url":"bangle1-impercise-word-clock-screenshot.png"}], "allow_emulator": true, "storage": [ diff --git a/apps/intclock/metadata.json b/apps/intclock/metadata.json index fff4c58b0..13f596392 100644 --- a/apps/intclock/metadata.json +++ b/apps/intclock/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"intclock.app.js","url":"app.js"}, diff --git a/apps/intervals/metadata.json b/apps/intervals/metadata.json index bc054a539..32c18ae70 100644 --- a/apps/intervals/metadata.json +++ b/apps/intervals/metadata.json @@ -7,6 +7,7 @@ "icon": "intervals.png", "tags": "", "supports": ["BANGLEJS"], + "readme": "README.md", "storage": [ {"name":"intervals.app.js","url":"intervals.app.js"}, {"name":"intervals.img","url":"intervals-icon.js","evaluate":true} diff --git a/apps/ios/metadata.json b/apps/ios/metadata.json index 0083c66b0..eb75a6dbc 100644 --- a/apps/ios/metadata.json +++ b/apps/ios/metadata.json @@ -7,6 +7,7 @@ "tags": "tool,system,ios,apple,messages,notifications", "dependencies": {"messages":"app"}, "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "storage": [ {"name":"ios.app.js","url":"app.js"}, {"name":"ios.img","url":"app-icon.js","evaluate":true}, diff --git a/apps/numerals/metadata.json b/apps/numerals/metadata.json index dcb86da9a..6ba850d86 100644 --- a/apps/numerals/metadata.json +++ b/apps/numerals/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "numerals,clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "screenshots": [{"url":"bangle1-numerals-screenshot.png"}], "storage": [ diff --git a/apps/pipboy/metadata.json b/apps/pipboy/metadata.json index 34a6cb0ac..3dfb94c4a 100644 --- a/apps/pipboy/metadata.json +++ b/apps/pipboy/metadata.json @@ -7,6 +7,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS"], + "readme": "README.md", "allow_emulator": true, "screenshots": [{"url":"bangle1-pipboy-themed-clock-screenshot.png"}], "storage": [ diff --git a/apps/promenu/metadata.json b/apps/promenu/metadata.json index d70f36b0a..443809004 100644 --- a/apps/promenu/metadata.json +++ b/apps/promenu/metadata.json @@ -7,6 +7,7 @@ "type": "boot", "tags": "system", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "screenshots": [{"url":"pro-menu-screenshot.png"}], "storage": [ {"name":"promenu.boot.js","url":"boot.js","supports": ["BANGLEJS"]}, diff --git a/apps/score/metadata.json b/apps/score/metadata.json index fd72e197d..b593d7388 100644 --- a/apps/score/metadata.json +++ b/apps/score/metadata.json @@ -8,6 +8,7 @@ "type": "app", "tags": "", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "storage": [ {"name":"score.app.js","url":"score.app.js"}, {"name":"score.settings.js","url":"score.settings.js"}, diff --git a/apps/showimg/metadata.json b/apps/showimg/metadata.json index d5e44c0ee..e4dbc5738 100644 --- a/apps/showimg/metadata.json +++ b/apps/showimg/metadata.json @@ -7,6 +7,7 @@ "icon": "app.png", "tags": "tool", "supports" : ["BANGLEJS2"], + "readme": "README.md", "storage": [ {"name":"showimg.app.js","url":"app.js"}, {"name":"showimg.img","url":"app-icon.js","evaluate":true} diff --git a/apps/sunclock/metadata.json b/apps/sunclock/metadata.json index a39343992..617d76821 100644 --- a/apps/sunclock/metadata.json +++ b/apps/sunclock/metadata.json @@ -7,6 +7,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"sunclock.app.js","url":"app.js"}, diff --git a/apps/supmariodark/metadata.json b/apps/supmariodark/metadata.json index b56b19735..e5d0861ae 100644 --- a/apps/supmariodark/metadata.json +++ b/apps/supmariodark/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS"], + "readme": "README.md", "storage": [ {"name":"supmariodark.app.js","url":"supmariodark.js"}, {"name":"supmariodark.img","url":"supmariodark-icon.js","evaluate":true}, diff --git a/apps/touchmenu/metadata.json b/apps/touchmenu/metadata.json index 825989d99..5335e9fd6 100644 --- a/apps/touchmenu/metadata.json +++ b/apps/touchmenu/metadata.json @@ -8,6 +8,7 @@ "type": "bootloader", "tags": "tool", "supports": ["BANGLEJS2"], + "readme": "README.md", "storage": [ {"name":"touchmenu.boot.js","url":"touchmenu.boot.js"} ] diff --git a/apps/waveclk/metadata.json b/apps/waveclk/metadata.json index 9ba2798ff..0e9163157 100644 --- a/apps/waveclk/metadata.json +++ b/apps/waveclk/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"waveclk.app.js","url":"app.js"}, From dc1bb3ea35b1d76e4d3a50c086ba7ad90b1b9923 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 4 Apr 2022 09:37:12 +0100 Subject: [PATCH 19/21] bump app version --- apps/bordle/ChangeLog | 2 ++ apps/bordle/metadata.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 apps/bordle/ChangeLog diff --git a/apps/bordle/ChangeLog b/apps/bordle/ChangeLog new file mode 100644 index 000000000..f45509a34 --- /dev/null +++ b/apps/bordle/ChangeLog @@ -0,0 +1,2 @@ +0.01: New App +0.02: app keeps track of statistics now diff --git a/apps/bordle/metadata.json b/apps/bordle/metadata.json index e70effed5..37ef5c855 100644 --- a/apps/bordle/metadata.json +++ b/apps/bordle/metadata.json @@ -2,7 +2,7 @@ "name": "Bordle", "shortName":"Bordle", "icon": "app.png", - "version":"0.01", + "version":"0.02", "description": "Bangle version of a popular word search game", "supports" : ["BANGLEJS2"], "readme": "README.md", From 6948926572c5699cb47f2599866be5f8731ab19a Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Mon, 4 Apr 2022 17:45:06 +0200 Subject: [PATCH 20/21] v0.09 Updated the readme and screenshots --- apps/game1024/README.md | 24 +++++++++++++----- .../game1024_sc_dump_app_settings.png | Bin 0 -> 3623 bytes apps/game1024/game1024_sc_dump_dark.png | Bin 4404 -> 0 bytes apps/game1024/game1024_sc_dump_dark_v0.09.png | Bin 0 -> 3853 bytes apps/game1024/game1024_sc_dump_light.png | Bin 4054 -> 0 bytes .../game1024/game1024_sc_dump_light.v0.09.png | Bin 0 -> 3729 bytes apps/game1024/screenshot.png | Bin 6079 -> 3504 bytes 7 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 apps/game1024/game1024_sc_dump_app_settings.png delete mode 100644 apps/game1024/game1024_sc_dump_dark.png create mode 100644 apps/game1024/game1024_sc_dump_dark_v0.09.png delete mode 100644 apps/game1024/game1024_sc_dump_light.png create mode 100644 apps/game1024/game1024_sc_dump_light.v0.09.png diff --git a/apps/game1024/README.md b/apps/game1024/README.md index 500453145..f72a7ffef 100644 --- a/apps/game1024/README.md +++ b/apps/game1024/README.md @@ -1,7 +1,7 @@ # Play the game of 1024 -Move the tiles by swiping to the lefthand, righthand or up- and downward side of the watch. +Move the tiles by swiping left, righth, up- or downward over the watchface. When two tiles with the same number are squashed together they will add up as exponentials: @@ -21,16 +21,28 @@ Use the side **BTN** to exit the game, score and tile positions will be saved. ## Buttons on the screen - - Button **U**: Undo the last move. There are currently a maximum of 4 undo levels. The level is indicated with a small number in the lower righthand corner of the Undo button - - Button **\***: Change the text on the tile to number, capitals or Roman numbers - - Button **R**: Reset the game. The Higscore will be remembered. You will be prompted first. + - Button **U**: Undo the last move. There are currently a maximum of 9 undo levels. The level is indicated with a small number in the lower righthand corner of the Undo button + - You can set the maximum undo level in the Apps settings menu. + + - Button **R**: Reset the game. The Higscore will be remembered. You will be prompted first. + - The highscore value can be reset in the Apps settings menu. + + Apps setting: ![Screenshot of the apps settings menu](./game1024_sc_dump_app_settings.png) + + - Stuff you can change in de 1024 Game settings: + - Symbols on the cells: numerical, alphabetical or Roman + - Undo levels [0-9] + - Exit: how to exit the game: long or short press + - Debug mode: on or off. This will log all kinds of stuff in the console of the Web IDE + - Reset Highsccore: Tired of looking at the old highscore? Now you can set it to 0 again. ### Credits Game 1024 is based on Saming's 2048 and Misho M. Petkovic 1024game.org and conceptually similar to Threes by Asher Vollmer. In Dark theme with numbers: -![Screenshot from the Banglejs 2 watch with the game in dark theme](./game1024_sc_dump_dark.png) +![Screenshot from the Banglejs 2 watch with the game in dark theme](./game1024_sc_dump_dark_v0.09.png) In Light theme with characters: -![Screenshot from the Banglejs 2 watch with the game in light theme](./game1024_sc_dump_light.png) \ No newline at end of file +![Screenshot from the Banglejs 2 watch with the game in light theme](./game1024_sc_dump_light.v0.09.png) + diff --git a/apps/game1024/game1024_sc_dump_app_settings.png b/apps/game1024/game1024_sc_dump_app_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..6c50898b371cda94ac6cab8edef79999b79d1d3b GIT binary patch literal 3623 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 literal 0 HcmV?d00001 diff --git a/apps/game1024/game1024_sc_dump_light.png b/apps/game1024/game1024_sc_dump_light.png deleted file mode 100644 index 06ada65ac44865e01178d2684c8212e40fd33aed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4054 zcmV;{4=M18P)Px^kV!;ARCr$Po$I!vAPj}4@Bh$emRee*gq?(|y64ZVQxG+5KSRLq`uqF)`^SH@ zz(pegvs<7j;Fz?frrmDz4)-tN#dF-WcQ*llUOL+&Oc9$E zY!>h))>PPj0T;;o5CR9$mfVS$)S-vd_Ykj!VQL>Z7HMh>^kl;F(%qv+5H`L> zg`7B3!D$3s7HOHnScC_mWs&B~dx{r{7z%hu_e&JMiFhT##$xn}S33~wCEm{{=Isr( zbmKomq`xChm3_0IIB@qcT6|Rx2%*J7wG85N8%#IUjgA0#kTxE#Pq> zT3kV|P#Ou`qIWLRhIbH`j&-d8nqJ~1fiEJw7MGcZ%B*3uZ#3XL&b7EAz1)Z;2&`FQ zmKq@bJ00k0J6t->+n)BkqwCd9WTb9K2v=EW;#!B$mLahA>5N}RabyC;3iA;&DXv(a z5gIMNUgy)!#O3N)1stMDo|!h(w<8HG#(@#>a?{5pBBM^176dh0D1&pv=3RXz9Vb4R zVIm_(V2#fk+z5>ieKz*lO~^eUn%CYavGq8QZ2*=ht+oxXIFb7h4=h`Y7A@r2^&!o~ zp&M?|p_1sW4?~MO zq`d+T;!W)*{VqOImM<;!&*hMs)dZGAY7w!Az(}O1JQlNuz(}O1{1gPp2?)3lNTjHo z1b+9>Zm3MKphW23PpyA@5Je%rUr6Vp6{tLRFFXWB0!8Jk3wQ`V8=T~}1h$0WdJx#s zHy#%P5f+t`z>5=DJAm8j^&s%o1#G$gnRQ8EXB^n#BA^Z?fsd5Eo|LcdI56^YQF$C< z^F$$XKCVpC@{Aq{j2}xGjNaMas38Ja%$;YgPXfzs1fvkY z>Tvm_$&M#l0*AB1`Xq2(#65gq%OJ1Dg^*l?+Ax}#$5x_R>yyA^34C<{KbpXnY2+i{ zt9>Re_FdD(@0J0a*9R`Gd9a9A9JEiKN`4H1r5n{Q#{8iDrB}JHIlyA7z)dfGZAc zB(Rpe=>?vm6`H-0*~hei#{zMteR&e69E48WNGVMMdwS*p$5atG@oka0r1)=2=q#~G zU}RpF&#*wc=}>MHqV2lCCNIZ6WShU;_y1fVa-i9SIB3gIVQErFS_{(O?xA1vs{vgz zW8SZeGsjgD_|;jo--jYQ89#X@O3FCYL)7`NDkj^1AU|@aB7rR(Kmz|*tA!6-OYqXb z?{j^!4?LLwB=FofpalRO>Pis|brj-Ixa|9)HF)Uwvrp~!fqUl1Ex8LQ-$IKoQfAtJ z1p=o8H%1{4frIFN>jiOZMeOx~d*;VQK5*~+$lF@y^1!*X{X0;#rpe|}2qaQeUQ1x~ z**Gdc8PnkdqYqb6c^sASL?MuUQ8}{ziUiL3)P5gWCct4FR9+W_KmtYOP{3f15R`cc zm7~l=H3V*A{~BBlJk}itMo%~@M+6YIe)yOM2^5t>0fRk05Mfa{3GB>9nZ}EI5ZET( zO-lAb91&fQRdqO4 z3ab?s^GqHE&lWHV+(Cx^Cd~py1VyhYRNl%5MkYb=+WmM&A&?oDE$>3$CZk{y*c}IM zV*h0&d%m!0A6O#wC<6CNFM1UpxR?DI2WA|2M+KVElQI)A4y=0xkihhT#q6N9tI38O z&p5CYhR*Lm8fMVA7D7kJ-nFU;+$|0{dl09bi7VZ|cJX`7T8Liue}E6%?lU9LOkC3^ zJ3A3rCa_kVntJ>q!{3{30=NA}&OVjwzvax4jySM3aiON3hrqqj0AQ@Av9#wxDTa0LN5DNa++33%Gjgb(X&*~ABE^l0Dcp9*>B=@_aoXy zHt<*ay@t;uFbUi~4xA7;2sGVw;`4hAiAi8z99ZifXzJZH3UMOt4vNFqk5`s?GE&CG zCV@%d_5@Dz{wBN9r!GU)j2&~M)p%e$7FwWDCU$Ych609N@W=|TI50|TEtU82fgjm# zylJlm64DyB3HMbFu*Yf-IA$b)tD+HfAs(Q{fw%aRQC$eBfjhm-67_TGf!>fPed>gPDvgtc92@U=p~MJaIcMHmg6)j%C(D ze6mYs)=1zhlxtkp2kxDpc=iK4{rn#C3aidOQ3h#^M2|S|Yy)Bf_sx$x`~GL2zlMt8 zSZU3}n6(fs?m*dwCklb`PM~s>8ECeErk}rtz`{Op!I%DtQjoy8t-$K?6HgbA^5Jh$ zt+fx_;+nK=T;2!nmYGIt!3Oni7lo)Hs+IiLjRVsMZt(2vO_0EqmaOrCrBmDD$czK0 zc67ymN0K*?ngr%d90@#;!1RGDjW4(mB(TA*c>5Eg*a^q z_U#D@c%mu|r(RaTH8XK7GL%!m1{F=Lx~zav6ame&p>oc|eO1?dHQLB%1fvj)LNE$Z z`3hki_}75bT^Q?(*sS{3C2-%|Y|{l)2?fjHB(TL=nYtbV^NWm1qeq9+2d=cGFAhus zSDO8EI0;;7NfMYouzTi@J}{#YBrpkFWdW`Sc7FZ5#hXcB5|{+8;!l1-HJXWI6r$4T zcaK7}GY?y$1^QWl*(v+k_R=l8q5{_Zz%ABHFgxX?b+*pMTk`|I_sgig0TQ^@f;T;W z1c8I;%(>TMa+AO}Rp98`%4DG|T|%6}J?viOx#VTTXtNj7>^pIe`j?4gO+I~9R!Xhe zJ|eF1g;$LO&+fpd3s@_{Pd#fMU~7Hhf=FN~vB%^mX!7Z+2pqcy+kJ?Cr~AoyNK66? znQ0~~X!7aJ0N&E+7sZ-MdcB>bHd7@DTuI=g+kXG$w~rNcaWfxSOW>|ih}i^~eSVD( z9K@T7Rr+1T+JXW$BbZT$v&p6lcz?gi-H1er%1J?XG2_i-U zMdhmt*lb#BRKZ%GQ3$z9;Bvx@h><{1`RW30L0~w;mb~O({aloSQ3z#z+(g7kps0Lx z0h7Q63#|A>LiX|_5hH=3^3?@Q0^d=<(ZCJ~6qTa%1oUa?1FJLyE5SirLBNtgN#JegsDfolV5m!V1(Sf^;6(yO<*U08E+5#r zwjtO85}Q$oyr$Ixe$XIJ{q!dlt!o>s^?zQ545KlO#@uM$$Mt>O@?o?GPGnSe>9E7O z8Vzmq_t2^28Xwr@%X;$*(}gIw5V}ZNJ#7{Yqt)Nkm=;Lj%Jslax@kcHlfZ_aUD5|0 zMc>U%3kulKeN(HFz$9>Xvu_gE@LZC>zs8#U0xD@EY;dFnDBzLS=DC_%fC6rAQZ_i!0&*0>yE=%+ z?Vr+IW+vd26rE0m{y zr@xb|3%*&dO5lAFSB{Erg671R3VDCcCxreSm$n_qOcE~z_Dd2t7FpKU45CC|$)b|9Rk?iQP@8t+wc>ZIeii8fw3#8VNy_oM{DL(bRnA{ueW1DC! zA&oIqzk^%2B!NX=)SBrI+5!Fg`3o-8K154BP+GvF*{u}IgCjz7B zKpLVc&CJ0#vYHY1tyqjIL?lJg3X9MC(`RC8sVk8}`vfDhqVlJb7TvdXW(~!Owf(tW z7YY1+rVXpy?#ooioi&(oE6(UWVJ6NRpOxxsyAS%>h*&Idw_f`41lFpK^=@f_dqg2f zw01c)Ca1gbl# zLCE;snIONdcftUtanGh69>&Mu>;jFXhjX%bvsW|tsI1DmjF6B2Wq*%CeP)l8cKO{Z zM8gv&e4iysM1Mtb&?N_$n?MKg2(}i>=7F_NhKEHX{8?Xq=F4QqwO&}th%{;3PRC^n zz`H_gB!WTBB%hq&n}=wv2sgl7I%#C5Y6$9ajqt>;F1 zi<9L+72oZwPAy)=YLf0+E_(ou(?(}IXqeDl@H5o~nrmCOm!b5;bl-kmB@p#p_W8~9 z$=Q~)K=Qd7dQVy3c|q|yE_IPpvLg$W zYJELPeaZi7MOc5#bqZ&aS&5o8!Si#h4DdEn+Smse)ze6|u^c&n(baSB#uTc|$Ee-B zIWG%tEQVFe`5y(mkA)1RXnf*81@~L)M84lqR=Ym&_nhv#%H5^d&U4j zxGnuVmOoRmnufDE1iFKeTaofE>nkIyPB_(zB9Pl1M5MN+ z^Fd`FVSdf9_)}GC*jf=5z;pp=Dm*Ahq?vgzP)h&@VIhe((bg(Tz|3U|VRbzqSNw&kGS%ad1cJa@cLPHCh=|`22~s0EB7b}kgA&J65pX0LB@ul- z?%Op2JhhTBVPK+D9=NGt;nd2%72aXg_WbsT(n(3-SSTJUD`31;Zyt)F4@ZzqPWqla zohHQXYv>CJyL_Gz7s7zW-7$=?JvzD2BY$=K?vQR3YN4dEHZ~Lbl?bG(Q5(mMDI5b` zH$xz3-ms%q7DVCEm&DZt&6hE|MX+|ZF;p3aAekwG#`8*U4Fx61osr1h8Z$jesH_+4 z`$Lssj~RU7)4wS z10(hL`fUfkk~Jqp`Pp^oleZhEW2q+UYR+G|kha+kppnN>Zn-EjuYGhJWy$aTfJB}6 z3(}=Z=u@aH4~HUU>LR@^{Gh~e^J>a^%*yMidGS9Glum!x(D9;XAnrf(WA;ivV%4ra zbbGzRXYh2kZV3vw##^ki{pGm~*nZeX~O)X(!AR`rv{a z%||gi{`{NVs^4$o-W%T49^UuXP1GcBI-|`W$OPw;^OClEOj6EcGrzRkr5!FoUeG(t zV^yznjP9*`c{+dtdJEr|{ofQD2a9v)45cnvt>cD@Pnj0x!Mz7O1rp`yX8kAlnevg^ zJ<$v`6y9q;;sx)S$-n;rd%NQ3P<5>czBF9_|C?TW`FxB`p$LH|ELdwzo(tBIR8Zm# z0^vb1uXOK)f6=0r#k|*#;PvvRxnk)IuZUrkqFyD&(jj#c6Jsl%nyh zMMD2|RSVO@&y5mp+XOc4QzcPdNeMG8+I;M{HybuR-BZNkH(A1fgs~_9(HljgW8vo) zdyDLx=~W&400;wA&qFb>^wu1-{ob;H5nCFW7~q+Wb;Bb*mr`Y-J1% z2lCR*J_A5SMVHQcwZ))eM&EXx`yxIyY#=7YrMF-JOO8JGXc{15Gmk5l?ZD55@X?!L z3gucu-8j~t(DFio6{S~wZ~LJ6e-$^>1~Obyo@7XM!g0vG82I=3)}KZ5_D4PJl@c3q zt2GL9f;Mv@r!2`}lL#!jy6=uzzqzCxq9{-sQpK*u0R&eLn01_7P!^xSAg^UP$T%gB z3H&SMWHXe+@&5;*JPiLDeIjW1w+=JTRh}5ba6wX(Kw3Fr%&(Lo-)R6!M5}iQOFR_@ zdj@mc<*ssRB_<;&*Y)M^OFQ{};u@5ozUK!WS-Lri>r3Xd8F{T|UeXA$EzEx|C`lz> z0lsQW82k>)n{INQ5+}sA=FuU7kA<9BVy_x;nO~iL)ey+=;Eu7d2LC$F9>M<{$_+8+ z7hYtb^~UZd{hMaxHzOu_&`TYM{R+%rcn+&l8`E%m(Ixl2iuSO$(xRuC9h0TYLuC!D z_qtMcLfwwXya>Ep@Dzpz1*uz6+H#p)Svo{)sKbljE9F|2BbiEbnMx&Qb0#HI4l#^o zc=Y+`9IL+E)QWfQrIRJ8g(I+;Kf^2vNOhp*o$XnCkJlW~<4AHEEFLWXEsc!K32+yUd-#s_= z_Yh*M>Pb4~qt0AVlo!kLtQta8?zv79xBGzK}) zTJ8#dXAEOSO+X{JOqfFJIf=DvmnwdH7k#7P5=Ai3zjOJLx*2-58@7+O@fmV?18>|w z2^cg@SE(_VJ1#HX^Z0pQa@8@YAz~`EF$Rlj%Si8^>lH+;gULRM+R7-D0Owsqn!xa>>( za($Wwi*hf#C_S(IU1JZ2CX*!A+xF=4Lt7%VKMsqB#erovj_f$Pj7!O+!7DtR4lxVj zg#6L>zwo4z$^y01F@9gTs6KbfY~xRZ8FI#-#2*)MnX?1l#VKnDqrgi>}q=ek=x=?)K9HxHa`9zEJ|t4?I_eJ^IzgE+1A)M&c{ryv&p_J9 z%tL3QP&3)LZC3%Cy%bl$h(cba%Z%0dfK>tXi zKReV1I%Qi5DY#=Zes%8=Uo=YGT;`@ zFJR}#8$!v%%g0AE|9;==dr2GLsx(V>eC;9g_5Po0cO%HVH;=9`I*R|j_Dm2 z-2m;R@!?F;!$`%Uw|fvE%|3lin@?lf%}(uQyuN$zPE9Dy@!5ljL=EKycBtjJ#gABn zqy8#ajIY&*?Q$ zvuP_)LZG+fjeAclH`{M_rd$EBt6%CfFr7%BEOp^YP&L(}WTW#{d)%FkAJ|czS2!uV z!?tdP)@8H-+wK<8m~t2{*$sPA#_$3s>vDR6?(wQxzYG*~Z-v--|MF4H*4q8kvO_*o))gOt4HcNX(Nt2(Bux{n{cGgeMRN2{7CcW((qse)<%wLQU zrP(@9faYS@%nb9kPbr=G{rNjT$J(Vmad^E#BE-hJIl8DIXr7#OrLb|#i?k60RA_T?6U}0O zo5BT!Y=c2=1bJrCd>TdaBLxUxAx9BKV-aq1n4>!v@F<4eAB~VX`2S<5@@zNtAFm(8 z-WD*i?>W6nHr;KQXpFDh+Y6+yw!t5L4-XyOd!gbRbAE3nlnw4V`8*O>tG!L!q`5;6 zBdSFgBBvy|L%Z9stv@Ore-mxWB4s*Kpog&<`Up5LrDKKvzkWeo!;VPOXngj8X9?L9 z$(abMQYN>G6pR8Xx#&P4UD!AP{%?|4wyKA**KC+@wN~474n#q)-6$ff2a**sV zixd+?9w@Hv{3z->o@DpbWAjXJI9#U#0hn~C`-iA3et+2pFiVgXG>MAl<DZllfi_g)>iGyh}4Dh1}&# zp~EZ(>vFeOb&8(9IY{}swmOnw$--;0v{p)4;iS}dGrsLZa?FfOLrTY*vvSxyIR$Yl z{T%amM4CvisEeb57`0#QtUGuX1gvfu#jDt9GReRdbi`e?r2FL~TS{T)=as^=#a<8+ z|2OKHDJg~R2tSF}bhU8`jzh}8t2aL^QgWgmK5i2bk~(_qJV3#bGCbpF8ioam{vcyX zZ0KN{EsEs2eNHa;$&51pk{jjtC7}2m!y}dOljDk&JKH}*vqa5BNR@VGwb2wjmx{0y8$mOyspg$L^^wUlI&Wo zCk(S)E$E-$H+o$F`?g!7q{G@*)puwkM=H$TE7fS!##~cZxgbdW=#mamLwjT?se2AA z;Weu`Wf+{9Y*u4RLg~~Pa*EVqbf;mB-F=$ZQ02Kql?8+N17k!wO*7|1A5T_(ilF92 zp*PQ87Kn@<#k?Rur&>#0Dkl7`H{k{Ca_V%y;+WgcTkYTVYaHI~2Dh&MkPiR)WsWd_IJ*|GG4vzNvm6ev;E!-u_mYj*sIKObSsZG}~6)%5y zz7?(42%hk;TZ~b&YmjOVka@0oPE)mv@h(l&#m3XvP!^G{do5KpJY6J6azT^5%89Zg z>DYeAv7!#3m-w==A^q2wW(2z*mGy=k`p99{NuD{f!h94s1;6{klY)e12a|K5$S(; z;d8ahh@c6Px!Ua(1NfZ2GD48sUGmtRxyQm>))%#;Z;Jz(;nnd8kj{$eTZPRK@M!2R zf(^Z1n*Dwde*AT|sEJ<~s%o7OfvKG84?*l3*<282>|M_V52}|R5%S*G^(}9#YSq5! zpWiocL1|$HnpPZqroXT28k*Ru#lEI#0ZKskSCuqe7)-U3rUvlBMZQ5H- z-xyDn#2tllk6Gxs#Q)tmG9o)TN!p{-U6m zx9nx0)5(gXOKtkMVA_L;p&t%3jh2lCznA|w15=&MxlkHk_H6S3FkXG`NwLqSf1Lf< z`pmz>)IXeqGYQ=})4XoZQ2H%*W|?H~p`4R_8nl(=#a~)o4_bt}v_Zd9^sj+2UiaE_ zT-+gRFO@E#%$t~B@dXzWt1==C@#Ty_2<;JpfPlTK+{Mt(|;pFpvTt2KFItfej zU3euR>zon=UfMN?n*KVmTiCS8H|mNjB<^iptqjN1G#o-yHG9d=CbwmKF93+SCCd3o z(6Cz9g1B31*X6U0_{sVxGeG5{yiabNqF_m_IUZvfyoxUREG&KET8V%nFyvtkzV1&j z{}=f=$LLd{d@OxhVeR|elij^4SE4y_kji81hTX8V{FuoYq`6^F<27+@`^$k;N^OT5 z7d*3m`luC*k}GTN(b*{_v!Q7r?e=^tzi#|Y-k9MkXz9Gp_sUBk4^eeGHz>vU9$J42 z7NziJT!2zs=jMGSJr8$uX%n>Y+_QVMJfra9&?KXPj(h8i%yUVZHA{>ED^~e|GW83o zdxymmAvhQ_aid`;jAJFUlQfn2^#&yW=8D7hqm>B|4lWFqTK|SQGQNtM4jo{&b5Nnn z`DU;65ObwfN_+&`JG;hhjqUM-X#=hk>=*or07T*%4D8 zyF_hBpAttO@vQFnE>m$N6N)?2ipf_%u*!a*xwkc>jp$8fpZ?(hIcz9@gHa0MyE4m% z8W26VV_`r`XPR1jRJE1XB?6{>3C=7QkK^mjmNj89z_<J;6>fi(@&cbX? z?};8MMmpU6Hk+Xa?qlj1V~_XZct_m=OZZ2&2qKd(;tcF#mSHn07}0AfnJVJ_axL(w zrNlc0YG+aZ#DSr^hNl7Ka5U^6kl7t=Z?PhJ9#JR~Bpqs_n5UwFsIvca>f1hZgVM&J zip-r8MQjJ+Whpxh9?IDA^Xnv75U=C;?`!C=dt@95{D!4z^jXs*6baG6jI+(D+(v+n zVr$dSBr*0OmHz4)|5?S@KmzJQF|yjV^_`q-D9mr;xZiAUq@}!(ny|b!N%lnZ)FuCD zd->toVxLbU+(07a5Y=vQO3r|nf}=OJA(a-R9(mFOTEjxOdDXY$Z8fX9HUM~zk z_B??Q^o9UwmxN5b3+>s!=k@wS!=HQ_{a8a|vV@yKo zb*@>-dAL?-@r^n9Ytbl&^$ z$jiqeKQPCRiRG1C>po_F$1QyPn`<6EpG=N#mbuURoLyztF#0&9RNu)Oj|5%z zv@h@tr~@_&*hlLn;%sx>RI-Nz{$L!rXq~HvAU3m6=bK-;*^Q_+6}U&xNq1|!a>DMN zTAvvFaEWkxuM~|4N5%eoRX(ThFzUfQkG9z}11Q!)X`unlz>IR@-^)pAib~zjRKk18 zEj&Tr`YbUIX9Us>71&fJ~Y)ZZHb6e0}o`1mj_uZZRST~&|yV)9XI ztw{|)v=V>z(Y!>6JEN&C&BeTc4fO0E#|)TrF~5^p^^U9W{ag5~>*D2LlWuLX^A$tk zsK0|vqowWyaAeyUKFuW=bFjzr2Q^E$2&P6Lm&tkcZi1`Ic8Xl_yKnd$qVs5Zjsa^S zz3rKjo*}c#O66w@-1X^N=~{?lM!%S8@op!anUogcLgEJ!gC>xJSp!9gJ8sTuIFfyk sk3a%6lz%(&NT?H;g^&aKdKFi96r+Uvu>MqWZm#`0Wno9C#*=RRA2DN;c>n+a literal 6079 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 From 0268fd3592c350e732490d7d05ddefed76e8e710 Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Mon, 4 Apr 2022 17:51:11 +0200 Subject: [PATCH 21/21] Corrected a few typos --- apps/game1024/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/game1024/README.md b/apps/game1024/README.md index f72a7ffef..a25683b68 100644 --- a/apps/game1024/README.md +++ b/apps/game1024/README.md @@ -1,7 +1,7 @@ # Play the game of 1024 -Move the tiles by swiping left, righth, up- or downward over the watchface. +Move the tiles by swiping left, right, up- or downward over the watchface. When two tiles with the same number are squashed together they will add up as exponentials: @@ -24,7 +24,7 @@ Use the side **BTN** to exit the game, score and tile positions will be saved. - Button **U**: Undo the last move. There are currently a maximum of 9 undo levels. The level is indicated with a small number in the lower righthand corner of the Undo button - You can set the maximum undo level in the Apps settings menu. - - Button **R**: Reset the game. The Higscore will be remembered. You will be prompted first. + - Button **R**: Reset the game. The Highscore will be remembered. You will be prompted first. - The highscore value can be reset in the Apps settings menu. Apps setting: ![Screenshot of the apps settings menu](./game1024_sc_dump_app_settings.png)