Skip to content

Instantly share code, notes, and snippets.

@Alikberov
Created August 17, 2023 09:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Alikberov/99c02e12fa83b8d6ad15736c60b0632a to your computer and use it in GitHub Desktop.
Save Alikberov/99c02e12fa83b8d6ad15736c60b0632a to your computer and use it in GitHub Desktop.
Televison Receiver Simulator
<html>
<head>
<meta http-equiv='refresh' content='1600'>
<title>Television Receiver Simulator</title>
<script>
class TELEVISION extends HTMLCanvasElement {
constructor() {
super();
this.time = 0;
this.speed = 1;
this.teleVision = "v0.23.07.20";
this.playing = false;
this.firstTime = new Date();
this.ctx = this.getContext("2d");
this.imageData = this.ctx.getImageData(0, 0, this.width, this.height);
this.raster = [];
this.lines = 768;
this.grains = 1024;
this.sync = 0;
this.new_lines = 0;
this.clock = 0;
this.noising = 502;
this.render();
}
flush() {
this.ctx.putImageData(this.imageData, 0, 0);
}
rasterize_asm() {
"use asm";
var width = this.width|0;
var height = this.height|0;
var lines = this.lines|0;
var grains = this.grains|0;
var pixels = this.imageData.data;
var i = 0|0;
var d = 0|0;
var c = 0|0;
var dots = 0|0;
var rows = 0|0;
var sync = 0|0;
var top = (((height|0) - (lines|0)) >> 1)|0;
var left = 0|0;
var r = 0|0;
var g = 0|0;
var b = 0|0;
var a = 0|0;
var x = 0|0;
var y = 0|0;
var flag = 0|0;
var raster = this.raster;
var clock = this.clock|0;
var raslen = this.raster.length|0;
for(y = 0|0; (y|0) < (height|0); y = (y|0) + 2 | 0) {
i = ((y|0) * (width|0) << 2)|0;
left = (((width|0) - (grains|0)) >> 1)|0;
for(x = 0|0; (x|0) < (width|0); x = (x|0) + 1 | 0) {
flag = (x|0) >= (left|0) && (y|0) >= (top|0) ? 1|0 : 0|0;
if((flag|0) > 0) {
d = raster[clock]|0;
clock = (clock|0) + 1 | 0;
if((clock|0) >= (raslen|0))
clock = 0|0;
if((d|0) < 0) {
sync = (sync|0) + 1 | 0;
if((sync|0) > 800|0) {
if((lines|0) > 0)
rows = lines|0;
lines = 0|0;
} else
if((sync|0) > 8) {
if((dots|0) > 0)
lines = (lines|0) + 1 | 0,
grains = dots|0;
dots = 0|0;
}
} else {
dots = (dots + 1)|0;
if((dots|0) > 0)
sync = 0|0;
}
r = c|0;
g = c|0;
b = c|0;
a = 255|0;
} else
r = 0|0,
g = 96|0,
b = 255|0,
a = 255|0;
pixels[(i|0) + 3336] = r|0;
pixels[i|0] = r|0; i = (i|0) + 1 | 0;
pixels[(i|0) + 3336] = g|0;
pixels[i|0] = g|0; i = (i|0) + 1 | 0;
pixels[(i|0) + 3336] = b|0;
pixels[i|0] = b|0; i = (i|0) + 1 | 0;
pixels[(i|0) + 3336] = a|0;
pixels[i|0] = a|0; i = (i|0) + 1 | 0;
}
}
this.clock = clock;
this.lines = rows;
this.grains = grains;
}
rasterize() {
var width = this.width;
var height = this.height;
var lines = this.lines;
var grains = this.grains;
var pair = width * 4;
var clock = this.clock;
var pixels = this.imageData.data;
var raslen = this.raster.length;
var blanking = Math.floor(width * 3 / 2);
var sync = this.sync;
var top = sync > 0 ? 0 : (height - lines) >> 1;
var new_lines = this.new_lines;
var new_grains = 0;
var start = sync > width >> 6 ? 0 : 1;
var i, d = 0, c = 0, flag;
var left;
var yd = 1;
var r, g, b, a;
var x, y;
for(y = 0; y < height; y += 2) {
i = y * width * 4;
left = (width - grains) >> 1;
for(x = 0; x < width; ++ x) {
flag = y >= top * start && x >= left;
if(flag) {
d = this.raster[clock ++] + Math.random() * this.noising;
c = d < 0 ? 0 : Math.floor(d / 4);
if(clock >= raslen)
clock = 0;
if(d < 0) {
sync ++;
if(sync >= blanking) {
if(sync == blanking) {
lines = new_lines << 1,
new_lines = 0;
if(y < height / 2)
y -= y >= 4 ? 2 : 2;
else
y += 2;
i = y * width * 4;
x -= 0;
}
r = Math.random() * 25 + 160,
g = Math.random() * 25 + 64,
b = Math.random() * 25 + 60;
} else
if(sync >= width >> 6) {
if(sync == width >> 6)
new_lines ++,
grains = new_grains,
left = width,
new_grains = 78;
r = Math.random() * 25,
g = Math.random() * 25 + 64,
b = Math.random() * 25 + 192;
}
} else {
start = 1;
yd = 0;
new_grains ++;
//if(new_grains > 8)
sync = 0;
r = g = b = c;
}
a = 255;
} else
a = 255,
r = Math.random() * 25,
g = Math.random() * 25 + 48,
b = Math.random() * 25 + 160;
pixels[i + pair] = r;
pixels[i ++] = r;
pixels[i + pair] = g;
pixels[i ++] = g;
pixels[i + pair] = b;
pixels[i ++] = b;
pixels[i + pair] = a;
pixels[i ++] = a;
}
}
this.sync = sync;
this.clock = clock;
this.lines = lines;
this.new_lines = new_lines;
this.grains = grains;
}
render() {
if(this.playing) {
this.rasterize();
this.flush();
}
window.requestAnimationFrame(this.render.bind(this));
}
play(img) {
this.playing = true;
if(img)
this.ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, this.width, this.height);
this.imageData = this.ctx.getImageData(0, 0, this.width, this.height);
var m = this.width * this.height >> 1;
var j = m >> 1;
for(var y = 0; y < this.height - 2; y += 2) {
for(var x = 0; x < this.width; ++ x) {
var i = (y * this.width + x) * 4;
var r = this.imageData.data[i + 2];
var g = this.imageData.data[i + 1];
var b = this.imageData.data[i];
var d = y < 5 || x < (this.width >> 6) + Math.random() * 9 - 5 ? -500 - Math.floor(500 * Math.random()) : Math.max(r, g, b) * 4;
this.raster[j ++] = d;
if(j >= m)
j = 0;
}
}
}
stop() {
this.playing = false;
}
receive(signal) {
var line = {
shading :0,
noise :[]
};
var shading = 0;
for(var data of signal) {
if(data < 0) {
if(shading > 10 && line.noise.length > 0) {
this.raster.push(line);
line = {
shading :0,
noise :[]
};
}
shading ++;
} else {
if(shading > 10)
line.shading = shading;
line.noise.push(data);
if(shading > 0)
shading --;
}
}
}
}
customElements.define("tele-vision", TELEVISION, { extends: "canvas" });
function main(img) {
canvas = document.querySelector("canvas");
if("teleVision" in canvas) {
var speed = window.location.href.match(/speed=(?<speed>\d+)/i);
/*var arr = [];
for(var i = 0; i < 327684; ++ i)
arr[i] = Math.floor(Math.random() * 2000 - 900);
canvas.receive(arr);*/
canvas.play(img);
}
}
</script>
<style>
body {
background-color:silver;
margin :0px 0px 0px 0px;
padding :0px 0px 0px 0px;
}
</style>
</head>
<body>
Noise level:<input type=number min=100 max=509 value=501 onchange='canvas.noising = this.value' /><br />
<canvas is='tele-vision' width=512 height=384></canvas>
<img crossOrigin='' src='https://i.imgur.com/iWjkVft.jpg' onload='main(this)' />
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment