From 04473acb74924c27471f7a025570741b2e322936 Mon Sep 17 00:00:00 2001 From: LoveEevee Date: Sun, 14 Oct 2018 21:08:05 +0300 Subject: [PATCH] Add debugging user interface --- public/src/css/debug.css | 77 +++++++++++++ public/src/js/assets.js | 3 +- public/src/js/circle.js | 2 + public/src/js/controller.js | 13 +++ public/src/js/debug.js | 211 ++++++++++++++++++++++++++++++++++++ public/src/js/main.js | 17 +++ public/src/js/parseosu.js | 1 + public/src/js/parsetja.js | 1 + public/src/views/debug.html | 8 ++ templates/index.html | 2 + 10 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 public/src/css/debug.css create mode 100644 public/src/js/debug.js create mode 100644 public/src/views/debug.html diff --git a/public/src/css/debug.css b/public/src/css/debug.css new file mode 100644 index 0000000..c0ea86b --- /dev/null +++ b/public/src/css/debug.css @@ -0,0 +1,77 @@ +#debug{ + position: absolute; + top: 0; + left: 0; + width: 180px; + height: 160px; + background: #fff; + border: 1px solid #333; + color: #000; + z-index: 50; + font-size: 14px; + font-family: TnT, Meiryo, sans-serif; +} + +#debug .title{ + position: relative; + height: 25px; + padding: 5px 0 0 5px; + box-sizing: border-box; + background: #bbb; + color: #fff; + cursor: default; + z-index: 1 +} + +#debug .title::before{ + left: auto; + -webkit-text-stroke: 0.25em #555; +} + +#debug .minimise{ + position: absolute; + top: 3px; + right: 3px; + width: 19px; + height: 19px; + background: #d77; + z-index: 1; +} + +#debug .content{ + height: calc(100% - 25px); + overflow-y: auto; + padding: 8px; + box-sizing: border-box; +} + +#debug .input-slider{ + display: flex; + width: 100%; + height: 30px; + margin: 5px 0; +} +#debug .input-slider>input{ + width: 70%; + height: 100%; + box-sizing: border-box; + font-size: 18px; + font-family: monospace; + padding: 2px 4px; + text-align: center; +} +#debug .input-slider>span{ + display: block; + width: 10%; + height: 100%; + opacity: 0.8; + background: #666; + color: #fff; + text-align: center; + line-height: 2em; + cursor: pointer; +} +#debug .input-slider>span:hover{ + opacity: 1; + background: #333; +} diff --git a/public/src/js/assets.js b/public/src/js/assets.js index fde1bec..3fa9dc8 100644 --- a/public/src/js/assets.js +++ b/public/src/js/assets.js @@ -124,7 +124,8 @@ var assets = { "songselect.html", "titlescreen.html", "tutorial.html", - "about.html" + "about.html", + "debug.html" ], "songs": [], diff --git a/public/src/js/circle.js b/public/src/js/circle.js index fdb0478..0bae2d8 100644 --- a/public/src/js/circle.js +++ b/public/src/js/circle.js @@ -3,10 +3,12 @@ class Circle{ // id, ms, type, text, speed, endTime, requiredHits this.id = config.id this.ms = config.start + this.originalMS = this.ms this.type = config.type this.text = config.txt this.speed = config.speed this.endTime = config.endTime || this.ms + this.originalEndTime = this.endTime this.isPlayed = 0 this.animating = false this.animT = 0 diff --git a/public/src/js/controller.js b/public/src/js/controller.js index 9ef9608..d6fcbe8 100644 --- a/public/src/js/controller.js +++ b/public/src/js/controller.js @@ -38,6 +38,12 @@ class Controller{ syncWith.startDate = this.game.startDate this.syncWith = syncWith } + if(this.multiplayer !== 2){ + debugObj.controller = this + if(debugObj.debug){ + debugObj.debug.updateStatus() + } + } } loadUIEvents(){ this.pauseMenu = document.getElementById("pause-menu") @@ -217,5 +223,12 @@ class Controller{ delete this.restartBtn pageEvents.remove(this.songSelBtn, ["click", "touchend"]) delete this.songSelBtn + + if(this.multiplayer !== 2){ + debugObj.controller = null + if(debugObj.debug){ + debugObj.debug.updateStatus() + } + } } } diff --git a/public/src/js/debug.js b/public/src/js/debug.js new file mode 100644 index 0000000..bb5ea0b --- /dev/null +++ b/public/src/js/debug.js @@ -0,0 +1,211 @@ +class Debug{ + constructor(){ + this.debugDiv = document.createElement("div") + this.debugDiv.id = "debug" + this.debugDiv.innerHTML = assets.pages["debug"] + document.body.appendChild(this.debugDiv) + + this.titleDiv = this.debugDiv.getElementsByClassName("title")[0] + this.minimiseDiv = this.debugDiv.getElementsByClassName("minimise")[0] + this.offsetDiv = this.debugDiv.getElementsByClassName("offset")[0] + + this.moving = false + pageEvents.add(window, ["mousedown", "mouseup", "blur"], this.stopMove.bind(this)) + pageEvents.add(window, "mousemove", this.onMove.bind(this)) + pageEvents.add(this.titleDiv, "mousedown", this.startMove.bind(this)) + pageEvents.add(this.minimiseDiv, "click", this.minimise.bind(this)) + + this.offsetSlider = new InputSlider(this.offsetDiv) + this.offsetSlider.onchange(this.offsetChange.bind(this)) + + this.moveTo(100, 100) + this.restore() + this.updateStatus() + } + startMove(event){ + if(event.which === 1){ + event.stopPropagation() + this.moving = { + x: event.offsetX, + y: event.offsetY + } + } + } + onMove(event){ + if(this.moving){ + var x = event.clientX - this.moving.x + var y = event.clientY - this.moving.y + this.moveTo(x, y) + } + } + stopMove(event){ + var x = event.clientX - this.moving.x + var y = event.clientY - this.moving.y + var w = this.debugDiv.offsetWidth + var h = this.debugDiv.offsetHeight + if(x + w > innerWidth){ + x = innerWidth - w + } + if(y + h > lastHeight){ + y = lastHeight - h + } + if(x < 0){ + x = 0 + } + if(y < 0){ + y = 0 + } + this.moveTo(x, y) + this.moving = false + } + moveTo(x, y){ + this.debugDiv.style.transform = "translate(" + x + "px, " + y + "px)" + } + restore(){ + debugObj.state = "open" + this.debugDiv.style.display = "" + } + minimise(){ + debugObj.state = "minimised" + this.debugDiv.style.display = "none" + } + updateStatus(){ + if(debugObj.controller && !this.controller){ + this.controller = debugObj.controller + var selectedSong = this.controller.selectedSong + this.defaultOffset = selectedSong.offset + if(this.songFolder === selectedSong.folder){ + this.offsetChange(this.offsetSlider.get()) + }else{ + this.songFolder = selectedSong.folder + this.offsetSlider.set(this.defaultOffset) + } + } + if(this.controller && !debugObj.controller){ + this.controller = null + } + } + offsetChange(value){ + if(this.controller){ + var offset = (this.defaultOffset - value) * 1000 + var songData = this.controller.parsedSongData + songData.circles.forEach(circle => { + circle.ms = circle.originalMS + offset + circle.endTime = circle.originalEndTime + offset + }) + songData.measures.forEach(measure => { + measure.ms = measure.originalMS + offset + }) + } + } + clean(){ + this.offsetSlider.clean() + + pageEvents.remove(window, ["mousedown", "mouseup", "mousemove", "blur"]) + pageEvents.remove(this.title, "mousedown") + + delete this.debugDiv + delete this.titleDiv + delete this.minimiseDiv + delete this.controller + + debugObj.state = "closed" + debugObj.debug = null + document.body.removeChild(this.debugDiv) + } +} +class InputSlider{ + constructor(sliderDiv){ + this.input = sliderDiv.getElementsByTagName("input")[0] + this.reset = sliderDiv.getElementsByClassName("reset")[0] + this.plus = sliderDiv.getElementsByClassName("plus")[0] + this.minus = sliderDiv.getElementsByClassName("minus")[0] + this.value = null + this.defaultValue = null + this.callbacks = [] + + pageEvents.add(this.plus, "click", this.add.bind(this)) + pageEvents.add(this.minus, "click", this.subtract.bind(this)) + pageEvents.add(this.reset, "click", this.resetValue.bind(this)) + pageEvents.add(this.input, "change", this.manualSet.bind(this)) + } + update(noCallback, force){ + var oldValue = this.input.value + if(this.value === null){ + this.input.value = "" + this.input.readOnly = true + }else{ + if(this.value > 60000){ + this.value = 60000 + } + if(this.value < -60000){ + this.value = -60000 + } + this.input.value = this.get().toFixed(3) + this.input.readOnly = false + } + if(force || !noCallback && oldValue !== this.input.value){ + this.callbacks.forEach(callback => { + callback(this.input.value) + }) + } + } + set(number){ + this.value = Math.floor(number * 1000) + this.defaultValue = this.value + this.update(true) + } + get(){ + if(this.value === null){ + return null + }else{ + return Math.floor(this.value) / 1000 + } + } + add(event){ + if(this.value !== null){ + var newValue = this.value + this.eventNumber(event) + if(newValue <= 60000){ + this.value = newValue + this.update() + } + } + } + subtract(event){ + if(this.value !== null){ + var newValue = this.value - this.eventNumber(event) + if(newValue >= -60000){ + this.value = newValue + this.update() + } + } + } + eventNumber(event){ + return (event.ctrlKey ? 10 : 1) * (event.shiftKey ? 10 : 1) * (event.altKey ? 10 : 1) * 1 + } + resetValue(){ + this.value = this.defaultValue + this.update() + } + onchange(callback){ + this.callbacks.push(callback) + } + manualSet(){ + var number = parseFloat(this.input.value) + if(Number.isFinite(number) && -60 <= number && number <= 60){ + this.value = number * 1000 + } + this.update(false, true) + } + clean(){ + pageEvents.remove(this.plus, "click") + pageEvents.remove(this.minus, "click") + pageEvents.remove(this.reset, "click") + pageEvents.remove(this.input, "change") + + delete this.input + delete this.reset + delete this.plus + delete this.minus + } +} diff --git a/public/src/js/main.js b/public/src/js/main.js index 7647985..3dd2975 100644 --- a/public/src/js/main.js +++ b/public/src/js/main.js @@ -40,6 +40,19 @@ function resizeRoot(){ } } +function debug(){ + if(debugObj.state === "open"){ + debugObj.debug.clean() + return "Debug closed" + }else if(debugObj.state === "minimised"){ + debugObj.debug.restore() + return "Debug restored" + }else{ + debugObj.debug = new Debug() + return "Debug opened" + } +} + var root = document.documentElement var fullScreenSupported = "requestFullscreen" in root || "webkitRequestFullscreen" in root || "mozRequestFullScreen" in root @@ -49,6 +62,10 @@ var p2 var disableBlur = false var cancelTouch = true var lastHeight +var debugObj = { + state: "closed", + debug: null +} var perf = { blur: 0, allImg: 0, diff --git a/public/src/js/parseosu.js b/public/src/js/parseosu.js index 8618450..c4b6280 100644 --- a/public/src/js/parseosu.js +++ b/public/src/js/parseosu.js @@ -150,6 +150,7 @@ class ParseOsu{ if(measureNumber === 0){ measures.push({ ms: start + this.offset, + originalMS: start + this.offset, speed: this.timingPoints[i].sliderMultiplier }) } diff --git a/public/src/js/parsetja.js b/public/src/js/parsetja.js index 52d56f0..5d390ce 100644 --- a/public/src/js/parsetja.js +++ b/public/src/js/parsetja.js @@ -140,6 +140,7 @@ } this.measures.push({ ms: ms, + originalMS: ms, speed: speed }) if(firstMeasure){ diff --git a/public/src/views/debug.html b/public/src/views/debug.html new file mode 100644 index 0000000..1f5edb7 --- /dev/null +++ b/public/src/views/debug.html @@ -0,0 +1,8 @@ +
Debug
+
+
+ Offset:
+
+ x+- +
+
diff --git a/templates/index.html b/templates/index.html index d4b8f13..b733fa0 100644 --- a/templates/index.html +++ b/templates/index.html @@ -21,6 +21,7 @@ + @@ -52,6 +53,7 @@ +