Get controller working + basic interface

This commit is contained in:
redfast00 2022-01-24 20:41:55 +01:00
parent 977ba5b589
commit 9cc70ea0f3
No known key found for this signature in database
GPG key ID: 5946E0E34FD0553C
4 changed files with 632 additions and 8 deletions

View file

@ -39,7 +39,7 @@ class PuzzleState:
class SharedWebToSerial:
game_duration: timedelta = timedelta(seconds=60)
max_allowed_strikes: int = 3
seed: int = 0
seed: int = 1
blocked_modules: list[ModuleAddress] = field(default_factory=list)
start_game: bool = False
restart_game: bool = False
@ -171,21 +171,23 @@ def serial_controller(serialport, web_to_serial, serial_to_web):
@app.route('/status.json')
def status():
status_dict = {
'gamestate': serial_to_web.gamestate.name
'gamestate': serial_to_web.gamestate.name,
'server_id': server_id
}
if serial_to_web.gamestate == Gamestate.GAME:
# Send the time left to avoid time syncronisation issues between server and client
# Client can then extrapolate if it wants to
status_dict['timeleft'] = (datetime.now() - serial_to_web.game_start).total_seconds()
status_dict['timeleft'] = (web_to_serial.game_duration - (datetime.now() - serial_to_web.game_start)).total_seconds()
elif serial_to_web.gamestate == Gamestate.GAMEOVER:
status_dict['timeleft'] = (serial_to_web.game_stop - serial_to_web.game_start).total_seconds()
if serial_to_web.gamestate in (Gamestate.DISCOVER, Gamestate.GAME, Gamestate.GAMEOVER):
status_dict['puzzles'] = [
{'address': address.to_binary(), 'solved': state.solved if address.is_puzzle() else None, 'strikes': state.strike_amount}
{'address': address.as_binary(), 'solved': state.solved if address.is_puzzle() else None, 'strikes': state.strike_amount}
for address, state
in serial_to_web.registered_modules.items()
]
print(status_dict)
return jsonify(status_dict)
@app.route('/start')
@ -211,6 +213,7 @@ if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python3 controller.py [serial port]")
sys.exit()
thread = Thread(target=serial_controller, args=(sys.argv[1], web_to_serial, serial_to_web))
thread.start()
if sys.argv[1] != 'mock':
thread = Thread(target=serial_controller, args=(sys.argv[1], web_to_serial, serial_to_web))
thread.start()
app.run(debug=False, host='0.0.0.0', port=8080)

View file

@ -4,11 +4,18 @@
<head>
<meta charset="utf-8">
<title>OBUS controller</title>
<link rel="stylesheet" href="/static/7sgd.css">
</head>
<body>
<body style="background: #222; color: #888">
<p>Timer: <div id="timeleft"></div></p>
<p>Game state: <div id="gamestate"></div></p>
<button onclick="startbutton()">START</button>
<button onclick="restartbutton()">RESTART</button>
<script src="static/controller.js"></script>
<canvas id="display" width="700">Timer should be here</canvas>
<script type="text/javascript" src="/static/segment-display.js"></script>
</body>
</html>

View file

