From 3f12145ca51a9186f7f4e5601dc0c9553ac5d615 Mon Sep 17 00:00:00 2001 From: sergystepanov Date: Fri, 20 Jun 2025 18:12:47 +0300 Subject: [PATCH] Verifies during startup if the system can run the emulator This check can be disabled with the emulator.failFast = false config option. Right now it checks SDL2 video context creation. --- pkg/config/config.yaml | 3 +++ pkg/config/emulator.go | 1 + pkg/worker/caged/libretro/caged.go | 8 ++++++++ pkg/worker/caged/libretro/frontend.go | 5 +++++ pkg/worker/caged/libretro/graphics/sdl.go | 9 +++++++++ pkg/worker/caged/libretro/nanoarch/nanoarch.go | 1 + 6 files changed, 27 insertions(+) diff --git a/pkg/config/config.yaml b/pkg/config/config.yaml index 33eb0b2a..1a1d2803 100644 --- a/pkg/config/config.yaml +++ b/pkg/config/config.yaml @@ -137,6 +137,9 @@ emulator: # path for storing emulator generated files localPath: "./libretro" + # checks if the system supports running an emulator at startup + failFast: true + libretro: # use zip compression for emulator save states saveCompression: true diff --git a/pkg/config/emulator.go b/pkg/config/emulator.go index d3daca3e..013225f7 100644 --- a/pkg/config/emulator.go +++ b/pkg/config/emulator.go @@ -9,6 +9,7 @@ import ( ) type Emulator struct { + FailFast bool Threads int Storage string LocalPath string diff --git a/pkg/worker/caged/libretro/caged.go b/pkg/worker/caged/libretro/caged.go index 8c06776b..3d21db11 100644 --- a/pkg/worker/caged/libretro/caged.go +++ b/pkg/worker/caged/libretro/caged.go @@ -31,6 +31,13 @@ func (c *Caged) Init() error { if err := manager.CheckCores(c.conf.Emulator, c.log); err != nil { c.log.Warn().Err(err).Msgf("a Libretro cores sync fail") } + + if c.conf.Emulator.FailFast { + if err := c.IsSupported(); err != nil { + return err + } + } + return nil } @@ -92,3 +99,4 @@ 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) } func (c *Caged) Close() { c.Emulator.Close() } +func (c *Caged) IsSupported() error { return c.base.IsSupported() } diff --git a/pkg/worker/caged/libretro/frontend.go b/pkg/worker/caged/libretro/frontend.go index c3666e98..8d0a73ac 100644 --- a/pkg/worker/caged/libretro/frontend.go +++ b/pkg/worker/caged/libretro/frontend.go @@ -13,6 +13,7 @@ import ( "github.com/giongto35/cloud-game/v3/pkg/logger" "github.com/giongto35/cloud-game/v3/pkg/os" "github.com/giongto35/cloud-game/v3/pkg/worker/caged/app" + "github.com/giongto35/cloud-game/v3/pkg/worker/caged/libretro/graphics" "github.com/giongto35/cloud-game/v3/pkg/worker/caged/libretro/nanoarch" ) @@ -422,6 +423,10 @@ func (f *Frontend) Load() error { return nil } +func (f *Frontend) IsSupported() error { + return graphics.TryInit() +} + func (f *Frontend) autosave(periodSec int) { f.log.Info().Msgf("Autosave every [%vs]", periodSec) ticker := time.NewTicker(time.Duration(periodSec) * time.Second) diff --git a/pkg/worker/caged/libretro/graphics/sdl.go b/pkg/worker/caged/libretro/graphics/sdl.go index d0df2c1d..7c25efbd 100644 --- a/pkg/worker/caged/libretro/graphics/sdl.go +++ b/pkg/worker/caged/libretro/graphics/sdl.go @@ -76,6 +76,15 @@ func NewSDLContext(cfg Config, log *logger.Logger) (*SDL, error) { return &display, nil } +// TryInit check weather SDL context can be created on the system. +func TryInit() error { + if err := sdl.Init(sdl.INIT_VIDEO); err != nil { + return fmt.Errorf("SDL init fail: %w", err) + } + sdl.Quit() + return nil +} + // Deinit destroys SDL/OpenGL context. // Uses main thread lock (see thread/mainthread). func (s *SDL) Deinit() error { diff --git a/pkg/worker/caged/libretro/nanoarch/nanoarch.go b/pkg/worker/caged/libretro/nanoarch/nanoarch.go index fd12ef14..e26ee07d 100644 --- a/pkg/worker/caged/libretro/nanoarch/nanoarch.go +++ b/pkg/worker/caged/libretro/nanoarch/nanoarch.go @@ -414,6 +414,7 @@ func (n *Nanoarch) Run() { } } +func (n *Nanoarch) IsSupported() error { return graphics.TryInit() } func (n *Nanoarch) IsGL() bool { return n.Video.gl.enabled } func (n *Nanoarch) IsStopped() bool { return n.Stopped.Load() } func (n *Nanoarch) InputRetropad(port int, data []byte) { n.retropad.Input(port, data) }