diff --git a/pkg/worker/coordinatorhandlers.go b/pkg/worker/coordinatorhandlers.go index 244765d22..27340aef9 100644 --- a/pkg/worker/coordinatorhandlers.go +++ b/pkg/worker/coordinatorhandlers.go @@ -126,12 +126,14 @@ func (c *coordinator) HandleGameStart(rq api.StartGameRequest[com.Uid], w *Worke } } - data, err := api.Wrap(api.Out{T: uint8(api.AppVideoChange), Payload: api.AppVideoInfo{ - W: m.VideoW, - H: m.VideoH, - A: app.AspectRatio(), - S: int(app.Scale()), - }}) + data, err := api.Wrap(api.Out{ + T: uint8(api.AppVideoChange), + Payload: api.AppVideoInfo{ + W: m.VideoW, + H: m.VideoH, + A: app.AspectRatio(), + S: int(app.Scale()), + }}) if err != nil { c.log.Error().Err(err).Msgf("wrap") } diff --git a/web/js/stream/stream.js b/web/js/stream/stream.js index 0a71ff9c2..af2dc0bec 100644 --- a/web/js/stream/stream.js +++ b/web/js/stream/stream.js @@ -179,7 +179,9 @@ const stream = (() => { if (fullscreen && !pointerLocked) { // event.pub(POINTER_LOCK_CHANGE, screen); - await screen.requestPointerLock(); + await screen.requestPointerLock( + // { unadjustedMovement: true,} + ); } screen.onpointerdown = fullscreen ? handlePointerDown : null; @@ -188,8 +190,32 @@ const stream = (() => { // !to flipped }) + let ex = 0, ey = 0; + const scaleCursorPos = (x, y) => { + const horizontal = screen.videoWidth > screen.videoHeight; + + const arW = horizontal ? screen.offsetHeight * state.aspect : screen.offsetHeight; + const arH = horizontal ? screen.offsetHeight : screen.offsetWidth * state.aspect; + const sw = arW / screen.videoWidth; + const sh = arH / screen.videoHeight; + + const rez = { + dx: x / sw + ex, + dy: y / sh + ey + } + + ex = rez.dx % 1; + ey = rez.dy % 1; + + rez.dx -= ex; + rez.dy -= ey; + + return rez; + } + const handlePointerMove = (e) => { - event.pub(MOUSE_MOVED, {dx: e.movementX, dy: e.movementY}); + const delta = scaleCursorPos(e.movementX, e.movementY); + event.pub(MOUSE_MOVED, delta); } event.sub(POINTER_LOCK_CHANGE, (lockedEl) => { @@ -214,9 +240,9 @@ const stream = (() => { state.screen.style['object-fit'] = a.toFixed(6) !== a2.toFixed(6) ? 'fill' : fit state.h = hh state.w = Math.floor(hh * a) - state.screen.setAttribute('width', '' + ww) - state.screen.setAttribute('height', '' + hh) - state.screen.style.aspectRatio = '' + state.aspect + state.screen.setAttribute('width', ww) + state.screen.setAttribute('height', hh) + state.screen.style.aspectRatio = state.aspect }) return {