diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f3ef9a0c..f20391e1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,9 +23,9 @@ jobs: step: [ build, check ] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v4 with: go-version: ^1.20 @@ -101,7 +101,7 @@ jobs: run: | make verify-cores - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 if: matrix.step == 'check' && always() with: name: emulator-test-frames @@ -112,5 +112,5 @@ jobs: runs-on: ubuntu-latest if: github.event_name == 'pull_request' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: docker build --build-arg VERSION=$(./scripts/version.sh) . diff --git a/.github/workflows/cd/cloudretro.io/config.yaml b/.github/workflows/cd/cloudretro.io/config.yaml new file mode 100644 index 00000000..91f06f93 --- /dev/null +++ b/.github/workflows/cd/cloudretro.io/config.yaml @@ -0,0 +1,24 @@ +version: 4 + +coordinator: + debug: true + server: + address: + https: true + tls: + domain: usw.cloudretro.io + analytics: + inject: true + gtag: UA-145078282-1 + +worker: + debug: true + network: + coordinatorAddress: usw.cloudretro.io + publicAddress: usw.cloudretro.io + secure: true + server: + https: true + tls: + address: :444 + domain: usw.cloudretro.io diff --git a/.github/workflows/cd/cloudretro.io/coordinator.env b/.github/workflows/cd/cloudretro.io/coordinator.env deleted file mode 100644 index 193f4bc9..00000000 --- a/.github/workflows/cd/cloudretro.io/coordinator.env +++ /dev/null @@ -1,6 +0,0 @@ -CLOUD_GAME_COORDINATOR_ANALYTICS_GTAG=UA-145078282-1 -CLOUD_GAME_COORDINATOR_ANALYTICS_INJECT=true -CLOUD_GAME_COORDINATOR_SERVER_ADDRESS= -CLOUD_GAME_COORDINATOR_SERVER_HTTPS=true -CLOUD_GAME_COORDINATOR_SERVER_TLS_DOMAIN=usw.cloudretro.io -CLOUD_GAME_COORDINATOR_DEBUG=true diff --git a/.github/workflows/cd/cloudretro.io/worker.env b/.github/workflows/cd/cloudretro.io/worker.env deleted file mode 100644 index ea57a801..00000000 --- a/.github/workflows/cd/cloudretro.io/worker.env +++ /dev/null @@ -1,8 +0,0 @@ -CLOUD_GAME_WORKER_NETWORK_COORDINATORADDRESS=usw.cloudretro.io -CLOUD_GAME_WORKER_NETWORK_PUBLICADDRESS=usw.cloudretro.io -CLOUD_GAME_WORKER_NETWORK_SECURE=true -CLOUD_GAME_WORKER_SERVER_ADDRESS=:80 -CLOUD_GAME_WORKER_SERVER_HTTPS=true -CLOUD_GAME_WORKER_SERVER_TLS_ADDRESS=:444 -CLOUD_GAME_WORKER_SERVER_TLS_DOMAIN=usw.cloudretro.io -CLOUD_GAME_WORKER_DEBUG=true diff --git a/.github/workflows/cd/deploy-app.sh b/.github/workflows/cd/deploy-app.sh index e8b027b0..c80c0eab 100755 --- a/.github/workflows/cd/deploy-app.sh +++ b/.github/workflows/cd/deploy-app.sh @@ -72,6 +72,7 @@ WORKERS=${WORKERS:-4} USER=${USER:-root} compose_src=$(cat $LOCAL_WORK_DIR/docker-compose.yml) +config_src=$(cat $LOCAL_WORK_DIR/configs/config.yaml) function remote_run_commands() { ret="" @@ -171,7 +172,14 @@ for ip in $IP_LIST; do # build Docker container env file run_env="" + custom_config="" if [[ ! -z "${ENV_DIR}" ]]; then + env_f=$ENV_DIR/config.yaml + if [[ -e "$env_f" ]]; then + echo "config.yaml found" + custom_config=$(cat $env_f) + fi + if [ $deploy_coordinator == 1 ]; then env_f=$ENV_DIR/coordinator.env if [[ -e "$env_f" ]]; then @@ -216,11 +224,10 @@ for ip in $IP_LIST; do docker compose version; \ mkdir -p $REMOTE_WORK_DIR; \ cd $REMOTE_WORK_DIR; \ + mkdir -p $REMOTE_WORK_DIR/home; \ + echo \"$custom_config\" > $REMOTE_WORK_DIR/home/config.yaml; \ echo '$compose_src' > ./docker-compose.yml; \ - echo '$run_env' > ./run.env; \ - docker image prune -f -a; \ + docker compose stop; \ IMAGE_TAG=$DOCKER_IMAGE_TAG docker compose pull; \ - echo '$run' > ./run.sh; \ - chmod +x ./run.sh; \ - ./run.sh" + docker compose up -d;" done diff --git a/.github/workflows/cd/docker-compose.yml b/.github/workflows/cd/docker-compose.yml index 1943eec8..6e91027a 100644 --- a/.github/workflows/cd/docker-compose.yml +++ b/.github/workflows/cd/docker-compose.yml @@ -1,8 +1,7 @@ -version: "3.4" +version: "3.9" x-params: &default-params - env_file: run.env image: ghcr.io/giongto35/cloud-game/cloud-game:${IMAGE_TAG:-latest} network_mode: "host" privileged: true @@ -10,8 +9,8 @@ x-params: logging: driver: "json-file" options: - max-size: "64m" - max-file: "5" + max-size: "32m" + max-file: "4" compress: "true" services: @@ -29,11 +28,11 @@ services: - coordinator deploy: mode: replicated - replicas: ${WORKER_REPLICAS:-4} + replicas: 4 environment: - MESA_GL_VERSION_OVERRIDE=3.3 #entrypoint: [ "/bin/sh", "-c", "xvfb-run -a $$@", "" ] - command: worker --zone=${ZONE:-} + command: worker volumes: - ${APP_DIR:-/cloud-game}/cache:/usr/local/share/cloud-game/assets/cache - ${APP_DIR:-/cloud-game}/cores:/usr/local/share/cloud-game/assets/cores diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c58fc810..dd296ead 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -16,7 +16,7 @@ jobs: key: ${{ secrets.SSH_PRIVATE_KEY }} known_hosts: 'PLACEHOLDER' - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Deploy to all servers env: diff --git a/.github/workflows/docker_publish_stable.yml b/.github/workflows/docker_publish_stable.yml index ea1b1c43..e06facac 100644 --- a/.github/workflows/docker_publish_stable.yml +++ b/.github/workflows/docker_publish_stable.yml @@ -13,7 +13,7 @@ jobs: docker-publish-stable: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV diff --git a/.github/workflows/docker_publish_unstable.yml b/.github/workflows/docker_publish_unstable.yml index c5bdba5d..9b81b188 100644 --- a/.github/workflows/docker_publish_unstable.yml +++ b/.github/workflows/docker_publish_unstable.yml @@ -13,7 +13,7 @@ jobs: docker-publish-unstable: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: echo "V=$(./scripts/version.sh)" >> $GITHUB_ENV diff --git a/.github/workflows/release.yml_ b/.github/workflows/release.yml_ index 701e2618..4f7d1d27 100644 --- a/.github/workflows/release.yml_ +++ b/.github/workflows/release.yml_ @@ -37,9 +37,9 @@ jobs: env: release-dir: _release steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v4 with: go-version: ^1.20 diff --git a/Dockerfile b/Dockerfile index b9e6fb83..af99250b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -55,7 +55,6 @@ RUN mkdir -p ./assets/cache && \ mkdir -p ./assets/games && \ mkdir -p ./libretro && \ mkdir -p /root/.cr -COPY assets/cores ./assets/cores COPY configs ./configs COPY web ./web ARG VERSION diff --git a/assets/cores/mupen64plus_next_libretro.cfg b/assets/cores/mupen64plus_next_libretro.cfg deleted file mode 100644 index c6cb78bb..00000000 --- a/assets/cores/mupen64plus_next_libretro.cfg +++ /dev/null @@ -1,14 +0,0 @@ -mupen64plus-169screensize = 640x360 -mupen64plus-43screensize = 320x240 -mupen64plus-EnableCopyColorToRDRAM = Off -mupen64plus-EnableCopyDepthToRDRAM = Off -mupen64plus-EnableEnhancedTextureStorage = True -mupen64plus-EnableFBEmulation = True -mupen64plus-EnableLegacyBlending = True -mupen64plus-FrameDuping = False -mupen64plus-MaxTxCacheSize = 8000 -mupen64plus-ThreadedRenderer = False -mupen64plus-cpucore = dynamic_recompiler -mupen64plus-pak1 = memory -mupen64plus-rdp-plugin = gliden64 -mupen64plus-rsp-plugin = hle diff --git a/assets/cores/nestopia_libretro.cfg b/assets/cores/nestopia_libretro.cfg deleted file mode 100644 index fd06bde7..00000000 --- a/assets/cores/nestopia_libretro.cfg +++ /dev/null @@ -1 +0,0 @@ -nestopia_audio_type=stereo diff --git a/configs/config.yaml b/configs/config.yaml index ef6e6d39..3d756231 100644 --- a/configs/config.yaml +++ b/configs/config.yaml @@ -131,7 +131,6 @@ emulator: cores: paths: libs: assets/cores - configs: assets/cores # Config params for Libretro cores repository, # available types are: # - buildbot (the default Libretro nightly repository) @@ -162,7 +161,6 @@ emulator: # Available config params: # - altRepo (bool) prioritize secondary repo as the download source # - lib (string) - # - config (string) # - roms ([]string) # - folder (string) # By default emulator selection is based on the folder named as cores @@ -181,15 +179,20 @@ emulator: # their tick rate (1/system FPS), but OpenGL cores like N64 may have significant # frame rendering time inconsistencies. In general, VFR for CFR cores leads to # noticeable video stutter (with the current frame rendering time calculations). + # - options ([]string) a list of Libretro core options for tweaking list: gba: lib: mgba_libretro roms: [ "gba", "gbc" ] pcsx: lib: pcsx_rearmed_libretro - roms: [ "cue" ] + roms: [ "cue", "chd" ] # example of folder override folder: psx + # see: https://github.com/libretro/pcsx_rearmed/blob/master/frontend/libretro_core_options.h + options: + pcsx_rearmed_drc: enabled + pcsx_rearmed_display_internal_fps: disabled # MAME core requires additional manual setup, please read: # https://docs.libretro.com/library/fbneo/ mame: @@ -197,8 +200,10 @@ emulator: roms: [ "zip" ] nes: lib: nestopia_libretro - config: nestopia_libretro.cfg roms: [ "nes" ] + # see: https://github.com/libretro/nestopia/blob/master/libretro/libretro_core_options.h + options: + nestopia_audio_type: stereo snes: lib: snes9x_libretro roms: [ "smc", "sfc", "swc", "fig", "bs" ] @@ -206,11 +211,26 @@ emulator: n64: lib: mupen64plus_next_libretro altRepo: true - config: mupen64plus_next_libretro.cfg roms: [ "n64", "v64", "z64" ] isGlAllowed: true usesLibCo: true vfr: true + # see: https://github.com/libretro/mupen64plus-libretro-nx/blob/master/libretro/libretro_core_options.h + options: + mupen64plus-169screensize: 640x360 + mupen64plus-43screensize: 320x240 + mupen64plus-EnableCopyColorToRDRAM: Off + mupen64plus-EnableCopyDepthToRDRAM: Off + mupen64plus-EnableEnhancedTextureStorage: True + mupen64plus-EnableFBEmulation: True + mupen64plus-EnableLegacyBlending: True + mupen64plus-FrameDuping: False + mupen64plus-MaxTxCacheSize: 8000 + mupen64plus-ThreadedRenderer: False + mupen64plus-cpucore: dynamic_recompiler + mupen64plus-pak1: memory + mupen64plus-rdp-plugin: gliden64 + mupen64plus-rsp-plugin: hle encoder: audio: diff --git a/go.mod b/go.mod index f21adf9f..99132d31 100644 --- a/go.mod +++ b/go.mod @@ -6,13 +6,13 @@ require ( github.com/VictoriaMetrics/metrics v1.23.1 github.com/cavaliergopher/grab/v3 v3.0.1 github.com/fsnotify/fsnotify v1.6.0 - github.com/goccy/go-json v0.10.1 + github.com/goccy/go-json v0.10.2 github.com/gofrs/flock v0.8.1 github.com/gorilla/websocket v1.5.0 github.com/kkyr/fig v0.3.1 github.com/pion/interceptor v0.1.12 github.com/pion/logging v0.2.2 - github.com/pion/webrtc/v3 v3.1.58 + github.com/pion/webrtc/v3 v3.1.59 github.com/rs/xid v1.4.0 github.com/rs/zerolog v1.29.0 github.com/veandco/go-sdl2 v0.4.33 @@ -23,12 +23,12 @@ require ( require ( github.com/google/uuid v1.3.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pion/datachannel v1.5.5 // indirect github.com/pion/dtls/v2 v2.2.6 // indirect - github.com/pion/ice/v2 v2.3.1 // indirect + github.com/pion/ice/v2 v2.3.2 // indirect github.com/pion/mdns v0.0.7 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/rtcp v1.2.10 // indirect @@ -43,7 +43,7 @@ require ( github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/histogram v1.2.0 // indirect golang.org/x/net v0.8.0 // indirect - golang.org/x/sys v0.6.0 // indirect + golang.org/x/sys v0.7.0 // indirect golang.org/x/text v0.8.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 2b13b9f8..25aa0141 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/goccy/go-json v0.10.1 h1:lEs5Ob+oOG/Ze199njvzHbhn6p9T+h64F5hRj69iTTo= -github.com/goccy/go-json v0.10.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= @@ -46,8 +46,8 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -65,8 +65,8 @@ github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= github.com/pion/dtls/v2 v2.2.6 h1:yXMxKr0Skd+Ub6A8UqXTRLSywskx93ooMRHsQUtd+Z4= github.com/pion/dtls/v2 v2.2.6/go.mod h1:t8fWJCIquY5rlQZwA2yWxUS1+OCrAdXrhVKXB5oD/wY= -github.com/pion/ice/v2 v2.3.1 h1:FQCmUfZe2Jpe7LYStVBOP6z1DiSzbIateih3TztgTjc= -github.com/pion/ice/v2 v2.3.1/go.mod h1:aq2kc6MtYNcn4XmMhobAv6hTNJiHzvD0yXRz80+bnP8= +github.com/pion/ice/v2 v2.3.2 h1:vh+fi4RkZ8H5fB4brZ/jm3j4BqFgMmNs+aB3X52Hu7M= +github.com/pion/ice/v2 v2.3.2/go.mod h1:AMIpuJqcpe+UwloocNebmTSWhCZM1TUCo9v7nW50jX0= github.com/pion/interceptor v0.1.12 h1:CslaNriCFUItiXS5o+hh5lpL0t0ytQkFnUcbbCs2Zq8= github.com/pion/interceptor v0.1.12/go.mod h1:bDtgAD9dRkBZpWHGKaoKb42FhDHTG2rX8Ii9LRALLVA= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -97,8 +97,8 @@ github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI= github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= github.com/pion/udp/v2 v2.0.1 h1:xP0z6WNux1zWEjhC7onRA3EwwSliXqu1ElUZAQhUP54= github.com/pion/udp/v2 v2.0.1/go.mod h1:B7uvTMP00lzWdyMr/1PVZXtV3wpPIxBRd4Wl6AksXn8= -github.com/pion/webrtc/v3 v3.1.58 h1:husXqiKQuk6gbOqJlPHs185OskAyxUW6iAEgHghgCrc= -github.com/pion/webrtc/v3 v3.1.58/go.mod h1:jJdqoqGBlZiE3y8Z1tg1fjSkyEDCZLL+foypUBn0Lhk= +github.com/pion/webrtc/v3 v3.1.59 h1:B3YFo8q6dwBYKA2LUjWRChP59Qtt+xvv1Ul7UPDp6Zc= +github.com/pion/webrtc/v3 v3.1.59/go.mod h1:rJGgStRoFyFOWJULHLayaimsG+jIEoenhJ5MB5gIFqw= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -178,8 +178,9 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/pkg/config/emulator/config.go b/pkg/config/emulator/config.go index 17aaee6d..311cff5d 100644 --- a/pkg/config/emulator/config.go +++ b/pkg/config/emulator/config.go @@ -37,8 +37,7 @@ func (a AspectRatio) ResizeToAspect(ratio float64, sw int, sh int) (dw int, dh i type LibretroConfig struct { Cores struct { Paths struct { - Libs string - Configs string + Libs string } Repo struct { Sync bool @@ -61,12 +60,12 @@ type LibretroRepoConfig struct { type LibretroCoreConfig struct { AltRepo bool AutoGlContext bool // hack: keep it here to pass it down the emulator - Config string Folder string HasMultitap bool Height int IsGlAllowed bool Lib string + Options map[string]string Roms []string UsesLibCo bool VFR bool @@ -83,9 +82,6 @@ func (e Emulator) GetLibretroCoreConfig(emulator string) LibretroCoreConfig { cores := e.Libretro.Cores conf := cores.List[emulator] conf.Lib = path.Join(cores.Paths.Libs, conf.Lib) - if conf.Config != "" { - conf.Config = path.Join(cores.Paths.Configs, conf.Config) - } return conf } diff --git a/pkg/worker/emulator/emulator.go b/pkg/worker/emulator/emulator.go index 11c10e52..32602549 100644 --- a/pkg/worker/emulator/emulator.go +++ b/pkg/worker/emulator/emulator.go @@ -40,11 +40,7 @@ type Emulator interface { } type Metadata struct { - // the full path to some emulator lib - LibPath string - // the full path to the emulator config - ConfigPath string - + LibPath string // the full path to some emulator lib AudioSampleRate int Fps float64 BaseWidth int @@ -55,6 +51,7 @@ type Metadata struct { AutoGlContext bool HasMultitap bool HasVFR bool + Options map[string]string } type ( diff --git a/pkg/worker/emulator/image/canvas_test.go b/pkg/worker/emulator/image/canvas_test.go index 9b076f7d..a7bc47af 100644 --- a/pkg/worker/emulator/image/canvas_test.go +++ b/pkg/worker/emulator/image/canvas_test.go @@ -89,7 +89,7 @@ func Test_ix8888(t *testing.T) { args: args{ dst: new(uint32), px: 0x11223344, - expect: 0xff443322, + expect: 0x00443322, }, }, } diff --git a/pkg/worker/emulator/libretro/frontend.go b/pkg/worker/emulator/libretro/frontend.go index 9a7e4d7e..d904d13d 100644 --- a/pkg/worker/emulator/libretro/frontend.go +++ b/pkg/worker/emulator/libretro/frontend.go @@ -106,16 +106,17 @@ func NewFrontend(conf conf.Emulator, log *logger.Logger) (*Frontend, error) { func (f *Frontend) LoadMetadata(emu string) { config := f.conf.GetLibretroCoreConfig(emu) - f.mu.Lock() - coreLoad(emulator.Metadata{ + meta := emulator.Metadata{ AutoGlContext: config.AutoGlContext, - ConfigPath: config.Config, HasMultitap: config.HasMultitap, HasVFR: config.VFR, IsGlAllowed: config.IsGlAllowed, LibPath: config.Lib, + Options: config.Options, UsesLibCo: config.UsesLibCo, - }) + } + f.mu.Lock() + coreLoad(meta) f.mu.Unlock() } diff --git a/pkg/worker/emulator/libretro/manager/remotehttp/manager.go b/pkg/worker/emulator/libretro/manager/remotehttp/manager.go index 90216acc..fe214a31 100644 --- a/pkg/worker/emulator/libretro/manager/remotehttp/manager.go +++ b/pkg/worker/emulator/libretro/manager/remotehttp/manager.go @@ -63,7 +63,7 @@ func CheckCores(conf emulator.Emulator, log *logger.Logger) error { coreManager := NewRemoteHttpManager(conf.Libretro, log) // make a dir for cores dir := coreManager.Conf.GetCoresStorePath() - if err := os.MkdirAll(dir, os.ModeDir); err != nil { + if err := os.MkdirAll(dir, os.ModeDir|os.ModePerm); err != nil { return err } if err := coreManager.Sync(); err != nil { diff --git a/pkg/worker/emulator/libretro/nanoarch.go b/pkg/worker/emulator/libretro/nanoarch.go index 5a7303e8..a45c87dc 100644 --- a/pkg/worker/emulator/libretro/nanoarch.go +++ b/pkg/worker/emulator/libretro/nanoarch.go @@ -31,6 +31,7 @@ const lastKey = int(C.RETRO_DEVICE_ID_JOYPAD_R3) type ( nanoarch struct { + opts CoreOptions v video multitap multitap rot *image.Rotate @@ -58,6 +59,25 @@ type ( } ) +type CoreOptions struct{ KV map[string]*C.char } + +func NewCoreOptions(m *map[string]string) CoreOptions { + if m == nil { + return CoreOptions{} + } + opts := CoreOptions{KV: make(map[string]*C.char, len(*m))} + for k, v := range *m { + opts.KV[k] = C.CString(v) + } + return opts +} + +func (c *CoreOptions) Free() { + for _, v := range c.KV { + C.free(unsafe.Pointer(v)) + } +} + // Global link for C callbacks to Go var nano = nanoarch{ // this thing forbids concurrent use of the emulator @@ -65,7 +85,6 @@ var nano = nanoarch{ } var ( - coreConfig *CoreProperties frontend *Frontend lastFrameTime int64 libretroLogger = logger.Default() @@ -309,8 +328,8 @@ func coreEnvironment(cmd C.unsigned, data unsafe.Pointer) C.bool { case C.RETRO_ENVIRONMENT_GET_VARIABLE: variable := (*C.struct_retro_variable)(data) key := C.GoString(variable.key) - if val, ok := coreConfig.Get(key); ok { - variable.value = (*C.char)(val) + if val, ok := nano.opts.KV[key]; ok { + variable.value = val libretroLogger.Debug().Msgf("Set %s=%v", key, C.GoString(variable.value)) return true } @@ -440,10 +459,8 @@ func coreLoad(meta emulator.Metadata) { usesLibCo = meta.UsesLibCo nano.v.autoGlContext = meta.AutoGlContext hasVFR = meta.HasVFR - coreConfig, err = ReadProperties(meta.ConfigPath) - if err != nil { - libretroLogger.Warn().Err(err).Msg("config scan has been failed") - } + + nano.opts = NewCoreOptions(&meta.Options) nano.multitap.supported = meta.HasMultitap nano.multitap.enabled = false @@ -613,7 +630,7 @@ func nanoarchShutdown() { if err := closeLib(coreLib); err != nil { libretroLogger.Error().Err(err).Msg("lib close failed") } - coreConfig.Free() + nano.opts.Free() } func run() { diff --git a/pkg/worker/emulator/libretro/nanoarch_test.go b/pkg/worker/emulator/libretro/nanoarch_test.go index 6a625ee1..ee6d317f 100644 --- a/pkg/worker/emulator/libretro/nanoarch_test.go +++ b/pkg/worker/emulator/libretro/nanoarch_test.go @@ -58,7 +58,8 @@ func GetEmulatorMock(room string, system string) *EmulatorMock { meta := conf.Emulator.GetLibretroCoreConfig(system) l := logger.Default() - SetLibretroLogger(l.Extend(l.Level(logger.ErrorLevel).With())) + l2 := l.Extend(l.Level(logger.ErrorLevel).With()) + SetLibretroLogger(l2) // an emu emu := &EmulatorMock{ @@ -71,6 +72,7 @@ func GetEmulatorMock(room string, system string) *EmulatorMock { input: NewGameSessionInput(), done: make(chan struct{}), th: conf.Emulator.Threads, + log: l2, }, core: path.Base(meta.Lib), diff --git a/pkg/worker/emulator/libretro/properties.go b/pkg/worker/emulator/libretro/properties.go deleted file mode 100644 index 7d8580cf..00000000 --- a/pkg/worker/emulator/libretro/properties.go +++ /dev/null @@ -1,71 +0,0 @@ -package libretro - -import ( - "bufio" - "fmt" - "os" - "strings" - "sync" - "unsafe" -) - -// #include -import "C" - -type CoreProperties struct { - m map[string]*C.char - mu sync.Mutex -} - -func ReadProperties(filename string) (*CoreProperties, error) { - config := CoreProperties{ - m: make(map[string]*C.char), - } - - if len(filename) == 0 { - return &config, nil - } - - file, err := os.Open(filename) - if err != nil { - return &config, fmt.Errorf("couldn't find the %v config file", filename) - } - defer func() { - _ = file.Close() - }() - - scanner := bufio.NewScanner(file) - config.mu.Lock() - defer config.mu.Unlock() - for scanner.Scan() { - line := scanner.Text() - if equal := strings.Index(line, "="); equal >= 0 { - if key := strings.TrimSpace(line[:equal]); len(key) > 0 { - value := "" - if len(line) > equal { - value = strings.TrimSpace(line[equal+1:]) - } - config.m[key] = C.CString(value) - } - } - } - if err := scanner.Err(); err != nil { - panic(err) - } - return &config, nil -} - -func (c *CoreProperties) Get(key string) (*C.char, bool) { - c.mu.Lock() - defer c.mu.Unlock() - v, ok := c.m[key] - return v, ok -} - -func (c *CoreProperties) Free() { - c.mu.Lock() - for _, element := range c.m { - C.free(unsafe.Pointer(element)) - } - c.mu.Unlock() -} diff --git a/pkg/worker/room_test.go b/pkg/worker/room_test.go index 810c9d4f..374fa468 100644 --- a/pkg/worker/room_test.go +++ b/pkg/worker/room_test.go @@ -217,9 +217,8 @@ func getRoomMock(cfg roomMockConfig) roomMock { } // sync cores - coreManager := remotehttp.NewRemoteHttpManager(conf.Emulator.Libretro, l) - if err := coreManager.Sync(); err != nil { - log.Printf("error: cores sync has failed, %v", err) + if err := remotehttp.CheckCores(conf.Emulator, l); err != nil { + l.Error().Err(err).Msg("cores sync error") } conf.Encoder.Video.Codec = string(cfg.vCodec) @@ -255,8 +254,6 @@ func fixEmulators(config *worker.Config, autoGlContext bool) { config.Emulator.Libretro.Cores.Paths.Libs = filepath.FromSlash(rootPath + config.Emulator.Libretro.Cores.Paths.Libs) - config.Emulator.Libretro.Cores.Paths.Configs = - filepath.FromSlash(rootPath + config.Emulator.Libretro.Cores.Paths.Configs) config.Emulator.LocalPath = filepath.FromSlash(filepath.Join(rootPath, "tests", config.Emulator.LocalPath)) config.Emulator.Storage = filepath.FromSlash(filepath.Join(rootPath, "tests", "storage"))