]> git.sesse.net Git - ultimatescore/blob - score.js
In SBS, do not apply white balance to the overlay.
[ultimatescore] / score.js
1 'use strict';
2
3 let num_clocks = 3;
4 let clocks = [
5         { 'running': false, 'elapsed': 0, 'origin': undefined, 'id': 'clock' },
6         { 'running': false, 'elapsed': 0, 'origin': undefined, 'id': 'clock2' },
7         { 'running': false, 'elapsed': 0, 'origin': undefined, 'id': 'clock3' }
8 ];
9
10 let clock_visible = false;
11 let comment_visible = false;
12 let lowerthird_visible = false;
13 let clock_limit = 30 * 60;
14 let scoreA = 0;
15 let scoreB = 0;
16 let state = {};
17
18 function setteams()
19 {
20         document.getElementById('team1').innerHTML = state['team1'];
21         document.getElementById('team2').innerHTML = state['team2'];
22
23         let sheets = { 'A': state['team1'], 'B': state['team2'] };
24         loadquickl3s(sheets);
25 }
26
27 function setteams2()
28 {
29         document.getElementById('score2_team1').innerHTML = state['team1'];
30         document.getElementById('score2_team2').innerHTML = state['team2'];
31 }
32
33 function setteams3()
34 {
35         document.getElementById('score3_team1').innerHTML = state['team1'];
36         document.getElementById('score3_team2').innerHTML = state['team2'];
37 }
38
39 function setcolors()
40 {
41         document.getElementById('team1color').style.backgroundColor = state['team1color'];
42         document.getElementById('team2color').style.backgroundColor = state['team2color'];
43 }
44
45 function setscore()
46 {
47         scoreA = state['score1'];
48         scoreB = state['score2'];
49         update_score();
50 }
51
52 function setscore2()
53 {
54         scoreA = state['score1'];
55         scoreB = state['score2'];
56         document.getElementById('score2_score').innerHTML = scoreA + " – " + scoreB;
57 }
58
59 function setscore3()
60 {
61         scoreA = state['score1'];
62         scoreB = state['score2'];
63         document.getElementById('score3_score').innerHTML = scoreA + " – " + scoreB;
64 }
65
66 function startclock(num)
67 {
68         if (!clocks[num].running) {
69                 clocks[num].origin = Date.now();
70                 clocks[num].running = true;
71         }
72         if (num == 0) {
73                 showclock();
74         }
75 }
76
77 function stopclock(num)
78 {
79         if (!clocks[num].running) return;
80         clocks[num].elapsed = time_elapsed(num);
81         clocks[num].origin = Date.now();
82         clocks[num].running = false;
83 }
84
85 function setclock(num, amount)
86 {
87         clocks[num].elapsed = amount;
88         clocks[num].origin = Date.now();
89         update_clock(num);
90 }
91
92 function setclockfromstate()
93 {
94         let amount = parseInt(state['clock_min']) * 60 + parseInt(state['clock_sec']);
95         setclock(0, amount);
96 }
97
98 // No setclock2fromstate.
99
100 function adjustclockfromstate(num)
101 {
102         let amount = parseInt(state['clock_min']) * 60 + parseInt(state['clock_sec']);
103         let elapsed = time_elapsed_raw(num);
104         if (Math.abs(amount - elapsed) >= 2.0) {
105                 setclock(num, amount);
106         }
107 }
108
109 function setclocklimitfromstate()
110 {
111         let amount = parseInt(state['clock_limit_min']) * 60 + parseInt(state['clock_limit_sec']);
112         clock_limit = amount;
113 }
114
115 function showclock()
116 {
117         if (clock_visible) return;
118         let clockbug = document.getElementById('clockbug');
119         clockbug.className = 'clockbug clockbug-animate-in';
120         clock_visible = true;
121 }
122
123 function hideclock()
124 {
125         if (!clock_visible) return;
126         let clockbug = document.getElementById('clockbug');
127         clockbug.className = 'clockbug clockbug-animate-out';
128         clock_visible = false;
129 }
130
131 function setcomment()
132 {
133         document.getElementById('comment').innerHTML = state['comment'];
134 }
135
136 function showcomment()
137 {
138         if (comment_visible) return;
139         let commentbug = document.getElementById('commentbug');
140         commentbug.className = 'commentbug commentbug-animate-in';
141         comment_visible = true;
142 }
143
144 function hidecomment()
145 {
146         if (!comment_visible) return;
147         let commentbug = document.getElementById('commentbug');
148         commentbug.className = 'commentbug commentbug-animate-out';
149         comment_visible = false;
150 }
151
152 function showlowerthird()
153 {
154         if (lowerthird_visible) return;
155
156         document.getElementById('lowerthird-headline').className = 'lowerthird-headline lowerthird-headline-animate-in';
157         document.getElementById('lowerthird-headline-content').className = 'lowerthird-headline-content lowerthird-headline-content-animate-in';
158         document.getElementById('lowerthird-subheading').className = 'lowerthird-subheading lowerthird-subheading-animate-in';
159         document.getElementById('lowerthird-subheading-content').className = 'lowerthird-subheading-content lowerthird-subheading-content-animate-in';
160         document.getElementById('lowerthird-picture').className = 'lowerthird-picture lowerthird-picture-animate-in';
161         document.getElementById('lowerthird-picture-content').className = 'lowerthird-picture-content lowerthird-picture-content-animate-in';
162         lowerthird_visible = true;
163 }
164
165 function setandshowlowerthird()
166 {
167         document.getElementById('lowerthird-headline-content').innerHTML = state['text1'];
168         document.getElementById('lowerthird-subheading-content').innerHTML = state['text2'];
169         let img = document.getElementById('lowerthird-img');
170         if (state['image'] === undefined) {
171                 img.style.display = 'none';
172         } else {
173                 img.src = state['image'];
174                 img.style.display = 'inline';
175         }
176         showlowerthird();
177 }
178
179 function hidelowerthird()
180 {
181         if (!lowerthird_visible) return;
182         document.getElementById('lowerthird-headline').className = 'lowerthird-headline lowerthird-headline-hidden lowerthird-headline-animate-out';
183         document.getElementById('lowerthird-headline-content').className = 'lowerthird-headline-content lowerthird-headline-content-animate-out';
184         document.getElementById('lowerthird-subheading').className = 'lowerthird-subheading lowerthird-subheading-animate-out';
185         document.getElementById('lowerthird-subheading-content').className = 'lowerthird-subheading-content lowerthird-subheading-content-animate-out';
186         document.getElementById('lowerthird-picture').className = 'lowerthird-picture lowerthird-picture-animate-out';
187         document.getElementById('lowerthird-picture-content').className = 'lowerthird-picture-content lowerthird-picture-content-animate-out';
188         lowerthird_visible = false;
189 }
190
191 function time_elapsed_raw(num)
192 {
193         let elapsed = (Date.now() - clocks[num].origin) * 1e-3;
194         if (clocks[num].elapsed + elapsed >= clock_limit) {
195                 console.log("limit for", num);
196                 if (num == 0) {
197                         clocks[num].elapsed = clock_limit;
198                         clocks[num].origin = Date.now();
199                         clocks[num].running = false;
200
201                         if (state['autocomment_on_clock_limit'] == '1' && !comment_visible) {
202                                 state['comment'] = state['autocomment'];
203                                 setcomment();
204                                 showcomment();
205                         }
206                 }
207
208                 return clock_limit;
209         }
210         return clocks[num].elapsed + elapsed;
211 }
212
213 function time_elapsed(num)
214 {
215         return Math.floor(time_elapsed_raw(num));
216 }
217
218 function update_given_clock(elapsed, id)
219 {
220         let min = Math.floor(elapsed / 60);
221         let sec = elapsed % 60;
222
223         if (sec < 10) sec = "0" + sec;
224         let text = min + ":" + sec;
225
226         if (ultimateconfig['exohack']) {
227                 // This is a hack around the fact that Exo has variable-width numerals.
228                 // It doesn't look fantastic, but for the clock, it's better not to have
229                 // the text jumping around.
230                 let html = "";
231                 for (let i = 0; i < text.length; ++i) {
232                         if (text.charAt(i) === ':') {
233                                 html += ':';
234                         } else {
235                                 html += "<div style='display: inline-block; width: 15px'>" + text.charAt(i) + "</div>";
236                         }
237                 }
238                 document.getElementById(id).innerHTML = html;
239         } else {
240                 document.getElementById(id).innerHTML = text;
241         }
242 }
243
244 function update_clock(num)
245 {
246         update_given_clock(time_elapsed(num), clocks[num].id);
247 }
248
249 function goalA()
250 {
251         ++scoreA;
252         update_score();
253 }
254
255 function goalB()
256 {
257         ++scoreB;
258         update_score();
259 }
260
261 function ungoalA()
262 {
263         if (scoreA > 0) --scoreA;
264         update_score();
265 }
266
267 function ungoalB()
268 {
269         if (scoreB > 0) --scoreB;
270         update_score();
271 }
272
273 function resetscore()
274 {
275         scoreA = scoreB = 0;
276         update_score();
277 }
278
279 function update_score()
280 {
281         document.getElementById('score').innerHTML = scoreA + "&nbsp;–&nbsp;" + scoreB;
282 }
283
284 /* called by the Nageru theme only */
285 function play()
286 {
287         document.getElementById('manualcontrols').style.display = 'none';
288         document.getElementById('area').style.display = 'none';
289 }
290
291 function update(v)
292 {
293         console.log('[[[' + v + ']]]');
294         let j = JSON.parse(v);
295         for(let key in j) state[key] = j[key];
296 }
297
298 setInterval(function() {
299         for (let i = 0; i < num_clocks; ++i) {
300                 if (clocks[i].running) {
301                         update_clock(i);
302                 }
303         }
304 }, 100);
305 update_score();
306
307 //play();
308 //startclock();
309
310 let websocket = null;
311
312 function open_ws()
313 {
314         console.log("Connecting...");
315         try {
316                 if (websocket)
317                         websocket.close();
318                 websocket = new WebSocket("ws://127.0.0.1:5250/");
319                 websocket.onopen = function(evt) {
320                         console.log("Connected to client.");
321                 };
322                 websocket.onclose = function(evt) {
323                         console.log("Disconnected from client.");
324                         setTimeout(open_ws, 100);
325                 };
326                 websocket.onmessage = function(evt) {
327                         let msg = evt.data;
328                         let m = msg.match(/^update (.*)/);
329                         if (m !== null) {
330                                 update(m[1]);
331                         }
332                         m = msg.match(/^eval (.*)/);
333                         if (m !== null) {
334                                 eval(m[1]);
335                         }
336                 };
337                 websocket.onerror = function(evt) {
338                         console.log('Error: ' + evt.data);
339                 };
340         } catch (exception) {
341                 console.log('Error: ' + exception);
342                 setTimeout(open_ws, 100);
343         }
344 };
345 open_ws();