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 .= '
' . fmtBef($PARAM_CODE) . '
' . "\n"; $result .= '
' . "\n"; $result .= '
' . "\n"; - $result .= '
Start
' . "\n"; + $result .= '
' . "\n"; + $result .= '
Start
' . "\n"; + $result .= '
3+
' . "\n"; + $result .= '
' . "\n"; $result .= '
Pause
' . "\n"; $result .= '
Reset
' . "\n"; $result .= '
' . "\n"; @@ -34,8 +37,14 @@ if ($PARAM_INTERACTIVE) { } $result .= '
' . "\n"; $result .= '
' . "\n"; - $result .= '
' . "\n"; - $result .= '
' . "\n"; + $result .= '
' . "\n"; + $result .= ' Output:' . "\n"; + $result .= '
' . "\n"; + $result .= '
' . "\n"; + $result .= '
' . "\n"; + $result .= ' Stack:   (0)' . "\n"; + $result .= '
' . "\n"; + $result .= '
' . "\n"; $result .= '
' . "\n"; $result .= '' . "\n"; diff --git a/www/fragments/blogview_euler_single.php b/www/fragments/blogview_euler_single.php index 6ecda88..9de4ba7 100644 --- a/www/fragments/blogview_euler_single.php +++ b/www/fragments/blogview_euler_single.php @@ -7,7 +7,7 @@ require_once (__DIR__ . '/../internals/ParsedownCustom.php'); $subview = $OPTIONS['subview']; $euler = Euler::listAll(); -$problem = Euler::getEulerProblem(intval(explode('-', $subview)[1])); +$problem = Euler::getEulerProblemFromStrIdent($subview); if ($post === NULL) httpError(404, 'problem not found'); diff --git a/www/internals/euler.php b/www/internals/euler.php index 8b19ae7..1d55bd8 100644 --- a/www/internals/euler.php +++ b/www/internals/euler.php @@ -35,6 +35,17 @@ class Euler return array_map('self::readSingle', $files); } + public static function getEulerProblemFromStrIdent($ident) + { + $e = explode('-', $ident, 2); + if (count($e)!==2) return null; + + $i = intval($e[1], 10); + if ($i == 0) return null; + + return self::getEulerProblem($i); + } + public static function getEulerProblem($num) { foreach (self::listAll() as $ep) { diff --git a/www/pages/blog_view.php b/www/pages/blog_view.php index 448013f..bea82c9 100644 --- a/www/pages/blog_view.php +++ b/www/pages/blog_view.php @@ -19,7 +19,19 @@ if ($post === NULL) httpError(404, 'blogpost not found'); - + '; + } + else + { + echo ''; + } + ?> +