Merge branch 'master' of github.com:espruino/BangleApps
commit
071b2bbf01
36
apps.json
36
apps.json
|
|
@ -384,6 +384,18 @@
|
|||
{"name":"*hrings","url":"hypno-rings-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{ "id": "morse",
|
||||
"name": "Morse Code",
|
||||
"icon": "morse-code.png",
|
||||
"description": "Learn morse code by hearing/seeing/feeling the code. Tap to toggle buzz!",
|
||||
"tags": "morse,sound,visual,input",
|
||||
"type":"app",
|
||||
"storage": [
|
||||
{"name":"+morse","url":"morse-code.json"},
|
||||
{"name":"-morse","url":"morse-code.js"},
|
||||
{"name":"*morse","url":"morse-code-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "blescan",
|
||||
"name": "BLE Scanner",
|
||||
|
|
@ -430,5 +442,29 @@
|
|||
{"name":"-scolor","url":"show-color.js"},
|
||||
{"name":"*scolor","url":"show-color-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{ "id": "bclock",
|
||||
"name": "Binary Clock",
|
||||
"icon": "clock-binary.png",
|
||||
"description": "A simple binary clock watch face",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
"storage": [
|
||||
{"name":"+bclock","url":"clock-binary.json"},
|
||||
{"name":"-bclock","url":"clock-binary.js"},
|
||||
{"name":"*bclock","url":"clock-binary-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{ "id": "clotris",
|
||||
"name": "Clock-Tris",
|
||||
"icon": "clock-tris.png",
|
||||
"description": "A fully functional clone of a classic game of falling blocks",
|
||||
"tags": "",
|
||||
"storage": [
|
||||
{"name":"+clotris","url":"clock-tris.json"},
|
||||
{"name":"-clotris","url":"clock-tris.js"},
|
||||
{"name":"*clotris","url":"clock-tris-icon.js","evaluate":true},
|
||||
{"name":".trishig","url":"clock-tris-high"}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAMGAAAAAAYDAAAAAAwBgAAAABgAwAAAABAAQAAAABAAQAAAABAAQAAAABAAQAAAABAAQAAAABgAwAAAAAwBgAAAAAYDAAAAAAMGAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAP+AAAAAAf/AAAAAA//gAAAAB//wAAAAB//wAAAAB//wAAAAB//wAAAAB//wAAAAB//wAAAAB//wAAAAA//gAAAAAf/AAAAAAP+AAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"))
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
(() => {
|
||||
const canvasWidth = 290;
|
||||
const numberOfColumns = 6;
|
||||
const drawFullGrid = false;
|
||||
|
||||
const colpos = canvasWidth / numberOfColumns - 10;
|
||||
const binSize = (canvasWidth / numberOfColumns) / 3;
|
||||
|
||||
const findBinary = target => {
|
||||
return [
|
||||
[0, 0, 0, 0], // 0
|
||||
[1, 0, 0, 0], // 1
|
||||
[0, 1, 0, 0], // 2
|
||||
[1, 1, 0, 0], // 3
|
||||
[0, 0, 1, 0], // 4
|
||||
[1, 0, 1, 0], // 5
|
||||
[0, 1, 1, 0], // 6
|
||||
[1, 1, 1, 0], // 7
|
||||
[0, 0, 0, 1], // 8
|
||||
[1, 0, 0, 1], // 9
|
||||
][target];
|
||||
};
|
||||
|
||||
const getCurrentTime = () => {
|
||||
const flattenArray = (array = []) => [].concat.apply([], array);
|
||||
const format = number => {
|
||||
const numberStr = number.toString();
|
||||
return numberStr.length === 1 ? ["0", numberStr] : numberStr.split("");
|
||||
};
|
||||
const now = new Date();
|
||||
return flattenArray([now.getHours(), now.getMinutes(), now.getSeconds()].map(format));
|
||||
};
|
||||
|
||||
let prevFrame = [];
|
||||
const drawColumn = (position = 0, column = [0, 0, 0, 0]) => {
|
||||
const maxDotsPerColumn = [2, 4, 3, 4, 3, 4];
|
||||
|
||||
const columnPos = position * colpos;
|
||||
let pos = colpos / 2 + 45;
|
||||
const frame = column.reverse();
|
||||
const drawDot = fn => g[fn]((columnPos + colpos / 2), pos, binSize);
|
||||
|
||||
for (let i = 0; i < frame.length; i += 1) {
|
||||
if (i + maxDotsPerColumn[position] >= 4 || drawFullGrid) {
|
||||
if (prevFrame && prevFrame[position] && prevFrame[position][i]) {
|
||||
if (frame[i] !== prevFrame[position][i]) {
|
||||
// subsequent draw
|
||||
g.clearRect((columnPos + colpos / 2) - 15, pos - 15, (columnPos + colpos / 2) + 20, pos + 20);
|
||||
if (frame[i]) {
|
||||
drawDot('fillCircle');
|
||||
} else {
|
||||
drawDot('drawCircle');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// First draw
|
||||
if (frame[i]) {
|
||||
drawDot('fillCircle');
|
||||
} else {
|
||||
drawDot('drawCircle');
|
||||
}
|
||||
}
|
||||
}
|
||||
pos += colpos;
|
||||
}
|
||||
};
|
||||
|
||||
const drawClock = () => {
|
||||
const data = getCurrentTime().map(findBinary);
|
||||
for (let i = 0; i < data.length; i += 1) {
|
||||
drawColumn(i, data[i]);
|
||||
}
|
||||
prevFrame = data;
|
||||
};
|
||||
|
||||
// Themes
|
||||
const drawTheme = (idx) => () => {
|
||||
idx += 1;
|
||||
const themes = [
|
||||
[[0, 0, 0], [1, 1, 1]],
|
||||
[[1, 1, 1], [0, 0, 0]],
|
||||
[[0, 0, 0], [1, 0, 0]],
|
||||
[[0, 0, 0], [0, 1, 0]],
|
||||
[[0, 0, 0], [0, 0, 1]],
|
||||
];
|
||||
if (idx >= themes.length) idx = 0;
|
||||
const color = themes[idx];
|
||||
g.setBgColor.apply(g, color[0]);
|
||||
g.setColor.apply(g, color[1]);
|
||||
g.clear();
|
||||
};
|
||||
|
||||
const nextTheme = drawTheme(0);
|
||||
setWatch(() => {
|
||||
prevFrame = [];
|
||||
Bangle.beep();
|
||||
nextTheme();
|
||||
}, BTN1, { repeat: true });
|
||||
|
||||
Bangle.on('lcdPower', on => {
|
||||
if (on) drawClock();
|
||||
});
|
||||
|
||||
g.clear();
|
||||
setInterval(() => { drawClock(); }, 1000);
|
||||
})();
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name":"Binary Clock",
|
||||
"type":"clock",
|
||||
"icon":"*bclock",
|
||||
"src":"-bclock"
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 743 B |
|
|
@ -0,0 +1 @@
|
|||
0
|
||||
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwiBC/AH4A/AHOQzYBNJ/5f/L/5P/L/5f/J/5f/L/5P/L/4A/AH6/haP5f/L/5f/L/5f/L/5f/L/5f/L/4A/AFP/ABy/lL/5f/L/5f/L/5f/L/5f/L/5f/L/4A/VtK/jL/5f/L/5f/L/5f/L/5f/L/5f/L/4A/X/7RxEa5f/L/5f/L/5f/L/5f/L/5f/L/5ffAH4A/AHYA="))
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
Bangle.setLCDMode("doublebuffered");
|
||||
|
||||
const storage = require("Storage");
|
||||
|
||||
var BTN_L = BTN1;
|
||||
var BTN_R = BTN3;
|
||||
var BTN_ROT = BTN2;
|
||||
var BTN_DOWN = BTN5;
|
||||
var BTN_PAUSE = BTN4;
|
||||
|
||||
const W = g.getWidth();
|
||||
const H = g.getHeight();
|
||||
const CX = W / 2;
|
||||
const CY = H / 2;
|
||||
|
||||
const HEIGHT_BUFFER = 4;
|
||||
|
||||
const LINES = 20;
|
||||
const COLUMNS = 11;
|
||||
const CELL_SIZE = Math.floor((H - HEIGHT_BUFFER) / (LINES + 1));
|
||||
|
||||
const BOARD_X = Math.floor((W - CELL_SIZE * COLUMNS) / 2) + 2;
|
||||
const BOARD_Y = Math.floor((H - CELL_SIZE * (LINES + 1)) / 2);
|
||||
const BOARD_W = COLUMNS * CELL_SIZE;
|
||||
const BOARD_H = LINES * CELL_SIZE;
|
||||
|
||||
const TEXT_X = BOARD_X + BOARD_W + 10;
|
||||
|
||||
const BLOCKS = [
|
||||
[
|
||||
[2, 7],
|
||||
[2, 6, 2],
|
||||
[0, 7, 2],
|
||||
[2, 3, 2]
|
||||
],
|
||||
[
|
||||
[1, 3, 2],
|
||||
[6, 3]
|
||||
],
|
||||
[
|
||||
[2, 3, 1],
|
||||
[3, 6]
|
||||
],
|
||||
[
|
||||
[2, 2, 6],
|
||||
[0, 7, 1],
|
||||
[3, 2, 2],
|
||||
[4, 7]
|
||||
],
|
||||
[
|
||||
[2, 2, 3],
|
||||
[1, 7],
|
||||
[6, 2, 2],
|
||||
[0, 7, 4]
|
||||
],
|
||||
[
|
||||
[2, 2, 2, 2],
|
||||
[0, 15]
|
||||
],
|
||||
[[3, 3]]
|
||||
];
|
||||
|
||||
const COLOR_WHITE = 0b1111111111111111;
|
||||
const COLOR_BLACK = 0b0000000000000000;
|
||||
|
||||
const BLOCK_COLORS = [
|
||||
//0brrrrrggggggbbbbb
|
||||
0b0111100000001111,
|
||||
0b0000011111100000,
|
||||
0b1111100000000011,
|
||||
0b0111100111100000,
|
||||
0b0000000000011111,
|
||||
0b0000001111111111,
|
||||
0b1111111111100000
|
||||
];
|
||||
|
||||
const EMPTY_LINE = 0b00000000000000;
|
||||
const BOUNDARY = 0b10000000000010;
|
||||
const FULL_LINE = 0b01111111111100;
|
||||
|
||||
let gameOver = false;
|
||||
let paused = false;
|
||||
let currentBlock = 0;
|
||||
let nextBlock = 0;
|
||||
let x, y;
|
||||
let points;
|
||||
let level;
|
||||
let lines;
|
||||
let board;
|
||||
let rotation = 0;
|
||||
let ticker = null;
|
||||
let needDraw = true;
|
||||
let highScore = parseInt(storage.read(".trishig") || 0, 10);
|
||||
|
||||
function getBlock(a, c, d) {
|
||||
const block = BLOCKS[a % 7];
|
||||
return block[(a + c) % block.length];
|
||||
}
|
||||
|
||||
function drawBlock(block, screenX, screenY, x, y) {
|
||||
for (let row in block) {
|
||||
let mask = block[row];
|
||||
for (let col = 0; mask; mask >>= 1, col++) {
|
||||
if (mask % 2) {
|
||||
const dx = screenX + (x + col) * CELL_SIZE;
|
||||
const dy = screenY + (y + row) * CELL_SIZE;
|
||||
g.fillRect(dx, dy, dx + CELL_SIZE - 3, dy + CELL_SIZE - 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawBoard() {
|
||||
g.setColor(COLOR_WHITE);
|
||||
g.drawRect(BOARD_X - 3, BOARD_Y - 3, BOARD_X + BOARD_W, BOARD_Y + BOARD_H);
|
||||
drawBlock(board, BOARD_X, BOARD_Y, -2, 0);
|
||||
|
||||
g.setColor(BLOCK_COLORS[currentBlock]);
|
||||
drawBlock(getBlock(currentBlock, rotation), BOARD_X, BOARD_Y, x - 2, y);
|
||||
}
|
||||
|
||||
function drawNextBlock() {
|
||||
g.setFontAlign(0, -1, 0);
|
||||
g.setColor(COLOR_WHITE);
|
||||
g.drawString("NEXT BLOCK", BOARD_X / 2, 10);
|
||||
g.setColor(BLOCK_COLORS[nextBlock]);
|
||||
drawBlock(getBlock(nextBlock, 0), BOARD_X / 2 - 2 * CELL_SIZE, 25, 0, 0);
|
||||
}
|
||||
|
||||
function drawTextLine(text, line) {
|
||||
g.drawString(text, TEXT_X, 10 + line * 15);
|
||||
}
|
||||
|
||||
function drawGameState() {
|
||||
g.setFontAlign(-1, -1, 0);
|
||||
g.setColor(COLOR_WHITE);
|
||||
let ln = 0;
|
||||
drawTextLine("CLOCK-TRIS", ln++);
|
||||
ln++;
|
||||
drawTextLine("LVL " + level, ln++);
|
||||
drawTextLine("LNS " + lines, ln++);
|
||||
drawTextLine("PTS " + points, ln++);
|
||||
drawTextLine("TOP " + highScore, ln++);
|
||||
}
|
||||
|
||||
function drawBanner(text) {
|
||||
g.setFontAlign(0, 0, 0);
|
||||
g.setColor(COLOR_BLACK);
|
||||
g.fillRect(CX - 46, CY - 11, CX + 46, CY + 9);
|
||||
g.setColor(COLOR_WHITE);
|
||||
g.drawRect(CX - 45, CY - 10, CX + 45, CY + 8);
|
||||
g.drawString(text, CX, CY);
|
||||
}
|
||||
|
||||
function drawPaused() {
|
||||
drawBanner("PAUSED");
|
||||
}
|
||||
|
||||
function drawGameOver() {
|
||||
drawBanner("GAME OVER");
|
||||
}
|
||||
|
||||
function draw() {
|
||||
g.clear();
|
||||
g.setFont("6x8");
|
||||
drawBoard();
|
||||
drawNextBlock();
|
||||
drawGameState();
|
||||
if (paused) {
|
||||
drawPaused();
|
||||
}
|
||||
if (gameOver) {
|
||||
drawGameOver();
|
||||
}
|
||||
g.flip();
|
||||
}
|
||||
|
||||
function getNextBlock() {
|
||||
currentBlock = nextBlock;
|
||||
nextBlock = (Math.random() * BLOCKS.length) | 0;
|
||||
x = 6;
|
||||
y = 0;
|
||||
rotation = 0;
|
||||
}
|
||||
|
||||
function landBlock(a) {
|
||||
const block = getBlock(currentBlock, rotation);
|
||||
for (let row in block) {
|
||||
board[y + (row | 0)] |= block[row] << x;
|
||||
}
|
||||
|
||||
let clearedLines = 0;
|
||||
let keepLine = LINES;
|
||||
for (let line = LINES - 1; line >= 0; line--) {
|
||||
if (board[line] === FULL_LINE) {
|
||||
clearedLines++;
|
||||
} else {
|
||||
board[--keepLine] = board[line];
|
||||
}
|
||||
}
|
||||
|
||||
lines += clearedLines;
|
||||
if (lines > level * 10) {
|
||||
level++;
|
||||
setSpeed();
|
||||
}
|
||||
|
||||
while (--keepLine > 0) {
|
||||
board[keepLine] = EMPTY_LINE;
|
||||
}
|
||||
if (clearedLines) {
|
||||
points += 100 * (1 << (clearedLines - 1));
|
||||
needDraw = true;
|
||||
}
|
||||
|
||||
getNextBlock();
|
||||
if (!checkMove(0, 0, 0)) {
|
||||
gameOver = true;
|
||||
needDraw = true;
|
||||
highScore = Math.max(points, highScore);
|
||||
storage.write(".trishig", highScore.toString());
|
||||
}
|
||||
}
|
||||
|
||||
function checkMove(dx, dy, rot) {
|
||||
if (gameOver) {
|
||||
startGame();
|
||||
return;
|
||||
}
|
||||
if (paused) {
|
||||
return;
|
||||
}
|
||||
const block = getBlock(currentBlock, rotation + rot);
|
||||
for (const row in block) {
|
||||
const movedBlockRow = block[row] << (x + dx);
|
||||
if (
|
||||
row + y === LINES - 1 ||
|
||||
movedBlockRow & board[y + dy + row] ||
|
||||
movedBlockRow & BOUNDARY
|
||||
) {
|
||||
if (dy) {
|
||||
landBlock();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
rotation += rot;
|
||||
x += dx;
|
||||
y += dy;
|
||||
needDraw = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
function drawLoop() {
|
||||
if (needDraw) {
|
||||
needDraw = false;
|
||||
draw();
|
||||
}
|
||||
setTimeout(drawLoop, 10);
|
||||
}
|
||||
|
||||
function gameTick() {
|
||||
if (!gameOver) {
|
||||
checkMove(0, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function setSpeed() {
|
||||
if (ticker) {
|
||||
clearInterval(ticker);
|
||||
}
|
||||
ticker = setInterval(gameTick, 1000 - level * 100);
|
||||
}
|
||||
|
||||
function togglePause() {
|
||||
if (!gameOver) {
|
||||
paused = !paused;
|
||||
needDraw = true;
|
||||
}
|
||||
}
|
||||
|
||||
function startGame() {
|
||||
board = [];
|
||||
for (let i = 0; i < LINES; i++) {
|
||||
board[i] = EMPTY_LINE;
|
||||
}
|
||||
|
||||
gameOver = false;
|
||||
points = 0;
|
||||
lines = 0;
|
||||
level = 0;
|
||||
getNextBlock();
|
||||
setSpeed();
|
||||
needDraw = true;
|
||||
}
|
||||
|
||||
function bindButton(btn, dx, dy, r) {
|
||||
setWatch(checkMove.bind(null, dx, dy, r), btn, { repeat: true });
|
||||
}
|
||||
|
||||
bindButton(BTN_L, -1, 0, 0);
|
||||
bindButton(BTN_R, 1, 0, 0);
|
||||
bindButton(BTN_ROT, 0, 0, 1);
|
||||
bindButton(BTN_DOWN, 0, 1, 0);
|
||||
|
||||
setWatch(togglePause, BTN_PAUSE, { repeat: true });
|
||||
|
||||
startGame();
|
||||
drawLoop();
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name":"Clock-Tris",
|
||||
"icon":"*clotris",
|
||||
"src":"-clotris"
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 303 B |
|
|
@ -0,0 +1,147 @@
|
|||
/**
|
||||
* Teach a user morse code
|
||||
*/
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
const FONT_NAME = 'Vector12';
|
||||
const FONT_SIZE = 80;
|
||||
const SCREEN_PIXELS = 240;
|
||||
const UNIT = 100;
|
||||
const MORSE_MAP = {
|
||||
A: '.-',
|
||||
B: '-...',
|
||||
C: '-.-.',
|
||||
D: '-..',
|
||||
E: '.',
|
||||
F: '..-.',
|
||||
G: '--.',
|
||||
H: '....',
|
||||
I: '..',
|
||||
J: '.---',
|
||||
K: '-.-',
|
||||
L: '.-..',
|
||||
M: '--',
|
||||
N: '-.',
|
||||
O: '---',
|
||||
P: '.--.',
|
||||
Q: '--.-',
|
||||
R: '.-.',
|
||||
S: '...',
|
||||
T: '-',
|
||||
U: '..-',
|
||||
V: '...-',
|
||||
W: '.--',
|
||||
X: '-..-',
|
||||
Y: '-.--',
|
||||
Z: '--..',
|
||||
'1': '.----',
|
||||
'2': '..---',
|
||||
'3': '...--',
|
||||
'4': '....-',
|
||||
'5': '.....',
|
||||
'6': '-....',
|
||||
'7': '--...',
|
||||
'8': '---..',
|
||||
'9': '----.',
|
||||
'0': '-----',
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the local state
|
||||
*/
|
||||
let INDEX = 0;
|
||||
let BEEPING = false;
|
||||
let BUZZING = true;
|
||||
let UNIT_INDEX = 0;
|
||||
let UNITS = MORSE_MAP[Object.keys(MORSE_MAP)[INDEX]].split('');
|
||||
/**
|
||||
* Utility functions for writing text, changing state
|
||||
*/
|
||||
const writeText = (txt) => {
|
||||
g.clear();
|
||||
const width = g.stringWidth(txt);
|
||||
g.drawString(txt, (SCREEN_PIXELS / 2) - (width / 2), SCREEN_PIXELS / 2);
|
||||
};
|
||||
const writeLetter = () => {
|
||||
writeText(Object.keys(MORSE_MAP)[INDEX]);
|
||||
};
|
||||
const writeCode = () => {
|
||||
writeText(MORSE_MAP[Object.keys(MORSE_MAP)[INDEX]]);
|
||||
};
|
||||
const setUnits = () => {
|
||||
UNITS = MORSE_MAP[Object.keys(MORSE_MAP)[INDEX]].split('');
|
||||
};
|
||||
/**
|
||||
* Bootstrapping
|
||||
*/
|
||||
g.clear();
|
||||
g.setFont(FONT_NAME, FONT_SIZE);
|
||||
g.setColor(0, 1, 0);
|
||||
g.setFontAlign(-1, 0, 0);
|
||||
/**
|
||||
* The length of a dot is one unit
|
||||
* The length of a dash is three units
|
||||
* The length of a space is one unit
|
||||
* The space between letters is three units
|
||||
* The space between words is seven units
|
||||
*/
|
||||
const beepItOut = () => {
|
||||
// If we are starting the beeps, use a timeout for pause of three units
|
||||
const wait = UNIT_INDEX === 0 ? UNIT * 3 : 0;
|
||||
setTimeout(() => {
|
||||
Promise.all([
|
||||
Bangle.beep(UNITS[UNIT_INDEX] === '.' ? UNIT : 3 * UNIT),
|
||||
// Could make buzz optional or switchable potentially
|
||||
BUZZING ? Bangle.buzz(UNITS[UNIT_INDEX] === '.' ? UNIT : 3 * UNIT) : null
|
||||
])
|
||||
.then(() => {
|
||||
if (UNITS[UNIT_INDEX + 1]) {
|
||||
setTimeout(() => {
|
||||
UNIT_INDEX++;
|
||||
beepItOut();
|
||||
}, UNIT);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
BEEPING = false;
|
||||
UNIT_INDEX = 0;
|
||||
writeLetter();
|
||||
}, 3 * UNIT);
|
||||
}
|
||||
});
|
||||
}, wait);
|
||||
};
|
||||
const startBeep = () => {
|
||||
if (BEEPING) return;
|
||||
else {
|
||||
BEEPING = true;
|
||||
writeCode();
|
||||
beepItOut();
|
||||
}
|
||||
};
|
||||
|
||||
const step = (positive) => () => {
|
||||
if (BEEPING) return;
|
||||
if (positive) {
|
||||
INDEX = INDEX + 1;
|
||||
if (INDEX > Object.keys(MORSE_MAP).length - 1) INDEX = 0;
|
||||
} else {
|
||||
INDEX = INDEX - 1;
|
||||
if (INDEX < 0) INDEX = Object.keys(MORSE_MAP).length - 1;
|
||||
}
|
||||
setUnits();
|
||||
writeLetter();
|
||||
};
|
||||
|
||||
const toggleBuzzing = () => (BUZZING = !BUZZING);
|
||||
|
||||
writeLetter();
|
||||
|
||||
// Press the middle button to hear the morse code translation
|
||||
setWatch(startBeep, BTN2, { repeat: true });
|
||||
// Allow user to switch between letters
|
||||
setWatch(step(true), BTN1, { repeat: true });
|
||||
setWatch(step(false), BTN3, { repeat: true });
|
||||
// Toggle buzzing/beeping with the touchscreen
|
||||
setWatch(toggleBuzzing, BTN4, { repeat: true });
|
||||
setWatch(toggleBuzzing, BTN5, { repeat: true });
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name":"Morse Code","type":"app",
|
||||
"icon":"*morse",
|
||||
"src":"-morse"
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 413 B |
Loading…
Reference in New Issue