Add Model Context Protocol input

This commit is contained in:
giongto35 2025-06-13 01:17:42 -07:00
parent 8083ba086b
commit aca9b84020
7 changed files with 78 additions and 0 deletions

21
pkg/mcp/keycodes.go Normal file
View file

@ -0,0 +1,21 @@
package mcp
var keys = map[string]uint32{
"ArrowUp": 273,
"ArrowDown": 274,
"ArrowRight": 275,
"ArrowLeft": 276,
"Enter": 13,
"Space": 32,
"KeyA": 97,
"KeyB": 98,
"KeyX": 99,
"KeyY": 100,
}
func keyCode(k string) uint32 {
if v, ok := keys[k]; ok {
return v
}
return 0
}

39
pkg/mcp/modelcontext.go Normal file
View file

@ -0,0 +1,39 @@
package mcp
import (
"encoding/binary"
"encoding/json"
)
type Action struct {
Key string `json:"key"`
Press bool `json:"press"`
}
type Message struct {
Actions []Action `json:"actions"`
}
func Parse(data []byte) (Message, error) {
var m Message
err := json.Unmarshal(data, &m)
return m, err
}
func actionBytes(a Action) []byte {
buf := make([]byte, 7)
binary.BigEndian.PutUint32(buf, keyCode(a.Key))
if a.Press {
buf[4] = 1
}
// last two bytes are modifier flags, not used
return buf
}
func ToBytes(m Message) [][]byte {
b := make([][]byte, len(m.Actions))
for i, a := range m.Actions {
b[i] = actionBytes(a)
}
return b
}

View file

@ -19,6 +19,7 @@ const (
RetroPad = libretro.RetroPad
Keyboard = libretro.Keyboard
Mouse = libretro.Mouse
MCP = libretro.MCP
)
type ModName string

View file

@ -78,6 +78,7 @@ const (
RetroPad = Device(nanoarch.RetroPad)
Keyboard = Device(nanoarch.Keyboard)
Mouse = Device(nanoarch.Mouse)
MCP = Device(nanoarch.MCP)
)
var (
@ -340,6 +341,8 @@ func (f *Frontend) Input(port int, device byte, data []byte) {
f.nano.InputKeyboard(port, data)
case Mouse:
f.nano.InputMouse(port, data)
case MCP:
f.nano.InputMCP(port, data)
}
}

View file

@ -47,6 +47,7 @@ const (
RetroPad Device = iota
Keyboard
Mouse
MCP
)
const (

View file

@ -13,6 +13,7 @@ import (
"unsafe"
"github.com/giongto35/cloud-game/v3/pkg/logger"
"github.com/giongto35/cloud-game/v3/pkg/mcp"
"github.com/giongto35/cloud-game/v3/pkg/os"
"github.com/giongto35/cloud-game/v3/pkg/worker/caged/libretro/graphics"
"github.com/giongto35/cloud-game/v3/pkg/worker/thread"
@ -443,6 +444,17 @@ func (n *Nanoarch) InputMouse(_ int, data []byte) {
}
}
func (n *Nanoarch) InputMCP(port int, data []byte) {
msg, err := mcp.Parse(data)
if err != nil {
Nan0.log.Error().Err(err).Msg("mcp parse")
return
}
for _, b := range mcp.ToBytes(msg) {
n.InputKeyboard(port, b)
}
}
func videoSetPixelFormat(format uint32) (C.bool, error) {
switch format {
case C.RETRO_PIXEL_FORMAT_0RGB1555:

View file

@ -200,6 +200,7 @@ func (c *coordinator) HandleGameStart(rq api.StartGameRequest[com.Uid], w *Worke
if needsKbMouse {
_ = s.AddChannel("keyboard", func(data []byte) { r.App().Input(user.Index, byte(caged.Keyboard), data) })
_ = s.AddChannel("mouse", func(data []byte) { r.App().Input(user.Index, byte(caged.Mouse), data) })
_ = s.AddChannel("mcp", func(data []byte) { r.App().Input(user.Index, byte(caged.MCP), data) })
}
c.RegisterRoom(r.Id())