From 154652e51d9d7e46e4566a3b8c70b2d2e3cc8122 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Sun, 10 Oct 2021 22:08:20 +0200 Subject: [PATCH 01/52] create new app 'score' --- apps.json | 13 ++ apps/score/ChangeLog | 1 + apps/score/score.app-icon.js | 1 + apps/score/score.app.js | 288 +++++++++++++++++++++++++++++++++++ apps/score/score.app.png | Bin 0 -> 897 bytes apps/score/score.settings.js | 81 ++++++++++ 6 files changed, 384 insertions(+) create mode 100644 apps/score/ChangeLog create mode 100644 apps/score/score.app-icon.js create mode 100644 apps/score/score.app.js create mode 100644 apps/score/score.app.png create mode 100644 apps/score/score.settings.js diff --git a/apps.json b/apps.json index 6b0703601..314504276 100644 --- a/apps.json +++ b/apps.json @@ -3554,5 +3554,18 @@ {"name":"floralclk.app.js","url":"app.js"}, {"name":"floralclk.img","url":"app-icon.js","evaluate":true} ] +}, +{ "id": "score", + "name": "Score Tracker", + "icon": "score.app.png", + "version":"0.01", + "description": "Score Tracker for sports that use plain numbers. (e.g. Badminton, Volleyball, Soccer, Table Tennis, ...)", + "tags": "b2", + "type": "app", + "storage": [ + {"name":"score.app.js","url":"score.app.js"}, + {"name":"score.settings.js","url":"score.settings.js"}, + {"name":"score.img","url":"score.app-icon.js","evaluate":true} + ] } ] diff --git a/apps/score/ChangeLog b/apps/score/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/score/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/score/score.app-icon.js b/apps/score/score.app-icon.js new file mode 100644 index 000000000..b1d4631ba --- /dev/null +++ b/apps/score/score.app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AE2IxAKSCigv/F/4vS44ABB4IECAAoKECgM7AAIJBAgQAFBQguJF6HHEhAvKGAwvy4wPB4wuGBQwdCmgJBmguGBQwvJ0ulF5AKFEgeCwQvIBQqPJ4wuHBQ4lEFw4KHF5IAQFJAALF+vNACYv/F/4v053P64vPxPXAAOJF6vP6wbCF52zCQQAB2YvTDIgvOLoWzMJQvOL6JeCss7spgIF5nPMQgvNCAQEBr4FEd6YvVAowv/F/4v4d9WzCANlndlAgOzF82JFQWJGgWJF8xgDAAReGF8RhDLo4vRABQiHABgv/F/4v/F4owTCgIuZAH4A/AH4A/ADgA==")) diff --git a/apps/score/score.app.js b/apps/score/score.app.js new file mode 100644 index 000000000..7bfadb1ce --- /dev/null +++ b/apps/score/score.app.js @@ -0,0 +1,288 @@ +require('Font5x9Numeric7Seg').add(Graphics); +require('Font7x11Numeric7Seg').add(Graphics); +require('FontTeletext5x9Ascii').add(Graphics); +require('FontTeletext10x18Ascii').add(Graphics); + +let settingsMenu = eval(require('Storage').read('score.settings.js')); +let settings = settingsMenu(null, true); + +let scores = null; +let cSet = null; + +let firstShownSet = null; + +let settingsMenuOpened = null; +let correctionMode = false; + +let w = g.getWidth(); +let h = g.getHeight(); + +function setupInputWatchers() { + if (global.BTN4) { + setWatch(() => handleInput(2), BTN2, { repeat: true }); + setWatch(() => handleInput(3), BTN1, { repeat: true }); + setWatch(() => handleInput(4), BTN3, { repeat: true }); + } else { + setWatch(() => handleInput(2), BTN, { repeat: true }); + } + Bangle.on('touch', (b, e) => { + if (b) { + if (b === 1) { + handleInput(0); + } else { + handleInput(1); + } + } else { + if (e.x < w/2) { + handleInput(0); + } else { + handleInput(1); + } + } + }) +} + +function setupMatch() { + scores = []; + for (let s = 0; s < sets(); s++) { + scores.push([0,0,null]); + } + scores.push([0,0,null]); + + scores[0][2] = getTime(); + + cSet = 0; + firstShownSet = 0 - Math.floor(setsPerPage() / 2); +} + +function showSettingsMenu() { + settingsMenuOpened = getTime(); + settingsMenu(function (s, reset) { + E.showMenu(); + + settings = s; + + if (reset) { + setupMatch(); + } else if (getTime() - settingsMenuOpened < 0.5 || correctionMode) { + correctionMode = !correctionMode; + } + + settingsMenuOpened = null; + + draw(); + }); +} + +function setsPerPage() { + return Math.min(settings.setsPerPage, sets()); +} + +function sets() { + return settings.winSets * 2 - 1; +} + +function currentSet() { + return matchEnded() ? cSet - 1 : cSet; +} + +function formatNumber(num, length) { + return num.toString().padStart(length ? length : 2,"0"); +} + +function formatDuration(duration) { + let durS = Math.floor(duration); + let durM = Math.floor(durS / 60); + let durH = Math.floor(durM / 60); + durS = durS - durM * 60; + durM = durM - durH * 60; + + durS = formatNumber(durS); + durM = formatNumber(durM); + durH = formatNumber(durH); + + let dur = null; + if (durH > 0) { + dur = durH + ':' + durM; + } else { + dur = durM + ':' + durS; + } + + return dur; +} + +function setWon(set, player) { + let pScore = scores[set][player]; + let p2Score = scores[set][~~!player]; + + let winScoreReached = pScore >= settings.winScore; + let isTwoAhead = !settings.enableTwoAhead || pScore - p2Score >= 2; + let reachedMaxScore = settings.enableMaxScore && pScore >= settings.maxScore; + + return reachedMaxScore || (winScoreReached && isTwoAhead); +} + +function setEnded(set) { + return setWon(set, 0) || setWon(set, 1); +} + +function setsWon(player) { + return Array(sets()).fill(0).map((_, s) => ~~setWon(s, player)).reduce((a,v) => a+v, 0); +} + +function matchWon(player) { + return setsWon(player) >= settings.winSets; +} + +function matchEnded() { + return matchWon(0) || matchWon(1); +} + +function matchScore(player) { + return scores.reduce((acc, val) => acc += val[player], 0); +} + +function score(player) { + let updateCurrentSet = function (val) { + cSet += val; + firstShownSet = Math.max(0, currentSet() - settings.setsPerPage + 1); + } + + if (!matchEnded() || correctionMode) { + firstShownSet = currentSet() - Math.floor(setsPerPage() / 2); + } + + if (correctionMode) { + if ( + scores[cSet][0] === 0 && scores[cSet][1] === 0 && + cSet > 0 + ) { + updateCurrentSet(-1); + } + + if (scores[cSet][player] > 0) { + scores[cSet][player]--; + } + } else { + if (matchEnded()) return; + + scores[cSet][player]++; + + if (setEnded(cSet) && cSet < sets()) { + updateCurrentSet(1); + scores[cSet][2] = getTime(); + } + + if (matchEnded()) { + firstShownSet = 0; + } + } +} + +function handleInput(button) { + if (settingsMenuOpened) { + return; + } + + switch (button) { + case 0: + case 1: + score(button); + break; + case 2: + showSettingsMenu(); + return; + case 3: + case 4: + let hLimit = currentSet(); + let lLimit = 1 - setsPerPage(); + let val = (button * 2 - 7); + firstShownSet += val; + if (firstShownSet > hLimit) firstShownSet = hLimit; + if (firstShownSet < lLimit) firstShownSet = lLimit; + break; + } + + draw(); +} + +function draw() { + g.setFontAlign(0,0); + g.clear(); + + for (let p = 0; p < 2; p++) { + if (matchWon(p)) { + g.setFontAlign(0,0); + g.setFont('Teletext10x18Ascii',1); + g.drawString("WINNER", p === 0 ? w/4 : w/4*3, 15); + } else if (matchEnded()) { + g.setFontAlign(0,-1); + + let dur1 = formatDuration(scores[cSet][2] - scores[0][2]); + g.setFont('5x9Numeric7Seg',1); + g.drawString(dur1, p === 0 ? w/8 : w/8*5, 10); + + g.setFont('Teletext5x9Ascii',1); + g.drawString((currentSet()+1) + ' set' + (currentSet() > 1 ? 's' : ''), p === 0 ? w/8*3 : w/8*7, 12); + + } + + g.setFontAlign(p === 0 ? -1 : 1,1); + g.setFont('7x11Numeric7Seg',2); + g.drawString(setsWon(p), p === 0 ? 10 : w-8, h-5); + + g.setFontAlign(p === 0 ? 1 : -1,1); + g.setFont('7x11Numeric7Seg',2); + g.drawString(formatNumber(matchScore(p), 3), p === 0 ? w/2 - 8 : w/2 + 11, h-5); + } + g.setFontAlign(0,0); + + if (correctionMode) { + g.setFont('Teletext10x18Ascii',1); + g.drawString("R", w/2, h-10); + } + + let lastShownSet = Math.min( + sets(), + currentSet() + 1, + firstShownSet+setsPerPage() + ); + let setsOnCurrentPage = Math.min( + sets(), + setsPerPage() + ); + for (let set = firstShownSet; set < lastShownSet; set++) { + if (set < 0) continue; + + let y = (h-15)/(setsOnCurrentPage+1)*(set-firstShownSet+1)+5; + + g.setFontAlign(1,0); + g.setFont('7x11Numeric7Seg',1); + g.drawString(set+1, 40, y-10); + if (scores[set+1][2] != null) { + let dur2 = formatDuration(scores[set+1][2] - scores[set][2]); + g.drawString(dur2, 40, y+10); + } + + g.setFontAlign(0,0); + g.setFont('7x11Numeric7Seg',3); + for (let p = 0; p < 2; p++) { + if (!setWon(set, p === 0 ? 1 : 0) || matchEnded()) { + g.drawString( + formatNumber(scores[set][p]), + p === 0 ? (w-20)/4+20 : (w-20)/4*3+20, + y + ); + } + } + } + + // draw separator + g.drawLine(w/2,20,w/2,h-25); + + g.flip(); +} + +setupInputWatchers(); +setupMatch(); +draw(); diff --git a/apps/score/score.app.png b/apps/score/score.app.png new file mode 100644 index 0000000000000000000000000000000000000000..c1e7e22157fc295811c8b0291dd736d7d1878e5a GIT binary patch literal 897 zcmV-{1AhF8P)-q;>a)qdEv4t%nBoLyDDR~j<9&`&l zbnlXgNO%l7dGZn+>{ierq}uY3iGi7fhrmBe8YsJ!ZRKF5hsneX&? z@7wQvzu)iun+1IM@Zsag;`zG|(=XDKQ*LtI)|9FZ5{3?d@yx}|bz4*5QaZvo_5oOy zko+<=h%Gt*3K0Na?esrO?pyOcToDvOX{aMREff?CXj)klm;(SLM)Dl%$jTK2(7J#y z^yO~k;SR%E0h9SdgF=K%2d(B02Tg-mP_#jFpEUrJd6qArQo9mtxf&DA=4r8L3>7!4 zYT9w>u4LHm0lKe`mM57SG_L|kWOZVz^-?kMX^$|#^ zgzW@QxI(xVp)>ZTop4XqJs`B!xIRIGx}T#ZQ~TIgzz@J{RJ{l6KYO`()yg>E zR8B~V0^f2P0AOxi)5qJI_;Sl1z{-<@_}do^q4IMkUt;=KZ=qx?`uZT>gU_>LRIK37 zyk{j&XUF~?@GJmY;fORBMb-9>SAu5&{M}yfVbd;b3>hJ8$b27Co&~V*tDNH60KwUY zvW;Z3VQ29-UkMyNCEP$dLvf|GeAYj>7DPHj(c5O6{co2kmyTxvj4!IVaZW^gOhmF- zuw?)98pWGszQ>SfOGslt|AdUOc?D|)22}&r3JhcO3i>Bx-v1JuRY0A%?Br*Au%!Z{ zvkFFM6~`L>J>WG?TmUO>iZkH*f6~-p34j27y9tMxh%nLz=B}ndSf3kOK79D_;ST-* XivUhVT==`h00000NkvXXu0mjflmwo` literal 0 HcmV?d00001 diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js new file mode 100644 index 000000000..dde77a225 --- /dev/null +++ b/apps/score/score.settings.js @@ -0,0 +1,81 @@ +(function (back, ret) { + + const fileName = 'score.json' + let settings = require('Storage').readJSON(fileName, 1) || {}; + const offon = ['No', 'Yes']; + + let changed = false; + + function save(key, value) { + changed = true; + settings[key] = value; + if (key === 'winScore' && settings.maxScore < value) { + settings.maxScore = value; + } + require('Storage').writeJSON(fileName, settings); + } + + if (!settings.winSets) { + settings.winSets = 1; + } + if (!settings.winScore) { + settings.winScore = 21; + } + if (!settings.enableTwoAhead) { + settings.enableTwoAhead = true; + } + if (!settings.enableMaxScore) { + settings.enableMaxScore = true; + } + if (!settings.maxScore) { + settings.maxScore = 30; + } + if (!settings.setsPerPage) { + settings.setsPerPage = 5; + } + + if (ret) { + return settings; + } + + const appMenu = {}; + appMenu[''] = {'title': 'Score Settings'}, + appMenu['< Back'] = function () { back(settings, changed); }; + if (reset) { + appMenu['Reset match'] = function () { back(settings, true); }; + } + appMenu['Sets to win'] = { + value: settings.winSets, + min:1, + onchange: m => save('winSets', m) + }; + appMenu['Sets per page'] = { + value: settings.setsPerPage, + min:1, + max:5, + onchange: m => save('setsPerPage', m) + }; + appMenu['Score to win'] = { + value: settings.winScore, + min:1, + onchange: m => save('winScore', m) + }; + appMenu['2-point lead'] = { + value: settings['enableTwoAhead'], + format: m => offon[~~m], + onchange: m => save('enableTwoAhead', m) + }; + appMenu['Maximum score?'] = { + value: settings['enableMaxScore'], + format: m => offon[~~m], + onchange: m => save('enableMaxScore', m) + }; + appMenu['Maximum score'] = { + value: settings.maxScore, + min: settings.winScore, + onchange: m => save('maxScore', m) + }; + + E.showMenu(appMenu) + +}) From 2b612de6f6281651ccc611f77eef9d348880492e Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 03:45:48 +0200 Subject: [PATCH 02/52] score: refactor and fix settings --- apps/score/score.settings.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index dde77a225..4843b4a4c 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -15,22 +15,22 @@ require('Storage').writeJSON(fileName, settings); } - if (!settings.winSets) { + if (!settings.winSets == null) { settings.winSets = 1; } - if (!settings.winScore) { + if (!settings.winScore == null) { settings.winScore = 21; } - if (!settings.enableTwoAhead) { + if (!settings.enableTwoAhead == null) { settings.enableTwoAhead = true; } - if (!settings.enableMaxScore) { + if (settings.enableMaxScore == null) { settings.enableMaxScore = true; } - if (!settings.maxScore) { + if (!settings.maxScore == null) { settings.maxScore = 30; } - if (!settings.setsPerPage) { + if (!settings.setsPerPage == null) { settings.setsPerPage = 5; } @@ -61,12 +61,12 @@ onchange: m => save('winScore', m) }; appMenu['2-point lead'] = { - value: settings['enableTwoAhead'], + value: settings.enableTwoAhead, format: m => offon[~~m], onchange: m => save('enableTwoAhead', m) }; appMenu['Maximum score?'] = { - value: settings['enableMaxScore'], + value: settings.enableMaxScore, format: m => offon[~~m], onchange: m => save('enableMaxScore', m) }; From e598c4abf691bdbc052d9464e2419984a21dbe33 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 03:46:03 +0200 Subject: [PATCH 03/52] score: fix maxScore --- apps/score/score.app.js | 6 +++++- apps/score/score.settings.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 7bfadb1ce..dbe9f74ef 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -74,6 +74,10 @@ function showSettingsMenu() { }); } +function maxScore() { + return Math.max(settings.maxScore, settings.winScore); +} + function setsPerPage() { return Math.min(settings.setsPerPage, sets()); } @@ -117,7 +121,7 @@ function setWon(set, player) { let winScoreReached = pScore >= settings.winScore; let isTwoAhead = !settings.enableTwoAhead || pScore - p2Score >= 2; - let reachedMaxScore = settings.enableMaxScore && pScore >= settings.maxScore; + let reachedMaxScore = settings.enableMaxScore && pScore >= maxScore(); return reachedMaxScore || (winScoreReached && isTwoAhead); } diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index 4843b4a4c..d1a4332fd 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -72,7 +72,7 @@ }; appMenu['Maximum score'] = { value: settings.maxScore, - min: settings.winScore, + min: 1, onchange: m => save('maxScore', m) }; From 7a68984626ce8eace5e55d9a5be86fa30a3b9872 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 03:40:55 +0200 Subject: [PATCH 04/52] score: fix set/sets display --- apps/score/score.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index dbe9f74ef..7e02f8dfe 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -227,7 +227,7 @@ function draw() { g.drawString(dur1, p === 0 ? w/8 : w/8*5, 10); g.setFont('Teletext5x9Ascii',1); - g.drawString((currentSet()+1) + ' set' + (currentSet() > 1 ? 's' : ''), p === 0 ? w/8*3 : w/8*7, 12); + g.drawString((currentSet()+1) + ' set' + (currentSet() > 0 ? 's' : ''), p === 0 ? w/8*3 : w/8*7, 12); } From dcd15516f14696c9cff94b09bcf019b7f7a14a32 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 03:41:15 +0200 Subject: [PATCH 05/52] score: add tennis scoring --- apps.json | 2 +- apps/score/score.app.js | 66 ++++++++++++++++++++++++++++++------ apps/score/score.settings.js | 8 +++++ 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/apps.json b/apps.json index 314504276..c98686e72 100644 --- a/apps.json +++ b/apps.json @@ -3559,7 +3559,7 @@ "name": "Score Tracker", "icon": "score.app.png", "version":"0.01", - "description": "Score Tracker for sports that use plain numbers. (e.g. Badminton, Volleyball, Soccer, Table Tennis, ...)", + "description": "Score Tracker for sports that use plain numbers (e.g. Badminton, Volleyball, Soccer, Table Tennis, ...). Also supports tennis scoring.", "tags": "b2", "type": "app", "storage": [ diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 7e02f8dfe..11d158440 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -6,7 +6,10 @@ require('FontTeletext10x18Ascii').add(Graphics); let settingsMenu = eval(require('Storage').read('score.settings.js')); let settings = settingsMenu(null, true); +let tennisScores = ['00','15','30','40','DC','AD'] + let scores = null; +let tScores = null; let cSet = null; let firstShownSet = null; @@ -49,6 +52,12 @@ function setupMatch() { } scores.push([0,0,null]); + if (settings.enableTennisScoring) { + tScores = [0,0]; + } else { + tScores = null; + } + scores[0][2] = getTime(); cSet = 0; @@ -170,7 +179,22 @@ function score(player) { } else { if (matchEnded()) return; - scores[cSet][player]++; + if (settings.enableTennisScoring) { + if (tScores[player] === 4 && tScores[~~!player] === 5) { // DC : AD + tScores[~~!player]--; + } else if (tScores[player] === 2 && tScores[~~!player] === 3) { // 30 : 40 + tScores[0] = 4; + tScores[1] = 4; + } else if (tScores[player] === 3 || tScores[player] === 5) { // 40 / AD + tScores[0] = 0; + tScores[1] = 0; + scores[cSet][player]++; + } else { + tScores[player]++; + } + } else { + scores[cSet][player]++; + } if (setEnded(cSet) && cSet < sets()) { updateCurrentSet(1); @@ -235,9 +259,11 @@ function draw() { g.setFont('7x11Numeric7Seg',2); g.drawString(setsWon(p), p === 0 ? 10 : w-8, h-5); - g.setFontAlign(p === 0 ? 1 : -1,1); - g.setFont('7x11Numeric7Seg',2); - g.drawString(formatNumber(matchScore(p), 3), p === 0 ? w/2 - 8 : w/2 + 11, h-5); + if (!settings.enableTennisScoring) { + g.setFontAlign(p === 0 ? 1 : -1,1); + g.setFont('7x11Numeric7Seg',2); + g.drawString(formatNumber(matchScore(p), 3), p === 0 ? w/2 - 8 : w/2 + 11, h-5); + } } g.setFontAlign(0,0); @@ -268,15 +294,33 @@ function draw() { g.drawString(dur2, 40, y+10); } - g.setFontAlign(0,0); - g.setFont('7x11Numeric7Seg',3); for (let p = 0; p < 2; p++) { if (!setWon(set, p === 0 ? 1 : 0) || matchEnded()) { - g.drawString( - formatNumber(scores[set][p]), - p === 0 ? (w-20)/4+20 : (w-20)/4*3+20, - y - ); + if (settings.enableTennisScoring && set === cSet) { + g.setFontAlign(0,0); + g.setFont('7x11Numeric7Seg',3); + g.drawString( + formatNumber(tennisScores[tScores[p]]), + p === 0 ? (w-20)/4+20 : (w-20)/4*3+2, + y + ); + + g.setFontAlign(p === 0 ? 1 : -1,0); + g.setFont('7x11Numeric7Seg',1); + g.drawString( + formatNumber(scores[set][p]), + p === 0 ? w/2-5 : w/2+6, + y + ); + } else { + g.setFontAlign(0,0); + g.setFont('7x11Numeric7Seg',3); + g.drawString( + formatNumber(scores[set][p]), + p === 0 ? (w-20)/4+20 : (w-20)/4*3+2, + y + ); + } } } } diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index d1a4332fd..7d058f07f 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -33,6 +33,9 @@ if (!settings.setsPerPage == null) { settings.setsPerPage = 5; } + if (!settings.enableTennisScoring == null) { + settings.enableTennisScoring = false; + } if (ret) { return settings; @@ -75,6 +78,11 @@ min: 1, onchange: m => save('maxScore', m) }; + appMenu['Tennis scoring'] = { + value: settings.enableTennisScoring, + format: m => offon[~~m], + onchange: m => save('enableTennisScoring', m) + }; E.showMenu(appMenu) From a6a5f674a090473e1396647ea19e4e2a3f2c29d2 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 03:59:24 +0200 Subject: [PATCH 06/52] score: fix commit 58c7b6c4 --- apps/score/score.settings.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index 7d058f07f..ab8b8fb85 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -15,25 +15,25 @@ require('Storage').writeJSON(fileName, settings); } - if (!settings.winSets == null) { + if (settings.winSets == null) { settings.winSets = 1; } - if (!settings.winScore == null) { + if (settings.winScore == null) { settings.winScore = 21; } - if (!settings.enableTwoAhead == null) { + if (settings.enableTwoAhead == null) { settings.enableTwoAhead = true; } if (settings.enableMaxScore == null) { settings.enableMaxScore = true; } - if (!settings.maxScore == null) { + if (settings.maxScore == null) { settings.maxScore = 30; } - if (!settings.setsPerPage == null) { + if (settings.setsPerPage == null) { settings.setsPerPage = 5; } - if (!settings.enableTennisScoring == null) { + if (settings.enableTennisScoring == null) { settings.enableTennisScoring = false; } From a441d423a417538969d8fd6b39c73e0043acddfe Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 04:27:27 +0200 Subject: [PATCH 07/52] score: refactor --- apps/score/score.app.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 11d158440..2052df226 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -6,7 +6,7 @@ require('FontTeletext10x18Ascii').add(Graphics); let settingsMenu = eval(require('Storage').read('score.settings.js')); let settings = settingsMenu(null, true); -let tennisScores = ['00','15','30','40','DC','AD'] +let tennisScores = ['00','15','30','40','DC','AD']; let scores = null; let tScores = null; @@ -42,7 +42,7 @@ function setupInputWatchers() { handleInput(1); } } - }) + }); } function setupMatch() { @@ -159,17 +159,14 @@ function score(player) { let updateCurrentSet = function (val) { cSet += val; firstShownSet = Math.max(0, currentSet() - settings.setsPerPage + 1); - } + }; if (!matchEnded() || correctionMode) { firstShownSet = currentSet() - Math.floor(setsPerPage() / 2); } if (correctionMode) { - if ( - scores[cSet][0] === 0 && scores[cSet][1] === 0 && - cSet > 0 - ) { + if (scores[cSet][0] === 0 && scores[cSet][1] === 0 && cSet > 0) { updateCurrentSet(-1); } From 4c6e9a086049d1250f49cc499df99c2c807b54cd Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 04:34:30 +0200 Subject: [PATCH 08/52] score: tennis scoring: allow corrections --- apps/score/score.app.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 2052df226..636d3a97e 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -171,7 +171,12 @@ function score(player) { } if (scores[cSet][player] > 0) { - scores[cSet][player]--; + if (tScores[player] === 0 && tScores[~~!player] === 0) { + scores[cSet][player]--; + } else { + tScores[player] = 0; + tScores[~~!player] = 0; + } } } else { if (matchEnded()) return; From c45781bc8b536c91718ecb67ef25d94cbaaa90c9 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 04:42:35 +0200 Subject: [PATCH 09/52] score: add README --- apps/score/README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 apps/score/README.md diff --git a/apps/score/README.md b/apps/score/README.md new file mode 100644 index 000000000..cdb34902c --- /dev/null +++ b/apps/score/README.md @@ -0,0 +1,37 @@ +This app will allow you to keep scores for most kinds of sports. + +# Keybinds +*On Bangle.js 2 BTN is equivalent to BTN2 on Bangle.js 1* +| Keybinding | Description | +|-------------------|------------------------------| +| `BTN1` | Scroll up | +| `BTN3` | Scroll down | +| `BTN2` | Menu | +| tap on left side | increment left player score | +| tap on right side | increment right player score | + +To correct a falsely awarded point simply open and close the menu within .5 seconds. This will put the app into correction mode (indicated by the `R`). +In this mode any score increments will be decrements. To move back a set, reduce both players scores to 0, then decrement one of the scores once again. + +# Settings +| Setting | Description | +|----------------|------------------------------------------------------------------------------------------------------------------------------| +| Sets to win | How many sets a player has to win before the match is won (Maximum sets: this*2-1) | +| Sets per page | How many sets should be shown in the app. Further sets will be available by scrolling (ignored if higher than `Sets to win`) | +| Score to win | What score ends a given set | +| 2-point lead | Does winning a set require a two-point lead | +| Maximum score? | Should there be a maximum score, at which point the two-point lead rule falls away | +| Maximum score | At which score should the two-point lead rule fall away (ignored if lower than Sets to win) | +| Tennis scoring | If enabled, each point in a set will require a full tennis game | + +The settings can be changed both from within the app by simply pressing `BTN2` (`BTN1` on Bangle.js 2) or in the `App Settings` in the `Settings` app. + +If changes are made to the settings from within the app, a new match will automatically be initialized upon exiting the settings. + +By default the settings will reflect Badminton rules. + +## Tennis Scoring +While tennis scoring is available, correcting in this mode will reset to the beginning of the current game. +Resetting at the beginning of the current game will reset to the beginning of the previous game, leaving the user to fast-forward to the correct score once again. + +This might get changed at some point. From 97166e0d1a876c8ddbea00b12afcd7cd99b2bde1 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 13:45:23 +0200 Subject: [PATCH 10/52] score: refactor settings --- apps/score/score.settings.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index ab8b8fb85..b7a2fefad 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -18,6 +18,9 @@ if (settings.winSets == null) { settings.winSets = 1; } + if (settings.setsPerPage == null) { + settings.setsPerPage = 5; + } if (settings.winScore == null) { settings.winScore = 21; } @@ -30,9 +33,6 @@ if (settings.maxScore == null) { settings.maxScore = 30; } - if (settings.setsPerPage == null) { - settings.setsPerPage = 5; - } if (settings.enableTennisScoring == null) { settings.enableTennisScoring = false; } From c0a18add642da63d9afd74b740e06474587f4509 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 13:47:22 +0200 Subject: [PATCH 11/52] score: implement tie-breaks instead of fixed max scores --- apps/score/score.app.js | 86 ++++++++++++++++++++++++++++++------ apps/score/score.settings.js | 39 ++++++++++++++++ 2 files changed, 111 insertions(+), 14 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 636d3a97e..2566d6922 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -48,9 +48,9 @@ function setupInputWatchers() { function setupMatch() { scores = []; for (let s = 0; s < sets(); s++) { - scores.push([0,0,null]); + scores.push([0,0,null,0,0]); } - scores.push([0,0,null]); + scores.push([0,0,null,0,0]); if (settings.enableTennisScoring) { tScores = [0,0]; @@ -87,6 +87,10 @@ function maxScore() { return Math.max(settings.maxScore, settings.winScore); } +function tiebreakMaxScore() { + return Math.max(settings.maxScoreTiebreakMaxScore, settings.maxScoreTiebreakWinScore); +} + function setsPerPage() { return Math.min(settings.setsPerPage, sets()); } @@ -99,6 +103,11 @@ function currentSet() { return matchEnded() ? cSet - 1 : cSet; } +function shouldTiebreak() { + return settings.enableMaxScoreTiebreak && + scores[cSet][0] + scores[cSet][1] === (maxScore() - 1) * 2; +} + function formatNumber(num, length) { return num.toString().padStart(length ? length : 2,"0"); } @@ -124,15 +133,30 @@ function formatDuration(duration) { return dur; } +function tiebreakWon(set, player) { + let pScore = scores[set][3+player]; + let p2Score = scores[set][3+~~!player]; + + let winScoreReached = pScore >= settings.maxScoreTiebreakWinScore; + let isTwoAhead = !settings.maxScoreTiebreakEnableTwoAhead || pScore - p2Score >= 2; + let reachedMaxScore = settings.maxScoreTiebreakEnableMaxScore && pScore >= tiebreakMaxScore(); + + return reachedMaxScore || (winScoreReached && isTwoAhead); +} + function setWon(set, player) { let pScore = scores[set][player]; let p2Score = scores[set][~~!player]; let winScoreReached = pScore >= settings.winScore; let isTwoAhead = !settings.enableTwoAhead || pScore - p2Score >= 2; + let tiebreakW = tiebreakWon(set, player); let reachedMaxScore = settings.enableMaxScore && pScore >= maxScore(); - return reachedMaxScore || (winScoreReached && isTwoAhead); + return ( + (settings.enableMaxScoreTiebreak ? tiebreakW : reachedMaxScore) || + (winScoreReached && isTwoAhead) + ); } function setEnded(set) { @@ -166,11 +190,19 @@ function score(player) { } if (correctionMode) { - if (scores[cSet][0] === 0 && scores[cSet][1] === 0 && cSet > 0) { + if ( + scores[cSet][0] === 0 && scores[cSet][1] === 0 && + scores[cSet][3] === 0 && scores[cSet][4] === 0 && + cSet > 0 + ) { updateCurrentSet(-1); } - if (scores[cSet][player] > 0) { + if (scores[cSet][3] > 0 || scores[cSet][4] > 0) { + if (scores[cSet][3+player] > 0) { + scores[cSet][3+player]--; + } + } else if (scores[cSet][player] > 0) { if (tScores[player] === 0 && tScores[~~!player] === 0) { scores[cSet][player]--; } else { @@ -181,7 +213,9 @@ function score(player) { } else { if (matchEnded()) return; - if (settings.enableTennisScoring) { + if (shouldTiebreak()) { + scores[cSet][3+player]++; + } else if (settings.enableTennisScoring) { if (tScores[player] === 4 && tScores[~~!player] === 5) { // DC : AD tScores[~~!player]--; } else if (tScores[player] === 2 && tScores[~~!player] === 3) { // 30 : 40 @@ -199,6 +233,9 @@ function score(player) { } if (setEnded(cSet) && cSet < sets()) { + if (shouldTiebreak()) { + scores[cSet][player]++; + } updateCurrentSet(1); scores[cSet][2] = getTime(); } @@ -298,20 +335,23 @@ function draw() { for (let p = 0; p < 2; p++) { if (!setWon(set, p === 0 ? 1 : 0) || matchEnded()) { - if (settings.enableTennisScoring && set === cSet) { + let bigNumX = p === 0 ? (w-20)/4+18 : (w-20)/4*3+4; + let smallNumX = p === 0 ? w/2-2 : w/2+3; + + if (settings.enableTennisScoring && set === cSet && !shouldTiebreak()) { g.setFontAlign(0,0); g.setFont('7x11Numeric7Seg',3); g.drawString( formatNumber(tennisScores[tScores[p]]), - p === 0 ? (w-20)/4+20 : (w-20)/4*3+2, + bigNumX, y ); - - g.setFontAlign(p === 0 ? 1 : -1,0); - g.setFont('7x11Numeric7Seg',1); + } else if (shouldTiebreak() && set === cSet) { + g.setFontAlign(0,0); + g.setFont('7x11Numeric7Seg',3); g.drawString( - formatNumber(scores[set][p]), - p === 0 ? w/2-5 : w/2+6, + formatNumber(scores[set][3+p], 3), + bigNumX, y ); } else { @@ -319,7 +359,25 @@ function draw() { g.setFont('7x11Numeric7Seg',3); g.drawString( formatNumber(scores[set][p]), - p === 0 ? (w-20)/4+20 : (w-20)/4*3+2, + bigNumX, + y + ); + } + + if ((shouldTiebreak() || settings.enableTennisScoring) && set === cSet) { + g.setFontAlign(p === 0 ? 1 : -1,0); + g.setFont('7x11Numeric7Seg',1); + g.drawString( + formatNumber(scores[set][p]), + smallNumX, + y + ); + } else if ((scores[set][3] !== 0 || scores[set][4] !== 0) && set !== cSet) { + g.setFontAlign(p === 0 ? 1 : -1,0); + g.setFont('7x11Numeric7Seg',1); + g.drawString( + formatNumber(scores[set][3+p], 3), + smallNumX, y ); } diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index b7a2fefad..c1a0382d2 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -37,6 +37,22 @@ settings.enableTennisScoring = false; } + if (settings.enableMaxScoreTiebreak == null) { + settings.enableMaxScoreTiebreak = false; + } + if (settings.maxScoreTiebreakWinScore == null) { + settings.maxScoreTiebreakWinScore = 6; + } + if (settings.maxScoreTiebreakEnableTwoAhead == null) { + settings.maxScoreTiebreakEnableTwoAhead = true; + } + if (settings.maxScoreTiebreakEnableMaxScore == null) { + settings.maxScoreTiebreakEnableMaxScore = false; + } + if (settings.maxScoreTiebreakMaxScore == null) { + settings.maxScoreTiebreakMaxScore = 15; + } + if (ret) { return settings; } @@ -83,6 +99,29 @@ format: m => offon[~~m], onchange: m => save('enableTennisScoring', m) }; + appMenu['TB sets?'] = { + value: settings.enableMaxScoreTiebreak, + format: m => offon[~~m], + onchange: m => save('enableMaxScoreTiebreak', m) + } + appMenu['TB Score to win'] = { + value: settings.maxScoreTiebreakWinScore, + onchange: m => save('maxScoreTiebreakWinScore', m) + } + appMenu['TB 2-point lead'] = { + value: settings.maxScoreTiebreakEnableTwoAhead, + format: m => offon[~~m], + onchange: m => save('maxScoreTiebreakEnableTwoAhead', m) + } + appMenu['TB max score?'] = { + value: settings.maxScoreTiebreakEnableMaxScore, + format: m => offon[~~m], + onchange: m => save('maxScoreTiebreakEnableMaxScore', m) + } + appMenu['TB max score'] = { + value: settings.maxScoreTiebreakMaxScore, + onchange: m => save('maxScoreTiebreakMaxScore', m) + } E.showMenu(appMenu) From de2e897119b4644fd2744ca35ff4644a79e0e391 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 13:47:49 +0200 Subject: [PATCH 12/52] score: always disable correction mode on new match --- apps/score/score.app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 2566d6922..053a8df43 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -62,6 +62,8 @@ function setupMatch() { cSet = 0; firstShownSet = 0 - Math.floor(setsPerPage() / 2); + + correctionMode = false; } function showSettingsMenu() { From 64930265d7cf00a032894e239c65890a007f2948 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 13:48:12 +0200 Subject: [PATCH 13/52] score: fix automatic scrolling on score --- apps/score/score.app.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 053a8df43..9f22927af 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -182,13 +182,16 @@ function matchScore(player) { } function score(player) { + let setFirstShownSet = function () { + firstShownSet = currentSet() - Math.floor(setsPerPage() / 2); + }; let updateCurrentSet = function (val) { cSet += val; - firstShownSet = Math.max(0, currentSet() - settings.setsPerPage + 1); + setFirstShownSet(); }; if (!matchEnded() || correctionMode) { - firstShownSet = currentSet() - Math.floor(setsPerPage() / 2); + setFirstShownSet(); } if (correctionMode) { From 1983c37a819005179be5cc9b0cd410d272271973 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 13:53:24 +0200 Subject: [PATCH 14/52] score: document tiebreaks --- apps/score/README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/apps/score/README.md b/apps/score/README.md index cdb34902c..ffd35e065 100644 --- a/apps/score/README.md +++ b/apps/score/README.md @@ -14,15 +14,17 @@ To correct a falsely awarded point simply open and close the menu within .5 seco In this mode any score increments will be decrements. To move back a set, reduce both players scores to 0, then decrement one of the scores once again. # Settings -| Setting | Description | -|----------------|------------------------------------------------------------------------------------------------------------------------------| -| Sets to win | How many sets a player has to win before the match is won (Maximum sets: this*2-1) | -| Sets per page | How many sets should be shown in the app. Further sets will be available by scrolling (ignored if higher than `Sets to win`) | -| Score to win | What score ends a given set | -| 2-point lead | Does winning a set require a two-point lead | -| Maximum score? | Should there be a maximum score, at which point the two-point lead rule falls away | -| Maximum score | At which score should the two-point lead rule fall away (ignored if lower than Sets to win) | -| Tennis scoring | If enabled, each point in a set will require a full tennis game | +| Setting | Description | +|------------------------------------|------------------------------------------------------------------------------------------------------------------------------| +| `Sets to win` | How many sets a player has to win before the match is won (Maximum sets: this*2-1) | +| `Sets per page` | How many sets should be shown in the app. Further sets will be available by scrolling (ignored if higher than `Sets to win`) | +| `Score to win` | What score ends a given set | +| `2-point lead` | Does winning a set require a two-point lead | +| `Maximum score?` | Should there be a maximum score, at which point the two-point lead rule falls away | +| `Maximum score` | At which score should the two-point lead rule fall away (ignored if lower than Sets to win) | +| `Tennis scoring` | If enabled, each point in a set will require a full tennis game | +| `TB sets?` | Should sets that have reached `(maxScore-1):(maxScore-1)` be decided with a tiebreak | +| All other options starting with TB | Equivalent to option with same name but applied to tiebreaks | The settings can be changed both from within the app by simply pressing `BTN2` (`BTN1` on Bangle.js 2) or in the `App Settings` in the `Settings` app. From 506918e77239cd67a7a78865670d82cc310473a3 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Mon, 27 Sep 2021 23:04:22 +0200 Subject: [PATCH 15/52] score: fix code style (indent by 2 spaces) --- apps/score/score.app.js | 554 +++++++++++++++++------------------ apps/score/score.settings.js | 232 +++++++-------- 2 files changed, 393 insertions(+), 393 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 9f22927af..7f0b04a59 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -21,93 +21,93 @@ let w = g.getWidth(); let h = g.getHeight(); function setupInputWatchers() { - if (global.BTN4) { - setWatch(() => handleInput(2), BTN2, { repeat: true }); - setWatch(() => handleInput(3), BTN1, { repeat: true }); - setWatch(() => handleInput(4), BTN3, { repeat: true }); + if (global.BTN4) { + setWatch(() => handleInput(2), BTN2, { repeat: true }); + setWatch(() => handleInput(3), BTN1, { repeat: true }); + setWatch(() => handleInput(4), BTN3, { repeat: true }); + } else { + setWatch(() => handleInput(2), BTN, { repeat: true }); + } + Bangle.on('touch', (b, e) => { + if (b) { + if (b === 1) { + handleInput(0); + } else { + handleInput(1); + } } else { - setWatch(() => handleInput(2), BTN, { repeat: true }); + if (e.x < w/2) { + handleInput(0); + } else { + handleInput(1); + } } - Bangle.on('touch', (b, e) => { - if (b) { - if (b === 1) { - handleInput(0); - } else { - handleInput(1); - } - } else { - if (e.x < w/2) { - handleInput(0); - } else { - handleInput(1); - } - } - }); + }); } function setupMatch() { - scores = []; - for (let s = 0; s < sets(); s++) { - scores.push([0,0,null,0,0]); - } + scores = []; + for (let s = 0; s < sets(); s++) { scores.push([0,0,null,0,0]); + } + scores.push([0,0,null,0,0]); - if (settings.enableTennisScoring) { - tScores = [0,0]; - } else { - tScores = null; - } + if (settings.enableTennisScoring) { + tScores = [0,0]; + } else { + tScores = null; + } - scores[0][2] = getTime(); + scores[0][2] = getTime(); - cSet = 0; - firstShownSet = 0 - Math.floor(setsPerPage() / 2); + cSet = 0; + firstShownSet = 0 - Math.floor(setsPerPage() / 2); - correctionMode = false; + correctionMode = false; } function showSettingsMenu() { - settingsMenuOpened = getTime(); - settingsMenu(function (s, reset) { - E.showMenu(); + settingsMenuOpened = getTime(); + settingsMenu(function (s, reset) { + E.showMenu(); - settings = s; + settings = s; - if (reset) { - setupMatch(); - } else if (getTime() - settingsMenuOpened < 0.5 || correctionMode) { - correctionMode = !correctionMode; - } + if (reset) { + setupMatch(); + } else if (getTime() - settingsMenuOpened < 0.5 || correctionMode) { + correctionMode = !correctionMode; + } - settingsMenuOpened = null; + settingsMenuOpened = null; - draw(); - }); + draw(); + }); } function maxScore() { - return Math.max(settings.maxScore, settings.winScore); + return Math.max(settings.maxScore, settings.winScore); } function tiebreakMaxScore() { - return Math.max(settings.maxScoreTiebreakMaxScore, settings.maxScoreTiebreakWinScore); + return Math.max(settings.maxScoreTiebreakMaxScore, settings.maxScoreTiebreakWinScore); } function setsPerPage() { - return Math.min(settings.setsPerPage, sets()); + return Math.min(settings.setsPerPage, sets()); } function sets() { - return settings.winSets * 2 - 1; + return settings.winSets * 2 - 1; } function currentSet() { - return matchEnded() ? cSet - 1 : cSet; + return matchEnded() ? cSet - 1 : cSet; } function shouldTiebreak() { - return settings.enableMaxScoreTiebreak && - scores[cSet][0] + scores[cSet][1] === (maxScore() - 1) * 2; + return settings.enableMaxScoreTiebreak && + scores[cSet][0] + scores[cSet][1] === (maxScore() - 1) * 2; } function formatNumber(num, length) { @@ -115,285 +115,285 @@ function formatNumber(num, length) { } function formatDuration(duration) { - let durS = Math.floor(duration); - let durM = Math.floor(durS / 60); - let durH = Math.floor(durM / 60); - durS = durS - durM * 60; - durM = durM - durH * 60; + let durS = Math.floor(duration); + let durM = Math.floor(durS / 60); + let durH = Math.floor(durM / 60); + durS = durS - durM * 60; + durM = durM - durH * 60; - durS = formatNumber(durS); - durM = formatNumber(durM); - durH = formatNumber(durH); + durS = formatNumber(durS); + durM = formatNumber(durM); + durH = formatNumber(durH); - let dur = null; - if (durH > 0) { - dur = durH + ':' + durM; - } else { - dur = durM + ':' + durS; - } + let dur = null; + if (durH > 0) { + dur = durH + ':' + durM; + } else { + dur = durM + ':' + durS; + } - return dur; + return dur; } function tiebreakWon(set, player) { - let pScore = scores[set][3+player]; - let p2Score = scores[set][3+~~!player]; + let pScore = scores[set][3+player]; + let p2Score = scores[set][3+~~!player]; - let winScoreReached = pScore >= settings.maxScoreTiebreakWinScore; - let isTwoAhead = !settings.maxScoreTiebreakEnableTwoAhead || pScore - p2Score >= 2; - let reachedMaxScore = settings.maxScoreTiebreakEnableMaxScore && pScore >= tiebreakMaxScore(); + let winScoreReached = pScore >= settings.maxScoreTiebreakWinScore; + let isTwoAhead = !settings.maxScoreTiebreakEnableTwoAhead || pScore - p2Score >= 2; + let reachedMaxScore = settings.maxScoreTiebreakEnableMaxScore && pScore >= tiebreakMaxScore(); - return reachedMaxScore || (winScoreReached && isTwoAhead); + return reachedMaxScore || (winScoreReached && isTwoAhead); } function setWon(set, player) { - let pScore = scores[set][player]; - let p2Score = scores[set][~~!player]; + let pScore = scores[set][player]; + let p2Score = scores[set][~~!player]; - let winScoreReached = pScore >= settings.winScore; - let isTwoAhead = !settings.enableTwoAhead || pScore - p2Score >= 2; - let tiebreakW = tiebreakWon(set, player); - let reachedMaxScore = settings.enableMaxScore && pScore >= maxScore(); + let winScoreReached = pScore >= settings.winScore; + let isTwoAhead = !settings.enableTwoAhead || pScore - p2Score >= 2; + let tiebreakW = tiebreakWon(set, player); + let reachedMaxScore = settings.enableMaxScore && pScore >= maxScore(); - return ( - (settings.enableMaxScoreTiebreak ? tiebreakW : reachedMaxScore) || - (winScoreReached && isTwoAhead) - ); + return ( + (settings.enableMaxScoreTiebreak ? tiebreakW : reachedMaxScore) || + (winScoreReached && isTwoAhead) + ); } function setEnded(set) { - return setWon(set, 0) || setWon(set, 1); + return setWon(set, 0) || setWon(set, 1); } function setsWon(player) { - return Array(sets()).fill(0).map((_, s) => ~~setWon(s, player)).reduce((a,v) => a+v, 0); + return Array(sets()).fill(0).map((_, s) => ~~setWon(s, player)).reduce((a,v) => a+v, 0); } function matchWon(player) { - return setsWon(player) >= settings.winSets; + return setsWon(player) >= settings.winSets; } function matchEnded() { - return matchWon(0) || matchWon(1); + return matchWon(0) || matchWon(1); } function matchScore(player) { - return scores.reduce((acc, val) => acc += val[player], 0); + return scores.reduce((acc, val) => acc += val[player], 0); } function score(player) { - let setFirstShownSet = function () { - firstShownSet = currentSet() - Math.floor(setsPerPage() / 2); - }; - let updateCurrentSet = function (val) { - cSet += val; - setFirstShownSet(); - }; + let setFirstShownSet = function () { + firstShownSet = currentSet() - Math.floor(setsPerPage() / 2); + }; + let updateCurrentSet = function (val) { + cSet += val; + setFirstShownSet(); + }; - if (!matchEnded() || correctionMode) { - setFirstShownSet(); + if (!matchEnded() || correctionMode) { + setFirstShownSet(); + } + + if (correctionMode) { + if ( + scores[cSet][0] === 0 && scores[cSet][1] === 0 && + scores[cSet][3] === 0 && scores[cSet][4] === 0 && + cSet > 0 + ) { + updateCurrentSet(-1); } - if (correctionMode) { - if ( - scores[cSet][0] === 0 && scores[cSet][1] === 0 && - scores[cSet][3] === 0 && scores[cSet][4] === 0 && - cSet > 0 - ) { - updateCurrentSet(-1); - } + if (scores[cSet][3] > 0 || scores[cSet][4] > 0) { + if (scores[cSet][3+player] > 0) { + scores[cSet][3+player]--; + } + } else if (scores[cSet][player] > 0) { + if (tScores[player] === 0 && tScores[~~!player] === 0) { + scores[cSet][player]--; + } else { + tScores[player] = 0; + tScores[~~!player] = 0; + } + } + } else { + if (matchEnded()) return; - if (scores[cSet][3] > 0 || scores[cSet][4] > 0) { - if (scores[cSet][3+player] > 0) { - scores[cSet][3+player]--; - } - } else if (scores[cSet][player] > 0) { - if (tScores[player] === 0 && tScores[~~!player] === 0) { - scores[cSet][player]--; - } else { - tScores[player] = 0; - tScores[~~!player] = 0; - } - } + if (shouldTiebreak()) { + scores[cSet][3+player]++; + } else if (settings.enableTennisScoring) { + if (tScores[player] === 4 && tScores[~~!player] === 5) { // DC : AD + tScores[~~!player]--; + } else if (tScores[player] === 2 && tScores[~~!player] === 3) { // 30 : 40 + tScores[0] = 4; + tScores[1] = 4; + } else if (tScores[player] === 3 || tScores[player] === 5) { // 40 / AD + tScores[0] = 0; + tScores[1] = 0; + scores[cSet][player]++; + } else { + tScores[player]++; + } } else { - if (matchEnded()) return; - - if (shouldTiebreak()) { - scores[cSet][3+player]++; - } else if (settings.enableTennisScoring) { - if (tScores[player] === 4 && tScores[~~!player] === 5) { // DC : AD - tScores[~~!player]--; - } else if (tScores[player] === 2 && tScores[~~!player] === 3) { // 30 : 40 - tScores[0] = 4; - tScores[1] = 4; - } else if (tScores[player] === 3 || tScores[player] === 5) { // 40 / AD - tScores[0] = 0; - tScores[1] = 0; - scores[cSet][player]++; - } else { - tScores[player]++; - } - } else { - scores[cSet][player]++; - } - - if (setEnded(cSet) && cSet < sets()) { - if (shouldTiebreak()) { - scores[cSet][player]++; - } - updateCurrentSet(1); - scores[cSet][2] = getTime(); - } - - if (matchEnded()) { - firstShownSet = 0; - } + scores[cSet][player]++; } + + if (setEnded(cSet) && cSet < sets()) { + if (shouldTiebreak()) { + scores[cSet][player]++; + } + updateCurrentSet(1); + scores[cSet][2] = getTime(); + } + + if (matchEnded()) { + firstShownSet = 0; + } + } } function handleInput(button) { - if (settingsMenuOpened) { + if (settingsMenuOpened) { + return; + } + + switch (button) { + case 0: + case 1: + score(button); + break; + case 2: + showSettingsMenu(); return; - } + case 3: + case 4: + let hLimit = currentSet(); + let lLimit = 1 - setsPerPage(); + let val = (button * 2 - 7); + firstShownSet += val; + if (firstShownSet > hLimit) firstShownSet = hLimit; + if (firstShownSet < lLimit) firstShownSet = lLimit; + break; + } - switch (button) { - case 0: - case 1: - score(button); - break; - case 2: - showSettingsMenu(); - return; - case 3: - case 4: - let hLimit = currentSet(); - let lLimit = 1 - setsPerPage(); - let val = (button * 2 - 7); - firstShownSet += val; - if (firstShownSet > hLimit) firstShownSet = hLimit; - if (firstShownSet < lLimit) firstShownSet = lLimit; - break; - } - - draw(); + draw(); } function draw() { - g.setFontAlign(0,0); - g.clear(); + g.setFontAlign(0,0); + g.clear(); + + for (let p = 0; p < 2; p++) { + if (matchWon(p)) { + g.setFontAlign(0,0); + g.setFont('Teletext10x18Ascii',1); + g.drawString("WINNER", p === 0 ? w/4 : w/4*3, 15); + } else if (matchEnded()) { + g.setFontAlign(0,-1); + + let dur1 = formatDuration(scores[cSet][2] - scores[0][2]); + g.setFont('5x9Numeric7Seg',1); + g.drawString(dur1, p === 0 ? w/8 : w/8*5, 10); + + g.setFont('Teletext5x9Ascii',1); + g.drawString((currentSet()+1) + ' set' + (currentSet() > 0 ? 's' : ''), p === 0 ? w/8*3 : w/8*7, 12); + + } + + g.setFontAlign(p === 0 ? -1 : 1,1); + g.setFont('7x11Numeric7Seg',2); + g.drawString(setsWon(p), p === 0 ? 10 : w-8, h-5); + + if (!settings.enableTennisScoring) { + g.setFontAlign(p === 0 ? 1 : -1,1); + g.setFont('7x11Numeric7Seg',2); + g.drawString(formatNumber(matchScore(p), 3), p === 0 ? w/2 - 8 : w/2 + 11, h-5); + } + } + g.setFontAlign(0,0); + + if (correctionMode) { + g.setFont('Teletext10x18Ascii',1); + g.drawString("R", w/2, h-10); + } + + let lastShownSet = Math.min( + sets(), + currentSet() + 1, + firstShownSet+setsPerPage() + ); + let setsOnCurrentPage = Math.min( + sets(), + setsPerPage() + ); + for (let set = firstShownSet; set < lastShownSet; set++) { + if (set < 0) continue; + + let y = (h-15)/(setsOnCurrentPage+1)*(set-firstShownSet+1)+5; + + g.setFontAlign(1,0); + g.setFont('7x11Numeric7Seg',1); + g.drawString(set+1, 40, y-10); + if (scores[set+1][2] != null) { + let dur2 = formatDuration(scores[set+1][2] - scores[set][2]); + g.drawString(dur2, 40, y+10); + } for (let p = 0; p < 2; p++) { - if (matchWon(p)) { - g.setFontAlign(0,0); - g.setFont('Teletext10x18Ascii',1); - g.drawString("WINNER", p === 0 ? w/4 : w/4*3, 15); - } else if (matchEnded()) { - g.setFontAlign(0,-1); - - let dur1 = formatDuration(scores[cSet][2] - scores[0][2]); - g.setFont('5x9Numeric7Seg',1); - g.drawString(dur1, p === 0 ? w/8 : w/8*5, 10); - - g.setFont('Teletext5x9Ascii',1); - g.drawString((currentSet()+1) + ' set' + (currentSet() > 0 ? 's' : ''), p === 0 ? w/8*3 : w/8*7, 12); + if (!setWon(set, p === 0 ? 1 : 0) || matchEnded()) { + let bigNumX = p === 0 ? (w-20)/4+18 : (w-20)/4*3+4; + let smallNumX = p === 0 ? w/2-2 : w/2+3; + if (settings.enableTennisScoring && set === cSet && !shouldTiebreak()) { + g.setFontAlign(0,0); + g.setFont('7x11Numeric7Seg',3); + g.drawString( + formatNumber(tennisScores[tScores[p]]), + bigNumX, + y + ); + } else if (shouldTiebreak() && set === cSet) { + g.setFontAlign(0,0); + g.setFont('7x11Numeric7Seg',3); + g.drawString( + formatNumber(scores[set][3+p], 3), + bigNumX, + y + ); + } else { + g.setFontAlign(0,0); + g.setFont('7x11Numeric7Seg',3); + g.drawString( + formatNumber(scores[set][p]), + bigNumX, + y + ); } - g.setFontAlign(p === 0 ? -1 : 1,1); - g.setFont('7x11Numeric7Seg',2); - g.drawString(setsWon(p), p === 0 ? 10 : w-8, h-5); - - if (!settings.enableTennisScoring) { - g.setFontAlign(p === 0 ? 1 : -1,1); - g.setFont('7x11Numeric7Seg',2); - g.drawString(formatNumber(matchScore(p), 3), p === 0 ? w/2 - 8 : w/2 + 11, h-5); + if ((shouldTiebreak() || settings.enableTennisScoring) && set === cSet) { + g.setFontAlign(p === 0 ? 1 : -1,0); + g.setFont('7x11Numeric7Seg',1); + g.drawString( + formatNumber(scores[set][p]), + smallNumX, + y + ); + } else if ((scores[set][3] !== 0 || scores[set][4] !== 0) && set !== cSet) { + g.setFontAlign(p === 0 ? 1 : -1,0); + g.setFont('7x11Numeric7Seg',1); + g.drawString( + formatNumber(scores[set][3+p], 3), + smallNumX, + y + ); } + } } - g.setFontAlign(0,0); + } - if (correctionMode) { - g.setFont('Teletext10x18Ascii',1); - g.drawString("R", w/2, h-10); - } + // draw separator + g.drawLine(w/2,20,w/2,h-25); - let lastShownSet = Math.min( - sets(), - currentSet() + 1, - firstShownSet+setsPerPage() - ); - let setsOnCurrentPage = Math.min( - sets(), - setsPerPage() - ); - for (let set = firstShownSet; set < lastShownSet; set++) { - if (set < 0) continue; - - let y = (h-15)/(setsOnCurrentPage+1)*(set-firstShownSet+1)+5; - - g.setFontAlign(1,0); - g.setFont('7x11Numeric7Seg',1); - g.drawString(set+1, 40, y-10); - if (scores[set+1][2] != null) { - let dur2 = formatDuration(scores[set+1][2] - scores[set][2]); - g.drawString(dur2, 40, y+10); - } - - for (let p = 0; p < 2; p++) { - if (!setWon(set, p === 0 ? 1 : 0) || matchEnded()) { - let bigNumX = p === 0 ? (w-20)/4+18 : (w-20)/4*3+4; - let smallNumX = p === 0 ? w/2-2 : w/2+3; - - if (settings.enableTennisScoring && set === cSet && !shouldTiebreak()) { - g.setFontAlign(0,0); - g.setFont('7x11Numeric7Seg',3); - g.drawString( - formatNumber(tennisScores[tScores[p]]), - bigNumX, - y - ); - } else if (shouldTiebreak() && set === cSet) { - g.setFontAlign(0,0); - g.setFont('7x11Numeric7Seg',3); - g.drawString( - formatNumber(scores[set][3+p], 3), - bigNumX, - y - ); - } else { - g.setFontAlign(0,0); - g.setFont('7x11Numeric7Seg',3); - g.drawString( - formatNumber(scores[set][p]), - bigNumX, - y - ); - } - - if ((shouldTiebreak() || settings.enableTennisScoring) && set === cSet) { - g.setFontAlign(p === 0 ? 1 : -1,0); - g.setFont('7x11Numeric7Seg',1); - g.drawString( - formatNumber(scores[set][p]), - smallNumX, - y - ); - } else if ((scores[set][3] !== 0 || scores[set][4] !== 0) && set !== cSet) { - g.setFontAlign(p === 0 ? 1 : -1,0); - g.setFont('7x11Numeric7Seg',1); - g.drawString( - formatNumber(scores[set][3+p], 3), - smallNumX, - y - ); - } - } - } - } - - // draw separator - g.drawLine(w/2,20,w/2,h-25); - - g.flip(); + g.flip(); } setupInputWatchers(); diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index c1a0382d2..901867d7b 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -1,128 +1,128 @@ (function (back, ret) { - const fileName = 'score.json' - let settings = require('Storage').readJSON(fileName, 1) || {}; - const offon = ['No', 'Yes']; + const fileName = 'score.json' + let settings = require('Storage').readJSON(fileName, 1) || {}; + const offon = ['No', 'Yes']; - let changed = false; + let changed = false; - function save(key, value) { - changed = true; - settings[key] = value; - if (key === 'winScore' && settings.maxScore < value) { - settings.maxScore = value; - } - require('Storage').writeJSON(fileName, settings); + function save(key, value) { + changed = true; + settings[key] = value; + if (key === 'winScore' && settings.maxScore < value) { + settings.maxScore = value; } + require('Storage').writeJSON(fileName, settings); + } - if (settings.winSets == null) { - settings.winSets = 1; - } - if (settings.setsPerPage == null) { - settings.setsPerPage = 5; - } - if (settings.winScore == null) { - settings.winScore = 21; - } - if (settings.enableTwoAhead == null) { - settings.enableTwoAhead = true; - } - if (settings.enableMaxScore == null) { - settings.enableMaxScore = true; - } - if (settings.maxScore == null) { - settings.maxScore = 30; - } - if (settings.enableTennisScoring == null) { - settings.enableTennisScoring = false; - } + if (settings.winSets == null) { + settings.winSets = 1; + } + if (settings.setsPerPage == null) { + settings.setsPerPage = 5; + } + if (settings.winScore == null) { + settings.winScore = 21; + } + if (settings.enableTwoAhead == null) { + settings.enableTwoAhead = true; + } + if (settings.enableMaxScore == null) { + settings.enableMaxScore = true; + } + if (settings.maxScore == null) { + settings.maxScore = 30; + } + if (settings.enableTennisScoring == null) { + settings.enableTennisScoring = false; + } - if (settings.enableMaxScoreTiebreak == null) { - settings.enableMaxScoreTiebreak = false; - } - if (settings.maxScoreTiebreakWinScore == null) { - settings.maxScoreTiebreakWinScore = 6; - } - if (settings.maxScoreTiebreakEnableTwoAhead == null) { - settings.maxScoreTiebreakEnableTwoAhead = true; - } - if (settings.maxScoreTiebreakEnableMaxScore == null) { - settings.maxScoreTiebreakEnableMaxScore = false; - } - if (settings.maxScoreTiebreakMaxScore == null) { - settings.maxScoreTiebreakMaxScore = 15; - } + if (settings.enableMaxScoreTiebreak == null) { + settings.enableMaxScoreTiebreak = false; + } + if (settings.maxScoreTiebreakWinScore == null) { + settings.maxScoreTiebreakWinScore = 6; + } + if (settings.maxScoreTiebreakEnableTwoAhead == null) { + settings.maxScoreTiebreakEnableTwoAhead = true; + } + if (settings.maxScoreTiebreakEnableMaxScore == null) { + settings.maxScoreTiebreakEnableMaxScore = false; + } + if (settings.maxScoreTiebreakMaxScore == null) { + settings.maxScoreTiebreakMaxScore = 15; + } - if (ret) { - return settings; - } + if (ret) { + return settings; + } - const appMenu = {}; - appMenu[''] = {'title': 'Score Settings'}, - appMenu['< Back'] = function () { back(settings, changed); }; - if (reset) { - appMenu['Reset match'] = function () { back(settings, true); }; - } - appMenu['Sets to win'] = { - value: settings.winSets, - min:1, - onchange: m => save('winSets', m) - }; - appMenu['Sets per page'] = { - value: settings.setsPerPage, - min:1, - max:5, - onchange: m => save('setsPerPage', m) - }; - appMenu['Score to win'] = { - value: settings.winScore, - min:1, - onchange: m => save('winScore', m) - }; - appMenu['2-point lead'] = { - value: settings.enableTwoAhead, - format: m => offon[~~m], - onchange: m => save('enableTwoAhead', m) - }; - appMenu['Maximum score?'] = { - value: settings.enableMaxScore, - format: m => offon[~~m], - onchange: m => save('enableMaxScore', m) - }; - appMenu['Maximum score'] = { - value: settings.maxScore, - min: 1, - onchange: m => save('maxScore', m) - }; - appMenu['Tennis scoring'] = { - value: settings.enableTennisScoring, - format: m => offon[~~m], - onchange: m => save('enableTennisScoring', m) - }; - appMenu['TB sets?'] = { - value: settings.enableMaxScoreTiebreak, - format: m => offon[~~m], - onchange: m => save('enableMaxScoreTiebreak', m) - } - appMenu['TB Score to win'] = { - value: settings.maxScoreTiebreakWinScore, - onchange: m => save('maxScoreTiebreakWinScore', m) - } - appMenu['TB 2-point lead'] = { - value: settings.maxScoreTiebreakEnableTwoAhead, - format: m => offon[~~m], - onchange: m => save('maxScoreTiebreakEnableTwoAhead', m) - } - appMenu['TB max score?'] = { - value: settings.maxScoreTiebreakEnableMaxScore, - format: m => offon[~~m], - onchange: m => save('maxScoreTiebreakEnableMaxScore', m) - } - appMenu['TB max score'] = { - value: settings.maxScoreTiebreakMaxScore, - onchange: m => save('maxScoreTiebreakMaxScore', m) - } + const appMenu = {}; + appMenu[''] = {'title': 'Score Settings'}, + appMenu['< Back'] = function () { back(settings, changed); }; + if (reset) { + appMenu['Reset match'] = function () { back(settings, true); }; + } + appMenu['Sets to win'] = { + value: settings.winSets, + min:1, + onchange: m => save('winSets', m) + }; + appMenu['Sets per page'] = { + value: settings.setsPerPage, + min:1, + max:5, + onchange: m => save('setsPerPage', m) + }; + appMenu['Score to win'] = { + value: settings.winScore, + min:1, + onchange: m => save('winScore', m) + }; + appMenu['2-point lead'] = { + value: settings.enableTwoAhead, + format: m => offon[~~m], + onchange: m => save('enableTwoAhead', m) + }; + appMenu['Maximum score?'] = { + value: settings.enableMaxScore, + format: m => offon[~~m], + onchange: m => save('enableMaxScore', m) + }; + appMenu['Maximum score'] = { + value: settings.maxScore, + min: 1, + onchange: m => save('maxScore', m) + }; + appMenu['Tennis scoring'] = { + value: settings.enableTennisScoring, + format: m => offon[~~m], + onchange: m => save('enableTennisScoring', m) + }; + appMenu['TB sets?'] = { + value: settings.enableMaxScoreTiebreak, + format: m => offon[~~m], + onchange: m => save('enableMaxScoreTiebreak', m) + } + appMenu['TB Score to win'] = { + value: settings.maxScoreTiebreakWinScore, + onchange: m => save('maxScoreTiebreakWinScore', m) + } + appMenu['TB 2-point lead'] = { + value: settings.maxScoreTiebreakEnableTwoAhead, + format: m => offon[~~m], + onchange: m => save('maxScoreTiebreakEnableTwoAhead', m) + } + appMenu['TB max score?'] = { + value: settings.maxScoreTiebreakEnableMaxScore, + format: m => offon[~~m], + onchange: m => save('maxScoreTiebreakEnableMaxScore', m) + } + appMenu['TB max score'] = { + value: settings.maxScoreTiebreakMaxScore, + onchange: m => save('maxScoreTiebreakMaxScore', m) + } - E.showMenu(appMenu) + E.showMenu(appMenu) }) From 9f73450b8318b930cdf6108184ebc9f757393c91 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 01:03:13 +0200 Subject: [PATCH 16/52] score: add configuration preset functionality --- apps.json | 1 + apps/score/README.md | 1 + apps/score/score.presets.json | 1 + apps/score/score.settings.js | 208 ++++++++++++++++++++-------------- 4 files changed, 127 insertions(+), 84 deletions(-) create mode 100644 apps/score/score.presets.json diff --git a/apps.json b/apps.json index c98686e72..b1e6f70fc 100644 --- a/apps.json +++ b/apps.json @@ -3565,6 +3565,7 @@ "storage": [ {"name":"score.app.js","url":"score.app.js"}, {"name":"score.settings.js","url":"score.settings.js"}, + {"name":"score.presets.json","url":"score.presets.json"}, {"name":"score.img","url":"score.app-icon.js","evaluate":true} ] } diff --git a/apps/score/README.md b/apps/score/README.md index ffd35e065..c3ad0e622 100644 --- a/apps/score/README.md +++ b/apps/score/README.md @@ -16,6 +16,7 @@ In this mode any score increments will be decrements. To move back a set, reduce # Settings | Setting | Description | |------------------------------------|------------------------------------------------------------------------------------------------------------------------------| +| `Presets` | Enable a preset for one of the configured sports | | `Sets to win` | How many sets a player has to win before the match is won (Maximum sets: this*2-1) | | `Sets per page` | How many sets should be shown in the app. Further sets will be available by scrolling (ignored if higher than `Sets to win`) | | `Score to win` | What score ends a given set | diff --git a/apps/score/score.presets.json b/apps/score/score.presets.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/apps/score/score.presets.json @@ -0,0 +1 @@ +{} diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index 901867d7b..cbae83f0c 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -1,20 +1,4 @@ -(function (back, ret) { - - const fileName = 'score.json' - let settings = require('Storage').readJSON(fileName, 1) || {}; - const offon = ['No', 'Yes']; - - let changed = false; - - function save(key, value) { - changed = true; - settings[key] = value; - if (key === 'winScore' && settings.maxScore < value) { - settings.maxScore = value; - } - require('Storage').writeJSON(fileName, settings); - } - +function fillSettingsWithDefaults(settings) { if (settings.winSets == null) { settings.winSets = 1; } @@ -53,76 +37,132 @@ settings.maxScoreTiebreakMaxScore = 15; } + return settings; +} + +(function (back, ret) { + + const fileName = 'score.json'; + let settings = require('Storage').readJSON(fileName, 1) || {}; + const offon = ['No', 'Yes']; + + let presetsFileName = 'score.presets.json'; + let presets = require('Storage').readJSON(presetsFileName); + let presetNames = Object.keys(presets); + + let changed = false; + + function save(settings) { + require('Storage').writeJSON(fileName, settings); + } + + function setAndSave(key, value) { + changed = true; + settings[key] = value; + if (key === 'winScore' && settings.maxScore < value) { + settings.maxScore = value; + } + save(settings); + } + + settings = fillSettingsWithDefaults(settings); + if (ret) { return settings; } - const appMenu = {}; - appMenu[''] = {'title': 'Score Settings'}, - appMenu['< Back'] = function () { back(settings, changed); }; - if (reset) { - appMenu['Reset match'] = function () { back(settings, true); }; - } - appMenu['Sets to win'] = { - value: settings.winSets, - min:1, - onchange: m => save('winSets', m) - }; - appMenu['Sets per page'] = { - value: settings.setsPerPage, - min:1, - max:5, - onchange: m => save('setsPerPage', m) - }; - appMenu['Score to win'] = { - value: settings.winScore, - min:1, - onchange: m => save('winScore', m) - }; - appMenu['2-point lead'] = { - value: settings.enableTwoAhead, - format: m => offon[~~m], - onchange: m => save('enableTwoAhead', m) - }; - appMenu['Maximum score?'] = { - value: settings.enableMaxScore, - format: m => offon[~~m], - onchange: m => save('enableMaxScore', m) - }; - appMenu['Maximum score'] = { - value: settings.maxScore, - min: 1, - onchange: m => save('maxScore', m) - }; - appMenu['Tennis scoring'] = { - value: settings.enableTennisScoring, - format: m => offon[~~m], - onchange: m => save('enableTennisScoring', m) - }; - appMenu['TB sets?'] = { - value: settings.enableMaxScoreTiebreak, - format: m => offon[~~m], - onchange: m => save('enableMaxScoreTiebreak', m) - } - appMenu['TB Score to win'] = { - value: settings.maxScoreTiebreakWinScore, - onchange: m => save('maxScoreTiebreakWinScore', m) - } - appMenu['TB 2-point lead'] = { - value: settings.maxScoreTiebreakEnableTwoAhead, - format: m => offon[~~m], - onchange: m => save('maxScoreTiebreakEnableTwoAhead', m) - } - appMenu['TB max score?'] = { - value: settings.maxScoreTiebreakEnableMaxScore, - format: m => offon[~~m], - onchange: m => save('maxScoreTiebreakEnableMaxScore', m) - } - appMenu['TB max score'] = { - value: settings.maxScoreTiebreakMaxScore, - onchange: m => save('maxScoreTiebreakMaxScore', m) - } + const presetMenu = function () { + let ret = function () { E.showMenu(appMenu()); }; + let m = { + '': {'title': 'Score Presets'}, + '< Back': ret, + }; + for (let i = 0; i < presetNames.length; i++) { + m[presetNames[i]] = (function (i) { + return function() { + changed = true; + settings = fillSettingsWithDefaults(presets[presetNames[i]]); + save(settings); + ret(); + }; + })(i); + } - E.showMenu(appMenu) + return m; + }; -}) + const appMenu = function () { + let m = {}; + + m[''] = {'title': 'Score Settings'}; + m['< Back'] = function () { back(settings, changed); }; + if (reset) { + m['Reset match'] = function () { back(settings, true); }; + } + m['Presets'] = function () { E.showMenu(presetMenu()); }; + m['Sets to win'] = { + value: settings.winSets, + min:1, + onchange: m => setAndSave('winSets', m), + }; + m['Sets per page'] = { + value: settings.setsPerPage, + min:1, + max:5, + onchange: m => setAndSave('setsPerPage', m), + }; + m['Score to win'] = { + value: settings.winScore, + min:1, + onchange: m => setAndSave('winScore', m), + }; + m['2-point lead'] = { + value: settings.enableTwoAhead, + format: m => offon[~~m], + onchange: m => setAndSave('enableTwoAhead', m), + }; + m['Maximum score?'] = { + value: settings.enableMaxScore, + format: m => offon[~~m], + onchange: m => setAndSave('enableMaxScore', m), + }; + m['Maximum score'] = { + value: settings.maxScore, + min: 1, + onchange: m => setAndSave('maxScore', m), + }; + m['Tennis scoring'] = { + value: settings.enableTennisScoring, + format: m => offon[~~m], + onchange: m => setAndSave('enableTennisScoring', m), + }; + m['TB sets?'] = { + value: settings.enableMaxScoreTiebreak, + format: m => offon[~~m], + onchange: m => setAndSave('enableMaxScoreTiebreak', m), + }; + m['TB Score to win'] = { + value: settings.maxScoreTiebreakWinScore, + onchange: m => setAndSave('maxScoreTiebreakWinScore', m), + }; + m['TB 2-point lead'] = { + value: settings.maxScoreTiebreakEnableTwoAhead, + format: m => offon[~~m], + onchange: m => setAndSave('maxScoreTiebreakEnableTwoAhead', m), + }; + m['TB max score?'] = { + value: settings.maxScoreTiebreakEnableMaxScore, + format: m => offon[~~m], + onchange: m => setAndSave('maxScoreTiebreakEnableMaxScore', m), + }; + m['TB max score'] = { + value: settings.maxScoreTiebreakMaxScore, + onchange: m => setAndSave('maxScoreTiebreakMaxScore', m), + }; + + return m; + }; + + E.showMenu(appMenu()); + +}); From a516d409919e0f4052321bc5713b4a6caa67a31c Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 01:04:13 +0200 Subject: [PATCH 17/52] score: add badminton config preset --- apps/score/score.presets.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/score/score.presets.json b/apps/score/score.presets.json index 0967ef424..12b030044 100644 --- a/apps/score/score.presets.json +++ b/apps/score/score.presets.json @@ -1 +1,8 @@ -{} +{ + "Badminton": { + "winScore": 21, + "enableTwoAhead": true, + "enableMaxScore": true, + "maxScore": 30 + } +} From 8567e3d8e156592640d4d6495199e5fcd7716b76 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 01:04:26 +0200 Subject: [PATCH 18/52] score: add tennis config preset --- apps/score/score.presets.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/score/score.presets.json b/apps/score/score.presets.json index 12b030044..fe11c9e6b 100644 --- a/apps/score/score.presets.json +++ b/apps/score/score.presets.json @@ -4,5 +4,16 @@ "enableTwoAhead": true, "enableMaxScore": true, "maxScore": 30 + }, + "Tennis": { + "winScore": 6, + "enableTwoAhead": true, + "enableMaxScore": true, + "maxScore": 7, + "enableMaxScoreTiebreak": true, + "maxScoreTiebreakWinScore": 7, + "maxScoreTiebreakEnableTwoAhead": true, + "maxScoreTiebreakEnableMaxScore": false, + "enableTennisScoring": true } } From ad90c410d7a3c4fa959a5cfdca5768c633b566e7 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 01:09:13 +0200 Subject: [PATCH 19/52] score: select winSets entry after selecting preset --- apps/score/score.settings.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index cbae83f0c..8442fd80b 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -72,7 +72,7 @@ function fillSettingsWithDefaults(settings) { } const presetMenu = function () { - let ret = function () { E.showMenu(appMenu()); }; + let ret = function (changed) { E.showMenu(appMenu(changed ? 3 : null)); }; let m = { '': {'title': 'Score Presets'}, '< Back': ret, @@ -83,7 +83,7 @@ function fillSettingsWithDefaults(settings) { changed = true; settings = fillSettingsWithDefaults(presets[presetNames[i]]); save(settings); - ret(); + ret(true); }; })(i); } @@ -91,10 +91,13 @@ function fillSettingsWithDefaults(settings) { return m; }; - const appMenu = function () { + const appMenu = function (selected) { let m = {}; m[''] = {'title': 'Score Settings'}; + if (selected != null) { + m[''].selected = selected; + } m['< Back'] = function () { back(settings, changed); }; if (reset) { m['Reset match'] = function () { back(settings, true); }; From ecc4e59a01fb82edc096040a05eeaa13eee0c43a Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 14:02:15 +0200 Subject: [PATCH 20/52] score: set default winSets to 2 --- apps/score/score.settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index 8442fd80b..83a98d93f 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -1,6 +1,6 @@ function fillSettingsWithDefaults(settings) { if (settings.winSets == null) { - settings.winSets = 1; + settings.winSets = 2; } if (settings.setsPerPage == null) { settings.setsPerPage = 5; From 7074340f444c25100434ee3101a30424ba626fba Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 14:03:23 +0200 Subject: [PATCH 21/52] score: add additional in-app menu, allow ending current set --- apps/score/score.app.js | 50 ++++++++++++++++++++++++------------ apps/score/score.settings.js | 33 +++++++++++++++++------- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 7f0b04a59..4b72f911c 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -4,7 +4,7 @@ require('FontTeletext5x9Ascii').add(Graphics); require('FontTeletext10x18Ascii').add(Graphics); let settingsMenu = eval(require('Storage').read('score.settings.js')); -let settings = settingsMenu(null, true); +let settings = settingsMenu(null, null, true); let tennisScores = ['00','15','30','40','DC','AD']; @@ -61,7 +61,7 @@ function setupMatch() { scores[0][2] = getTime(); cSet = 0; - firstShownSet = 0 - Math.floor(setsPerPage() / 2); + setFirstShownSet(); correctionMode = false; } @@ -82,6 +82,12 @@ function showSettingsMenu() { settingsMenuOpened = null; draw(); + }, function (msg) { + switch (msg) { + case 'end_set': + updateCurrentSet(1); + break; + } }); } @@ -154,10 +160,12 @@ function setWon(set, player) { let isTwoAhead = !settings.enableTwoAhead || pScore - p2Score >= 2; let tiebreakW = tiebreakWon(set, player); let reachedMaxScore = settings.enableMaxScore && pScore >= maxScore(); + let manuallyEndedWon = cSet > set ? pScore > p2Score : false return ( (settings.enableMaxScoreTiebreak ? tiebreakW : reachedMaxScore) || - (winScoreReached && isTwoAhead) + (winScoreReached && isTwoAhead) || + manuallyEndedWon ); } @@ -181,15 +189,30 @@ function matchScore(player) { return scores.reduce((acc, val) => acc += val[player], 0); } -function score(player) { - let setFirstShownSet = function () { - firstShownSet = currentSet() - Math.floor(setsPerPage() / 2); - }; - let updateCurrentSet = function (val) { - cSet += val; - setFirstShownSet(); - }; +function setFirstShownSet() { + firstShownSet = Math.max(0, currentSet() - setsPerPage() + 1); +} +function updateCurrentSet(val) { + if (val > 0) { + cSet++ + } else if (val < 0) { + cSet-- + } else { + return; + } + setFirstShownSet(); + + if (matchEnded()) { + firstShownSet = 0; + } + + if (val > 0) { + scores[cSet][2] = getTime(); + } +} + +function score(player) { if (!matchEnded() || correctionMode) { setFirstShownSet(); } @@ -242,11 +265,6 @@ function score(player) { scores[cSet][player]++; } updateCurrentSet(1); - scores[cSet][2] = getTime(); - } - - if (matchEnded()) { - firstShownSet = 0; } } } diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index 83a98d93f..4a4b5e56a 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -40,7 +40,7 @@ function fillSettingsWithDefaults(settings) { return settings; } -(function (back, ret) { +(function (back, inApp, ret) { const fileName = 'score.json'; let settings = require('Storage').readJSON(fileName, 1) || {}; @@ -71,8 +71,8 @@ function fillSettingsWithDefaults(settings) { return settings; } - const presetMenu = function () { - let ret = function (changed) { E.showMenu(appMenu(changed ? 3 : null)); }; + const presetMenu = function (appMenuBack) { + let ret = function (changed) { E.showMenu(appMenu(appMenuBack, changed ? 2 : null)); }; let m = { '': {'title': 'Score Presets'}, '< Back': ret, @@ -91,7 +91,7 @@ function fillSettingsWithDefaults(settings) { return m; }; - const appMenu = function (selected) { + const appMenu = function (back, selected) { let m = {}; m[''] = {'title': 'Score Settings'}; @@ -99,10 +99,7 @@ function fillSettingsWithDefaults(settings) { m[''].selected = selected; } m['< Back'] = function () { back(settings, changed); }; - if (reset) { - m['Reset match'] = function () { back(settings, true); }; - } - m['Presets'] = function () { E.showMenu(presetMenu()); }; + m['Presets'] = function () { E.showMenu(presetMenu(back)); }; m['Sets to win'] = { value: settings.winSets, min:1, @@ -166,6 +163,24 @@ function fillSettingsWithDefaults(settings) { return m; }; - E.showMenu(appMenu()); + const inAppMenu = function () { + let m = { + '': {'title': 'Score Menu'}, + '< Back': function () { back(settings, changed); }, + 'Reset match': function () { back(settings, true); }, + 'End current set': function () { inApp('end_set'); back(settings, changed); }, + 'Configuration': function () { E.showMenu(appMenu(function () { + E.showMenu(inAppMenu()); + })); }, + }; + + return m; + }; + + if (inApp != null) { + E.showMenu(inAppMenu()); + } else { + E.showMenu(appMenu(back)); + } }); From e27303a09a0d899675fea361e691de2a781df101 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 14:04:15 +0200 Subject: [PATCH 22/52] score: code style + firstShownSet limits --- apps/score/score.app.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 4b72f911c..4409b86b6 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -275,22 +275,22 @@ function handleInput(button) { } switch (button) { - case 0: - case 1: - score(button); - break; - case 2: - showSettingsMenu(); - return; - case 3: - case 4: - let hLimit = currentSet(); - let lLimit = 1 - setsPerPage(); - let val = (button * 2 - 7); - firstShownSet += val; - if (firstShownSet > hLimit) firstShownSet = hLimit; - if (firstShownSet < lLimit) firstShownSet = lLimit; - break; + case 0: + case 1: + score(button); + break; + case 2: + showSettingsMenu(); + return; + case 3: + case 4: + let hLimit = currentSet() - setsPerPage() + 1; + let lLimit = 0; + let val = (button * 2 - 7); + firstShownSet += val; + if (firstShownSet > hLimit) firstShownSet = hLimit; + if (firstShownSet < lLimit) firstShownSet = lLimit; + break; } draw(); From a504addd8f220ea786053bb613f3bf029d414958 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 14:29:34 +0200 Subject: [PATCH 23/52] score: remove reference to Teletext10x18Ascii font --- apps/score/score.app.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 4409b86b6..c9ed89260 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -1,7 +1,6 @@ require('Font5x9Numeric7Seg').add(Graphics); require('Font7x11Numeric7Seg').add(Graphics); require('FontTeletext5x9Ascii').add(Graphics); -require('FontTeletext10x18Ascii').add(Graphics); let settingsMenu = eval(require('Storage').read('score.settings.js')); let settings = settingsMenu(null, null, true); @@ -303,7 +302,7 @@ function draw() { for (let p = 0; p < 2; p++) { if (matchWon(p)) { g.setFontAlign(0,0); - g.setFont('Teletext10x18Ascii',1); + g.setFont('Teletext5x9Ascii',2); g.drawString("WINNER", p === 0 ? w/4 : w/4*3, 15); } else if (matchEnded()) { g.setFontAlign(0,-1); @@ -318,7 +317,7 @@ function draw() { } g.setFontAlign(p === 0 ? -1 : 1,1); - g.setFont('7x11Numeric7Seg',2); + g.setFont('5x9Numeric7Seg',2); g.drawString(setsWon(p), p === 0 ? 10 : w-8, h-5); if (!settings.enableTennisScoring) { @@ -330,7 +329,7 @@ function draw() { g.setFontAlign(0,0); if (correctionMode) { - g.setFont('Teletext10x18Ascii',1); + g.setFont('Teletext5x9Ascii',2); g.drawString("R", w/2, h-10); } From 978c181435f9afa14b6705e073fd95999109c495 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 14:30:05 +0200 Subject: [PATCH 24/52] score: fix correctionMode without tennis scoring --- apps/score/score.app.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index c9ed89260..eb373ed50 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -230,7 +230,10 @@ function score(player) { scores[cSet][3+player]--; } } else if (scores[cSet][player] > 0) { - if (tScores[player] === 0 && tScores[~~!player] === 0) { + if ( + !settings.enableTennisScoring || + (tScores[player] === 0 && tScores[~~!player] === 0) + ) { scores[cSet][player]--; } else { tScores[player] = 0; From f3398e65501ba3d0bbd52a2f703943ca3fb53ca0 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 14:32:14 +0200 Subject: [PATCH 25/52] score: add preset for soccer --- apps/score/score.presets.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/score/score.presets.json b/apps/score/score.presets.json index fe11c9e6b..3224556a6 100644 --- a/apps/score/score.presets.json +++ b/apps/score/score.presets.json @@ -15,5 +15,11 @@ "maxScoreTiebreakEnableTwoAhead": true, "maxScoreTiebreakEnableMaxScore": false, "enableTennisScoring": true + }, + "Soccer": { + "winSets": 1, + "winScore": 9999, + "enableTwoAhead": false, + "enableMaxScore": false } } From 6155893856c42248e0c3a070f9112aebd802050b Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 14:36:25 +0200 Subject: [PATCH 26/52] score: add preset for table tennis --- apps/score/score.presets.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/score/score.presets.json b/apps/score/score.presets.json index 3224556a6..b57b52157 100644 --- a/apps/score/score.presets.json +++ b/apps/score/score.presets.json @@ -21,5 +21,10 @@ "winScore": 9999, "enableTwoAhead": false, "enableMaxScore": false + }, + "Table Tennis": { + "winScore": 11, + "enableTwoAhead": true, + "enableMaxScore": false } } From f4d820bf607c4ec16c955464364a595c0f457f96 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 15:43:21 +0200 Subject: [PATCH 27/52] score: code style --- apps/score/score.app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index eb373ed50..48f503cb7 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -159,7 +159,7 @@ function setWon(set, player) { let isTwoAhead = !settings.enableTwoAhead || pScore - p2Score >= 2; let tiebreakW = tiebreakWon(set, player); let reachedMaxScore = settings.enableMaxScore && pScore >= maxScore(); - let manuallyEndedWon = cSet > set ? pScore > p2Score : false + let manuallyEndedWon = cSet > set ? pScore > p2Score : false; return ( (settings.enableMaxScoreTiebreak ? tiebreakW : reachedMaxScore) || @@ -194,9 +194,9 @@ function setFirstShownSet() { function updateCurrentSet(val) { if (val > 0) { - cSet++ + cSet++; } else if (val < 0) { - cSet-- + cSet--; } else { return; } From 7a98c039e705e67db0f10e94c7623cc6769c7b78 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 15:47:19 +0200 Subject: [PATCH 28/52] score: fix settings module --- apps/score/score.settings.js | 83 ++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index 4a4b5e56a..c4e22e45d 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -1,46 +1,45 @@ -function fillSettingsWithDefaults(settings) { - if (settings.winSets == null) { - settings.winSets = 2; - } - if (settings.setsPerPage == null) { - settings.setsPerPage = 5; - } - if (settings.winScore == null) { - settings.winScore = 21; - } - if (settings.enableTwoAhead == null) { - settings.enableTwoAhead = true; - } - if (settings.enableMaxScore == null) { - settings.enableMaxScore = true; - } - if (settings.maxScore == null) { - settings.maxScore = 30; - } - if (settings.enableTennisScoring == null) { - settings.enableTennisScoring = false; - } - - if (settings.enableMaxScoreTiebreak == null) { - settings.enableMaxScoreTiebreak = false; - } - if (settings.maxScoreTiebreakWinScore == null) { - settings.maxScoreTiebreakWinScore = 6; - } - if (settings.maxScoreTiebreakEnableTwoAhead == null) { - settings.maxScoreTiebreakEnableTwoAhead = true; - } - if (settings.maxScoreTiebreakEnableMaxScore == null) { - settings.maxScoreTiebreakEnableMaxScore = false; - } - if (settings.maxScoreTiebreakMaxScore == null) { - settings.maxScoreTiebreakMaxScore = 15; - } - - return settings; -} - (function (back, inApp, ret) { + function fillSettingsWithDefaults(settings) { + if (settings.winSets == null) { + settings.winSets = 2; + } + if (settings.setsPerPage == null) { + settings.setsPerPage = 5; + } + if (settings.winScore == null) { + settings.winScore = 21; + } + if (settings.enableTwoAhead == null) { + settings.enableTwoAhead = true; + } + if (settings.enableMaxScore == null) { + settings.enableMaxScore = true; + } + if (settings.maxScore == null) { + settings.maxScore = 30; + } + if (settings.enableTennisScoring == null) { + settings.enableTennisScoring = false; + } + + if (settings.enableMaxScoreTiebreak == null) { + settings.enableMaxScoreTiebreak = false; + } + if (settings.maxScoreTiebreakWinScore == null) { + settings.maxScoreTiebreakWinScore = 6; + } + if (settings.maxScoreTiebreakEnableTwoAhead == null) { + settings.maxScoreTiebreakEnableTwoAhead = true; + } + if (settings.maxScoreTiebreakEnableMaxScore == null) { + settings.maxScoreTiebreakEnableMaxScore = false; + } + if (settings.maxScoreTiebreakMaxScore == null) { + settings.maxScoreTiebreakMaxScore = 15; + } + + return settings; + } const fileName = 'score.json'; let settings = require('Storage').readJSON(fileName, 1) || {}; From ea3cfece674c5af827ca4fb077694fc1098c4daf Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 15:57:56 +0200 Subject: [PATCH 29/52] score: prevent warning in web ide for settings module --- apps/score/score.settings.js | 342 ++++++++++++++++++----------------- 1 file changed, 172 insertions(+), 170 deletions(-) diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index c4e22e45d..da35d7a21 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -1,185 +1,187 @@ -(function (back, inApp, ret) { - function fillSettingsWithDefaults(settings) { - if (settings.winSets == null) { - settings.winSets = 2; - } - if (settings.setsPerPage == null) { - settings.setsPerPage = 5; - } - if (settings.winScore == null) { - settings.winScore = 21; - } - if (settings.enableTwoAhead == null) { - settings.enableTwoAhead = true; - } - if (settings.enableMaxScore == null) { - settings.enableMaxScore = true; - } - if (settings.maxScore == null) { - settings.maxScore = 30; - } - if (settings.enableTennisScoring == null) { - settings.enableTennisScoring = false; +(function () { + return (function (back, inApp, ret) { + function fillSettingsWithDefaults(settings) { + if (settings.winSets == null) { + settings.winSets = 2; + } + if (settings.setsPerPage == null) { + settings.setsPerPage = 5; + } + if (settings.winScore == null) { + settings.winScore = 21; + } + if (settings.enableTwoAhead == null) { + settings.enableTwoAhead = true; + } + if (settings.enableMaxScore == null) { + settings.enableMaxScore = true; + } + if (settings.maxScore == null) { + settings.maxScore = 30; + } + if (settings.enableTennisScoring == null) { + settings.enableTennisScoring = false; + } + + if (settings.enableMaxScoreTiebreak == null) { + settings.enableMaxScoreTiebreak = false; + } + if (settings.maxScoreTiebreakWinScore == null) { + settings.maxScoreTiebreakWinScore = 6; + } + if (settings.maxScoreTiebreakEnableTwoAhead == null) { + settings.maxScoreTiebreakEnableTwoAhead = true; + } + if (settings.maxScoreTiebreakEnableMaxScore == null) { + settings.maxScoreTiebreakEnableMaxScore = false; + } + if (settings.maxScoreTiebreakMaxScore == null) { + settings.maxScoreTiebreakMaxScore = 15; + } + + return settings; } - if (settings.enableMaxScoreTiebreak == null) { - settings.enableMaxScoreTiebreak = false; - } - if (settings.maxScoreTiebreakWinScore == null) { - settings.maxScoreTiebreakWinScore = 6; - } - if (settings.maxScoreTiebreakEnableTwoAhead == null) { - settings.maxScoreTiebreakEnableTwoAhead = true; - } - if (settings.maxScoreTiebreakEnableMaxScore == null) { - settings.maxScoreTiebreakEnableMaxScore = false; - } - if (settings.maxScoreTiebreakMaxScore == null) { - settings.maxScoreTiebreakMaxScore = 15; + const fileName = 'score.json'; + let settings = require('Storage').readJSON(fileName, 1) || {}; + const offon = ['No', 'Yes']; + + let presetsFileName = 'score.presets.json'; + let presets = require('Storage').readJSON(presetsFileName); + let presetNames = Object.keys(presets); + + let changed = false; + + function save(settings) { + require('Storage').writeJSON(fileName, settings); } - return settings; - } - - const fileName = 'score.json'; - let settings = require('Storage').readJSON(fileName, 1) || {}; - const offon = ['No', 'Yes']; - - let presetsFileName = 'score.presets.json'; - let presets = require('Storage').readJSON(presetsFileName); - let presetNames = Object.keys(presets); - - let changed = false; - - function save(settings) { - require('Storage').writeJSON(fileName, settings); - } - - function setAndSave(key, value) { - changed = true; - settings[key] = value; - if (key === 'winScore' && settings.maxScore < value) { - settings.maxScore = value; - } - save(settings); - } - - settings = fillSettingsWithDefaults(settings); - - if (ret) { - return settings; - } - - const presetMenu = function (appMenuBack) { - let ret = function (changed) { E.showMenu(appMenu(appMenuBack, changed ? 2 : null)); }; - let m = { - '': {'title': 'Score Presets'}, - '< Back': ret, - }; - for (let i = 0; i < presetNames.length; i++) { - m[presetNames[i]] = (function (i) { - return function() { - changed = true; - settings = fillSettingsWithDefaults(presets[presetNames[i]]); - save(settings); - ret(true); - }; - })(i); + function setAndSave(key, value) { + changed = true; + settings[key] = value; + if (key === 'winScore' && settings.maxScore < value) { + settings.maxScore = value; + } + save(settings); } - return m; - }; + settings = fillSettingsWithDefaults(settings); - const appMenu = function (back, selected) { - let m = {}; - - m[''] = {'title': 'Score Settings'}; - if (selected != null) { - m[''].selected = selected; + if (ret) { + return settings; } - m['< Back'] = function () { back(settings, changed); }; - m['Presets'] = function () { E.showMenu(presetMenu(back)); }; - m['Sets to win'] = { - value: settings.winSets, - min:1, - onchange: m => setAndSave('winSets', m), - }; - m['Sets per page'] = { - value: settings.setsPerPage, - min:1, - max:5, - onchange: m => setAndSave('setsPerPage', m), - }; - m['Score to win'] = { - value: settings.winScore, - min:1, - onchange: m => setAndSave('winScore', m), - }; - m['2-point lead'] = { - value: settings.enableTwoAhead, - format: m => offon[~~m], - onchange: m => setAndSave('enableTwoAhead', m), - }; - m['Maximum score?'] = { - value: settings.enableMaxScore, - format: m => offon[~~m], - onchange: m => setAndSave('enableMaxScore', m), - }; - m['Maximum score'] = { - value: settings.maxScore, - min: 1, - onchange: m => setAndSave('maxScore', m), - }; - m['Tennis scoring'] = { - value: settings.enableTennisScoring, - format: m => offon[~~m], - onchange: m => setAndSave('enableTennisScoring', m), - }; - m['TB sets?'] = { - value: settings.enableMaxScoreTiebreak, - format: m => offon[~~m], - onchange: m => setAndSave('enableMaxScoreTiebreak', m), - }; - m['TB Score to win'] = { - value: settings.maxScoreTiebreakWinScore, - onchange: m => setAndSave('maxScoreTiebreakWinScore', m), - }; - m['TB 2-point lead'] = { - value: settings.maxScoreTiebreakEnableTwoAhead, - format: m => offon[~~m], - onchange: m => setAndSave('maxScoreTiebreakEnableTwoAhead', m), - }; - m['TB max score?'] = { - value: settings.maxScoreTiebreakEnableMaxScore, - format: m => offon[~~m], - onchange: m => setAndSave('maxScoreTiebreakEnableMaxScore', m), - }; - m['TB max score'] = { - value: settings.maxScoreTiebreakMaxScore, - onchange: m => setAndSave('maxScoreTiebreakMaxScore', m), + + const presetMenu = function (appMenuBack) { + let ret = function (changed) { E.showMenu(appMenu(appMenuBack, changed ? 2 : null)); }; + let m = { + '': {'title': 'Score Presets'}, + '< Back': ret, + }; + for (let i = 0; i < presetNames.length; i++) { + m[presetNames[i]] = (function (i) { + return function() { + changed = true; + settings = fillSettingsWithDefaults(presets[presetNames[i]]); + save(settings); + ret(true); + }; + })(i); + } + + return m; }; - return m; - }; + const appMenu = function (back, selected) { + let m = {}; - const inAppMenu = function () { - let m = { - '': {'title': 'Score Menu'}, - '< Back': function () { back(settings, changed); }, - 'Reset match': function () { back(settings, true); }, - 'End current set': function () { inApp('end_set'); back(settings, changed); }, - 'Configuration': function () { E.showMenu(appMenu(function () { - E.showMenu(inAppMenu()); - })); }, + m[''] = {'title': 'Score Settings'}; + if (selected != null) { + m[''].selected = selected; + } + m['< Back'] = function () { back(settings, changed); }; + m['Presets'] = function () { E.showMenu(presetMenu(back)); }; + m['Sets to win'] = { + value: settings.winSets, + min:1, + onchange: m => setAndSave('winSets', m), + }; + m['Sets per page'] = { + value: settings.setsPerPage, + min:1, + max:5, + onchange: m => setAndSave('setsPerPage', m), + }; + m['Score to win'] = { + value: settings.winScore, + min:1, + onchange: m => setAndSave('winScore', m), + }; + m['2-point lead'] = { + value: settings.enableTwoAhead, + format: m => offon[~~m], + onchange: m => setAndSave('enableTwoAhead', m), + }; + m['Maximum score?'] = { + value: settings.enableMaxScore, + format: m => offon[~~m], + onchange: m => setAndSave('enableMaxScore', m), + }; + m['Maximum score'] = { + value: settings.maxScore, + min: 1, + onchange: m => setAndSave('maxScore', m), + }; + m['Tennis scoring'] = { + value: settings.enableTennisScoring, + format: m => offon[~~m], + onchange: m => setAndSave('enableTennisScoring', m), + }; + m['TB sets?'] = { + value: settings.enableMaxScoreTiebreak, + format: m => offon[~~m], + onchange: m => setAndSave('enableMaxScoreTiebreak', m), + }; + m['TB Score to win'] = { + value: settings.maxScoreTiebreakWinScore, + onchange: m => setAndSave('maxScoreTiebreakWinScore', m), + }; + m['TB 2-point lead'] = { + value: settings.maxScoreTiebreakEnableTwoAhead, + format: m => offon[~~m], + onchange: m => setAndSave('maxScoreTiebreakEnableTwoAhead', m), + }; + m['TB max score?'] = { + value: settings.maxScoreTiebreakEnableMaxScore, + format: m => offon[~~m], + onchange: m => setAndSave('maxScoreTiebreakEnableMaxScore', m), + }; + m['TB max score'] = { + value: settings.maxScoreTiebreakMaxScore, + onchange: m => setAndSave('maxScoreTiebreakMaxScore', m), + }; + + return m; }; - return m; - }; + const inAppMenu = function () { + let m = { + '': {'title': 'Score Menu'}, + '< Back': function () { back(settings, changed); }, + 'Reset match': function () { back(settings, true); }, + 'End current set': function () { inApp('end_set'); back(settings, changed); }, + 'Configuration': function () { E.showMenu(appMenu(function () { + E.showMenu(inAppMenu()); + })); }, + }; - if (inApp != null) { - E.showMenu(inAppMenu()); - } else { - E.showMenu(appMenu(back)); - } + return m; + }; -}); + if (inApp != null) { + E.showMenu(inAppMenu()); + } else { + E.showMenu(appMenu(back)); + } + + }); +})(); From 656d3e65cd54b079e2fb5b47d75f2f5314238d3d Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 16:22:16 +0200 Subject: [PATCH 30/52] score: shift score display right --- apps/score/score.app.js | 46 +++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 48f503cb7..8c4a16a41 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -299,6 +299,10 @@ function handleInput(button) { } function draw() { + let getXCoord = function (func) { + let offset = 40; + return func(w-offset)+offset; + }; g.setFontAlign(0,0); g.clear(); @@ -306,34 +310,58 @@ function draw() { if (matchWon(p)) { g.setFontAlign(0,0); g.setFont('Teletext5x9Ascii',2); - g.drawString("WINNER", p === 0 ? w/4 : w/4*3, 15); + g.drawString( + "WINNER", + getXCoord(w => p === 0 ? w/4 : w/4*3), + 15 + ); } else if (matchEnded()) { g.setFontAlign(0,-1); let dur1 = formatDuration(scores[cSet][2] - scores[0][2]); g.setFont('5x9Numeric7Seg',1); - g.drawString(dur1, p === 0 ? w/8 : w/8*5, 10); + g.drawString( + dur1, + getXCoord(w => p === 0 ? w/8 : w/8*5), + 10 + ); g.setFont('Teletext5x9Ascii',1); - g.drawString((currentSet()+1) + ' set' + (currentSet() > 0 ? 's' : ''), p === 0 ? w/8*3 : w/8*7, 12); + g.drawString( + (currentSet()+1) + ' set' + (currentSet() > 0 ? 's' : ''), + getXCoord(w => p === 0 ? w/8*3 : w/8*7), + 12 + ); } g.setFontAlign(p === 0 ? -1 : 1,1); g.setFont('5x9Numeric7Seg',2); - g.drawString(setsWon(p), p === 0 ? 10 : w-8, h-5); + g.drawString( + setsWon(p), + getXCoord(w => p === 0 ? 10 : w-8), + h-5 + ); if (!settings.enableTennisScoring) { g.setFontAlign(p === 0 ? 1 : -1,1); g.setFont('7x11Numeric7Seg',2); - g.drawString(formatNumber(matchScore(p), 3), p === 0 ? w/2 - 8 : w/2 + 11, h-5); + g.drawString( + formatNumber(matchScore(p), 3), + getXCoord(w => p === 0 ? w/2 - 8 : w/2 + 11), + h-5 + ); } } g.setFontAlign(0,0); if (correctionMode) { g.setFont('Teletext5x9Ascii',2); - g.drawString("R", w/2, h-10); + g.drawString( + "R", + getXCoord(w => w/2), + h-10 + ); } let lastShownSet = Math.min( @@ -360,8 +388,8 @@ function draw() { for (let p = 0; p < 2; p++) { if (!setWon(set, p === 0 ? 1 : 0) || matchEnded()) { - let bigNumX = p === 0 ? (w-20)/4+18 : (w-20)/4*3+4; - let smallNumX = p === 0 ? w/2-2 : w/2+3; + let bigNumX = getXCoord(w => p === 0 ? w/4 : w/4*3+3); + let smallNumX = getXCoord(w => p === 0 ? w/2-2 : w/2+3); if (settings.enableTennisScoring && set === cSet && !shouldTiebreak()) { g.setFontAlign(0,0); @@ -411,7 +439,7 @@ function draw() { } // draw separator - g.drawLine(w/2,20,w/2,h-25); + g.drawLine(getXCoord(w => w/2), 20, getXCoord(w => w/2), h-25); g.flip(); } From df13e80b143b613a7d2d8e58edcedb054b28f965 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 16:22:31 +0200 Subject: [PATCH 31/52] score: move match sets and time tothe left --- apps/score/score.app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 8c4a16a41..73e1e8794 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -316,20 +316,20 @@ function draw() { 15 ); } else if (matchEnded()) { - g.setFontAlign(0,-1); + g.setFontAlign(1,0); let dur1 = formatDuration(scores[cSet][2] - scores[0][2]); g.setFont('5x9Numeric7Seg',1); g.drawString( dur1, - getXCoord(w => p === 0 ? w/8 : w/8*5), + 40, 10 ); g.setFont('Teletext5x9Ascii',1); g.drawString( (currentSet()+1) + ' set' + (currentSet() > 0 ? 's' : ''), - getXCoord(w => p === 0 ? w/8*3 : w/8*7), + 40, 12 ); From 7f5037066925f26088bc45e87265029795a23579 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 16:42:21 +0200 Subject: [PATCH 32/52] score: change b1 control scheme --- apps/score/README.md | 25 ++++++++++++++++--------- apps/score/score.app.js | 19 ++++++++++--------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/apps/score/README.md b/apps/score/README.md index c3ad0e622..1de1ccdb5 100644 --- a/apps/score/README.md +++ b/apps/score/README.md @@ -1,18 +1,25 @@ This app will allow you to keep scores for most kinds of sports. # Keybinds -*On Bangle.js 2 BTN is equivalent to BTN2 on Bangle.js 1* -| Keybinding | Description | -|-------------------|------------------------------| -| `BTN1` | Scroll up | -| `BTN3` | Scroll down | -| `BTN2` | Menu | -| tap on left side | increment left player score | -| tap on right side | increment right player score | - To correct a falsely awarded point simply open and close the menu within .5 seconds. This will put the app into correction mode (indicated by the `R`). In this mode any score increments will be decrements. To move back a set, reduce both players scores to 0, then decrement one of the scores once again. +## Bangle.js 1 +| Keybinding | Description | +|---------------------|------------------------------| +| `BTN1` | Increment left player score | +| `BTN3` | Increment right player score | +| `BTN2` | Menu | +| touch on left side | Scroll up | +| touch on right side | Scroll down | + +## Bangle.js 2 +| Keybinding | Description | +|-------------------------------------|------------------------------| +| `BTN1` | Menu | +| touch on left side of divider line | Increment left player score | +| touch on right side of divider line | Increment right player score | + # Settings | Setting | Description | |------------------------------------|------------------------------------------------------------------------------------------------------------------------------| diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 73e1e8794..072617e6b 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -19,23 +19,28 @@ let correctionMode = false; let w = g.getWidth(); let h = g.getHeight(); +function getXCoord(func) { + let offset = 40; + return func(w-offset)+offset; +}; + function setupInputWatchers() { if (global.BTN4) { setWatch(() => handleInput(2), BTN2, { repeat: true }); - setWatch(() => handleInput(3), BTN1, { repeat: true }); - setWatch(() => handleInput(4), BTN3, { repeat: true }); + setWatch(() => handleInput(0), BTN1, { repeat: true }); + setWatch(() => handleInput(1), BTN3, { repeat: true }); } else { setWatch(() => handleInput(2), BTN, { repeat: true }); } Bangle.on('touch', (b, e) => { if (b) { if (b === 1) { - handleInput(0); + handleInput(3); } else { - handleInput(1); + handleInput(4); } } else { - if (e.x < w/2) { + if (e.x < getXCoord(w => w/2)) { handleInput(0); } else { handleInput(1); @@ -299,10 +304,6 @@ function handleInput(button) { } function draw() { - let getXCoord = function (func) { - let offset = 40; - return func(w-offset)+offset; - }; g.setFontAlign(0,0); g.clear(); From f5b9c5d005e44b756fc4c5dc28e61c0bbed393eb Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 16:44:33 +0200 Subject: [PATCH 33/52] score: fix scrolling in correction mode --- apps/score/score.app.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 072617e6b..357cd965b 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -186,7 +186,7 @@ function matchWon(player) { } function matchEnded() { - return matchWon(0) || matchWon(1); + return (matchWon(0) || matchWon(1)) && cSet > (setsWon(0) + setsWon(1) - 1); } function matchScore(player) { @@ -207,17 +207,17 @@ function updateCurrentSet(val) { } setFirstShownSet(); - if (matchEnded()) { - firstShownSet = 0; - } - if (val > 0) { scores[cSet][2] = getTime(); + + if (matchEnded()) { + firstShownSet = 0; + } } } function score(player) { - if (!matchEnded() || correctionMode) { + if (!matchEnded()) { setFirstShownSet(); } From a749a382716664ebba33695e8337d6182d7c39c0 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 16:44:49 +0200 Subject: [PATCH 34/52] score: fix/reorder draw function --- apps/score/score.app.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 357cd965b..1ec15adb2 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -319,21 +319,20 @@ function draw() { } else if (matchEnded()) { g.setFontAlign(1,0); + g.setFont('Teletext5x9Ascii',1); + g.drawString( + (currentSet()+1) + ' set' + (currentSet() > 0 ? 's' : ''), + 40, + 8 + ); + let dur1 = formatDuration(scores[cSet][2] - scores[0][2]); g.setFont('5x9Numeric7Seg',1); g.drawString( dur1, 40, - 10 + 18 ); - - g.setFont('Teletext5x9Ascii',1); - g.drawString( - (currentSet()+1) + ' set' + (currentSet() > 0 ? 's' : ''), - 40, - 12 - ); - } g.setFontAlign(p === 0 ? -1 : 1,1); From 46fc78772b7bba41314f4feba4f3bbca0d76e06d Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 16:47:23 +0200 Subject: [PATCH 35/52] score: remove unnecessary semicolon --- apps/score/score.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 1ec15adb2..2f07c7de5 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -22,7 +22,7 @@ let h = g.getHeight(); function getXCoord(func) { let offset = 40; return func(w-offset)+offset; -}; +} function setupInputWatchers() { if (global.BTN4) { From fb3f55be7cd6af03638c3869b485de7cce5f7e1c Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 21:07:00 +0200 Subject: [PATCH 36/52] score: prevent floating point numbers from getTime() --- apps/score/score.app.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 2f07c7de5..0c5d66169 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -24,6 +24,10 @@ function getXCoord(func) { return func(w-offset)+offset; } +function getSecondsTime() { + return Math.floor(getTime() * 1000); +} + function setupInputWatchers() { if (global.BTN4) { setWatch(() => handleInput(2), BTN2, { repeat: true }); @@ -62,7 +66,7 @@ function setupMatch() { tScores = null; } - scores[0][2] = getTime(); + scores[0][2] = getSecondsTime(); cSet = 0; setFirstShownSet(); @@ -71,7 +75,8 @@ function setupMatch() { } function showSettingsMenu() { - settingsMenuOpened = getTime(); + settingsMenuOpened = getSecondsTime(); + l = null; settingsMenu(function (s, reset) { E.showMenu(); @@ -79,7 +84,7 @@ function showSettingsMenu() { if (reset) { setupMatch(); - } else if (getTime() - settingsMenuOpened < 0.5 || correctionMode) { + } else if (getSecondsTime() - settingsMenuOpened < 500 || correctionMode) { correctionMode = !correctionMode; } @@ -125,7 +130,7 @@ function formatNumber(num, length) { } function formatDuration(duration) { - let durS = Math.floor(duration); + let durS = Math.floor(duration / 1000); let durM = Math.floor(durS / 60); let durH = Math.floor(durM / 60); durS = durS - durM * 60; @@ -208,7 +213,7 @@ function updateCurrentSet(val) { setFirstShownSet(); if (val > 0) { - scores[cSet][2] = getTime(); + scores[cSet][2] = getSecondsTime(); if (matchEnded()) { firstShownSet = 0; From eb384cef31027b03d009cecfa761188e52ccfe8b Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 21:56:18 +0200 Subject: [PATCH 37/52] score: fix layout for 176x176 resolution --- apps/score/score.app.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 0c5d66169..8e1535f86 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -344,7 +344,7 @@ function draw() { g.setFont('5x9Numeric7Seg',2); g.drawString( setsWon(p), - getXCoord(w => p === 0 ? 10 : w-8), + getXCoord(w => p === 0 ? 5 : w-3), h-5 ); @@ -353,7 +353,7 @@ function draw() { g.setFont('7x11Numeric7Seg',2); g.drawString( formatNumber(matchScore(p), 3), - getXCoord(w => p === 0 ? w/2 - 8 : w/2 + 11), + getXCoord(w => p === 0 ? w/2 - 3 : w/2 + 6), h-5 ); } @@ -383,17 +383,17 @@ function draw() { let y = (h-15)/(setsOnCurrentPage+1)*(set-firstShownSet+1)+5; - g.setFontAlign(1,0); + g.setFontAlign(-1,0); g.setFont('7x11Numeric7Seg',1); - g.drawString(set+1, 40, y-10); + g.drawString(set+1, 5, y-10); if (scores[set+1][2] != null) { let dur2 = formatDuration(scores[set+1][2] - scores[set][2]); - g.drawString(dur2, 40, y+10); + g.drawString(dur2, 5, y+10); } for (let p = 0; p < 2; p++) { if (!setWon(set, p === 0 ? 1 : 0) || matchEnded()) { - let bigNumX = getXCoord(w => p === 0 ? w/4 : w/4*3+3); + let bigNumX = getXCoord(w => p === 0 ? w/4-12 : w/4*3+15); let smallNumX = getXCoord(w => p === 0 ? w/2-2 : w/2+3); if (settings.enableTennisScoring && set === cSet && !shouldTiebreak()) { From dca65f0490e25747e57f10c08afc6d8dfa293751 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Tue, 28 Sep 2021 21:56:33 +0200 Subject: [PATCH 38/52] score: set score limit of 999 --- apps/score/score.settings.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index da35d7a21..d63c52a9b 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -114,6 +114,7 @@ m['Score to win'] = { value: settings.winScore, min:1, + max: 999, onchange: m => setAndSave('winScore', m), }; m['2-point lead'] = { @@ -129,6 +130,7 @@ m['Maximum score'] = { value: settings.maxScore, min: 1, + max: 999, onchange: m => setAndSave('maxScore', m), }; m['Tennis scoring'] = { From a15622f00a89e434f085e4920642dbe4243563a0 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Fri, 1 Oct 2021 22:17:51 +0200 Subject: [PATCH 39/52] score: add readme to apps.json --- apps.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps.json b/apps.json index b1e6f70fc..f0690f0d3 100644 --- a/apps.json +++ b/apps.json @@ -3560,6 +3560,7 @@ "icon": "score.app.png", "version":"0.01", "description": "Score Tracker for sports that use plain numbers (e.g. Badminton, Volleyball, Soccer, Table Tennis, ...). Also supports tennis scoring.", + "readme": "README.md", "tags": "b2", "type": "app", "storage": [ From e7d0903e82939d257b2a73b275b8a3e1fba1fa95 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Fri, 1 Oct 2021 22:18:07 +0200 Subject: [PATCH 40/52] score: add data "scores.json" to apps.json --- apps.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps.json b/apps.json index f0690f0d3..611edb53a 100644 --- a/apps.json +++ b/apps.json @@ -3568,6 +3568,9 @@ {"name":"score.settings.js","url":"score.settings.js"}, {"name":"score.presets.json","url":"score.presets.json"}, {"name":"score.img","url":"score.app-icon.js","evaluate":true} + ], + "data": [ + {"name":"score.json"} ] } ] From fbe14a79d1aa096ba3c2bb891a918f5ffc896885 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Sun, 3 Oct 2021 15:39:07 +0200 Subject: [PATCH 41/52] score: fix scrolling on b2, change b2 detection --- apps/score/score.app.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 8e1535f86..24e49fa66 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -29,15 +29,11 @@ function getSecondsTime() { } function setupInputWatchers() { - if (global.BTN4) { - setWatch(() => handleInput(2), BTN2, { repeat: true }); - setWatch(() => handleInput(0), BTN1, { repeat: true }); - setWatch(() => handleInput(1), BTN3, { repeat: true }); - } else { - setWatch(() => handleInput(2), BTN, { repeat: true }); - } + isBangle1 = !!global.BTN4; + setWatch(() => handleInput(2), isBangle1 != null ? BTN2 : BTN, { repeat: true }); + Bangle.setUI('updown', v => v && handleInput(Math.floor((v+2)/2)+(isBangle1 ? 0 : 3))); Bangle.on('touch', (b, e) => { - if (b) { + if (isBangle1) { if (b === 1) { handleInput(3); } else { From 01d33cbbfa0864b793c2022296607aae0330d3d9 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Sat, 9 Oct 2021 20:01:48 +0200 Subject: [PATCH 42/52] score: call setUI after menu --- apps/score/score.app.js | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 24e49fa66..b48995849 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -28,25 +28,27 @@ function getSecondsTime() { return Math.floor(getTime() * 1000); } -function setupInputWatchers() { +function setupInputWatchers(init) { isBangle1 = !!global.BTN4; - setWatch(() => handleInput(2), isBangle1 != null ? BTN2 : BTN, { repeat: true }); Bangle.setUI('updown', v => v && handleInput(Math.floor((v+2)/2)+(isBangle1 ? 0 : 3))); - Bangle.on('touch', (b, e) => { - if (isBangle1) { - if (b === 1) { - handleInput(3); + if (init) { + setWatch(() => handleInput(2), isBangle1 != null ? BTN2 : BTN, { repeat: true }); + Bangle.on('touch', (b, e) => { + if (isBangle1) { + if (b === 1) { + handleInput(3); + } else { + handleInput(4); + } } else { - handleInput(4); + if (e.x < getXCoord(w => w/2)) { + handleInput(0); + } else { + handleInput(1); + } } - } else { - if (e.x < getXCoord(w => w/2)) { - handleInput(0); - } else { - handleInput(1); - } - } - }); + }); + } } function setupMatch() { @@ -87,6 +89,8 @@ function showSettingsMenu() { settingsMenuOpened = null; draw(); + + setupInputWatchers(); }, function (msg) { switch (msg) { case 'end_set': @@ -445,6 +449,6 @@ function draw() { g.flip(); } -setupInputWatchers(); +setupInputWatchers(true); setupMatch(); draw(); From 88f17232bc6d99def85f20f1ed83ee1a546a4cac Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Sun, 10 Oct 2021 17:16:09 +0200 Subject: [PATCH 43/52] score: update b1 detection to use process.env --- apps/score/score.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index b48995849..7da068294 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -29,7 +29,7 @@ function getSecondsTime() { } function setupInputWatchers(init) { - isBangle1 = !!global.BTN4; + isBangle1 = process.env.BOARD === 'BANGLEJS'; Bangle.setUI('updown', v => v && handleInput(Math.floor((v+2)/2)+(isBangle1 ? 0 : 3))); if (init) { setWatch(() => handleInput(2), isBangle1 != null ? BTN2 : BTN, { repeat: true }); From 23ec132b4d7a7f4574a8bcc8c0e079612d27e8ea Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Sun, 10 Oct 2021 17:19:03 +0200 Subject: [PATCH 44/52] score: switch score buttons --- apps/score/score.app.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 7da068294..0c2d8c78d 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -30,7 +30,15 @@ function getSecondsTime() { function setupInputWatchers(init) { isBangle1 = process.env.BOARD === 'BANGLEJS'; - Bangle.setUI('updown', v => v && handleInput(Math.floor((v+2)/2)+(isBangle1 ? 0 : 3))); + Bangle.setUI('updown', v => { + if (v) { + if (isBangle1) { + handleInput(Math.floor(((v*-1)+2)/2)) + } else { + handleInput(Math.floor((v+2)/2)+3) + } + } + }); if (init) { setWatch(() => handleInput(2), isBangle1 != null ? BTN2 : BTN, { repeat: true }); Bangle.on('touch', (b, e) => { From f6f1a1c352b4f43037280e6bcd198ebe86b405f7 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Sun, 10 Oct 2021 17:26:35 +0200 Subject: [PATCH 45/52] score: allow user to mirror score buttons on b1 --- apps/score/score.app.js | 5 +++-- apps/score/score.settings.js | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 0c2d8c78d..4f1fd7b7b 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -33,9 +33,10 @@ function setupInputWatchers(init) { Bangle.setUI('updown', v => { if (v) { if (isBangle1) { - handleInput(Math.floor(((v*-1)+2)/2)) + let i = settings.mirrorScoreButtons ? v * -1 : v; + handleInput(Math.floor((i+2)/2)); } else { - handleInput(Math.floor((v+2)/2)+3) + handleInput(Math.floor((v+2)/2)+3); } } }); diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index d63c52a9b..3fc04839b 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -1,6 +1,13 @@ (function () { return (function (back, inApp, ret) { + const isBangle1 = process.env.BOARD === 'BANGLEJS' + function fillSettingsWithDefaults(settings) { + if (isBangle1) { + if (settings.mirrorScoreButtons == null) { + settings.mirrorScoreButtons = false; + } + } if (settings.winSets == null) { settings.winSets = 2; } @@ -100,6 +107,13 @@ } m['< Back'] = function () { back(settings, changed); }; m['Presets'] = function () { E.showMenu(presetMenu(back)); }; + if (isBangle1) { + m['Mirror Buttons'] = { + value: settings.mirrorScoreButtons, + format: m => offon[~~m], + onchange: m => setAndSave('mirrorScoreButtons', m), + }; + } m['Sets to win'] = { value: settings.winSets, min:1, From f5fefc7c993946a66ca7b62cf0f982d030ff05b8 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Sun, 10 Oct 2021 17:27:50 +0200 Subject: [PATCH 46/52] score: keep display powered on --- apps/score/score.app.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 4f1fd7b7b..87fdecf0c 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -19,6 +19,8 @@ let correctionMode = false; let w = g.getWidth(); let h = g.getHeight(); +let isBangle1 = process.env.BOARD === 'BANGLEJS'; + function getXCoord(func) { let offset = 40; return func(w-offset)+offset; @@ -29,7 +31,6 @@ function getSecondsTime() { } function setupInputWatchers(init) { - isBangle1 = process.env.BOARD === 'BANGLEJS'; Bangle.setUI('updown', v => { if (v) { if (isBangle1) { @@ -458,6 +459,12 @@ function draw() { g.flip(); } +// make sure LCD on Bangle.js 1 stays on +if (isBangle1) { + Bangle.setLCDTimeout(0); + Bangle.setLCDPower(true); +} + setupInputWatchers(true); setupMatch(); draw(); From a575f323d85fd00ac637bb68e9733e2446ef10c1 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Sun, 10 Oct 2021 17:41:54 +0200 Subject: [PATCH 47/52] score: don't reset match when changing button assignment --- apps/score/score.settings.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index 3fc04839b..20482db65 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -63,8 +63,10 @@ require('Storage').writeJSON(fileName, settings); } - function setAndSave(key, value) { - changed = true; + function setAndSave(key, value, notChanged) { + if (!notChanged) { + changed = true; + } settings[key] = value; if (key === 'winScore' && settings.maxScore < value) { settings.maxScore = value; @@ -111,7 +113,7 @@ m['Mirror Buttons'] = { value: settings.mirrorScoreButtons, format: m => offon[~~m], - onchange: m => setAndSave('mirrorScoreButtons', m), + onchange: m => setAndSave('mirrorScoreButtons', m, true), }; } m['Sets to win'] = { From 729f5baf16350329fb4f49d2d5ec754aacb8fac7 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Sun, 10 Oct 2021 17:42:21 +0200 Subject: [PATCH 48/52] score: keep specific settings when selecting new preset --- apps/score/score.settings.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index 20482db65..982652b94 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -90,7 +90,11 @@ m[presetNames[i]] = (function (i) { return function() { changed = true; + let mirrorScoreButtons = settings.mirrorScoreButtons; + settings = fillSettingsWithDefaults(presets[presetNames[i]]); + + settings.mirrorScoreButtons = mirrorScoreButtons; save(settings); ret(true); }; From ed9566dbb3486e8d2d82cdbb5b18bc49d3ffa814 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Sun, 10 Oct 2021 17:44:03 +0200 Subject: [PATCH 49/52] score: change default score button assignment --- apps/score/score.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 87fdecf0c..d3bc5d1e1 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -34,7 +34,7 @@ function setupInputWatchers(init) { Bangle.setUI('updown', v => { if (v) { if (isBangle1) { - let i = settings.mirrorScoreButtons ? v * -1 : v; + let i = settings.mirrorScoreButtons ? v : v * -1; handleInput(Math.floor((i+2)/2)); } else { handleInput(Math.floor((v+2)/2)+3); From 52bdf22352b8d8752b62189b7daffda90a68d033 Mon Sep 17 00:00:00 2001 From: Mika Dede Date: Sun, 10 Oct 2021 20:39:53 +0200 Subject: [PATCH 50/52] score: allow user to choose if screen of b1 should stay on --- apps/score/score.app.js | 20 ++++++++++++++------ apps/score/score.settings.js | 10 ++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index d3bc5d1e1..3a9b71505 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -30,6 +30,18 @@ function getSecondsTime() { return Math.floor(getTime() * 1000); } +function setupDisplay() { + // make sure LCD on Bangle.js 1 stays on + if (isBangle1) { + if (settings.keepDisplayOn) { + Bangle.setLCDTimeout(0); + Bangle.setLCDPower(true); + } else { + Bangle.setLCDTimeout(10); + } + } +} + function setupInputWatchers(init) { Bangle.setUI('updown', v => { if (v) { @@ -100,6 +112,7 @@ function showSettingsMenu() { draw(); + setupDisplay(); setupInputWatchers(); }, function (msg) { switch (msg) { @@ -459,12 +472,7 @@ function draw() { g.flip(); } -// make sure LCD on Bangle.js 1 stays on -if (isBangle1) { - Bangle.setLCDTimeout(0); - Bangle.setLCDPower(true); -} - +setupDisplay(); setupInputWatchers(true); setupMatch(); draw(); diff --git a/apps/score/score.settings.js b/apps/score/score.settings.js index 982652b94..88e367821 100644 --- a/apps/score/score.settings.js +++ b/apps/score/score.settings.js @@ -7,6 +7,9 @@ if (settings.mirrorScoreButtons == null) { settings.mirrorScoreButtons = false; } + if (settings.keepDisplayOn == null) { + settings.keepDisplayOn = true; + } } if (settings.winSets == null) { settings.winSets = 2; @@ -91,10 +94,12 @@ return function() { changed = true; let mirrorScoreButtons = settings.mirrorScoreButtons; + let keepDisplayOn = settings.keepDisplayOn; settings = fillSettingsWithDefaults(presets[presetNames[i]]); settings.mirrorScoreButtons = mirrorScoreButtons; + settings.keepDisplayOn = keepDisplayOn; save(settings); ret(true); }; @@ -119,6 +124,11 @@ format: m => offon[~~m], onchange: m => setAndSave('mirrorScoreButtons', m, true), }; + m['Keep display on'] = { + value: settings.keepDisplayOn, + format: m => offon[~~m], + onchange: m => setAndSave('keepDisplayOn', m, true), + } } m['Sets to win'] = { value: settings.winSets, From e8d8de648ba820c7be585e7f1b19a902317d3f76 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 11 Oct 2021 14:00:40 +0100 Subject: [PATCH 51/52] small tweak for Bangle2 --- apps/score/score.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/score/score.app.js b/apps/score/score.app.js index 3a9b71505..5a0f9c1e1 100644 --- a/apps/score/score.app.js +++ b/apps/score/score.app.js @@ -54,7 +54,7 @@ function setupInputWatchers(init) { } }); if (init) { - setWatch(() => handleInput(2), isBangle1 != null ? BTN2 : BTN, { repeat: true }); + setWatch(() => handleInput(2), isBangle1 ? BTN2 : BTN, { repeat: true }); Bangle.on('touch', (b, e) => { if (isBangle1) { if (b === 1) { From 54d98db6c84a6ab1d984472025faba6a30b9c9c4 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 11 Oct 2021 14:29:58 +0100 Subject: [PATCH 52/52] Bangle.js2 tweaks --- apps.json | 6 +++--- apps/gpsrec/ChangeLog | 1 + apps/gpsrec/app.js | 35 ++++++++++++++++++++--------------- apps/widbt/ChangeLog | 1 + apps/widbt/widget.js | 4 ++-- apps/widid/ChangeLog | 1 + apps/widid/widget.js | 3 +-- 7 files changed, 29 insertions(+), 22 deletions(-) diff --git a/apps.json b/apps.json index 611edb53a..1e2612fce 100644 --- a/apps.json +++ b/apps.json @@ -511,7 +511,7 @@ { "id": "gpsrec", "name": "GPS Recorder", "icon": "app.png", - "version":"0.23", + "version":"0.24", "interface": "interface.html", "description": "Application that allows you to record a GPS track. Can run in background", "tags": "tool,outdoors,gps,widget", @@ -687,7 +687,7 @@ { "id": "widbt", "name": "Bluetooth Widget", "icon": "widget.png", - "version":"0.05", + "version":"0.06", "description": "Show the current Bluetooth connection status in the top right of the clock", "tags": "widget,bluetooth,b2", "type":"widget", @@ -1316,7 +1316,7 @@ { "id": "widid", "name": "Bluetooth ID Widget", "icon": "widget.png", - "version":"0.02", + "version":"0.03", "description": "Display the last two tuple of your Bangle.js MAC address in the widget section. This is useful for figuring out which Bangle.js to connect to if you have more than one Bangle.js!", "tags": "widget,address,mac", "type":"widget", diff --git a/apps/gpsrec/ChangeLog b/apps/gpsrec/ChangeLog index 8d13df000..c91003914 100644 --- a/apps/gpsrec/ChangeLog +++ b/apps/gpsrec/ChangeLog @@ -25,3 +25,4 @@ 0.21: Fix issue where a period of 1s recorded every 2s, 5s every 6s, and so on 0.22: Ensure Bangle.setGPSPower uses 'gpsrec' as a tag 0.23: Fix issue where tracks wouldn't record when running from OpenStMap if a period hadn't been set up first +0.24: Better support for Bangle.js 2, avoid widget area for Graphs, smooth graphs more diff --git a/apps/gpsrec/app.js b/apps/gpsrec/app.js index 29594289d..164124257 100644 --- a/apps/gpsrec/app.js +++ b/apps/gpsrec/app.js @@ -102,7 +102,8 @@ function getTrackInfo(fn) { var lfactor = Math.cos(minLat*Math.PI/180); var ylen = (maxLat-minLat); var xlen = (maxLong-minLong)* lfactor; - var scale = xlen>ylen ? 200/xlen : 200/ylen; + var screenSize = g.getHeight()-48; // 24 for widgets, plus a border + var scale = xlen>ylen ? screenSize/xlen : screenSize/ylen; return { fn : fn, filename : filename, @@ -110,6 +111,7 @@ function getTrackInfo(fn) { records : nl, minLat : minLat, maxLat : maxLat, minLong : minLong, maxLong : maxLong, + lat : (minLat+maxLat)/2, lon : (minLong+maxLong)/2, lfactor : lfactor, scale : scale, duration : Math.round(duration/1000) @@ -180,16 +182,18 @@ function plotTrack(info) { getMapXY = osm.latLonToXY.bind(osm); } else { getMapXY = function(lat, lon) { "ram" - var ix = 30 + Math.round((long - info.minLong)*info.lfactor*info.scale); - var iy = 210 - Math.round((lat - info.minLat)*info.scale); - return {x:ix, y:iy}; + return {x:cx + Math.round((long - info.lon)*info.lfactor*info.scale), + y:cy + Math.round((info.lat - lat)*info.scale)}; } } E.showMenu(); // remove menu + E.showMessage("Drawing...","GPS Track "+info.fn); + g.flip(); // on buffered screens, draw a not saying we're busy + g.clear(1); var s = require("Storage"); var cx = g.getWidth()/2; - var cy = g.getHeight()/2; + var cy = 24 + (g.getHeight()-24)/2; g.setColor(1,0.5,0.5); g.setFont("Vector",16); g.drawString("Track"+info.fn.toString()+" - Loading",10,220); @@ -203,8 +207,8 @@ function plotTrack(info) { g.drawString("N",2,40); g.setColor(1,1,1); } else { - osm.lat = (info.minLat+info.maxLat)/2; - osm.lon = (info.minLong+info.maxLong)/2; + osm.lat = info.lat; + osm.lon = info.lon; osm.draw(); g.setColor(0, 0, 0); } @@ -251,7 +255,8 @@ function plotTrack(info) { g.drawString("Back",230,200); setWatch(function() { viewTrack(info.fn, info); - }, BTN3); + }, global.BTN3||BTN1); + Bangle.drawWidgets(); g.flip(); } @@ -260,8 +265,8 @@ function plotGraph(info, style) { E.showMenu(); // remove menu E.showMessage("Calculating...","GPS Track "+info.fn); var filename = getFN(info.fn); - var infn = new Float32Array(200); - var infc = new Uint16Array(200); + var infn = new Float32Array(80); + var infc = new Uint16Array(80); var title; var lt = 0; // last time var tn = 0; // count for each time period @@ -278,7 +283,7 @@ function plotGraph(info, style) { title = "Altitude (m)"; while(l!==undefined) { ++nl;c=l.split(","); - i = Math.round(200*(c[0]/1000 - strt)/dur); + i = Math.round(80*(c[0]/1000 - strt)/dur); infn[i]+=+c[3]; infc[i]++; l = f.readLine(f); @@ -289,7 +294,7 @@ function plotGraph(info, style) { var t,dx,dy,d,lt = c[0]/1000; while(l!==undefined) { ++nl;c=l.split(","); - i = Math.round(200*(c[0]/1000 - strt)/dur); + i = Math.round(80*(c[0]/1000 - strt)/dur); t = c[0]/1000; p = Bangle.project({lat:c[1],lon:c[2]}); dx = p.x-lp.x; @@ -320,9 +325,9 @@ function plotGraph(info, style) { // draw g.clear(1).setFont("6x8",1); var r = require("graph").drawLine(g, infn, { - x:4,y:0, + x:4,y:24, width: g.getWidth()-24, - height: g.getHeight()-8, + height: g.getHeight()-(24+8), axes : true, gridy : grid, gridx : 50, @@ -334,7 +339,7 @@ function plotGraph(info, style) { g.drawString("Back",230,200); setWatch(function() { viewTrack(info.fn, info); - }, BTN3); + }, global.BTN3||BTN1); g.flip(); } diff --git a/apps/widbt/ChangeLog b/apps/widbt/ChangeLog index e639f4044..4509487ac 100644 --- a/apps/widbt/ChangeLog +++ b/apps/widbt/ChangeLog @@ -2,3 +2,4 @@ 0.03: Ensure redrawing works with variable size widget system 0.04: Fix automatic update of Bluetooth connection status 0.05: Make Bluetooth widget thinner, and when on a bright theme use light grey for disabled color +0.06: Tweaking colors for dark/light themes and low bpp screens diff --git a/apps/widbt/widget.js b/apps/widbt/widget.js index 89a3cbdb8..a25d2c21c 100644 --- a/apps/widbt/widget.js +++ b/apps/widbt/widget.js @@ -2,9 +2,9 @@ function draw() { g.reset(); if (NRF.getSecurityStatus().connected) - g.setColor("#07f"); + g.setColor((g.getBPP()>8) ? "#07f" : (g.theme.dark ? "#0ff" : "#00f")); else - g.setColor(g.theme.bg ? "#AAA" : "#555"); + g.setColor(g.theme.dark ? "#666" : "#999"); g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="),2+this.x,2+this.y); } function changed() { diff --git a/apps/widid/ChangeLog b/apps/widid/ChangeLog index 4152a8406..56f114d5f 100644 --- a/apps/widid/ChangeLog +++ b/apps/widid/ChangeLog @@ -1,2 +1,3 @@ 0.01: New Widget! 0.02: Tweaks for variable size widget system +0.03: Tweaking colors for dark/light themes diff --git a/apps/widid/widget.js b/apps/widid/widget.js index d4f4d6386..1c7a721bc 100644 --- a/apps/widid/widget.js +++ b/apps/widid/widget.js @@ -1,8 +1,7 @@ -/* jshint esversion: 6 */ (() => { function draw() { var id = NRF.getAddress().substr().substr(12).split(":"); - g.reset().setColor(0, 0.49, 1).setFont("6x8", 1); + g.reset().setColor(g.theme.dark ? "#0ff" : "#00f").setFont("6x8", 1); g.drawString(id[0], this.x+2, this.y+4, true); g.drawString(id[1], this.x+2, this.y+14, true); }