Skip to content

Commit

Permalink
Add ugly way of keyboard and mouse support notify
Browse files Browse the repository at this point in the history
  • Loading branch information
sergystepanov committed Mar 9, 2024
1 parent 08393ae commit 6496327
Show file tree
Hide file tree
Showing 16 changed files with 56 additions and 32 deletions.
5 changes: 3 additions & 2 deletions pkg/api/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ type (
PlayerIndex int `json:"player_index"`
}
GameStartUserResponse struct {
RoomId string `json:"roomId"`
Av *AppVideoInfo `json:"av"`
RoomId string `json:"roomId"`
Av *AppVideoInfo `json:"av"`
KbMouse bool `json:"kb_mouse"`
}
IceServer struct {
Urls string `json:"urls,omitempty"`
Expand Down
5 changes: 3 additions & 2 deletions pkg/api/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ type (
}
StartGameResponse struct {
Room
AV *AppVideoInfo `json:"av"`
Record bool
AV *AppVideoInfo `json:"av"`
Record bool `json:"record"`
KbMouse bool `json:"kb_mouse"`
}
RecordGameRequest[T Id] struct {
StatefulRoom[T]
Expand Down
1 change: 1 addition & 0 deletions pkg/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ emulator:
# A list of device IDs to bind to the input ports.
# Some cores allow binding multiple devices to a single port (DosBox), but typically,
# you should bind just one device to one port.
# - kbMouseSupport (bool) -- (temp) a flag if the core needs the keyboard and mouse on the client
# - vfr (bool)
# (experimental)
# Enable variable frame rate only for cores that can't produce a constant frame rate.
Expand Down
1 change: 1 addition & 0 deletions pkg/config/emulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type LibretroCoreConfig struct {
Height int
Hid map[int][]int
IsGlAllowed bool
KbMouseSupport bool
Lib string
Options map[string]string
Roms []string
Expand Down
4 changes: 2 additions & 2 deletions pkg/coordinator/userapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ func (u *User) SendWebrtcOffer(sdp string) { u.Notify(api.WebrtcOffer, sdp) }
func (u *User) SendWebrtcIceCandidate(candidate string) { u.Notify(api.WebrtcIce, candidate) }

// StartGame signals the user that everything is ready to start a game.
func (u *User) StartGame(av *api.AppVideoInfo) {
u.Notify(api.StartGame, api.GameStartUserResponse{RoomId: u.w.RoomId, Av: av})
func (u *User) StartGame(av *api.AppVideoInfo, kbMouse bool) {
u.Notify(api.StartGame, api.GameStartUserResponse{RoomId: u.w.RoomId, Av: av, KbMouse: kbMouse})
}
2 changes: 1 addition & 1 deletion pkg/coordinator/userhandlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (u *User) HandleStartGame(rq api.GameStartUserRequest, launcher games.Launc
return
}
u.log.Info().Str("id", startGameResp.Rid).Msg("Received room response from worker")
u.StartGame(startGameResp.AV)
u.StartGame(startGameResp.AV, startGameResp.KbMouse)

// send back recording status
if conf.Recording.Enabled && rq.Record {
Expand Down
1 change: 1 addition & 0 deletions pkg/worker/caged/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type App interface {
InputGamepad(port int, data []byte)
InputKeyboard(port int, data []byte)
InputMouse(port int, data []byte)
KbMouseSupport() bool
}

type Audio struct {
Expand Down
1 change: 1 addition & 0 deletions pkg/worker/caged/libretro/caged.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func (c *Caged) Scale() float64 { return c.Emulator.Scale()
func (c *Caged) InputGamepad(port int, data []byte) { c.base.Input(port, RetroPad, data) }
func (c *Caged) InputKeyboard(port int, data []byte) { c.base.Input(port, Keyboard, data) }
func (c *Caged) InputMouse(port int, data []byte) { c.base.Input(port, Mouse, data) }
func (c *Caged) KbMouseSupport() bool { return c.base.KbMouseSupport() }
func (c *Caged) Start() { go c.Emulator.Start() }
func (c *Caged) SetSaveOnClose(v bool) { c.base.SaveOnClose = v }
func (c *Caged) SetSessionId(name string) { c.base.SetSessionId(name) }
Expand Down
2 changes: 2 additions & 0 deletions pkg/worker/caged/libretro/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ func (f *Frontend) LoadCore(emu string) {
Options: conf.Options,
UsesLibCo: conf.UsesLibCo,
CoreAspectRatio: conf.CoreAspectRatio,
KbMouseSupport: conf.KbMouseSupport,
}
f.mu.Lock()
scale := 1.0
Expand Down Expand Up @@ -279,6 +280,7 @@ func (f *Frontend) FrameSize() (int, int) { return f.nano.BaseWidth(), f
func (f *Frontend) HasSave() bool { return os.Exists(f.HashPath()) }
func (f *Frontend) HashPath() string { return f.storage.GetSavePath() }
func (f *Frontend) IsPortrait() bool { return f.nano.IsPortrait() }
func (f *Frontend) KbMouseSupport() bool { return f.nano.KbMouseSupport() }
func (f *Frontend) LoadGame(path string) error { return f.nano.LoadGame(path) }
func (f *Frontend) PixFormat() uint32 { return f.nano.Video.PixFmt.C }
func (f *Frontend) RestoreGameState() error { return f.Load() }
Expand Down
2 changes: 2 additions & 0 deletions pkg/worker/caged/libretro/nanoarch/nanoarch.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ type Metadata struct {
Hacks []string
Hid map[int][]int
CoreAspectRatio bool
KbMouseSupport bool
}

type PixFmt struct {
Expand Down Expand Up @@ -143,6 +144,7 @@ func (n *Nanoarch) AspectRatio() float32 { return float32(n.sys.av.g
func (n *Nanoarch) AudioSampleRate() int { return int(n.sys.av.timing.sample_rate) }
func (n *Nanoarch) VideoFramerate() int { return int(n.sys.av.timing.fps) }
func (n *Nanoarch) IsPortrait() bool { return 90 == n.Rot%180 }
func (n *Nanoarch) KbMouseSupport() bool { return n.meta.KbMouseSupport }
func (n *Nanoarch) BaseWidth() int { return int(n.sys.av.geometry.base_width) }
func (n *Nanoarch) BaseHeight() int { return int(n.sys.av.geometry.base_height) }
func (n *Nanoarch) WaitReady() { <-n.reserved }
Expand Down
6 changes: 5 additions & 1 deletion pkg/worker/coordinatorhandlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,11 @@ func (c *coordinator) HandleGameStart(rq api.StartGameRequest[com.Uid], w *Worke

c.RegisterRoom(r.Id())

response := api.StartGameResponse{Room: api.Room{Rid: r.Id()}, Record: w.conf.Recording.Enabled}
response := api.StartGameResponse{
Room: api.Room{Rid: r.Id()},
Record: w.conf.Recording.Enabled,
KbMouse: r.App().KbMouseSupport(),
}
if r.App().AspectEnabled() {
ww, hh := r.App().ViewportSize()
response.AV = &api.AppVideoInfo{W: ww, H: hh, A: r.App().AspectRatio(), S: int(r.App().Scale())}
Expand Down
6 changes: 3 additions & 3 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ <h1>Options</h1>
<script src="js/api/api.js?v=4"></script>
<script src="js/workerManager.js?v=1"></script>
<script src="js/stats/stats.js?v=1"></script>
<script src="js/controller.js?v=10"></script>
<script src="js/stream/stream.js?v=8"></script>
<script src="js/input/keyboard.js?v=8"></script>
<script src="js/controller.js?v=11"></script>
<script src="js/stream/stream.js?v=9"></script>
<script src="js/input/keyboard.js?v=9"></script>
<script src="js/input/touch.js?v=3"></script>
<script src="js/input/joystick.js?v=3"></script>

Expand Down
5 changes: 2 additions & 3 deletions web/js/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,8 @@
event.pub(WEBRTC_ICE_CANDIDATE_RECEIVED, {candidate: payload});
break;
case api.endpoint.GAME_START:
if (payload.av) {
event.pub(APP_VIDEO_CHANGED, payload.av)
}
payload.av && event.pub(APP_VIDEO_CHANGED, payload.av)
payload.kb_mouse && event.pub(KB_MOUSE_FLAG);
event.pub(GAME_ROOM_AVAILABLE, {roomId: payload.roomId});
break;
case api.endpoint.GAME_SAVE:
Expand Down
1 change: 1 addition & 0 deletions web/js/event/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,4 @@ const RECORDING_TOGGLED = 'recordingToggle'
const RECORDING_STATUS_CHANGED = 'recordingStatusChanged'

const APP_VIDEO_CHANGED = 'appVideoChanged'
const KB_MOUSE_FLAG = 'kbMouseFlag'
27 changes: 15 additions & 12 deletions web/js/input/keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,21 @@ const keyboard = (() => {

event.sub(DPAD_TOGGLE, (data) => onDpadToggle(data.checked));

const supportsKeyboardLock =
('keyboard' in navigator) && ('lock' in navigator.keyboard);

if (supportsKeyboardLock) {
event.sub(FULLSCREEN_CHANGE, async (fullscreenEl) => {
enabled = !fullscreenEl;
enabled ? navigator.keyboard.unlock() : await navigator.keyboard.lock();
log.debug(`Keyboard lock: ${!enabled}`);
})
} else {
log.warn('Browser doesn\'t support keyboard lock!');
}
event.sub(KB_MOUSE_FLAG, () => {
const supportsKeyboardLock =
('keyboard' in navigator) && ('lock' in navigator.keyboard);

if (supportsKeyboardLock) {
event.sub(FULLSCREEN_CHANGE, async (fullscreenEl) => {
enabled = !fullscreenEl;
enabled ? navigator.keyboard.unlock() : await navigator.keyboard.lock();
log.debug(`Keyboard lock: ${!enabled}`);
})
} else {
log.warn('Browser doesn\'t support keyboard lock!');
}
})


return {
init: () => {
Expand Down
19 changes: 13 additions & 6 deletions web/js/stream/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const stream = (() => {
state = {
screen: screen,
fullscreen: false,
kbmLock: false,
timerId: null,
w: 0,
h: 0,
Expand Down Expand Up @@ -191,6 +192,8 @@ const stream = (() => {

screen.blur();

if (!state.kbmLock) return;

if (state.fullscreen && !pointerLocked) {
// event.pub(POINTER_LOCK_CHANGE, screen);
await screen.requestPointerLock(
Expand Down Expand Up @@ -230,12 +233,6 @@ const stream = (() => {
event.pub(MOUSE_MOVED, scaleCursorPos(e.movementX, e.movementY));
}

event.sub(POINTER_LOCK_CHANGE, (lockedEl) => {
pointerLocked = lockedEl === screen;
screen.onpointermove = pointerLocked ? handlePointerMove : null;
log.debug(`Pointer lock: ${pointerLocked}`);
});

const fit = 'contain'

event.sub(APP_VIDEO_CHANGED, (payload) => {
Expand All @@ -257,6 +254,16 @@ const stream = (() => {
state.screen.style.aspectRatio = '' + state.aspect
})

event.sub(KB_MOUSE_FLAG, () => {
console.info('Keyboard and mouse will be locked in fullscreen');
state.kbmLock = true;
event.sub(POINTER_LOCK_CHANGE, (lockedEl) => {
pointerLocked = lockedEl === screen;
screen.onpointermove = pointerLocked ? handlePointerMove : null;
log.debug(`Pointer lock: ${pointerLocked}`);
});
})

return {
audio: {mute},
video: {toggleFullscreen, el: getVideoEl},
Expand Down

0 comments on commit 6496327

Please sign in to comment.