File: /var/www/html/simulink/circuit/pong/pongsplit.html
<meta name="viewport" content="width=820">
<title>Circuit Simulator Applet</title>
<link rel="SHORTCUT ICON" href="favicon.ico">
<link rel="stylesheet" href="pong.css" type="text/css">
<body>
<hr>
<div class="split">
<div id="split-0">
<iframe id="circuitFrame" src="../circuitjs.html?startCircuit=pongvonly.txt&mouseMode=DragAll"></iframe>
</div>
<div id="split-1">
<div id="info"></div>
<button onclick="startGame()">New Game</button>
<button onclick="stopGame()">Attract Mode</button>
<div class="checkbox">Autoplay: <input type="checkbox" id="autoplayCheck"><br>
<br>
<canvas id="canvas" width=375 height=246 style="background-color:black;"></canvas>
<p>
Here is some text explaining what's happening.
<p>
Here is some more text.
</div>
<script type="module">
import Split from './split.js';
Split(['#split-0', '#split-1'], { sizes: [70, 30] });
// get iframe the simulator is running in. Must have same origin as this file!
var iframe = document.getElementById("circuitFrame");
var sim;
var freq, ampl;
var v1, h256, video, ctx, vblank, vpad1, vpad2, vvid, Aa, Ba;
var pad1 = 100, pad2 = 100, lineCount;
var nettext = '';
var highlightY = -1;
var savedLine;
var resetCounter = 50;
var attractMode = false;
function didAnalyze(sim) {
v1 = sim.getNode("1V");
h256 = sim.getNode("256H");
video = sim.getNode("VIDEO");
vblank = sim.getNode("VBLANK");
vpad1 = sim.getNode("/VPAD1");
vpad2 = sim.getNode("/VPAD2");
vvid = sim.getNode("/VVID");
Aa = sim.getNode("Aa");
Ba = sim.getNode("Ba");
}
// called when simulator updates its display
function didUpdate(sim) {
var info = document.getElementById("info");
if (savedLine)
ctx.putImageData(savedLine, 0, highlightY);
highlightY = y-1;
ctx.fillStyle = "red";
savedLine = ctx.getImageData(0, highlightY, 455, 1);
if (lineCount < 150)
ctx.fillRect(0, highlightY, 455, 1);
ctx.fillStyle = "white";
if (serveTime > 0 && sim.getTime() > serveTime) {
serveTime = 0;
if (!attractMode)
ballx = 200;
}
sim.setExtVoltage("/SERVE", serveTime == 0 ? 5 : 0);
if (scTime > 0 && sim.getTime() > scTime) {
scTime = 0;
sim.setExtVoltage("SC", 0);
}
if (resetCounter == 0 && sim.getNodeVoltage("STOP G") > 2.5)
sim.setExtVoltage("/RUN", 5);
lineCount = 0;
}
var lastv1 = -1;
var y = 0;
var ballx = 200;
var clearedY = -1;
var oldmiss = true, oldhit = true;
var serveTime = 0;
var scTime = 0;
var needH256 = 0;
var oldVblank = false;
var ballY;
var padAdj = 0;
// called every timestep
function didStep(sim) {
if (needH256 > 0) {
var h = h256.getVoltage();
if ((h > 2.5) == (ballx > 256)) {
needH256--;
if (needH256 == 0)
setHit(sim, true)
}
}
var c = v1.getVoltage();
if (c == lastv1)
return;
lastv1 = c;
y++;
lineCount++;
var Aaval = (Aa.getVoltage() > 2.5) ? 1 : 0;
var Baval = (Ba.getVoltage() > 2.5) ? 1 : 0;
ballx += 2-(Aaval+Baval*2);
var miss = (ballx < 0 || ballx >= 375);
if (miss != oldmiss) {
if (ballx < 0)
ballx += 375;
if (ballx >= 375)
ballx -= 375;
sim.setExtVoltage("/MISS", miss ? 0 : 5);
oldmiss = miss;
if (miss) {
serveTime = sim.getTime() + 1;
sim.setExtVoltage("SC", 5);
sim.setExtVoltage("/SERVE", 5);
scTime = sim.getTime() + .5;
}
}
if (vblank.getVoltage() > 2.5) {
y = 0;
clearedY = -1;
if (!oldVblank) {
sim.setExtVoltage("PADTRIGGER1", 5);
sim.setExtVoltage("PADTRIGGER2", 5);
attractMode = sim.getNodeVoltage("ATTRACT") > 2.5;
if (autoplayCheck.checked)
pad1 = pad2 = Math.max(1, ballY-8+padAdj);
}
oldVblank = true;
} else
oldVblank = false;
if (y == pad1)
sim.setExtVoltage("PADTRIGGER1", 0);
if (y == pad2)
sim.setExtVoltage("PADTRIGGER2", 0);
ctx.fillStyle = "black";
ctx.fillRect(0, y, 455, 1);
ctx.fillStyle = "white";
if (video.getVoltage() > 2.5 && (serveTime == 0 || attractMode)) {
ctx.fillRect(ballx, y, 4, 1);
ballY = y;
}
var hit = false;
if (vpad1.getVoltage() < 2.5 && !attractMode) {
ctx.fillRect(48, y, 4, 1);
if ((ballx >= 48 && ballx <= 52) && vvid.getVoltage() < 2.5)
hit = true;
}
if (vpad2.getVoltage() < 2.5 && !attractMode) {
ctx.fillRect(48+256, y, 4, 1);
if ((ballx >= 48+256 && ballx <= 52+256) && vvid.getVoltage() < 2.5)
hit = true;
}
if (hit != oldhit) {
if (hit) {
// we got a hit but we need to wait until 256H has the correct value
// before setting HIT. actually wait 10 iterations after that so that
// we have a chance to process all the logic.
needH256 = 10;
} else
setHit(sim, false);
oldhit = hit;
}
if (y % 8 < 4)
ctx.fillRect(256-80, y, 1, 1);
var realY = y+16;
if (realY >= 32 && realY < 64) {
ctx.translate(-80, 0);
ctx.fillStyle = "#d4d4d4";
drawScore(realY);
ctx.translate(+80, 0);
}
if (resetCounter > 0) {
resetCounter--;
sim.setExtVoltage("SRST", resetCounter == 0 ? 0 : 5);
}
}
var code11, code12, code21, code22;
function getCode(name) {
var s1 = sim.getNodeVoltage(name + "_1") > 2.5 ? 1 : 0;
var s2 = sim.getNodeVoltage(name + "_2") > 2.5 ? 2 : 0;
var s4 = sim.getNodeVoltage(name + "_4") > 2.5 ? 4 : 0;
var s8 = sim.getNodeVoltage(name + "_8") > 2.5 ? 8 : 0;
return decoder[s1+s2+s4+s8];
}
function drawScore(ry) {
if (ry == 32) {
code11 = sim.getNodeVoltage("SCORE1_10") > 2.5 ? decoder[1] : null;
code12 = getCode("SCORE1");
code21 = sim.getNodeVoltage("SCORE2_10") > 2.5 ? decoder[1] : null;
code22 = getCode("SCORE2");
}
drawScoreDigit(128, ry, code11);
drawScoreDigit(128+32, ry, code12);
drawScoreDigit(256+64, ry, code21);
drawScoreDigit(256+64+32, ry, code22);
}
var decoder = [
[true,true,true,true,true,true,false],//0
[false,true,true,false,false,false,false],//1
[true,true,false,true,true,false,true],//2
[true,true,true,true,false,false,true],//3
[false,true,true,false,false,true,true],//4
[true,false,true,true,false,true,true],//5
[true,false,true,true,true,true,true],//6
[true,true,true,false,false,false,false],//7
[true,true,true,true,true,true,true],//8
[true,true,true,false,false,true,true]//9
];
function drawScoreDigit(x, ry, code) {
if (!code)
return;
if (ry & 16) {
if (code[4])
ctx.fillRect(x+16, y, 4, 1); // E
if (code[2])
ctx.fillRect(x+16+4+8, y, 4, 1); // C
if (code[3] && (ry & (4+8)) == 12)
ctx.fillRect(x+16, y, 16, 1); // D
} else {
if (code[5])
ctx.fillRect(x+16, y, 4, 1); // F
if (code[1])
ctx.fillRect(x+16+4+8, y, 4, 1); // B
if (code[0] && (ry & (4+8)) == 0)
ctx.fillRect(x+16, y, 16, 1); // A
if (code[6] && (ry & (4+8)) == 12)
ctx.fillRect(x+16, y, 16, 1); // G
}
// c, 16V=1, 16H=1, 4H=1, 8H=1
// a: 16V=0, 8V=0, 4V=0, 16H=1
// g: 4V=1, 8V=1, 16H=1, 16V=0
// d: 16V=1, 4V,8V,16H=1
}
function setHit(sim, hit) {
sim.setExtVoltage("HIT", hit ? 5 : 0);
sim.setExtVoltage("/HIT1", hit && ballx < 256 ? 0 : 5);
sim.setExtVoltage("/HIT2", hit && ballx > 256 ? 0 : 5);
padAdj = Math.floor(Math.random()*8)-5;
}
window.startGame = function () {
sim.setExtVoltage("/RUN", 0);
resetCounter = 50;
serveTime = sim.getTime() + 1;
sim.setExtVoltage("/SERVE", 0);
}
window.stopGame = function () {
sim.setExtVoltage("/RUN", 5);
}
// callback called when simulation is done initializing
function simLoaded() {
// get simulator object
sim = iframe.contentWindow.CircuitJS1;
// set up callbacks on update and timestep
sim.onupdate = didUpdate;
sim.ontimestep = didStep;
sim.onanalyze = didAnalyze;
ctx = canvas.getContext("2d");
//ctx.fillRect(0, 0, 455, 262);
ctx.strokeStyle = "white";
ctx.fillStyle = "white";
canvas.onmousemove = function (event) {
var rect = canvas.getBoundingClientRect();
var mouseX = Math.floor((event.clientX - rect.left) * 375 / rect.width);
var mouseY = Math.floor((event.clientY - rect.top) * 246 / rect.height);
var padY = Math.max(mouseY-8, 1);
if (mouseX < 256-80)
pad1 = padY;
else
pad2 = padY;
}
}
// set up callback
iframe.contentWindow.oncircuitjsloaded = simLoaded;
</script>