@ -1,4 +1,6 @@
var estimated_timeout_date;
var display;
var laststate;
function startbutton() {
fetch('/start');
@ -7,3 +9,60 @@ function startbutton() {
function restartbutton() {
fetch('/restart');
}
function updateDisplay() {
if (laststate != 'GAME' || !estimated_timeout_date) {
return;
}
setTimeleft((estimated_timeout_date - (new Date())) * 1000);
}
function setTimeleft(timeleft) {
var integral = Math.floor(timeleft);
var fractional = timeleft - integral;
var minutes = Math.floor(integral / 60);
var seconds = integral % 60;
display.setValue(String(minutes).padStart(2, '0') + ':' + String(seconds).padStart(2, '0') + '.' + String(Math.floor(fractional * 10)));
}
function state_update() {
// TODO automatically timeout this request after the update interval
fetch('/status.json')
.then(
function(response) {
if (response.status !== 200) {
console.log('FAIL: ' + response.status);
return;
}
response.json().then(function(data) {
document.getElementById('gamestate').innerHTML = data['gamestate'];
laststate = data['gamestate'];
if (data['gamestate'] == 'GAME') {
// TODO maybe smooth this with the previous value of estimated_timeout_date?
var new_estimate = new Date();
new_estimate.setSeconds(new_estimate.getSeconds() + data['timeleft']);
estimated_timeout_date = new_estimate;
}
});
}
)
}
window.onload = function() {
setInterval(state_update, 500);
display = new SegmentDisplay("display");
display.pattern = "##:##.#";
display.displayAngle = 0;
display.digitHeight = 26.5;
display.digitWidth = display.digitHeight / 2;
display.digitDistance = 2.9;
display.segmentWidth = 3;
display.segmentDistance = 0.3;
display.segmentCount = 7;
display.cornerType = 1;
display.colorOn = "#24dd22";
display.colorOff = "#1b4105";
display.draw();
display.draw();
};

View file

@ -0,0 +1,555 @@
/*!
* segment-display.js
*
* Copyright 2012, Rüdiger Appel
* http://www.3quarks.com
* Published under Creative Commons 3.0 License.
*
* Date: 2012-02-14
* Version: 1.0.0
*
* Dokumentation: http://www.3quarks.com/de/Segmentanzeige
* Documentation: http://www.3quarks.com/en/SegmentDisplay
*/
// Segment display types
SegmentDisplay.SevenSegment = 7;
SegmentDisplay.FourteenSegment = 14;
SegmentDisplay.SixteenSegment = 16;
// Segment corner types
SegmentDisplay.SymmetricCorner = 0;
SegmentDisplay.SquaredCorner = 1;
SegmentDisplay.RoundedCorner = 2;
function SegmentDisplay(displayId) {
this.displayId = displayId;
this.pattern = '##:##:##';
this.value = '12:34:56';
this.digitHeight = 20;
this.digitWidth = 10;
this.digitDistance = 2.5;
this.displayAngle = 12;
this.segmentWidth = 2.5;
this.segmentDistance = 0.2;
this.segmentCount = SegmentDisplay.SevenSegment;
this.cornerType = SegmentDisplay.RoundedCorner;
this.colorOn = 'rgb(233, 93, 15)';
this.colorOff = 'rgb(75, 30, 5)';
};
SegmentDisplay.prototype.setValue = function(value) {
this.value = value;
this.draw();
};
SegmentDisplay.prototype.draw = function() {
var display = document.getElementById(this.displayId);
if (display) {
var context = display.getContext('2d');
if (context) {
// clear canvas
context.clearRect(0, 0, display.width, display.height);
// compute and check display width
var width = 0;
var first = true;
if (this.pattern) {
for (var i = 0; i < this.pattern.length; i++) {
var c = this.pattern.charAt(i).toLowerCase();
if (c == '#') {
width += this.digitWidth;
} else if (c == '.' || c == ':') {
width += this.segmentWidth;
} else if (c != ' ') {
return;
}
width += first ? 0 : this.digitDistance;
first = false;
}
}
if (width <= 0) {
return;
}
// compute skew factor
var angle = -1.0 * Math.max(-45.0, Math.min(45.0, this.displayAngle));
var skew = Math.tan((angle * Math.PI) / 180.0);
// compute scale factor
var scale = Math.min(display.width / (width + Math.abs(skew * this.digitHeight)), display.height / this.digitHeight);
// compute display offset
var offsetX = (display.width - (width + skew * this.digitHeight) * scale) / 2.0;
var offsetY = (display.height - this.digitHeight * scale) / 2.0;
// context transformation
context.save();
context.translate(offsetX, offsetY);
context.scale(scale, scale);
context.transform(1, 0, skew, 1, 0, 0);
// draw segments
var xPos = 0;
var size = (this.value) ? this.value.length : 0;
for (var i = 0; i < this.pattern.length; i++) {
var mask = this.pattern.charAt(i);
var value = (i < size) ? this.value.charAt(i).toLowerCase() : ' ';
xPos += this.drawDigit(context, xPos, mask, value);
}
// finish drawing
context.restore();
}
}
};
SegmentDisplay.prototype.drawDigit = function(context, xPos, mask, c) {
switch (mask) {
case '#':
var r = Math.sqrt(this.segmentWidth * this.segmentWidth / 2.0);
var d = Math.sqrt(this.segmentDistance * this.segmentDistance / 2.0);
var e = d / 2.0;
var f = (this.segmentWidth - d) * Math.sin((45.0 * Math.PI) / 180.0);
var g = f / 2.0;
var h = (this.digitHeight - 3.0 * this.segmentWidth) / 2.0;
var w = (this.digitWidth - 3.0 * this.segmentWidth) / 2.0;
var s = this.segmentWidth / 2.0;
var t = this.digitWidth / 2.0;
// draw segment a (a1 and a2 for 16 segments)
if (this.segmentCount == 16) {
var x = xPos;
var y = 0;
context.fillStyle = this.getSegmentColor(c, null, '02356789abcdefgiopqrstz@%');
context.beginPath();
switch (this.cornerType) {
case SegmentDisplay.SymmetricCorner:
context.moveTo(x + s + d, y + s);
context.lineTo(x + this.segmentWidth + d, y);
break;
case SegmentDisplay.SquaredCorner:
context.moveTo(x + s + e, y + s - e);
context.lineTo(x + this.segmentWidth, y);
break;
default:
context.moveTo(x + this.segmentWidth - f, y + this.segmentWidth - f - d);
context.quadraticCurveTo(x + this.segmentWidth - g, y, x + this.segmentWidth, y);
}
context.lineTo(x + t - d - s, y);
context.lineTo(x + t - d, y + s);
context.lineTo(x + t - d - s, y + this.segmentWidth);
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
context.fill();
var x = xPos;
var y = 0;
context.fillStyle = this.getSegmentColor(c, null, '02356789abcdefgiopqrstz@');
context.beginPath();
context.moveTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
context.lineTo(x + t + d + s, y + this.segmentWidth);
context.lineTo(x + t + d, y + s);
context.lineTo(x + t + d + s, y);
switch (this.cornerType) {
case SegmentDisplay.SymmetricCorner:
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
context.lineTo(x + this.digitWidth - s - d, y + s);
break;
case SegmentDisplay.SquaredCorner:
context.lineTo(x + this.digitWidth - this.segmentWidth, y);
context.lineTo(x + this.digitWidth - s - e, y + s - e);
break;
default:
context.lineTo(x + this.digitWidth - this.segmentWidth, y);
context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y, x + this.digitWidth - this.segmentWidth + f, y + this.segmentWidth - f - d);
}
context.fill();
} else {
var x = xPos;
var y = 0;
context.fillStyle = this.getSegmentColor(c, '02356789acefp', '02356789abcdefgiopqrstz@');
context.beginPath();
switch (this.cornerType) {
case SegmentDisplay.SymmetricCorner:
context.moveTo(x + s + d, y + s);
context.lineTo(x + this.segmentWidth + d, y);
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
context.lineTo(x + this.digitWidth - s - d, y + s);
break;
case SegmentDisplay.SquaredCorner:
context.moveTo(x + s + e, y + s - e);
context.lineTo(x + this.segmentWidth, y);
context.lineTo(x + this.digitWidth - this.segmentWidth, y);
context.lineTo(x + this.digitWidth - s - e, y + s - e);
break;
default:
context.moveTo(x + this.segmentWidth - f, y + this.segmentWidth - f - d);
context.quadraticCurveTo(x + this.segmentWidth - g, y, x + this.segmentWidth, y);
context.lineTo(x + this.digitWidth - this.segmentWidth, y);
context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y, x + this.digitWidth - this.segmentWidth + f, y + this.segmentWidth - f - d);
}
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
context.fill();
}
// draw segment b
x = xPos + this.digitWidth - this.segmentWidth;
y = 0;
context.fillStyle = this.getSegmentColor(c, '01234789adhpy', '01234789abdhjmnopqruwy');
context.beginPath();
switch (this.cornerType) {
case SegmentDisplay.SymmetricCorner:
context.moveTo(x + s, y + s + d);
context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
break;
case SegmentDisplay.SquaredCorner:
context.moveTo(x + s + e, y + s + e);
context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
break;
default:
context.moveTo(x + f + d, y + this.segmentWidth - f);
context.quadraticCurveTo(x + this.segmentWidth, y + this.segmentWidth - g, x + this.segmentWidth, y + this.segmentWidth);
}
context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
context.lineTo(x + s, y + h + this.segmentWidth + s - d);
context.lineTo(x, y + h + this.segmentWidth - d);
context.lineTo(x, y + this.segmentWidth + d);
context.fill();
// draw segment c
x = xPos + this.digitWidth - this.segmentWidth;
y = h + this.segmentWidth;
context.fillStyle = this.getSegmentColor(c, '013456789abdhnouy', '01346789abdghjmnoqsuw@', '%');
context.beginPath();
context.moveTo(x, y + this.segmentWidth + d);
context.lineTo(x + s, y + s + d);
context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
switch (this.cornerType) {
case SegmentDisplay.SymmetricCorner:
context.lineTo(x + s, y + h + this.segmentWidth + s - d);
context.lineTo(x, y + h + this.segmentWidth - d);
break;
case SegmentDisplay.SquaredCorner:
context.lineTo(x + s + e, y + h + this.segmentWidth + s - e);
context.lineTo(x, y + h + this.segmentWidth - d);
break;
default:
context.quadraticCurveTo(x + this.segmentWidth, y + h + this.segmentWidth + g, x + f + d, y + h + this.segmentWidth + f); //
context.lineTo(x, y + h + this.segmentWidth - d);
}
context.fill();
// draw segment d (d1 and d2 for 16 segments)
if (this.segmentCount == 16) {
x = xPos;
y = this.digitHeight - this.segmentWidth;
context.fillStyle = this.getSegmentColor(c, null, '0235689bcdegijloqsuz_=@');
context.beginPath();
context.moveTo(x + this.segmentWidth + d, y);
context.lineTo(x + t - d - s, y);
context.lineTo(x + t - d, y + s);
context.lineTo(x + t - d - s, y + this.segmentWidth);
switch (this.cornerType) {
case SegmentDisplay.SymmetricCorner:
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
context.lineTo(x + s + d, y + s);
break;
case SegmentDisplay.SquaredCorner:
context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
context.lineTo(x + s + e, y + s + e);
break;
default:
context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
context.quadraticCurveTo(x + this.segmentWidth - g, y + this.segmentWidth, x + this.segmentWidth - f, y + f + d);
context.lineTo(x + this.segmentWidth - f, y + f + d);
}
context.fill();
x = xPos;
y = this.digitHeight - this.segmentWidth;
context.fillStyle = this.getSegmentColor(c, null, '0235689bcdegijloqsuz_=@', '%');
context.beginPath();
context.moveTo(x + t + d + s, y + this.segmentWidth);
context.lineTo(x + t + d, y + s);
context.lineTo(x + t + d + s, y);
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
switch (this.cornerType) {
case SegmentDisplay.SymmetricCorner:
context.lineTo(x + this.digitWidth - s - d, y + s);
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
break;
case SegmentDisplay.SquaredCorner:
context.lineTo(x + this.digitWidth - s - e, y + s + e);
context.lineTo(x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
break;
default:
context.lineTo(x + this.digitWidth - this.segmentWidth + f, y + f + d);
context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y + this.segmentWidth, x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
}
context.fill();
}
else {
x = xPos;
y = this.digitHeight - this.segmentWidth;
context.fillStyle = this.getSegmentColor(c, '0235689bcdelotuy_', '0235689bcdegijloqsuz_=@');
context.beginPath();
context.moveTo(x + this.segmentWidth + d, y);
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
switch (this.cornerType) {
case SegmentDisplay.SymmetricCorner:
context.lineTo(x + this.digitWidth - s - d, y + s);
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
context.lineTo(x + s + d, y + s);
break;
case SegmentDisplay.SquaredCorner:
context.lineTo(x + this.digitWidth - s - e, y + s + e);
context.lineTo(x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
context.lineTo(x + s + e, y + s + e);
break;
default:
context.lineTo(x + this.digitWidth - this.segmentWidth + f, y + f + d);
context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y + this.segmentWidth, x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
context.quadraticCurveTo(x + this.segmentWidth - g, y + this.segmentWidth, x + this.segmentWidth - f, y + f + d);
context.lineTo(x + this.segmentWidth - f, y + f + d);
}
context.fill();
}
// draw segment e
x = xPos;
y = h + this.segmentWidth;
context.fillStyle = this.getSegmentColor(c, '0268abcdefhlnoprtu', '0268acefghjklmnopqruvw@');
context.beginPath();
context.moveTo(x, y + this.segmentWidth + d);
context.lineTo(x + s, y + s + d);
context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
switch (this.cornerType) {
case SegmentDisplay.SymmetricCorner:
context.lineTo(x + s, y + h + this.segmentWidth + s - d);
context.lineTo(x, y + h + this.segmentWidth - d);
break;
case SegmentDisplay.SquaredCorner:
context.lineTo(x + s - e, y + h + this.segmentWidth + s - d + e);
context.lineTo(x, y + h + this.segmentWidth);
break;
default:
context.lineTo(x + this.segmentWidth - f - d, y + h + this.segmentWidth + f);
context.quadraticCurveTo(x, y + h + this.segmentWidth + g, x, y + h + this.segmentWidth);
}
context.fill();
// draw segment f
x = xPos;
y = 0;
context.fillStyle = this.getSegmentColor(c, '045689abcefhlpty', '045689acefghklmnopqrsuvwy@', '%');
context.beginPath();
context.moveTo(x + this.segmentWidth, y + this.segmentWidth + d);
context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
context.lineTo(x + s, y + h + this.segmentWidth + s - d);
context.lineTo(x, y + h + this.segmentWidth - d);
switch (this.cornerType) {
case SegmentDisplay.SymmetricCorner:
context.lineTo(x, y + this.segmentWidth + d);
context.lineTo(x + s, y + s + d);
break;
case SegmentDisplay.SquaredCorner:
context.lineTo(x, y + this.segmentWidth);
context.lineTo(x + s - e, y + s + e);
break;
default:
context.lineTo(x, y + this.segmentWidth);
context.quadraticCurveTo(x, y + this.segmentWidth - g, x + this.segmentWidth - f - d, y + this.segmentWidth - f);
context.lineTo(x + this.segmentWidth - f - d, y + this.segmentWidth - f);
}
context.fill();
// draw segment g for 7 segments
if (this.segmentCount == 7) {
x = xPos;
y = (this.digitHeight - this.segmentWidth) / 2.0;
context.fillStyle = this.getSegmentColor(c, '2345689abdefhnoprty-=');
context.beginPath();
context.moveTo(x + s + d, y + s);
context.lineTo(x + this.segmentWidth + d, y);
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
context.lineTo(x + this.digitWidth - s - d, y + s);
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
context.fill();
}
// draw inner segments for the fourteen- and sixteen-segment-display
if (this.segmentCount != 7) {
// draw segment g1
x = xPos;
y = (this.digitHeight - this.segmentWidth) / 2.0;
context.fillStyle = this.getSegmentColor(c, null, '2345689aefhkprsy-+*=', '%');
context.beginPath();
context.moveTo(x + s + d, y + s);
context.lineTo(x + this.segmentWidth + d, y);
context.lineTo(x + t - d - s, y);
context.lineTo(x + t - d, y + s);
context.lineTo(x + t - d - s, y + this.segmentWidth);
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
context.fill();
// draw segment g2
x = xPos;
y = (this.digitHeight - this.segmentWidth) / 2.0;
context.fillStyle = this.getSegmentColor(c, null, '234689abefghprsy-+*=@', '%');
context.beginPath();
context.moveTo(x + t + d, y + s);
context.lineTo(x + t + d + s, y);
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
context.lineTo(x + this.digitWidth - s - d, y + s);
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
context.lineTo(x + t + d + s, y + this.segmentWidth);
context.fill();
// draw segment j
x = xPos + t - s;
y = 0;
context.fillStyle = this.getSegmentColor(c, null, 'bdit+*', '%');
context.beginPath();
if (this.segmentCount == 14) {
context.moveTo(x, y + this.segmentWidth + this.segmentDistance);
context.lineTo(x + this.segmentWidth, y + this.segmentWidth + this.segmentDistance);
} else {
context.moveTo(x, y + this.segmentWidth + d);
context.lineTo(x + s, y + s + d);
context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
}
context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
context.lineTo(x + s, y + h + this.segmentWidth + s - d);
context.lineTo(x, y + h + this.segmentWidth - d);
context.fill();
// draw segment m
x = xPos + t - s;
y = this.digitHeight;
context.fillStyle = this.getSegmentColor(c, null, 'bdity+*@', '%');
context.beginPath();
if (this.segmentCount == 14) {
context.moveTo(x, y - this.segmentWidth - this.segmentDistance);
context.lineTo(x + this.segmentWidth, y - this.segmentWidth - this.segmentDistance);
} else {
context.moveTo(x, y - this.segmentWidth - d);
context.lineTo(x + s, y - s - d);
context.lineTo(x + this.segmentWidth, y - this.segmentWidth - d);
}
context.lineTo(x + this.segmentWidth, y - h - this.segmentWidth + d);
context.lineTo(x + s, y - h - this.segmentWidth - s + d);
context.lineTo(x, y - h - this.segmentWidth + d);
context.fill();
// draw segment h
x = xPos + this.segmentWidth;
y = this.segmentWidth;
context.fillStyle = this.getSegmentColor(c, null, 'mnx\\*');
context.beginPath();
context.moveTo(x + this.segmentDistance, y + this.segmentDistance);
context.lineTo(x + this.segmentDistance + r, y + this.segmentDistance);
context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance - r);
context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance);
context.lineTo(x + w - this.segmentDistance - r , y + h - this.segmentDistance);
context.lineTo(x + this.segmentDistance, y + this.segmentDistance + r);
context.fill();
// draw segment k
x = xPos + w + 2.0 * this.segmentWidth;
y = this.segmentWidth;
context.fillStyle = this.getSegmentColor(c, null, '0kmvxz/*', '%');
context.beginPath();
context.moveTo(x + w - this.segmentDistance, y + this.segmentDistance);
context.lineTo(x + w - this.segmentDistance, y + this.segmentDistance + r);
context.lineTo(x + this.segmentDistance + r, y + h - this.segmentDistance);
context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance);
context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance - r);
context.lineTo(x + w - this.segmentDistance - r, y + this.segmentDistance);
context.fill();
// draw segment l
x = xPos + w + 2.0 * this.segmentWidth;
y = h + 2.0 * this.segmentWidth;
context.fillStyle = this.getSegmentColor(c, null, '5knqrwx\\*');
context.beginPath();
context.moveTo(x + this.segmentDistance, y + this.segmentDistance);
context.lineTo(x + this.segmentDistance + r, y + this.segmentDistance);
context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance - r);
context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance);
context.lineTo(x + w - this.segmentDistance - r , y + h - this.segmentDistance);
context.lineTo(x + this.segmentDistance, y + this.segmentDistance + r);
context.fill();
// draw segment n
x = xPos + this.segmentWidth;
y = h + 2.0 * this.segmentWidth;
context.fillStyle = this.getSegmentColor(c, null, '0vwxz/*', '%');
context.beginPath();
context.moveTo(x + w - this.segmentDistance, y + this.segmentDistance);
context.lineTo(x + w - this.segmentDistance, y + this.segmentDistance + r);
context.lineTo(x + this.segmentDistance + r, y + h - this.segmentDistance);
context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance);
context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance - r);
context.lineTo(x + w - this.segmentDistance - r, y + this.segmentDistance);
context.fill();
}
return this.digitDistance + this.digitWidth;
case '.':
context.fillStyle = (c == '#') || (c == '.') ? this.colorOn : this.colorOff;
this.drawPoint(context, xPos, this.digitHeight - this.segmentWidth, this.segmentWidth);
return this.digitDistance + this.segmentWidth;
case ':':
context.fillStyle = (c == '#') || (c == ':') ? this.colorOn : this.colorOff;
var offset = this.segmentWidth / 2;
var y = (this.digitHeight - this.segmentWidth) / 2.0 - this.segmentWidth;
this.drawPoint(context, xPos, y - offset, this.segmentWidth);
this.drawPoint(context, xPos, y + 2.0 * this.segmentWidth + offset, this.segmentWidth);
return this.digitDistance + this.segmentWidth;
default:
return this.digitDistance;
}
};
SegmentDisplay.prototype.drawPoint = function(context, x1, y1, size) {
var x2 = x1 + size;
var y2 = y1 + size;
var d = size / 4.0;
context.beginPath();
context.moveTo(x2 - d, y1);
context.quadraticCurveTo(x2, y1, x2, y1 + d);
context.lineTo(x2, y2 - d);
context.quadraticCurveTo(x2, y2, x2 - d, y2);
context.lineTo(x1 + d, y2);
context.quadraticCurveTo(x1, y2, x1, y2 - d);
context.lineTo(x1, y1 + d);
context.quadraticCurveTo(x1, y1, x1 + d, y1);
context.fill();
};
SegmentDisplay.prototype.getSegmentColor = function(c, charSet7, charSet14, charSet16) {
if (c == '#') {
return this.colorOn;
} else {
switch (this.segmentCount) {
case 7: return (charSet7.indexOf(c) == -1) ? this.colorOff : this.colorOn;
case 14: return (charSet14.indexOf(c) == -1) ? this.colorOff : this.colorOn;
case 16: var pattern = charSet14 + (charSet16 === undefined ? '' : charSet16);
return (pattern.indexOf(c) == -1) ? this.colorOff : this.colorOn;
default: return this.colorOff;
}
}
};