From d671c8adc08525e60a7d2e21784e9448cc046f58 Mon Sep 17 00:00:00 2001 From: Johann Schopplich Date: Mon, 15 Jun 2026 09:08:03 +0200 Subject: [PATCH 1/6] Emscripten: Rework touch input and shell layout --- resources/emscripten/emscripten-shell.html | 842 ++++++++++++--------- 1 file changed, 487 insertions(+), 355 deletions(-) diff --git a/resources/emscripten/emscripten-shell.html b/resources/emscripten/emscripten-shell.html index ebe713eb99..c546337419 100644 --- a/resources/emscripten/emscripten-shell.html +++ b/resources/emscripten/emscripten-shell.html @@ -1,365 +1,497 @@ - - - - EasyRPG Player - - - -
- -
- -
- -
- - -
- - - - - - - + + html { + touch-action: none; + } + + body { + margin: 0; + font-family: system-ui, sans-serif; + color: white; + background: black; + -webkit-touch-callout: none; + -webkit-user-select: none; + user-select: none; + } + + #boot { + position: fixed; + inset: 0; + z-index: 1; + display: grid; + place-content: center; + justify-items: center; + font-family: ui-monospace, monospace; + text-align: center; + background: black; + pointer-events: none; + transition: + opacity 300ms ease, + visibility 300ms ease; + } + + #boot.done { + visibility: hidden; + opacity: 0; + } + + #status { + font-size: 0.875rem; + color: var(--color-gray); + } + + #controls { + position: fixed; + top: env(safe-area-inset-top); + right: env(safe-area-inset-right); + z-index: 10; + } + + #controls button { + display: inline-flex; + padding: 0.5rem; + color: white; + background: transparent; + border: 0; + cursor: pointer; + opacity: 0.7; + transition: opacity 80ms ease; + } + + #controls button[hidden] { + display: none; + } + + #controls button:focus-visible { + opacity: 1; + } + + + #canvas { + position: absolute; + top: 50%; + left: 50%; + width: 100%; + height: 100%; + border: 0; + outline: none; + image-rendering: pixelated; + transform: translate(-50%, -50%); + } + + img#canvas { + object-fit: contain; + } + + + @media (hover: none), (pointer: coarse) { + #viewport { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100dvh; + display: grid; + grid-template-areas: + "screen screen" + "dpad apad"; + grid-template-rows: minmax(0, 1fr) auto; + grid-template-columns: 1fr 1fr; + } + + #canvas { + position: static; + grid-area: screen; + object-fit: contain; + transform: none; + } + + + #dpad, + #apad { + align-self: center; + } + + #dpad { + grid-area: dpad; + padding: 0.75rem 0 calc(0.75rem + env(safe-area-inset-bottom)) + calc(0.75rem + env(safe-area-inset-left)); + } + + #apad { + grid-area: apad; + justify-self: end; + padding: 0.75rem calc(0.75rem + env(safe-area-inset-right)) + calc(0.75rem + env(safe-area-inset-bottom)) 0; + } + + @media (orientation: landscape) { + #viewport { + grid-template-areas: "dpad screen apad"; + grid-template-rows: minmax(0, 1fr); + grid-template-columns: auto minmax(0, 1fr) auto; + } + + #dpad { + padding: 0 0.75rem 0 calc(0.75rem + env(safe-area-inset-left)); + } + + #apad { + padding: 0 calc(0.75rem + env(safe-area-inset-right)) 0 0.75rem; + } + } + } + + #dpad svg { + width: calc(2 * var(--controls-size)); + height: calc(2 * var(--controls-size)); + fill: var(--color-gray); + } + + #apad > * { + width: var(--controls-size); + height: var(--controls-size); + background-color: var(--color-gray); + border-radius: 50%; + } + + #apad > :first-child { + margin-left: var(--controls-size); + } + + #dpad svg > *, + #apad > * { + opacity: var(--controls-opacity); + transition: + opacity var(--controls-fade) ease, + scale 80ms ease; + } + + #dpad path { + transform-box: fill-box; + transform-origin: center; + } + + #dpad path.active, + #apad > .active { + opacity: 1; + scale: 0.94; + } + + /* Idle dims the whole deck by flipping the shared opacity var */ + body.controls-idle { + --controls-opacity: 0.2; + --controls-fade: 500ms; + } + + body.gamepad-connected #dpad, + body.gamepad-connected #apad { + display: none; + } + + @media (hover: hover) and (pointer: fine) { + #apad, + #dpad { + display: none; + } + + #controls button:hover { + opacity: 1; + } + } + + + +
+ +
+ +
+
-
-
-
+
+ + + + +
-
- -{{{ SCRIPT }}} - - - - + + + From 1b7151bf54e636ec1a584c3ee0748294196384d6 Mon Sep 17 00:00:00 2001 From: Johann Schopplich Date: Mon, 15 Jun 2026 09:08:03 +0200 Subject: [PATCH 2/6] Emscripten: Add pixel-perfect integer scaling toggle --- resources/emscripten/emscripten-shell.html | 133 +++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/resources/emscripten/emscripten-shell.html b/resources/emscripten/emscripten-shell.html index c546337419..5a9990a08e 100644 --- a/resources/emscripten/emscripten-shell.html +++ b/resources/emscripten/emscripten-shell.html @@ -83,6 +83,10 @@ opacity: 1; } + body[data-scaling="integer"] #controls-scaling .icon-fit, + body:not([data-scaling="integer"]) #controls-scaling .icon-integer { + display: none; + } #canvas { position: absolute; @@ -100,6 +104,12 @@ object-fit: contain; } + /* Pixel-perfect mode: `!important` beats the inline styles SDL + writes onto the canvas while it manages its window size */ + body[data-scaling="integer"] #canvas { + width: var(--canvas-width, 100%) !important; + height: var(--canvas-height, 100%) !important; + } @media (hover: none), (pointer: coarse) { #viewport { @@ -123,6 +133,11 @@ transform: none; } + body[data-scaling="integer"] #canvas { + place-self: center; + outline: 1px solid hsl(0 0% 25%); + box-shadow: 0 0 0 6px hsl(0 0% 8%); + } #dpad, #apad { @@ -220,6 +235,40 @@
+