diff --git a/www/data/css/styles.css b/www/data/css/styles.css
index f94af1b..8e0aee5 100644
--- a/www/data/css/styles.css
+++ b/www/data/css/styles.css
@@ -646,6 +646,19 @@ html, body {
background: #333;
color: #FFF;
border: 1px solid black; }
+ .bce_code .bce_code_ctrl .ctrl_btn_group {
+ display: flex;
+ flex-direction: row; }
+ .bce_code .bce_code_ctrl .ctrl_btn_ll {
+ margin-right: 0;
+ flex-grow: 1; }
+ .bce_code .bce_code_ctrl .ctrl_btn_rr {
+ margin-left: 0;
+ flex-grow: 0;
+ min-width: 25px;
+ border-left: none; }
+ .bce_code .bce_code_ctrl .ctrl_btn_rr:hover {
+ border-left: none; }
.bce_code .bce_code_ctrl .ctrl_btn_disabled {
background: #999;
color: #BBB; }
@@ -677,28 +690,36 @@ html, body {
overflow-x: auto;
background: #FFF;
color: #000;
- flex-grow: 1;
- margin: 0 4px 4px 4px;
border: 1px solid #888;
- height: 200px; }
+ flex-grow: 1; }
.bce_code_out .bce_code_out_stack {
font-family: Consolas, Monaco, "Courier New", Menlo, monospace;
overflow-y: scroll;
overflow-x: auto;
background: #FFF;
color: #000;
- margin: 0 4px 4px 4px;
- width: 200px;
border: 1px solid #888;
- height: 200px; }
+ flex-grow: 1; }
+ .bce_code_out .bce_code_out_left {
+ flex-grow: 1;
+ margin: 0 4px 4px 4px;
+ height: 200px;
+ display: flex;
+ flex-direction: column; }
+ .bce_code_out .bce_code_out_right {
+ height: 200px;
+ width: 200px;
+ margin: 0 4px 4px 4px;
+ display: flex;
+ flex-direction: column; }
@media (max-width: 767px) {
.bce_code_out {
flex-direction: column; }
- .bce_code_out .bce_code_out_text {
+ .bce_code_out .bce_code_out_left {
flex-grow: 0;
height: 100px; }
- .bce_code_out .bce_code_out_stack {
+ .bce_code_out .b93rnr_outpanel_right {
width: auto;
height: 150px; } }
.b93rnr_outpanel_hidden {
diff --git a/www/data/css/styles_befungerunner.scss b/www/data/css/styles_befungerunner.scss
index 2a617eb..3e789ee 100644
--- a/www/data/css/styles_befungerunner.scss
+++ b/www/data/css/styles_befungerunner.scss
@@ -55,6 +55,14 @@
}
}
+ .ctrl_btn_group {
+ display: flex;
+ flex-direction: row;
+ }
+
+ .ctrl_btn_ll {margin-right: 0; flex-grow: 1; }
+ .ctrl_btn_rr {margin-left: 0; flex-grow: 0; min-width: 25px; border-left: none; &:hover { border-left: none; } }
+
.ctrl_btn_disabled { background: #999; color: #BBB; }
.ctrl_btn_disabled:hover { background: #999; color: #BBB; cursor: default; }
}
@@ -83,10 +91,8 @@
overflow-x: auto;
background: #FFF;
color: #000;
- flex-grow: 1;
- margin: 0 4px 4px 4px;
border: 1px solid #888;
- height: 200px;
+ flex-grow: 1;
}
.bce_code_out_stack {
@@ -95,18 +101,32 @@
overflow-x: auto;
background: #FFF;
color: #000;
- margin: 0 4px 4px 4px;
- width: 200px;
border: 1px solid #888;
+ flex-grow: 1;
+ }
+
+ .bce_code_out_left {
+ flex-grow: 1;
+ margin: 0 4px 4px 4px;
height: 200px;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .bce_code_out_right {
+ height: 200px;
+ width: 200px;
+ margin: 0 4px 4px 4px;
+ display: flex;
+ flex-direction: column;
}
}
@media (max-width: 767px) {
.bce_code_out {
flex-direction: column;
- .bce_code_out_text { flex-grow: 0; height: 100px;}
- .bce_code_out_stack { width: auto; height: 150px;}
+ .bce_code_out_left { flex-grow: 0; height: 100px;}
+ .bce_code_out_right { width: auto; height: 150px;}
}
}
diff --git a/www/data/javascript/blogpost_bef93runner.js b/www/data/javascript/blogpost_bef93runner.js
index e769ca7..dd1b634 100644
--- a/www/data/javascript/blogpost_bef93runner.js
+++ b/www/data/javascript/blogpost_bef93runner.js
@@ -1,5 +1,6 @@
const BefState = Object.freeze ({ UNINIITIALIZED: {}, INITIAL: {}, RUNNING: {}, PAUSED: {} });
+const BefSpeed = Object.freeze ({ NORMAL: {str:'+'}, FAST: {str:'++'}, SUPERFAST: {str:'3+'}, MAX: {str:'4+'} });
Array.prototype.peek = function() { return this[this.length - 1]; };
Array.prototype.revjoin = function(sep) {
@@ -9,15 +10,17 @@ Array.prototype.revjoin = function(sep) {
};
function BefObject(domBase) {
- this.btnStart = domBase.getElementsByClassName('b93rnr_start')[0];
- this.btnStop = domBase.getElementsByClassName('b93rnr_pause')[0];
- this.btnReset = domBase.getElementsByClassName('b93rnr_reset')[0];
- this.pnlCode = domBase.getElementsByClassName('b93rnr_data')[0];
- this.pnlBottom = domBase.getElementsByClassName('b93rnr_outpanel')[0];
- this.pnlOutput = domBase.getElementsByClassName('b93rnr_output')[0];
- this.pnlStack = domBase.getElementsByClassName('b93rnr_stack')[0];
+ this.btnStart = domBase.getElementsByClassName('b93rnr_start')[0];
+ this.btnStop = domBase.getElementsByClassName('b93rnr_pause')[0];
+ this.btnReset = domBase.getElementsByClassName('b93rnr_reset')[0];
+ this.btnSpeed = domBase.getElementsByClassName('b93rnr_speed')[0];
+ this.pnlCode = domBase.getElementsByClassName('b93rnr_data')[0];
+ this.pnlBottom = domBase.getElementsByClassName('b93rnr_outpanel')[0];
+ this.pnlOutput = domBase.getElementsByClassName('b93rnr_output')[0];
+ this.pnlStack = domBase.getElementsByClassName('b93rnr_stack')[0];
+ this.lblStackSize = domBase.getElementsByClassName('b93rnr_stacksize')[0];
- this.state = BefState.UNINIITIALIZED;
+ this.state = BefState.UNINIITIALIZED;
this.initial = atob(this.pnlCode.getAttribute('data-befcode'));
this.code = [];
this.width = 0;
@@ -29,6 +32,7 @@ function BefObject(domBase) {
this.stack = [];
this.timer = null;
this.psteps = 0;
+ this.simspeed = BefSpeed.SUPERFAST;
}
BefObject.prototype.Init = function() {
@@ -81,8 +85,6 @@ BefObject.prototype.stop = function() {
BefObject.prototype.reset = function() {
if (this.state === BefState.RUNNING) this.stop();
- //reset
-
this.state = BefState.INITIAL;
this.Init();
this.state = BefState.INITIAL;
@@ -91,36 +93,69 @@ BefObject.prototype.reset = function() {
this.updateDisplay();
};
-BefObject.prototype.step = function() {
+BefObject.prototype.incSpeed = function() {
- let t0 = performance.now();
- let first = true;
-
- let steps = 0;
- while(steps===0 || (performance.now() - t0 < 33)) // 32ms == 30FPS
- {
- first = false;
-
- let chr = this.code[this.position[1]][this.position[0]];
- this.exec(chr);
- this.move();
-
- if (this.delta[0]===0 && this.delta[1]===0) {
- console.log('Finished in ' + this.psteps + ' steps');
- this.stop();
- return;
- }
- steps++;
- }
+ if (this.simspeed === BefSpeed.NORMAL) this.simspeed = BefSpeed.FAST;
+ else if (this.simspeed === BefSpeed.FAST) this.simspeed = BefSpeed.SUPERFAST;
+ else if (this.simspeed === BefSpeed.SUPERFAST) this.simspeed = BefSpeed.MAX;
+ else if (this.simspeed === BefSpeed.MAX) this.simspeed = BefSpeed.NORMAL;
this.updateUI();
+};
+
+BefObject.prototype.step = function() {
+
+ if (this.simspeed === BefSpeed.NORMAL) {
+
+ this.stepSingle();
+
+ } else if (this.simspeed === BefSpeed.FAST) {
+
+ let t0 = performance.now();
+ let stepc = 0;
+ while(this.state=== BefState.RUNNING && (stepc===0 || (performance.now() - t0 < 16)) && stepc < 128) // 16ms == 60FPS
+ {
+ this.stepSingle();
+ stepc++;
+ }
+
+ } else if (this.simspeed === BefSpeed.SUPERFAST) {
+
+ let t0 = performance.now();
+ let first = true;
+ while(this.state=== BefState.RUNNING && (first || (performance.now() - t0 < 16))) // 16ms == 60FPS
+ {
+ this.stepSingle();
+ first = false;
+ }
+
+ } else if (this.simspeed === BefSpeed.MAX) {
+
+ let t0 = performance.now();
+ let first = true;
+ while(this.state=== BefState.RUNNING && (first || (performance.now() - t0 < 33))) // 32ms == 30FPS
+ {
+ this.stepSingle();
+ first = false;
+ }
+ }
+
+ if (this.state !== BefState.RUNNING) this.updateUI();
this.updateDisplay();
};
+BefObject.prototype.stepSingle = function() {
+ let chr = this.code[this.position[1]][this.position[0]];
+ this.exec(chr);
+ this.move();
+
+ if (this.delta[0]===0 && this.delta[1]===0) {
+ console.log('Finished in ' + this.psteps + ' steps');
+ this.stop();
+ }
+};
+
BefObject.prototype.exec = function(chr) {
-
-
-
if (this.strmode)
{
this.psteps++;
@@ -197,7 +232,6 @@ BefObject.prototype.pop_i = function() { return this.stack.pop(); };
BefObject.prototype.peek_i = function() { return this.stack.peek(); };
BefObject.prototype.push_b = function(v) { this.stack.push(v?1:0); };
BefObject.prototype.pop_b = function() { return this.stack.pop()!==0; };
-BefObject.prototype.peek_b = function() { return this.stack.peek()!==0; };
BefObject.prototype.push_c = function(v) { this.stack.push(v.charCodeAt(0)); };
BefObject.prototype.gridset_i = function(x,y,c) { if (x < 0 || y < 0 || x >= this.width || y >= this.height) return; this.code[y][x]=String.fromCharCode(c); };
BefObject.prototype.gridget_i = function(x,y) { if (x < 0 || y < 0 || x >= this.width || y >= this.height) return 0; return this.code[y][x].charCodeAt(0); };
@@ -209,6 +243,8 @@ BefObject.prototype.updateUI = function() {
classListSet(this.btnReset, 'ctrl_btn_disabled', this.state === BefState.UNINIITIALIZED || this.state === BefState.INITIAL);
classListSet(this.pnlBottom, 'b93rnr_outpanel_hidden', this.state === BefState.UNINIITIALIZED || this.state === BefState.INITIAL);
+
+ this.btnSpeed.innerHTML = this.simspeed.str;
};
BefObject.prototype.updateDisplay = function() {
@@ -233,6 +269,8 @@ BefObject.prototype.updateDisplay = function() {
this.pnlOutput.innerHTML = htmlescape(this.output);
this.pnlStack.innerHTML = this.stack.revjoin("
");
+
+ this.lblStackSize.innerHTML = "(" + this.stack.length + ")";
};
BefObject.prototype.parseBef = function(str) {
@@ -285,5 +323,6 @@ window.onload = function ()
befungeObject.btnStart.onclick = function () { if (befungeObject.btnStart.classList.contains('ctrl_btn_disabled')) return; befungeObject.start(); };
befungeObject.btnStop.onclick = function () { if (befungeObject.btnStop.classList.contains('ctrl_btn_disabled')) return; befungeObject.stop(); };
befungeObject.btnReset.onclick = function () { if (befungeObject.btnReset.classList.contains('ctrl_btn_disabled')) return; befungeObject.reset(); };
+ befungeObject.btnSpeed.onclick = function () { if (befungeObject.btnSpeed.classList.contains('ctrl_btn_disabled')) return; befungeObject.incSpeed(); };
}
};
\ No newline at end of file
diff --git a/www/fragments/befunge93_runner.php b/www/fragments/befunge93_runner.php
index 33dc393..3f37bcf 100644
--- a/www/fragments/befunge93_runner.php
+++ b/www/fragments/befunge93_runner.php
@@ -23,7 +23,10 @@ if ($PARAM_INTERACTIVE) {
$result .= '