From 24316aad7d41323f7b8d912435e110d2b2ab3a15 Mon Sep 17 00:00:00 2001 From: Ethan O'Brien <77750390+ethanaobrien@users.noreply.github.com> Date: Sat, 1 Jul 2023 16:21:48 -0500 Subject: [PATCH] Add volume slider --- src/GameManager.js | 6 ++- src/css/main.css | 132 +++++++++++++++++++++++++++++++++++++++++++++ src/emulator.js | 57 ++++++++++++++++++++ 3 files changed, 194 insertions(+), 1 deletion(-) diff --git a/src/GameManager.js b/src/GameManager.js index 0d59ca8..e34645b 100644 --- a/src/GameManager.js +++ b/src/GameManager.js @@ -17,7 +17,8 @@ class EJS_GameManager { toggleShader: this.Module.cwrap('shader_enable', 'null', ['number']), getDiskCount: this.Module.cwrap('get_disk_count', 'number', []), getCurrentDisk: this.Module.cwrap('get_current_disk', 'number', []), - setCurrentDisk: this.Module.cwrap('set_current_disk', 'null', ['number']) + setCurrentDisk: this.Module.cwrap('set_current_disk', 'null', ['number']), + setVolume: this.Module.cwrap('set_volume', 'null', ['number']) } this.mkdir("/home"); this.mkdir("/home/web_user"); @@ -134,6 +135,9 @@ class EJS_GameManager { setCurrentDisk(disk) { this.functions.setCurrentDisk(disk); } + setVolume(volume) { + this.functions.setVolume(volume); + } } window.EJS_GameManager = EJS_GameManager; diff --git a/src/css/main.css b/src/css/main.css index a4333f6..1e5d620 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -951,3 +951,135 @@ right: .025rem; border: 0; } + +.ejs_volume_parent { + padding-right: 15px; + max-width: 110px; + align-items: center; + display: flex; + flex: 1; + position: relative; +} +.ejs_volume_parent::-webkit-media-controls{ + display: none; +} +.ejs_volume_parent input[type='range']{ + -webkit-appearance:none; + border:0; + border-radius:28px; + color:rgba(var(--ejs-primary-color), 1); + display:block; + margin:0; + padding:0; + transition:box-shadow 0.3s ease; + width:100% +} +.ejs_volume_parent input[type='range']::-webkit-slider-runnable-track{ + background-color:rgba(255,255,255,0.25) + box-shadow:0 0 0 5px rgba(var(--ejs-primary-color), 0.5); + outline:0 + background:transparent; + border:0; + border-radius:3px; + height:6px; + transition:box-shadow 0.3s ease; + user-select:none; + background-image:linear-gradient(to right, currentColor var(--value, 0%), transparent var(--value, 0%)) +} +.ejs_volume_parent input[type='range']::-webkit-slider-thumb{ + background:#fff; + border:0; + border-radius:100%; + box-shadow:0 1px 1px rgba(0,0,0,0.15),0 0 0 1px rgba(47,52,61,0.2); + height:14px; + position:relative; + transition:all 0.2s ease; + width:14px; + -webkit-appearance:none; + margin-top:-4px +} +.ejs_volume_parent input[type='range']::-moz-range-track{ + background-color:rgba(255,255,255,0.25) + box-shadow:0 0 0 5px rgba(var(--ejs-primary-color), 0.5); + outline:0 + background:transparent; + border:0; + border-radius:3px; + height:6px; + transition:box-shadow 0.3s ease; + user-select:none +} +.ejs_volume_parent input[type='range']::-moz-range-thumb{ + background:#fff; + border:0; + border-radius:100%; + box-shadow:0 1px 1px rgba(0,0,0,0.15),0 0 0 1px rgba(47,52,61,0.2); + height:14px; + position:relative; + transition:all 0.2s ease; + width:14px +} +.ejs_volume_parent input[type='range']::-moz-range-progress{ + background:currentColor; + border-radius:3px; + height:6px +} +.ejs_volume_parent input[type='range']::-ms-track{ + background-color:rgba(255,255,255,0.25) + box-shadow:0 0 0 5px rgba(var(--ejs-primary-color), 0.5); + outline:0 + background:transparent; + border:0; + border-radius:3px; + height:6px; + transition:box-shadow 0.3s ease; + user-select:none; + color:transparent +} +.ejs_volume_parent input[type='range']::-ms-fill-upper{ + background:transparent; + border:0; + border-radius:3px; + height:6px; + transition:box-shadow 0.3s ease; + user-select:none +} +.ejs_volume_parent input[type='range']::-ms-fill-lower{ + background:transparent; + border:0; + border-radius:3px; + height:6px; + transition:box-shadow 0.3s ease; + user-select:none; + background:currentColor +} +.ejs_volume_parent input[type='range']::-ms-thumb{ + background:#fff; + border:0; + border-radius:100%; + box-shadow:0 1px 1px rgba(0,0,0,0.15),0 0 0 1px rgba(47,52,61,0.2); + height:14px; + position:relative; + transition:all 0.2s ease; + width:14px; + margin-top:0 +} +.ejs_volume_parent input[type='range']::-ms-tooltip{ + display:none +} +.ejs_volume_parent input[type='range']:focus{ + outline:0 +} +.ejs_volume_parent input[type='range']::-moz-focus-outer{ + border:0 +} + +.ejs_volume_parent input[type='range']:active::-webkit-slider-thumb { + box-shadow:0 1px 1px rgba(0,0,0,0.15),0 0 0 1px rgba(47,52,61,0.2),0 0 0 3px rgba(255,255,255,0.5) +} +.ejs_volume_parent input[type='range']:active::-moz-range-thumb { + box-shadow:0 1px 1px rgba(0,0,0,0.15),0 0 0 1px rgba(47,52,61,0.2),0 0 0 3px rgba(255,255,255,0.5) +} +.ejs_volume_parent input[type='range']:active::-ms-thumb { + box-shadow:0 1px 1px rgba(0,0,0,0.15),0 0 0 1px rgba(47,52,61,0.2),0 0 0 3px rgba(255,255,255,0.5) +} diff --git a/src/emulator.js b/src/emulator.js index 0ab4e34..7f402ee 100644 --- a/src/emulator.js +++ b/src/emulator.js @@ -154,6 +154,8 @@ class EmulatorJS { this.debug = (window.EJS_DEBUG_XX === true); this.cheats = []; this.started = false; + this.volume = 0.5; + this.muted = false; this.paused = true; this.listeners = []; this.config = config; @@ -636,6 +638,7 @@ class EmulatorJS { this.handleResize(); this.updateCheatUI(); this.updateGamepadLabels(); + this.setVolume(this.volume); this.elements.parent.focus(); this.callEvent("start"); } @@ -925,6 +928,60 @@ class EmulatorJS { spacer.style = "flex:1;"; this.elements.menu.appendChild(spacer); + const volumeSettings = this.createElement("div"); + volumeSettings.classList.add("ejs_volume_parent"); + const muteButton = addButton("Mute", '', () => { + muteButton.style.display = "none"; + unmuteButton.style.display = ""; + this.muted = true; + this.setVolume(0); + }, volumeSettings); + const unmuteButton = addButton("Unmute", '', () => { + muteButton.style.display = ""; + unmuteButton.style.display = "none"; + this.muted = false; + this.setVolume(this.volume); + }, volumeSettings); + unmuteButton.style.display = "none"; + + const volumeSlider = this.createElement("input"); + volumeSlider.setAttribute("data-range", "volume"); + volumeSlider.setAttribute("type", "range"); + volumeSlider.setAttribute("min", 0); + volumeSlider.setAttribute("max", 1); + volumeSlider.setAttribute("step", 0.01); + volumeSlider.setAttribute("autocomplete", "off"); + volumeSlider.setAttribute("role", "slider"); + volumeSlider.setAttribute("aria-label", "Volume"); + volumeSlider.setAttribute("aria-valuemin", 0); + volumeSlider.setAttribute("aria-valuemax", 100); + + this.setVolume = (volume) => { + volumeSlider.setAttribute("value", volume); + volumeSlider.setAttribute("aria-valuenow", volume*100); + volumeSlider.setAttribute("aria-valuetext", (volume*100).toFixed(1) + "%"); + volumeSlider.setAttribute("style", "--value: "+volume*100+"%;margin-left: 5px;position: relative;z-index: 2;"); + if (this.gameManager) this.gameManager.setVolume(volume); + } + this.setVolume(this.volume); + + this.addEventListener(volumeSlider, "change mousemove touchmove mousedown touchstart mouseup", (e) => { + setTimeout(() => { + this.volume = parseFloat(volumeSlider.value); + this.setVolume(this.volume); + unmuteButton.style.display = (this.volume === 0) ? "" : "none"; + muteButton.style.display = (this.volume === 0) ? "none" : ""; + }, 5); + }) + + volumeSettings.appendChild(volumeSlider); + + + + //this.volume this.muted + + this.elements.menu.appendChild(volumeSettings); + this.settingParent = this.createElement("div"); this.settingsMenuOpen = false; const settingButton = addButton("Settings", '', () => {