Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ec8b26ebbd | |||
| 91a0788146 | |||
| 22e04b2cb9 |
25
README.md
25
README.md
@ -1,19 +1,40 @@
|
|||||||
# MatCat BrowserLogic
|
# MatCat BrowserLogic
|
||||||
|
|
||||||
MatCat BrowserLogic https://www.logic.parts/ is a logic simulator written purely in HTML5 / Javascript using 2D Canvas.
|
MatCat BrowserLogic https://www.logic.parts/ is a logic simulator written purely in HTML5 / Javascript using 2D Canvas. This code will always work standalone, just download and browse to index.html with your favorite browser.
|
||||||
|
|
||||||
|
The goal of this project is to offer a logic simulator that is full featured conceptual simulation of logic. It does not aim to be an electrical simulator, so realistic propagation delays and such are not simulated, however that is not to say that there aren't (as some elements such as clocks and buffers and IC I/O do have delayed buffers).
|
||||||
|
|
||||||
|
I designed this to design CPU's in, I am sure someone with some imagination could design nearly anything in it :).
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
This simulator is in extremely early stages, it is not even Alpha at this point but early development. Outside contribution is welcome, please contact me in #LogicParts on Freenode IRC network.
|
Currently, in pre-alpha early dev stage; however the simulator is about to enter the alpha stage, this means that the simulator core functionality is mostly in place. The Alpha stage will be dedicated to polishing the simulator itself, finding and fixing bugs, introduction of local storage for saves, introduction of server storage, and development of the website including adding integration features. Outside contribution is welcome, please contact me (MatCat) in #LogicParts on Freenode IRC network.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
To be decided, but at this moment this code is open source and free to use for non-commercial uses.
|
To be decided, but at this moment this code is open source and free to use for non-commercial uses.
|
||||||
|
|
||||||
|
Copyright (c) 2021, MatCat
|
||||||
|
|
||||||
LZ-String, Copyright 2013 pieroxy under MIT license https://github.com/pieroxy/lz-string/blob/master/LICENSE
|
LZ-String, Copyright 2013 pieroxy under MIT license https://github.com/pieroxy/lz-string/blob/master/LICENSE
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
### 0.4.16
|
||||||
|
|
||||||
|
* Fixed bug where properties window didn't disappear at certain times when it should
|
||||||
|
|
||||||
|
### 0.4.15
|
||||||
|
|
||||||
|
* Prepending ! or ~ (active low) before a pin name will now overline it when displayed on element
|
||||||
|
* Fixed a bug that disabled a switch after it was disconnected
|
||||||
|
* Fixed bug in how JK flipflops handled PRE and CLR and CLK
|
||||||
|
|
||||||
|
### 0.4.14
|
||||||
|
|
||||||
|
* Added WireNode element, allows you to better manage wires. Please note that signals only flow in the direction of connection! It is NOT a bidirectional element
|
||||||
|
* Added draw speed to FPS display (in uS)
|
||||||
|
|
||||||
### 0.4.13
|
### 0.4.13
|
||||||
|
|
||||||
* Clicking on an element on the toolbar no longer spawns an element to the work area directly, but rather lets the user place it.
|
* Clicking on an element on the toolbar no longer spawns an element to the work area directly, but rather lets the user place it.
|
||||||
|
|||||||
@ -32,25 +32,41 @@ class CanvasTools {
|
|||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
drawTextCentered(ctx,x,y,x2,y2,text,fontStyle="24px Console",fontColor = "#555") {
|
drawTextCentered(ctx,x,y,x2,y2,text,fontStyle="24px Console",fontColor = "#555", Overline = false) {
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.font = fontStyle;
|
ctx.font = fontStyle;
|
||||||
ctx.fillStyle = fontColor;
|
ctx.fillStyle = fontColor;
|
||||||
|
let textSize = this.textSize(ctx,text,fontStyle);
|
||||||
let tHeight = ctx.measureText(text).actualBoundingBoxAscent + ctx.measureText(text).actualBoundingBoxDescent;
|
let tHeight = ctx.measureText(text).actualBoundingBoxAscent + ctx.measureText(text).actualBoundingBoxDescent;
|
||||||
let tX = x+((x2/2)-(ctx.measureText(text).width/2));
|
let tX = x+((x2/2)-(ctx.measureText(text).width/2));
|
||||||
let tY = y+tHeight+((y2/2)-(tHeight/2));
|
let tY = y+tHeight+((y2/2)-(tHeight/2));
|
||||||
|
if (Overline) {
|
||||||
|
ctx.strokeStyle = fontColor;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(tX,tY-textSize.height-1);
|
||||||
|
ctx.lineTo(tX+textSize.width,tY-textSize.height-1);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
ctx.fillText(text,tX,tY);
|
ctx.fillText(text,tX,tY);
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
drawText(ctx,x,y,text,fontStyle="24px Console",fontColor = "#555") {
|
drawText(ctx,x,y,text,fontStyle="24px Console",fontColor = "#555",Overline = false) {
|
||||||
|
let textSize = this.textSize(ctx,text,fontStyle);
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.font = fontStyle;
|
ctx.font = fontStyle;
|
||||||
ctx.fillStyle = fontColor;
|
ctx.fillStyle = fontColor;
|
||||||
ctx.fillText(text,x,y);
|
ctx.fillText(text,x,y);
|
||||||
|
if (Overline) {
|
||||||
|
ctx.strokeStyle = fontColor;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(x,y-textSize.height-2);
|
||||||
|
ctx.lineTo(x+textSize.width,y-textSize.height-2);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ContainerConnection {
|
class ContainerConnection {
|
||||||
|
|||||||
@ -239,6 +239,7 @@ class Element extends CanvasTools {
|
|||||||
this.OutputConnections.splice(a,1);
|
this.OutputConnections.splice(a,1);
|
||||||
a--;
|
a--;
|
||||||
}
|
}
|
||||||
|
this.Disconnecting = false;
|
||||||
}
|
}
|
||||||
this.drawElement(0,0,this.StaticCtx);
|
this.drawElement(0,0,this.StaticCtx);
|
||||||
}
|
}
|
||||||
@ -354,7 +355,17 @@ class Element extends CanvasTools {
|
|||||||
if ((mouseDist <= (this.inputCircleRadius)) && this.LogicEngine.ActiveLink) ctx.fillStyle = circleColorHover;
|
if ((mouseDist <= (this.inputCircleRadius)) && this.LogicEngine.ActiveLink) ctx.fillStyle = circleColorHover;
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
if (this.InputLabels[a] && drawFresh) this.drawText(ctx,x+(this.inputCircleRadius*2)+ 5,(firstY + (a*24)) + 5,this.InputLabels[a],"10px Console","#000");
|
let drawOverline = false;
|
||||||
|
let label = this.InputLabels[a];
|
||||||
|
|
||||||
|
if (this.InputLabels[a] && drawFresh) {
|
||||||
|
if (this.InputLabels[a].charAt(0) == "!" || this.InputLabels[a].charAt(0) == "~") {
|
||||||
|
// Draw a NOT line
|
||||||
|
drawOverline = true;
|
||||||
|
label = this.InputLabels[a].substring(1);
|
||||||
|
}
|
||||||
|
this.drawText(ctx,x+(this.inputCircleRadius*2)+ 5,(firstY + (a*24)) + 5,label,"10px Console","#000",drawOverline);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
@ -379,9 +390,18 @@ class Element extends CanvasTools {
|
|||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
let textSize = false;
|
let textSize = false;
|
||||||
|
let drawOverline = false;
|
||||||
|
let label = this.OutputLabels[a];
|
||||||
|
if (this?.OutputLabels[a]?.charAt(0) == "!" || this?.OutputLabels[a]?.charAt(0) == "~") {
|
||||||
|
// Draw a NOT line
|
||||||
|
drawOverline = true;
|
||||||
|
label = this.OutputLabels[a].substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.OutputLabels[a]) textSize = this.textSize(ctx,this.OutputLabels[a],"10px Console");
|
if (this.OutputLabels[a]) textSize = this.textSize(ctx,label,"10px Console");
|
||||||
if (this.OutputLabels[a] && drawFresh) this.drawText(ctx,(x+(this.Width)) - (textSize.width + 5 + (this.outputCircleRadius*2)),(firstY + (a*24)) + 5,this.OutputLabels[a],"10px Console","#000");
|
if (this.OutputLabels[a] && drawFresh) {
|
||||||
|
this.drawText(ctx,(x+(this.Width)) - (textSize.width + 5 + (this.outputCircleRadius*2)),(firstY + (a*24)) + 5,label,"10px Console","#000",drawOverline);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,28 @@
|
|||||||
|
class LogicWireNode extends Element {
|
||||||
|
constructor(_Container, RestoreData = null, logicengine) {
|
||||||
|
super(_Container, RestoreData,logicengine,1);
|
||||||
|
this.removeProperty("Inputs");
|
||||||
|
this.Name = "WireNode";
|
||||||
|
this.Width = 20;
|
||||||
|
this.Height = 20;
|
||||||
|
}
|
||||||
|
getOutput(Output = 0) {
|
||||||
|
if (Output > 0) return false;
|
||||||
|
return this.Inputs[0];
|
||||||
|
}
|
||||||
|
drawElement(x,y,ctx) {
|
||||||
|
if (this.LogicEngine.ActiveContainer !== this._Container) return; // No point if we aren't visible
|
||||||
|
this.StaticCanvas.width = this.Width;
|
||||||
|
this.StaticCanvas.height = this.Height;
|
||||||
|
|
||||||
|
this.drawInputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
|
||||||
|
this.drawOutputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let ElementCatalog_WireNode = new ElementCatalog_Element("WireNode","A simple compact wire node for organizing wiring","-O-",LogicWireNode,[]);
|
||||||
|
ElementReferenceTable.push(ElementCatalog_WireNode);
|
||||||
|
ElementCategory_Other.addElement(ElementCatalog_WireNode);
|
||||||
|
|
||||||
class LogicAND extends Element {
|
class LogicAND extends Element {
|
||||||
constructor(_Container, RestoreData = null, logicengine,Inputs) {
|
constructor(_Container, RestoreData = null, logicengine,Inputs) {
|
||||||
super(_Container, RestoreData,logicengine,Inputs);
|
super(_Container, RestoreData,logicengine,Inputs);
|
||||||
|
|||||||
@ -3,11 +3,12 @@ class FlipFlopJK extends Element {
|
|||||||
super(_Container, RestoreData,logicengine,5);
|
super(_Container, RestoreData,logicengine,5);
|
||||||
this.Name = "JK-FF";
|
this.Name = "JK-FF";
|
||||||
this.Outputs = new Array(2);
|
this.Outputs = new Array(2);
|
||||||
this.InputLabels = new Array("J","CLK","K","!PRE", "!CLR");
|
this.InputLabels = new Array("J","!CLK","K","!PRE", "!CLR");
|
||||||
this.OutputLabels = new Array("Q","~Q");
|
this.OutputLabels = new Array("Q","~Q");
|
||||||
this.removeProperty("Inputs");
|
this.removeProperty("Inputs");
|
||||||
this.Height = 140;
|
this.Height = 140;
|
||||||
|
this.Outputs[0] = true;
|
||||||
|
this.Outputs[1] = true;
|
||||||
if (RestoreData) {
|
if (RestoreData) {
|
||||||
this.Outputs = RestoreData.OutputStates;
|
this.Outputs = RestoreData.OutputStates;
|
||||||
}
|
}
|
||||||
@ -26,9 +27,12 @@ class FlipFlopJK extends Element {
|
|||||||
if (Value !== false) Value = true;
|
if (Value !== false) Value = true;
|
||||||
let oldOutput = this.Outputs[0];
|
let oldOutput = this.Outputs[0];
|
||||||
let oldOutput2 = this.Outputs[1];
|
let oldOutput2 = this.Outputs[1];
|
||||||
|
let oldInput2 = this.Inputs[1];
|
||||||
|
let oldInput3 = this.Inputs[3];
|
||||||
|
let oldInput4 = this.Inputs[4];
|
||||||
this.Inputs[Input] = Value;
|
this.Inputs[Input] = Value;
|
||||||
|
|
||||||
if (this.Inputs[1]) {
|
if (!this.Inputs[1] && oldInput2) {
|
||||||
if (!this.Inputs[0] && this.Inputs[2]) {
|
if (!this.Inputs[0] && this.Inputs[2]) {
|
||||||
// set Q low
|
// set Q low
|
||||||
this.Outputs[0] = false;
|
this.Outputs[0] = false;
|
||||||
@ -43,11 +47,18 @@ class FlipFlopJK extends Element {
|
|||||||
this.Outputs[1] = !this.Outputs[0];
|
this.Outputs[1] = !this.Outputs[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!this.Inputs[3]) {
|
|
||||||
|
if (this.Inputs[4] && !oldInput4 && this.Outputs[0] && this.Outputs[1]) {
|
||||||
|
this.Outputs[1] = false;
|
||||||
|
}
|
||||||
|
if (this.Inputs[3] && !oldInput3 && this.Outputs[0] && this.Outputs[1]) {
|
||||||
|
this.Outputs[0] = false;
|
||||||
|
}
|
||||||
|
if (!this.Inputs[3] && oldInput3) {
|
||||||
this.Outputs[0] = true;
|
this.Outputs[0] = true;
|
||||||
this.Outputs[1] = false;
|
this.Outputs[1] = false;
|
||||||
}
|
}
|
||||||
if (!this.Inputs[4]) {
|
if (!this.Inputs[4] && oldInput4) {
|
||||||
this.Outputs[0] = false;
|
this.Outputs[0] = false;
|
||||||
this.Outputs[1] = true;
|
this.Outputs[1] = true;
|
||||||
}
|
}
|
||||||
@ -105,26 +116,37 @@ class FlipFlopSR extends Element {
|
|||||||
if (Value !== false) Value = true;
|
if (Value !== false) Value = true;
|
||||||
let oldOutput = this.Outputs[0];
|
let oldOutput = this.Outputs[0];
|
||||||
let oldOutput2 = this.Outputs[1];
|
let oldOutput2 = this.Outputs[1];
|
||||||
|
let oldInput1 = this.Inputs[1];
|
||||||
|
let oldInput3 = this.Inputs[3];
|
||||||
|
let oldInput4 = this.Inputs[4];
|
||||||
|
|
||||||
this.Inputs[Input] = Value;
|
this.Inputs[Input] = Value;
|
||||||
this.redraw = true;
|
this.redraw = true;
|
||||||
|
|
||||||
if (this.Inputs[1]) {
|
if (this.Inputs[1] && !oldInput1) {
|
||||||
if (!this.Inputs[0] && this.Inputs[2]) {
|
if (!this.Inputs[0] && this.Inputs[2]) {
|
||||||
// set Q low
|
// set Q low
|
||||||
this.Outputs[0] = false;
|
this.Outputs[0] = false;
|
||||||
this.Outputs[1] = true;
|
this.Outputs[1] = true;
|
||||||
} else if (this.Inputs[0] && !this.Inputs[2]) {
|
} else if (this.Inputs[0] && !this.Inputs[2]) {
|
||||||
// set Q low
|
// set Q high
|
||||||
this.Outputs[0] = true;
|
this.Outputs[0] = true;
|
||||||
this.Outputs[1] = false;
|
this.Outputs[1] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.Inputs[3]) {
|
if (this.Inputs[4] && !oldInput4 && !this.Inputs[3] && this.Outputs[1]) {
|
||||||
|
this.Outputs[1] = false;
|
||||||
|
}
|
||||||
|
if (this.Inputs[3] && !oldInput3 && !this.Inputs[4] && this.Outputs[0]) {
|
||||||
|
this.Outputs[0] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.Inputs[3] && oldInput3) {
|
||||||
this.Outputs[0] = true;
|
this.Outputs[0] = true;
|
||||||
this.Outputs[1] = false;
|
this.Outputs[1] = false;
|
||||||
}
|
}
|
||||||
if (!this.Inputs[4]) {
|
if (!this.Inputs[4] && oldInput4) {
|
||||||
this.Outputs[0] = false;
|
this.Outputs[0] = false;
|
||||||
this.Outputs[1] = true;
|
this.Outputs[1] = true;
|
||||||
}
|
}
|
||||||
@ -182,6 +204,8 @@ class FlipFlopT extends Element {
|
|||||||
if (Value !== false) Value = true;
|
if (Value !== false) Value = true;
|
||||||
let oldOutput = this.Outputs[0];
|
let oldOutput = this.Outputs[0];
|
||||||
let oldOutput2 = this.Outputs[1];
|
let oldOutput2 = this.Outputs[1];
|
||||||
|
let oldInput2 = this.Inputs[2];
|
||||||
|
let oldInput3 = this.Inputs[3];
|
||||||
this.Inputs[Input] = Value;
|
this.Inputs[Input] = Value;
|
||||||
this.redraw = true;
|
this.redraw = true;
|
||||||
|
|
||||||
@ -190,11 +214,11 @@ class FlipFlopT extends Element {
|
|||||||
this.Outputs[1] = !this.Outputs[0];
|
this.Outputs[1] = !this.Outputs[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.Inputs[2]) {
|
if (!this.Inputs[2] && oldInput2) {
|
||||||
this.Outputs[0] = true;
|
this.Outputs[0] = true;
|
||||||
this.Outputs[1] = false;
|
this.Outputs[1] = false;
|
||||||
}
|
}
|
||||||
if (!this.Inputs[3]) {
|
if (!this.Inputs[3] && oldInput3) {
|
||||||
this.Outputs[0] = false;
|
this.Outputs[0] = false;
|
||||||
this.Outputs[1] = true;
|
this.Outputs[1] = true;
|
||||||
}
|
}
|
||||||
@ -254,18 +278,19 @@ class FlipFlopD extends Element {
|
|||||||
let oldOutput = this.Outputs[0];
|
let oldOutput = this.Outputs[0];
|
||||||
let oldOutput2 = this.Outputs[1];
|
let oldOutput2 = this.Outputs[1];
|
||||||
let oldInput = this.Inputs[1];
|
let oldInput = this.Inputs[1];
|
||||||
|
let oldInput2 = this.Inputs[2];
|
||||||
|
let oldInput3 = this.Inputs[3];
|
||||||
this.Inputs[Input] = Value;
|
this.Inputs[Input] = Value;
|
||||||
this.redraw = true;
|
|
||||||
|
|
||||||
if (this.Inputs[1] && !oldInput) {
|
if (this.Inputs[1] && !oldInput) {
|
||||||
this.Outputs[0] = this.Inputs[0];
|
this.Outputs[0] = this.Inputs[0];
|
||||||
this.Outputs[1] = !this.Outputs[0];
|
this.Outputs[1] = !this.Outputs[0];
|
||||||
}
|
}
|
||||||
if (!this.Inputs[2]) {
|
if (!this.Inputs[2] && oldInput2) {
|
||||||
this.Outputs[0] = true;
|
this.Outputs[0] = true;
|
||||||
this.Outputs[1] = false;
|
this.Outputs[1] = false;
|
||||||
}
|
}
|
||||||
if (!this.Inputs[3]) {
|
if (!this.Inputs[3] && oldInput3) {
|
||||||
this.Outputs[0] = false;
|
this.Outputs[0] = false;
|
||||||
this.Outputs[1] = true;
|
this.Outputs[1] = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,9 +78,17 @@ class ICInput extends Element {
|
|||||||
this.StaticCanvas.width = this.Width;
|
this.StaticCanvas.width = this.Width;
|
||||||
this.StaticCanvas.height = this.Height;
|
this.StaticCanvas.height = this.Height;
|
||||||
|
|
||||||
|
let drawOverline = false;
|
||||||
|
let label = (this.Properties[0].CurrentValue) ? this.Properties[0].CurrentValue.toString() : "";
|
||||||
|
if (label.charAt(0) == "!" || label.charAt(0) == "~") {
|
||||||
|
// Draw a NOT line
|
||||||
|
drawOverline = true;
|
||||||
|
label = label.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
this.drawBorderBox(ctx,x+10,y,this.Width-30,this.Height);
|
this.drawBorderBox(ctx,x+10,y,this.Width-30,this.Height);
|
||||||
this.drawTextCentered(ctx,x,y+2,this.Width-10,14,this.Designator,"12px Console");
|
this.drawTextCentered(ctx,x,y+2,this.Width-10,14,this.Designator,"12px Console");
|
||||||
this.drawTextCentered(ctx,x,y,this.Width-10,this.Height,this.Properties[0].CurrentValue,"12px Console");
|
this.drawTextCentered(ctx,x,y,this.Width-10,this.Height,label,"12px Console",undefined,drawOverline);
|
||||||
this.drawOutputs(ctx,x,y);
|
this.drawOutputs(ctx,x,y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,9 +194,17 @@ class ICOutput extends Element {
|
|||||||
this.StaticCanvas.width = this.Width;
|
this.StaticCanvas.width = this.Width;
|
||||||
this.StaticCanvas.height = this.Height;
|
this.StaticCanvas.height = this.Height;
|
||||||
|
|
||||||
|
let drawOverline = false;
|
||||||
|
let label = (this.Properties[0].CurrentValue) ? this.Properties[0].CurrentValue.toString() : "";
|
||||||
|
if (label.charAt(0) == "!" || label.charAt(0) == "~") {
|
||||||
|
// Draw a NOT line
|
||||||
|
drawOverline = true;
|
||||||
|
label = label.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
this.drawBorderBox(ctx,x+20,y,this.Width-10,this.Height);
|
this.drawBorderBox(ctx,x+20,y,this.Width-10,this.Height);
|
||||||
this.drawTextCentered(ctx,x+20,y+2,this.Width-10,14,this.Designator,"12px Console");
|
this.drawTextCentered(ctx,x+20,y+2,this.Width-10,14,this.Designator,"12px Console");
|
||||||
this.drawTextCentered(ctx,x+20,y,this.Width-10,this.Height,this.Properties[0].CurrentValue,"12px Console");
|
this.drawTextCentered(ctx,x+20,y,this.Width-10,this.Height,label,"12px Console",undefined,drawOverline);
|
||||||
this.drawInputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
|
this.drawInputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -307,12 +307,11 @@ class InputKeypad extends inputElement {
|
|||||||
for (let pX = 0; pX < this.ButtonColumns; pX++) {
|
for (let pX = 0; pX < this.ButtonColumns; pX++) {
|
||||||
this.drawBorderBox(ctx, x + (5*(pX+1))+(buttonWidth*pX), y + (5*(pY+1))+(buttonHeight*pY), buttonWidth, buttonHeight, 1, "#ccc", "#777");
|
this.drawBorderBox(ctx, x + (5*(pX+1))+(buttonWidth*pX), y + (5*(pY+1))+(buttonHeight*pY), buttonWidth, buttonHeight, 1, "#ccc", "#777");
|
||||||
this.drawTextCentered(ctx,x + (5*(pX+1))+(buttonWidth*pX), y + (5*(pY+1))+(buttonHeight*pY), buttonWidth, buttonHeight, this.Buttons[(pY*this.ButtonColumns) + pX].Text,"16px Console", "#fff");
|
this.drawTextCentered(ctx,x + (5*(pX+1))+(buttonWidth*pX), y + (5*(pY+1))+(buttonHeight*pY), buttonWidth, buttonHeight, this.Buttons[(pY*this.ButtonColumns) + pX].Text,"16px Console", "#fff");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.drawTextCentered(ctx,x,y+(this.Height-14),this.Width-(this.outputCircleRadius*2),12,this.Designator,"12px Console","#000");
|
this.drawTextCentered(ctx,x,y+(this.Height-14),this.Width-(this.outputCircleRadius*2),12,this.Designator,"12px Console","#000");
|
||||||
this.drawOutputs(ctx,x,y);
|
this.drawOutputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -266,6 +266,11 @@ function HideHelp() {
|
|||||||
helpWindow.style.display = "none";
|
helpWindow.style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function HidePropertiesWindow() {
|
||||||
|
let propwin = document.getElementById("PropertiesBox");
|
||||||
|
propwin.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
function SaveSettings() {
|
function SaveSettings() {
|
||||||
localStorage.setItem("LogicEngineSettings",JSON.stringify(logicEngine.Settings));
|
localStorage.setItem("LogicEngineSettings",JSON.stringify(logicEngine.Settings));
|
||||||
console.log("Settings Saved");
|
console.log("Settings Saved");
|
||||||
|
|||||||
@ -203,7 +203,7 @@ class LogicEngineSettings {
|
|||||||
if (restoresettings) {
|
if (restoresettings) {
|
||||||
let othis = this;
|
let othis = this;
|
||||||
Object.keys(restoresettings).forEach(function(key) {
|
Object.keys(restoresettings).forEach(function(key) {
|
||||||
othis[key] = restoresettings[key];
|
if (key != "Keybindings") othis[key] = restoresettings[key]; //TODO: Iterate keybindings as well
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -653,13 +653,15 @@ class LogicEngine {
|
|||||||
let FPSOffset = 5 - this.Panning.OffsetX;
|
let FPSOffset = 5 - this.Panning.OffsetX;
|
||||||
if (this.Settings.ShowFPS) {
|
if (this.Settings.ShowFPS) {
|
||||||
ct.drawText(this.Ctx, FPSOffset, 15 - this.Panning.OffsetY, "FPS: " + this.FPS, "12px console", "#00ff00");
|
ct.drawText(this.Ctx, FPSOffset, 15 - this.Panning.OffsetY, "FPS: " + this.FPS, "12px console", "#00ff00");
|
||||||
ct.drawText(this.Ctx, FPSOffset, 29 - this.Panning.OffsetY, "Potential FPS: " + Math.floor(this.PotentialFPS), "12px console", "#00ff00");
|
ct.drawText(this.Ctx, FPSOffset, 29 - this.Panning.OffsetY, "Draw Speed: " + Math.floor(this.frameTimeUS) + "uS", "12px console", "#00ff00");
|
||||||
|
ct.drawText(this.Ctx, FPSOffset, 43 - this.Panning.OffsetY, "Potential FPS: " + Math.floor(this.PotentialFPS), "12px console", "#00ff00");
|
||||||
}
|
}
|
||||||
let timeCheck = performance.now();
|
let timeCheck = performance.now();
|
||||||
this.FPSCounter++;
|
this.FPSCounter++;
|
||||||
|
|
||||||
if (!(Math.round(timeCheck - this.LastFPSCheck) % 50)) {
|
if (!(Math.round(timeCheck - this.LastFPSCheck) % 50)) {
|
||||||
let frameTimeUS = (performance.now() - startLoop) * 1000;
|
let frameTimeUS = (performance.now() - startLoop) * 1000;
|
||||||
|
this.frameTimeUS = frameTimeUS;
|
||||||
let potentialFPS = 1000000 / frameTimeUS;
|
let potentialFPS = 1000000 / frameTimeUS;
|
||||||
this.PotentialFPSAVGs[this.PotentialFPSAVGLoc] = Math.round(potentialFPS);
|
this.PotentialFPSAVGs[this.PotentialFPSAVGLoc] = Math.round(potentialFPS);
|
||||||
this.PotentialFPSAVGLoc++;
|
this.PotentialFPSAVGLoc++;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
MatCat BrowserLogic Simulator
|
MatCat BrowserLogic Simulator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let Version = "0.4.13";
|
let Version = "0.4.16";
|
||||||
|
|
||||||
let spanVersion = document.getElementById("version");
|
let spanVersion = document.getElementById("version");
|
||||||
spanVersion.innerText = Version;
|
spanVersion.innerText = Version;
|
||||||
|
|||||||
@ -34,12 +34,15 @@ function RightClickMenuListeners() {
|
|||||||
logicEngine.Ctx.setTransform(1, 0, 0, 1, 0, 0);
|
logicEngine.Ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
logicEngine.Panning.OffsetX = 0;
|
logicEngine.Panning.OffsetX = 0;
|
||||||
logicEngine.Panning.OffsetY = 0;
|
logicEngine.Panning.OffsetY = 0;
|
||||||
|
HidePropertiesWindow();
|
||||||
|
disableSelectedMenus(true);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let rcm_Delete = document.getElementById("rcm_Delete");
|
let rcm_Delete = document.getElementById("rcm_Delete");
|
||||||
rcm_Delete.addEventListener('click', function (evt) {
|
rcm_Delete.addEventListener('click', function (evt) {
|
||||||
logicEngine.Key_Press({ctrlKey: false, key: "Delete"});
|
logicEngine.Key_Press({ctrlKey: false, key: "Delete"});
|
||||||
|
HidePropertiesWindow();
|
||||||
disableSelectedMenus(true);
|
disableSelectedMenus(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -80,6 +80,9 @@ function TopMenuListeners() {
|
|||||||
logicEngine.Ctx.setTransform(1, 0, 0, 1, 0, 0);
|
logicEngine.Ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
logicEngine.Panning.OffsetX = 0;
|
logicEngine.Panning.OffsetX = 0;
|
||||||
logicEngine.Panning.OffsetY = 0;
|
logicEngine.Panning.OffsetY = 0;
|
||||||
|
HidePropertiesWindow();
|
||||||
|
disableSelectedMenus(true);
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
hideMenus()
|
hideMenus()
|
||||||
}, 10);
|
}, 10);
|
||||||
@ -116,6 +119,7 @@ function TopMenuListeners() {
|
|||||||
let tfm_Delete = document.getElementById("tfm_Delete");
|
let tfm_Delete = document.getElementById("tfm_Delete");
|
||||||
tfm_Delete.addEventListener('click', function (evt) {
|
tfm_Delete.addEventListener('click', function (evt) {
|
||||||
logicEngine.Key_Press({ctrlKey: false, key: "Delete"});
|
logicEngine.Key_Press({ctrlKey: false, key: "Delete"});
|
||||||
|
HidePropertiesWindow();
|
||||||
disableSelectedMenus(true);
|
disableSelectedMenus(true);
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
hideMenus()
|
hideMenus()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user