diff --git a/.ci/scripts/android/build.sh b/.ci/scripts/android/build.sh
index 935919b6de..885ebfee4c 100755
--- a/.ci/scripts/android/build.sh
+++ b/.ci/scripts/android/build.sh
@@ -7,6 +7,8 @@
export NDK_CCACHE="$(which ccache)"
ccache -s
+git submodule update --init --recursive
+
BUILD_FLAVOR="mainline"
BUILD_TYPE="release"
diff --git a/.ci/scripts/clang/docker.sh b/.ci/scripts/clang/docker.sh
index 57fbb97544..d59f672087 100755
--- a/.ci/scripts/clang/docker.sh
+++ b/.ci/scripts/clang/docker.sh
@@ -7,7 +7,9 @@
# Exit on error, rather than continuing with the rest of the script.
set -e
-ccache -sv
+ccache -s
+
+git submodule update --init --recursive
mkdir build || true && cd build
cmake .. \
diff --git a/.ci/scripts/linux/docker.sh b/.ci/scripts/linux/docker.sh
index 82432bd835..9854429257 100755
--- a/.ci/scripts/linux/docker.sh
+++ b/.ci/scripts/linux/docker.sh
@@ -6,7 +6,9 @@
# Exit on error, rather than continuing with the rest of the script.
set -e
-ccache -sv
+ccache -s
+
+git submodule update --init --recursive
mkdir build || true && cd build
cmake .. \
@@ -52,9 +54,9 @@ DESTDIR="$PWD/AppDir" ninja install
rm -vf AppDir/usr/bin/suyu-cmd AppDir/usr/bin/suyu-tester
# Download tools needed to build an AppImage
-wget -nc https://gitlab.com/suyu-emu/ext-linux-bin/-/raw/main/appimage/deploy-linux.sh
-wget -nc https://gitlab.com/suyu-emu/ext-linux-bin/-/raw/main/appimage/exec-x86_64.so
-wget -nc https://gitlab.com/suyu-emu/AppImageKit-checkrt/-/raw/old/AppRun.sh
+wget -nc https://git.suyu.dev/suyu/ext-linux-bin/raw/branch/main/appimage/deploy-linux.sh
+wget -nc https://git.suyu.dev/suyu/ext-linux-bin/raw/branch/main/appimage/exec-x86_64.so
+wget -nc https://git.suyu.dev/suyu/AppImageKit-checkrt/raw/branch/gh-workflow/AppRun
# Set executable bit
chmod 755 \
diff --git a/.ci/scripts/linux/upload.sh b/.ci/scripts/linux/upload.sh
index 392106bcd2..0e383fd059 100755
--- a/.ci/scripts/linux/upload.sh
+++ b/.ci/scripts/linux/upload.sh
@@ -37,7 +37,7 @@ fi
# Don't let AppImageLauncher ask to integrate EA
if [ "${RELEASE_NAME}" = "mainline" ] || [ "${RELEASE_NAME}" = "early-access" ]; then
- echo "X-AppImage-Integrate=false" >> AppDir/org.suyu_emu.suyu.desktop
+ echo "X-AppImage-Integrate=false" >> AppDir/dev.suyu_emu.suyu.desktop
fi
if [ "${RELEASE_NAME}" = "mainline" ]; then
diff --git a/.ci/scripts/windows/docker.sh b/.ci/scripts/windows/docker.sh
index 70eadda41e..ba40e5dbbb 100755
--- a/.ci/scripts/windows/docker.sh
+++ b/.ci/scripts/windows/docker.sh
@@ -1,20 +1,26 @@
#!/bin/bash -ex
# SPDX-FileCopyrightText: 2019 yuzu Emulator Project
+# SPDX-FileCopyrightText: 2024 suyu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
set -e
#cd /suyu
-ccache -sv
+ccache -s
+git submodule update --init --recursive
+
+rm -rf build
mkdir -p build && cd build
-cmake .. \
+/usr/bin/x86_64-w64-mingw32-cmake .. \
-DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_TOOLCHAIN_FILE="${PWD}/../CMakeModules/MinGWCross.cmake" \
-DDISPLAY_VERSION="$1" \
- -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
+ -DDYNARMIC_USE_PRECOMPILED_HEADERS=OFF \
+ -DSUYU_USE_PRECOMPILED_HEADERS=OFF \
+ -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=OFF \
+ -DUSE_DISCORD_PRESENCE=ON \
-DENABLE_QT_TRANSLATION=ON \
-DUSE_CCACHE=ON \
-DSUYU_USE_BUNDLED_SDL2=OFF \
diff --git a/.forgejo/ISSUE_TEMPLATE/config.yml b/.forgejo/ISSUE_TEMPLATE/config.yml
index 0be63fdb7a..1a365db1a9 100644
--- a/.forgejo/ISSUE_TEMPLATE/config.yml
+++ b/.forgejo/ISSUE_TEMPLATE/config.yml
@@ -1,5 +1,5 @@
blank_issues_enabled: false
contact_links:
- - name: suyu Discord
- url: https://discord.com/invite/suyu
- about: If you are experiencing an issue with suyu, and you need tech support, or if you have a general question, try asking in the official suyu Discord linked here. Piracy is not allowed.
+ - name: suyu chat
+ url: https://chat.suyu.dev/
+ about: If you are experiencing an issue with suyu, and you need tech support, or if you have a general question, try asking in the official suyu chat linked here. Piracy is not allowed.
diff --git a/.forgejo/workflows/codespell.yml b/.forgejo/workflows/codespell.yml
index d711137d3a..951e1583ef 100644
--- a/.forgejo/workflows/codespell.yml
+++ b/.forgejo/workflows/codespell.yml
@@ -20,7 +20,7 @@ permissions: {}
jobs:
codespell:
name: Check for spelling errors
- runs-on: verify
+ runs-on: docker
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
with:
diff --git a/.forgejo/workflows/reuse.yml b/.forgejo/workflows/reuse.yml
index 39bbbdf2c6..ba2fe448b5 100644
--- a/.forgejo/workflows/reuse.yml
+++ b/.forgejo/workflows/reuse.yml
@@ -30,7 +30,7 @@ jobs:
reuse:
name: Check REUSE Specification
- runs-on: verify
+ runs-on: docker
if: ${{ github.repository == 'suyu/suyu' }}
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
diff --git a/.forgejo/workflows/verify.yml b/.forgejo/workflows/verify.yml
index 61a6fdf1f5..3eb8682435 100644
--- a/.forgejo/workflows/verify.yml
+++ b/.forgejo/workflows/verify.yml
@@ -4,214 +4,214 @@
# Actions Documentation: https://forgejo.org/docs/next/user/actions/#list-of-tasks-in-a-repository
-name: 'suyu verify'
+name: "suyu verify"
on:
- pull_request:
- branches: [ "dev" ]
- paths:
- - 'src/**'
- - 'CMakeModules/**'
- - 'dist/**'
- - 'externals/**'
- - 'CMakeLists.txt'
- - 'vcpkg.json'
- # paths-ignore:
- # - 'src/android/**'
- push:
- branches: [ "dev", "metal-dev" ]
- paths:
- - 'src/**'
- - 'CMakeModules/**'
- - 'dist/**'
- - 'externals/**'
- - 'CMakeLists.txt'
- - 'vcpkg.json'
- - '.forgejo/workflows/verify.yml'
- - '.ci/**'
- # paths-ignore:
- # - 'src/android/**'
+ pull_request:
+ # branches: [ "dev" ]
+ paths:
+ - "src/**"
+ - "CMakeModules/**"
+ - "dist/**"
+ - "externals/**"
+ - "CMakeLists.txt"
+ - "vcpkg.json"
+ # paths-ignore:
+ # - 'src/android/**'
+ push:
+ branches: ["dev", "metal-dev"]
+ paths:
+ - "src/**"
+ - "CMakeModules/**"
+ - "dist/**"
+ - "externals/**"
+ - "CMakeLists.txt"
+ - "vcpkg.json"
+ - ".forgejo/workflows/verify.yml"
+ - ".ci/**"
+ # paths-ignore:
+ # - 'src/android/**'
env:
- PR_NUMBER: pr${{ github.event.number }}
+ PR_NUMBER: pr${{ github.event.number }}
jobs:
- format:
- name: 'Verify Format'
- runs-on: ubuntu-latest
- container: fijxu/build-environments:linux-clang-format
- steps:
- - uses: https://code.forgejo.org/actions/checkout@v3
- with:
- submodules: false
- # - name: set up JDK 17
- # uses: https://github.com/actions/setup-java@v3
- # with:
- # java-version: '17'
- # distribution: 'temurin'
- - name: 'Verify Formatting'
- run: bash -ex ./.ci/scripts/format/script.sh
- build-linux:
- name: 'test build'
- needs: format
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- include:
- - type: clang
- image: linux-fresh
- - type: linux
- image: linux-fresh
- # - type: windows
- # image: linux-mingw
- container: fijxu/build-environments:${{ matrix.image }}
- # User 1001 doesn't exists on the images.
- # options: -u 1001
- steps:
- - uses: https://code.forgejo.org/actions/checkout@v3
- with:
- submodules: recursive
- fetch-depth: 0
- - name: Set up cache
- uses: https://code.forgejo.org/actions/cache@v3
- id: ccache-restore
- with:
- path: ~/.ccache
- key: ${{ runner.os }}-${{ matrix.type }}-${{ github.sha }}
- restore-keys: |
- ${{ runner.os }}-${{ matrix.type }}-
- - name: Create ccache directory
- if: steps.ccache-restore.outputs.cache-hit != 'true'
- run: mkdir -p ~/.ccache
- - name: Build
- run: ./.ci/scripts/${{ matrix.type }}/docker.sh
- env:
- ENABLE_COMPATIBILITY_REPORTING: "ON"
- - name: Pack
- run: ./.ci/scripts/${{ matrix.type }}/upload.sh
- env:
- NO_SOURCE_PACK: "YES"
- - name: Upload
- uses: https://code.forgejo.org/actions/upload-artifact@v3
- with:
- name: ${{ matrix.type }}
- path: artifacts/
- # build-mac:
- # name: 'test build (macos)'
- # needs: format
- # runs-on: macos-14
- # steps:
- # - uses: https://code.forgejo.org/actions/checkout@v3
- # with:
- # submodules: recursive
- # fetch-depth: 0
- # - name: Install dependencies
- # run: |
- # brew install autoconf automake boost ccache ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@5 sdl2 speexdsp zlib zlib zstd
- # - name: Build
- # run: |
- # mkdir build
- # cd build
- # export Qt5_DIR="$(brew --prefix qt@5)/lib/cmake"
- # cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DSUYU_USE_BUNDLED_VCPKG=OFF -DSUYU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF
- # ninja
- # build-msvc:
- # name: 'test build (windows, msvc)'
- # needs: format
- # runs-on: windows-2022
- # steps:
- # - uses: https://code.forgejo.org/actions/checkout@v3
- # with:
- # submodules: recursive
- # fetch-depth: 0
- # - name: Set up cache
- # uses: https://code.forgejo.org/actions/cache@v3
- # with:
- # path: ~/.buildcache
- # key: ${{ runner.os }}-msvc-${{ github.sha }}
- # restore-keys: |
- # ${{ runner.os }}-msvc-
- # - name: Install dependencies
- # shell: pwsh
- # run: |
- # $ErrorActionPreference = "Stop"
- # $BuildCacheVer = "v0.28.4"
- # $File = "buildcache-windows.zip"
- # $Uri = "https://github.com/mbitsnbites/buildcache/releases/download/$BuildCacheVer/$File"
- # $WebClient = New-Object System.Net.WebClient
- # $WebClient.DownloadFile($Uri, $File)
- # 7z x $File
- # $CurrentDir = Convert-Path .
- # echo "$CurrentDir/buildcache/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- # - name: Install Vulkan SDK
- # shell: pwsh
- # run: .\.ci\scripts\windows\install-vulkan-sdk.ps1
- # - name: Set up MSVC
- # uses: https://github.com/ilammy/msvc-dev-cmd@v1
- # - name: Configure
- # env:
- # CC: cl.exe
- # CXX: cl.exe
- # run: |
- # glslangValidator --version
- # mkdir build
- # cmake . -B build -GNinja -DCMAKE_TOOLCHAIN_FILE="CMakeModules/MSVCCache.cmake" -DUSE_CCACHE=ON -DSUYU_USE_BUNDLED_QT=1 -DSUYU_USE_BUNDLED_SDL2=1 -DSUYU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DSUYU_ENABLE_COMPATIBILITY_REPORTING=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DGIT_BRANCH=pr-verify -DSUYU_CRASH_DUMPS=ON
- # - name: Build
- # run: cmake --build build
- # - name: Cache Summary
- # run: buildcache -s
- # - name: Pack
- # shell: pwsh
- # run: .\.ci\scripts\windows\upload.ps1
- # - name: Upload
- # uses: https://code.forgejo.org/actions/upload-artifact@v3
- # with:
- # name: msvc
- # path: artifacts/
- # - name: Upload EXE
- # uses: https://code.forgejo.org/actions/upload-artifact@v3
- # with:
- # name: ${{ env.INDIVIDUAL_EXE }}
- # path: ${{ env.INDIVIDUAL_EXE }}
- android:
- runs-on: ubuntu-latest
- container: fijxu/build-environments:android
- needs: format
- steps:
- - uses: https://code.forgejo.org/actions/checkout@v3
- with:
- submodules: recursive
- fetch-depth: 0
- - name: set up JDK 17
- uses: https://github.com/actions/setup-java@v3
- with:
- java-version: '17'
- distribution: 'temurin'
- - name: Set up cache
- uses: https://code.forgejo.org/actions/cache@v3
- with:
- path: |
- ~/.gradle/caches
- ~/.gradle/wrapper
- ~/.ccache
- key: ${{ runner.os }}-android-${{ github.sha }}
- restore-keys: |
- ${{ runner.os }}-android-
- - name: Query tag name
- uses: https://github.com/olegtarasov/get-tag@v2.1.2
- id: tagName
- - name: Build
- run: ./.ci/scripts/android/build.sh
- - name: Copy and sign artifacts
- env:
- ANDROID_KEYSTORE_B64: ${{ secrets.ANDROID_KEYSTORE_B64 }}
- ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
- ANDROID_KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }}
- run: ./.ci/scripts/android/upload.sh
- - name: Upload
- uses: https://code.forgejo.org/actions/upload-artifact@v3
- with:
- name: android
- path: artifacts/
-
+ format:
+ name: "Verify Format"
+ runs-on: docker
+ container: fijxu/build-environments:linux-clang-format
+ steps:
+ - uses: https://code.forgejo.org/actions/checkout@v3
+ with:
+ submodules: false
+ # - name: set up JDK 17
+ # uses: https://github.com/actions/setup-java@v3
+ # with:
+ # java-version: '17'
+ # distribution: 'temurin'
+ - name: "Verify Formatting"
+ run: bash -ex ./.ci/scripts/format/script.sh
+ build-linux:
+ name: "test build"
+ needs: format
+ runs-on: docker
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - type: clang
+ image: linux-fresh
+ - type: linux
+ image: linux-fresh
+ - type: windows
+ image: linux-mingw
+ container:
+ fijxu/build-environments:${{ matrix.image }}
+ # User 1001 doesn't exists on the images.
+ # options: -u 1001
+ steps:
+ - uses: https://code.forgejo.org/actions/checkout@v3
+ with:
+ submodules: recursive
+ fetch-depth: 0
+ - name: Set up cache
+ uses: https://code.forgejo.org/actions/cache@v3
+ id: ccache-restore
+ with:
+ path: ~/.ccache
+ key: ${{ runner.os }}-${{ matrix.type }}-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-${{ matrix.type }}-
+ - name: Create ccache directory
+ if: steps.ccache-restore.outputs.cache-hit != 'true'
+ run: mkdir -p ~/.ccache
+ - name: Build
+ run: ./.ci/scripts/${{ matrix.type }}/docker.sh
+ env:
+ ENABLE_COMPATIBILITY_REPORTING: "ON"
+ - name: Pack
+ run: ./.ci/scripts/${{ matrix.type }}/upload.sh
+ env:
+ NO_SOURCE_PACK: "YES"
+ - name: Upload
+ uses: https://code.forgejo.org/actions/upload-artifact@v3
+ with:
+ name: ${{ matrix.type }}
+ path: artifacts/
+ # build-mac:
+ # name: 'test build (macos)'
+ # needs: format
+ # runs-on: macos-14
+ # steps:
+ # - uses: https://code.forgejo.org/actions/checkout@v3
+ # with:
+ # submodules: recursive
+ # fetch-depth: 0
+ # - name: Install dependencies
+ # run: |
+ # brew install autoconf automake boost ccache ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@5 sdl2 speexdsp zlib zlib zstd
+ # - name: Build
+ # run: |
+ # mkdir build
+ # cd build
+ # export Qt5_DIR="$(brew --prefix qt@5)/lib/cmake"
+ # cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DSUYU_USE_BUNDLED_VCPKG=OFF -DSUYU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF
+ # ninja
+ # build-msvc:
+ # name: 'test build (windows, msvc)'
+ # needs: format
+ # runs-on: windows-2022
+ # steps:
+ # - uses: https://code.forgejo.org/actions/checkout@v3
+ # with:
+ # submodules: recursive
+ # fetch-depth: 0
+ # - name: Set up cache
+ # uses: https://code.forgejo.org/actions/cache@v3
+ # with:
+ # path: ~/.buildcache
+ # key: ${{ runner.os }}-msvc-${{ github.sha }}
+ # restore-keys: |
+ # ${{ runner.os }}-msvc-
+ # - name: Install dependencies
+ # shell: pwsh
+ # run: |
+ # $ErrorActionPreference = "Stop"
+ # $BuildCacheVer = "v0.28.4"
+ # $File = "buildcache-windows.zip"
+ # $Uri = "https://github.com/mbitsnbites/buildcache/releases/download/$BuildCacheVer/$File"
+ # $WebClient = New-Object System.Net.WebClient
+ # $WebClient.DownloadFile($Uri, $File)
+ # 7z x $File
+ # $CurrentDir = Convert-Path .
+ # echo "$CurrentDir/buildcache/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+ # - name: Install Vulkan SDK
+ # shell: pwsh
+ # run: .\.ci\scripts\windows\install-vulkan-sdk.ps1
+ # - name: Set up MSVC
+ # uses: https://github.com/ilammy/msvc-dev-cmd@v1
+ # - name: Configure
+ # env:
+ # CC: cl.exe
+ # CXX: cl.exe
+ # run: |
+ # glslangValidator --version
+ # mkdir build
+ # cmake . -B build -GNinja -DCMAKE_TOOLCHAIN_FILE="CMakeModules/MSVCCache.cmake" -DUSE_CCACHE=ON -DSUYU_USE_BUNDLED_QT=1 -DSUYU_USE_BUNDLED_SDL2=1 -DSUYU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DSUYU_ENABLE_COMPATIBILITY_REPORTING=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DGIT_BRANCH=pr-verify -DSUYU_CRASH_DUMPS=ON
+ # - name: Build
+ # run: cmake --build build
+ # - name: Cache Summary
+ # run: buildcache -s
+ # - name: Pack
+ # shell: pwsh
+ # run: .\.ci\scripts\windows\upload.ps1
+ # - name: Upload
+ # uses: https://code.forgejo.org/actions/upload-artifact@v3
+ # with:
+ # name: msvc
+ # path: artifacts/
+ # - name: Upload EXE
+ # uses: https://code.forgejo.org/actions/upload-artifact@v3
+ # with:
+ # name: ${{ env.INDIVIDUAL_EXE }}
+ # path: ${{ env.INDIVIDUAL_EXE }}
+ android:
+ runs-on: docker
+ container: fijxu/build-environments:android
+ needs: format
+ steps:
+ - uses: https://code.forgejo.org/actions/checkout@v3
+ with:
+ submodules: recursive
+ fetch-depth: 0
+ - name: set up JDK 17
+ uses: https://github.com/actions/setup-java@v3
+ with:
+ java-version: "17"
+ distribution: "temurin"
+ - name: Set up cache
+ uses: https://code.forgejo.org/actions/cache@v3
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ ~/.ccache
+ key: ${{ runner.os }}-android-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-android-
+ - name: Query tag name
+ uses: https://github.com/olegtarasov/get-tag@v2.1.2
+ id: tagName
+ - name: Build
+ run: ./.ci/scripts/android/build.sh
+ - name: Copy and sign artifacts
+ env:
+ ANDROID_KEYSTORE_B64: ${{ secrets.ANDROID_KEYSTORE_B64 }}
+ ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
+ ANDROID_KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }}
+ run: ./.ci/scripts/android/upload.sh
+ - name: Upload
+ uses: https://code.forgejo.org/actions/upload-artifact@v3
+ with:
+ name: android
+ path: artifacts/
diff --git a/.gitea/ISSUE_TEMPLATE/config.yml b/.gitea/ISSUE_TEMPLATE/config.yml
index 0be63fdb7a..1a365db1a9 100644
--- a/.gitea/ISSUE_TEMPLATE/config.yml
+++ b/.gitea/ISSUE_TEMPLATE/config.yml
@@ -1,5 +1,5 @@
blank_issues_enabled: false
contact_links:
- - name: suyu Discord
- url: https://discord.com/invite/suyu
- about: If you are experiencing an issue with suyu, and you need tech support, or if you have a general question, try asking in the official suyu Discord linked here. Piracy is not allowed.
+ - name: suyu chat
+ url: https://chat.suyu.dev/
+ about: If you are experiencing an issue with suyu, and you need tech support, or if you have a general question, try asking in the official suyu chat linked here. Piracy is not allowed.
diff --git a/.reuse/dep5 b/.reuse/dep5
index baf1354bf6..9779726e3f 100644
--- a/.reuse/dep5
+++ b/.reuse/dep5
@@ -5,10 +5,13 @@ Comment: It is best to use this file to record copyright information about
Files: dist/english_plurals/*
dist/icons/controller/*.png
dist/icons/overlay/*.png
+ dist/icons/overlay_dark/*.png
dist/languages/*
dist/qt_themes/*/icons/48x48/sd_card.png
dist/qt_themes/*/icons/index.theme
dist/qt_themes/default/style.qss
+ dist/qt_themes/*/icons.qrc
+ dist/qt_themes/*/style.qrc
Copyright: yuzu Emulator Project
suyu Emulator Project
License: GPL-2.0-or-later
@@ -22,8 +25,7 @@ Copyright: suyu Emulator Project
License: GPL-2.0-or-later
Files: dist/qt_themes/qdarkstyle*/LICENSE.*
- dist/qt_themes/qdarkstyle*/style.qrc
- dist/qt_themes/qdarkstyle*/style.qss
+ dist/qt_themes/qdarkstyle*/dark.qss
Copyright: 2013 Colin Duquesnoy
2019 Daniel Cosmo Pizetta
License: MIT
@@ -33,28 +35,28 @@ Copyright: 2013 Colin Duquesnoy
2019 Daniel Cosmo Pizetta
License: CC-BY-4.0
-Files: dist/qt_themes/default/icons/256x256/plus_folder.png
- dist/qt_themes/default/icons/48x48/bad_folder.png
- dist/qt_themes/default/icons/48x48/chip.png
- dist/qt_themes/default/icons/48x48/folder.png
- dist/qt_themes/default/icons/48x48/star.png
- dist/qt_themes/qdarkstyle/icons/256x256/plus_folder.png
- dist/qt_themes/qdarkstyle/icons/48x48/bad_folder.png
- dist/qt_themes/qdarkstyle/icons/48x48/chip.png
- dist/qt_themes/qdarkstyle/icons/48x48/folder.png
- dist/qt_themes/qdarkstyle/icons/48x48/star.png
+Files: dist/qt_themes/monochrome/icons/256x256/plus_folder.png
+ dist/qt_themes/monochrome/icons/48x48/bad_folder.png
+ dist/qt_themes/monochrome/icons/48x48/chip.png
+ dist/qt_themes/monochrome/icons/48x48/folder.png
+ dist/qt_themes/monochrome/icons/48x48/star.png
+ dist/qt_themes/monochrome_dark/icons/48x48/bad_folder.png
+ dist/qt_themes/monochrome_dark/icons/48x48/chip.png
+ dist/qt_themes/monochrome_dark/icons/48x48/folder.png
+ dist/qt_themes/monochrome_dark/icons/48x48/star.png
+ dist/qt_themes/monochrome_dark/icons/256x256/plus_folder.png
Copyright: Refactoring UI Inc.
License: MIT
Comment: https://github.com/tailwindlabs/heroicons
-Files: dist/qt_themes/colorful/icons/16x16/lock.png
- dist/qt_themes/colorful/icons/256x256/plus_folder.png
- dist/qt_themes/colorful/icons/48x48/bad_folder.png
- dist/qt_themes/colorful/icons/48x48/chip.png
- dist/qt_themes/colorful/icons/48x48/folder.png
- dist/qt_themes/colorful_dark/icons/16x16/lock.png
- dist/qt_themes/colorful/icons/16x16/info.png
- dist/qt_themes/colorful/icons/16x16/sync.png
+Files: dist/qt_themes/default/icons/16x16/lock.png
+ dist/qt_themes/default/icons/256x256/plus_folder.png
+ dist/qt_themes/default/icons/48x48/bad_folder.png
+ dist/qt_themes/default/icons/48x48/chip.png
+ dist/qt_themes/default/icons/48x48/folder.png
+ dist/qt_themes/default_dark/icons/16x16/lock.png
+ dist/qt_themes/default/icons/16x16/info.png
+ dist/qt_themes/default/icons/16x16/sync.png
Copyright: Icons8
License: MIT
Comment: https://github.com/icons8/flat-color-icons
@@ -70,15 +72,15 @@ Files: dist/qt_themes/*/icons/48x48/no_avatar.png
Copyright: Ionic (http://ionic.io/)
License: MIT
-Files: dist/qt_themes/colorful/icons/48x48/star.png
- dist/qt_themes/colorful/icons/16x16/checked.png
- dist/qt_themes/colorful/icons/16x16/failed.png
+Files: dist/qt_themes/default/icons/48x48/star.png
+ dist/qt_themes/default/icons/16x16/checked.png
+ dist/qt_themes/default/icons/16x16/failed.png
Copyright: SVG Repo
License: CC0-1.0
Files: dist/qt_themes/*/icons/16x16/view-refresh.png
- dist/qt_themes/default/icons/16x16/lock.png
- dist/qt_themes/qdarkstyle/icons/16x16/lock.png
+ dist/qt_themes/monochrome/icons/16x16/lock.png
+ dist/qt_themes/monochrome_dark/icons/16x16/lock.png
Copyright: Google, Inc.
License: Apache-2.0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9406dd64a1..cbeb2ee689 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -732,14 +732,14 @@ endif()
# https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html
# https://www.freedesktop.org/software/appstream/docs/
if(ENABLE_QT AND UNIX AND NOT APPLE)
- install(FILES "dist/org.suyu_emu.suyu.desktop"
+ install(FILES "dist/dev.suyu_emu.suyu.desktop"
DESTINATION "share/applications")
install(FILES "dist/suyu.svg"
DESTINATION "share/icons/hicolor/scalable/apps"
- RENAME "org.suyu_emu.suyu.svg")
- install(FILES "dist/org.suyu_emu.suyu.xml"
+ RENAME "dev.suyu_emu.suyu.svg")
+ install(FILES "dist/dev.suyu_emu.suyu.xml"
DESTINATION "share/mime/packages")
- install(FILES "dist/org.suyu_emu.suyu.metainfo.xml"
+ install(FILES "dist/dev.suyu_emu.suyu.metainfo.xml"
DESTINATION "share/metainfo")
endif()
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b2bb3f0c76..1ff49d5b1f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -6,5 +6,5 @@ SPDX-License-Identifier: GPL-2.0-or-later
Please check out the
- * [Contributors's guide](https://gitlab.com/suyu-emu/suyu/-/wikis/Contributing).
- * [Merge request guidelines](https://gitlab.com/suyu-emu/suyu/-/wikis/Merge-requests)
+ * [Contributors's guide](https://git.suyu.dev/suyu/suyu/wiki/Contributing).
+ * [Merge request guidelines](https://git.suyu.dev/suyu/suyu/wiki/Typical-Git-Workflow#once-your-pull-request-is-ready-to-be-merged)
diff --git a/MIGRATION.md b/MIGRATION.md
new file mode 100644
index 0000000000..3963b5004f
--- /dev/null
+++ b/MIGRATION.md
@@ -0,0 +1,25 @@
+
+# Migrating from yuzu
+
+When coming from yuzu, the migration is as easy as renaming some directories.
+
+## Windows
+
+Use the run dialog to go to `%APPDATA%` or manually go to `C:\Users\{USERNAME}\AppData\Roaming` (you may have to enable hidden files) and simply rename the `yuzu` directories and simply rename those to `suyu`.
+
+## Unix (macOS/Linux)
+Similarly, you can simply rename the folders `~/.local/share/yuzu` and `~/.config/yuzu` to `suyu`, either via a file manager or with the following commands:
+```sh
+ $ mv ~/.local/share/yuzu ~/.local/share/suyu
+ $ mv ~/.config/yuzu ~/.config/suyu
+```
+There is also `~/.cache/yuzu`, which you can safely delete. Suyu will build a fresh cache in its own directory.
+
+### Linux
+Depending on your setup, you may want to substitute those base paths for `$XDG_DATA_HOME` and `$XDG_CONFIG_HOME` respectively.
+
+## Android
+TBD
\ No newline at end of file
diff --git a/README.md b/README.md
index 703b475e78..e2cfaa9ded 100644
--- a/README.md
+++ b/README.md
@@ -6,8 +6,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
**Note**: We do not support or condone piracy in any form. In order to use suyu, you'll need keys from your real Switch system, and games which you have legally obtained and paid for. We do not intend to make money or profit from this project.
-We're in need of developers. Please join our Discord server below if you want to contribute!
-This repo is based on Yuzu EA 4176.
+We're in need of developers. Please join our chat below or DM a dev if you want to contribute!
+This repo is currently based on Yuzu EA 4176 but the code will be rewritten for legal and performance reasons.
+
+Our only website is suyu.dev so please be cautious when using other sites offering builds/downloads.
@@ -19,13 +21,15 @@ This repo is based on Yuzu EA 4176.
-
suyu is the continuation of the world's most popular, open-source, Nintendo Switch emulator, yuzu.
+
suyu was the continuation of the world's most popular, open-source Nintendo Switch emulator, yuzu, but is now something more.
-It is written in C++ with portability in mind, and we're actively working on builds for Windows, Linux and Android.
+It is written in C++ with portability in mind, and we actively provide builds for Windows, Linux and Android, iOS may come later.
+
- Discord |
+ Chat |
+ Reddit |
Status |
Development |
Downloads |
@@ -38,6 +42,10 @@ It is written in C++ with portability in mind, and we're actively working on bui
## Hardware Requirements
[Click here to see the Hardware Requirements](https://git.suyu.dev/suyu/suyu/wiki/Hardware-Requirements)
+## Migrating from yuzu
+
+See [MIGRATION.md](MIGRATION.md).
+
## Status
We currently have builds over at the [Releases](https://git.suyu.dev/suyu/suyu/releases) page.
@@ -48,10 +56,10 @@ We currently have builds over at the [Releases](https://git.suyu.dev/suyu/suyu/r
This project is completely free and open source, and anyone can contribute to help improve suyu.
-Most of the development happens on GitLab. For development discussion, please join us on [Discord](https://discord.gg/suyu).
+Most of the development happens on Git. For development discussion, please join us in our [Chat](https://chat.suyu.dev) or [Subreddit](reddit.com/r/suyu/), you can also contact a developer.
If you want to contribute, please take a look at the [Contributor's Guide](https://git.suyu.dev/suyu/suyu/wiki/Contributing) and [Developer Information](https://git.suyu.dev/suyu/suyu/wiki/Developer-Information).
-You can also contact any of the developers on Discord to learn more about the current state of suyu.
+You can also contact any of the developers on the Chat to learn more about the current state of suyu.
## Downloads
@@ -59,25 +67,27 @@ You can also contact any of the developers on Discord to learn more about the cu
* __Linux__: [Releases](https://git.suyu.dev/suyu/suyu/releases)
* __macOS__: [Releases](https://git.suyu.dev/suyu/suyu/releases)
* __Android__: [Releases](https://git.suyu.dev/suyu/suyu/releases)
+###### We currently do not provide builds for iOS, however if you would like, you could try the experimental Sudachi Emulator and it's bigger project: [Folium](https://apps.apple.com/us/app/folium/id6498623389).
-If you want daily builds then [Click here](https://git.suyu.dev/suyu/suyu/actions)
+If you want daily builds then [Click here](https://git.suyu.dev/suyu/suyu/actions).
If you don't know how to download the daily builds then [Click here](https://git.suyu.dev/suyu/suyu/raw/branch/dev/img/daily-builds.png)
-Right now we only have daily builds for Linux and Android.
-We have official builds [here.](https://git.suyu.dev/suyu/suyu/releases) If any website or person is claiming to have a build for suyu, take that with a grain of salt.
+We have official builds [here.](https://git.suyu.dev/suyu/suyu/releases) If any website or person is claiming to have a build for suyu, take that with a grain of salt and let us know.
+
+For Multiplayer, we recommend using the "Yuzu Online" patch, install instructions can be found on Reddit and their Discord.
## Building
* __Windows__: [Windows Build](https://git.suyu.dev/suyu/suyu/wiki/Building-For-Windows)
* __Linux__: [Linux Build](https://git.suyu.dev/suyu/suyu/wiki/Building-For-Linux)
* __Android__: [Android Build](https://git.suyu.dev/suyu/suyu/wiki/Building-For-Android)
-* __macOS__: [macOS Build](https://git.suyu.dev/suyu/suyu/wiki/Building-for-macOS)
+* __MacOS__: [MacOS Build](https://git.suyu.dev/suyu/suyu/wiki/Building-for-macOS)
## Support
-If you have any questions, don't hesitate to ask us on [Discord](https://discord.gg/suyu). We don't bite!
+If you have any questions, don't hesitate to ask us in our [Chat](https://chat.suyu.dev) or Subreddit, make an issue or contact a developer. We don't bite!
## License
diff --git a/dist/org.suyu_emu.suyu.desktop b/dist/dev.suyu_emu.suyu.desktop
similarity index 95%
rename from dist/org.suyu_emu.suyu.desktop
rename to dist/dev.suyu_emu.suyu.desktop
index 26bc6dd6f1..215c9d884a 100644
--- a/dist/org.suyu_emu.suyu.desktop
+++ b/dist/dev.suyu_emu.suyu.desktop
@@ -8,7 +8,7 @@ Type=Application
Name=suyu
GenericName=Switch Emulator
Comment=Nintendo Switch video game console emulator
-Icon=org.suyu_emu.suyu
+Icon=dev.suyu_emu.suyu
TryExec=suyu
Exec=suyu %f
Categories=Game;Emulator;Qt;
diff --git a/dist/org.suyu_emu.suyu.metainfo.xml b/dist/dev.suyu_emu.suyu.metainfo.xml
similarity index 96%
rename from dist/org.suyu_emu.suyu.metainfo.xml
rename to dist/dev.suyu_emu.suyu.metainfo.xml
index aeb2fecfbe..7677919f77 100644
--- a/dist/org.suyu_emu.suyu.metainfo.xml
+++ b/dist/dev.suyu_emu.suyu.metainfo.xml
@@ -7,7 +7,7 @@ SPDX-License-Identifier: CC0-1.0
-->
- org.suyu_emu.suyu
+ dev.suyu_emu.suyuCC0-1.0suyuNintendo Switch emulator
@@ -34,7 +34,7 @@ SPDX-License-Identifier: CC0-1.0
https://community.citra-emu.org/https://gitlab.com/suyu-emu/suyuhttps://suyu-emu.org/wiki/contributing/
- org.suyu_emu.suyu.desktop
+ dev.suyu_emu.suyu.desktopsuyusuyu-cmd
diff --git a/dist/org.suyu_emu.suyu.xml b/dist/dev.suyu_emu.suyu.xml
similarity index 88%
rename from dist/org.suyu_emu.suyu.xml
rename to dist/dev.suyu_emu.suyu.xml
index 9fafef671b..7e1414ce17 100644
--- a/dist/org.suyu_emu.suyu.xml
+++ b/dist/dev.suyu_emu.suyu.xml
@@ -10,7 +10,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
Nintendo Switch homebrew executable
NRO
-
+
@@ -18,7 +18,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
Nintendo Switch homebrew executable
NSO
-
+
@@ -26,7 +26,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
Nintendo Switch Package
NSP
-
+
@@ -34,7 +34,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
Nintendo Switch Card Image
XCI
-
+
diff --git a/dist/icons/overlay/osk_button_backspace.png b/dist/icons/overlay/osk_button_backspace.png
index b7dc332282..b212efbbc3 100644
Binary files a/dist/icons/overlay/osk_button_backspace.png and b/dist/icons/overlay/osk_button_backspace.png differ
diff --git a/dist/icons/overlay/overlay.qrc b/dist/icons/overlay/overlay.qrc
index 8d7833aca0..2319e6dd28 100644
--- a/dist/icons/overlay/overlay.qrc
+++ b/dist/icons/overlay/overlay.qrc
@@ -6,64 +6,66 @@ SPDX-License-Identifier: GPL-2.0-or-later
arrow_left.png
- arrow_left_dark.pngarrow_right.png
- arrow_right_dark.pngbutton_minus.png
- button_minus_dark.pngbutton_plus.png
- button_plus_dark.pngbutton_A.png
- button_A_dark.pngbutton_B.png
- button_B_dark.pngbutton_X.png
- button_X_dark.pngbutton_Y.png
- button_Y_dark.pngbutton_L.png
- button_L_dark.pngbutton_R.png
- button_R_dark.pngbutton_press_stick.png
- button_press_stick_dark.pngosk_button_B.pngosk_button_B_disabled.png
- osk_button_B_dark.png
- osk_button_B_dark_disabled.pngosk_button_Y.pngosk_button_Y_disabled.png
- osk_button_Y_dark.png
- osk_button_Y_dark_disabled.pngosk_button_backspace.png
- osk_button_backspace_dark.pngosk_button_plus.pngosk_button_plus_disabled.png
- osk_button_plus_dark.png
- osk_button_plus_dark_disabled.pngosk_button_shift.png
- osk_button_shift_dark.pngosk_button_shift_on.png
- osk_button_shift_on_dark.pngosk_button_shift_lock_on.pngosk_button_shift_lock_off.pngcontroller_dual_joycon.png
- controller_dual_joycon_dark.pngcontroller_pro.png
- controller_pro_dark.pngcontroller_handheld.png
- controller_handheld_dark.pngcontroller_single_joycon_left.png
- controller_single_joycon_left_dark.pngcontroller_single_joycon_right.png
- controller_single_joycon_right_dark.pngcontroller_single_joycon_left_a.png
- controller_single_joycon_left_a_dark.pngcontroller_single_joycon_left_b.png
- controller_single_joycon_left_b_dark.pngcontroller_single_joycon_left_x.png
- controller_single_joycon_left_x_dark.pngcontroller_single_joycon_left_y.png
- controller_single_joycon_left_y_dark.png
+
+
+ ../overlay_dark/arrow_left.png
+ ../overlay_dark/arrow_right.png
+ ../overlay_dark/button_minus.png
+ ../overlay_dark/button_plus.png
+ ../overlay_dark/button_A.png
+ ../overlay_dark/button_B.png
+ ../overlay_dark/button_X.png
+ ../overlay_dark/button_Y.png
+ ../overlay_dark/button_L.png
+ ../overlay_dark/button_R.png
+ ../overlay_dark/button_press_stick.png
+ ../overlay_dark/osk_button_B.png
+ ../overlay_dark/osk_button_B.png
+ ../overlay_dark/osk_button_Y.png
+ ../overlay_dark/osk_button_Y.png
+ ../overlay_dark/osk_button_backspace.png
+ ../overlay_dark/osk_button_plus.png
+ ../overlay_dark/osk_button_plus.png
+ ../overlay_dark/osk_button_shift.png
+ ../overlay_dark/osk_button_shift_on.png
+ ../overlay_dark/controller_dual_joycon.png
+ ../overlay_dark/controller_pro.png
+ ../overlay_dark/controller_handheld.png
+ ../overlay_dark/controller_single_joycon_left.png
+ ../overlay_dark/controller_single_joycon_right.png
+ ../overlay_dark/controller_single_joycon_left_a.png
+ ../overlay_dark/controller_single_joycon_left_b.png
+ ../overlay_dark/controller_single_joycon_left_x.png
+ ../overlay_dark/controller_single_joycon_left_y.png
diff --git a/dist/icons/overlay/arrow_left_dark.png b/dist/icons/overlay_dark/arrow_left.png
similarity index 100%
rename from dist/icons/overlay/arrow_left_dark.png
rename to dist/icons/overlay_dark/arrow_left.png
diff --git a/dist/icons/overlay/arrow_right_dark.png b/dist/icons/overlay_dark/arrow_right.png
similarity index 100%
rename from dist/icons/overlay/arrow_right_dark.png
rename to dist/icons/overlay_dark/arrow_right.png
diff --git a/dist/icons/overlay/button_A_dark.png b/dist/icons/overlay_dark/button_A.png
similarity index 100%
rename from dist/icons/overlay/button_A_dark.png
rename to dist/icons/overlay_dark/button_A.png
diff --git a/dist/icons/overlay/button_B_dark.png b/dist/icons/overlay_dark/button_B.png
similarity index 100%
rename from dist/icons/overlay/button_B_dark.png
rename to dist/icons/overlay_dark/button_B.png
diff --git a/dist/icons/overlay/button_L_dark.png b/dist/icons/overlay_dark/button_L.png
similarity index 100%
rename from dist/icons/overlay/button_L_dark.png
rename to dist/icons/overlay_dark/button_L.png
diff --git a/dist/icons/overlay/button_R_dark.png b/dist/icons/overlay_dark/button_R.png
similarity index 100%
rename from dist/icons/overlay/button_R_dark.png
rename to dist/icons/overlay_dark/button_R.png
diff --git a/dist/icons/overlay/button_X_dark.png b/dist/icons/overlay_dark/button_X.png
similarity index 100%
rename from dist/icons/overlay/button_X_dark.png
rename to dist/icons/overlay_dark/button_X.png
diff --git a/dist/icons/overlay/button_Y_dark.png b/dist/icons/overlay_dark/button_Y.png
similarity index 100%
rename from dist/icons/overlay/button_Y_dark.png
rename to dist/icons/overlay_dark/button_Y.png
diff --git a/dist/icons/overlay/button_minus_dark.png b/dist/icons/overlay_dark/button_minus.png
similarity index 100%
rename from dist/icons/overlay/button_minus_dark.png
rename to dist/icons/overlay_dark/button_minus.png
diff --git a/dist/icons/overlay/button_plus_dark.png b/dist/icons/overlay_dark/button_plus.png
similarity index 100%
rename from dist/icons/overlay/button_plus_dark.png
rename to dist/icons/overlay_dark/button_plus.png
diff --git a/dist/icons/overlay/button_press_stick_dark.png b/dist/icons/overlay_dark/button_press_stick.png
similarity index 100%
rename from dist/icons/overlay/button_press_stick_dark.png
rename to dist/icons/overlay_dark/button_press_stick.png
diff --git a/dist/icons/overlay/controller_dual_joycon_dark.png b/dist/icons/overlay_dark/controller_dual_joycon.png
similarity index 100%
rename from dist/icons/overlay/controller_dual_joycon_dark.png
rename to dist/icons/overlay_dark/controller_dual_joycon.png
diff --git a/dist/icons/overlay/controller_handheld_dark.png b/dist/icons/overlay_dark/controller_handheld.png
similarity index 100%
rename from dist/icons/overlay/controller_handheld_dark.png
rename to dist/icons/overlay_dark/controller_handheld.png
diff --git a/dist/icons/overlay/controller_pro_dark.png b/dist/icons/overlay_dark/controller_pro.png
similarity index 100%
rename from dist/icons/overlay/controller_pro_dark.png
rename to dist/icons/overlay_dark/controller_pro.png
diff --git a/dist/icons/overlay/controller_single_joycon_left_dark.png b/dist/icons/overlay_dark/controller_single_joycon_left.png
similarity index 100%
rename from dist/icons/overlay/controller_single_joycon_left_dark.png
rename to dist/icons/overlay_dark/controller_single_joycon_left.png
diff --git a/dist/icons/overlay/controller_single_joycon_left_a_dark.png b/dist/icons/overlay_dark/controller_single_joycon_left_a.png
similarity index 100%
rename from dist/icons/overlay/controller_single_joycon_left_a_dark.png
rename to dist/icons/overlay_dark/controller_single_joycon_left_a.png
diff --git a/dist/icons/overlay/controller_single_joycon_left_b_dark.png b/dist/icons/overlay_dark/controller_single_joycon_left_b.png
similarity index 100%
rename from dist/icons/overlay/controller_single_joycon_left_b_dark.png
rename to dist/icons/overlay_dark/controller_single_joycon_left_b.png
diff --git a/dist/icons/overlay/controller_single_joycon_left_x_dark.png b/dist/icons/overlay_dark/controller_single_joycon_left_x.png
similarity index 100%
rename from dist/icons/overlay/controller_single_joycon_left_x_dark.png
rename to dist/icons/overlay_dark/controller_single_joycon_left_x.png
diff --git a/dist/icons/overlay/controller_single_joycon_left_y_dark.png b/dist/icons/overlay_dark/controller_single_joycon_left_y.png
similarity index 100%
rename from dist/icons/overlay/controller_single_joycon_left_y_dark.png
rename to dist/icons/overlay_dark/controller_single_joycon_left_y.png
diff --git a/dist/icons/overlay/controller_single_joycon_right_dark.png b/dist/icons/overlay_dark/controller_single_joycon_right.png
similarity index 100%
rename from dist/icons/overlay/controller_single_joycon_right_dark.png
rename to dist/icons/overlay_dark/controller_single_joycon_right.png
diff --git a/dist/icons/overlay/osk_button_B_dark.png b/dist/icons/overlay_dark/osk_button_B.png
similarity index 100%
rename from dist/icons/overlay/osk_button_B_dark.png
rename to dist/icons/overlay_dark/osk_button_B.png
diff --git a/dist/icons/overlay/osk_button_B_dark_disabled.png b/dist/icons/overlay_dark/osk_button_B_disabled.png
similarity index 100%
rename from dist/icons/overlay/osk_button_B_dark_disabled.png
rename to dist/icons/overlay_dark/osk_button_B_disabled.png
diff --git a/dist/icons/overlay/osk_button_Y_dark.png b/dist/icons/overlay_dark/osk_button_Y.png
similarity index 100%
rename from dist/icons/overlay/osk_button_Y_dark.png
rename to dist/icons/overlay_dark/osk_button_Y.png
diff --git a/dist/icons/overlay/osk_button_Y_dark_disabled.png b/dist/icons/overlay_dark/osk_button_Y_disabled.png
similarity index 100%
rename from dist/icons/overlay/osk_button_Y_dark_disabled.png
rename to dist/icons/overlay_dark/osk_button_Y_disabled.png
diff --git a/dist/icons/overlay/osk_button_backspace_dark.png b/dist/icons/overlay_dark/osk_button_backspace.png
similarity index 100%
rename from dist/icons/overlay/osk_button_backspace_dark.png
rename to dist/icons/overlay_dark/osk_button_backspace.png
diff --git a/dist/icons/overlay/osk_button_plus_dark.png b/dist/icons/overlay_dark/osk_button_plus.png
similarity index 100%
rename from dist/icons/overlay/osk_button_plus_dark.png
rename to dist/icons/overlay_dark/osk_button_plus.png
diff --git a/dist/icons/overlay/osk_button_plus_dark_disabled.png b/dist/icons/overlay_dark/osk_button_plus_disabled.png
similarity index 100%
rename from dist/icons/overlay/osk_button_plus_dark_disabled.png
rename to dist/icons/overlay_dark/osk_button_plus_disabled.png
diff --git a/dist/icons/overlay/osk_button_shift_dark.png b/dist/icons/overlay_dark/osk_button_shift.png
similarity index 100%
rename from dist/icons/overlay/osk_button_shift_dark.png
rename to dist/icons/overlay_dark/osk_button_shift.png
diff --git a/dist/icons/overlay/osk_button_shift_on_dark.png b/dist/icons/overlay_dark/osk_button_shift_on.png
similarity index 100%
rename from dist/icons/overlay/osk_button_shift_on_dark.png
rename to dist/icons/overlay_dark/osk_button_shift_on.png
diff --git a/dist/languages/ar.ts b/dist/languages/ar.ts
index d9017ada62..dacbcdf68d 100644
--- a/dist/languages/ar.ts
+++ b/dist/languages/ar.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">موقعنا</span></a>|<a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">رماز المصدر</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">المساهمون</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">الرخصة</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">موقعنا</span></a>|<a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">رماز المصدر</span></a>|<a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">المساهمون</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">الرخصة</span></a></p></body></html>
diff --git a/dist/languages/ca.ts b/dist/languages/ca.ts
index 61ad09bf06..a131d85022 100644
--- a/dist/languages/ca.ts
+++ b/dist/languages/ca.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Pàgina web</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Codi Font</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Contribuïdors</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Llicència</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Pàgina web</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Codi Font</span></a>|<a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Contribuïdors</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Llicència</span></a></p></body></html>
diff --git a/dist/languages/cs.ts b/dist/languages/cs.ts
index 9b6f5fc25a..ff25846b5a 100644
--- a/dist/languages/cs.ts
+++ b/dist/languages/cs.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Webové stránky</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Zdrojový kód</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Přispěvatelé</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licence</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Webové stránky</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Zdrojový kód</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Přispěvatelé</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licence</span></a></p></body></html>
diff --git a/dist/languages/da.ts b/dist/languages/da.ts
index ddc4c96d3d..3ca2244fb2 100644
--- a/dist/languages/da.ts
+++ b/dist/languages/da.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/">Netsted<span style=" text-decoration: underline; color:#039be5;"></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Kildekode</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Bidragsydere</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licens</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/">Netsted<span style=" text-decoration: underline; color:#039be5;"></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Kildekode</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Bidragsydere</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licens</span></a></p></body></html>
diff --git a/dist/languages/de.ts b/dist/languages/de.ts
index e1ddd36975..8d862a62b9 100644
--- a/dist/languages/de.ts
+++ b/dist/languages/de.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Webseite</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Quellcode</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Mitwirkende</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Lizenz</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Webseite</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Quellcode</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Mitwirkende</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Lizenz</span></a></p></body></html>
diff --git a/dist/languages/el.ts b/dist/languages/el.ts
index b8eb0ed3b8..4f8f6a5aac 100644
--- a/dist/languages/el.ts
+++ b/dist/languages/el.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Ιστοσελίδα</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Πηγαίος Κώδικας</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Συνεργάτες</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"></span>Άδεια</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Ιστοσελίδα</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Πηγαίος Κώδικας</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Συνεργάτες</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"></span>Άδεια</span></a></p></body></html>
diff --git a/dist/languages/es.ts b/dist/languages/es.ts
index 5690a95dec..e9824bc5fc 100644
--- a/dist/languages/es.ts
+++ b/dist/languages/es.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Página web</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Código fuente</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Contribuidores</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licencia</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Página web</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Código fuente</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Contribuidores</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licencia</span></a></p></body></html>
diff --git a/dist/languages/fi.ts b/dist/languages/fi.ts
index 146d4e1dd9..0f22433d5b 100644
--- a/dist/languages/fi.ts
+++ b/dist/languages/fi.ts
@@ -40,8 +40,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Nettisivu</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Lähdekoodi</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Lahjoittajat</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/license.txt"><span style=" text-decoration: underline; color:#039be5;">Lisenssi</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Nettisivu</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Lähdekoodi</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Lahjoittajat</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/license.txt"><span style=" text-decoration: underline; color:#039be5;">Lisenssi</span></a></p></body></html>
diff --git a/dist/languages/fr.ts b/dist/languages/fr.ts
index a45580d312..3619e564c7 100644
--- a/dist/languages/fr.ts
+++ b/dist/languages/fr.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Site Web</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Code Source</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Contributeurs</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licence</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Site Web</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Code Source</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Contributeurs</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licence</span></a></p></body></html>
diff --git a/dist/languages/hu.ts b/dist/languages/hu.ts
index bd7d056e04..1b43397f17 100644
--- a/dist/languages/hu.ts
+++ b/dist/languages/hu.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Weboldal</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Forráskód</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Közreműködők</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licensz</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Weboldal</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Forráskód</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Közreműködők</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licensz</span></a></p></body></html>
diff --git a/dist/languages/id.ts b/dist/languages/id.ts
index 1a03da74e3..3bce2fc749 100644
--- a/dist/languages/id.ts
+++ b/dist/languages/id.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Situs web</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Kode Sumber</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Kontributor</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Lisensi</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Situs web</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Kode Sumber</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Kontributor</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Lisensi</span></a></p></body></html>
diff --git a/dist/languages/it.ts b/dist/languages/it.ts
index 6155074272..ec70f9d809 100644
--- a/dist/languages/it.ts
+++ b/dist/languages/it.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Sito web</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Codice sorgente</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Contributori</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licenza</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Sito web</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Codice sorgente</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Contributori</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licenza</span></a></p></body></html>
diff --git a/dist/languages/ja_JP.ts b/dist/languages/ja_JP.ts
index c5d15f14f6..39bd1ba0a7 100644
--- a/dist/languages/ja_JP.ts
+++ b/dist/languages/ja_JP.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">ウェブサイト</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">ソースコード</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">貢献者</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">ライセンス</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">ウェブサイト</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">ソースコード</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">貢献者</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">ライセンス</span></a></p></body></html>
diff --git a/dist/languages/ko_KR.ts b/dist/languages/ko_KR.ts
index 57fdcced57..4fe347f6d5 100644
--- a/dist/languages/ko_KR.ts
+++ b/dist/languages/ko_KR.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">웹사이트</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">소스 코드</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">기여자</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">라이센스</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">웹사이트</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">소스 코드</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">기여자</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">라이센스</span></a></p></body></html>
diff --git a/dist/languages/nb.ts b/dist/languages/nb.ts
index 6feaaecb77..7ee7b5878b 100644
--- a/dist/languages/nb.ts
+++ b/dist/languages/nb.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Nettside</span></a>|<a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Kildekode</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Bidragsytere</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/blob/master/license.txt"><span style=" text-decoration: underline; color:#039be5;">Lisens</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Nettside</span></a>|<a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Kildekode</span></a>|<a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Bidragsytere</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/blob/master/license.txt"><span style=" text-decoration: underline; color:#039be5;">Lisens</span></a></p></body></html>
diff --git a/dist/languages/nl.ts b/dist/languages/nl.ts
index 6cf1353919..7fdba359b8 100644
--- a/dist/languages/nl.ts
+++ b/dist/languages/nl.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Website</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Broncode</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Bijdragers</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licentie</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Website</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Broncode</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Bijdragers</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licentie</span></a></p></body></html>
diff --git a/dist/languages/pl.ts b/dist/languages/pl.ts
index 218983e0c6..b60eca3648 100644
--- a/dist/languages/pl.ts
+++ b/dist/languages/pl.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Strona</span></a>I<a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Kod Źródłowy</span></a>I<a href="https://gitlab.com/suyu-emu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Kontrybutorzy</span></a>I<a href="https://gitlab.com/suyu-emu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licencja</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Strona</span></a>I<a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Kod Źródłowy</span></a>I<a href="https://gitlab.com/suyu-emu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Kontrybutorzy</span></a>I<a href="https://gitlab.com/suyu-emu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licencja</span></a></p></body></html>
diff --git a/dist/languages/pt_BR.ts b/dist/languages/pt_BR.ts
index 644edd310f..caf2f84078 100644
--- a/dist/languages/pt_BR.ts
+++ b/dist/languages/pt_BR.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Site</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Código-fonte</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Colaboradores</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licença</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Site</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Código-fonte</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Colaboradores</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licença</span></a></p></body></html>
diff --git a/dist/languages/pt_PT.ts b/dist/languages/pt_PT.ts
index d14540c667..8cd779e40a 100644
--- a/dist/languages/pt_PT.ts
+++ b/dist/languages/pt_PT.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- Site | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Código fonte | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Contribuidores</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licença</span></a></p></body></html>
+
+ Site | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Código fonte | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Contribuidores</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licença</span></a></p></body></html>
diff --git a/dist/languages/ru_RU.ts b/dist/languages/ru_RU.ts
index 66d56b73f3..924cca9909 100644
--- a/dist/languages/ru_RU.ts
+++ b/dist/languages/ru_RU.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Веб-сайт</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Исходный код</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Контрибьюторы</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Лицензия</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Веб-сайт</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Исходный код</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Контрибьюторы</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Лицензия</span></a></p></body></html>
diff --git a/dist/languages/sv.ts b/dist/languages/sv.ts
index 140189c779..26d4e8e497 100644
--- a/dist/languages/sv.ts
+++ b/dist/languages/sv.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Hemsida</span></a>I<a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Källkod</span></a>I<a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Bidragsgivare</span></a>I<a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licens</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Hemsida</span></a>I<a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Källkod</span></a>I<a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Bidragsgivare</span></a>I<a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Licens</span></a></p></body></html>
diff --git a/dist/languages/tr_TR.ts b/dist/languages/tr_TR.ts
index 61532becdb..3f17dd29d7 100644
--- a/dist/languages/tr_TR.ts
+++ b/dist/languages/tr_TR.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Website</span></a>|<a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Kaynak Kodu</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Katkıda Bulunanlar</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Lisans</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Website</span></a>|<a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Kaynak Kodu</span></a>|<a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Katkıda Bulunanlar</span></a>|<a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Lisans</span></a></p></body></html>
diff --git a/dist/languages/uk.ts b/dist/languages/uk.ts
index aeb837b4c2..b3b77aa3e0 100644
--- a/dist/languages/uk.ts
+++ b/dist/languages/uk.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Веб-сайт</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Першокод</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Вкладники</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Ліцензія</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Веб-сайт</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Першокод</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Вкладники</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Ліцензія</span></a></p></body></html>
diff --git a/dist/languages/vi.ts b/dist/languages/vi.ts
index 38bdc29076..07f153deca 100644
--- a/dist/languages/vi.ts
+++ b/dist/languages/vi.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Trang web</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Mã nguồn</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Người đóng góp</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Giấy phép</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Trang web</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Mã nguồn</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Người đóng góp</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">Giấy phép</span></a></p></body></html>
diff --git a/dist/languages/vi_VN.ts b/dist/languages/vi_VN.ts
index 81cb3647fd..e619e8ad8f 100644
--- a/dist/languages/vi_VN.ts
+++ b/dist/languages/vi_VN.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Trang web</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">Mã nguồn</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Đóng góp</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/license.txt"><span style=" text-decoration: underline; color:#039be5;">Giấy phép</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">Trang web</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">Mã nguồn</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Đóng góp</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/license.txt"><span style=" text-decoration: underline; color:#039be5;">Giấy phép</span></a></p></body></html>
diff --git a/dist/languages/zh_CN.ts b/dist/languages/zh_CN.ts
index 688a0eae01..09b8431f20 100644
--- a/dist/languages/zh_CN.ts
+++ b/dist/languages/zh_CN.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">官方网站</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">源代码</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">贡献者</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">许可证</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">官方网站</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">源代码</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">贡献者</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">许可证</span></a></p></body></html>
diff --git a/dist/languages/zh_TW.ts b/dist/languages/zh_TW.ts
index 29bdb89afd..399195b394 100644
--- a/dist/languages/zh_TW.ts
+++ b/dist/languages/zh_TW.ts
@@ -35,8 +35,8 @@ p, li { white-space: pre-wrap; }
-
- <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">官網</span></a> | <a href="https://gitlab.com/suyu-emu"><span style=" text-decoration: underline; color:#039be5;">原始碼</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">貢獻者</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">許可證</span></a></p></body></html>
+
+ <html><head/><body><p><a href="https://suyu.dev/"><span style=" text-decoration: underline; color:#039be5;">官網</span></a> | <a href="https://git.suyu.dev/suyu"><span style=" text-decoration: underline; color:#039be5;">原始碼</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">貢獻者</span></a> | <a href="https://gitlab.com/suyu-emu/suyu/blob/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">許可證</span></a></p></body></html>
diff --git a/dist/qt_themes/colorful/icons/16x16/connected.png b/dist/qt_themes/colorful/icons/16x16/connected.png
deleted file mode 100644
index 0afc18cb7a..0000000000
Binary files a/dist/qt_themes/colorful/icons/16x16/connected.png and /dev/null differ
diff --git a/dist/qt_themes/colorful/icons/16x16/connected_notification.png b/dist/qt_themes/colorful/icons/16x16/connected_notification.png
deleted file mode 100644
index 72466e098e..0000000000
Binary files a/dist/qt_themes/colorful/icons/16x16/connected_notification.png and /dev/null differ
diff --git a/dist/qt_themes/colorful/icons/16x16/disconnected.png b/dist/qt_themes/colorful/icons/16x16/disconnected.png
deleted file mode 100644
index 7258a8cfe5..0000000000
Binary files a/dist/qt_themes/colorful/icons/16x16/disconnected.png and /dev/null differ
diff --git a/dist/qt_themes/colorful/icons/16x16/lock.png b/dist/qt_themes/colorful/icons/16x16/lock.png
deleted file mode 100644
index fd27069d80..0000000000
Binary files a/dist/qt_themes/colorful/icons/16x16/lock.png and /dev/null differ
diff --git a/dist/qt_themes/colorful/icons/256x256/plus_folder.png b/dist/qt_themes/colorful/icons/256x256/plus_folder.png
deleted file mode 100644
index 760fe6245e..0000000000
Binary files a/dist/qt_themes/colorful/icons/256x256/plus_folder.png and /dev/null differ
diff --git a/dist/qt_themes/colorful/icons/48x48/bad_folder.png b/dist/qt_themes/colorful/icons/48x48/bad_folder.png
deleted file mode 100644
index 34069c6b23..0000000000
Binary files a/dist/qt_themes/colorful/icons/48x48/bad_folder.png and /dev/null differ
diff --git a/dist/qt_themes/colorful/icons/48x48/chip.png b/dist/qt_themes/colorful/icons/48x48/chip.png
deleted file mode 100644
index 6fa1589995..0000000000
Binary files a/dist/qt_themes/colorful/icons/48x48/chip.png and /dev/null differ
diff --git a/dist/qt_themes/colorful/icons/48x48/folder.png b/dist/qt_themes/colorful/icons/48x48/folder.png
deleted file mode 100644
index 498de4c629..0000000000
Binary files a/dist/qt_themes/colorful/icons/48x48/folder.png and /dev/null differ
diff --git a/dist/qt_themes/colorful/icons/48x48/list-add.png b/dist/qt_themes/colorful/icons/48x48/list-add.png
deleted file mode 100644
index 74e4882aae..0000000000
Binary files a/dist/qt_themes/colorful/icons/48x48/list-add.png and /dev/null differ
diff --git a/dist/qt_themes/colorful/icons/48x48/sd_card.png b/dist/qt_themes/colorful/icons/48x48/sd_card.png
deleted file mode 100644
index 652d61bc32..0000000000
Binary files a/dist/qt_themes/colorful/icons/48x48/sd_card.png and /dev/null differ
diff --git a/dist/qt_themes/colorful/icons/48x48/star.png b/dist/qt_themes/colorful/icons/48x48/star.png
deleted file mode 100644
index 19d55a0a80..0000000000
Binary files a/dist/qt_themes/colorful/icons/48x48/star.png and /dev/null differ
diff --git a/dist/qt_themes/colorful/style.qrc b/dist/qt_themes/colorful/style.qrc
deleted file mode 100644
index 82cd367be9..0000000000
--- a/dist/qt_themes/colorful/style.qrc
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
- icons/index.theme
- icons/16x16/checked.png
- icons/16x16/connected.png
- icons/16x16/connected_notification.png
- icons/16x16/disconnected.png
- icons/16x16/failed.png
- icons/16x16/info.png
- icons/16x16/lock.png
- icons/16x16/sync.png
- icons/16x16/view-refresh.png
- icons/48x48/bad_folder.png
- icons/48x48/chip.png
- icons/48x48/folder.png
- icons/48x48/list-add.png
- icons/48x48/no_avatar.png
- icons/48x48/sd_card.png
- icons/48x48/star.png
- icons/256x256/plus_folder.png
-
-
- ../default/style.qss
-
-
diff --git a/dist/qt_themes/colorful_dark/icons/index.theme b/dist/qt_themes/colorful_dark/icons/index.theme
deleted file mode 100644
index b37a06df78..0000000000
--- a/dist/qt_themes/colorful_dark/icons/index.theme
+++ /dev/null
@@ -1,8 +0,0 @@
-[Icon Theme]
-Name=colorful_dark
-Comment=Colorful theme (Dark style)
-Inherits=colorful
-Directories=16x16
-
-[16x16]
-Size=16
diff --git a/dist/qt_themes/colorful_dark/style.qrc b/dist/qt_themes/colorful_dark/style.qrc
deleted file mode 100644
index 72451ef023..0000000000
--- a/dist/qt_themes/colorful_dark/style.qrc
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
- icons/index.theme
- icons/16x16/lock.png
- icons/16x16/view-refresh.png
-
-
-
- ../qdarkstyle/rc/up_arrow_disabled.png
- ../qdarkstyle/rc/Hmovetoolbar.png
- ../qdarkstyle/rc/stylesheet-branch-end.png
- ../qdarkstyle/rc/branch_closed-on.png
- ../qdarkstyle/rc/stylesheet-vline.png
- ../qdarkstyle/rc/branch_closed.png
- ../qdarkstyle/rc/branch_open-on.png
- ../qdarkstyle/rc/transparent.png
- ../qdarkstyle/rc/right_arrow_disabled.png
- ../qdarkstyle/rc/sizegrip.png
- ../qdarkstyle/rc/close.png
- ../qdarkstyle/rc/close-hover.png
- ../qdarkstyle/rc/close-pressed.png
- ../qdarkstyle/rc/down_arrow.png
- ../qdarkstyle/rc/Vmovetoolbar.png
- ../qdarkstyle/rc/left_arrow.png
- ../qdarkstyle/rc/stylesheet-branch-more.png
- ../qdarkstyle/rc/up_arrow.png
- ../qdarkstyle/rc/right_arrow.png
- ../qdarkstyle/rc/left_arrow_disabled.png
- ../qdarkstyle/rc/Hsepartoolbar.png
- ../qdarkstyle/rc/branch_open.png
- ../qdarkstyle/rc/Vsepartoolbar.png
- ../qdarkstyle/rc/down_arrow_disabled.png
- ../qdarkstyle/rc/undock.png
- ../qdarkstyle/rc/checkbox_checked_disabled.png
- ../qdarkstyle/rc/checkbox_checked_focus.png
- ../qdarkstyle/rc/checkbox_checked.png
- ../qdarkstyle/rc/checkbox_indeterminate.png
- ../qdarkstyle/rc/checkbox_indeterminate_focus.png
- ../qdarkstyle/rc/checkbox_unchecked_disabled.png
- ../qdarkstyle/rc/checkbox_unchecked_focus.png
- ../qdarkstyle/rc/checkbox_unchecked.png
- ../qdarkstyle/rc/radio_checked_disabled.png
- ../qdarkstyle/rc/radio_checked_focus.png
- ../qdarkstyle/rc/radio_checked.png
- ../qdarkstyle/rc/radio_unchecked_disabled.png
- ../qdarkstyle/rc/radio_unchecked_focus.png
- ../qdarkstyle/rc/radio_unchecked.png
-
-
- ../qdarkstyle/style.qss
-
-
diff --git a/dist/qt_themes/colorful_midnight_blue/icons/index.theme b/dist/qt_themes/colorful_midnight_blue/icons/index.theme
deleted file mode 100644
index dcb2c50d68..0000000000
--- a/dist/qt_themes/colorful_midnight_blue/icons/index.theme
+++ /dev/null
@@ -1,8 +0,0 @@
-[Icon Theme]
-Name=colorful_midnight_blue
-Comment=Colorful theme (Midnight Blue style)
-Inherits=colorful
-Directories=16x16
-
-[16x16]
-Size=16
diff --git a/dist/qt_themes/colorful_midnight_blue/style.qrc b/dist/qt_themes/colorful_midnight_blue/style.qrc
deleted file mode 100644
index b9821c6722..0000000000
--- a/dist/qt_themes/colorful_midnight_blue/style.qrc
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
- icons/index.theme
- ../colorful_dark/icons/16x16/lock.png
- ../qdarkstyle/icons/16x16/view-refresh.png
- ../colorful/icons/48x48/bad_folder.png
- ../colorful/icons/48x48/chip.png
- ../colorful/icons/48x48/folder.png
- ../colorful/icons/48x48/list-add.png
- ../colorful/icons/48x48/sd_card.png
- ../colorful/icons/256x256/plus_folder.png
-
-
-
- ../qdarkstyle_midnight_blue/rc/up_arrow_disabled.png
- ../qdarkstyle_midnight_blue/rc/Hmovetoolbar.png
- ../qdarkstyle_midnight_blue/rc/stylesheet-branch-end.png
- ../qdarkstyle_midnight_blue/rc/branch_closed-on.png
- ../qdarkstyle_midnight_blue/rc/stylesheet-vline.png
- ../qdarkstyle_midnight_blue/rc/branch_closed.png
- ../qdarkstyle_midnight_blue/rc/branch_open-on.png
- ../qdarkstyle_midnight_blue/rc/transparent.png
- ../qdarkstyle_midnight_blue/rc/right_arrow_disabled.png
- ../qdarkstyle_midnight_blue/rc/sizegrip.png
- ../qdarkstyle_midnight_blue/rc/close.png
- ../qdarkstyle_midnight_blue/rc/close-hover.png
- ../qdarkstyle_midnight_blue/rc/close-pressed.png
- ../qdarkstyle_midnight_blue/rc/down_arrow.png
- ../qdarkstyle_midnight_blue/rc/Vmovetoolbar.png
- ../qdarkstyle_midnight_blue/rc/left_arrow.png
- ../qdarkstyle_midnight_blue/rc/stylesheet-branch-more.png
- ../qdarkstyle_midnight_blue/rc/up_arrow.png
- ../qdarkstyle_midnight_blue/rc/right_arrow.png
- ../qdarkstyle_midnight_blue/rc/left_arrow_disabled.png
- ../qdarkstyle_midnight_blue/rc/Hsepartoolbar.png
- ../qdarkstyle_midnight_blue/rc/branch_open.png
- ../qdarkstyle_midnight_blue/rc/Vsepartoolbar.png
- ../qdarkstyle_midnight_blue/rc/down_arrow_disabled.png
- ../qdarkstyle_midnight_blue/rc/undock.png
- ../qdarkstyle_midnight_blue/rc/checkbox_checked_disabled.png
- ../qdarkstyle_midnight_blue/rc/checkbox_checked_focus.png
- ../qdarkstyle_midnight_blue/rc/checkbox_checked.png
- ../qdarkstyle_midnight_blue/rc/checkbox_indeterminate.png
- ../qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus.png
- ../qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled.png
- ../qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus.png
- ../qdarkstyle_midnight_blue/rc/checkbox_unchecked.png
- ../qdarkstyle_midnight_blue/rc/radio_checked_disabled.png
- ../qdarkstyle_midnight_blue/rc/radio_checked_focus.png
- ../qdarkstyle_midnight_blue/rc/radio_checked.png
- ../qdarkstyle_midnight_blue/rc/radio_unchecked_disabled.png
- ../qdarkstyle_midnight_blue/rc/radio_unchecked_focus.png
- ../qdarkstyle_midnight_blue/rc/radio_unchecked.png
-
-
- ../qdarkstyle_midnight_blue/style.qss
-
-
diff --git a/dist/qt_themes/default/default.qrc b/dist/qt_themes/default/default.qrc
index 4522865b4c..125bc3f342 100644
--- a/dist/qt_themes/default/default.qrc
+++ b/dist/qt_themes/default/default.qrc
@@ -4,23 +4,37 @@ SPDX-License-Identifier: GPL-2.0-or-later
-->
+
+
+ style.qss
+
+
+
-
icons/index.themeicons/16x16/connected.pngicons/16x16/connected_notification.pngicons/16x16/disconnected.png
+ icons/16x16/failed.png
+ icons/16x16/info.pngicons/16x16/lock.png
+ icons/16x16/sync.png
+ icons/16x16/view-refresh.pngicons/48x48/bad_folder.pngicons/48x48/chip.pngicons/48x48/folder.pngicons/48x48/list-add.png
+ icons/48x48/no_avatar.pngicons/48x48/sd_card.pngicons/48x48/star.pngicons/256x256/plus_folder.pngicons/256x256/suyu.png
-
- style.qss
+
+
+
+ ../default_dark/icons/index.theme
+ ../default_dark/icons/16x16/lock.png
+ ../default_dark/icons/16x16/view-refresh.png
diff --git a/dist/qt_themes/colorful/icons/16x16/checked.png b/dist/qt_themes/default/icons/16x16/checked.png
similarity index 100%
rename from dist/qt_themes/colorful/icons/16x16/checked.png
rename to dist/qt_themes/default/icons/16x16/checked.png
diff --git a/dist/qt_themes/colorful/icons/16x16/failed.png b/dist/qt_themes/default/icons/16x16/failed.png
similarity index 100%
rename from dist/qt_themes/colorful/icons/16x16/failed.png
rename to dist/qt_themes/default/icons/16x16/failed.png
diff --git a/dist/qt_themes/colorful/icons/16x16/info.png b/dist/qt_themes/default/icons/16x16/info.png
similarity index 100%
rename from dist/qt_themes/colorful/icons/16x16/info.png
rename to dist/qt_themes/default/icons/16x16/info.png
diff --git a/dist/qt_themes/default/icons/16x16/lock.png b/dist/qt_themes/default/icons/16x16/lock.png
index 69d3990508..fd27069d80 100644
Binary files a/dist/qt_themes/default/icons/16x16/lock.png and b/dist/qt_themes/default/icons/16x16/lock.png differ
diff --git a/dist/qt_themes/colorful/icons/16x16/sync.png b/dist/qt_themes/default/icons/16x16/sync.png
similarity index 100%
rename from dist/qt_themes/colorful/icons/16x16/sync.png
rename to dist/qt_themes/default/icons/16x16/sync.png
diff --git a/dist/qt_themes/colorful/icons/16x16/view-refresh.png b/dist/qt_themes/default/icons/16x16/view-refresh.png
similarity index 100%
rename from dist/qt_themes/colorful/icons/16x16/view-refresh.png
rename to dist/qt_themes/default/icons/16x16/view-refresh.png
diff --git a/dist/qt_themes/default/icons/256x256/plus_folder.png b/dist/qt_themes/default/icons/256x256/plus_folder.png
index f44c80c3ae..760fe6245e 100644
Binary files a/dist/qt_themes/default/icons/256x256/plus_folder.png and b/dist/qt_themes/default/icons/256x256/plus_folder.png differ
diff --git a/dist/qt_themes/default/icons/48x48/bad_folder.png b/dist/qt_themes/default/icons/48x48/bad_folder.png
index 364ec646f6..34069c6b23 100644
Binary files a/dist/qt_themes/default/icons/48x48/bad_folder.png and b/dist/qt_themes/default/icons/48x48/bad_folder.png differ
diff --git a/dist/qt_themes/default/icons/48x48/chip.png b/dist/qt_themes/default/icons/48x48/chip.png
index 1b573d51af..6fa1589995 100644
Binary files a/dist/qt_themes/default/icons/48x48/chip.png and b/dist/qt_themes/default/icons/48x48/chip.png differ
diff --git a/dist/qt_themes/default/icons/48x48/folder.png b/dist/qt_themes/default/icons/48x48/folder.png
index 507337fae5..498de4c629 100644
Binary files a/dist/qt_themes/default/icons/48x48/folder.png and b/dist/qt_themes/default/icons/48x48/folder.png differ
diff --git a/dist/qt_themes/default/icons/48x48/list-add.png b/dist/qt_themes/default/icons/48x48/list-add.png
index fd8a06132c..74e4882aae 100644
Binary files a/dist/qt_themes/default/icons/48x48/list-add.png and b/dist/qt_themes/default/icons/48x48/list-add.png differ
diff --git a/dist/qt_themes/colorful/icons/48x48/no_avatar.png b/dist/qt_themes/default/icons/48x48/no_avatar.png
similarity index 100%
rename from dist/qt_themes/colorful/icons/48x48/no_avatar.png
rename to dist/qt_themes/default/icons/48x48/no_avatar.png
diff --git a/dist/qt_themes/default/icons/48x48/sd_card.png b/dist/qt_themes/default/icons/48x48/sd_card.png
index 6bcb7f6b1d..652d61bc32 100644
Binary files a/dist/qt_themes/default/icons/48x48/sd_card.png and b/dist/qt_themes/default/icons/48x48/sd_card.png differ
diff --git a/dist/qt_themes/default/icons/48x48/star.png b/dist/qt_themes/default/icons/48x48/star.png
index c2b78f0c3e..19d55a0a80 100644
Binary files a/dist/qt_themes/default/icons/48x48/star.png and b/dist/qt_themes/default/icons/48x48/star.png differ
diff --git a/dist/qt_themes/default/icons/index.theme b/dist/qt_themes/default/icons/index.theme
index 21b35e3e3c..6c455463ee 100644
--- a/dist/qt_themes/default/icons/index.theme
+++ b/dist/qt_themes/default/icons/index.theme
@@ -1,7 +1,6 @@
[Icon Theme]
Name=default
-Comment=default theme
-Inherits=colorful
+Comment=Colorful theme
Directories=16x16,48x48,256x256
[16x16]
@@ -9,6 +8,6 @@ Size=16
[48x48]
Size=48
-
+
[256x256]
Size=256
diff --git a/dist/qt_themes/default/style.qss b/dist/qt_themes/default/style.qss
index 921950c6c0..16b779b1b8 100644
--- a/dist/qt_themes/default/style.qss
+++ b/dist/qt_themes/default/style.qss
@@ -1,3 +1,14 @@
+/*
+* SPDX-FileCopyrightText: 2018 yuzu Emulator Project
+* SPDX-FileCopyrightText: 2024 suyu Emulator Project
+* SPDX-License-Identifier: GPL-2.0-or-later
+*/
+
+QWidget:item:hover {
+ background-color: #28668d;
+ color: #eff0f1;
+}
+
QAbstractSpinBox {
min-height: 19px;
}
@@ -11,7 +22,7 @@ QPushButton#TogglableStatusBarButton {
}
QPushButton#TogglableStatusBarButton:checked {
- color: #000000;
+ color: palette(text);
}
QPushButton#TogglableStatusBarButton:hover {
@@ -38,6 +49,10 @@ QPushButton#RendererStatusBarButton:!checked {
color: #0066ff;
}
+QPushButton#RendererStatusBarButton:!checked[dark=true] {
+ color: #00ccdd;
+}
+
QPushButton#GPUStatusBarButton {
color: #656565;
border: 1px solid transparent;
@@ -54,13 +69,21 @@ QPushButton#GPUStatusBarButton:checked {
color: #b06020;
}
+QPushButton#GPUStatusBarButton:checked[dark=true] {
+ color: #ff8040;
+}
+
QPushButton#GPUStatusBarButton:!checked {
color: #109010;
}
+QPushButton#GPUStatusBarButton:!checked[dark=true] {
+ color: #40dd40;
+}
+
QPushButton#DockingStatusBarButton {
min-width: 0px;
- color: #000000;
+ color: palette(text);
border: 1px solid transparent;
background-color: transparent;
padding: 0px 3px 0px 3px;
@@ -94,21 +117,21 @@ QGroupBox#groupPlayer5Connected:checked,
QGroupBox#groupPlayer6Connected:checked,
QGroupBox#groupPlayer7Connected:checked,
QGroupBox#groupPlayer8Connected:checked {
- background-color: #f5f5f5;
+ background-color: palette(window);
}
QWidget#topControllerApplet {
- border-bottom: 1px solid #828790
+ border-bottom: 1px solid palette(dark)
}
QWidget#bottomPerGameInput,
QWidget#bottomControllerApplet {
- border-top: 1px solid #828790
+ border-top: 1px solid palette(dark)
}
QWidget#topPerGameInput,
QWidget#middleControllerApplet {
- background-color: #fff;
+ background-color: palette(base)
}
QWidget#topPerGameInput QComboBox,
@@ -120,10 +143,6 @@ QWidget#connectedControllers {
background: transparent;
}
-QWidget#closeButtons {
- background: transparent;
-}
-
QWidget#playersSupported,
QWidget#controllersSupported,
QWidget#controllerSupported1,
@@ -345,7 +364,7 @@ QWidget#lineDialog {
QStackedWidget#bottomOSK,
QWidget#contentDialog,
QWidget#contentRichDialog {
- background: rgba(240, 240, 240, 1);
+ background: palette(base);
}
QWidget#contentDialog,
@@ -372,7 +391,7 @@ QStackedWidget#stackedDialog QTextBrowser QScrollBar::vertical {
border-radius: 4px;
}
-QStackedWidget#stackedDialog QTextBrowser QScrollBar::horizoncal {
+QStackedWidget#stackedDialog QTextBrowser QScrollBar::horizontal {
background: #cdcdcd;
height: 15px;
margin: 3px 15px 3px 15px;
@@ -402,6 +421,7 @@ QWidget#inputOSK QLineEdit {
background: transparent;
border: none;
color: #ccc;
+ padding: 0px;
}
QWidget#inputBoxOSK {
@@ -431,6 +451,27 @@ QWidget#boxOSK QLabel#label_characters_box {
color: #ccc;
}
+QWidget#buttonsDialog,
+QWidget#buttonsRichDialog,
+QWidget#mainOSK,
+QWidget#headerOSK,
+QWidget#normalOSK,
+QWidget#shiftOSK,
+QWidget#numOSK,
+QWidget#subOSK,
+QWidget#inputOSK,
+QWidget#inputBoxOSK,
+QWidget#charactersOSK,
+QWidget#charactersBoxOSK,
+QWidget#legendOSK,
+QWidget#legendOSK QWidget,
+QWidget#legendOSKshift,
+QWidget#legendOSKshift QWidget,
+QWidget#legendOSKnum,
+QWidget#legendOSKnum QWidget {
+ background: transparent;
+}
+
QWidget#contentDialog QLabel#label_title,
QWidget#contentRichDialog QLabel#label_title_rich {
color: #888;
@@ -471,8 +512,8 @@ QDialog#OverlayDialog QPushButton:pressed {
}
QDialog#QtSoftwareKeyboardDialog QPushButton {
- background: rgba(232, 232, 232, 1);
- border: 2px solid rgba(240, 240, 240, 1);
+ background: palette(window);
+ border: 2px solid palette(base);
}
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift,
@@ -481,27 +522,35 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
- background: rgba(218, 218, 218, 1);
- border: 2px solid rgba(240, 240, 240, 1);
+ background: palette(alternate-base);
+ border: 2px solid palette(base);
}
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
- color: rgba(240, 240, 240, 1);
- background: rgba(44, 44, 44, 1);
- border: 2px solid rgba(240, 240, 240, 1);
+ color: palette(base);
+ background: palette(mid);
+ border: 2px solid palette(base);
}
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
- color: rgba(240, 240, 240, 1);
- background: rgba(49, 79, 239, 1);
- border: 2px solid rgba(240, 240, 240, 1);
+ color: palette(base);
+ background: palette(highlight);
+ border: 2px solid palette(base);
}
QDialog#QtSoftwareKeyboardDialog QPushButton:focus,
+QDialog#QtSoftwareKeyboardDialog QPushButton:hover
+{
+ background: palette(base);
+ border: 5px solid rgba(148, 250, 202, 1);
+ border-radius: 6px;
+ outline: none;
+}
+
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:focus,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:focus,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:focus,
@@ -514,8 +563,6 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:focus,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:focus,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:focus,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:focus,
-
-QDialog#QtSoftwareKeyboardDialog QPushButton:hover,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:hover,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:hover,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:hover,
@@ -524,12 +571,11 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:hover,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:hover,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:hover,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:hover,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:hover,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:hover {
- color: rgba(0, 0, 0, 1);
- background: rgba(255, 255, 255, 1);
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:hover,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:hover
+{
border: 5px solid rgba(148, 250, 202, 1);
border-radius: 6px;
outline: none;
@@ -548,48 +594,12 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:pressed,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:pressed,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:pressed,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:pressed {
- color: rgba(240, 240, 240, 1);
+ color: palette(base);
background: rgba(150, 150, 150, 1);
border: 5px solid rgba(148, 250, 202, 1);
border-radius: 6px;
}
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
- image: url(:/overlay/osk_button_B.png);
- image-position: right;
- qproperty-icon: url(:/overlay/osk_button_backspace.png);
- qproperty-iconSize: 36px;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
- image: url(:/overlay/osk_button_Y.png);
- image-position: right;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
- image: url(:/overlay/osk_button_plus.png);
- image-position: right;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
- image: url(:/overlay/osk_button_shift_lock_off.png);
- image-position: left;
- qproperty-icon: url(:/overlay/osk_button_shift.png);
- qproperty-iconSize: 36px;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
- image: url(:/overlay/osk_button_shift_lock_off.png);
- image-position: left;
- qproperty-icon: url(:/overlay/osk_button_shift_on.png);
- qproperty-iconSize: 36px;
-}
-
QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_bracket,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_bracket,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_parenthesis,
@@ -602,47 +612,6 @@ QDialog#QtSoftwareKeyboardDialog QWidget#titleOSK QLabel {
color: #ccc;
}
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L_num {
- image: url(:/overlay/button_L.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
- image: url(:/overlay/arrow_left.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
- image: url(:/overlay/button_R.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
- image: url(:/overlay/arrow_right.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
- image: url(:/overlay/button_press_stick.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
- image: url(:/overlay/button_X.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
- image: url(:/overlay/button_A.png);
-}
-
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled,
@@ -653,8 +622,8 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
- color: rgba(164, 164, 164, 1);
- background-color: rgba(218, 218, 218, 1);
+ color: palette(midlight);
+ background-color: palette(alternate-base);
}
QDialog#QtSoftwareKeyboardDialog QPushButton#button_at:disabled,
@@ -671,22 +640,5 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_8:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_9:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_0:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled {
- color: rgba(164, 164, 164, 1);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
- image: url(:/overlay/osk_button_plus_disabled.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
- image: url(:/overlay/osk_button_B_disabled.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
- image: url(:/overlay/osk_button_Y_disabled.png);
+ color: palette(midlight);
}
diff --git a/dist/qt_themes/colorful_dark/icons/16x16/lock.png b/dist/qt_themes/default_dark/icons/16x16/lock.png
similarity index 100%
rename from dist/qt_themes/colorful_dark/icons/16x16/lock.png
rename to dist/qt_themes/default_dark/icons/16x16/lock.png
diff --git a/dist/qt_themes/colorful_dark/icons/16x16/view-refresh.png b/dist/qt_themes/default_dark/icons/16x16/view-refresh.png
similarity index 100%
rename from dist/qt_themes/colorful_dark/icons/16x16/view-refresh.png
rename to dist/qt_themes/default_dark/icons/16x16/view-refresh.png
diff --git a/dist/qt_themes/default_dark/icons/index.theme b/dist/qt_themes/default_dark/icons/index.theme
index 60a072d1d6..32d84fa9bd 100644
--- a/dist/qt_themes/default_dark/icons/index.theme
+++ b/dist/qt_themes/default_dark/icons/index.theme
@@ -1,7 +1,7 @@
[Icon Theme]
Name=default_dark
Comment=Colorful theme (Dark style)
-Inherits=colorful
+Inherits=default
Directories=16x16
[16x16]
diff --git a/dist/qt_themes/default_dark/style.qrc b/dist/qt_themes/default_dark/style.qrc
deleted file mode 100644
index 7de4737c2c..0000000000
--- a/dist/qt_themes/default_dark/style.qrc
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
- ../colorful/icons/16x16/connected.png
- ../colorful/icons/16x16/connected_notification.png
- ../colorful/icons/16x16/disconnected.png
- icons/index.theme
- ../colorful_dark/icons/16x16/lock.png
- ../colorful_dark/icons/16x16/view-refresh.png
- ../colorful/icons/48x48/bad_folder.png
- ../colorful/icons/48x48/chip.png
- ../colorful/icons/48x48/folder.png
- ../qdarkstyle/icons/48x48/no_avatar.png
- ../colorful/icons/48x48/list-add.png
- ../colorful/icons/48x48/sd_card.png
- ../colorful/icons/256x256/plus_folder.png
-
-
-
- style.qss
-
-
diff --git a/dist/qt_themes/default_dark/style.qss b/dist/qt_themes/default_dark/style.qss
deleted file mode 100644
index ca6daa2d52..0000000000
--- a/dist/qt_themes/default_dark/style.qss
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
-* SPDX-FileCopyrightText: 2018 yuzu Emulator Project
-* SPDX-License-Identifier: GPL-2.0-or-later
-*/
-QAbstractSpinBox {
- min-height: 19px;
-}
-
-QPushButton#TogglableStatusBarButton {
- color: #959595;
- border: 1px solid transparent;
- background-color: transparent;
- padding: 0px 3px 0px 3px;
- text-align: center;
-}
-
-QPushButton#TogglableStatusBarButton:checked {
- color: palette(text);
-}
-
-QPushButton#TogglableStatusBarButton:hover {
- border: 1px solid #76797C;
-}
-
-QPushButton#RendererStatusBarButton {
- color: #656565;
- border: 1px solid transparent;
- background-color: transparent;
- padding: 0px 3px 0px 3px;
- text-align: center;
-}
-
-QPushButton#RendererStatusBarButton:hover {
- border: 1px solid #76797C;
-}
-
-QPushButton#RendererStatusBarButton:checked {
- color: #e85c00;
-}
-
-QPushButton#RendererStatusBarButton:!checked {
- color: #00ccdd;
-}
-
-QPushButton#GPUStatusBarButton {
- color: #656565;
- border: 1px solid transparent;
- background-color: transparent;
- padding: 0px 3px 0px 3px;
- text-align: center;
-}
-
-QPushButton#GPUStatusBarButton:hover {
- border: 1px solid #76797C;
-}
-
-QPushButton#GPUStatusBarButton:checked {
- color: #ff8040;
-}
-
-QPushButton#GPUStatusBarButton:!checked {
- color: #40dd40;
-}
-
-QPushButton#DockingStatusBarButton {
- min-width: 0px;
- color: palette(text);
- border: 1px solid transparent;
- background-color: transparent;
- padding: 0px 3px 0px 3px;
- text-align: center;
-}
-
-QPushButton#DockingStatusBarButton:hover {
- border: 1px solid #76797C;
-}
-
-QPushButton#buttonRefreshDevices {
- min-width: 21px;
- min-height: 21px;
- max-width: 21px;
- max-height: 21px;
-}
-
-QWidget#bottomPerGameInput,
-QWidget#topControllerApplet,
-QWidget#bottomControllerApplet,
-QGroupBox#groupPlayer1Connected:checked,
-QGroupBox#groupPlayer2Connected:checked,
-QGroupBox#groupPlayer3Connected:checked,
-QGroupBox#groupPlayer4Connected:checked,
-QGroupBox#groupPlayer5Connected:checked,
-QGroupBox#groupPlayer6Connected:checked,
-QGroupBox#groupPlayer7Connected:checked,
-QGroupBox#groupPlayer8Connected:checked {
- background-color: #f5f5f5;
-}
-
-QWidget#topControllerApplet {
- border-bottom: 1px solid #828790
-}
-
-QWidget#bottomPerGameInput,
-QWidget#bottomControllerApplet {
- border-top: 1px solid #828790
-}
-
-QWidget#topPerGameInput,
-QWidget#middleControllerApplet {
- background-color: #fff;
-}
-
-QWidget#topPerGameInput QComboBox,
-QWidget#middleControllerApplet QComboBox {
- width: 120px;
-}
-
-QWidget#connectedControllers {
- background: transparent;
-}
-
-QWidget#playersSupported,
-QWidget#controllersSupported,
-QWidget#controllerSupported1,
-QWidget#controllerSupported2,
-QWidget#controllerSupported3,
-QWidget#controllerSupported4,
-QWidget#controllerSupported5,
-QWidget#controllerSupported6 {
- border: none;
- background: transparent;
-}
-
-QGroupBox#groupPlayer1Connected,
-QGroupBox#groupPlayer2Connected,
-QGroupBox#groupPlayer3Connected,
-QGroupBox#groupPlayer4Connected,
-QGroupBox#groupPlayer5Connected,
-QGroupBox#groupPlayer6Connected,
-QGroupBox#groupPlayer7Connected,
-QGroupBox#groupPlayer8Connected {
- border: 1px solid #828790;
- border-radius: 3px;
- padding: 0px;
- min-height: 98px;
- max-height: 98px;
-}
-
-QGroupBox#groupPlayer1Connected:unchecked,
-QGroupBox#groupPlayer2Connected:unchecked,
-QGroupBox#groupPlayer3Connected:unchecked,
-QGroupBox#groupPlayer4Connected:unchecked,
-QGroupBox#groupPlayer5Connected:unchecked,
-QGroupBox#groupPlayer6Connected:unchecked,
-QGroupBox#groupPlayer7Connected:unchecked,
-QGroupBox#groupPlayer8Connected:unchecked {
- border: 1px solid #d9d9d9;
-}
-
-QGroupBox#groupPlayer1Connected::title,
-QGroupBox#groupPlayer2Connected::title,
-QGroupBox#groupPlayer3Connected::title,
-QGroupBox#groupPlayer4Connected::title,
-QGroupBox#groupPlayer5Connected::title,
-QGroupBox#groupPlayer6Connected::title,
-QGroupBox#groupPlayer7Connected::title,
-QGroupBox#groupPlayer8Connected::title {
- subcontrol-origin: margin;
- subcontrol-position: top left;
- padding-left: 0px;
- padding-right: 0px;
- padding-top: 1px;
- margin-left: 0px;
- margin-right: -4px;
- margin-bottom: 4px;
-}
-
-QCheckBox#checkboxPlayer1Connected,
-QCheckBox#checkboxPlayer2Connected,
-QCheckBox#checkboxPlayer3Connected,
-QCheckBox#checkboxPlayer4Connected,
-QCheckBox#checkboxPlayer5Connected,
-QCheckBox#checkboxPlayer6Connected,
-QCheckBox#checkboxPlayer7Connected,
-QCheckBox#checkboxPlayer8Connected {
- spacing: 0px;
-}
-
-QWidget#Player1LEDs QCheckBox,
-QWidget#Player2LEDs QCheckBox,
-QWidget#Player3LEDs QCheckBox,
-QWidget#Player4LEDs QCheckBox,
-QWidget#Player5LEDs QCheckBox,
-QWidget#Player6LEDs QCheckBox,
-QWidget#Player7LEDs QCheckBox,
-QWidget#Player8LEDs QCheckBox {
- spacing: 0px;
-}
-
-QWidget#Player1LEDs QCheckBox::indicator,
-QWidget#Player2LEDs QCheckBox::indicator,
-QWidget#Player3LEDs QCheckBox::indicator,
-QWidget#Player4LEDs QCheckBox::indicator,
-QWidget#Player5LEDs QCheckBox::indicator,
-QWidget#Player6LEDs QCheckBox::indicator,
-QWidget#Player7LEDs QCheckBox::indicator,
-QWidget#Player8LEDs QCheckBox::indicator {
- width: 6px;
- height: 6px;
- margin-left: 0px;
-}
-
-QWidget#bottomPerGameInput QCheckBox#checkboxPlayer1Connected::indicator,
-QWidget#bottomPerGameInput QCheckBox#checkboxPlayer2Connected::indicator,
-QWidget#bottomPerGameInput QCheckBox#checkboxPlayer3Connected::indicator,
-QWidget#bottomPerGameInput QCheckBox#checkboxPlayer4Connected::indicator,
-QWidget#bottomPerGameInput QCheckBox#checkboxPlayer5Connected::indicator,
-QWidget#bottomPerGameInput QCheckBox#checkboxPlayer6Connected::indicator,
-QWidget#bottomPerGameInput QCheckBox#checkboxPlayer7Connected::indicator,
-QWidget#bottomPerGameInput QCheckBox#checkboxPlayer8Connected::indicator {
- width: 12px;
- height: 12px;
-}
-
-QCheckBox#checkboxPlayer1Connected::indicator,
-QCheckBox#checkboxPlayer2Connected::indicator,
-QCheckBox#checkboxPlayer3Connected::indicator,
-QCheckBox#checkboxPlayer4Connected::indicator,
-QCheckBox#checkboxPlayer5Connected::indicator,
-QCheckBox#checkboxPlayer6Connected::indicator,
-QCheckBox#checkboxPlayer7Connected::indicator,
-QCheckBox#checkboxPlayer8Connected::indicator {
- width: 14px;
- height: 14px;
-}
-
-QGroupBox#groupPlayer1Connected::indicator,
-QGroupBox#groupPlayer2Connected::indicator,
-QGroupBox#groupPlayer3Connected::indicator,
-QGroupBox#groupPlayer4Connected::indicator,
-QGroupBox#groupPlayer5Connected::indicator,
-QGroupBox#groupPlayer6Connected::indicator,
-QGroupBox#groupPlayer7Connected::indicator,
-QGroupBox#groupPlayer8Connected::indicator {
- width: 16px;
- height: 16px;
-}
-
-QWidget#Player1LEDs QCheckBox::indicator:checked,
-QWidget#Player2LEDs QCheckBox::indicator:checked,
-QWidget#Player3LEDs QCheckBox::indicator:checked,
-QWidget#Player4LEDs QCheckBox::indicator:checked,
-QWidget#Player5LEDs QCheckBox::indicator:checked,
-QWidget#Player6LEDs QCheckBox::indicator:checked,
-QWidget#Player7LEDs QCheckBox::indicator:checked,
-QWidget#Player8LEDs QCheckBox::indicator:checked,
-QGroupBox#groupPlayer1Connected::indicator:checked,
-QGroupBox#groupPlayer2Connected::indicator:checked,
-QGroupBox#groupPlayer3Connected::indicator:checked,
-QGroupBox#groupPlayer4Connected::indicator:checked,
-QGroupBox#groupPlayer5Connected::indicator:checked,
-QGroupBox#groupPlayer6Connected::indicator:checked,
-QGroupBox#groupPlayer7Connected::indicator:checked,
-QGroupBox#groupPlayer8Connected::indicator:checked,
-QCheckBox#checkboxPlayer1Connected::indicator:checked,
-QCheckBox#checkboxPlayer2Connected::indicator:checked,
-QCheckBox#checkboxPlayer3Connected::indicator:checked,
-QCheckBox#checkboxPlayer4Connected::indicator:checked,
-QCheckBox#checkboxPlayer5Connected::indicator:checked,
-QCheckBox#checkboxPlayer6Connected::indicator:checked,
-QCheckBox#checkboxPlayer7Connected::indicator:checked,
-QCheckBox#checkboxPlayer8Connected::indicator:checked,
-QGroupBox#groupConnectedController::indicator:checked {
- border-radius: 2px;
- border: 1px solid #929192;
- background: #39ff14;
- image: none;
-}
-
-QWidget#Player1LEDs QCheckBox::indicator:unchecked,
-QWidget#Player2LEDs QCheckBox::indicator:unchecked,
-QWidget#Player3LEDs QCheckBox::indicator:unchecked,
-QWidget#Player4LEDs QCheckBox::indicator:unchecked,
-QWidget#Player5LEDs QCheckBox::indicator:unchecked,
-QWidget#Player6LEDs QCheckBox::indicator:unchecked,
-QWidget#Player7LEDs QCheckBox::indicator:unchecked,
-QWidget#Player8LEDs QCheckBox::indicator:unchecked,
-QGroupBox#groupPlayer1Connected::indicator:unchecked,
-QGroupBox#groupPlayer2Connected::indicator:unchecked,
-QGroupBox#groupPlayer3Connected::indicator:unchecked,
-QGroupBox#groupPlayer4Connected::indicator:unchecked,
-QGroupBox#groupPlayer5Connected::indicator:unchecked,
-QGroupBox#groupPlayer6Connected::indicator:unchecked,
-QGroupBox#groupPlayer7Connected::indicator:unchecked,
-QGroupBox#groupPlayer8Connected::indicator:unchecked,
-QCheckBox#checkboxPlayer1Connected::indicator:unchecked,
-QCheckBox#checkboxPlayer2Connected::indicator:unchecked,
-QCheckBox#checkboxPlayer3Connected::indicator:unchecked,
-QCheckBox#checkboxPlayer4Connected::indicator:unchecked,
-QCheckBox#checkboxPlayer5Connected::indicator:unchecked,
-QCheckBox#checkboxPlayer6Connected::indicator:unchecked,
-QCheckBox#checkboxPlayer7Connected::indicator:unchecked,
-QCheckBox#checkboxPlayer8Connected::indicator:unchecked,
-QGroupBox#groupConnectedController::indicator:unchecked {
- border-radius: 2px;
- border: 1px solid #929192;
- background: transparent;
- image: none;
-}
-
-QWidget#controllerPlayer1,
-QWidget#controllerPlayer2,
-QWidget#controllerPlayer3,
-QWidget#controllerPlayer4,
-QWidget#controllerPlayer5,
-QWidget#controllerPlayer6,
-QWidget#controllerPlayer7,
-QWidget#controllerPlayer8 {
- background: transparent;
-}
-
-QDialog#QtSoftwareKeyboardDialog,
-QStackedWidget#topOSK {
- background: rgba(51, 51, 51, .9);
-}
-
-
-QDialog#OverlayDialog,
-QStackedWidget#stackedDialog {
- background: rgba(51, 51, 51, .7);
-}
-
-QWidget#boxOSK,
-QWidget#lineOSK,
-QWidget#richDialog,
-QWidget#lineDialog {
- background: transparent;
-}
-
-QStackedWidget#bottomOSK,
-QWidget#contentDialog,
-QWidget#contentRichDialog {
- background: rgba(240, 240, 240, 1);
-}
-
-QWidget#contentDialog,
-QWidget#contentRichDialog {
- margin: 5px;
- border-radius: 6px;
-}
-
-QWidget#buttonsDialog,
-QWidget#buttonsRichDialog {
- margin: 5px;
- border-top: 2px solid rgba(44, 44, 44, 1);
-}
-
-QWidget#legendOSKnum {
- border-top: 1px solid rgba(44, 44, 44, 1);
-}
-
-QStackedWidget#stackedDialog QTextBrowser QScrollBar::vertical {
- background: #cdcdcd;
- width: 15px;
- margin: 15px 3px 15px 3px;
- border: 1px transparent;
- border-radius: 4px;
-}
-
-QStackedWidget#stackedDialog QTextBrowser QScrollBar::horizoncal {
- background: #cdcdcd;
- height: 15px;
- margin: 3px 15px 3px 15px;
- border: 1px transparent;
- border-radius: 4px;
-}
-
-QStackedWidget#stackedDialog QTextBrowser QScrollBar::handle {
- background: #fff;
- border-radius: 4px;
- min-height: 5px;
- min-width: 5px;
-}
-
-QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-line,
-QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-line,
-QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-page,
-QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-page {
- background: none;
-}
-
-QWidget#inputOSK {
- border-bottom: 3px solid rgba(255, 255, 255, .9);
-}
-
-QWidget#inputOSK QLineEdit {
- background: transparent;
- border: none;
- color: #ccc;
-}
-
-QWidget#inputBoxOSK {
- border: 2px solid rgba(255, 255, 255, .9);
-}
-
-QWidget#inputBoxOSK QTextEdit {
- background: transparent;
- border: none;
- color: #ccc;
-}
-
-QWidget#richDialog QTextBrowser {
- background: transparent;
- border: none;
- padding: 35px 65px;
-}
-
-
-QWidget#lineOSK QLabel#label_header {
- color: #f0f0f0;
-}
-
-QWidget#lineOSK QLabel#label_sub,
-QWidget#lineOSK QLabel#label_characters,
-QWidget#boxOSK QLabel#label_characters_box {
- color: #ccc;
-}
-
-QWidget#contentDialog QLabel#label_title,
-QWidget#contentRichDialog QLabel#label_title_rich {
- color: #888;
-}
-
-QWidget#contentDialog QLabel#label_dialog {
- padding: 20px 65px;
-}
-
-QWidget#contentDialog QLabel#label_title,
-QWidget#contentRichDialog QLabel#label_title_rich {
- padding: 0px 65px;
-}
-
-QDialog#OverlayDialog QPushButton {
- color: rgba(49, 79, 239, 1);
- background: transparent;
- border: none;
- padding: 0px;
- min-width: 0px;
-}
-
-QDialog#OverlayDialog QPushButton:focus,
-QDialog#OverlayDialog QPushButton:hover {
- color: rgba(49, 79, 239, 1);
- background: rgba(255, 255, 255, 1);
- border: 5px solid rgba(148, 250, 202, 1);
- border-radius: 6px;
- outline: none;
-}
-
-QDialog#OverlayDialog QPushButton:pressed {
- color: rgba(240, 240, 240, 1);
- background: rgba(150, 150, 150, 1);
- border: 5px solid rgba(148, 250, 202, 1);
- border-radius: 6px;
- outline: none;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton {
- background: rgba(232, 232, 232, 1);
- border: 2px solid rgba(240, 240, 240, 1);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
- background: rgba(218, 218, 218, 1);
- border: 2px solid rgba(240, 240, 240, 1);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
- color: rgba(240, 240, 240, 1);
- background: rgba(44, 44, 44, 1);
- border: 2px solid rgba(240, 240, 240, 1);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
- color: rgba(240, 240, 240, 1);
- background: rgba(49, 79, 239, 1);
- border: 2px solid rgba(240, 240, 240, 1);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:focus,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:focus,
-
-QDialog#QtSoftwareKeyboardDialog QPushButton:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:hover,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:hover {
- color: rgba(0, 0, 0, 1);
- background: rgba(255, 255, 255, 1);
- border: 5px solid rgba(148, 250, 202, 1);
- border-radius: 6px;
- outline: none;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:pressed,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:pressed {
- color: rgba(240, 240, 240, 1);
- background: rgba(150, 150, 150, 1);
- border: 5px solid rgba(148, 250, 202, 1);
- border-radius: 6px;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
- image: url(:/overlay/osk_button_B.png);
- image-position: right;
- qproperty-icon: url(:/overlay/osk_button_backspace.png);
- qproperty-iconSize: 36px;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
- image: url(:/overlay/osk_button_Y.png);
- image-position: right;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
- image: url(:/overlay/osk_button_plus.png);
- image-position: right;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
- image: url(:/overlay/osk_button_shift_lock_off.png);
- image-position: left;
- qproperty-icon: url(:/overlay/osk_button_shift.png);
- qproperty-iconSize: 36px;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
- image: url(:/overlay/osk_button_shift_lock_off.png);
- image-position: left;
- qproperty-icon: url(:/overlay/osk_button_shift_on.png);
- qproperty-iconSize: 36px;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_bracket,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_bracket,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_parenthesis,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_parenthesis {
- padding-bottom: 7px;
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#titleOSK QLabel {
- background: transparent;
- color: #ccc;
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L_num {
- image: url(:/overlay/button_L.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
- image: url(:/overlay/arrow_left.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
- image: url(:/overlay/button_R.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
- image: url(:/overlay/arrow_right.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
- image: url(:/overlay/button_press_stick.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
- image: url(:/overlay/button_X.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
- image: url(:/overlay/button_A.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
- color: rgba(164, 164, 164, 1);
- background-color: rgba(218, 218, 218, 1);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_at:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_slash:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_percent:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_1:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_2:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_3:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_4:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_5:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_6:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_7:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_8:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_9:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_0:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled {
- color: rgba(164, 164, 164, 1);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
- image: url(:/overlay/osk_button_plus_disabled.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
- image: url(:/overlay/osk_button_B_disabled.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
- image: url(:/overlay/osk_button_Y_disabled.png);
-}
diff --git a/dist/qt_themes/monochrome/icons.qrc b/dist/qt_themes/monochrome/icons.qrc
new file mode 100644
index 0000000000..4eb16294fe
--- /dev/null
+++ b/dist/qt_themes/monochrome/icons.qrc
@@ -0,0 +1,32 @@
+
+
+
+
+ icons/index.theme
+ icons/16x16/lock.png
+ icons/48x48/bad_folder.png
+ icons/48x48/chip.png
+ icons/48x48/folder.png
+ icons/48x48/list-add.png
+ icons/48x48/sd_card.png
+ icons/48x48/star.png
+ icons/256x256/plus_folder.png
+
+
+
+
+ ../monochrome_dark/icons/index.theme
+ ../monochrome_dark/icons/16x16/lock.png
+ ../monochrome_dark/icons/48x48/bad_folder.png
+ ../monochrome_dark/icons/48x48/chip.png
+ ../monochrome_dark/icons/48x48/folder.png
+ ../monochrome_dark/icons/48x48/list-add.png
+ ../monochrome_dark/icons/48x48/no_avatar.png
+ ../monochrome_dark/icons/48x48/sd_card.png
+ ../monochrome_dark/icons/48x48/star.png
+ ../monochrome_dark/icons/256x256/plus_folder.png
+
+
diff --git a/dist/qt_themes/monochrome/icons/16x16/lock.png b/dist/qt_themes/monochrome/icons/16x16/lock.png
new file mode 100644
index 0000000000..69d3990508
Binary files /dev/null and b/dist/qt_themes/monochrome/icons/16x16/lock.png differ
diff --git a/dist/qt_themes/monochrome/icons/256x256/plus_folder.png b/dist/qt_themes/monochrome/icons/256x256/plus_folder.png
new file mode 100644
index 0000000000..f44c80c3ae
Binary files /dev/null and b/dist/qt_themes/monochrome/icons/256x256/plus_folder.png differ
diff --git a/dist/qt_themes/monochrome/icons/48x48/bad_folder.png b/dist/qt_themes/monochrome/icons/48x48/bad_folder.png
new file mode 100644
index 0000000000..364ec646f6
Binary files /dev/null and b/dist/qt_themes/monochrome/icons/48x48/bad_folder.png differ
diff --git a/dist/qt_themes/monochrome/icons/48x48/chip.png b/dist/qt_themes/monochrome/icons/48x48/chip.png
new file mode 100644
index 0000000000..1b573d51af
Binary files /dev/null and b/dist/qt_themes/monochrome/icons/48x48/chip.png differ
diff --git a/dist/qt_themes/monochrome/icons/48x48/folder.png b/dist/qt_themes/monochrome/icons/48x48/folder.png
new file mode 100644
index 0000000000..507337fae5
Binary files /dev/null and b/dist/qt_themes/monochrome/icons/48x48/folder.png differ
diff --git a/dist/qt_themes/monochrome/icons/48x48/list-add.png b/dist/qt_themes/monochrome/icons/48x48/list-add.png
new file mode 100644
index 0000000000..fd8a06132c
Binary files /dev/null and b/dist/qt_themes/monochrome/icons/48x48/list-add.png differ
diff --git a/dist/qt_themes/monochrome/icons/48x48/sd_card.png b/dist/qt_themes/monochrome/icons/48x48/sd_card.png
new file mode 100644
index 0000000000..6bcb7f6b1d
Binary files /dev/null and b/dist/qt_themes/monochrome/icons/48x48/sd_card.png differ
diff --git a/dist/qt_themes/monochrome/icons/48x48/star.png b/dist/qt_themes/monochrome/icons/48x48/star.png
new file mode 100644
index 0000000000..c2b78f0c3e
Binary files /dev/null and b/dist/qt_themes/monochrome/icons/48x48/star.png differ
diff --git a/dist/qt_themes/colorful/icons/index.theme b/dist/qt_themes/monochrome/icons/index.theme
similarity index 60%
rename from dist/qt_themes/colorful/icons/index.theme
rename to dist/qt_themes/monochrome/icons/index.theme
index 6eb3c69495..c2764622e0 100644
--- a/dist/qt_themes/colorful/icons/index.theme
+++ b/dist/qt_themes/monochrome/icons/index.theme
@@ -1,8 +1,9 @@
[Icon Theme]
-Name=colorful
-Comment=Colorful theme
+Name=monochrome
+Comment=Monochrome light icons
+Inherits=default
Directories=16x16,48x48,256x256
-
+
[16x16]
Size=16
diff --git a/dist/qt_themes/monochrome/style.qrc b/dist/qt_themes/monochrome/style.qrc
new file mode 100644
index 0000000000..54778e2f54
--- /dev/null
+++ b/dist/qt_themes/monochrome/style.qrc
@@ -0,0 +1,5 @@
+
+
+ ../default/style.qss
+
+
diff --git a/dist/qt_themes/qdarkstyle/icons/16x16/lock.png b/dist/qt_themes/monochrome_dark/icons/16x16/lock.png
similarity index 100%
rename from dist/qt_themes/qdarkstyle/icons/16x16/lock.png
rename to dist/qt_themes/monochrome_dark/icons/16x16/lock.png
diff --git a/dist/qt_themes/qdarkstyle/icons/256x256/plus_folder.png b/dist/qt_themes/monochrome_dark/icons/256x256/plus_folder.png
similarity index 100%
rename from dist/qt_themes/qdarkstyle/icons/256x256/plus_folder.png
rename to dist/qt_themes/monochrome_dark/icons/256x256/plus_folder.png
diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/bad_folder.png b/dist/qt_themes/monochrome_dark/icons/48x48/bad_folder.png
similarity index 100%
rename from dist/qt_themes/qdarkstyle/icons/48x48/bad_folder.png
rename to dist/qt_themes/monochrome_dark/icons/48x48/bad_folder.png
diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/chip.png b/dist/qt_themes/monochrome_dark/icons/48x48/chip.png
similarity index 100%
rename from dist/qt_themes/qdarkstyle/icons/48x48/chip.png
rename to dist/qt_themes/monochrome_dark/icons/48x48/chip.png
diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/folder.png b/dist/qt_themes/monochrome_dark/icons/48x48/folder.png
similarity index 100%
rename from dist/qt_themes/qdarkstyle/icons/48x48/folder.png
rename to dist/qt_themes/monochrome_dark/icons/48x48/folder.png
diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/list-add.png b/dist/qt_themes/monochrome_dark/icons/48x48/list-add.png
similarity index 100%
rename from dist/qt_themes/qdarkstyle/icons/48x48/list-add.png
rename to dist/qt_themes/monochrome_dark/icons/48x48/list-add.png
diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/no_avatar.png b/dist/qt_themes/monochrome_dark/icons/48x48/no_avatar.png
similarity index 100%
rename from dist/qt_themes/qdarkstyle/icons/48x48/no_avatar.png
rename to dist/qt_themes/monochrome_dark/icons/48x48/no_avatar.png
diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/sd_card.png b/dist/qt_themes/monochrome_dark/icons/48x48/sd_card.png
similarity index 100%
rename from dist/qt_themes/qdarkstyle/icons/48x48/sd_card.png
rename to dist/qt_themes/monochrome_dark/icons/48x48/sd_card.png
diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/star.png b/dist/qt_themes/monochrome_dark/icons/48x48/star.png
similarity index 100%
rename from dist/qt_themes/qdarkstyle/icons/48x48/star.png
rename to dist/qt_themes/monochrome_dark/icons/48x48/star.png
diff --git a/dist/qt_themes/monochrome_dark/icons/index.theme b/dist/qt_themes/monochrome_dark/icons/index.theme
new file mode 100644
index 0000000000..9ca318d09e
--- /dev/null
+++ b/dist/qt_themes/monochrome_dark/icons/index.theme
@@ -0,0 +1,14 @@
+[Icon Theme]
+Name=monochrome_dark
+Comment=Monochrome dark icons
+Inherits=default_dark
+Directories=16x16,48x48,256x256
+
+[16x16]
+Size=16
+
+[48x48]
+Size=48
+
+[256x256]
+Size=256
diff --git a/dist/qt_themes/qdarkstyle/style.qss b/dist/qt_themes/qdarkstyle/dark.qss
similarity index 93%
rename from dist/qt_themes/qdarkstyle/style.qss
rename to dist/qt_themes/qdarkstyle/dark.qss
index 328ac942fc..95e575c42f 100644
--- a/dist/qt_themes/qdarkstyle/style.qss
+++ b/dist/qt_themes/qdarkstyle/dark.qss
@@ -944,6 +944,10 @@ QListView::indicator:indeterminate:pressed {
image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png);
}
+QSlider:horizontal {
+ height: 20px;
+}
+
QSlider::groove:horizontal {
border: 1px solid #565a5e;
height: 4px;
@@ -1380,10 +1384,6 @@ QWidget#connectedControllers {
background: transparent;
}
-QWidget#closeButtons {
- background: transparent;
-}
-
QWidget#playersSupported,
QWidget#controllersSupported,
QWidget#controllerSupported1,
@@ -1843,40 +1843,17 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:pressed {
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
- image: url(:/overlay/osk_button_B_dark.png);
image-position: right;
- qproperty-icon: url(:/overlay/osk_button_backspace_dark.png);
qproperty-iconSize: 36px;
}
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
- image: url(:/overlay/osk_button_Y_dark.png);
- image-position: right;
-}
-
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
color: rgba(44, 44, 44, 1);
- image: url(:/overlay/osk_button_plus_dark.png);
image-position: right;
}
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
- image: url(:/overlay/osk_button_shift_lock_off.png);
- image-position: left;
- qproperty-icon: url(:/overlay/osk_button_shift_dark.png);
- qproperty-iconSize: 36px;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
- image: url(:/overlay/osk_button_shift_lock_off.png);
- image-position: left;
- qproperty-icon: url(:/overlay/osk_button_shift_on_dark.png);
- qproperty-iconSize: 36px;
-}
-
QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_bracket,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_bracket,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_parenthesis,
@@ -1889,47 +1866,6 @@ QDialog#QtSoftwareKeyboardDialog QWidget#titleOSK QLabel {
color: #ccc;
}
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L_num {
- image: url(:/overlay/button_L_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
- image: url(:/overlay/arrow_left_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
- image: url(:/overlay/button_R_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
- image: url(:/overlay/arrow_right_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
- image: url(:/overlay/button_press_stick_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
- image: url(:/overlay/button_X_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
- image: url(:/overlay/button_A_dark.png);
-}
-
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled,
@@ -1961,23 +1897,6 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled {
color: rgba(144, 144, 144, 1);
}
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
- image: url(:/overlay/osk_button_plus_dark_disabled.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
- image: url(:/overlay/osk_button_B_dark_disabled.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
- image: url(:/overlay/osk_button_Y_dark_disabled.png);
-}
-
QDialog#QtSoftwareKeyboardDialog QFrame,
QDialog#QtSoftwareKeyboardDialog QFrame[frameShape="0"],
QDialog#OverlayDialog QFrame,
diff --git a/dist/qt_themes/qdarkstyle/icons.qrc b/dist/qt_themes/qdarkstyle/icons.qrc
new file mode 100644
index 0000000000..d7ec900649
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/icons.qrc
@@ -0,0 +1,51 @@
+
+
+ icons/index.theme
+ ../default_dark/icons/16x16/lock.png
+
+
+ icons/index.theme
+ ../default_dark/icons/16x16/lock.png
+
+
+ rc/branch_closed-on.png
+ rc/branch_closed.png
+ rc/branch_open-on.png
+ rc/branch_open.png
+ rc/checkbox_checked.png
+ rc/checkbox_checked_disabled.png
+ rc/checkbox_checked_focus.png
+ rc/checkbox_indeterminate.png
+ rc/checkbox_indeterminate_focus.png
+ rc/checkbox_unchecked.png
+ rc/checkbox_unchecked_disabled.png
+ rc/checkbox_unchecked_focus.png
+ rc/close-hover.png
+ rc/close-pressed.png
+ rc/close.png
+ rc/down_arrow.png
+ rc/down_arrow_disabled.png
+ rc/Hmovetoolbar.png
+ rc/Hsepartoolbar.png
+ rc/left_arrow.png
+ rc/left_arrow_disabled.png
+ rc/radio_checked.png
+ rc/radio_checked_disabled.png
+ rc/radio_checked_focus.png
+ rc/radio_unchecked.png
+ rc/radio_unchecked_disabled.png
+ rc/radio_unchecked_focus.png
+ rc/right_arrow.png
+ rc/right_arrow_disabled.png
+ rc/sizegrip.png
+ rc/stylesheet-branch-end.png
+ rc/stylesheet-branch-more.png
+ rc/stylesheet-vline.png
+ rc/transparent.png
+ rc/undock.png
+ rc/up_arrow.png
+ rc/up_arrow_disabled.png
+ rc/Vmovetoolbar.png
+ rc/Vsepartoolbar.png
+
+
diff --git a/dist/qt_themes/qdarkstyle/icons/16x16/connected.png b/dist/qt_themes/qdarkstyle/icons/16x16/connected.png
deleted file mode 100644
index 0afc18cb7a..0000000000
Binary files a/dist/qt_themes/qdarkstyle/icons/16x16/connected.png and /dev/null differ
diff --git a/dist/qt_themes/qdarkstyle/icons/16x16/connected_notification.png b/dist/qt_themes/qdarkstyle/icons/16x16/connected_notification.png
deleted file mode 100644
index 72466e098e..0000000000
Binary files a/dist/qt_themes/qdarkstyle/icons/16x16/connected_notification.png and /dev/null differ
diff --git a/dist/qt_themes/qdarkstyle/icons/16x16/disconnected.png b/dist/qt_themes/qdarkstyle/icons/16x16/disconnected.png
deleted file mode 100644
index 7258a8cfe5..0000000000
Binary files a/dist/qt_themes/qdarkstyle/icons/16x16/disconnected.png and /dev/null differ
diff --git a/dist/qt_themes/qdarkstyle/icons/16x16/view-refresh.png b/dist/qt_themes/qdarkstyle/icons/16x16/view-refresh.png
deleted file mode 100644
index d4afd76f94..0000000000
Binary files a/dist/qt_themes/qdarkstyle/icons/16x16/view-refresh.png and /dev/null differ
diff --git a/dist/qt_themes/qdarkstyle/icons/index.theme b/dist/qt_themes/qdarkstyle/icons/index.theme
index 502717617c..0059b7ac96 100644
--- a/dist/qt_themes/qdarkstyle/icons/index.theme
+++ b/dist/qt_themes/qdarkstyle/icons/index.theme
@@ -1,14 +1,4 @@
[Icon Theme]
Name=qdarkstyle
-Comment=dark theme
-Inherits=colorful
-Directories=16x16,48x48,256x256
-
-[16x16]
-Size=16
-
-[48x48]
-Size=48
-
-[256x256]
-Size=256
+Comment=Dark theme (Mine Shaft style)
+Inherits=default_dark
diff --git a/dist/qt_themes/qdarkstyle/style.qrc b/dist/qt_themes/qdarkstyle/style.qrc
index a89fb26c68..b1180c3e0a 100644
--- a/dist/qt_themes/qdarkstyle/style.qrc
+++ b/dist/qt_themes/qdarkstyle/style.qrc
@@ -1,62 +1,5 @@
-
- icons/index.theme
- icons/16x16/connected.png
- icons/16x16/disconnected.png
- icons/16x16/connected_notification.png
- icons/16x16/lock.png
- icons/16x16/view-refresh.png
- icons/48x48/bad_folder.png
- icons/48x48/chip.png
- icons/48x48/folder.png
- icons/48x48/no_avatar.png
- icons/48x48/list-add.png
- icons/48x48/sd_card.png
- icons/48x48/star.png
- icons/256x256/plus_folder.png
-
-
- rc/up_arrow_disabled.png
- rc/Hmovetoolbar.png
- rc/stylesheet-branch-end.png
- rc/branch_closed-on.png
- rc/stylesheet-vline.png
- rc/branch_closed.png
- rc/branch_open-on.png
- rc/transparent.png
- rc/right_arrow_disabled.png
- rc/sizegrip.png
- rc/close.png
- rc/close-hover.png
- rc/close-pressed.png
- rc/down_arrow.png
- rc/Vmovetoolbar.png
- rc/left_arrow.png
- rc/stylesheet-branch-more.png
- rc/up_arrow.png
- rc/right_arrow.png
- rc/left_arrow_disabled.png
- rc/Hsepartoolbar.png
- rc/branch_open.png
- rc/Vsepartoolbar.png
- rc/down_arrow_disabled.png
- rc/undock.png
- rc/checkbox_checked_disabled.png
- rc/checkbox_checked_focus.png
- rc/checkbox_checked.png
- rc/checkbox_indeterminate.png
- rc/checkbox_indeterminate_focus.png
- rc/checkbox_unchecked_disabled.png
- rc/checkbox_unchecked_focus.png
- rc/checkbox_unchecked.png
- rc/radio_checked_disabled.png
- rc/radio_checked_focus.png
- rc/radio_checked.png
- rc/radio_unchecked_disabled.png
- rc/radio_unchecked_focus.png
- rc/radio_unchecked.png
-
-
- style.qss
-
+
+ dark.qss
+
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/style.qss b/dist/qt_themes/qdarkstyle_midnight_blue/dark.qss
similarity index 95%
rename from dist/qt_themes/qdarkstyle_midnight_blue/style.qss
rename to dist/qt_themes/qdarkstyle_midnight_blue/dark.qss
index eb0889b139..3086b90ade 100644
--- a/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/dark.qss
@@ -1296,6 +1296,10 @@ QSlider:focus {
border: none;
}
+QSlider:horizontal {
+ height: 20px;
+}
+
QSlider::groove:horizontal {
background: #32414B;
border: 1px solid #32414B;
@@ -2779,41 +2783,10 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:pressed {
border-radius: 6px;
}
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
- image: url(:/overlay/osk_button_B_dark.png);
- image-position: right;
- qproperty-icon: url(:/overlay/osk_button_backspace_dark.png);
- qproperty-iconSize: 36px;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
- image: url(:/overlay/osk_button_Y_dark.png);
- image-position: right;
-}
-
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
color: rgba(44, 44, 44, 1);
- image: url(:/overlay/osk_button_plus_dark.png);
- image-position: right;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
- image: url(:/overlay/osk_button_shift_lock_off.png);
- image-position: left;
- qproperty-icon: url(:/overlay/osk_button_shift_dark.png);
- qproperty-iconSize: 36px;
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
- image: url(:/overlay/osk_button_shift_lock_off.png);
- image-position: left;
- qproperty-icon: url(:/overlay/osk_button_shift_on_dark.png);
- qproperty-iconSize: 36px;
}
QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_bracket,
@@ -2828,47 +2801,6 @@ QDialog#QtSoftwareKeyboardDialog QWidget#titleOSK QLabel {
color: #ccc;
}
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_L_num {
- image: url(:/overlay/button_L_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
- image: url(:/overlay/arrow_left_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
- image: url(:/overlay/button_R_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
- image: url(:/overlay/arrow_right_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
- image: url(:/overlay/button_press_stick_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
- image: url(:/overlay/button_X_dark.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
-QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
- image: url(:/overlay/button_A_dark.png);
-}
-
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled,
@@ -2899,20 +2831,3 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_0:disabled,
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled {
color: rgba(144, 144, 144, 1);
}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
- image: url(:/overlay/osk_button_plus_dark_disabled.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
- image: url(:/overlay/osk_button_B_dark_disabled.png);
-}
-
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
-QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
- image: url(:/overlay/osk_button_Y_dark_disabled.png);
-}
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons.qrc b/dist/qt_themes/qdarkstyle_midnight_blue/icons.qrc
new file mode 100644
index 0000000000..1a071adda6
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/icons.qrc
@@ -0,0 +1,224 @@
+
+
+
+
+ icons/index.theme
+
+
+ icons/index.theme
+
+
+
+ rc/arrow_down.png
+ rc/arrow_down@2x.png
+ rc/arrow_down_disabled.png
+ rc/arrow_down_disabled@2x.png
+ rc/arrow_down_focus.png
+ rc/arrow_down_focus@2x.png
+ rc/arrow_down_pressed.png
+ rc/arrow_down_pressed@2x.png
+ rc/arrow_left.png
+ rc/arrow_left@2x.png
+ rc/arrow_left_disabled.png
+ rc/arrow_left_disabled@2x.png
+ rc/arrow_left_focus.png
+ rc/arrow_left_focus@2x.png
+ rc/arrow_left_pressed.png
+ rc/arrow_left_pressed@2x.png
+ rc/arrow_right.png
+ rc/arrow_right@2x.png
+ rc/arrow_right_disabled.png
+ rc/arrow_right_disabled@2x.png
+ rc/arrow_right_focus.png
+ rc/arrow_right_focus@2x.png
+ rc/arrow_right_pressed.png
+ rc/arrow_right_pressed@2x.png
+ rc/arrow_up.png
+ rc/arrow_up@2x.png
+ rc/arrow_up_disabled.png
+ rc/arrow_up_disabled@2x.png
+ rc/arrow_up_focus.png
+ rc/arrow_up_focus@2x.png
+ rc/arrow_up_pressed.png
+ rc/arrow_up_pressed@2x.png
+ rc/base_icon.png
+ rc/base_icon@2x.png
+ rc/base_icon_disabled.png
+ rc/base_icon_disabled@2x.png
+ rc/base_icon_focus.png
+ rc/base_icon_focus@2x.png
+ rc/base_icon_pressed.png
+ rc/base_icon_pressed@2x.png
+ rc/branch_closed.png
+ rc/branch_closed@2x.png
+ rc/branch_closed_disabled.png
+ rc/branch_closed_disabled@2x.png
+ rc/branch_closed_focus.png
+ rc/branch_closed_focus@2x.png
+ rc/branch_closed_pressed.png
+ rc/branch_closed_pressed@2x.png
+ rc/branch_end.png
+ rc/branch_end@2x.png
+ rc/branch_end_disabled.png
+ rc/branch_end_disabled@2x.png
+ rc/branch_end_focus.png
+ rc/branch_end_focus@2x.png
+ rc/branch_end_pressed.png
+ rc/branch_end_pressed@2x.png
+ rc/branch_line.png
+ rc/branch_line@2x.png
+ rc/branch_line_disabled.png
+ rc/branch_line_disabled@2x.png
+ rc/branch_line_focus.png
+ rc/branch_line_focus@2x.png
+ rc/branch_line_pressed.png
+ rc/branch_line_pressed@2x.png
+ rc/branch_more.png
+ rc/branch_more@2x.png
+ rc/branch_more_disabled.png
+ rc/branch_more_disabled@2x.png
+ rc/branch_more_focus.png
+ rc/branch_more_focus@2x.png
+ rc/branch_more_pressed.png
+ rc/branch_more_pressed@2x.png
+ rc/branch_open.png
+ rc/branch_open@2x.png
+ rc/branch_open_disabled.png
+ rc/branch_open_disabled@2x.png
+ rc/branch_open_focus.png
+ rc/branch_open_focus@2x.png
+ rc/branch_open_pressed.png
+ rc/branch_open_pressed@2x.png
+ rc/checkbox_checked.png
+ rc/checkbox_checked@2x.png
+ rc/checkbox_checked_disabled.png
+ rc/checkbox_checked_disabled@2x.png
+ rc/checkbox_checked_focus.png
+ rc/checkbox_checked_focus@2x.png
+ rc/checkbox_checked_pressed.png
+ rc/checkbox_checked_pressed@2x.png
+ rc/checkbox_indeterminate.png
+ rc/checkbox_indeterminate@2x.png
+ rc/checkbox_indeterminate_disabled.png
+ rc/checkbox_indeterminate_disabled@2x.png
+ rc/checkbox_indeterminate_focus.png
+ rc/checkbox_indeterminate_focus@2x.png
+ rc/checkbox_indeterminate_pressed.png
+ rc/checkbox_indeterminate_pressed@2x.png
+ rc/checkbox_unchecked.png
+ rc/checkbox_unchecked@2x.png
+ rc/checkbox_unchecked_disabled.png
+ rc/checkbox_unchecked_disabled@2x.png
+ rc/checkbox_unchecked_focus.png
+ rc/checkbox_unchecked_focus@2x.png
+ rc/checkbox_unchecked_pressed.png
+ rc/checkbox_unchecked_pressed@2x.png
+ rc/line_horizontal.png
+ rc/line_horizontal@2x.png
+ rc/line_horizontal_disabled.png
+ rc/line_horizontal_disabled@2x.png
+ rc/line_horizontal_focus.png
+ rc/line_horizontal_focus@2x.png
+ rc/line_horizontal_pressed.png
+ rc/line_horizontal_pressed@2x.png
+ rc/line_vertical.png
+ rc/line_vertical@2x.png
+ rc/line_vertical_disabled.png
+ rc/line_vertical_disabled@2x.png
+ rc/line_vertical_focus.png
+ rc/line_vertical_focus@2x.png
+ rc/line_vertical_pressed.png
+ rc/line_vertical_pressed@2x.png
+ rc/radio_checked.png
+ rc/radio_checked@2x.png
+ rc/radio_checked_disabled.png
+ rc/radio_checked_disabled@2x.png
+ rc/radio_checked_focus.png
+ rc/radio_checked_focus@2x.png
+ rc/radio_checked_pressed.png
+ rc/radio_checked_pressed@2x.png
+ rc/radio_unchecked.png
+ rc/radio_unchecked@2x.png
+ rc/radio_unchecked_disabled.png
+ rc/radio_unchecked_disabled@2x.png
+ rc/radio_unchecked_focus.png
+ rc/radio_unchecked_focus@2x.png
+ rc/radio_unchecked_pressed.png
+ rc/radio_unchecked_pressed@2x.png
+ rc/toolbar_move_horizontal.png
+ rc/toolbar_move_horizontal@2x.png
+ rc/toolbar_move_horizontal_disabled.png
+ rc/toolbar_move_horizontal_disabled@2x.png
+ rc/toolbar_move_horizontal_focus.png
+ rc/toolbar_move_horizontal_focus@2x.png
+ rc/toolbar_move_horizontal_pressed.png
+ rc/toolbar_move_horizontal_pressed@2x.png
+ rc/toolbar_move_vertical.png
+ rc/toolbar_move_vertical@2x.png
+ rc/toolbar_move_vertical_disabled.png
+ rc/toolbar_move_vertical_disabled@2x.png
+ rc/toolbar_move_vertical_focus.png
+ rc/toolbar_move_vertical_focus@2x.png
+ rc/toolbar_move_vertical_pressed.png
+ rc/toolbar_move_vertical_pressed@2x.png
+ rc/toolbar_separator_horizontal.png
+ rc/toolbar_separator_horizontal@2x.png
+ rc/toolbar_separator_horizontal_disabled.png
+ rc/toolbar_separator_horizontal_disabled@2x.png
+ rc/toolbar_separator_horizontal_focus.png
+ rc/toolbar_separator_horizontal_focus@2x.png
+ rc/toolbar_separator_horizontal_pressed.png
+ rc/toolbar_separator_horizontal_pressed@2x.png
+ rc/toolbar_separator_vertical.png
+ rc/toolbar_separator_vertical@2x.png
+ rc/toolbar_separator_vertical_disabled.png
+ rc/toolbar_separator_vertical_disabled@2x.png
+ rc/toolbar_separator_vertical_focus.png
+ rc/toolbar_separator_vertical_focus@2x.png
+ rc/toolbar_separator_vertical_pressed.png
+ rc/toolbar_separator_vertical_pressed@2x.png
+ rc/transparent.png
+ rc/transparent@2x.png
+ rc/transparent_disabled.png
+ rc/transparent_disabled@2x.png
+ rc/transparent_focus.png
+ rc/transparent_focus@2x.png
+ rc/transparent_pressed.png
+ rc/transparent_pressed@2x.png
+ rc/window_close.png
+ rc/window_close@2x.png
+ rc/window_close_disabled.png
+ rc/window_close_disabled@2x.png
+ rc/window_close_focus.png
+ rc/window_close_focus@2x.png
+ rc/window_close_pressed.png
+ rc/window_close_pressed@2x.png
+ rc/window_grip.png
+ rc/window_grip@2x.png
+ rc/window_grip_disabled.png
+ rc/window_grip_disabled@2x.png
+ rc/window_grip_focus.png
+ rc/window_grip_focus@2x.png
+ rc/window_grip_pressed.png
+ rc/window_grip_pressed@2x.png
+ rc/window_minimize.png
+ rc/window_minimize@2x.png
+ rc/window_minimize_disabled.png
+ rc/window_minimize_disabled@2x.png
+ rc/window_minimize_focus.png
+ rc/window_minimize_focus@2x.png
+ rc/window_minimize_pressed.png
+ rc/window_minimize_pressed@2x.png
+ rc/window_undock.png
+ rc/window_undock@2x.png
+ rc/window_undock_disabled.png
+ rc/window_undock_disabled@2x.png
+ rc/window_undock_focus.png
+ rc/window_undock_focus@2x.png
+ rc/window_undock_pressed.png
+ rc/window_undock_pressed@2x.png
+
+
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/index.theme b/dist/qt_themes/qdarkstyle_midnight_blue/icons/index.theme
index 20f9f6d633..34c449f19a 100644
--- a/dist/qt_themes/qdarkstyle_midnight_blue/icons/index.theme
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/icons/index.theme
@@ -1,14 +1,4 @@
[Icon Theme]
Name=qdarkstyle_midnight_blue
-Comment=dark theme
-Inherits=colorful
-Directories=16x16,48x48,256x256
-
-[16x16]
-Size=16
-
-[48x48]
-Size=48
-
-[256x256]
-Size=256
+Comment=Dark theme (Midnight Blue style)
+Inherits=default_dark
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/style.qrc b/dist/qt_themes/qdarkstyle_midnight_blue/style.qrc
index dc3d7fecbd..0cdaefa035 100644
--- a/dist/qt_themes/qdarkstyle_midnight_blue/style.qrc
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/style.qrc
@@ -1,228 +1,5 @@
-
- icons/index.theme
- ../qdarkstyle/icons/16x16/lock.png
- ../qdarkstyle/icons/16x16/view-refresh.png
- ../qdarkstyle/icons/48x48/bad_folder.png
- ../qdarkstyle/icons/48x48/chip.png
- ../qdarkstyle/icons/48x48/folder.png
- ../qdarkstyle/icons/48x48/no_avatar.png
- ../qdarkstyle/icons/48x48/list-add.png
- ../qdarkstyle/icons/48x48/sd_card.png
- ../qdarkstyle/icons/48x48/star.png
- ../qdarkstyle/icons/256x256/plus_folder.png
-
-
- rc/arrow_down.png
- rc/arrow_down@2x.png
- rc/arrow_down_disabled.png
- rc/arrow_down_disabled@2x.png
- rc/arrow_down_focus.png
- rc/arrow_down_focus@2x.png
- rc/arrow_down_pressed.png
- rc/arrow_down_pressed@2x.png
- rc/arrow_left.png
- rc/arrow_left@2x.png
- rc/arrow_left_disabled.png
- rc/arrow_left_disabled@2x.png
- rc/arrow_left_focus.png
- rc/arrow_left_focus@2x.png
- rc/arrow_left_pressed.png
- rc/arrow_left_pressed@2x.png
- rc/arrow_right.png
- rc/arrow_right@2x.png
- rc/arrow_right_disabled.png
- rc/arrow_right_disabled@2x.png
- rc/arrow_right_focus.png
- rc/arrow_right_focus@2x.png
- rc/arrow_right_pressed.png
- rc/arrow_right_pressed@2x.png
- rc/arrow_up.png
- rc/arrow_up@2x.png
- rc/arrow_up_disabled.png
- rc/arrow_up_disabled@2x.png
- rc/arrow_up_focus.png
- rc/arrow_up_focus@2x.png
- rc/arrow_up_pressed.png
- rc/arrow_up_pressed@2x.png
- rc/base_icon.png
- rc/base_icon@2x.png
- rc/base_icon_disabled.png
- rc/base_icon_disabled@2x.png
- rc/base_icon_focus.png
- rc/base_icon_focus@2x.png
- rc/base_icon_pressed.png
- rc/base_icon_pressed@2x.png
- rc/branch_closed.png
- rc/branch_closed@2x.png
- rc/branch_closed_disabled.png
- rc/branch_closed_disabled@2x.png
- rc/branch_closed_focus.png
- rc/branch_closed_focus@2x.png
- rc/branch_closed_pressed.png
- rc/branch_closed_pressed@2x.png
- rc/branch_end.png
- rc/branch_end@2x.png
- rc/branch_end_disabled.png
- rc/branch_end_disabled@2x.png
- rc/branch_end_focus.png
- rc/branch_end_focus@2x.png
- rc/branch_end_pressed.png
- rc/branch_end_pressed@2x.png
- rc/branch_line.png
- rc/branch_line@2x.png
- rc/branch_line_disabled.png
- rc/branch_line_disabled@2x.png
- rc/branch_line_focus.png
- rc/branch_line_focus@2x.png
- rc/branch_line_pressed.png
- rc/branch_line_pressed@2x.png
- rc/branch_more.png
- rc/branch_more@2x.png
- rc/branch_more_disabled.png
- rc/branch_more_disabled@2x.png
- rc/branch_more_focus.png
- rc/branch_more_focus@2x.png
- rc/branch_more_pressed.png
- rc/branch_more_pressed@2x.png
- rc/branch_open.png
- rc/branch_open@2x.png
- rc/branch_open_disabled.png
- rc/branch_open_disabled@2x.png
- rc/branch_open_focus.png
- rc/branch_open_focus@2x.png
- rc/branch_open_pressed.png
- rc/branch_open_pressed@2x.png
- rc/checkbox_checked.png
- rc/checkbox_checked@2x.png
- rc/checkbox_checked_disabled.png
- rc/checkbox_checked_disabled@2x.png
- rc/checkbox_checked_focus.png
- rc/checkbox_checked_focus@2x.png
- rc/checkbox_checked_pressed.png
- rc/checkbox_checked_pressed@2x.png
- rc/checkbox_indeterminate.png
- rc/checkbox_indeterminate@2x.png
- rc/checkbox_indeterminate_disabled.png
- rc/checkbox_indeterminate_disabled@2x.png
- rc/checkbox_indeterminate_focus.png
- rc/checkbox_indeterminate_focus@2x.png
- rc/checkbox_indeterminate_pressed.png
- rc/checkbox_indeterminate_pressed@2x.png
- rc/checkbox_unchecked.png
- rc/checkbox_unchecked@2x.png
- rc/checkbox_unchecked_disabled.png
- rc/checkbox_unchecked_disabled@2x.png
- rc/checkbox_unchecked_focus.png
- rc/checkbox_unchecked_focus@2x.png
- rc/checkbox_unchecked_pressed.png
- rc/checkbox_unchecked_pressed@2x.png
- rc/line_horizontal.png
- rc/line_horizontal@2x.png
- rc/line_horizontal_disabled.png
- rc/line_horizontal_disabled@2x.png
- rc/line_horizontal_focus.png
- rc/line_horizontal_focus@2x.png
- rc/line_horizontal_pressed.png
- rc/line_horizontal_pressed@2x.png
- rc/line_vertical.png
- rc/line_vertical@2x.png
- rc/line_vertical_disabled.png
- rc/line_vertical_disabled@2x.png
- rc/line_vertical_focus.png
- rc/line_vertical_focus@2x.png
- rc/line_vertical_pressed.png
- rc/line_vertical_pressed@2x.png
- rc/radio_checked.png
- rc/radio_checked@2x.png
- rc/radio_checked_disabled.png
- rc/radio_checked_disabled@2x.png
- rc/radio_checked_focus.png
- rc/radio_checked_focus@2x.png
- rc/radio_checked_pressed.png
- rc/radio_checked_pressed@2x.png
- rc/radio_unchecked.png
- rc/radio_unchecked@2x.png
- rc/radio_unchecked_disabled.png
- rc/radio_unchecked_disabled@2x.png
- rc/radio_unchecked_focus.png
- rc/radio_unchecked_focus@2x.png
- rc/radio_unchecked_pressed.png
- rc/radio_unchecked_pressed@2x.png
- rc/toolbar_move_horizontal.png
- rc/toolbar_move_horizontal@2x.png
- rc/toolbar_move_horizontal_disabled.png
- rc/toolbar_move_horizontal_disabled@2x.png
- rc/toolbar_move_horizontal_focus.png
- rc/toolbar_move_horizontal_focus@2x.png
- rc/toolbar_move_horizontal_pressed.png
- rc/toolbar_move_horizontal_pressed@2x.png
- rc/toolbar_move_vertical.png
- rc/toolbar_move_vertical@2x.png
- rc/toolbar_move_vertical_disabled.png
- rc/toolbar_move_vertical_disabled@2x.png
- rc/toolbar_move_vertical_focus.png
- rc/toolbar_move_vertical_focus@2x.png
- rc/toolbar_move_vertical_pressed.png
- rc/toolbar_move_vertical_pressed@2x.png
- rc/toolbar_separator_horizontal.png
- rc/toolbar_separator_horizontal@2x.png
- rc/toolbar_separator_horizontal_disabled.png
- rc/toolbar_separator_horizontal_disabled@2x.png
- rc/toolbar_separator_horizontal_focus.png
- rc/toolbar_separator_horizontal_focus@2x.png
- rc/toolbar_separator_horizontal_pressed.png
- rc/toolbar_separator_horizontal_pressed@2x.png
- rc/toolbar_separator_vertical.png
- rc/toolbar_separator_vertical@2x.png
- rc/toolbar_separator_vertical_disabled.png
- rc/toolbar_separator_vertical_disabled@2x.png
- rc/toolbar_separator_vertical_focus.png
- rc/toolbar_separator_vertical_focus@2x.png
- rc/toolbar_separator_vertical_pressed.png
- rc/toolbar_separator_vertical_pressed@2x.png
- rc/transparent.png
- rc/transparent@2x.png
- rc/transparent_disabled.png
- rc/transparent_disabled@2x.png
- rc/transparent_focus.png
- rc/transparent_focus@2x.png
- rc/transparent_pressed.png
- rc/transparent_pressed@2x.png
- rc/window_close.png
- rc/window_close@2x.png
- rc/window_close_disabled.png
- rc/window_close_disabled@2x.png
- rc/window_close_focus.png
- rc/window_close_focus@2x.png
- rc/window_close_pressed.png
- rc/window_close_pressed@2x.png
- rc/window_grip.png
- rc/window_grip@2x.png
- rc/window_grip_disabled.png
- rc/window_grip_disabled@2x.png
- rc/window_grip_focus.png
- rc/window_grip_focus@2x.png
- rc/window_grip_pressed.png
- rc/window_grip_pressed@2x.png
- rc/window_minimize.png
- rc/window_minimize@2x.png
- rc/window_minimize_disabled.png
- rc/window_minimize_disabled@2x.png
- rc/window_minimize_focus.png
- rc/window_minimize_focus@2x.png
- rc/window_minimize_pressed.png
- rc/window_minimize_pressed@2x.png
- rc/window_undock.png
- rc/window_undock@2x.png
- rc/window_undock_disabled.png
- rc/window_undock_disabled@2x.png
- rc/window_undock_focus.png
- rc/window_undock_focus@2x.png
- rc/window_undock_pressed.png
- rc/window_undock_pressed@2x.png
-
-
- style.qss
-
+
+ dark.qss
+
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue_monochrome/icons.qrc b/dist/qt_themes/qdarkstyle_midnight_blue_monochrome/icons.qrc
new file mode 100644
index 0000000000..60b95db02a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue_monochrome/icons.qrc
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ icons/index.theme
+ ../monochrome_dark/icons/16x16/lock.png
+ ../monochrome_dark/icons/48x48/bad_folder.png
+ ../monochrome_dark/icons/48x48/chip.png
+ ../monochrome_dark/icons/48x48/folder.png
+ ../monochrome_dark/icons/48x48/list-add.png
+ ../monochrome_dark/icons/48x48/sd_card.png
+ ../monochrome_dark/icons/48x48/star.png
+ ../monochrome_dark/icons/256x256/plus_folder.png
+
+
+
+ icons/index.theme
+ ../monochrome_dark/icons/16x16/lock.png
+ ../monochrome_dark/icons/48x48/bad_folder.png
+ ../monochrome_dark/icons/48x48/chip.png
+ ../monochrome_dark/icons/48x48/folder.png
+ ../monochrome_dark/icons/48x48/list-add.png
+ ../monochrome_dark/icons/48x48/no_avatar.png
+ ../monochrome_dark/icons/48x48/sd_card.png
+ ../monochrome_dark/icons/48x48/star.png
+ ../monochrome_dark/icons/256x256/plus_folder.png
+
+
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue_monochrome/icons/index.theme b/dist/qt_themes/qdarkstyle_midnight_blue_monochrome/icons/index.theme
new file mode 100644
index 0000000000..d6ed7d55ec
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue_monochrome/icons/index.theme
@@ -0,0 +1,14 @@
+[Icon Theme]
+Name=qdarkstyle_midnight_blue_monochrome
+Comment=Monochrome dark theme (Midnight Blue style)
+Inherits=qdarkstyle_midnight_blue
+Directories=16x16,48x48,256x256
+
+[16x16]
+Size=16
+
+[48x48]
+Size=48
+
+[256x256]
+Size=256
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue_monochrome/style.qrc b/dist/qt_themes/qdarkstyle_midnight_blue_monochrome/style.qrc
new file mode 100644
index 0000000000..eeb5f34cbb
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue_monochrome/style.qrc
@@ -0,0 +1,8 @@
+
+
+ ../qdarkstyle_midnight_blue/dark.qss
+
+
+ ../qdarkstyle/dark.qss
+
+
diff --git a/dist/qt_themes/qdarkstyle_monochrome/icons.qrc b/dist/qt_themes/qdarkstyle_monochrome/icons.qrc
new file mode 100644
index 0000000000..355fe22beb
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_monochrome/icons.qrc
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ icons/index.theme
+ ../monochrome_dark/icons/16x16/lock.png
+ ../monochrome_dark/icons/48x48/bad_folder.png
+ ../monochrome_dark/icons/48x48/chip.png
+ ../monochrome_dark/icons/48x48/folder.png
+ ../monochrome_dark/icons/48x48/list-add.png
+ ../monochrome_dark/icons/48x48/sd_card.png
+ ../monochrome_dark/icons/48x48/star.png
+ ../monochrome_dark/icons/256x256/plus_folder.png
+
+
+
+ icons/index.theme
+ ../monochrome_dark/icons/16x16/lock.png
+ ../monochrome_dark/icons/48x48/bad_folder.png
+ ../monochrome_dark/icons/48x48/chip.png
+ ../monochrome_dark/icons/48x48/folder.png
+ ../monochrome_dark/icons/48x48/list-add.png
+ ../monochrome_dark/icons/48x48/no_avatar.png
+ ../monochrome_dark/icons/48x48/sd_card.png
+ ../monochrome_dark/icons/48x48/star.png
+ ../monochrome_dark/icons/256x256/plus_folder.png
+
+
diff --git a/dist/qt_themes/qdarkstyle_monochrome/icons/index.theme b/dist/qt_themes/qdarkstyle_monochrome/icons/index.theme
new file mode 100644
index 0000000000..a8fd60ba29
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_monochrome/icons/index.theme
@@ -0,0 +1,14 @@
+[Icon Theme]
+Name=qdarkstyle_monochrome
+Comment=Monochrome dark theme (Mine Shaft style)
+Inherits=qdarkstyle
+Directories=16x16,48x48,256x256
+
+[16x16]
+Size=16
+
+[48x48]
+Size=48
+
+[256x256]
+Size=256
diff --git a/dist/qt_themes/qdarkstyle_monochrome/style.qrc b/dist/qt_themes/qdarkstyle_monochrome/style.qrc
new file mode 100644
index 0000000000..76f7767ca8
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_monochrome/style.qrc
@@ -0,0 +1,8 @@
+
+
+ ../qdarkstyle/dark.qss
+
+
+ ../qdarkstyle/dark.qss
+
+
diff --git a/img/need to fix bugs.png b/img/need to fix bugs.png
new file mode 100644
index 0000000000..124c55c91a
Binary files /dev/null and b/img/need to fix bugs.png differ
diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts
index 78f8cc3488..9312d48c33 100644
--- a/src/android/app/build.gradle.kts
+++ b/src/android/app/build.gradle.kts
@@ -25,7 +25,7 @@ val autoVersion = (((System.currentTimeMillis() / 1000) - 1451606400) / 10).toIn
@Suppress("UnstableApiUsage")
android {
- namespace = "org.suyu.suyu_emu"
+ namespace = "dev.suyu.suyu_emu"
compileSdkVersion = "android-34"
ndkVersion = "26.1.10909125"
@@ -54,7 +54,7 @@ android {
defaultConfig {
// TODO If this is ever modified, change application_id in strings.xml
- applicationId = "org.suyu.suyu_emu"
+ applicationId = "dev.suyu.suyu_emu"
minSdk = 30
targetSdk = 34
versionName = getGitVersion()
diff --git a/src/android/app/src/main/AndroidManifest.xml b/src/android/app/src/main/AndroidManifest.xml
index 02d08c00be..5f893cd986 100644
--- a/src/android/app/src/main/AndroidManifest.xml
+++ b/src/android/app/src/main/AndroidManifest.xml
@@ -17,7 +17,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
@@ -48,12 +48,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
() {
diff --git a/src/android/app/src/main/java/org/suyu/suyu_emu/adapters/AppletAdapter.kt b/src/android/app/src/main/java/dev/suyu/suyu_emu/adapters/AppletAdapter.kt
similarity index 84%
rename from src/android/app/src/main/java/org/suyu/suyu_emu/adapters/AppletAdapter.kt
rename to src/android/app/src/main/java/dev/suyu/suyu_emu/adapters/AppletAdapter.kt
index 73c43a6d2c..c6d373f7a5 100644
--- a/src/android/app/src/main/java/org/suyu/suyu_emu/adapters/AppletAdapter.kt
+++ b/src/android/app/src/main/java/dev/suyu/suyu_emu/adapters/AppletAdapter.kt
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-package org.suyu.suyu_emu.adapters
+package dev.suyu.suyu_emu.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
@@ -9,15 +9,15 @@ import android.widget.Toast
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.FragmentActivity
import androidx.navigation.findNavController
-import org.suyu.suyu_emu.HomeNavigationDirections
-import org.suyu.suyu_emu.NativeLibrary
-import org.suyu.suyu_emu.R
-import org.suyu.suyu_emu.SuyuApplication
-import org.suyu.suyu_emu.databinding.CardSimpleOutlinedBinding
-import org.suyu.suyu_emu.model.Applet
-import org.suyu.suyu_emu.model.AppletInfo
-import org.suyu.suyu_emu.model.Game
-import org.suyu.suyu_emu.viewholder.AbstractViewHolder
+import dev.suyu.suyu_emu.HomeNavigationDirections
+import dev.suyu.suyu_emu.NativeLibrary
+import dev.suyu.suyu_emu.R
+import dev.suyu.suyu_emu.SuyuApplication
+import dev.suyu.suyu_emu.databinding.CardSimpleOutlinedBinding
+import dev.suyu.suyu_emu.model.Applet
+import dev.suyu.suyu_emu.model.AppletInfo
+import dev.suyu.suyu_emu.model.Game
+import dev.suyu.suyu_emu.viewholder.AbstractViewHolder
class AppletAdapter(val activity: FragmentActivity, applets: List
+ app:argType="dev.suyu.suyu_emu.features.settings.model.Settings$MenuTag" />
+ app:argType="dev.suyu.suyu_emu.model.Game" />
@@ -157,19 +157,19 @@
app:destination="@id/perGamePropertiesFragment" />
+ app:argType="dev.suyu.suyu_emu.model.Game" />
+ app:argType="dev.suyu.suyu_emu.model.Game" />
diff --git a/src/android/app/src/main/res/navigation/settings_navigation.xml b/src/android/app/src/main/res/navigation/settings_navigation.xml
index 94ba7b61a6..31993fb171 100644
--- a/src/android/app/src/main/res/navigation/settings_navigation.xml
+++ b/src/android/app/src/main/res/navigation/settings_navigation.xml
@@ -6,14 +6,14 @@
+ app:argType="dev.suyu.suyu_emu.features.settings.model.Settings$MenuTag" />
diff --git a/src/android/app/src/main/res/values-ar/strings.xml b/src/android/app/src/main/res/values-ar/strings.xml
index 2eacae1d5c..3369a613ce 100644
--- a/src/android/app/src/main/res/values-ar/strings.xml
+++ b/src/android/app/src/main/res/values-ar/strings.xml
@@ -34,7 +34,7 @@
يسمح لـ يوزو بملء قائمة الألعابتخطي تحديد مجلد الألعاب؟لن يتم عرض الألعاب في قائمة الألعاب إذا لم يتم تحديد مجلد
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesالبحث عن ألعابإعدادات البحثتم تحديد مجلد الألعاب
@@ -42,7 +42,7 @@
مطلوب لفك تشفير ألعاب البيع بالتجزئةتخطي إضافة المفاتيح؟مطلوب مفاتيح صالحة لمحاكاة ألعاب البيع بالتجزئة. ستعمل تطبيقات البيرة المنزلية فقط إذا تابعت
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionالإشعاراتامنح إذن الإشعار باستخدام الزر أدناهمنح الإذن
@@ -63,7 +63,7 @@
وحاول مرة أخر keys تحقق من أن ملف المفاتيح له امتدادوحاول مرة أخر bin تحقق من أن ملف المفاتيح له امتدادمفاتيح التشفير غير صالحة
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysالملف المحدد غير صحيح أو تالف. يرجى إعادة المفاتيح الخاصة بكGPU مدير برنامج تشغيلGPU تثبيت برنامج تشغيل
@@ -107,7 +107,7 @@
لا يُسمح بتثبيت الألعاب الأساسية لتجنب التعارضات المحتملة.%1$d تم التثبيت بنجاح%1$d تمت الكتابة فوقه بنجاح
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesبرامج التشغيل المخصصة غير مدعومةتحميل برنامج التشغيل المخصص غير معتمد حاليًا لهذا الجهاز.\nحدد هذا الخيار مرة أخرى في المستقبل لمعرفة ما إذا تمت إضافة الدعم!إدارة بيانات يوزو
@@ -137,7 +137,7 @@
محاكي سويتش مفتوح المصدرالمساهمينمصنوع من فريق يوزو
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/المشاريع التي تجعل تطبيق يوزو لنظام أندرويد ممكنًاالبناءبيانات المستخدم
@@ -149,9 +149,9 @@
تم تصدير بيانات المستخدم بنجاحتم استيراد بيانات المستخدم بنجاحتم إلغاء التصدير
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/الوصول المبكر
diff --git a/src/android/app/src/main/res/values-ckb/strings.xml b/src/android/app/src/main/res/values-ckb/strings.xml
index bb630f934a..c294233f42 100644
--- a/src/android/app/src/main/res/values-ckb/strings.xml
+++ b/src/android/app/src/main/res/values-ckb/strings.xml
@@ -1,7 +1,7 @@
- ئەم نەرمەکاڵایە یارییەکانی کۆنسۆلی نینتێندۆ سویچ کارپێدەکات. هیچ ناونیشانێکی یاری و کلیلی تێدا نییە..<br /><br />پێش ئەوەی دەست پێ بکەیت، تکایە شوێنی فایلی prod.keys ]]> دیاریبکە لە نێو کۆگای ئامێرەکەت.<br /><br />زیاتر فێربە]]>
+ ئەم نەرمەکاڵایە یارییەکانی کۆنسۆلی نینتێندۆ سویچ کارپێدەکات. هیچ ناونیشانێکی یاری و کلیلی تێدا نییە..<br /><br />پێش ئەوەی دەست پێ بکەیت، تکایە شوێنی فایلی prod.keys ]]> دیاریبکە لە نێو کۆگای ئامێرەکەت.<br /><br />زیاتر فێربە]]>ئاگاداری و هەڵەکانئاگادارکردنەوەکان پیشان دەدات کاتێک شتێک بە هەڵەدا دەچێت.مۆڵەتی ئاگادارکردنەوە نەدراوە!
@@ -32,14 +32,14 @@
ڕێگە بە یوزو دەدات بۆ پڕکردنەوەی لیستی یارییەکانهەڵبژاردنی فۆڵدەری یارییەکان تێپەڕدەکەیت؟یارییەکان لە لیستی یارییەکاندا پیشان نادرێن ئەگەر فۆڵدەرێک هەڵنەبژێردرێت.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesگەڕان بەدوای یارییەکانداناونیشانی یارییەکان هەڵبژێردرادابمەزرێنە prod.keysپێویستە بۆ کۆدکردنەوەى یارییە تاکەکەسییەکانزیادکردنی کلیلەکان تێپەڕدەکەیت؟کلیلی دروست پێویستە بۆ وەرگرتنی یارییەکانی تاکەکەسی. تەنها ئەپەکانی homebrew کاردەکەن ئەگەر بەردەوام بیت.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionئاگادارکردنەوەکانبە دوگمەی خوارەوە مۆڵەتی ئاگادارکردنەوەکە بدە.مۆڵەت بدە
@@ -60,7 +60,7 @@
دڵنیابەوە کە فایلی کلیلەکانت درێژکراوەی .keys ی هەیە و دووبارە هەوڵبدەرەوە.دڵنیابە کە فایلی کلیلەکانت درێژکراوەی .bin ی هەیە و دووبارە هەوڵبدەرەوە.کلیلی کۆدکردنی نادروستە
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysفایلە هەڵبژێردراوەکە هەڵەیە یان تێکچووە. تکایە دووبارە کلیلەکانت دەربێنەوە.دامەزراندنی وەگەڕخەری GPUدامەزراندنی وەگەڕخەری بەدیل بۆ ئەوەی بە ئەگەرێکی زۆرەوە کارایی باشتر یان وردبینی هەبێت
@@ -94,8 +94,8 @@
هیچ فایلێکی لۆگ نەدۆزراوەدامەزراندنی ناوەڕۆکی یاریدامەزراندنی نوێکاری یارییەکان یان DLC
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysگایا ڕاستەقینە نییە
@@ -103,12 +103,12 @@
ئیمۆلیتەرێکی سەرچاوە-کراوەی سویچبەشداربوواندروستکراوە لەگەڵ \u2764 لەلایەن تیمەکەی یوزو
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/ئەو پڕۆژانەی کە یوزوی بۆ ئەندرۆید ڕەخساندبونیات
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/بەزوویی دەسپێگەشتن
@@ -246,7 +246,7 @@
وەشانڕۆمەکەت کۆدکراوە
- prod.keys فایلەکەت بۆ ئەوەی بتوانرێت یارییەکان کۆد بکرێنەوە.]]>
+ prod.keys فایلەکەت بۆ ئەوەی بتوانرێت یارییەکان کۆد بکرێنەوە.]]>هەڵەیەک لە دەستپێکردنی ناوەکی ڤیدیۆکەدا ڕوویدائەمەش بەزۆری بەهۆی وەگەڕخەرێکی ناتەبای GPU ەوەیە. دامەزراندنی وەگەڕخەری GPU ی تایبەتمەندکراو لەوانەیە ئەم کێشەیە چارەسەر بکات.ناتوانرێت ڕۆم باربکرێت
diff --git a/src/android/app/src/main/res/values-cs/strings.xml b/src/android/app/src/main/res/values-cs/strings.xml
index 6d09b552cd..865fb76f5e 100644
--- a/src/android/app/src/main/res/values-cs/strings.xml
+++ b/src/android/app/src/main/res/values-cs/strings.xml
@@ -26,10 +26,10 @@
Hledat a filtrovat hryVybrat složku s hramiSpravovat složky s hrami
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesInstalovat prod.keysPřeskočit přidávání klíčů?
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionOznámeníUdělit oprávněníPřeskočit udělení oprávnění k oznámení?
@@ -47,7 +47,7 @@
Klíče úspěšně nainstaloványChyba při čtení šifrovacích klíčůNeplatné šifrovací klíče
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysSprávce ovladače GPUInstalovat GPU ovladačPokročilé nastavení
@@ -86,7 +86,7 @@
Open-source Switch emulátorPřispěvateléVyrobeno s \u2764 od suyu týmu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Číslo sestaveníUživatelská dataExportování uživatelských dat...
@@ -96,9 +96,9 @@
Uživatelská data byla úspěšně exportována.Uživatelská data byla úspěšně importována.Export zrušen
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/https://play.google.com/store/apps/details?id=org.suyu.suyu_emu.eaŽádná manuální instalace
diff --git a/src/android/app/src/main/res/values-de/strings.xml b/src/android/app/src/main/res/values-de/strings.xml
index 8a69115433..4f4f34630a 100644
--- a/src/android/app/src/main/res/values-de/strings.xml
+++ b/src/android/app/src/main/res/values-de/strings.xml
@@ -1,7 +1,7 @@
- Diese Software kann Spiele für die Nintendo Switch abspielen. Keine Spiele oder Spielekeys sind enthalten.<br /><br />Bevor du beginnst, bitte halte deine prod.keys ]]> auf deinem Gerät bereit. .<br /><br />Mehr Infos]]>
+ Diese Software kann Spiele für die Nintendo Switch abspielen. Keine Spiele oder Spielekeys sind enthalten.<br /><br />Bevor du beginnst, bitte halte deine prod.keys ]]> auf deinem Gerät bereit. .<br /><br />Mehr Infos]]>Hinweise und FehlerZeigt Benachrichtigungen an, wenn etwas schief läuft.Berechtigung für Benachrichtigungen nicht erlaubt!
@@ -35,7 +35,7 @@
Erlaubt suyu die Spieleliste zu füllenAuswahl des Spieleverzeichnisses überspringen?Spiele werden in der Spieleliste nicht angezeigt, wenn kein Ordner ausgewählt ist.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesSpiele suchenEinstellungen suchenSpieleverzeichnis ausgewählt
@@ -43,7 +43,7 @@
Zum Entschlüsseln von Spielen benötigtHinzufügen der Schlüssel überspringen?Für die Emulation von Spielen sind gültige Schlüssel erforderlich. Wenn du fortfährst, funktionieren nur Homebrew-Anwendungen.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionBenachrichtigungenErteile mit dem Knopf unten die Berechtigung, Benachrichtigungen zu senden.Berechtigung erteilen
@@ -63,7 +63,7 @@
Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".keys\" hat, und versuchen Sie es erneut.Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".bin\" hat, und versuchen Sie es erneut.Ungültige Schlüssel
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysDie ausgewählte Datei ist falsch oder beschädigt. Bitte kopieren Sie Ihre Schlüssel erneut.GPU-Treiber VerwaltungGPU-Treiber installieren
@@ -108,12 +108,12 @@ Wirklich fortfahren?
%1$d Installationsfehler%1$d erfolgreich installiert%1$d erfolgreich überschrieben
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatessuyu-Daten VerwaltenSpeicherdaten teilenSpiele-OrdnerSpiele-Ordner hinzufügen
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysFirmware nicht installiert
@@ -122,7 +122,7 @@ Wirklich fortfahren?
Ein quelloffener Switch-EmulatorBeitragendeGemacht mit \u2764 vom suyu Team
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Projekte, die suyu für Android möglich machen BuildNutzerdaten
@@ -131,9 +131,9 @@ Wirklich fortfahren?
Nutzerdaten erfolgreich exportiertNutzerdaten erfolgreich importiertExport abgebrochen
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Early Access
@@ -319,7 +319,7 @@ Wirklich fortfahren?
Integritätsüberprüfung konnte nicht durchgeführt werdenDas ROM ist verschlüsselt
- prod.keys Datei installiert ist, damit Spiele entschlüsselt werden können.]]>
+ prod.keys Datei installiert ist, damit Spiele entschlüsselt werden können.]]>Bei der Initialisierung des Videokerns ist ein Fehler aufgetretenDies wird normalerweise durch einen inkompatiblen GPU-Treiber verursacht. Die Installation eines passenden GPU-Treibers kann dieses Problem beheben.ROM konnte nicht geladen werden
diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml
index ebe05df24a..8f401ce1bd 100644
--- a/src/android/app/src/main/res/values-es/strings.xml
+++ b/src/android/app/src/main/res/values-es/strings.xml
@@ -1,7 +1,7 @@
- Este software ejecuta juegos para la videoconsola Nintendo Switch. Los videojuegos o claves no vienen incluidos.<br /><br />Antes de empezar, por favor, localice el archivo prod.keys ]]>en el almacenamiento de su dispositivo..<br /><br />Saber más]]>
+ Este software ejecuta juegos para la videoconsola Nintendo Switch. Los videojuegos o claves no vienen incluidos.<br /><br />Antes de empezar, por favor, localice el archivo prod.keys ]]>en el almacenamiento de su dispositivo..<br /><br />Saber más]]>Avisos y erroresMostrar notificaciones cuándo algo vaya mal.¡Permisos de notificación no concedidos!
@@ -35,7 +35,7 @@
Permite que suyu llene la lista de juegos¿Omitir la selección de la carpeta de juegos?No se mostrará ningún juego si no se ha seleccionado una carpeta de juegos.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesBuscar juegosBuscar configuraciónDirectorio de juegos seleccionado
@@ -43,7 +43,7 @@
Requerido para descifrar juegos¿Omitir agregar claves?Se requieren claves válidas para emular juegos. Solo las aplicaciones homebrew funcionarán si continúas.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionNotificacionesOtorga el permiso de notificación con el botón de abajo.Conceder permiso
@@ -64,7 +64,7 @@
Compruebe que el archivo de claves tenga una extensión .keys y pruebe otra vez.Compruebe que el archivo de claves tenga una extensión .bin y pruebe otra vez.Claves de cifrado no válidas
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysEl archivo seleccionado es incorrecto o está corrupto. Vuelva a redumpear sus claves.Explorador de drivers de GPUInstalar driver de GPU
@@ -114,7 +114,7 @@
Contenido(s) de juego instalado/s con éxito%1$d instalado con éxito%1$d sobreescrito con éxito
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesDrivers personalizados no soportadosEn estos momentos, la carga de drivers personalizados no está disponible para este dispositivo..\n¡Comprueba esta opción en el futuro para ver si ya está añadido el soporte a ese dispositivo!Administrar datos de suyu
@@ -141,14 +141,14 @@
Comprueba todo el contenido instalado por si hubiese alguno corruptoFaltan las claves de encriptaciónEl firmware y los juegos no se pueden desencriptar
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysEjecutador de appletEjecutar applets de sistema usando el firmware instaladoFirmware no instaladoApplet no disponible
- prod.keys y el firmware estén instalados e inténtelo de nuevo.]]>
+ prod.keys y el firmware estén instalados e inténtelo de nuevo.]]>ÁlbumVer las imágenes que están en la carpeta \"screenshots\" del usuario con el visor de fotos del sistemaEditor de Mii
@@ -167,7 +167,7 @@
Un emulador de Switch de código abiertoContribuidoresHecho con \u2764 del equipo suyu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Proyectos que hacen que suyu para Android sea una realidadVersiónDatos de usuario
@@ -180,9 +180,9 @@
Datos de usuario importados con éxitoExportación canceladaAsegúrese de que las carpetas de datos de usuario estén en la raíz de la carpeta del zip y contengan un archivo config en config/config.ini e inténtelo de nuevo.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Early Access
@@ -410,8 +410,8 @@
Su ROM está encriptada
- cartuchos de juegos o títulos instalados.]]>
- prod.keys está instalado, para que los juegos sean descifrados.]]>
+ cartuchos de juegos o títulos instalados.]]>
+ prod.keys está instalado, para que los juegos sean descifrados.]]>Ocurrió un error al inicializar el núcleo de video, posiblemente debido a una incompatibilidad con el driver seleccionadoEsto suele deberse a un driver de GPU incompatible. La instalación de un controlador de GPU personalizado puede resolver este problema.No se pudo cargar la ROM
diff --git a/src/android/app/src/main/res/values-fa/strings.xml b/src/android/app/src/main/res/values-fa/strings.xml
index 8112b8a853..a63c32e059 100644
--- a/src/android/app/src/main/res/values-fa/strings.xml
+++ b/src/android/app/src/main/res/values-fa/strings.xml
@@ -35,7 +35,7 @@
به suyu اجازه می دهد تا لیست بازیها را پر کنداز انتخاب پوشه بازی رد میشوید؟اگر پوشهای انتخاب نشده باشد، بازیها در لیست بازیها نمایش داده نمیشوند.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesجستجو در بازیهاجستجو در تنظیماتپوشه بازیها انتخاب شد
@@ -43,7 +43,7 @@
برای رمزگشایی بازیهای فروشگاهی مورد نیاز استافزودن کلیدها را رد میکنید؟کلیدهای معتبر برای شبیهسازی بازیهای فروشگاهی مورد نیاز است. اگر ادامه دهید، فقط برنامههای سیستم ریزکامپیوتری کار خواهند کرد.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionاعلانهامجوز اعلان را با دکمه زیر اعطا کنید.اجازه بدهید
@@ -64,7 +64,7 @@
بررسی کنید که فایل کلیدهای شما دارای پسوند keys. باشد و دوباره امتحان کنید.بررسی کنید که فایل کلیدهای شما دارای پسوند bin. باشد و دوباره امتحان کنید.کلیدهای رمزگذاری نامعتبر
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysفایل انتخابی نادرست یا خراب است. لطفا کلیدهای خود را دوباره استخراج کنید.مدیریت درایور پردازنده گرافیکینصب درایور پردازنده گرافیکی
@@ -114,7 +114,7 @@
محتوا(های) بازی با موفقیت نصب شد%1$dبا موفقیت نصب شد%1$dبا موفقیت بازنویسی شد
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesدرایورهای سفارشی پشتیبانی نمیشوندبارگیری درایور سفارشی در حال حاضر برای این دستگاه پشتیبانی نمیشود.\nاین گزینه را دوباره در آینده بررسی کنید تا ببینید آیا پشتیبانی اضافه شده است یا خیر!مدیریت دادههای suyu
@@ -139,14 +139,14 @@
تمام محتوای نصب شده را از نظر خرابی بررسی میکندکلیدهای رمزگذاری وجود ندارندثابتافزار و بازیهای فروشگاهی قابل رمزگشایی نیستند
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysاجراکننده برنامکبرنامکهای سیستم را با استفاده از ثابتافزار نصب شده راه اندازی کنیدثابتافزار نصب نیستبرنامک در دسترس نیست
- prod.keys و ثابتافزار شما نصب شده است و دوباره امتحان کنید.]]>
+ prod.keys و ثابتافزار شما نصب شده است و دوباره امتحان کنید.]]>آلبومتصاویر ذخیره شده در پوشه اسکرین شاتهای کاربر را با نمایشگر عکس سیستم مشاهده کنیدویرایش Mii
@@ -165,7 +165,7 @@
یک شبیهساز سوئیچ منبع بازمشارکت کنندگانMade with \u2764 from the suyu team
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/پروژههایی که suyu را برای اندروید ممکن میسازندساختداده کاربر
@@ -178,9 +178,9 @@
دادههای کاربر با موفقیت وارد شدصدور لغو شدمطمئن شوید که پوشههای داده کاربر در ریشه پوشه zip و حاوی یک فایل پیکربندی در config/config.ini هستند سپس دوباره امتحان کنید.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/دسترسی زودهنگام
@@ -410,7 +410,7 @@
رام شما رمزگذاری شده است
- کارتیجهای بازی یا عناوین نصب شده خود را استخراج کنید.]]>
+ کارتیجهای بازی یا عناوین نصب شده خود را استخراج کنید.]]>در راهاندازی اولیه هسته ویدیو خطایی رخ داداین مورد معمولاً توسط یک درایور گرافیکی ناسازگار ایجاد میشود. نصب درایور گرافیکی سفارشی ممکن است این مشکل را حل کند.
diff --git a/src/android/app/src/main/res/values-fr/strings.xml b/src/android/app/src/main/res/values-fr/strings.xml
index f98ea6a35f..d1a36c0f79 100644
--- a/src/android/app/src/main/res/values-fr/strings.xml
+++ b/src/android/app/src/main/res/values-fr/strings.xml
@@ -1,7 +1,7 @@
- Ce logiciel exécutera des jeux pour la console de jeu Nintendo Switch. Aucun jeux ou clés n\'est inclus.<br /><br />Avant de commencer, veuillez localiser votre fichier prod.keys ]]> sur le stockage de votre appareil.<br /><br />En savoir plus]]>
+ Ce logiciel exécutera des jeux pour la console de jeu Nintendo Switch. Aucun jeux ou clés n\'est inclus.<br /><br />Avant de commencer, veuillez localiser votre fichier prod.keys ]]> sur le stockage de votre appareil.<br /><br />En savoir plus]]>Avis et erreursAffiche des notifications en cas de problème.Permission de notification non accordée !
@@ -35,7 +35,7 @@
Permet à suyu de remplir la liste des jeuxNe pas sélectionner le dossier des jeux ?Les jeux ne seront pas affichés dans la liste des jeux si aucun dossier n\'est sélectionné.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesRechercher des jeuxRechercher un paramètreRépertoire de jeux sélectionné
@@ -43,7 +43,7 @@
Nécessaire pour décrypter les jeux commerciaux.Sauter l\'ajout des clés ?Des clés valides sont nécessaires pour émuler des jeux commerciaux. Seules les applications homebrew fonctionneront si vous continuez.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionNotificationsAccorder la permission de notification avec le bouton ci-dessous.Accorder la permission
@@ -64,7 +64,7 @@
Vérifiez que votre fichier de clés a une extension .keys et réessayez.Vérifiez que votre fichier de clés a une extension .bin et réessayez.Clés de chiffrement invalides
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysLe fichier sélectionné est incorrect ou corrompu. Veuillez dumper à nouveau vos clés.Gestionnaire de pilotes du GPUInstaller le pilote du GPU
@@ -114,7 +114,7 @@
Contenu du jeu installé avec succès%1$d installé avec succès%1$d écrasé avec succès
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesPilotes personnalisés non supportéLe chargement des pilotes personnalisés ne sont pas actuellement pris en charge pour ce périphérique. Vérifiez à nouveau cette option à l\'avenir pour voir si la prise en charge a été ajoutée !Gérer les données de suyu
@@ -141,14 +141,14 @@
Vérifie l\'intégrité des contenus installésLes clés de chiffrement sont manquantes.Le firmware et les jeux commerciaux ne peuvent pas être déchiffrés
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysLanceur d\'appletsLancer des applets système en utilisant le firmware installéFirmware non installéApplet non disponible
- prod.keys et le firmware sont installés et essayez à nouveau.]]>
+ prod.keys et le firmware sont installés et essayez à nouveau.]]>AlbumAfficher les images stockées dans le dossier de captures d\'écran de l\'utilisateur avec le visualiseur de photos système.Éditeur Mii
@@ -167,7 +167,7 @@
Un émulateur Switch open sourceContributeursFait avec \u2764 de l\'équipe suyu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Des projets qui rendent possible suyu pour AndroidBuildDonnées utilisateur
@@ -180,9 +180,9 @@
Les données utilisateur ont été importées avec succèsExportation annuléeAssurez-vous que les dossiers de données utilisateur se trouvent à la racine du dossier ZIP et contiennent un fichier de configuration à config/config.ini, puis réessayez.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Early Access
@@ -460,8 +460,8 @@
Votre ROM est cryptée
- cartouches de jeu ou de vos titres installés.]]>
- prod.keys est installé pour que les jeux puissent être déchiffrés.]]>
+ cartouches de jeu ou de vos titres installés.]]>
+ prod.keys est installé pour que les jeux puissent être déchiffrés.]]>Une erreur s\'est produite lors de l\'initialisation du noyau vidéoCela est généralement dû à un pilote GPU incompatible. L\'installation d\'un pilote GPU personnalisé peut résoudre ce problème.Impossible de charger la ROM
diff --git a/src/android/app/src/main/res/values-he/strings.xml b/src/android/app/src/main/res/values-he/strings.xml
index f1087d6131..fb5163268c 100644
--- a/src/android/app/src/main/res/values-he/strings.xml
+++ b/src/android/app/src/main/res/values-he/strings.xml
@@ -1,7 +1,7 @@
- התוכנה תריץ משחקים לקונסולת ה Nintendo Switch. אף משחק או קבצים בעלי זכויות יוצרים נכללים.<br /><br /> לפני שאת/ה מתחיל בבקשה מצא את קובץ prod.keys]]> על המכשיר.<br /><br />קרא עוד]]>
+ התוכנה תריץ משחקים לקונסולת ה Nintendo Switch. אף משחק או קבצים בעלי זכויות יוצרים נכללים.<br /><br /> לפני שאת/ה מתחיל בבקשה מצא את קובץ prod.keys]]> על המכשיר.<br /><br />קרא עוד]]>התראות ותקלותמציג התראות כאשר משהו הולך לא כשורה.הרשאות התראות לא ניתנה!
@@ -35,7 +35,7 @@
אפשר ל suyu לאכלס את רשימת המשחקיםלדלג על בחירת תיקיית המשחקים?משחקים לא יוצגו ברשימת המשחקים אם לנבחרה תיקיית משחקים.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesחפש משחקיםחפש בהגדרותספריית משחקים נבחרה
@@ -43,7 +43,7 @@
הכרחי בכדי לפענח משחקיםלדלג על הוספת מפתחות?מפתחות חוקיים הכרחיים כדי לשחק במשחקים. רק אפליקציות פירטיות יפעלו אם תמשיך.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionהתראותתן גישה להתראות עם הכפתור למטה.תן הרשאה
@@ -64,7 +64,7 @@
ודא שלקובץ המפתחות שלך יש סיומת של key. ונסה/י שוב.ודא/י שלקובץ המפתחות שלך יש סיומת של bin. ונסה/י שוב.מפתחות הצפנה לא חוקיים
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysקבוץ שנבחר מושחת או לא נכון. בבקשה הוצא מחדש את המפתחות שלך.מנהל הדרייברים של המעבד הגרפיהתקן דרייבר למעבד הגרפי
@@ -114,7 +114,7 @@
תוכן (או תכני) המשחק הותקנו בהצלחה%1$d הותקן בהצלחה%1$d נדרס/נכתב מעל בהצלחה
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesדרייברים מותאמים אישית לא נתמכיםהטענת דרייבים מותאמים אישית לא נתמך כרגע על מכשיר זה. \nבבקשה בדוק אופציה זו בעתיד בכדי לראות אם נוספה תמיכה!נהל את המידע של suyu
@@ -126,14 +126,14 @@
הוסף תיקיית משחקיםהתיקייה הזו נוספה כבר!מאפייני תיקיית משחקים
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysמשגר Appletמערכת שיגור Applet משתמשת בתוכנה המותקנתה Firmware לא מותקןApplet לא זמין
- prod.keysו firmwareשלך מותקנים ונסה שוב.]]>
+ prod.keysו firmwareשלך מותקנים ונסה שוב.]]>אלבוםצפה בתמונות השמורות בתיקיית צילומי המסך של המשתמש בעזרת מציג התמונות של המערכתעורך Mii
@@ -152,7 +152,7 @@
אמולטור Switch עם קוד פתוחתורמיםנוצר עם \u2764 מקבוצת suyu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/פרוייקטים שהופכים את suyu ל Android אפשריגרסהנתוני משתמש
@@ -165,9 +165,9 @@
נתוני משתמש יובאו בהצלחהייצוא בוטלודא שנתוני המשתמש נמצאים בשורש קובץ ה zip ושהוא מכיל קובץ סידור ב config/config.ini ונסה שוב.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/גישה מוקדמת
@@ -325,8 +325,8 @@
אימות התקינות הצליח!המשחק שלך מוצפן
- כרטיסי המשחקאו הכותרות המותקנות שלך.]]>
- prod.keys מותקן כך שניתן יהיה לפענח משחקים.]]>
+ כרטיסי המשחקאו הכותרות המותקנות שלך.]]>
+ prod.keys מותקן כך שניתן יהיה לפענח משחקים.]]>התרחשה בעיה באתחול של ליבת הווידאוזה בדרך כלל נגרם על ידי דרייבר לא מתאים עבור המעבד הגרפי. התקנת דרייבר אשר מתאים למעבד הגרפי יכול לפתור את הבעיה הזו.אין אפשרות לטעון את המשחק
diff --git a/src/android/app/src/main/res/values-hu/strings.xml b/src/android/app/src/main/res/values-hu/strings.xml
index 098d65f9fa..073c41f6a9 100644
--- a/src/android/app/src/main/res/values-hu/strings.xml
+++ b/src/android/app/src/main/res/values-hu/strings.xml
@@ -1,7 +1,7 @@
- Ez a szoftver Nintendo Switch játékkonzolhoz készült játékokat futtat. Nem tartalmaz játékokat vagy kulcsokat. .<br /><br />Mielőtt hozzákezdenél, kérjük, válaszd ki a prod.keys]]> fájl helyét a készülék tárhelyén<br /><br />Tudj meg többet]]>
+ Ez a szoftver Nintendo Switch játékkonzolhoz készült játékokat futtat. Nem tartalmaz játékokat vagy kulcsokat. .<br /><br />Mielőtt hozzákezdenél, kérjük, válaszd ki a prod.keys]]> fájl helyét a készülék tárhelyén<br /><br />Tudj meg többet]]>Megjegyzések és hibákÉrtesítések megjelenítése, ha valami rosszul sül el.Nincs engedély az értesítés megjelenítéséhez!
@@ -34,7 +34,7 @@
Játékmappák kezeléseKihagyod a játékok mappa kiválasztását?A játékok nem jelennek meg a Játékok listában, ha egy mappa nincs kijelölve.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesJátékok kereséseBeállítások kereséseJátékok könyvtár kiválasztva
@@ -42,7 +42,7 @@
Kiskereskedelmi játékok dekódolásához szükségesKihagyod a kulcsok hozzáadását?A kiskereskedelmi játékok emulálásához érvényes kulcsokra van szükség. Csak a homebrew alkalmazások fognak működni, ha folytatod.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionÉrtesítésekÉrtesítési engedélyek megadása az alábbi gombbal.Engedély megadása
@@ -63,7 +63,7 @@
Győződj meg róla, hogy a titkosító fájlod .keys kiterjesztéssel rendelkezik, majd próbáld újra.Győződj meg róla, hogy a titkosító fájlod .bin kiterjesztéssel rendelkezik, majd próbáld újra.Érvénytelen titkosítókulcsok
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysA kiválasztott fájl helytelen, vagy sérült. Állíts össze egy új kulcsot.GPU illesztőprogram-kezelőGPU illesztőprogram telepítése
@@ -112,7 +112,7 @@
Játéktartalom sikeresen telepítve%1$d sikeresen telepítve%1$d sikeresen felülírva
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesEgyéni illesztőprogramok nem támogatottakEgyéni illesztőprogram telepítése jelenleg nem támogatott ezen az eszközön.\nNézz vissza később, hátha hozzáadtuk a támogatását!suyu adatok kezelése
@@ -137,14 +137,14 @@
A telepített tartalom épségét ellenőrziHiányzó titkosítókulcsokA Firmware és a kiskereskedelmi (retail) játékok nem dekódolhatók
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysApplet indítóRendszer appletek indítása a telepített firmware-relFirmware nincs telepítveApplet nem elérhető
- prod.keys fájl és a firmware telepítve van, majd próbáld újra.]]>
+ prod.keys fájl és a firmware telepítve van, majd próbáld újra.]]>AlbumKépernyőképek megtekintése a rendszer fényképnézegetőjévelMii szerkesztés
@@ -163,7 +163,7 @@
Egy nyílt forráskódú Switch emulátorHozzájárulók\u2764 által készítve a suyu csapattól
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Projektek, amik nélkül a suyu nem jöhetett volna létre AndroidraFelhasználói adatokAz összes alkalmazásadat importálása/exportálása.\n\nA felhasználói adatok importálásakor az összes meglévő felhasználói adat törlődik!
@@ -175,9 +175,9 @@
Felhasználói adatok sikeresen importálvaExportálás megszakítvaEllenőrizd, hogy a felhasználói adatok mappái a zip mappa gyökerében vannak, és tartalmaznak egy konfig fájlt a config/config.ini címen, majd próbáld meg újra.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Korai hozzáférés
@@ -448,7 +448,7 @@
ROM titkosítva
- prod.keys fájl telepítve van, hogy a játékok visszafejthetők legyenek.]]>
+ prod.keys fájl telepítve van, hogy a játékok visszafejthetők legyenek.]]>Hiba lépett fel a videómag inicializása soránEzt általában egy nem kompatibilis GPU illesztő okozza. Egyéni GPU illesztőprogram telepítése megoldhatja a problémát.Nem sikerült betölteni a ROM-ot
diff --git a/src/android/app/src/main/res/values-id/strings.xml b/src/android/app/src/main/res/values-id/strings.xml
index c8437b45c1..032d4e7aad 100644
--- a/src/android/app/src/main/res/values-id/strings.xml
+++ b/src/android/app/src/main/res/values-id/strings.xml
@@ -1,7 +1,7 @@
- Perangkat lunak ini akan menjalankan game untuk konsol game Nintendo Switch. Tidak ada judul game atau kunci yang disertakan.<br /><br />Sebelum memulai, harap cari file prod.keys ]]> di penyimpanan perangkat anda. <br /><br /> Selengkapnya ]]>
+ Perangkat lunak ini akan menjalankan game untuk konsol game Nintendo Switch. Tidak ada judul game atau kunci yang disertakan.<br /><br />Sebelum memulai, harap cari file prod.keys ]]> di penyimpanan perangkat anda. <br /><br /> Selengkapnya ]]>Pemberitahuan dan errorMenampilkan pemberitahuan ketika terjadi kesalahan.Izin notifikasi tidak diberikan!
@@ -35,7 +35,7 @@
Izinkan suyu mengisi daftar gameLewati pemilihan folder game?Game tidak akan muncul di list jika tidak ada folder yang dipilih.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesCari permainanCari pengaturanDirektori game sudah terpilih
@@ -43,7 +43,7 @@
Diperlukan untuk mendekripsi game retailLewati penginstalan keys?Perlu keys yang valid untuk meng-emulate game retail. Hanya homebrew apps yang akan berfungsi jika kamu melanjutkan.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionNotifikasiBerikan izin notifikasi dengan tombol di bawah ini.Berikan izin
@@ -64,7 +64,7 @@
Pastikan file keys anda memiliki format .keys dan coba lagi.Pastikan file keys anda memiliki format .bin dan coba lagi.Keys enkripsi tidak valid
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysFile yang dipilih salah atau rusak. Silakan masukkan kembali kunci Anda.Manajer driver GPUInstall driver GPU
@@ -114,7 +114,7 @@
Konten(-konten) game sudah berhasil terinstal.%1$d telah berhasil terinstal%1$d telah berhasil ditimpa.
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesDriver kustom tidak didukungDriver kustom saat ini tidak dapat digunakan pada perangkat ini. \nCek opsi ini lain waktu untuk mengetahui apakah dapat digunakan!Kelola data Suyu.
@@ -137,7 +137,7 @@
Memeriksa semua konten yang terinstal dari kerusakanKunci enkripsi hilangFirmware dan game retail tidak dapat didekripsi
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysLuncurkan applet
@@ -163,7 +163,7 @@
Emulator Switch Open-SourceKontributorDibuat dengan \u2764 dari tim suyu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Proyek yang memungkinkan suyu untuk AndroidVersiData pengguna
@@ -176,9 +176,9 @@
Berhasil mengimpor data penggunaEkspor DibatalkanPastikan folder data pengguna berada di akar folder zip dan berisi file konfigurasi di config/config.ini dan coba lagi.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Akses lebih awal
@@ -402,8 +402,8 @@
ROM-mu ter-enkripsi
- kartu permainan atau judul yang terinstal.]]>
- prod.keys diinstal sehingga game dapat didekripsi.]]>
+ kartu permainan atau judul yang terinstal.]]>
+ prod.keys diinstal sehingga game dapat didekripsi.]]>Terjadi kesalahan ketika menginisialisasi inti video.Hal ini biasanya disebabkan oleh driver GPU yang tidak kompatibel. Menginstal driver GPU khusus dapat mengatasi masalah iniTidak Dapat Memuat ROM
diff --git a/src/android/app/src/main/res/values-it/strings.xml b/src/android/app/src/main/res/values-it/strings.xml
index 10552f1504..d4f7f8eca2 100644
--- a/src/android/app/src/main/res/values-it/strings.xml
+++ b/src/android/app/src/main/res/values-it/strings.xml
@@ -1,7 +1,7 @@
- Questo software permette di giocare ai giochi della console Nintendo Switch. Nessun gioco o chiave è inclusa.<br /><br />Prima di iniziare, perfavore individua il file prod.keys ]]> nella memoria del tuo dispositivo.<br /><br />Scopri di più]]>
+ Questo software permette di giocare ai giochi della console Nintendo Switch. Nessun gioco o chiave è inclusa.<br /><br />Prima di iniziare, perfavore individua il file prod.keys ]]> nella memoria del tuo dispositivo.<br /><br />Scopri di più]]>Avvisi ed erroriMostra le notifiche quando qualcosa va storto.Autorizzazione di notifica non concessa!
@@ -35,7 +35,7 @@
Consente a suyu di popolare l\'elenco dei giochiSaltare la selezione della cartella dei giochi?I giochi non saranno mostrati nella lista dei giochi se una cartella non è selezionata.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesCerca giochiCerca impostazioneCartella dei giochi selezionata
@@ -43,7 +43,7 @@
Necessario per decrittografare i giochiSaltare l\'aggiunta delle chiavi?Sono necessarie delle chiavi valide per emulare i giochi. Se continui, funzioneranno solo le app homebrew.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionNotificheConcedi l\'autorizzazione alle notifiche con il pulsante in basso.Concedere l\'autorizzazione
@@ -64,7 +64,7 @@
Controlla che le tue chiavi abbiano l\'estensione .keys e prova di nuovo.Controlla che le tue chiavi abbiano l\'estensione .bin e prova di nuovoChiavi di crittografia non valide
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysIl file selezionato è incorretto o corrotto. Per favore riesegui il dump delle tue chiavi.Gestore driver GPUInstalla i driver GPU
@@ -114,7 +114,7 @@
Contenuto/i di gioco installato/i con successo.%1$dinstallato con successo.%1$dsovrascritto con successo
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesI driver personalizzati non sono supportati.I driver personalizzati non sono attualmente supportati su questo dispositivo.\n Ricontrolla in futuro.Gestisci i dati di Suyu
@@ -129,14 +129,14 @@
Nessun salvataggio trovatoVerifica i contenuti installatiVerifica l\'integrità di tutti i contenuti installati.
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysAvvia appletAvvia applet di sistema usando il firmware installatoFirmware non installatoApplet non disponibile
- prod.keys e il firmware siano installati e riprova.]]>
+ prod.keys e il firmware siano installati e riprova.]]>AlbumVisualizza le immagini salvate nella cartella screenshots dell\'utente con il visualizzatore immagini di sistemaModifica Mii
@@ -155,7 +155,7 @@
Un emulatore della Switch open-source.CollaboratoriRealizzato con \u2764 dal team suyu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Progetti che rendono suyu per Android possibileCompilazioneDati Utente
@@ -168,9 +168,9 @@
Dati Utente importati con successo.Esportazione annullataAssicurati che la cartella dei Dati dell\'utente stiano nella radice del file.zip e che sia presente una cartella config in config/config.ini, poi, riprova.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Accesso Anticipato
@@ -364,8 +364,8 @@
L\'integrità dei contenuti non è stata validataLa tua ROM è criptata
- dump delle tue cartucce di giocooppure dei titoli già installati.]]>
- prod.keys sia installato in modo che i giochi possano essere decrittati.]]>
+ dump delle tue cartucce di giocooppure dei titoli già installati.]]>
+ prod.keys sia installato in modo che i giochi possano essere decrittati.]]>È stato riscontrato un errore nell\'inizializzazione del core videoQuesto è causato solitamente dal driver incompatibile di una GPU. L\'installazione di driver GPU personalizzati potrebbe risolvere questo problema.Impossibile caricare la ROM
diff --git a/src/android/app/src/main/res/values-ja/strings.xml b/src/android/app/src/main/res/values-ja/strings.xml
index 21e2070e31..58be4d92df 100644
--- a/src/android/app/src/main/res/values-ja/strings.xml
+++ b/src/android/app/src/main/res/values-ja/strings.xml
@@ -1,7 +1,7 @@
- このソフトウェアでは、Nintendo Switchのゲームを実行できます。 ゲームソフトやキーは含まれません。<br /><br />事前に、 prod.keys ]]> ファイルをストレージに配置しておいてください。<br /><br />詳細]]>
+ このソフトウェアでは、Nintendo Switchのゲームを実行できます。 ゲームソフトやキーは含まれません。<br /><br />事前に、 prod.keys ]]> ファイルをストレージに配置しておいてください。<br /><br />詳細]]>通知とエラー問題の発生時に通知を表示します。通知が許可されていません!
@@ -34,7 +34,7 @@
ゲームをsuyuのゲームリストに追加しますゲームフォルダの選択をスキップしますか?フォルダを選択しないと、ゲームがリストに表示されません。
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesゲームを検索設定を検索フォルダを選択しました
@@ -42,7 +42,7 @@
製品版ゲームの復号化に必要ですキーの追加をスキップしますか?製品版ゲームのエミュレーションには、有効なキーが必要です。続行すると自作アプリしか機能しません。
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introduction通知下のボタンで通知を許可してください。許可
@@ -63,7 +63,7 @@
キーの拡張子が.keysであることを確認し、再度お試しください。キーの拡張子が.binであることを確認し、再度お試しください。暗号化キーが無効
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysファイルが間違っているか破損しています。キーを再ダンプしてください。GPUドライバーの管理GPUドライバー
@@ -107,11 +107,11 @@
ゲームコンテンツのインストールに成功しました%1$d のインストールに成功しました%1$d の上書きに成功しました
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesカスタムドライバはサポートされていませんsuyu データを管理セーブファイルを共有
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysファームウェア未インストールアルバム
@@ -122,7 +122,7 @@
オープンソースのSwitchエミュレータ貢献者suyuチームの\u2764で作られた
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/suyu for Androidの作成を可能にしたプロジェクトビルドユーザデータ
@@ -132,9 +132,9 @@
ユーザデータのエクスポートに成功しましたユーザデータのインポートに成功しましたエクスポートをキャンセルしました
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/早期アクセス
@@ -299,7 +299,7 @@
整合性の確認に失敗しました!ROMが暗号化されています
- prod.keys ファイルがインストールされていることを確認してください。]]>
+ prod.keys ファイルがインストールされていることを確認してください。]]>ビデオコアの初期化中にエラーが発生しましたこれは通常、互換性のないGPUドライバーが原因で発生します。 カスタムGPUドライバーをインストールすると、問題が解決する可能性があります。ROMの読み込みに失敗しました
diff --git a/src/android/app/src/main/res/values-ko/strings.xml b/src/android/app/src/main/res/values-ko/strings.xml
index a2d2bb9511..b843589fcd 100644
--- a/src/android/app/src/main/res/values-ko/strings.xml
+++ b/src/android/app/src/main/res/values-ko/strings.xml
@@ -1,7 +1,7 @@
- 이 소프트웨어는 Nintendo Switch 게임을 실행합니다. 게임 타이틀이나 키는 포함되어 있지 않습니다.<br /><br />시작하기 전에 장치 저장소에서 prod.keys ]]> 파일을 찾아주세요.<br /><br />자세히 알아보기]]>
+ 이 소프트웨어는 Nintendo Switch 게임을 실행합니다. 게임 타이틀이나 키는 포함되어 있지 않습니다.<br /><br />시작하기 전에 장치 저장소에서 prod.keys ]]> 파일을 찾아주세요.<br /><br />자세히 알아보기]]>알림 및 오류문제가 발생하면 알림을 표시합니다.알림 권한이 부여되지 않았습니다!
@@ -35,7 +35,7 @@
suyu에 게임 목록 추가하기게임 폴더 선택을 건너뛰겠습니까?폴더를 선택하지 않으면 게임 목록에 게임이 표시되지 않습니다.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-games게임 검색검색 설정게임 디렉터리를 설정했습니다.
@@ -43,7 +43,7 @@
패키지 게임 암호 해독에 필요키 추가를 건너뛰겠습니까?패키지 게임을 에뮬레이트하려면 유효한 키 값이 필요합니다. 이 단계를 건너뛰면 홈브류 게임만 실행할 수 있습니다.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introduction알림아래 버튼으로 알림 권한을 부여합니다.알림 켜기
@@ -64,7 +64,7 @@
키 파일의 확장자가 .keys인지 확인하고 다시 시도하세요.키 파일의 확장자가 .bin인지 확인하고 다시 시도하세요.암호화 키가 올바르지 않음
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keys선택한 파일이 잘못되었거나 손상되었습니다. 키를 다시 덤프하세요.GPU 드라이버 관리자GPU 드라이버 설치
@@ -114,7 +114,7 @@
게임 콘텐츠 설치됨%1$d개를 설치했습니다.%1$d개를 덮어씌웠습니다.
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updates사용자 지정 드라이버는 지원하지 않습니다.이 장치의 사용자 지정 드라이버 로딩은 현재 지원하지 않습니다.\n나중에 이 옵션을 확인하면 지원이 추가되었는지 확인할 수 있습니다.suyu 데이터 관리
@@ -137,14 +137,14 @@
전체 설치된 콘텐츠의 손상을 확인합니다.암호화 키를 찾을 수 없음펌웨어 및 패키지 게임을 해독할 수 없음
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keys애플릿 런처설치된 펌웨어를 사용해 시스템 애플릿을 실행합니다.펌웨어가 설치되지 않았습니다.애플릿을 사용할 수 없음
- prod.keys 파일과 펌웨어가 설치되었는지 확인하고 다시 시도하세요.]]>
+ prod.keys 파일과 펌웨어가 설치되었는지 확인하고 다시 시도하세요.]]>앨범시스템 사진 뷰어로 유저 스크린샷 폴더에 저장된 이미지를 확인합니다. Mii 편집
@@ -163,7 +163,7 @@
오픈 소스 Switch 에뮬레이터기여자suyu 팀의 \u2764로 제작
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Android용 suyu를 가능하게 하는 프로젝트빌드유저 데이터
@@ -176,9 +176,9 @@
유저 데이터를 가져왔습니다.내보내기 취소됨유저 데이터 폴더가 ZIP 폴더의 루트 디렉토리에 위치하고 config/config.ini 구성 파일이 있는지 확인하고 다시 시도하세요.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/앞서 해보기
@@ -403,8 +403,8 @@
롬 파일이 암호화되어있음
- 게임 카트리지 또는 설치된 타이틀을 다시 덤프하세요.]]>
- prod.keys 파일이 설치되어 있는지 확인하세요.]]>
+ 게임 카트리지 또는 설치된 타이틀을 다시 덤프하세요.]]>
+ prod.keys 파일이 설치되어 있는지 확인하세요.]]>비디오 코어를 초기화하는 동안 오류 발생일반적으로 이 문제는 호환되지 않는 GPU 드라이버로 인해 발생합니다. 사용자 지정 GPU 드라이버를 설치하면 이 문제가 해결될 수 있습니다.롬 파일을 불러올 수 없음
diff --git a/src/android/app/src/main/res/values-nb/strings.xml b/src/android/app/src/main/res/values-nb/strings.xml
index 9ce92d899f..5ba71ffcb3 100644
--- a/src/android/app/src/main/res/values-nb/strings.xml
+++ b/src/android/app/src/main/res/values-nb/strings.xml
@@ -1,7 +1,7 @@
- Denne programvaren vil kjøre spill for Nintendo Switch-spillkonsollen. Ingen spilltitler eller nøkler er inkludert.<br /><br />Før du begynner, må du finne prod.keys ]]> filen din på enhetslagringen.<br /><br />Lær mer]]>
+ Denne programvaren vil kjøre spill for Nintendo Switch-spillkonsollen. Ingen spilltitler eller nøkler er inkludert.<br /><br />Før du begynner, må du finne prod.keys ]]> filen din på enhetslagringen.<br /><br />Lær mer]]>Merknader og feilViser varsler når noe går galt.Varslingstillatelse ikke gitt!
@@ -32,14 +32,14 @@
Gjør det mulig for suyu å fylle ut spillelisten.Hoppe over valg av spillmappe?Spill vises ikke i Spill-listen hvis en mappe ikke er valgt.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesSøk i spill|Spillkatalogen er valgtInstaller prod.keysNødvendig for å dekryptere spillHoppe over å legge til nøkler?Gyldige nøkler er påkrevd for å emulere spill. Bare hjemmebryggede apper vil fungere hvis du fortsetter.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionVarslerGi varslingstillatelse med knappen nedenfor.Gi tillatelse
@@ -60,7 +60,7 @@
Kontroller at nøkkelfilen har filtypen .keys, og prøv igjen.Kontroller at nøkkelfilen har filtypen .bin, og prøv igjen.Ugyldige krypteringsnøkler
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysDen valgte filen er feil eller ødelagt. Vennligst dump nøklene på nytt.Installer GPU-driverInstaller alternative drivere for potensielt bedre ytelse eller nøyaktighet.
@@ -94,8 +94,8 @@
Ingen loggfil funnetInstaller spillinnholdInstaller spilloppdateringer eller DLC
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysGaia er ikke ekte
@@ -103,12 +103,12 @@
En Switch-emulator med åpen kildekodeBidragsytereLaget med \u2764 fra suyu-teamet
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Prosjekter som gjør suyu for Android muligBygg
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Tidlig tilgang
@@ -257,7 +257,7 @@
Integritetsverifisering mislyktes!ROM-en din er kryptert
- prod.keys filen er installert slik at spillene kan dekrypteres.]]>
+ prod.keys filen er installert slik at spillene kan dekrypteres.]]>Det oppstod en feil ved initialisering av videokjernenDette skyldes vanligvis en inkompatibel GPU-driver. Installering av en tilpasset GPU-driver kan løse problemet.Kunne ikke laste inn ROM
diff --git a/src/android/app/src/main/res/values-pl/strings.xml b/src/android/app/src/main/res/values-pl/strings.xml
index 02587fd8b1..490547daa2 100644
--- a/src/android/app/src/main/res/values-pl/strings.xml
+++ b/src/android/app/src/main/res/values-pl/strings.xml
@@ -1,7 +1,7 @@
- To oprogramowanie umożliwia uruchomienie gier z konsoli Nintendo Switch. Nie zawiera gier ani wymaganych kluczy.<br /><br />Zanim zaczniesz, wybierz plik kluczy prod.keys ]]> z katalogu w pamięci masowej.<br /><br />Dowiedz się więcej]]>
+ To oprogramowanie umożliwia uruchomienie gier z konsoli Nintendo Switch. Nie zawiera gier ani wymaganych kluczy.<br /><br />Zanim zaczniesz, wybierz plik kluczy prod.keys ]]> z katalogu w pamięci masowej.<br /><br />Dowiedz się więcej]]>Powiadomienia błędyPokaż powiadomienie gdy coś pójdzie źleNie zezwolono na powiadomienia!
@@ -32,14 +32,14 @@
Pozwala suyu wygenerować listę gierPominąć wybór folderu z grami?Aby pokazać listę gier wybierz katalog zawierający gry.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesSzukaj gierWybrano katalog gierInstaluj klucze prod.keysWymagane aby poprawnie odczytać sklepowe gryPominąć dodawanie kluczy?Poprawne klucze są wymagane aby emulować sklepowe gry. Jeśli przejdziesz dalej, jedynie homebrew będą działać.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionPowiadomieniaNadaj uprawnienia dostępu do powiadomień. Nadaj uprawnienia
@@ -60,7 +60,7 @@
Upewnij się że twoje klucze mają rozszerzenie .keys i spróbuj ponownie.Upewnij się że twoje klucze mają rozszerzenie .bin i spróbuj ponownie.Niepoprawne klucze
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysWybrany plik jest niepoprawny lub uszkodzony. Zrzuć ponownie swoje klucze.Zainstaluj sterownik GPUUżyj alternatywnych sterowników aby potencjalnie zwiększyć wydajność i naprawić błędy
@@ -94,8 +94,8 @@
Nie znaleziono plików logówZainstaluj zawartość gryZainstaluj aktualizację gry lub dodatek DLC
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysGaia isn\'t real
@@ -103,12 +103,12 @@
Otwarto-źródłowy emulator konsoli SwitchWspółtwórcyStworzone z \u2764 przez zespół suyu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Projekty dzięki którym suyu mógł zostać stworzonyWersja
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Wczesny dostęp
@@ -255,7 +255,7 @@
DodatkiTwój ROM jest zakodowany
- prod.keys jest zainstalowany aby gry mogły zostać odczytane.]]>
+ prod.keys jest zainstalowany aby gry mogły zostać odczytane.]]>Błąd inicjacji podsystemu graficznegoZazwyczaj spowodowane niekompatybilnym sterownikiem GPU, instalacja niestandardowego sterownika może rozwiązać ten problem.Nie można wczytać pliku ROM
diff --git a/src/android/app/src/main/res/values-pt-rBR/strings.xml b/src/android/app/src/main/res/values-pt-rBR/strings.xml
index 3b3bf806b7..ae2036d4b4 100644
--- a/src/android/app/src/main/res/values-pt-rBR/strings.xml
+++ b/src/android/app/src/main/res/values-pt-rBR/strings.xml
@@ -1,7 +1,7 @@
- Este software executa jogos do console Nintendo Switch. Não estão inclusos nem jogos ou chaves.<br /><br />Antes de começar, por favor localize o arquivo prod.keys ]]> no armazenamento de seu dispositivo.<br /><br />Saiba mais]]>
+ Este software executa jogos do console Nintendo Switch. Não estão inclusos nem jogos ou chaves.<br /><br />Antes de começar, por favor localize o arquivo prod.keys ]]> no armazenamento de seu dispositivo.<br /><br />Saiba mais]]>Notificações e errosMostra notificações quando algo dá errado.Acesso às notificações não concedido!
@@ -35,7 +35,7 @@
Permite que o Suyu preencha a lista de jogosIgnorar a seleção da pasta de jogos?Os jogos não serão exibidos na lista de jogos se uma pasta não estiver selecionada.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesProcurar jogosProcurar nas configuraçõesPasta de jogos selecionada
@@ -43,7 +43,7 @@
Necessárias para desencriptar jogos comerciaisIgnorar a adição de chaves?São necessárias chaves válidas para emular jogos comerciais. Somente aplicativos homebrew funcionarão se você continuar.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionNotificaçõesConceda a permissão de notificação com o botão abaixo.Conceder permissão
@@ -64,7 +64,7 @@
Verifique se seu arquivo de chaves possui a extensão .keys e tente novamente.Verifique se seu arquivo de chaves possui a extensão .bin e tente novamente.Chaves de encriptação inválidas
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysO arquivo selecionado está incorreto ou corrompido. Por favor extraia suas chaves novamente.Gerenciador de driver de GPUInstalar driver para GPU
@@ -114,7 +114,7 @@
Conteúdo(s) de jogo instalado(s) com sucesso%1$d instalado com sucesso%1$d substituído com sucesso
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesDrivers personalizados não suportadosCarregamento de drivers personalizados não suportado para este dispositivo no momento.\nVerifique essa opção novamente no futuro para ver se o suporte foi adicionado!Administrar dados do suyu
@@ -141,14 +141,14 @@
Verifica todo o conteúdo instalado em busca de dados corrompidosFaltando chaves de encriptaçãoO firmware e jogos comerciais não poderão ser decriptados
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysLauncher de miniaplicativosExecute miniaplicativos do sistema usando o firmware instaladoFirmware não instaladoMiniaplicativo não disponível
- prod.keys e o firmware estão instalados e tente novamente.]]>
+ prod.keys e o firmware estão instalados e tente novamente.]]>ÁlbumVisualize imagens armazenadas na pasta de capturas de telas do usuário com o visualizador de imagens do sistemaEditor de Mii
@@ -167,7 +167,7 @@
Um emulador de Switch de código abertoColaboradoresFeito com \u2764 da equipe do Suyu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Projetos que tornam o suyu para Android possívelVersão da CompilaçãoDados do usuário
@@ -180,9 +180,9 @@
Dados de usuário importados com sucessoExportação canceladaVerifique se as pastas de dados do usuário estão na raiz da pasta zip, se possuem um arquivo de configuração em config/config.ini e tente novamente.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Acesso Antecipado
@@ -461,8 +461,8 @@ uma tentativa de mapeamento automático
Sua ROM está encriptada
- cartuchos de jogos ou títulos instalados.]]>
- prod.keys está instalado para que os jogos possam ser decriptados.]]>
+ cartuchos de jogos ou títulos instalados.]]>
+ prod.keys está instalado para que os jogos possam ser decriptados.]]>Ocorreu um erro ao iniciar o núcleo de vídeo.Isto é normalmente causado por um driver de GPU incompatível. Instalar um driver de GPU personalizado pode resolver este problema.Impossível carregar a ROM
diff --git a/src/android/app/src/main/res/values-pt-rPT/strings.xml b/src/android/app/src/main/res/values-pt-rPT/strings.xml
index 75ca1330cc..4c34f902be 100644
--- a/src/android/app/src/main/res/values-pt-rPT/strings.xml
+++ b/src/android/app/src/main/res/values-pt-rPT/strings.xml
@@ -35,7 +35,7 @@
Permite que o Suyu preencha a lista de jogosIgnorar a seleção da pasta de jogos?Os jogos não serão exibidos na lista de jogos se uma pasta não estiver selecionada.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesProcurar jogosProcurar nas definiçõesPasta de Jogos selecionada
@@ -43,7 +43,7 @@
Necessário para desencriptar jogos comerciaisIgnorar a adição de chaves?São necessárias chaves válidas para emular jogos comerciais. Somente aplicativos homebrew funcionarão se você continuar.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionNotificaçõesConceda a permissão de notificação com o botão abaixo.Conceda permissão
@@ -64,7 +64,7 @@
Verifique se seu arquivo keys possui a extensão .keys e tente novamente.Verifique se seu arquivo keys possui a extensão .bin e tente novamente.Chaves de encriptação inválidas
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysO ficheiro selecionado está corrompido. Por favor recarrega as tuas chaves.Gerenciador de driver de GPUInstala driver para GPU
@@ -114,7 +114,7 @@
Conteúdo(s) de jogo instalados com sucesso%1$d instalado com sucesso%1$d substituída com êxito
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesDrivers personalizados não suportadosCarrea«gamento de drivers personalizados não é suportado pr este dispositivo. \nCheck verifica esta opção de futuro para confirmar se o suporte foi adicionado!Administrar dados suyu
@@ -141,7 +141,7 @@
Verifica todo o conteúdo instalado em busca de dados corrompidosFaltando chaves de encriptaçãoO firmware e jogos comerciais não poderão ser decriptados
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysLauncher de miniaplicativos
@@ -167,7 +167,7 @@
Um emulador Switch de código abertoContribuidoresFeito com \u2764 da equipa do Suyu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Projetos que tornam o suyu para Android possívelVersãoDado de utilizados
@@ -180,9 +180,9 @@
Dados de utilizador importado com sucessoExportação canceladaVerifiqua se as pastas de dados do utilizados estão na raiz da pasta zip e contêm um arquivo de configuração em config/config.ini e tenta novamente.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Acesso antecipado
@@ -461,8 +461,8 @@ uma tentativa de mapeamento automático
A tua ROM está encriptada
- cartucho de jogo or títulos instalados.]]>
- prod.keys está instalado para que os jogos possam ser desencriptados.]]>
+ cartucho de jogo or títulos instalados.]]>
+ prod.keys está instalado para que os jogos possam ser desencriptados.]]>Ocorreu um erro ao iniciar o núcleo de vídeo.Isto é normalmente causado por um driver de GPU incompatível. Instalar um driver GPU pode resolver este problema.Impossível carregar a tua ROM
diff --git a/src/android/app/src/main/res/values-ru/strings.xml b/src/android/app/src/main/res/values-ru/strings.xml
index 0190726def..f86af3c931 100644
--- a/src/android/app/src/main/res/values-ru/strings.xml
+++ b/src/android/app/src/main/res/values-ru/strings.xml
@@ -1,7 +1,7 @@
- Это программное обеспечение позволяет запускать игры для игровой консоли Nintendo Switch. Мы не предоставляем сами игры или ключи.<br /><br />Перед началом работы найдите файл prod.keys ]]> в хранилище устройства..<br /><br />Узнать больше]]>
+ Это программное обеспечение позволяет запускать игры для игровой консоли Nintendo Switch. Мы не предоставляем сами игры или ключи.<br /><br />Перед началом работы найдите файл prod.keys ]]> в хранилище устройства..<br /><br />Узнать больше]]>Уведомления и ошибкиПоказывать уведомления, когда что-то пошло не такВы не предоставили разрешение на уведомления!
@@ -35,7 +35,7 @@
Позволяет suyu заполнить список игрПропустить выбор папки с играми?Игры не будут отображаться в списке Игры, если папка не выбрана.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesНайти игрыНастройки поискаВыбрана папка с играми
@@ -43,7 +43,7 @@
Требуется для расшифровки розничных игрПропустить добавление ключей?Для эмуляции розничных игр требуются действительные ключи. Если вы продолжите, будут работать только homebrew приложения.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionУведомленияПредоставьте разрешение уведомлений с помощью кнопки ниже.Предоставить разрешение
@@ -64,7 +64,7 @@
Убедитесь, что файл ключей имеет расширение .keys, и повторите попытку.Убедитесь, что файл ключей имеет расширение .bin, и повторите попытку.Неверные ключи шифрования
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysВыбранный файл неверен или поврежден. Пожалуйста, пере-дампите ваши ключи.Менеджер драйверов ГПУстановить драйвер ГП
@@ -114,7 +114,7 @@
Игровой контент успешно установлен%1$d Успешно установлено%1$d Успешно перезаписано
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesПользовательские драйверы не поддерживаютсяЗагрузка пользовательского драйвера в настоящее время не поддерживается для этого устройства.\nПроверьте этот параметр еще раз в будущем чтобы узнать была ли добавлена поддержка!
@@ -144,14 +144,14 @@
Проверяет весь установленный контент на наличие поврежденийОтсутствуют ключи шифрованияПрошивка и розничные игры не могут быть расшифрованы
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysЗапуск апплетаЗапуск системных апплетов на установленной прошивкеПрошивка не установленаАпплет недоступен
- prod.keys и firmware установлены и попробуйте еще раз.]]>
+ prod.keys и firmware установлены и попробуйте еще раз.]]>АльбомПросмотрите изображения, сохраненные в папке скриншотов пользователя, с помощью системного просмотрщика фотографий.Mii редактор
@@ -170,7 +170,7 @@
Эмулятор Switch с открытым исходным кодомКонтрибьюторыСделано с \u2764 от команды suyu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Проекты, которые сделали suyu для Android возможнымСборкаДанные пользователя
@@ -183,9 +183,9 @@
Пользовательские данные успешно импортированыЭкспорт отмененУбедитесь что папки пользовательских данных находятся в корне zip-папки и содержат файл конфигурации config/config.ini и повторите попытку.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Ранний доступ
@@ -463,8 +463,8 @@
Ваш ROM зашифрованный
- или установленные игры.]]>
- prod.keys установлен, чтобы игры можно было расшифровать.]]>
+ или установленные игры.]]>
+ prod.keys установлен, чтобы игры можно было расшифровать.]]>Произошла ошибка при инициализации видеоядра.Обычно это вызвано несовместимым драйвером ГП. Установка пользовательского драйвера ГП может решить эту проблему.Не удалось запустить ROM
diff --git a/src/android/app/src/main/res/values-uk/strings.xml b/src/android/app/src/main/res/values-uk/strings.xml
index 4b212d8bc0..2564c03205 100644
--- a/src/android/app/src/main/res/values-uk/strings.xml
+++ b/src/android/app/src/main/res/values-uk/strings.xml
@@ -1,7 +1,7 @@
- Це програмне забезпечення дозволяє запускати ігри для ігрової консолі Nintendo Switch. Ми не надаємо самі ігри або ключі.<br /><br />Перед початком роботи знайдіть ваш файл prod.keys ]]> у сховищі пристрою.<br /><br />Дізнатися більше]]>
+ Це програмне забезпечення дозволяє запускати ігри для ігрової консолі Nintendo Switch. Ми не надаємо самі ігри або ключі.<br /><br />Перед початком роботи знайдіть ваш файл prod.keys ]]> у сховищі пристрою.<br /><br />Дізнатися більше]]>Сповіщення та помилкиПоказувати сповіщення, коли щось пішло не такВи не надали дозвіл сповіщень!
@@ -32,14 +32,14 @@
Дозволяє suyu заповнити список ігорПропустити вибір папки з іграми?Ігри не відображатимуться у списку Ігри, якщо папку не вибрано.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesЗнайти ігриВибрано папку з іграмиВстановити prod.keysПотрібно для розшифровки роздрібних ігорПропустити додавання ключів?Для емуляції роздрібних ігор потрібні дійсні ключі. Якщо ви продовжите, працюватимуть тільки homebrew додатки.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionСповіщенняНадайте дозвіл сповіщень за допомогою кнопки нижче.Надати дозвіл
@@ -59,7 +59,7 @@
Помилка під час зчитування ключів шифруванняПереконайтеся, що файл ключів має розширення .keys, і повторіть спробу.Невірні ключі шифрування
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysОбраний файл невірний або пошкоджений. Будь ласка, пере-дампіть ваші ключі.Встановити драйвер ГПВстановіть альтернативні драйвери для потенційно кращої продуктивності та/або точності
@@ -81,7 +81,7 @@
Назва першої вкладеної папки має бути ідентифікатором гри.ІмпортЕкспорт
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysGaia не існує
@@ -89,11 +89,11 @@
Емулятор Switch із відкритим першокодомВкладникиЗроблено з \u2764 від команди suyu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Збірка
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Ранній доступ
@@ -214,7 +214,7 @@
ДоповненняВаш ROM зашифрований
- prod.keys встановлено, щоб ігри можна було розшифрувати.]]>
+ prod.keys встановлено, щоб ігри можна було розшифрувати.]]>Сталася помилка під час ініціалізації відеоядра.Зазвичай це спричинено несумісним драйвером ГП. Встановлення користувацького драйвера ГП може вирішити цю проблему.Не вдалося запустити ROM
diff --git a/src/android/app/src/main/res/values-vi/strings.xml b/src/android/app/src/main/res/values-vi/strings.xml
index 6355582cb0..272d8000ed 100644
--- a/src/android/app/src/main/res/values-vi/strings.xml
+++ b/src/android/app/src/main/res/values-vi/strings.xml
@@ -1,7 +1,7 @@
- Phần mềm này sẽ chạy trò chơi cho máy chơi game Nintendo Switch. Không có game titles hoặc keys được bao gồm.<br /><br />Trước khi bạn bắt đầu, hãy tìm file prod.keys ]]> trên bộ nhớ thiết bị của bạn.<br /><br />Tìm hiểu thêm]]>
+ Phần mềm này sẽ chạy trò chơi cho máy chơi game Nintendo Switch. Không có game titles hoặc keys được bao gồm.<br /><br />Trước khi bạn bắt đầu, hãy tìm file prod.keys ]]> trên bộ nhớ thiết bị của bạn.<br /><br />Tìm hiểu thêm]]>Thông báo và lỗiHiển thị thông báo khi có sự cố xảy raỨng dụng không được cấp quyền thông báo!
@@ -32,14 +32,14 @@
Cho phép suyu thêm các trò chơi vào danh sáchBỏ qua lựa chọn thư mục trò chơi?Trò chơi sẽ không hiển thị trong danh sách nếu một thư mục không được chọn
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesTìm kiếm gamesThư mục trò chơi đã được chọnCài prod.keysYêu cầu để giải mã các game bán lẻBỏ qua thêm chìa khóa?Cần có chìa khóa hợp lệ để giả lập trò chơi. Chỉ có các ứng dụng homebrew có thể vận hành nếu bạn tiếp tục
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionThông báoẤn vào nút bên dưới để cấp quyền ứng dụng gửi thông báoCấp quyền
@@ -60,7 +60,7 @@
Xác minh rằng tệp keys của bạn có đuôi .keys và thử lại.Xác minh rằng tệp keys của bạn có đuôi .bin và thử lại.Keys mã hoá không hợp lệ
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysChọn file sai hoặc bị hỏng. Hãy xuất chìa khóa khácCài đặt driver GPUCài đặt driver thay thế để có thể có hiệu suất tốt và chính xác hơn
@@ -94,8 +94,8 @@
Không tìm thấy tệp logCài đặt nội dung gameCài đặt cập nhật game hoặc DLC
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysGaia không có thật
@@ -103,12 +103,12 @@
Một giả lập Switch mã nguồn mởNgười đóng gópĐược làm với \u2764 từ nhóm suyu
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Các dự án làm cho suyu trên Android trở thành điều có thểDựng
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Early Access
@@ -259,7 +259,7 @@
Kiểm tra tính toàn vẹn thất bại!ROM của bạn đã bị mã hoá
- prod.keys đã được cài đặt để game có thể được giải mã.]]>
+ prod.keys đã được cài đặt để game có thể được giải mã.]]>Đã xảy ra lỗi khi khởi tạo lõi videoViệc này thường do driver GPU không tương thích. Cài đặt một driver GPU tùy chỉnh có thể giải quyết vấn đề này.Không thể tải ROM
diff --git a/src/android/app/src/main/res/values-zh-rCN/strings.xml b/src/android/app/src/main/res/values-zh-rCN/strings.xml
index 3ad450e1c9..6834e8c708 100644
--- a/src/android/app/src/main/res/values-zh-rCN/strings.xml
+++ b/src/android/app/src/main/res/values-zh-rCN/strings.xml
@@ -1,7 +1,7 @@
- 此软件可以运行 Nintendo Switch 游戏,但不包含任何游戏和密钥文件。<br /><br />在开始前,请找到放置于设备存储中的 prod.keys ]]> 文件。<br /><br />了解更多]]>
+ 此软件可以运行 Nintendo Switch 游戏,但不包含任何游戏和密钥文件。<br /><br />在开始前,请找到放置于设备存储中的 prod.keys ]]> 文件。<br /><br />了解更多]]>通知及错误提醒当发生错误时显示通知。未授予通知权限!
@@ -35,7 +35,7 @@
允许 suyu 更新游戏列表跳过选择游戏文件夹?如果未选择游戏文件夹,游戏将不会显示在游戏列表中。
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-games搜索游戏搜索设置已选择游戏文件夹
@@ -43,7 +43,7 @@
需要密钥文件来解密游戏跳过添加密钥文件?对于商业游戏,需要有效的密钥文件才能运行。如果没有密钥文件,将只能运行自制软件。
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introduction通知使用下方的按钮授予通知权限。授予权限
@@ -64,7 +64,7 @@
请确保您的密钥文件扩展名为 .keys 并重试。请确保您的密钥文件扩展名为 .bin 并重试。无效的加密密钥
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keys选择的密钥文件不正确或已损坏。请重新转储密钥文件。GPU 驱动管理器安装 GPU 驱动
@@ -114,7 +114,7 @@
游戏附加内容已成功安装%1$d 个包安装成功%1$d 个包覆盖安装成功
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updates不支持自定义驱动此设备不支持自定义驱动。\n请之后再访问此项,查看是否已为此设备添加支持。管理 suyu 数据
@@ -137,14 +137,14 @@
检查所有安装的内容是否有损坏密钥缺失无法解密固件和商业游戏
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keys小程序启动器使用已安装的固件启动系统小程序未安装固件小程序不可用
- prod.keys 文件和固件已安装,然后再试一次。]]>
+ prod.keys 文件和固件已安装,然后再试一次。]]>相册查看存储在用户屏幕截图文件夹中的图像Mii edit
@@ -163,7 +163,7 @@
一款开放源代码的 Switch 模拟器贡献者suyu 团队的用 \u2764 制作
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Android 版 suyu 离不开这些项目的支持构建版本用户数据
@@ -176,9 +176,9 @@
导入用户数据成功已取消导出数据请确保用户数据文件夹位于 zip 压缩包的根目录,并在 config/config.ini 路径中包含配置文件,然后重试。
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/抢先体验
@@ -456,8 +456,8 @@
您的 ROM 已加密
- 游戏卡带或已安装的游戏。]]>
- prod.keys 文件已安装,使得游戏可以被解密。]]>
+ 游戏卡带或已安装的游戏。]]>
+ prod.keys 文件已安装,使得游戏可以被解密。]]>初始化视频核心时发生错误这通常由不兼容的 GPU 驱动程序造成,安装自定义 GPU 驱动程序可能解决此问题。无法载入 ROM
diff --git a/src/android/app/src/main/res/values-zh-rTW/strings.xml b/src/android/app/src/main/res/values-zh-rTW/strings.xml
index 06e23d4c4e..5cf8f6f15a 100644
--- a/src/android/app/src/main/res/values-zh-rTW/strings.xml
+++ b/src/android/app/src/main/res/values-zh-rTW/strings.xml
@@ -1,7 +1,7 @@
- 此軟體可以執行 Nintendo Switch 主機遊戲,但不包含任何遊戲和金鑰。<br /><br />在您開始前,請找到放置於您的裝置儲存空間的 prod.keys ]]> 檔案。<br /><br />深入瞭解]]>
+ 此軟體可以執行 Nintendo Switch 主機遊戲,但不包含任何遊戲和金鑰。<br /><br />在您開始前,請找到放置於您的裝置儲存空間的 prod.keys ]]> 檔案。<br /><br />深入瞭解]]>通知和錯誤發生錯誤時顯示通知。未授予通知權限!
@@ -35,7 +35,7 @@
允許 suyu 填入遊戲清單跳過選取遊戲資料夾?如果資料夾未選取,遊戲將不會顯示在遊戲清單。
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-games搜尋遊戲搜尋設定遊戲目錄已選取
@@ -43,7 +43,7 @@
需要解密零售遊戲跳過新增金鑰?模擬零售遊戲需要有效的金鑰,若要繼續,將僅有自製遊戲應用程式可以運作。
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introduction通知使用下方的按鈕授予通知權限。授予權限
@@ -64,7 +64,7 @@
驗證您的金鑰檔案是否具有 .keys 副檔名並再試一次。驗證您的金鑰檔案是否具有 .bin 副檔名並再試一次。無效的加密金鑰
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keys選取的檔案不正確或已損毀,請重新傾印您的金鑰。GPU 驅動程式管理員安裝 GPU 驅動程式
@@ -114,7 +114,7 @@
遊戲內容已成功安裝%1$d 安裝成功%1$d 覆寫成功
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updates不支援自訂的驅動程式此裝置不支援自訂的驅動程式。\n請以後再來查看是否已新增支援!管理 suyu 資料
@@ -137,14 +137,14 @@
检查所有安装的内容是否有损坏密钥缺失无法解密固件和商业游戏
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keys小程式啟動器使用已安裝的韌體啟動系統小程式未安裝韌體無法使用小程式
- prod.keys 檔案和韌體已安裝,然後再試一次。]]>
+ prod.keys 檔案和韌體已安裝,然後再試一次。]]>相簿使用系統相片檢視器查看儲存在使用者螢幕截圖資料夾中的影像Mii 編輯
@@ -163,7 +163,7 @@
一個開放原始碼的 Switch 模擬器參與者使用來自 suyu 團隊的 \u2764 製作
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/這些專案使 suyu Android 版成為可能組建使用者資料
@@ -176,9 +176,9 @@
使用者資料匯入成功匯出已取消請確保使用者資料夾位於 zip 壓縮檔的根目錄,並在 config/config.ini 路徑中包含組態檔案,並再試一次。
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/搶先體驗
@@ -456,8 +456,8 @@
您的 ROM 已加密
- 遊戲卡匣或已安裝的遊戲。]]>
- prod.keys 檔案已安裝,讓遊戲可以解密。]]>
+ 遊戲卡匣或已安裝的遊戲。]]>
+ prod.keys 檔案已安裝,讓遊戲可以解密。]]>初始化視訊核心時發生錯誤這經常由不相容的 GPU 驅動程式造成,安裝自訂 GPU 驅動程式可能會解決此問題。無法載入 ROM
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 5331f2b419..cbbfd9c766 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -3,7 +3,7 @@
suyu
- This software will run games for the Nintendo Switch game console. No game titles or keys are included.<br /><br />Before you begin, please locate your prod.keys ]]> file on your device storage.<br /><br />Learn more]]>
+ This software will run games for the Nintendo Switch game console. No game titles or keys are included.<br /><br />Before you begin, please locate your prod.keys ]]> file on your device storage.<br /><br />Learn more]]>Notices and errorsnoticesAndErrorsShows notifications when something goes wrong.
@@ -38,7 +38,7 @@
Allows suyu to populate the games listSkip selecting games folder?Games won\'t be displayed in the Games list if a folder isn\'t selected.
- https://suyu-emu.org/help/quickstart/#dumping-games
+ https://suyu.dev/help/quickstart/#dumping-gamesSearch gamesSearch settingsGames directory selected
@@ -46,7 +46,7 @@
Required to decrypt retail gamesSkip adding keys?Valid keys are required to emulate retail games. Only homebrew apps will function if you continue.
- https://suyu-emu.org/help/quickstart/#guide-introduction
+ https://suyu.dev/help/quickstart/#guide-introductionNotificationsGrant the notification permission with the button below.Grant permission
@@ -67,7 +67,7 @@
Verify your keys file has a .keys extension and try again.Verify your keys file has a .bin extension and try again.Invalid encryption keys
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysThe selected file is incorrect or corrupt. Please redump your keys.GPU driver managerInstall GPU driver
@@ -117,7 +117,7 @@
Game content(s) installed successfully%1$d installed successfully%1$d overwritten successfully
- https://suyu-emu.org/help/quickstart/#dumping-installed-updates
+ https://suyu.dev/help/quickstart/#dumping-installed-updatesCustom drivers not supportedCustom driver loading isn\'t currently supported for this device.\nCheck this option again in the future to see if support was added!Manage suyu data
@@ -142,7 +142,7 @@
Checks all installed content for corruptionEncryption keys are missingFirmware and retail games cannot be decrypted
- https://suyu-emu.org/help/quickstart/#dumping-decryption-keys
+ https://suyu.dev/help/quickstart/#dumping-decryption-keysQlaunch
@@ -151,7 +151,7 @@
Launch system applets using installed firmwareFirmware not installedApplet not available
- prod.keys file and firmware are installed and try again.]]>
+ prod.keys file and firmware are installed and try again.]]>AlbumSee images stored in the user screenshots folder with the system photo viewerMii edit
@@ -170,7 +170,7 @@
An open-source Switch emulatorContributorsMade with \u2764 from the suyu team
- https://github.com/suyu-emu/suyu/graphs/contributors
+ https://git.suyu.dev/suyu/suyu/activity/Projects that make suyu for Android possibleBuildUser data
@@ -183,9 +183,9 @@
User data imported successfullyExport cancelledMake sure the user data folders are at the root of the zip folder and contain a config file at config/config.ini and try again.
- https://discord.gg/suyu
- https://suyu-emu.org/
- https://github.com/suyu-emu
+ https://chat.suyu.dev/
+ https://suyu.dev/
+ https://git.suyu.dev/Early Access
@@ -463,8 +463,8 @@
Your ROM is encrypted
- game cartidges or installed titles.]]>
- prod.keys file is installed so that games can be decrypted.]]>
+ game cartidges or installed titles.]]>
+ prod.keys file is installed so that games can be decrypted.]]>An error occurred initializing the video coreThis is usually caused by an incompatible GPU driver. Installing a custom GPU driver may resolve this problem.Unable to load ROM
diff --git a/src/audio_core/common/feature_support.h b/src/audio_core/common/feature_support.h
index e71905ae84..e2e00769c2 100644
--- a/src/audio_core/common/feature_support.h
+++ b/src/audio_core/common/feature_support.h
@@ -13,7 +13,7 @@
#include "common/polyfill_ranges.h"
namespace AudioCore {
-constexpr u32 CurrentRevision = 11;
+constexpr u32 CurrentRevision = 12;
enum class SupportTags {
CommandProcessingTimeEstimatorVersion4,
diff --git a/src/audio_core/device/audio_buffers.h b/src/audio_core/device/audio_buffers.h
index 9e84a9c059..6e5e27ae3d 100644
--- a/src/audio_core/device/audio_buffers.h
+++ b/src/audio_core/device/audio_buffers.h
@@ -54,7 +54,8 @@ public:
const s32 to_register{std::min(std::min(appended_count, BufferAppendLimit),
BufferAppendLimit - registered_count)};
- for (s32 i = 0; i < to_register; i++) {
+ out_buffers.reserve(to_register);
+ for (s32 i = 0; i < to_register; ++i) {
s32 index{appended_index - appended_count};
if (index < 0) {
index += N;
@@ -180,6 +181,7 @@ public:
return 0;
}
+ buffers_flushed.reserve(registered_count + appended_count);
while (registered_count > 0) {
auto index{registered_index - registered_count};
if (index < 0) {
diff --git a/src/common/android/applets/software_keyboard.cpp b/src/common/android/applets/software_keyboard.cpp
index 2f0c58227a..8a49ff0442 100644
--- a/src/common/android/applets/software_keyboard.cpp
+++ b/src/common/android/applets/software_keyboard.cpp
@@ -253,19 +253,19 @@ void AndroidKeyboard::SubmitNormalText(const ResultData& data) const {
void InitJNI(JNIEnv* env) {
s_software_keyboard_class = reinterpret_cast(
- env->NewGlobalRef(env->FindClass("org/suyu/suyu_emu/applets/keyboard/SoftwareKeyboard")));
+ env->NewGlobalRef(env->FindClass("dev/suyu/suyu_emu/applets/keyboard/SoftwareKeyboard")));
s_keyboard_config_class = reinterpret_cast(env->NewGlobalRef(
- env->FindClass("org/suyu/suyu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig")));
+ env->FindClass("dev/suyu/suyu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig")));
s_keyboard_data_class = reinterpret_cast(env->NewGlobalRef(
- env->FindClass("org/suyu/suyu_emu/applets/keyboard/SoftwareKeyboard$KeyboardData")));
+ env->FindClass("dev/suyu/suyu_emu/applets/keyboard/SoftwareKeyboard$KeyboardData")));
s_swkbd_execute_normal = env->GetStaticMethodID(
s_software_keyboard_class, "executeNormal",
- "(Lorg/suyu/suyu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig;)Lorg/suyu/suyu_emu/"
+ "(Ldev/suyu/suyu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig;)Ldev/suyu/suyu_emu/"
"applets/keyboard/SoftwareKeyboard$KeyboardData;");
s_swkbd_execute_inline = env->GetStaticMethodID(
s_software_keyboard_class, "executeInline",
- "(Lorg/suyu/suyu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig;)V");
+ "(Ldev/suyu/suyu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig;)V");
}
void CleanupJNI(JNIEnv* env) {
diff --git a/src/common/android/id_cache.cpp b/src/common/android/id_cache.cpp
index 40faea9fa0..c4ef648ae5 100644
--- a/src/common/android/id_cache.cpp
+++ b/src/common/android/id_cache.cpp
@@ -400,14 +400,14 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
return JNI_ERR;
// Initialize Java classes
- const jclass native_library_class = env->FindClass("org/suyu/suyu_emu/NativeLibrary");
+ const jclass native_library_class = env->FindClass("dev/suyu/suyu_emu/NativeLibrary");
s_native_library_class = reinterpret_cast(env->NewGlobalRef(native_library_class));
s_disk_cache_progress_class = reinterpret_cast(env->NewGlobalRef(
- env->FindClass("org/suyu/suyu_emu/disk_shader_cache/DiskShaderCacheProgress")));
+ env->FindClass("dev/suyu/suyu_emu/disk_shader_cache/DiskShaderCacheProgress")));
s_load_callback_stage_class = reinterpret_cast(env->NewGlobalRef(env->FindClass(
- "org/suyu/suyu_emu/disk_shader_cache/DiskShaderCacheProgress$LoadCallbackStage")));
+ "dev/suyu/suyu_emu/disk_shader_cache/DiskShaderCacheProgress$LoadCallbackStage")));
- const jclass game_dir_class = env->FindClass("org/suyu/suyu_emu/model/GameDir");
+ const jclass game_dir_class = env->FindClass("dev/suyu/suyu_emu/model/GameDir");
s_game_dir_class = reinterpret_cast(env->NewGlobalRef(game_dir_class));
s_game_dir_constructor = env->GetMethodID(game_dir_class, "", "(Ljava/lang/String;Z)V");
env->DeleteLocalRef(game_dir_class);
@@ -424,7 +424,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
s_on_program_changed =
env->GetStaticMethodID(s_native_library_class, "onProgramChanged", "(I)V");
- const jclass game_class = env->FindClass("org/suyu/suyu_emu/model/Game");
+ const jclass game_class = env->FindClass("dev/suyu/suyu_emu/model/Game");
s_game_class = reinterpret_cast(env->NewGlobalRef(game_class));
s_game_constructor = env->GetMethodID(game_class, "",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
@@ -450,7 +450,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
env->DeleteLocalRef(pair_class);
const jclass overlay_control_data_class =
- env->FindClass("org/suyu/suyu_emu/overlay/model/OverlayControlData");
+ env->FindClass("dev/suyu/suyu_emu/overlay/model/OverlayControlData");
s_overlay_control_data_class =
reinterpret_cast(env->NewGlobalRef(overlay_control_data_class));
s_overlay_control_data_constructor =
@@ -468,7 +468,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
env->GetFieldID(overlay_control_data_class, "foldablePosition", "Lkotlin/Pair;");
env->DeleteLocalRef(overlay_control_data_class);
- const jclass patch_class = env->FindClass("org/suyu/suyu_emu/model/Patch");
+ const jclass patch_class = env->FindClass("dev/suyu/suyu_emu/model/Patch");
s_patch_class = reinterpret_cast(env->NewGlobalRef(patch_class));
s_patch_constructor = env->GetMethodID(
patch_class, "",
@@ -500,7 +500,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
env->DeleteLocalRef(boolean_class);
const jclass player_input_class =
- env->FindClass("org/suyu/suyu_emu/features/input/model/PlayerInput");
+ env->FindClass("dev/suyu/suyu_emu/features/input/model/PlayerInput");
s_player_input_class = reinterpret_cast(env->NewGlobalRef(player_input_class));
s_player_input_constructor = env->GetMethodID(
player_input_class, "",
@@ -531,7 +531,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
env->DeleteLocalRef(player_input_class);
const jclass suyu_input_device_interface =
- env->FindClass("org/suyu/suyu_emu/features/input/SuyuInputDevice");
+ env->FindClass("dev/suyu/suyu_emu/features/input/SuyuInputDevice");
s_suyu_input_device_interface =
reinterpret_cast(env->NewGlobalRef(suyu_input_device_interface));
s_suyu_input_device_get_name =
diff --git a/src/common/fs/fs_paths.h b/src/common/fs/fs_paths.h
index 3720976efe..de06571a6f 100644
--- a/src/common/fs/fs_paths.h
+++ b/src/common/fs/fs_paths.h
@@ -15,6 +15,7 @@
#define CONFIG_DIR "config"
#define CRASH_DUMPS_DIR "crash_dumps"
#define DUMP_DIR "dump"
+#define ICONS_DIR "icons"
#define KEYS_DIR "keys"
#define LOAD_DIR "load"
#define LOG_DIR "log"
@@ -24,7 +25,7 @@
#define SDMC_DIR "sdmc"
#define SHADER_DIR "shader"
#define TAS_DIR "tas"
-#define ICONS_DIR "icons"
+#define THEMES_DIR "qt_themes"
// suyu-specific files
diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp
index e23f53fb9d..9362e18c39 100644
--- a/src/common/fs/path_util.cpp
+++ b/src/common/fs/path_util.cpp
@@ -121,6 +121,7 @@ public:
GenerateSuyuPath(SuyuPath::ConfigDir, suyu_path_config);
GenerateSuyuPath(SuyuPath::CrashDumpsDir, suyu_path / CRASH_DUMPS_DIR);
GenerateSuyuPath(SuyuPath::DumpDir, suyu_path / DUMP_DIR);
+ GenerateSuyuPath(SuyuPath::IconsDir, suyu_path / ICONS_DIR);
GenerateSuyuPath(SuyuPath::KeysDir, suyu_path / KEYS_DIR);
GenerateSuyuPath(SuyuPath::LoadDir, suyu_path / LOAD_DIR);
GenerateSuyuPath(SuyuPath::LogDir, suyu_path / LOG_DIR);
@@ -130,7 +131,7 @@ public:
GenerateSuyuPath(SuyuPath::SDMCDir, suyu_path / SDMC_DIR);
GenerateSuyuPath(SuyuPath::ShaderDir, suyu_path / SHADER_DIR);
GenerateSuyuPath(SuyuPath::TASDir, suyu_path / TAS_DIR);
- GenerateSuyuPath(SuyuPath::IconsDir, suyu_path / ICONS_DIR);
+ GenerateSuyuPath(SuyuPath::ThemesDir, suyu_path / THEMES_DIR);
}
private:
diff --git a/src/common/fs/path_util.h b/src/common/fs/path_util.h
index 2076fbcd43..1ac4a26eea 100644
--- a/src/common/fs/path_util.h
+++ b/src/common/fs/path_util.h
@@ -17,6 +17,7 @@ enum class SuyuPath {
ConfigDir, // Where config files are stored.
CrashDumpsDir, // Where crash dumps are stored.
DumpDir, // Where dumped data is stored.
+ IconsDir, // Where Icons for Windows shortcuts are stored.
KeysDir, // Where key files are stored.
LoadDir, // Where cheat/mod files are stored.
LogDir, // Where log files are stored.
@@ -26,7 +27,7 @@ enum class SuyuPath {
SDMCDir, // Where the emulated SDMC is stored.
ShaderDir, // Where shaders are stored.
TASDir, // Where TAS scripts are stored.
- IconsDir, // Where Icons for Windows shortcuts are stored.
+ ThemesDir, // Where users should put their custom themes
};
/**
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 948c557674..3339d5b4f0 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -67,6 +67,7 @@ SWITCHABLE(u8, true);
// Used in UISettings
// TODO see if we can move this to uisettings.cpp
SWITCHABLE(ConfirmStop, true);
+SWITCHABLE(DarkModeState, true);
#undef SETTING
#undef SWITCHABLE
diff --git a/src/common/settings.h b/src/common/settings.h
index 829759c94b..4e993ea622 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -1,8 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-// Modified by palfaiate on <2024/03/07>
-
#pragma once
#include
@@ -90,6 +88,7 @@ SWITCHABLE(u8, true);
// Used in UISettings
// TODO see if we can move this to uisettings.h
SWITCHABLE(ConfirmStop, true);
+SWITCHABLE(DarkModeState, true);
#undef SETTING
#undef SWITCHABLE
diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h
index 09006f6223..8cd91bf032 100644
--- a/src/common/settings_enums.h
+++ b/src/common/settings_enums.h
@@ -155,6 +155,8 @@ ENUM(ConsoleMode, Handheld, Docked);
ENUM(AppletMode, HLE, LLE);
+ENUM(DarkModeState, Off, On, Auto);
+
template
inline std::string CanonicalizeEnum(Type id) {
const auto group = EnumMetadata::Canonicalizations();
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 0cb81d6d8f..83517d46cc 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -80,6 +80,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
if (filename == "00") {
const auto dir = vfs->OpenDirectory(dir_name, FileSys::OpenMode::Read);
std::vector concat;
+ concat.reserve(0x10);
for (u32 i = 0; i < 0x10; ++i) {
const auto file_name = fmt::format("{:02X}", i);
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 1abfa920c4..6ac0007764 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -26,24 +26,6 @@ std::shared_ptr CreateEvent(std::string name, TimedCallback&& callbac
return std::make_shared(std::move(callback), std::move(name));
}
-struct CoreTiming::Event {
- s64 time;
- u64 fifo_order;
- std::weak_ptr type;
- s64 reschedule_time;
- heap_t::handle_type handle{};
-
- // Sort by time, unless the times are the same, in which case sort by
- // the order added to the queue
- friend bool operator>(const Event& left, const Event& right) {
- return std::tie(left.time, left.fifo_order) > std::tie(right.time, right.fifo_order);
- }
-
- friend bool operator<(const Event& left, const Event& right) {
- return std::tie(left.time, left.fifo_order) < std::tie(right.time, right.fifo_order);
- }
-};
-
CoreTiming::CoreTiming() : clock{Common::CreateOptimalClock()} {}
CoreTiming::~CoreTiming() {
@@ -87,7 +69,7 @@ void CoreTiming::Pause(bool is_paused) {
}
void CoreTiming::SyncPause(bool is_paused) {
- if (is_paused == paused && paused_set == paused) {
+ if (is_paused == paused && paused_set == is_paused) {
return;
}
@@ -112,7 +94,7 @@ bool CoreTiming::IsRunning() const {
bool CoreTiming::HasPendingEvents() const {
std::scoped_lock lock{basic_lock};
- return !(wait_set && event_queue.empty());
+ return !event_queue.empty();
}
void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future,
@@ -121,8 +103,8 @@ void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future,
std::scoped_lock scope{basic_lock};
const auto next_time{absolute_time ? ns_into_future : GetGlobalTimeNs() + ns_into_future};
- auto h{event_queue.emplace(Event{next_time.count(), event_fifo_id++, event_type, 0})};
- (*h).handle = h;
+ event_queue.emplace_back(Event{next_time.count(), event_fifo_id++, event_type});
+ std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
event.Set();
@@ -136,9 +118,9 @@ void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
std::scoped_lock scope{basic_lock};
const auto next_time{absolute_time ? start_time : GetGlobalTimeNs() + start_time};
- auto h{event_queue.emplace(
- Event{next_time.count(), event_fifo_id++, event_type, resched_time.count()})};
- (*h).handle = h;
+ event_queue.emplace_back(
+ Event{next_time.count(), event_fifo_id++, event_type, resched_time.count()});
+ std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
event.Set();
@@ -149,17 +131,11 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr& event_type,
{
std::scoped_lock lk{basic_lock};
- std::vector to_remove;
- for (auto itr = event_queue.begin(); itr != event_queue.end(); itr++) {
- const Event& e = *itr;
- if (e.type.lock().get() == event_type.get()) {
- to_remove.push_back(itr->handle);
- }
- }
-
- for (auto& h : to_remove) {
- event_queue.erase(h);
- }
+ event_queue.erase(
+ std::remove_if(event_queue.begin(), event_queue.end(),
+ [&](const Event& e) { return e.type.lock().get() == event_type.get(); }),
+ event_queue.end());
+ std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
event_type->sequence_number++;
}
@@ -172,7 +148,7 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr& event_type,
void CoreTiming::AddTicks(u64 ticks_to_add) {
cpu_ticks += ticks_to_add;
- downcount -= static_cast(cpu_ticks);
+ downcount -= static_cast(ticks_to_add);
}
void CoreTiming::Idle() {
@@ -180,7 +156,7 @@ void CoreTiming::Idle() {
}
void CoreTiming::ResetTicks() {
- downcount = MAX_SLICE_LENGTH;
+ downcount.store(MAX_SLICE_LENGTH, std::memory_order_release);
}
u64 CoreTiming::GetClockTicks() const {
@@ -201,48 +177,38 @@ std::optional CoreTiming::Advance() {
std::scoped_lock lock{advance_lock, basic_lock};
global_timer = GetGlobalTimeNs().count();
- while (!event_queue.empty() && event_queue.top().time <= global_timer) {
- const Event& evt = event_queue.top();
+ while (!event_queue.empty() && event_queue.front().time <= global_timer) {
+ Event evt = std::move(event_queue.front());
+ std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>());
+ event_queue.pop_back();
- if (const auto event_type{evt.type.lock()}) {
+ if (const auto event_type = evt.type.lock()) {
const auto evt_time = evt.time;
const auto evt_sequence_num = event_type->sequence_number;
- if (evt.reschedule_time == 0) {
- event_queue.pop();
+ basic_lock.unlock();
- basic_lock.unlock();
+ const auto new_schedule_time = event_type->callback(
+ evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time});
- event_type->callback(
- evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time});
+ basic_lock.lock();
- basic_lock.lock();
- } else {
- basic_lock.unlock();
+ if (evt_sequence_num != event_type->sequence_number) {
+ continue;
+ }
- const auto new_schedule_time{event_type->callback(
- evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time})};
+ if (new_schedule_time.has_value() || evt.reschedule_time != 0) {
+ const auto next_schedule_time = new_schedule_time.value_or(
+ std::chrono::nanoseconds{evt.reschedule_time});
- basic_lock.lock();
-
- if (evt_sequence_num != event_type->sequence_number) {
- // Heap handle is invalidated after external modification.
- continue;
- }
-
- const auto next_schedule_time{new_schedule_time.has_value()
- ? new_schedule_time.value().count()
- : evt.reschedule_time};
-
- // If this event was scheduled into a pause, its time now is going to be way
- // behind. Re-set this event to continue from the end of the pause.
- auto next_time{evt.time + next_schedule_time};
+ auto next_time = evt.time + next_schedule_time.count();
if (evt.time < pause_end_time) {
- next_time = pause_end_time + next_schedule_time;
+ next_time = pause_end_time + next_schedule_time.count();
}
- event_queue.update(evt.handle, Event{next_time, event_fifo_id++, evt.type,
- next_schedule_time, evt.handle});
+ event_queue.emplace_back(Event{next_time, event_fifo_id++, evt.type,
+ next_schedule_time.count()});
+ std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
}
@@ -250,7 +216,7 @@ std::optional CoreTiming::Advance() {
}
if (!event_queue.empty()) {
- return event_queue.top().time;
+ return event_queue.front().time;
} else {
return std::nullopt;
}
@@ -269,7 +235,7 @@ void CoreTiming::ThreadLoop() {
#ifdef _WIN32
while (!paused && !event.IsSet() && wait_time > 0) {
wait_time = *next_time - GetGlobalTimeNs().count();
- if (wait_time >= timer_resolution_ns) {
+ if (wait_time >= 1'000'000) { // 1ms
Common::Windows::SleepForOneTick();
} else {
#ifdef ARCHITECTURE_x86_64
@@ -290,10 +256,8 @@ void CoreTiming::ThreadLoop() {
} else {
// Queue is empty, wait until another event is scheduled and signals us to
// continue.
- wait_set = true;
event.Wait();
}
- wait_set = false;
}
paused_set = true;
@@ -327,10 +291,4 @@ std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const {
return std::chrono::microseconds{Common::WallClock::CPUTickToUS(cpu_ticks)};
}
-#ifdef _WIN32
-void CoreTiming::SetTimerResolutionNs(std::chrono::nanoseconds ns) {
- timer_resolution_ns = ns.count();
-}
-#endif
-
} // namespace Core::Timing
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 7e4dff7f3d..5b42b0e491 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -11,8 +11,7 @@
#include
#include
#include
-
-#include
+#include
#include "common/common_types.h"
#include "common/thread.h"
@@ -43,18 +42,6 @@ enum class UnscheduleEventType {
NoWait,
};
-/**
- * This is a system to schedule events into the emulated machine's future. Time is measured
- * in main CPU clock cycles.
- *
- * To schedule an event, you first have to register its type. This is where you pass in the
- * callback. You then schedule events using the type ID you get back.
- *
- * The s64 ns_late that the callbacks get is how many ns late it was.
- * So to schedule a new event on a regular basis:
- * inside callback:
- * ScheduleEvent(period_in_ns - ns_late, callback, "whatever")
- */
class CoreTiming {
public:
CoreTiming();
@@ -66,99 +53,56 @@ public:
CoreTiming& operator=(const CoreTiming&) = delete;
CoreTiming& operator=(CoreTiming&&) = delete;
- /// CoreTiming begins at the boundary of timing slice -1. An initial call to Advance() is
- /// required to end slice - 1 and start slice 0 before the first cycle of code is executed.
void Initialize(std::function&& on_thread_init_);
-
- /// Clear all pending events. This should ONLY be done on exit.
void ClearPendingEvents();
-
- /// Sets if emulation is multicore or single core, must be set before Initialize
void SetMulticore(bool is_multicore_) {
is_multicore = is_multicore_;
}
-
- /// Pauses/Unpauses the execution of the timer thread.
void Pause(bool is_paused);
-
- /// Pauses/Unpauses the execution of the timer thread and waits until paused.
void SyncPause(bool is_paused);
-
- /// Checks if core timing is running.
bool IsRunning() const;
-
- /// Checks if the timer thread has started.
bool HasStarted() const {
return has_started;
}
-
- /// Checks if there are any pending time events.
bool HasPendingEvents() const;
-
- /// Schedules an event in core timing
void ScheduleEvent(std::chrono::nanoseconds ns_into_future,
const std::shared_ptr& event_type, bool absolute_time = false);
-
- /// Schedules an event which will automatically re-schedule itself with the given time, until
- /// unscheduled
void ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
std::chrono::nanoseconds resched_time,
const std::shared_ptr& event_type,
bool absolute_time = false);
-
void UnscheduleEvent(const std::shared_ptr& event_type,
UnscheduleEventType type = UnscheduleEventType::Wait);
-
void AddTicks(u64 ticks_to_add);
-
void ResetTicks();
-
void Idle();
-
s64 GetDowncount() const {
- return downcount;
+ return downcount.load(std::memory_order_relaxed);
}
-
- /// Returns the current CNTPCT tick value.
u64 GetClockTicks() const;
-
- /// Returns the current GPU tick value.
u64 GetGPUTicks() const;
-
- /// Returns current time in microseconds.
std::chrono::microseconds GetGlobalTimeUs() const;
-
- /// Returns current time in nanoseconds.
std::chrono::nanoseconds GetGlobalTimeNs() const;
-
- /// Checks for events manually and returns time in nanoseconds for next event, threadsafe.
std::optional Advance();
-#ifdef _WIN32
- void SetTimerResolutionNs(std::chrono::nanoseconds ns);
-#endif
-
private:
- struct Event;
+ struct Event {
+ s64 time;
+ u64 fifo_order;
+ std::shared_ptr type;
+ bool operator>(const Event& other) const {
+ return std::tie(time, fifo_order) > std::tie(other.time, other.fifo_order);
+ }
+ };
static void ThreadEntry(CoreTiming& instance);
void ThreadLoop();
-
void Reset();
std::unique_ptr clock;
-
- s64 global_timer = 0;
-
-#ifdef _WIN32
- s64 timer_resolution_ns;
-#endif
-
- using heap_t =
- boost::heap::fibonacci_heap>>;
-
- heap_t event_queue;
- u64 event_fifo_id = 0;
+ std::atomic global_timer{0};
+ std::vector event_queue;
+ std::atomic event_fifo_id{0};
Common::Event event{};
Common::Event pause_event{};
@@ -173,20 +117,12 @@ private:
std::function on_thread_init{};
bool is_multicore{};
- s64 pause_end_time{};
+ std::atomic pause_end_time{};
- /// Cycle timing
- u64 cpu_ticks{};
- s64 downcount{};
+ std::atomic cpu_ticks{};
+ std::atomic downcount{};
};
-/// Creates a core timing event with the given name and callback.
-///
-/// @param name The name of the core timing event to create.
-/// @param callback The callback to execute for the event.
-///
-/// @returns An EventType instance representing the created event.
-///
std::shared_ptr CreateEvent(std::string name, TimedCallback&& callback);
} // namespace Core::Timing
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 9b1c773877..e7e341de16 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -1,6 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include
+#include
+#include
+#include
+#include
+
#include "common/fiber.h"
#include "common/microprofile.h"
#include "common/scope_exit.h"
@@ -24,6 +30,7 @@ void CpuManager::Initialize() {
num_cores = is_multicore ? Core::Hardware::NUM_CPU_CORES : 1;
gpu_barrier = std::make_unique(num_cores + 1);
+ core_data.resize(num_cores);
for (std::size_t core = 0; core < num_cores; core++) {
core_data[core].host_thread =
std::jthread([this, core](std::stop_token token) { RunThread(token, core); });
@@ -31,10 +38,10 @@ void CpuManager::Initialize() {
}
void CpuManager::Shutdown() {
- for (std::size_t core = 0; core < num_cores; core++) {
- if (core_data[core].host_thread.joinable()) {
- core_data[core].host_thread.request_stop();
- core_data[core].host_thread.join();
+ for (auto& data : core_data) {
+ if (data.host_thread.joinable()) {
+ data.host_thread.request_stop();
+ data.host_thread.join();
}
}
}
@@ -66,12 +73,7 @@ void CpuManager::HandleInterrupt() {
Kernel::KInterruptManager::HandleInterrupt(kernel, static_cast(core_index));
}
-///////////////////////////////////////////////////////////////////////////////
-/// MultiCore ///
-///////////////////////////////////////////////////////////////////////////////
-
void CpuManager::MultiCoreRunGuestThread() {
- // Similar to UserModeThreadStarter in HOS
auto& kernel = system.Kernel();
auto* thread = Kernel::GetCurrentThreadPointer(kernel);
kernel.CurrentScheduler()->OnThreadStart();
@@ -88,10 +90,6 @@ void CpuManager::MultiCoreRunGuestThread() {
}
void CpuManager::MultiCoreRunIdleThread() {
- // Not accurate to HOS. Remove this entire method when singlecore is removed.
- // See notes in KScheduler::ScheduleImpl for more information about why this
- // is inaccurate.
-
auto& kernel = system.Kernel();
kernel.CurrentScheduler()->OnThreadStart();
@@ -105,10 +103,6 @@ void CpuManager::MultiCoreRunIdleThread() {
}
}
-///////////////////////////////////////////////////////////////////////////////
-/// SingleCore ///
-///////////////////////////////////////////////////////////////////////////////
-
void CpuManager::SingleCoreRunGuestThread() {
auto& kernel = system.Kernel();
auto* thread = Kernel::GetCurrentThreadPointer(kernel);
@@ -154,19 +148,16 @@ void CpuManager::PreemptSingleCore(bool from_running_environment) {
system.CoreTiming().Advance();
kernel.SetIsPhantomModeForSingleCore(false);
}
- current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES);
+ current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES, std::memory_order_release);
system.CoreTiming().ResetTicks();
kernel.Scheduler(current_core).PreemptSingleCore();
- // We've now been scheduled again, and we may have exchanged schedulers.
- // Reload the scheduler in case it's different.
if (!kernel.Scheduler(current_core).IsIdle()) {
idle_count = 0;
}
}
void CpuManager::GuestActivate() {
- // Similar to the HorizonKernelMain callback in HOS
auto& kernel = system.Kernel();
auto* scheduler = kernel.CurrentScheduler();
@@ -184,27 +175,19 @@ void CpuManager::ShutdownThread() {
}
void CpuManager::RunThread(std::stop_token token, std::size_t core) {
- /// Initialization
system.RegisterCoreThread(core);
- std::string name;
- if (is_multicore) {
- name = "CPUCore_" + std::to_string(core);
- } else {
- name = "CPUThread";
- }
+ std::string name = is_multicore ? "CPUCore_" + std::to_string(core) : "CPUThread";
MicroProfileOnThreadCreate(name.c_str());
Common::SetCurrentThreadName(name.c_str());
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
auto& data = core_data[core];
data.host_context = Common::Fiber::ThreadToFiber();
- // Cleanup
SCOPE_EXIT {
data.host_context->Exit();
MicroProfileOnThreadExit();
};
- // Running
if (!gpu_barrier->Sync(token)) {
return;
}
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp
index 80091cc7e0..27d45fca5f 100644
--- a/src/core/debugger/gdbstub.cpp
+++ b/src/core/debugger/gdbstub.cpp
@@ -481,6 +481,7 @@ void GDBStub::HandleQuery(std::string_view command) {
// beginning of list
const auto& threads = GetProcess()->GetThreadList();
std::vector thread_ids;
+ thread_ids.reserve(threads.size());
for (const auto& thread : threads) {
thread_ids.push_back(fmt::format("{:x}", thread.GetThreadId()));
}
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index c208be83f2..fae8e74e44 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -261,7 +261,7 @@ std::vector PlaceholderCache::List() const {
std::vector out;
for (const auto& sdir : dir->GetSubdirectories()) {
for (const auto& file : sdir->GetFiles()) {
- const auto name = file->GetName();
+ const auto& name = file->GetName();
if (name.length() == 36 && name.ends_with(".nca")) {
out.push_back(Common::HexStringToArray<0x10>(name.substr(0, 32)));
}
diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp
index 68e8ec22fc..4ab7e03590 100644
--- a/src/core/file_sys/submission_package.cpp
+++ b/src/core/file_sys/submission_package.cpp
@@ -117,7 +117,9 @@ std::vector> NSP::GetNCAsCollapsed() const {
if (extracted)
LOG_WARNING(Service_FS, "called on an NSP that is of type extracted.");
std::vector> out;
+ out.reserve(ncas.size());
for (const auto& map : ncas) {
+ out.reserve(map.second.size());
for (const auto& inner_map : map.second)
out.push_back(inner_map.second);
}
diff --git a/src/core/file_sys/system_archive/ng_word.cpp b/src/core/file_sys/system_archive/ng_word.cpp
index 1fa67877dd..13ae1999ee 100644
--- a/src/core/file_sys/system_archive/ng_word.cpp
+++ b/src/core/file_sys/system_archive/ng_word.cpp
@@ -24,7 +24,7 @@ constexpr std::array WORD_TXT{
VirtualDir NgWord1() {
std::vector files;
- files.reserve(NgWord1Data::NUMBER_WORD_TXT_FILES);
+ files.reserve(files.size() + 2);
for (std::size_t i = 0; i < files.size(); ++i) {
files.push_back(MakeArrayFile(NgWord1Data::WORD_TXT, fmt::format("{}.txt", i)));
@@ -54,7 +54,7 @@ constexpr std::array AC_NX_DATA{
VirtualDir NgWord2() {
std::vector files;
- files.reserve(NgWord2Data::NUMBER_AC_NX_FILES * 3);
+ files.reserve(NgWord2Data::NUMBER_AC_NX_FILES + 4);
for (std::size_t i = 0; i < NgWord2Data::NUMBER_AC_NX_FILES; ++i) {
files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b1_nx", i)));
diff --git a/src/core/file_sys/system_archive/time_zone_binary.cpp b/src/core/file_sys/system_archive/time_zone_binary.cpp
index 316ff0dc6f..3fa703a6fa 100644
--- a/src/core/file_sys/system_archive/time_zone_binary.cpp
+++ b/src/core/file_sys/system_archive/time_zone_binary.cpp
@@ -37,6 +37,7 @@ const static std::map& directory,
const std::map>& files) {
+ directory.reserve(files.size());
for (const auto& [filename, data] : files) {
const auto data_copy{data};
const std::string filename_copy{filename};
@@ -54,6 +55,7 @@ static std::vector GenerateZoneinfoFiles() {
VirtualDir TimeZoneBinary() {
std::vector america_sub_dirs;
+ america_sub_dirs.reserve(tzdb_america_dirs.size());
for (const auto& [dir_name, files] : tzdb_america_dirs) {
std::vector vfs_files;
GenerateFiles(vfs_files, files);
@@ -62,6 +64,7 @@ VirtualDir TimeZoneBinary() {
}
std::vector zoneinfo_sub_dirs;
+ zoneinfo_sub_dirs.reserve(tzdb_zoneinfo_dirs.size());
for (const auto& [dir_name, files] : tzdb_zoneinfo_dirs) {
std::vector vfs_files;
GenerateFiles(vfs_files, files);
diff --git a/src/core/file_sys/vfs/vfs_cached.cpp b/src/core/file_sys/vfs/vfs_cached.cpp
index 01cd0f1e08..9f570520bb 100644
--- a/src/core/file_sys/vfs/vfs_cached.cpp
+++ b/src/core/file_sys/vfs/vfs_cached.cpp
@@ -38,7 +38,8 @@ VirtualDir CachedVfsDirectory::GetSubdirectory(std::string_view dir_name) const
std::vector CachedVfsDirectory::GetFiles() const {
std::vector out;
- for (auto& [file_name, file] : files) {
+ out.reserve(files.size());
+ for (const auto& [_, file] : files) {
out.push_back(file);
}
return out;
@@ -46,7 +47,8 @@ std::vector CachedVfsDirectory::GetFiles() const {
std::vector CachedVfsDirectory::GetSubdirectories() const {
std::vector out;
- for (auto& [dir_name, dir] : dirs) {
+ out.reserve(dirs.size());
+ for (auto& [_, dir] : dirs) {
out.push_back(dir);
}
return out;
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp
index 7714717f74..e67105dea4 100644
--- a/src/core/hle/kernel/k_page_table_base.cpp
+++ b/src/core/hle/kernel/k_page_table_base.cpp
@@ -172,6 +172,7 @@ Result KPageTableBase::InitializeForKernel(bool is_64_bit, KVirtualAddress start
m_mapped_unsafe_physical_memory = 0;
m_mapped_insecure_memory = 0;
m_mapped_ipc_server_memory = 0;
+ m_alias_region_extra_size = 0;
m_memory_block_slab_manager =
m_kernel.GetSystemSystemResource().GetMemoryBlockSlabManagerPointer();
@@ -269,6 +270,12 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool
process_code_end = m_code_region_end;
}
+ m_alias_region_extra_size = 0;
+ if (as_type == Svc::CreateProcessFlag::EnableReservedRegionExtraSize) {
+ m_alias_region_extra_size = GetAddressSpaceSize() / 8;
+ alias_region_size += m_alias_region_extra_size;
+ }
+
// Set other basic fields.
m_enable_aslr = enable_aslr;
m_enable_device_address_space_merge = enable_das_merge;
diff --git a/src/core/hle/kernel/k_page_table_base.h b/src/core/hle/kernel/k_page_table_base.h
index 37c745d14a..d944306b70 100644
--- a/src/core/hle/kernel/k_page_table_base.h
+++ b/src/core/hle/kernel/k_page_table_base.h
@@ -208,6 +208,7 @@ private:
size_t m_mapped_unsafe_physical_memory{};
size_t m_mapped_insecure_memory{};
size_t m_mapped_ipc_server_memory{};
+ size_t m_alias_region_extra_size{};
mutable KLightLock m_general_lock;
mutable KLightLock m_map_physical_memory_lock;
KLightLock m_device_map_lock;
@@ -682,6 +683,9 @@ public:
size_t GetAliasRegionSize() const {
return m_alias_region_end - m_alias_region_start;
}
+ size_t GetReservedRegionExtraSize() const {
+ return m_alias_region_extra_size;
+ }
size_t GetStackRegionSize() const {
return m_stack_region_end - m_stack_region_start;
}
diff --git a/src/core/hle/kernel/k_process_page_table.h b/src/core/hle/kernel/k_process_page_table.h
index 346d7ca083..38c5fb8162 100644
--- a/src/core/hle/kernel/k_process_page_table.h
+++ b/src/core/hle/kernel/k_process_page_table.h
@@ -410,6 +410,9 @@ public:
size_t GetAliasRegionSize() const {
return m_page_table.GetAliasRegionSize();
}
+ size_t GetReservedRegionExtraSize() const {
+ return m_page_table.GetReservedRegionExtraSize();
+ }
size_t GetStackRegionSize() const {
return m_page_table.GetStackRegionSize();
}
diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp
index 231e4d0e1b..007bb9f705 100644
--- a/src/core/hle/kernel/svc/svc_info.cpp
+++ b/src/core/hle/kernel/svc/svc_info.cpp
@@ -37,7 +37,8 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
case InfoType::TotalNonSystemMemorySize:
case InfoType::UsedNonSystemMemorySize:
case InfoType::IsApplication:
- case InfoType::FreeThreadCount: {
+ case InfoType::FreeThreadCount:
+ case InfoType::ReservedRegionExtraSize: {
R_UNLESS(info_sub_id == 0, ResultInvalidEnumValue);
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
@@ -134,6 +135,10 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
}
R_SUCCEED();
+ case InfoType::ReservedRegionExtraSize:
+ *result = process->GetPageTable().GetReservedRegionExtraSize();
+ R_SUCCEED();
+
default:
break;
}
diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h
index ab432ea78b..df92fa0089 100644
--- a/src/core/hle/kernel/svc_types.h
+++ b/src/core/hle/kernel/svc_types.h
@@ -153,6 +153,7 @@ enum class InfoType : u32 {
ThreadTickCount = 25,
IsSvcPermitted = 26,
IoRegionHint = 27,
+ ReservedRegionExtraSize = 28,
MesosphereMeta = 65000,
MesosphereCurrentProcess = 65001,
@@ -642,9 +643,12 @@ enum class CreateProcessFlag : u32 {
// 11.x+ DisableDeviceAddressSpaceMerge.
DisableDeviceAddressSpaceMerge = (1 << 12),
+ EnableReservedRegionExtraSize = (1 << 13),
+
// Mask of all flags.
All = Is64Bit | AddressSpaceMask | EnableDebug | EnableAslr | IsApplication |
- PoolPartitionMask | OptimizeMemoryAllocation | DisableDeviceAddressSpaceMerge,
+ PoolPartitionMask | OptimizeMemoryAllocation | DisableDeviceAddressSpaceMerge |
+ EnableReservedRegionExtraSize,
};
DECLARE_ENUM_FLAG_OPERATORS(CreateProcessFlag);
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 888b34336b..fd7104dfee 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -102,6 +102,7 @@ public:
{150, nullptr, "CreateAuthorizationRequest"},
{160, nullptr, "RequiresUpdateNetworkServiceAccountIdTokenCache"},
{161, nullptr, "RequireReauthenticationOfNetworkServiceAccount"},
+ {180, nullptr, "GetRequestForNintendoAccountReauthentication"}, // 18.0.0+
};
// clang-format on
@@ -135,6 +136,7 @@ public:
{13, nullptr, "GetLinkedNintendoAccountId"},
{14, nullptr, "GetNickname"},
{15, nullptr, "GetProfileImage"},
+ {16, nullptr, "GetProfileLargeImage"}, // 18.0.0+
{21, nullptr, "LoadIdTokenCache"},
{100, nullptr, "RegisterUser"}, // [1.0.0-3.0.2] RegisterAsync
{101, nullptr, "RegisterUserWithUid"}, // [1.0.0-3.0.2] RegisterWithUidAsync
@@ -176,10 +178,11 @@ public:
{140, nullptr, "GetNetworkServiceLicenseCache"}, // 5.0.0+
{141, nullptr, "RefreshNetworkServiceLicenseCacheAsync"}, // 5.0.0+
{142, nullptr, "RefreshNetworkServiceLicenseCacheAsyncIfSecondsElapsed"}, // 5.0.0+
- {143, nullptr, "GetNetworkServiceLicenseCacheEx"},
+ {143, nullptr, "GetNetworkServiceLicenseCacheEx"}, // 15.0.0+
{150, nullptr, "CreateAuthorizationRequest"},
- {160, nullptr, "RequiresUpdateNetworkServiceAccountIdTokenCache"},
- {161, nullptr, "RequireReauthenticationOfNetworkServiceAccount"},
+ {160, nullptr, "RequiresUpdateNetworkServiceAccountIdTokenCache"}, // 16.0.0+
+ {161, nullptr, "RequireReauthenticationOfNetworkServiceAccount"}, // 16.0.0+
+ {180, nullptr, "GetRequestForNintendoAccountReauthentication"}, // 18.0.0+
{200, nullptr, "IsRegistered"},
{201, nullptr, "RegisterAsync"},
{202, nullptr, "UnregisterAsync"},
@@ -263,6 +266,7 @@ public:
{101, nullptr, "GetLinkedNintendoAccountId"},
{102, nullptr, "GetNickname"},
{103, nullptr, "GetProfileImage"},
+ {104, nullptr, "GetProfileLargeImage"}, // 18.0.0+
};
// clang-format on
@@ -317,6 +321,9 @@ public:
{1, &IProfileCommon::GetBase, "GetBase"},
{10, &IProfileCommon::GetImageSize, "GetImageSize"},
{11, &IProfileCommon::LoadImage, "LoadImage"},
+ {20, &IProfileCommon::GetImageSize, "GetLargeImageSize"}, // 18.0.0+
+ {21, &IProfileCommon::LoadImage, "LoadLargeImage"}, // 18.0.0+
+ {30, &IProfileCommon::Unknown, "GetImageId"}, // 18.0.0+
};
RegisterHandlers(functions);
@@ -325,6 +332,7 @@ public:
static const FunctionInfo editor_functions[] = {
{100, &IProfileCommon::Store, "Store"},
{101, &IProfileCommon::StoreWithImage, "StoreWithImage"},
+ {110, &IProfileCommon::StoreWithImage, "StoreWithLargeImage"}, // 18.0.0+
};
RegisterHandlers(editor_functions);
@@ -486,6 +494,13 @@ protected:
rb.Push(ResultSuccess);
}
+ void Unknown(HLERequestContext& ctx) {
+ LOG_WARNING(Service_ACC, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(0);
+ }
+
ProfileManager& profile_manager;
Common::UUID user_id{}; ///< The user id this profile refers to.
};
@@ -501,7 +516,15 @@ class IProfileEditor final : public IProfileCommon {
public:
explicit IProfileEditor(Core::System& system_, Common::UUID user_id_,
ProfileManager& profile_manager_)
- : IProfileCommon{system_, "IProfileEditor", true, user_id_, profile_manager_} {}
+ : IProfileCommon{system_, "IProfileEditor", true, user_id_, profile_manager_} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {30, &IProfileEditor::Unknown, "Unknown"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
};
class ISessionObject final : public ServiceFramework {
@@ -530,6 +553,7 @@ public:
{13, nullptr, "GetLinkedNintendoAccountId"},
{14, nullptr, "GetNickname"},
{15, nullptr, "GetProfileImage"},
+ {16, nullptr, "GetProfileLargeImage"}, // 18.0.0+
{21, nullptr, "LoadIdTokenCache"}, // 3.0.0+
};
// clang-format on
@@ -684,8 +708,15 @@ public:
{101, nullptr, "GetLinkedNintendoAccountId"},
{102, nullptr, "GetNickname"},
{103, nullptr, "GetProfileImage"},
+ {104, nullptr, "GetProfileLargeImage"}, // 18.0.0+
{110, nullptr, "RegisterUserAsync"},
{111, nullptr, "GetUid"},
+ {200, nullptr, "ApplyResponseForUserCreationAsync"}, // 17.0.0+
+ {205, nullptr, "SuspendAfterApplyResponse"}, // 17.0.0+
+ {210, nullptr, "IsProfileAvailable"}, // 17.0.0+
+ {220, nullptr, "RegisterUserAsyncWithoutProfile"}, // 17.0.0+
+ {221, nullptr, "RegisterUserWithProfileAsync"}, // 17.0.0+
+ {230, nullptr, "RegisterUserWithLargeImageProfileAsync"}, // 18.0.0+
};
// clang-format on
diff --git a/src/core/hle/service/am/window_system.cpp b/src/core/hle/service/am/window_system.cpp
index 5cf24007cc..ca289a84d1 100644
--- a/src/core/hle/service/am/window_system.cpp
+++ b/src/core/hle/service/am/window_system.cpp
@@ -121,7 +121,7 @@ void WindowSystem::RequestAppletVisibilityState(Applet& applet, bool visible) {
void WindowSystem::OnOperationModeChanged() {
std::scoped_lock lk{m_lock};
- for (const auto& [aruid, applet] : m_applets) {
+ for (const auto& [_, applet] : m_applets) {
std::scoped_lock lk2{applet->lock};
applet->lifecycle_manager.OnOperationAndPerformanceModeChanged();
}
@@ -130,7 +130,7 @@ void WindowSystem::OnOperationModeChanged() {
void WindowSystem::OnExitRequested() {
std::scoped_lock lk{m_lock};
- for (const auto& [aruid, applet] : m_applets) {
+ for (const auto& [_, applet] : m_applets) {
std::scoped_lock lk2{applet->lock};
applet->lifecycle_manager.RequestExit();
}
@@ -156,7 +156,7 @@ void WindowSystem::OnHomeButtonPressed(ButtonPressDuration type) {
void WindowSystem::PruneTerminatedAppletsLocked() {
for (auto it = m_applets.begin(); it != m_applets.end(); /* ... */) {
- const auto& [aruid, applet] = *it;
+ const auto& [_, applet] = *it;
std::scoped_lock lk{applet->lock};
diff --git a/src/core/hle/service/audio/audio_device.cpp b/src/core/hle/service/audio/audio_device.cpp
index 438f3cccdf..d3b104f710 100644
--- a/src/core/hle/service/audio/audio_device.cpp
+++ b/src/core/hle/service/audio/audio_device.cpp
@@ -27,8 +27,15 @@ IAudioDevice::IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u
{10, D<&IAudioDevice::GetActiveAudioDeviceNameAuto>, "GetActiveAudioDeviceNameAuto"},
{11, D<&IAudioDevice::QueryAudioDeviceInputEvent>, "QueryAudioDeviceInputEvent"},
{12, D<&IAudioDevice::QueryAudioDeviceOutputEvent>, "QueryAudioDeviceOutputEvent"},
- {13, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioOutputDeviceName"},
- {14, D<&IAudioDevice::ListAudioOutputDeviceName>, "ListAudioOutputDeviceName"},
+ {13, D<&IAudioDevice::GetActiveAudioDeviceName>,
+ "GetActiveAudioOutputDeviceName"}, // 13.0.0+
+ {14, D<&IAudioDevice::ListAudioOutputDeviceName>, "ListAudioOutputDeviceName"}, // 13.0.0+
+ {15, nullptr, "AcquireAudioInputDeviceNotification"}, // 17.0.0+
+ {16, nullptr, "ReleaseAudioInputDeviceNotification"}, // 17.0.0+
+ {17, nullptr, "AcquireAudioOutputDeviceNotification"}, // 17.0.0+
+ {18, nullptr, "ReleaseAudioOutputDeviceNotification"}, // 17.0.0+
+ {19, nullptr, "SetAudioDeviceOutputVolumeAutoTuneEnabled"}, // 18.0.0+
+ {20, nullptr, "IsAudioDeviceOutputVolumeAutoTuneEnabled"} // 18.0.0+
};
RegisterHandlers(functions);
diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp
index 2bc6361bb7..ed503d5d6a 100644
--- a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp
@@ -53,7 +53,7 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{1, D<&FSP_SRV::SetCurrentProcess>, "SetCurrentProcess"},
{2, nullptr, "OpenDataFileSystemByCurrentProcess"},
{7, D<&FSP_SRV::OpenFileSystemWithPatch>, "OpenFileSystemWithPatch"},
- {8, nullptr, "OpenFileSystemWithId"},
+ {8, nullptr, "OpenFileSystemWithIdObsolete"}, // 16.0.0+, OpenFileSystemWithId 2.0.0-15.0.1
{9, nullptr, "OpenDataFileSystemByApplicationId"},
{11, nullptr, "OpenBisFileSystem"},
{12, nullptr, "OpenBisStorage"},
@@ -169,6 +169,7 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{1018, nullptr, "SetDebugOption"},
{1019, nullptr, "UnsetDebugOption"},
{1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
+ {1101, nullptr, "OverrideSaveDataTransferKeyForTest"}, // 18.0.0+
{1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
{1200, D<&FSP_SRV::OpenMultiCommitManager>, "OpenMultiCommitManager"},
{1300, nullptr, "OpenBisWiper"},
diff --git a/src/core/hle/service/ldn/lan_discovery.cpp b/src/core/hle/service/ldn/lan_discovery.cpp
index b9db19618a..e947a3c2a0 100644
--- a/src/core/hle/service/ldn/lan_discovery.cpp
+++ b/src/core/hle/service/ldn/lan_discovery.cpp
@@ -119,7 +119,7 @@ Result LANDiscovery::Scan(std::span out_networks, s16& out_count,
std::this_thread::sleep_for(std::chrono::seconds(1));
std::scoped_lock lock{packet_mutex};
- for (const auto& [key, info] : scan_results) {
+ for (const auto& [_, info] : scan_results) {
if (out_count >= static_cast(out_networks.size())) {
break;
}
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp
index f2d638c30e..1b0148fda0 100644
--- a/src/core/hle/service/ldn/ldn.cpp
+++ b/src/core/hle/service/ldn/ldn.cpp
@@ -40,6 +40,7 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, C<&ISystemServiceCreator::CreateSystemLocalCommunicationService>, "CreateSystemLocalCommunicationService"},
+ {1, nullptr, "CreateClientProcessMonitor"} // 18.0.0+
};
// clang-format on
@@ -62,6 +63,7 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, C<&IUserServiceCreator::CreateUserLocalCommunicationService>, "CreateUserLocalCommunicationService"},
+ {1, nullptr, "CreateClientProcessMonitor"}, // 18.0.0+
};
// clang-format on
diff --git a/src/core/hle/service/ldn/system_local_communication_service.cpp b/src/core/hle/service/ldn/system_local_communication_service.cpp
index 7b52223cdc..fc283da4cf 100644
--- a/src/core/hle/service/ldn/system_local_communication_service.cpp
+++ b/src/core/hle/service/ldn/system_local_communication_service.cpp
@@ -40,6 +40,13 @@ ISystemLocalCommunicationService::ISystemLocalCommunicationService(Core::System&
{401, nullptr, "FinalizeSystem"},
{402, nullptr, "SetOperationMode"},
{403, C<&ISystemLocalCommunicationService::InitializeSystem2>, "InitializeSystem2"},
+ {500, nullptr, "EnableActionFrame"}, // 18.0.0+
+ {501, nullptr, "DisableActionFrame"}, // 18.0.0+
+ {502, nullptr, "SendActionFrame"}, // 18.0.0+
+ {503, nullptr, "RecvActionFrame"}, // 18.0.0+
+ {505, nullptr, "SetHomeChannel"}, // 18.0.0+
+ {600, nullptr, "SetTxPower"}, // 18.0.0+
+ {601, nullptr, "ResetTxPower"} // 18.0.0+
};
// clang-format on
diff --git a/src/core/hle/service/ldn/user_local_communication_service.cpp b/src/core/hle/service/ldn/user_local_communication_service.cpp
index f28368962f..8e559f4400 100644
--- a/src/core/hle/service/ldn/user_local_communication_service.cpp
+++ b/src/core/hle/service/ldn/user_local_communication_service.cpp
@@ -53,7 +53,14 @@ IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& sys
{304, C<&IUserLocalCommunicationService::Disconnect>, "Disconnect"},
{400, C<&IUserLocalCommunicationService::Initialize>, "Initialize"},
{401, C<&IUserLocalCommunicationService::Finalize>, "Finalize"},
- {402, C<&IUserLocalCommunicationService::Initialize2>, "Initialize2"},
+ {402, C<&IUserLocalCommunicationService::Initialize2>, "Initialize2"}, // 7.0.0+
+ {500, nullptr, "EnableActionFrame"}, // 18.0.0+
+ {501, nullptr, "DisableActionFrame"}, // 18.0.0+
+ {502, nullptr, "SendActionFrame"}, // 18.0.0+
+ {503, nullptr, "RecvActionFrame"}, // 18.0.0+
+ {505, nullptr, "SetHomeChannel"}, // 18.0.0+
+ {600, nullptr, "SetTxPower"}, // 18.0.0+
+ {601, nullptr, "ResetTxPower"} // 18.0.0+
};
// clang-format on
diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp
index e54827efef..0c6ba14b4e 100644
--- a/src/core/hle/service/npns/npns.cpp
+++ b/src/core/hle/service/npns/npns.cpp
@@ -24,26 +24,44 @@ public:
{4, nullptr, "ReceiveRaw"},
{5, C<&INpnsSystem::GetReceiveEvent>, "GetReceiveEvent"},
{6, nullptr, "ListenUndelivered"},
- {7, nullptr, "GetStateChangeEVent"},
+ {7, nullptr, "GetStateChangeEvent"},
+ {8, nullptr, "ListenToByName"}, // 18.0.0+
{11, nullptr, "SubscribeTopic"},
{12, nullptr, "UnsubscribeTopic"},
{13, nullptr, "QueryIsTopicExist"},
+ {14, nullptr, "SubscribeTopicByAccount"}, // 18.0.0+
+ {15, nullptr, "UnsubscribeTopicByAccount"}, // 18.0.0+
+ {16, nullptr, "DownloadSubscriptionList"}, // 18.0.0+
{21, nullptr, "CreateToken"},
{22, nullptr, "CreateTokenWithApplicationId"},
{23, nullptr, "DestroyToken"},
{24, nullptr, "DestroyTokenWithApplicationId"},
{25, nullptr, "QueryIsTokenValid"},
{26, nullptr, "ListenToMyApplicationId"},
- {27, nullptr, "DestroyTokenAll"},
+ {27, nullptr, "DestroyTokenAll"}, // 13.0.0+
+ {28, nullptr, "CreateTokenWithName"}, // 18.0.0+
+ {29, nullptr, "DestroyTokenWithName"}, // 18.0.0+
{31, nullptr, "UploadTokenToBaaS"},
{32, nullptr, "DestroyTokenForBaaS"},
{33, nullptr, "CreateTokenForBaaS"},
{34, nullptr, "SetBaaSDeviceAccountIdList"},
+ {35, nullptr, "LinkNsaId"}, // 17.0.0+
+ {36, nullptr, "UnlinkNsaId"}, // 17.0.0+
+ {37, nullptr, "RelinkNsaId"}, // 18.0.0+
+ {40, nullptr, "GetNetworkServiceAccountIdTokenRequestEvent"}, // 17.0.0+
+ {41, nullptr, "TryPopNetworkServiceAccountIdTokenRequestUid"}, // 17.0.0+
+ {42, nullptr, "SetNetworkServiceAccountIdTokenSuccess"}, // 17.0.0+
+ {43, nullptr, "SetNetworkServiceAccountIdTokenFailure"}, // 17.0.0+
+ {44, nullptr, "SetUidList"}, // 17.0.0+
+ {45, nullptr, "PutDigitalTwinKeyValue"}, // 17.0.0+
+ {51, nullptr, "DeleteDigitalTwinKeyValue"}, // 18.0.0+
{101, nullptr, "Suspend"},
{102, nullptr, "Resume"},
{103, nullptr, "GetState"},
{104, nullptr, "GetStatistics"},
{105, nullptr, "GetPlayReportRequestEvent"},
+ {106, nullptr, "GetLastNotifiedTime"},
+ {107, nullptr, "SetLastNotifiedTime"},
{111, nullptr, "GetJid"},
{112, nullptr, "CreateJid"},
{113, nullptr, "DestroyJid"},
@@ -55,10 +73,17 @@ public:
{153, nullptr, "GetDropEventWithHandover"},
{154, nullptr, "CreateTokenAsync"},
{155, nullptr, "CreateTokenAsyncWithApplicationId"},
- {161, nullptr, "GetRequestChangeStateCancelEvent"},
- {162, nullptr, "RequestChangeStateForceTimedWithCancelEvent"},
- {201, nullptr, "RequestChangeStateForceTimed"},
- {202, nullptr, "RequestChangeStateForceAsync"},
+ {156, nullptr, "CreateTokenWithNameAsync"}, // 18.0.0+
+ {161, nullptr, "GetRequestChangeStateCancelEvent"}, // 10.0.0+
+ {162, nullptr, "RequestChangeStateForceTimedWithCancelEvent"}, // 10.0.0+
+ {201, nullptr, "RequestChangeStateForceTimed"}, // 3.0.0+
+ {202, nullptr, "RequestChangeStateForceAsync"}, // 3.0.0+
+ {301, nullptr, "GetPassword"}, // 18.0.0+
+ {302, nullptr, "GetAllImmigration"}, // 18.0.0+
+ {303, nullptr, "GetNotificationHistories"}, // 18.0.0+
+ {304, nullptr, "GetPersistentConnectionSummary"}, // 18.0.0+
+ {305, nullptr, "GetDigitalTwinSummary"}, // 18.0.0+
+ {306, nullptr, "GetDigitalTwinValue"}, // 18.0.0+
};
// clang-format on
@@ -98,7 +123,8 @@ public:
{3, nullptr, "Receive"},
{4, nullptr, "ReceiveRaw"},
{5, nullptr, "GetReceiveEvent"},
- {7, nullptr, "GetStateChangeEVent"},
+ {7, nullptr, "GetStateChangeEvent"},
+ {8, nullptr, "ListenToByName"}, // 18.0.0+
{21, nullptr, "CreateToken"},
{23, nullptr, "DestroyToken"},
{25, nullptr, "QueryIsTokenValid"},
diff --git a/src/core/hle/service/ns/application_manager_interface.cpp b/src/core/hle/service/ns/application_manager_interface.cpp
index 7a91727f97..df0bd8acce 100644
--- a/src/core/hle/service/ns/application_manager_interface.cpp
+++ b/src/core/hle/service/ns/application_manager_interface.cpp
@@ -348,7 +348,7 @@ Result IApplicationManagerInterface::ListApplicationRecord(
size_t i = 0;
u8 ii = 24;
- for (const auto& [slot, game] : installed_games) {
+ for (const auto& [_, game] : installed_games) {
if (i >= limit) {
break;
}
diff --git a/src/core/hle/service/pctl/parental_control_service.cpp b/src/core/hle/service/pctl/parental_control_service.cpp
index f57f2f1577..664d9c1fd8 100644
--- a/src/core/hle/service/pctl/parental_control_service.cpp
+++ b/src/core/hle/service/pctl/parental_control_service.cpp
@@ -86,6 +86,7 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili
{1472, nullptr, "CancelNetworkRequest"},
{1473, D<&IParentalControlService::GetUnlinkedEvent>, "GetUnlinkedEvent"},
{1474, nullptr, "ClearUnlinkedEvent"},
+ {1475, nullptr, "GetExtendedPlayTimerEvent"}, // 18.0.0+
{1601, nullptr, "DisableAllFeatures"},
{1602, nullptr, "PostEnableAllFeatures"},
{1603, nullptr, "IsAllFeaturesDisabled"},
@@ -101,6 +102,10 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili
{1951, nullptr, "SetPlayTimerSettingsForDebug"},
{1952, nullptr, "GetPlayTimerSpentTimeForTest"},
{1953, nullptr, "SetPlayTimerAlarmDisabledForDebug"},
+ {1954, nullptr, "IsBedtimeAlarmEnabled"}, // 18.0.0+
+ {1955, nullptr, "GetBedtimeAlarmTime"}, // 18.0.0+
+ {1956, nullptr, "GetBedtimeAlarmTimeHour"}, // 18.0.0+
+ {1967, nullptr, "GetBedtimeAlarmMinute"}, // 18.0.0+
{2001, nullptr, "RequestPairingAsync"},
{2002, nullptr, "FinishRequestPairing"},
{2003, nullptr, "AuthorizePairingAsync"},
@@ -117,6 +122,8 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili
{2014, nullptr, "FinishSynchronizeParentalControlSettings"},
{2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"},
{2016, nullptr, "RequestUpdateExemptionListAsync"},
+ {145601, nullptr, "GetPlayTimerSettingsVer2"}, // 18.0.0+
+ {195101, nullptr, "SetPlayTimerSettingsForDebugVer2"}, // 18.0.0+
};
// clang-format on
RegisterHandlers(functions);
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 1095dcf6c3..2cf12aba52 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -28,7 +28,7 @@ ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {
}
ServiceManager::~ServiceManager() {
- for (auto& [name, port] : service_ports) {
+ for (auto& [_, port] : service_ports) {
port->Close();
}
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp
index 008ee44923..37105d74b7 100644
--- a/src/core/hle/service/ssl/ssl.cpp
+++ b/src/core/hle/service/ssl/ssl.cpp
@@ -507,7 +507,11 @@ public:
{6, nullptr, "FlushSessionCache"},
{7, nullptr, "SetDebugOption"},
{8, nullptr, "GetDebugOption"},
- {8, nullptr, "ClearTls12FallbackFlag"},
+ {9, nullptr, "ClearTls12FallbackFlag"},
+ {100, nullptr, "CreateContextForSystem"},
+ {101, nullptr, "SetThreadCoreMask"},
+ {102, nullptr, "GetThreadCoreMask"},
+ {103, nullptr, "VerifySignature"}, // 18.0.0+
};
// clang-format on
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index f7eae9c598..6e53db3640 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
#include "common/assert.h"
#include "common/atomic_ops.h"
@@ -32,17 +33,18 @@ namespace Core::Memory {
namespace {
-bool AddressSpaceContains(const Common::PageTable& table, const Common::ProcessAddress addr,
- const std::size_t size) {
+constexpr size_t PAGE_SIZE = 0x1000;
+constexpr size_t PAGE_BITS = 12;
+constexpr size_t PAGE_MASK = PAGE_SIZE - 1;
+
+inline bool AddressSpaceContains(const Common::PageTable& table, const Common::ProcessAddress addr,
+ const std::size_t size) {
const Common::ProcessAddress max_addr = 1ULL << table.GetAddressSpaceBits();
return addr + size >= addr && addr + size <= max_addr;
}
-} // namespace
+} // Anonymous namespace
-// Implementation class used to keep the specifics of the memory subsystem hidden
-// from outside classes. This also allows modification to the internals of the memory
-// subsystem without needing to rebuild all files that make use of the memory interface.
struct Memory::Impl {
explicit Impl(Core::System& system_) : system{system_} {}
@@ -66,12 +68,11 @@ struct Memory::Impl {
void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
Common::PhysicalAddress target, Common::MemoryPermission perms,
bool separate_heap) {
- ASSERT_MSG((size & SUYU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
- ASSERT_MSG((base & SUYU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base));
+ ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
+ ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", GetInteger(base));
ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}",
GetInteger(target));
- MapPages(page_table, base / SUYU_PAGESIZE, size / SUYU_PAGESIZE, target,
- Common::PageType::Memory);
+ MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory);
if (current_page_table->fastmem_arena) {
buffer->Map(GetInteger(base), GetInteger(target) - DramMemoryMap::Base, size, perms,
@@ -81,10 +82,9 @@ struct Memory::Impl {
void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
bool separate_heap) {
- ASSERT_MSG((size & SUYU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
- ASSERT_MSG((base & SUYU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base));
- MapPages(page_table, base / SUYU_PAGESIZE, size / SUYU_PAGESIZE, 0,
- Common::PageType::Unmapped);
+ ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
+ ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", GetInteger(base));
+ MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, 0, Common::PageType::Unmapped);
if (current_page_table->fastmem_arena) {
buffer->Unmap(GetInteger(base), size, separate_heap);
@@ -93,55 +93,28 @@ struct Memory::Impl {
void ProtectRegion(Common::PageTable& page_table, VAddr vaddr, u64 size,
Common::MemoryPermission perms) {
- ASSERT_MSG((size & SUYU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
- ASSERT_MSG((vaddr & SUYU_PAGEMASK) == 0, "non-page aligned base: {:016X}", vaddr);
+ ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
+ ASSERT_MSG((vaddr & PAGE_MASK) == 0, "non-page aligned base: {:016X}", vaddr);
if (!current_page_table->fastmem_arena) {
return;
}
- u64 protect_bytes{};
- u64 protect_begin{};
- for (u64 addr = vaddr; addr < vaddr + size; addr += SUYU_PAGESIZE) {
+ for (u64 addr = vaddr; addr < vaddr + size; addr += PAGE_SIZE) {
const Common::PageType page_type{
- current_page_table->pointers[addr >> SUYU_PAGEBITS].Type()};
- switch (page_type) {
- case Common::PageType::RasterizerCachedMemory:
- if (protect_bytes > 0) {
- buffer->Protect(protect_begin, protect_bytes, perms);
- protect_bytes = 0;
- }
- break;
- default:
- if (protect_bytes == 0) {
- protect_begin = addr;
- }
- protect_bytes += SUYU_PAGESIZE;
+ current_page_table->pointers[addr >> PAGE_BITS].Type()};
+ if (page_type != Common::PageType::RasterizerCachedMemory) {
+ buffer->Protect(addr, PAGE_SIZE, perms);
}
}
-
- if (protect_bytes > 0) {
- buffer->Protect(protect_begin, protect_bytes, perms);
- }
}
- [[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(u64 vaddr) const {
+ u8* GetPointerFromRasterizerCachedMemory(u64 vaddr) const {
const Common::PhysicalAddress paddr{
- current_page_table->backing_addr[vaddr >> SUYU_PAGEBITS]};
+ current_page_table->backing_addr[vaddr >> PAGE_BITS]};
if (!paddr) {
- return {};
- }
-
- return system.DeviceMemory().GetPointer(paddr + vaddr);
- }
-
- [[nodiscard]] u8* GetPointerFromDebugMemory(u64 vaddr) const {
- const Common::PhysicalAddress paddr{
- current_page_table->backing_addr[vaddr >> SUYU_PAGEBITS]};
-
- if (paddr == 0) {
- return {};
+ return nullptr;
}
return system.DeviceMemory().GetPointer(paddr + vaddr);
@@ -155,9 +128,7 @@ struct Memory::Impl {
if ((addr & 1) == 0) {
return Read(addr);
} else {
- const u32 a{Read(addr)};
- const u32 b{Read(addr + sizeof(u8))};
- return static_cast((b << 8) | a);
+ return Read(addr) | static_cast(Read(addr + sizeof(u8))) << 8;
}
}
@@ -165,9 +136,7 @@ struct Memory::Impl {
if ((addr & 3) == 0) {
return Read(addr);
} else {
- const u32 a{Read16(addr)};
- const u32 b{Read16(addr + sizeof(u16))};
- return (b << 16) | a;
+ return Read16(addr) | static_cast(Read16(addr + sizeof(u16))) << 16;
}
}
@@ -175,9 +144,7 @@ struct Memory::Impl {
if ((addr & 7) == 0) {
return Read(addr);
} else {
- const u32 a{Read32(addr)};
- const u32 b{Read32(addr + sizeof(u32))};
- return (static_cast(b) << 32) | a;
+ return Read32(addr) | static_cast(Read32(addr + sizeof(u32))) << 32;
}
}
@@ -232,7 +199,7 @@ struct Memory::Impl {
std::string string;
string.reserve(max_length);
for (std::size_t i = 0; i < max_length; ++i) {
- const char c = Read(vaddr);
+ const char c = Read(vaddr);
if (c == '\0') {
break;
}
@@ -243,648 +210,72 @@ struct Memory::Impl {
return string;
}
- bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped,
- auto on_memory, auto on_rasterizer, auto increment) {
- const auto& page_table = *current_page_table;
- std::size_t remaining_size = size;
- std::size_t page_index = addr >> SUYU_PAGEBITS;
- std::size_t page_offset = addr & SUYU_PAGEMASK;
- bool user_accessible = true;
-
- if (!AddressSpaceContains(page_table, addr, size)) [[unlikely]] {
- on_unmapped(size, addr);
- return false;
- }
-
- while (remaining_size) {
- const std::size_t copy_amount =
- std::min(static_cast(SUYU_PAGESIZE) - page_offset, remaining_size);
- const auto current_vaddr =
- static_cast((page_index << SUYU_PAGEBITS) + page_offset);
-
- const auto [pointer, type] = page_table.pointers[page_index].PointerType();
- switch (type) {
- case Common::PageType::Unmapped: {
- user_accessible = false;
- on_unmapped(copy_amount, current_vaddr);
- break;
- }
- case Common::PageType::Memory: {
- u8* mem_ptr =
- reinterpret_cast(pointer + page_offset + (page_index << SUYU_PAGEBITS));
- on_memory(copy_amount, mem_ptr);
- break;
- }
- case Common::PageType::DebugMemory: {
- u8* const mem_ptr{GetPointerFromDebugMemory(current_vaddr)};
- on_memory(copy_amount, mem_ptr);
- break;
- }
- case Common::PageType::RasterizerCachedMemory: {
- u8* const host_ptr{GetPointerFromRasterizerCachedMemory(current_vaddr)};
- on_rasterizer(current_vaddr, copy_amount, host_ptr);
- break;
- }
- default:
- UNREACHABLE();
- }
-
- page_index++;
- page_offset = 0;
- increment(copy_amount);
- remaining_size -= copy_amount;
- }
-
- return user_accessible;
- }
-
- template
- bool ReadBlockImpl(const Common::ProcessAddress src_addr, void* dest_buffer,
- const std::size_t size) {
- return WalkBlock(
- src_addr, size,
- [src_addr, size, &dest_buffer](const std::size_t copy_amount,
- const Common::ProcessAddress current_vaddr) {
- LOG_ERROR(HW_Memory,
- "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
- GetInteger(current_vaddr), GetInteger(src_addr), size);
- std::memset(dest_buffer, 0, copy_amount);
- },
- [&](const std::size_t copy_amount, const u8* const src_ptr) {
- std::memcpy(dest_buffer, src_ptr, copy_amount);
- },
- [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
- const u8* const host_ptr) {
- if constexpr (!UNSAFE) {
- HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount);
- }
- std::memcpy(dest_buffer, host_ptr, copy_amount);
- },
- [&](const std::size_t copy_amount) {
- dest_buffer = static_cast(dest_buffer) + copy_amount;
- });
- }
-
- bool ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
- const std::size_t size) {
- return ReadBlockImpl(src_addr, dest_buffer, size);
- }
-
- bool ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
- const std::size_t size) {
- return ReadBlockImpl(src_addr, dest_buffer, size);
- }
-
- const u8* GetSpan(const VAddr src_addr, const std::size_t size) const {
- if (current_page_table->blocks[src_addr >> SUYU_PAGEBITS] ==
- current_page_table->blocks[(src_addr + size) >> SUYU_PAGEBITS]) {
- return GetPointerSilent(src_addr);
- }
- return nullptr;
- }
-
- u8* GetSpan(const VAddr src_addr, const std::size_t size) {
- if (current_page_table->blocks[src_addr >> SUYU_PAGEBITS] ==
- current_page_table->blocks[(src_addr + size) >> SUYU_PAGEBITS]) {
- return GetPointerSilent(src_addr);
- }
- return nullptr;
- }
-
- template
- bool WriteBlockImpl(const Common::ProcessAddress dest_addr, const void* src_buffer,
- const std::size_t size) {
- return WalkBlock(
- dest_addr, size,
- [dest_addr, size](const std::size_t copy_amount,
- const Common::ProcessAddress current_vaddr) {
- LOG_ERROR(HW_Memory,
- "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
- GetInteger(current_vaddr), GetInteger(dest_addr), size);
- },
- [&](const std::size_t copy_amount, u8* const dest_ptr) {
- std::memcpy(dest_ptr, src_buffer, copy_amount);
- },
- [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
- u8* const host_ptr) {
- if constexpr (!UNSAFE) {
- HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
- }
- std::memcpy(host_ptr, src_buffer, copy_amount);
- },
- [&](const std::size_t copy_amount) {
- src_buffer = static_cast(src_buffer) + copy_amount;
- });
- }
-
- bool WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
- const std::size_t size) {
- return WriteBlockImpl(dest_addr, src_buffer, size);
- }
-
- bool WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
- const std::size_t size) {
- return WriteBlockImpl(dest_addr, src_buffer, size);
- }
-
- bool ZeroBlock(const Common::ProcessAddress dest_addr, const std::size_t size) {
- return WalkBlock(
- dest_addr, size,
- [dest_addr, size](const std::size_t copy_amount,
- const Common::ProcessAddress current_vaddr) {
- LOG_ERROR(HW_Memory,
- "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
- GetInteger(current_vaddr), GetInteger(dest_addr), size);
- },
- [](const std::size_t copy_amount, u8* const dest_ptr) {
- std::memset(dest_ptr, 0, copy_amount);
- },
- [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
- u8* const host_ptr) {
- HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
- std::memset(host_ptr, 0, copy_amount);
- },
- [](const std::size_t copy_amount) {});
- }
-
- bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
- const std::size_t size) {
- return WalkBlock(
- dest_addr, size,
- [&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) {
- LOG_ERROR(HW_Memory,
- "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
- GetInteger(current_vaddr), GetInteger(src_addr), size);
- ZeroBlock(dest_addr, copy_amount);
- },
- [&](const std::size_t copy_amount, const u8* const src_ptr) {
- WriteBlockImpl(dest_addr, src_ptr, copy_amount);
- },
- [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
- u8* const host_ptr) {
- HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount);
- WriteBlockImpl(dest_addr, host_ptr, copy_amount);
- },
- [&](const std::size_t copy_amount) {
- dest_addr += copy_amount;
- src_addr += copy_amount;
- });
- }
-
- template
- Result PerformCacheOperation(Common::ProcessAddress dest_addr, std::size_t size,
- Callback&& cb) {
- class InvalidMemoryException : public std::exception {};
-
- try {
- WalkBlock(
- dest_addr, size,
- [&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) {
- LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}",
- GetInteger(current_vaddr));
- throw InvalidMemoryException();
- },
- [&](const std::size_t block_size, u8* const host_ptr) {},
- [&](const Common::ProcessAddress current_vaddr, const std::size_t block_size,
- u8* const host_ptr) { cb(current_vaddr, block_size); },
- [](const std::size_t block_size) {});
- } catch (InvalidMemoryException&) {
- return Kernel::ResultInvalidCurrentMemory;
- }
-
- return ResultSuccess;
- }
-
- Result InvalidateDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
- auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
- const std::size_t block_size) {
- // dc ivac: Invalidate to point of coherency
- // GPU flush -> CPU invalidate
- HandleRasterizerDownload(GetInteger(current_vaddr), block_size);
- };
- return PerformCacheOperation(dest_addr, size, on_rasterizer);
- }
-
- Result StoreDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
- auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
- const std::size_t block_size) {
- // dc cvac: Store to point of coherency
- // CPU flush -> GPU invalidate
- HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
- };
- return PerformCacheOperation(dest_addr, size, on_rasterizer);
- }
-
- Result FlushDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
- auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
- const std::size_t block_size) {
- // dc civac: Store to point of coherency, and invalidate from cache
- // CPU flush -> GPU invalidate
- HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
- };
- return PerformCacheOperation(dest_addr, size, on_rasterizer);
- }
-
- void MarkRegionDebug(u64 vaddr, u64 size, bool debug) {
- if (vaddr == 0 || !AddressSpaceContains(*current_page_table, vaddr, size)) {
- return;
- }
-
- if (current_page_table->fastmem_arena) {
- const auto perm{debug ? Common::MemoryPermission{}
- : Common::MemoryPermission::ReadWrite};
- buffer->Protect(vaddr, size, perm);
- }
-
- // Iterate over a contiguous CPU address space, marking/unmarking the region.
- // The region is at a granularity of CPU pages.
-
- const u64 num_pages = ((vaddr + size - 1) >> SUYU_PAGEBITS) - (vaddr >> SUYU_PAGEBITS) + 1;
- for (u64 i = 0; i < num_pages; ++i, vaddr += SUYU_PAGESIZE) {
- const Common::PageType page_type{
- current_page_table->pointers[vaddr >> SUYU_PAGEBITS].Type()};
- if (debug) {
- // Switch page type to debug if now debug
- switch (page_type) {
- case Common::PageType::Unmapped:
- ASSERT_MSG(false, "Attempted to mark unmapped pages as debug");
- break;
- case Common::PageType::RasterizerCachedMemory:
- case Common::PageType::DebugMemory:
- // Page is already marked.
- break;
- case Common::PageType::Memory:
- current_page_table->pointers[vaddr >> SUYU_PAGEBITS].Store(
- 0, Common::PageType::DebugMemory);
- break;
- default:
- UNREACHABLE();
- }
- } else {
- // Switch page type to non-debug if now non-debug
- switch (page_type) {
- case Common::PageType::Unmapped:
- ASSERT_MSG(false, "Attempted to mark unmapped pages as non-debug");
- break;
- case Common::PageType::RasterizerCachedMemory:
- case Common::PageType::Memory:
- // Don't mess with already non-debug or rasterizer memory.
- break;
- case Common::PageType::DebugMemory: {
- u8* const pointer{GetPointerFromDebugMemory(vaddr & ~SUYU_PAGEMASK)};
- current_page_table->pointers[vaddr >> SUYU_PAGEBITS].Store(
- reinterpret_cast(pointer) - (vaddr & ~SUYU_PAGEMASK),
- Common::PageType::Memory);
- break;
- }
- default:
- UNREACHABLE();
- }
- }
- }
- }
-
- void RasterizerMarkRegionCached(u64 vaddr, u64 size, bool cached) {
- if (vaddr == 0 || !AddressSpaceContains(*current_page_table, vaddr, size)) {
- return;
- }
-
- if (current_page_table->fastmem_arena) {
- Common::MemoryPermission perm{};
- if (!Settings::values.use_reactive_flushing.GetValue() || !cached) {
- perm |= Common::MemoryPermission::Read;
- }
- if (!cached) {
- perm |= Common::MemoryPermission::Write;
- }
- buffer->Protect(vaddr, size, perm);
- }
-
- // Iterate over a contiguous CPU address space, which corresponds to the specified GPU
- // address space, marking the region as un/cached. The region is marked un/cached at a
- // granularity of CPU pages, hence why we iterate on a CPU page basis (note: GPU page size
- // is different). This assumes the specified GPU address region is contiguous as well.
-
- const u64 num_pages = ((vaddr + size - 1) >> SUYU_PAGEBITS) - (vaddr >> SUYU_PAGEBITS) + 1;
- for (u64 i = 0; i < num_pages; ++i, vaddr += SUYU_PAGESIZE) {
- const Common::PageType page_type{
- current_page_table->pointers[vaddr >> SUYU_PAGEBITS].Type()};
- if (cached) {
- // Switch page type to cached if now cached
- switch (page_type) {
- case Common::PageType::Unmapped:
- // It is not necessary for a process to have this region mapped into its address
- // space, for example, a system module need not have a VRAM mapping.
- break;
- case Common::PageType::DebugMemory:
- case Common::PageType::Memory:
- current_page_table->pointers[vaddr >> SUYU_PAGEBITS].Store(
- 0, Common::PageType::RasterizerCachedMemory);
- break;
- case Common::PageType::RasterizerCachedMemory:
- // There can be more than one GPU region mapped per CPU region, so it's common
- // that this area is already marked as cached.
- break;
- default:
- UNREACHABLE();
- }
- } else {
- // Switch page type to uncached if now uncached
- switch (page_type) {
- case Common::PageType::Unmapped: // NOLINT(bugprone-branch-clone)
- // It is not necessary for a process to have this region mapped into its address
- // space, for example, a system module need not have a VRAM mapping.
- break;
- case Common::PageType::DebugMemory:
- case Common::PageType::Memory:
- // There can be more than one GPU region mapped per CPU region, so it's common
- // that this area is already unmarked as cached.
- break;
- case Common::PageType::RasterizerCachedMemory: {
- u8* const pointer{GetPointerFromRasterizerCachedMemory(vaddr & ~SUYU_PAGEMASK)};
- if (pointer == nullptr) {
- // It's possible that this function has been called while updating the
- // pagetable after unmapping a VMA. In that case the underlying VMA will no
- // longer exist, and we should just leave the pagetable entry blank.
- current_page_table->pointers[vaddr >> SUYU_PAGEBITS].Store(
- 0, Common::PageType::Unmapped);
- } else {
- current_page_table->pointers[vaddr >> SUYU_PAGEBITS].Store(
- reinterpret_cast(pointer) - (vaddr & ~SUYU_PAGEMASK),
- Common::PageType::Memory);
- }
- break;
- }
- default:
- UNREACHABLE();
- }
- }
- }
- }
-
- /**
- * Maps a region of pages as a specific type.
- *
- * @param page_table The page table to use to perform the mapping.
- * @param base The base address to begin mapping at.
- * @param size The total size of the range in bytes.
- * @param target The target address to begin mapping from.
- * @param type The page type to map the memory as.
- */
- void MapPages(Common::PageTable& page_table, Common::ProcessAddress base_address, u64 size,
- Common::PhysicalAddress target, Common::PageType type) {
- auto base = GetInteger(base_address);
-
- LOG_DEBUG(HW_Memory, "Mapping {:016X} onto {:016X}-{:016X}", GetInteger(target),
- base * SUYU_PAGESIZE, (base + size) * SUYU_PAGESIZE);
-
- const auto end = base + size;
- ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}",
- base + page_table.pointers.size());
-
- if (!target) {
- ASSERT_MSG(type != Common::PageType::Memory,
- "Mapping memory page without a pointer @ {:016x}", base * SUYU_PAGESIZE);
-
- while (base != end) {
- page_table.pointers[base].Store(0, type);
- page_table.backing_addr[base] = 0;
- page_table.blocks[base] = 0;
- base += 1;
- }
- } else {
- auto orig_base = base;
- while (base != end) {
- auto host_ptr =
- reinterpret_cast(system.DeviceMemory().GetPointer(target)) -
- (base << SUYU_PAGEBITS);
- auto backing = GetInteger(target) - (base << SUYU_PAGEBITS);
- page_table.pointers[base].Store(host_ptr, type);
- page_table.backing_addr[base] = backing;
- page_table.blocks[base] = orig_base << SUYU_PAGEBITS;
-
- ASSERT_MSG(page_table.pointers[base].Pointer(),
- "memory mapping base yield a nullptr within the table");
-
- base += 1;
- target += SUYU_PAGESIZE;
- }
- }
- }
-
- [[nodiscard]] u8* GetPointerImpl(u64 vaddr, auto on_unmapped, auto on_rasterizer) const {
- // AARCH64 masks the upper 16 bit of all memory accesses
- vaddr = vaddr & 0xffffffffffffULL;
-
- if (!AddressSpaceContains(*current_page_table, vaddr, 1)) [[unlikely]] {
- on_unmapped();
- return nullptr;
- }
-
- // Avoid adding any extra logic to this fast-path block
- const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> SUYU_PAGEBITS].Raw();
- if (const uintptr_t pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
- return reinterpret_cast(pointer + vaddr);
- }
- switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
- case Common::PageType::Unmapped:
- on_unmapped();
- return nullptr;
- case Common::PageType::Memory:
- ASSERT_MSG(false, "Mapped memory page without a pointer @ 0x{:016X}", vaddr);
- return nullptr;
- case Common::PageType::DebugMemory:
- return GetPointerFromDebugMemory(vaddr);
- case Common::PageType::RasterizerCachedMemory: {
- u8* const host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)};
- on_rasterizer();
- return host_ptr;
- }
- default:
- UNREACHABLE();
- }
- return nullptr;
- }
-
- [[nodiscard]] u8* GetPointer(const Common::ProcessAddress vaddr) const {
- return GetPointerImpl(
- GetInteger(vaddr),
- [vaddr]() {
- LOG_ERROR(HW_Memory, "Unmapped GetPointer @ 0x{:016X}", GetInteger(vaddr));
- },
- []() {});
- }
-
- [[nodiscard]] u8* GetPointerSilent(const Common::ProcessAddress vaddr) const {
- return GetPointerImpl(
- GetInteger(vaddr), []() {}, []() {});
- }
-
- /**
- * Reads a particular data type out of memory at the given virtual address.
- *
- * @param vaddr The virtual address to read the data type from.
- *
- * @tparam T The data type to read out of memory. This type *must* be
- * trivially copyable, otherwise the behavior of this function
- * is undefined.
- *
- * @returns The instance of T read from the specified virtual address.
- */
template
- T Read(Common::ProcessAddress vaddr) {
- T result = 0;
- const u8* const ptr = GetPointerImpl(
- GetInteger(vaddr),
- [vaddr]() {
- LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:016X}", sizeof(T) * 8,
- GetInteger(vaddr));
- },
- [&]() { HandleRasterizerDownload(GetInteger(vaddr), sizeof(T)); });
+ T Read(const Common::ProcessAddress vaddr) {
+ T value;
+ const u8* const ptr = GetPointerFromRasterizerCachedMemory(GetInteger(vaddr));
if (ptr) {
- std::memcpy(&result, ptr, sizeof(T));
+ std::memcpy(&value, ptr, sizeof(T));
+ } else {
+ LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:016X}", sizeof(T) * 8, GetInteger(vaddr));
+ value = 0;
}
- return result;
+ return value;
}
- /**
- * Writes a particular data type to memory at the given virtual address.
- *
- * @param vaddr The virtual address to write the data type to.
- *
- * @tparam T The data type to write to memory. This type *must* be
- * trivially copyable, otherwise the behavior of this function
- * is undefined.
- */
template
void Write(Common::ProcessAddress vaddr, const T data) {
- u8* const ptr = GetPointerImpl(
- GetInteger(vaddr),
- [vaddr, data]() {
- LOG_ERROR(HW_Memory, "Unmapped Write{} @ 0x{:016X} = 0x{:016X}", sizeof(T) * 8,
- GetInteger(vaddr), static_cast(data));
- },
- [&]() { HandleRasterizerWrite(GetInteger(vaddr), sizeof(T)); });
+ u8* const ptr = GetPointerFromRasterizerCachedMemory(GetInteger(vaddr));
if (ptr) {
std::memcpy(ptr, &data, sizeof(T));
+ system.GPU().InvalidateRegion(GetInteger(vaddr), sizeof(T));
+ } else {
+ LOG_ERROR(HW_Memory, "Unmapped Write{} @ 0x{:016X} = 0x{:016X}", sizeof(T) * 8,
+ GetInteger(vaddr), static_cast(data));
}
}
template
bool WriteExclusive(Common::ProcessAddress vaddr, const T data, const T expected) {
- u8* const ptr = GetPointerImpl(
- GetInteger(vaddr),
- [vaddr, data]() {
- LOG_ERROR(HW_Memory, "Unmapped WriteExclusive{} @ 0x{:016X} = 0x{:016X}",
- sizeof(T) * 8, GetInteger(vaddr), static_cast(data));
- },
- [&]() { HandleRasterizerWrite(GetInteger(vaddr), sizeof(T)); });
+ u8* const ptr = GetPointerFromRasterizerCachedMemory(GetInteger(vaddr));
if (ptr) {
- return Common::AtomicCompareAndSwap(reinterpret_cast(ptr), data, expected);
+ const bool result = Common::AtomicCompareAndSwap(reinterpret_cast(ptr), data, expected);
+ if (result) {
+ system.GPU().InvalidateRegion(GetInteger(vaddr), sizeof(T));
+ }
+ return result;
+ } else {
+ LOG_ERROR(HW_Memory, "Unmapped WriteExclusive{} @ 0x{:016X} = 0x{:016X}", sizeof(T) * 8,
+ GetInteger(vaddr), static_cast(data));
+ return true;
}
- return true;
}
- bool WriteExclusive128(Common::ProcessAddress vaddr, const u128 data, const u128 expected) {
- u8* const ptr = GetPointerImpl(
- GetInteger(vaddr),
- [vaddr, data]() {
- LOG_ERROR(HW_Memory, "Unmapped WriteExclusive128 @ 0x{:016X} = 0x{:016X}{:016X}",
- GetInteger(vaddr), static_cast(data[1]), static_cast(data[0]));
- },
- [&]() { HandleRasterizerWrite(GetInteger(vaddr), sizeof(u128)); });
- if (ptr) {
- return Common::AtomicCompareAndSwap(reinterpret_cast(ptr), data, expected);
+ bool ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
+ const std::size_t size) {
+ const u8* src_ptr = GetPointerFromRasterizerCachedMemory(GetInteger(src_addr));
+ if (src_ptr) {
+ std::memcpy(dest_buffer, src_ptr, size);
+ return true;
}
- return true;
+ LOG_ERROR(HW_Memory, "Unmapped ReadBlock @ 0x{:016X}", GetInteger(src_addr));
+ return false;
}
- void HandleRasterizerDownload(VAddr v_address, size_t size) {
- const auto* p = GetPointerImpl(
- v_address, []() {}, []() {});
- if (!gpu_device_memory) [[unlikely]] {
- gpu_device_memory = &system.Host1x().MemoryManager();
+ bool WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
+ const std::size_t size) {
+ u8* const dest_ptr = GetPointerFromRasterizerCachedMemory(GetInteger(dest_addr));
+ if (dest_ptr) {
+ std::memcpy(dest_ptr, src_buffer, size);
+ system.GPU().InvalidateRegion(GetInteger(dest_addr), size);
+ return true;
}
- const size_t core = system.GetCurrentHostThreadID();
- auto& current_area = rasterizer_read_areas[core];
- gpu_device_memory->ApplyOpOnPointer(p, scratch_buffers[core], [&](DAddr address) {
- const DAddr end_address = address + size;
- if (current_area.start_address <= address && end_address <= current_area.end_address)
- [[likely]] {
- return;
- }
- current_area = system.GPU().OnCPURead(address, size);
- });
- }
-
- void HandleRasterizerWrite(VAddr v_address, size_t size) {
- const auto* p = GetPointerImpl(
- v_address, []() {}, []() {});
- constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1;
- const size_t core = std::min(system.GetCurrentHostThreadID(),
- sys_core); // any other calls threads go to syscore.
- if (!gpu_device_memory) [[unlikely]] {
- gpu_device_memory = &system.Host1x().MemoryManager();
- }
- // Guard on sys_core;
- if (core == sys_core) [[unlikely]] {
- sys_core_guard.lock();
- }
- SCOPE_EXIT {
- if (core == sys_core) [[unlikely]] {
- sys_core_guard.unlock();
- }
- };
- gpu_device_memory->ApplyOpOnPointer(p, scratch_buffers[core], [&](DAddr address) {
- auto& current_area = rasterizer_write_areas[core];
- PAddr subaddress = address >> SUYU_PAGEBITS;
- bool do_collection = current_area.last_address == subaddress;
- if (!do_collection) [[unlikely]] {
- do_collection = system.GPU().OnCPUWrite(address, size);
- if (!do_collection) {
- return;
- }
- current_area.last_address = subaddress;
- }
- gpu_dirty_managers[core].Collect(address, size);
- });
- }
-
- struct GPUDirtyState {
- PAddr last_address;
- };
-
- void InvalidateGPUMemory(u8* p, size_t size) {
- constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1;
- const size_t core = std::min(system.GetCurrentHostThreadID(),
- sys_core); // any other calls threads go to syscore.
- if (!gpu_device_memory) [[unlikely]] {
- gpu_device_memory = &system.Host1x().MemoryManager();
- }
- // Guard on sys_core;
- if (core == sys_core) [[unlikely]] {
- sys_core_guard.lock();
- }
- SCOPE_EXIT {
- if (core == sys_core) [[unlikely]] {
- sys_core_guard.unlock();
- }
- };
- auto& gpu = system.GPU();
- gpu_device_memory->ApplyOpOnPointer(
- p, scratch_buffers[core], [&](DAddr address) { gpu.InvalidateRegion(address, size); });
+ LOG_ERROR(HW_Memory, "Unmapped WriteBlock @ 0x{:016X}", GetInteger(dest_addr));
+ return false;
}
Core::System& system;
- Tegra::MaxwellDeviceMemoryManager* gpu_device_memory{};
Common::PageTable* current_page_table = nullptr;
- std::array
- rasterizer_read_areas{};
- std::array rasterizer_write_areas{};
- std::array, Core::Hardware::NUM_CPU_CORES> scratch_buffers{};
- std::span gpu_dirty_managers;
- std::mutex sys_core_guard;
-
std::optional heap_tracker;
#ifdef __linux__
Common::HeapTracker* buffer{};
@@ -893,16 +284,10 @@ struct Memory::Impl {
#endif
};
-Memory::Memory(Core::System& system_) : system{system_} {
- Reset();
-}
+Memory::Memory(Core::System& system_) : impl{std::make_unique(system_)} {}
Memory::~Memory() = default;
-void Memory::Reset() {
- impl = std::make_unique(system);
-}
-
void Memory::SetCurrentPageTable(Kernel::KProcess& process) {
impl->SetCurrentPageTable(process);
}
@@ -925,38 +310,20 @@ void Memory::ProtectRegion(Common::PageTable& page_table, Common::ProcessAddress
bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
const auto& page_table = *impl->current_page_table;
- const size_t page = vaddr >> SUYU_PAGEBITS;
+ const size_t page = vaddr >> PAGE_BITS;
if (page >= page_table.pointers.size()) {
return false;
}
const auto [pointer, type] = page_table.pointers[page].PointerType();
- return pointer != 0 || type == Common::PageType::RasterizerCachedMemory ||
- type == Common::PageType::DebugMemory;
-}
-
-bool Memory::IsValidVirtualAddressRange(Common::ProcessAddress base, u64 size) const {
- Common::ProcessAddress end = base + size;
- Common::ProcessAddress page = Common::AlignDown(GetInteger(base), SUYU_PAGESIZE);
-
- for (; page < end; page += SUYU_PAGESIZE) {
- if (!IsValidVirtualAddress(page)) {
- return false;
- }
- }
-
- return true;
+ return pointer != 0 || type == Common::PageType::RasterizerCachedMemory;
}
u8* Memory::GetPointer(Common::ProcessAddress vaddr) {
- return impl->GetPointer(vaddr);
-}
-
-u8* Memory::GetPointerSilent(Common::ProcessAddress vaddr) {
- return impl->GetPointerSilent(vaddr);
+ return impl->GetPointerFromRasterizerCachedMemory(GetInteger(vaddr));
}
const u8* Memory::GetPointer(Common::ProcessAddress vaddr) const {
- return impl->GetPointer(vaddr);
+ return impl->GetPointerFromRasterizerCachedMemory(GetInteger(vaddr));
}
u8 Memory::Read8(const Common::ProcessAddress addr) {
@@ -1007,10 +374,6 @@ bool Memory::WriteExclusive64(Common::ProcessAddress addr, u64 data, u64 expecte
return impl->WriteExclusive64(addr, data, expected);
}
-bool Memory::WriteExclusive128(Common::ProcessAddress addr, u128 data, u128 expected) {
- return impl->WriteExclusive128(addr, data, expected);
-}
-
std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_length) {
return impl->ReadCString(vaddr, max_length);
}
@@ -1020,93 +383,9 @@ bool Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
return impl->ReadBlock(src_addr, dest_buffer, size);
}
-bool Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
- const std::size_t size) {
- return impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
-}
-
-const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const {
- return impl->GetSpan(src_addr, size);
-}
-
-u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) {
- return impl->GetSpan(src_addr, size);
-}
-
bool Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
const std::size_t size) {
return impl->WriteBlock(dest_addr, src_buffer, size);
}
-bool Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
- const std::size_t size) {
- return impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
-}
-
-bool Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
- const std::size_t size) {
- return impl->CopyBlock(dest_addr, src_addr, size);
-}
-
-bool Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) {
- return impl->ZeroBlock(dest_addr, size);
-}
-
-void Memory::SetGPUDirtyManagers(std::span managers) {
- impl->gpu_dirty_managers = managers;
-}
-
-Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
- return impl->InvalidateDataCache(dest_addr, size);
-}
-
-Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
- return impl->StoreDataCache(dest_addr, size);
-}
-
-Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
- return impl->FlushDataCache(dest_addr, size);
-}
-
-void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) {
- impl->RasterizerMarkRegionCached(GetInteger(vaddr), size, cached);
-}
-
-void Memory::MarkRegionDebug(Common::ProcessAddress vaddr, u64 size, bool debug) {
- impl->MarkRegionDebug(GetInteger(vaddr), size, debug);
-}
-
-bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) {
- [[maybe_unused]] bool mapped = true;
- [[maybe_unused]] bool rasterizer = false;
-
- u8* const ptr = impl->GetPointerImpl(
- GetInteger(vaddr),
- [&] {
- LOG_ERROR(HW_Memory, "Unmapped InvalidateNCE for {} bytes @ {:#x}", size,
- GetInteger(vaddr));
- mapped = false;
- },
- [&] { rasterizer = true; });
- if (rasterizer) {
- impl->InvalidateGPUMemory(ptr, size);
- }
-
-#ifdef __linux__
- if (!rasterizer && mapped) {
- impl->buffer->DeferredMapSeparateHeap(GetInteger(vaddr));
- }
-#endif
-
- return mapped && ptr != nullptr;
-}
-
-bool Memory::InvalidateSeparateHeap(void* fault_address) {
-#ifdef __linux__
- return impl->buffer->DeferredMapSeparateHeap(static_cast(fault_address));
-#else
- return false;
-#endif
-}
-
} // namespace Core::Memory
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp
index eea607b66d..20aecf4c76 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -571,7 +571,7 @@ SDLDriver::~SDLDriver() {
std::vector SDLDriver::GetInputDevices() const {
std::vector devices;
std::unordered_map> joycon_pairs;
- for (const auto& [key, value] : joystick_map) {
+ for (const auto& [_, value] : joystick_map) {
for (const auto& joystick : value) {
if (!joystick->GetSDLJoystick()) {
continue;
@@ -591,7 +591,7 @@ std::vector SDLDriver::GetInputDevices() const {
}
// Add dual controllers
- for (const auto& [key, value] : joystick_map) {
+ for (const auto& [_, value] : joystick_map) {
for (const auto& joystick : value) {
if (joystick->IsJoyconRight()) {
if (!joycon_pairs.contains(joystick->GetPort())) {
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index 945cdb42bc..75767448c3 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -196,8 +196,11 @@ Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR
}
Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& index) {
- if (!index.IsImmediate() || index.U32() != 0) {
- throw NotImplementedException("Indirect image indexing");
+ // if (!index.IsImmediate() || index.Type() != Shader::IR::Type::U32 || index.U32() != 0) {
+ // throw NotImplementedException("Indirect image indexing");
+ // }
+ if (index.Type() != Shader::IR::Type::U32) {
+ LOG_WARNING(Shader_SPIRV, "Non-U32 type provided as index: {}", index.Type());
}
if (info.type == TextureType::Buffer) {
const TextureBufferDefinition& def{ctx.texture_buffers.at(info.descriptor_index)};
@@ -215,8 +218,11 @@ Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& ind
}
std::pair Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
- if (!index.IsImmediate() || index.U32() != 0) {
- throw NotImplementedException("Indirect image indexing");
+ // if (!index.IsImmediate() || index.Type() != Shader::IR::Type::U32 || index.U32() != 0) {
+ // throw NotImplementedException("Indirect image indexing");
+ // }
+ if (index.Type() != Shader::IR::Type::U32) {
+ LOG_WARNING(Shader_SPIRV, "Non-U32 type provided as index: {}", index.Type());
}
if (info.type == TextureType::Buffer) {
const ImageBufferDefinition def{ctx.image_buffers.at(info.descriptor_index)};
diff --git a/src/suyu/about_dialog.cpp b/src/suyu/about_dialog.cpp
index 40c99f91b7..d5f05b4a2a 100644
--- a/src/suyu/about_dialog.cpp
+++ b/src/suyu/about_dialog.cpp
@@ -20,7 +20,7 @@ AboutDialog::AboutDialog(QWidget* parent)
ui->setupUi(this);
// Try and request the icon from Qt theme (Linux?)
- const QIcon suyu_logo = QIcon::fromTheme(QStringLiteral("org.suyu_emu.suyu"));
+ const QIcon suyu_logo = QIcon::fromTheme(QStringLiteral("dev.suyu_emu.suyu"));
if (!suyu_logo.isNull()) {
ui->labelLogo->setPixmap(suyu_logo.pixmap(200));
}
diff --git a/src/suyu/aboutdialog.ui b/src/suyu/aboutdialog.ui
index d3ed825310..f0752f3746 100644
--- a/src/suyu/aboutdialog.ui
+++ b/src/suyu/aboutdialog.ui
@@ -127,7 +127,7 @@ p, li { white-space: pre-wrap; }
- <html><head/><body><p><a href="https://suyu.dev"><span style=" text-decoration: underline; color:#039be5;">Website</span></a> | <a href="https://discord.com/invite/2gQRBp44KT"><span style=" text-decoration: underline; color:#039be5;">Discord</span></a> | <a href="https://git.suyu.dev/suyu/suyu"><span style=" text-decoration: underline; color:#039be5;">Source Code</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Contributors</span></a> | <a href="https://git.suyu.dev/suyu/suyu/src/branch/dev/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">License</span></a></p></body></html>
+ <html><head/><body><p><a href="https://suyu.dev"><span style=" text-decoration: underline; color:#039be5;">Website</span></a> | <a href="https://chat.suyu.dev"><span style=" text-decoration: underline; color:#039be5;">Chat</span></a> | <a href="https://git.suyu.dev/suyu/suyu"><span style=" text-decoration: underline; color:#039be5;">Source Code</span></a> | <a href="https://git.suyu.dev/suyu/suyu/activity"><span style=" text-decoration: underline; color:#039be5;">Contributors</span></a> | <a href="https://git.suyu.dev/suyu/suyu/src/branch/dev/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">License</span></a></p></body></html>true
diff --git a/src/suyu/applets/qt_controller.cpp b/src/suyu/applets/qt_controller.cpp
index f27ab835e5..d41d23eceb 100644
--- a/src/suyu/applets/qt_controller.cpp
+++ b/src/suyu/applets/qt_controller.cpp
@@ -384,10 +384,12 @@ bool QtControllerSelectorDialog::CheckIfParametersMet() {
void QtControllerSelectorDialog::SetSupportedControllers() {
const QString theme = [] {
- if (QIcon::themeName().contains(QStringLiteral("dark"))) {
- return QStringLiteral("_dark");
- } else if (QIcon::themeName().contains(QStringLiteral("midnight"))) {
+ if (QIcon::themeName().contains(QStringLiteral("midnight"))) {
return QStringLiteral("_midnight");
+ } else if (GMainWindow::CheckDarkMode() ||
+ QIcon::themeName().contains(QStringLiteral("dark"))) {
+ // Use dark icons if current OS mode is dark, or the theme contains "dark" in its name
+ return QStringLiteral("_dark");
} else {
return QString{};
}
@@ -572,10 +574,12 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index)
}
const QString theme = [] {
- if (QIcon::themeName().contains(QStringLiteral("dark"))) {
- return QStringLiteral("_dark");
- } else if (QIcon::themeName().contains(QStringLiteral("midnight"))) {
+ if (QIcon::themeName().contains(QStringLiteral("midnight"))) {
return QStringLiteral("_midnight");
+ } else if (GMainWindow::CheckDarkMode() ||
+ QIcon::themeName().contains(QStringLiteral("dark"))) {
+ // Use dark icons if current OS mode is dark, or the theme contains "dark" in its name
+ return QStringLiteral("_dark");
} else {
return QString{};
}
diff --git a/src/suyu/applets/qt_software_keyboard.cpp b/src/suyu/applets/qt_software_keyboard.cpp
index a1bcfa717e..3a88656a17 100644
--- a/src/suyu/applets/qt_software_keyboard.cpp
+++ b/src/suyu/applets/qt_software_keyboard.cpp
@@ -372,6 +372,14 @@ QtSoftwareKeyboardDialog::~QtSoftwareKeyboardDialog() {
StopInputThread();
}
+QString QtSoftwareKeyboardDialog::theme() {
+ if (GMainWindow::CheckDarkMode()) {
+ return QStringLiteral("_dark");
+ } else {
+ return QString{};
+ }
+}
+
void QtSoftwareKeyboardDialog::ShowNormalKeyboard(QPoint pos, QSize size) {
if (isVisible()) {
return;
@@ -382,6 +390,7 @@ void QtSoftwareKeyboardDialog::ShowNormalKeyboard(QPoint pos, QSize size) {
SetKeyboardType();
SetPasswordMode();
SetControllerImage();
+ SetButtonImages();
DisableKeyboardButtons();
SetBackspaceOkEnabled();
@@ -449,6 +458,7 @@ void QtSoftwareKeyboardDialog::ShowInlineKeyboard(
SetKeyboardType();
SetControllerImage();
+ SetButtonImages();
DisableKeyboardButtons();
SetBackspaceOkEnabled();
@@ -822,68 +832,146 @@ void QtSoftwareKeyboardDialog::SetControllerImage() {
const auto controller_type =
handheld->IsConnected() ? handheld->GetNpadStyleIndex() : player_1->GetNpadStyleIndex();
- const QString theme = [] {
- if (QIcon::themeName().contains(QStringLiteral("dark")) ||
- QIcon::themeName().contains(QStringLiteral("midnight"))) {
- return QStringLiteral("_dark");
- } else {
- return QString{};
- }
- }();
-
switch (controller_type) {
case Core::HID::NpadStyleIndex::Fullkey:
case Core::HID::NpadStyleIndex::GameCube:
ui->icon_controller->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_pro.png);").arg(theme()));
ui->icon_controller_shift->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_pro.png);").arg(theme()));
ui->icon_controller_num->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_pro.png);").arg(theme()));
break;
case Core::HID::NpadStyleIndex::JoyconDual:
ui->icon_controller->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_dual_joycon%1.png);").arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_dual_joycon.png);").arg(theme()));
ui->icon_controller_shift->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_dual_joycon%1.png);").arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_dual_joycon.png);").arg(theme()));
ui->icon_controller_num->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_dual_joycon%1.png);").arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_dual_joycon.png);").arg(theme()));
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
ui->icon_controller->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_single_joycon_left%1.png);")
- .arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_single_joycon_left.png);")
+ .arg(theme()));
ui->icon_controller_shift->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_single_joycon_left%1.png);")
- .arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_single_joycon_left.png);")
+ .arg(theme()));
ui->icon_controller_num->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_single_joycon_left%1.png);")
- .arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_single_joycon_left.png);")
+ .arg(theme()));
break;
case Core::HID::NpadStyleIndex::JoyconRight:
ui->icon_controller->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_single_joycon_right%1.png);")
- .arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_single_joycon_right.png);")
+ .arg(theme()));
ui->icon_controller_shift->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_single_joycon_right%1.png);")
- .arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_single_joycon_right.png);")
+ .arg(theme()));
ui->icon_controller_num->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_single_joycon_right%1.png);")
- .arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_single_joycon_right.png);")
+ .arg(theme()));
break;
case Core::HID::NpadStyleIndex::Handheld:
ui->icon_controller->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_handheld%1.png);").arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_handheld.png);").arg(theme()));
ui->icon_controller_shift->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_handheld%1.png);").arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_handheld.png);").arg(theme()));
ui->icon_controller_num->setStyleSheet(
- QStringLiteral("image: url(:/overlay/controller_handheld%1.png);").arg(theme));
+ QStringLiteral("image: url(:/overlay%1/controller_handheld.png);").arg(theme()));
break;
default:
break;
}
}
+void QtSoftwareKeyboardDialog::SetButtonImages() {
+ QString button_backspace_stylesheet =
+ QStringLiteral("QPushButton {"
+ " image: url(:/overlay%1/osk_button_B.png);"
+ " image-position: right;"
+ " qproperty-icon: url(:/overlay%1/osk_button_backspace.png); }"
+ "QPushButton:disabled { image: url(:/overlay%1/osk_button_B_disabled.png);}")
+ .arg(theme());
+ ui->button_backspace->setStyleSheet(button_backspace_stylesheet);
+ ui->button_backspace_shift->setStyleSheet(button_backspace_stylesheet);
+ ui->button_backspace_shift->setIconSize(ui->button_backspace->iconSize());
+ ui->button_backspace_num->setStyleSheet(button_backspace_stylesheet);
+
+ QString button_space_stylesheet =
+ QStringLiteral("QPushButton {"
+ " image: url(:/overlay%1/osk_button_Y.png);"
+ " image-position: right;"
+ " qproperty-icon: url(:/overlay%1/osk_button_space.png); }"
+ "QPushButton:disabled { image: url(:/overlay%1/osk_button_Y_disabled.png);}")
+ .arg(theme());
+ ui->button_space->setStyleSheet(button_space_stylesheet);
+ ui->button_space_shift->setStyleSheet(button_space_stylesheet);
+
+ QString button_ok_stylesheet =
+ QStringLiteral(
+ "QPushButton { image: url(:/overlay%1/osk_button_plus.png); }"
+ "QPushButton:disabled { image: url(:/overlay%1/osk_button_plus_disabled.png); }")
+ .arg(theme());
+ ui->button_ok->setStyleSheet(button_ok_stylesheet);
+ ui->button_ok_shift->setStyleSheet(button_ok_stylesheet);
+ ui->button_ok_num->setStyleSheet(button_ok_stylesheet);
+
+ QString button_shift_stylesheet =
+ QStringLiteral("image: url(:/overlay/osk_button_shift_lock_off.png);"
+ "image-position: left;"
+ "qproperty-icon: url(:/overlay%1/osk_button_shift.png);")
+ .arg(theme());
+ ui->button_shift->setStyleSheet(button_shift_stylesheet);
+
+ QString button_shift_shift_stylesheet =
+ QStringLiteral("image: url(:/overlay/osk_button_shift_lock_off.png);"
+ "image-position: left;"
+ "qproperty-icon: url(:/overlay%1/osk_button_shift_on.png);")
+ .arg(theme());
+ ui->button_shift_shift->setStyleSheet(button_shift_shift_stylesheet);
+ ui->button_shift_shift->setIconSize(ui->button_shift->iconSize());
+
+ QString L_stylesheet = QStringLiteral("image: url(:/overlay%1/button_L.png);").arg(theme());
+ ui->button_L->setStyleSheet(L_stylesheet);
+ ui->button_L_shift->setStyleSheet(L_stylesheet);
+ ui->button_L_num->setStyleSheet(L_stylesheet);
+
+ QString R_stylesheet = QStringLiteral("image: url(:/overlay%1/button_R.png);").arg(theme());
+ ui->button_R->setStyleSheet(R_stylesheet);
+ ui->button_R_shift->setStyleSheet(R_stylesheet);
+ ui->button_R_num->setStyleSheet(R_stylesheet);
+
+ QString arrow_left_stylesheet =
+ QStringLiteral("image: url(:/overlay%1/arrow_left.png);").arg(theme());
+ ui->arrow_left->setStyleSheet(arrow_left_stylesheet);
+ ui->arrow_left_shift->setStyleSheet(arrow_left_stylesheet);
+ ui->arrow_left_num->setStyleSheet(arrow_left_stylesheet);
+
+ QString arrow_right_stylesheet =
+ QStringLiteral("image: url(:/overlay%1/arrow_right.png);").arg(theme());
+ ui->arrow_right->setStyleSheet(arrow_right_stylesheet);
+ ui->arrow_right_shift->setStyleSheet(arrow_right_stylesheet);
+ ui->arrow_right_num->setStyleSheet(arrow_right_stylesheet);
+
+ QString button_press_stick_stylesheet =
+ QStringLiteral("image: url(:/overlay%1/button_press_stick.png);").arg(theme());
+ ui->button_press_stick->setStyleSheet(button_press_stick_stylesheet);
+ ui->button_press_stick_shift->setStyleSheet(button_press_stick_stylesheet);
+
+ QString button_X_stylesheet =
+ QStringLiteral("image: url(:/overlay%1/button_X.png);").arg(theme());
+ ui->button_X->setStyleSheet(button_X_stylesheet);
+ ui->button_X_shift->setStyleSheet(button_X_stylesheet);
+ ui->button_X_num->setStyleSheet(button_X_stylesheet);
+
+ QString button_A_stylesheet =
+ QStringLiteral("image: url(:/overlay%1/button_A.png);").arg(theme());
+ ui->button_A->setStyleSheet(button_A_stylesheet);
+ ui->button_A_shift->setStyleSheet(button_A_stylesheet);
+ ui->button_A_num->setStyleSheet(button_A_stylesheet);
+}
+
void QtSoftwareKeyboardDialog::DisableKeyboardButtons() {
switch (bottom_osk_index) {
case BottomOSKIndex::LowerCase:
@@ -1050,10 +1138,8 @@ void QtSoftwareKeyboardDialog::ChangeBottomOSKIndex() {
ui->bottomOSK->setCurrentIndex(static_cast(bottom_osk_index));
ui->button_shift_shift->setStyleSheet(
- QStringLiteral("image: url(:/overlay/osk_button_shift_lock_off.png);"
- "\nimage-position: left;"));
+ QStringLiteral("image: url(:/overlay/osk_button_shift_lock_off.png);"));
- ui->button_shift_shift->setIconSize(ui->button_shift->iconSize());
ui->button_backspace_shift->setIconSize(ui->button_backspace->iconSize());
break;
case BottomOSKIndex::UpperCase:
@@ -1064,9 +1150,6 @@ void QtSoftwareKeyboardDialog::ChangeBottomOSKIndex() {
QStringLiteral("image: url(:/overlay/osk_button_shift_lock_off.png);"
"\nimage-position: left;"));
- ui->button_shift_shift->setIconSize(ui->button_shift->iconSize());
- ui->button_backspace_shift->setIconSize(ui->button_backspace->iconSize());
-
ui->label_shift_shift->setText(QStringLiteral("Caps Lock"));
bottom_osk_index = BottomOSKIndex::LowerCase;
@@ -1078,9 +1161,6 @@ void QtSoftwareKeyboardDialog::ChangeBottomOSKIndex() {
QStringLiteral("image: url(:/overlay/osk_button_shift_lock_on.png);"
"\nimage-position: left;"));
- ui->button_shift_shift->setIconSize(ui->button_shift->iconSize());
- ui->button_backspace_shift->setIconSize(ui->button_backspace->iconSize());
-
ui->label_shift_shift->setText(QStringLiteral("Caps Lock Off"));
}
break;
diff --git a/src/suyu/applets/qt_software_keyboard.h b/src/suyu/applets/qt_software_keyboard.h
index 7e2fdf09ea..fda6ac623d 100644
--- a/src/suyu/applets/qt_software_keyboard.h
+++ b/src/suyu/applets/qt_software_keyboard.h
@@ -80,6 +80,12 @@ private:
NumberPad,
};
+ /**
+ * Get the current theme suffix
+ * @return an empty string for light theme, "_dark" for dark theme
+ */
+ QString theme();
+
/**
* Moves and resizes the window to a specified position and size.
*
@@ -109,6 +115,9 @@ private:
/// Sets the controller image at the bottom left of the software keyboard.
void SetControllerImage();
+ /// Sets the controller image at the bottom left of the software keyboard.
+ void SetButtonImages();
+
/// Disables buttons based on initialize_parameters.
void DisableKeyboardButtons();
diff --git a/src/suyu/configuration/configure_applets.cpp b/src/suyu/configuration/configure_applets.cpp
index a607fa3af8..d5e3520718 100644
--- a/src/suyu/configuration/configure_applets.cpp
+++ b/src/suyu/configuration/configure_applets.cpp
@@ -69,7 +69,7 @@ void ConfigureApplets::Setup(const ConfigurationShared::Builder& builder) {
applets_hold.emplace(setting->Id(), widget);
}
- for (const auto& [label, widget] : applets_hold) {
+ for (const auto& [_, widget] : applets_hold) {
library_applets_layout.addWidget(widget);
}
}
diff --git a/src/suyu/configuration/configure_audio.cpp b/src/suyu/configuration/configure_audio.cpp
index 2341131585..5ecd79ae31 100644
--- a/src/suyu/configuration/configure_audio.cpp
+++ b/src/suyu/configuration/configure_audio.cpp
@@ -164,7 +164,7 @@ void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) {
}
}
- for (const auto& [id, widget] : hold) {
+ for (const auto& [_, widget] : hold) {
layout.addWidget(widget);
}
}
diff --git a/src/suyu/configuration/configure_cpu.cpp b/src/suyu/configuration/configure_cpu.cpp
index ce266642ff..0a26f531fb 100644
--- a/src/suyu/configuration/configure_cpu.cpp
+++ b/src/suyu/configuration/configure_cpu.cpp
@@ -79,7 +79,7 @@ void ConfigureCpu::Setup(const ConfigurationShared::Builder& builder) {
}
}
- for (const auto& [label, widget] : unsafe_hold) {
+ for (const auto& [_, widget] : unsafe_hold) {
unsafe_layout->addWidget(widget);
}
diff --git a/src/suyu/configuration/configure_general.cpp b/src/suyu/configuration/configure_general.cpp
index 689d9be2b8..f8007574d4 100644
--- a/src/suyu/configuration/configure_general.cpp
+++ b/src/suyu/configuration/configure_general.cpp
@@ -81,10 +81,10 @@ void ConfigureGeneral::Setup(const ConfigurationShared::Builder& builder) {
}
}
- for (const auto& [id, widget] : general_hold) {
+ for (const auto& [_, widget] : general_hold) {
general_layout.addWidget(widget);
}
- for (const auto& [id, widget] : linux_hold) {
+ for (const auto& [_, widget] : linux_hold) {
linux_layout.addWidget(widget);
}
}
diff --git a/src/suyu/configuration/configure_graphics.cpp b/src/suyu/configuration/configure_graphics.cpp
index 0810009125..3a5cf3b042 100644
--- a/src/suyu/configuration/configure_graphics.cpp
+++ b/src/suyu/configuration/configure_graphics.cpp
@@ -358,7 +358,7 @@ void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) {
}
}
- for (const auto& [id, widget] : hold_graphics) {
+ for (const auto& [_, widget] : hold_graphics) {
graphics_layout.addWidget(widget);
}
diff --git a/src/suyu/configuration/configure_graphics_advanced.cpp b/src/suyu/configuration/configure_graphics_advanced.cpp
index 8cdae0a65d..28b3f7c3c8 100644
--- a/src/suyu/configuration/configure_graphics_advanced.cpp
+++ b/src/suyu/configuration/configure_graphics_advanced.cpp
@@ -53,7 +53,7 @@ void ConfigureGraphicsAdvanced::Setup(const ConfigurationShared::Builder& builde
checkbox_enable_compute_pipelines = widget;
}
}
- for (const auto& [id, widget] : hold) {
+ for (const auto& [_, widget] : hold) {
layout.addWidget(widget);
}
}
diff --git a/src/suyu/configuration/configure_input_player.ui b/src/suyu/configuration/configure_input_player.ui
index 5beb1b6bfc..761015cd94 100644
--- a/src/suyu/configuration/configure_input_player.ui
+++ b/src/suyu/configuration/configure_input_player.ui
@@ -1430,12 +1430,12 @@
-
-
- 0
- 0
-
-
+
+
+ 0
+ 0
+
+ ZL
@@ -1481,20 +1481,20 @@
-
-
-
- 70
- 15
-
-
-
- 100
-
-
- Qt::Horizontal
-
-
+
+
+
+ 70
+ 40
+
+
+
+ 100
+
+
+ Qt::Horizontal
+
+
@@ -1927,22 +1927,22 @@
-
-
-
-
- 70
- 15
-
-
-
- 100
-
-
- Qt::Horizontal
-
-
-
+
+
+
+
+ 70
+ 40
+
+
+
+ 100
+
+
+ Qt::Horizontal
+
+
+
diff --git a/src/suyu/configuration/configure_linux_tab.cpp b/src/suyu/configuration/configure_linux_tab.cpp
index 1db9893b71..488db7b932 100644
--- a/src/suyu/configuration/configure_linux_tab.cpp
+++ b/src/suyu/configuration/configure_linux_tab.cpp
@@ -50,7 +50,7 @@ void ConfigureLinuxTab::Setup(const ConfigurationShared::Builder& builder) {
linux_hold.insert({setting->Id(), widget});
}
- for (const auto& [id, widget] : linux_hold) {
+ for (const auto& [_, widget] : linux_hold) {
linux_layout.addWidget(widget);
}
}
diff --git a/src/suyu/configuration/configure_system.cpp b/src/suyu/configuration/configure_system.cpp
index 3204303e98..e0312eb6fc 100644
--- a/src/suyu/configuration/configure_system.cpp
+++ b/src/suyu/configuration/configure_system.cpp
@@ -174,10 +174,10 @@ void ConfigureSystem::Setup(const ConfigurationShared::Builder& builder) {
widget->deleteLater();
}
}
- for (const auto& [label, widget] : core_hold) {
+ for (const auto& [_, widget] : core_hold) {
core_layout.addWidget(widget);
}
- for (const auto& [id, widget] : system_hold) {
+ for (const auto& [_, widget] : system_hold) {
system_layout.addWidget(widget);
}
}
diff --git a/src/suyu/configuration/configure_ui.cpp b/src/suyu/configuration/configure_ui.cpp
index a3648c5b1c..74add9bbd3 100644
--- a/src/suyu/configuration/configure_ui.cpp
+++ b/src/suyu/configuration/configure_ui.cpp
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include "common/common_types.h"
#include "common/fs/path_util.h"
@@ -29,6 +30,8 @@
#include "suyu/uisettings.h"
#include "ui_configure_ui.h"
+using Settings::DarkModeState;
+
namespace {
constexpr std::array default_game_icon_sizes{
std::make_pair(0, QT_TRANSLATE_NOOP("ConfigureUI", "None")),
@@ -80,7 +83,7 @@ static void PopulateResolutionComboBox(QComboBox* screenshot_height, QWidget* pa
const auto& enumeration =
Settings::EnumMetadata::Canonicalizations();
std::set resolutions{};
- for (const auto& [name, value] : enumeration) {
+ for (const auto& [_, value] : enumeration) {
const float up_factor = GetUpFactor(value);
u32 height_undocked = Layout::ScreenUndocked::Height * up_factor;
u32 height_docked = Layout::ScreenDocked::Height * up_factor;
@@ -106,11 +109,31 @@ ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent)
InitializeLanguageComboBox();
- for (const auto& theme : UISettings::themes) {
+ for (const auto& theme : UISettings::included_themes) {
ui->theme_combobox->addItem(QString::fromUtf8(theme.first),
QString::fromUtf8(theme.second));
}
+ // Add custom styles stored in yuzu directory
+ const QDir themes_local_dir(
+ QString::fromStdString(Common::FS::GetSuyuPathString(Common::FS::SuyuPath::ThemesDir)));
+ for (const QString& theme_dir :
+ themes_local_dir.entryList(QDir::NoDot | QDir::NoDotDot | QDir::Dirs)) {
+ // folders ending with "_dark" are reserved for dark variant icons of other styles
+ if (theme_dir.endsWith(QStringLiteral("_dark"))) {
+ continue;
+ }
+ // Split at _ and capitalize words in name
+ QStringList cased_name;
+ for (QString word : theme_dir.split(QChar::fromLatin1('_'))) {
+ cased_name.append(word.at(0).toUpper() + word.mid(1));
+ }
+ QString theme_name = cased_name.join(QChar::fromLatin1(' '));
+ theme_name += QStringLiteral(" (%1)").arg(tr("Custom"));
+
+ ui->theme_combobox->addItem(theme_name, themes_local_dir.filePath(theme_dir));
+ }
+
InitializeIconSizeComboBox();
InitializeRowComboBoxes();
@@ -133,6 +156,9 @@ ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent)
&ConfigureUi::RequestGameListUpdate);
connect(ui->row_2_text_combobox, QOverload::of(&QComboBox::currentIndexChanged), this,
&ConfigureUi::RequestGameListUpdate);
+ // Update available dark mode options depending on selected style
+ connect(ui->theme_combobox, QOverload::of(&QComboBox::currentIndexChanged), this,
+ &ConfigureUi::UpdateDarkModeOptions);
// Update text ComboBoxes after user interaction.
connect(ui->row_1_text_combobox, QOverload::of(&QComboBox::activated),
@@ -164,7 +190,9 @@ ConfigureUi::~ConfigureUi() = default;
void ConfigureUi::ApplyConfiguration() {
UISettings::values.theme =
- ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString().toStdString();
+ ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString();
+ UISettings::values.dark_mode_state =
+ static_cast(ui->dark_mode_combobox->currentData().toUInt());
UISettings::values.show_add_ons = ui->show_add_ons->isChecked();
UISettings::values.show_compat = ui->show_compat->isChecked();
UISettings::values.show_size = ui->show_size->isChecked();
@@ -186,13 +214,71 @@ void ConfigureUi::ApplyConfiguration() {
system.ApplySettings();
}
+void ConfigureUi::UpdateDarkModeOptions() {
+ ui->dark_mode_combobox->clear();
+
+ QString selected_theme = ui->theme_combobox->currentData().toString();
+
+ /* Dark mode option are added according to the modes the current style supports */
+ bool has_common_style = QFile::exists(selected_theme + QStringLiteral("/style.qss"));
+ bool has_light_style = QFile::exists(selected_theme + QStringLiteral("/light.qss"));
+ bool has_dark_style = QFile::exists(selected_theme + QStringLiteral("/dark.qss"));
+#ifdef _WIN32
+ // Indicate which option needs a restart to be applied, depending on current environment
+ // variable
+ QByteArray current_qt_qpa = qgetenv("QT_QPA_PLATFORM");
+ if (current_qt_qpa.contains("darkmode=2")) {
+ if (has_common_style || (has_dark_style && has_light_style)) {
+ ui->dark_mode_combobox->addItem(tr("Auto"), QVariant::fromValue(DarkModeState::Auto));
+ }
+ if (has_common_style || has_dark_style) {
+ ui->dark_mode_combobox->addItem(tr("Always On") +
+ QStringLiteral(" (%1)").arg(tr("Needs restart")),
+ QVariant::fromValue(DarkModeState::On));
+ }
+ if (has_common_style || has_light_style) {
+ ui->dark_mode_combobox->addItem(tr("Always Off") +
+ QStringLiteral(" (%1)").arg(tr("Needs restart")),
+ QVariant::fromValue(DarkModeState::Off));
+ }
+ } else {
+ if (has_common_style || (has_dark_style && has_light_style)) {
+ ui->dark_mode_combobox->addItem(tr("Auto") +
+ QStringLiteral(" (%1)").arg(tr("Needs restart")),
+ QVariant::fromValue(DarkModeState::Auto));
+ }
+ if (has_common_style || has_dark_style) {
+ ui->dark_mode_combobox->addItem(tr("Always On"),
+ QVariant::fromValue(DarkModeState::On));
+ }
+ if (has_common_style || has_light_style) {
+ ui->dark_mode_combobox->addItem(tr("Always Off"),
+ QVariant::fromValue(DarkModeState::Off));
+ }
+ }
+#else
+ if (has_common_style || (has_dark_style && has_light_style)) {
+ ui->dark_mode_combobox->addItem(tr("Auto"), QVariant::fromValue(DarkModeState::Auto));
+ }
+ if (has_common_style || has_dark_style) {
+ ui->dark_mode_combobox->addItem(tr("Always On"), QVariant::fromValue(DarkModeState::On));
+ }
+ if (has_common_style || has_light_style) {
+ ui->dark_mode_combobox->addItem(tr("Always Off"), QVariant::fromValue(DarkModeState::Off));
+ }
+#endif
+}
+
void ConfigureUi::RequestGameListUpdate() {
UISettings::values.is_game_list_reload_pending.exchange(true);
}
void ConfigureUi::SetConfiguration() {
- ui->theme_combobox->setCurrentIndex(
- ui->theme_combobox->findData(QString::fromStdString(UISettings::values.theme)));
+ ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
+ // Dark mode options are populated after the theme is selected, to get the current configuration
+ UpdateDarkModeOptions();
+ ui->dark_mode_combobox->setCurrentIndex(
+ ui->dark_mode_combobox->findData(QVariant::fromValue(UISettings::values.dark_mode_state)));
ui->language_combobox->setCurrentIndex(ui->language_combobox->findData(
QString::fromStdString(UISettings::values.language.GetValue())));
ui->show_add_ons->setChecked(UISettings::values.show_add_ons.GetValue());
diff --git a/src/suyu/configuration/configure_ui.h b/src/suyu/configuration/configure_ui.h
index 2a2563a131..a52ad7cc74 100644
--- a/src/suyu/configuration/configure_ui.h
+++ b/src/suyu/configuration/configure_ui.h
@@ -34,6 +34,7 @@ signals:
void LanguageChanged(const QString& locale);
private:
+ void UpdateDarkModeOptions();
void RequestGameListUpdate();
void SetConfiguration();
diff --git a/src/suyu/configuration/configure_ui.ui b/src/suyu/configuration/configure_ui.ui
index b8e6483814..cdd46005fd 100644
--- a/src/suyu/configuration/configure_ui.ui
+++ b/src/suyu/configuration/configure_ui.ui
@@ -63,6 +63,20 @@
+
+
+
+
+
+ Dark Mode:
+
+
+
+
+
+
+
+
diff --git a/src/suyu/configuration/input_profiles.cpp b/src/suyu/configuration/input_profiles.cpp
index a2ca806899..5add5f057b 100644
--- a/src/suyu/configuration/input_profiles.cpp
+++ b/src/suyu/configuration/input_profiles.cpp
@@ -61,7 +61,7 @@ std::vector InputProfiles::GetInputProfileNames() {
auto it = map_profiles.cbegin();
while (it != map_profiles.cend()) {
- const auto& [profile_name, config] = *it;
+ const auto& [profile_name, _] = *it;
if (!ProfileExistsInFilesystem(profile_name)) {
it = map_profiles.erase(it);
continue;
diff --git a/src/suyu/configuration/qt_config.cpp b/src/suyu/configuration/qt_config.cpp
index 37951b9c84..2ed14ee2be 100644
--- a/src/suyu/configuration/qt_config.cpp
+++ b/src/suyu/configuration/qt_config.cpp
@@ -260,9 +260,10 @@ void QtConfig::ReadShortcutValues() {
void QtConfig::ReadUIValues() {
BeginGroup(Settings::TranslateCategory(Settings::Category::Ui));
- UISettings::values.theme = ReadStringSetting(
- std::string("theme"),
- std::string(UISettings::themes[static_cast(UISettings::default_theme)].second));
+ UISettings::values.theme =
+ QString::fromStdString(ReadStringSetting("theme", std::string(UISettings::default_theme)));
+ UISettings::values.dark_mode_state = static_cast(
+ ReadIntegerSetting("dark_mode_state", static_cast(DarkModeState::Auto)));
ReadUIGamelistValues();
ReadUILayoutValues();
@@ -468,10 +469,10 @@ void QtConfig::SaveUIValues() {
WriteCategory(Settings::Category::Ui);
WriteCategory(Settings::Category::UiGeneral);
- WriteStringSetting(
- std::string("theme"), UISettings::values.theme,
- std::make_optional(std::string(
- UISettings::themes[static_cast(UISettings::default_theme)].second)));
+ WriteStringSetting("theme", UISettings::values.theme.toStdString(),
+ std::make_optional(std::string(UISettings::default_theme)));
+ WriteIntegerSetting("dark_mode_state", static_cast(UISettings::values.dark_mode_state),
+ std::make_optional(static_cast(DarkModeState::Auto)));
SaveUIGamelistValues();
SaveUILayoutValues();
diff --git a/src/suyu/configuration/shared_widget.cpp b/src/suyu/configuration/shared_widget.cpp
index 76a6b417cd..8a552d68c9 100644
--- a/src/suyu/configuration/shared_widget.cpp
+++ b/src/suyu/configuration/shared_widget.cpp
@@ -135,7 +135,7 @@ QWidget* Widget::CreateCombobox(std::function& serializer,
const ComboboxTranslations* enumeration{nullptr};
if (combobox_enumerations.contains(type)) {
enumeration = &combobox_enumerations.at(type);
- for (const auto& [id, name] : *enumeration) {
+ for (const auto& [_, name] : *enumeration) {
combobox->addItem(name);
}
} else {
@@ -223,7 +223,7 @@ QWidget* Widget::CreateRadioGroup(std::function& serializer,
};
if (!Settings::IsConfiguringGlobal()) {
- for (const auto& [id, button] : radio_buttons) {
+ for (const auto& [_, button] : radio_buttons) {
QObject::connect(button, &QAbstractButton::clicked, [touch]() { touch(); });
}
}
diff --git a/src/suyu/debugger/wait_tree.cpp b/src/suyu/debugger/wait_tree.cpp
index b339862ba7..b5ee4bcfdf 100644
--- a/src/suyu/debugger/wait_tree.cpp
+++ b/src/suyu/debugger/wait_tree.cpp
@@ -35,9 +35,8 @@ constexpr std::array, 10> WaitTreeColors{{
}};
bool IsDarkTheme() {
- const auto& theme = UISettings::values.theme;
- return theme == std::string("qdarkstyle") || theme == std::string("qdarkstyle_midnight_blue") ||
- theme == std::string("colorful_dark") || theme == std::string("colorful_midnight_blue");
+ return UISettings::values.theme.contains(QStringLiteral("dark")) ||
+ UISettings::values.theme.contains(QStringLiteral("midnight"));
}
} // namespace
diff --git a/src/suyu/game_list.cpp b/src/suyu/game_list.cpp
index bda0d489bf..132ff30b0c 100644
--- a/src/suyu/game_list.cpp
+++ b/src/suyu/game_list.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Modified by palfaiate on <2024/03/07>
+// Reverted palfaiate's changes on <2024/03/25> -Nine-Ball
#include
#include
@@ -580,6 +581,9 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
remove_menu->addSeparator();
QAction* remove_shader_cache = remove_menu->addAction(tr("Remove All Pipeline Caches"));
QAction* remove_all_content = remove_menu->addAction(tr("Remove All Installed Contents"));
+ QMenu* dump_romfs_menu = context_menu.addMenu(tr("Dump RomFS"));
+ QAction* dump_romfs = dump_romfs_menu->addAction(tr("Dump RomFS"));
+ QAction* dump_romfs_sdmc = dump_romfs_menu->addAction(tr("Dump RomFS to SDMC"));
QAction* verify_integrity = context_menu.addAction(tr("Verify Integrity"));
QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard"));
QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry"));
@@ -647,6 +651,12 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
connect(remove_cache_storage, &QAction::triggered, [this, program_id, path] {
emit RemoveFileRequested(program_id, GameListRemoveTarget::CacheStorage, path);
});
+ connect(dump_romfs, &QAction::triggered, [this, program_id, path]() {
+ emit DumpRomFSRequested(program_id, path, DumpRomFSTarget::Normal);
+ });
+ connect(dump_romfs_sdmc, &QAction::triggered, [this, program_id, path]() {
+ emit DumpRomFSRequested(program_id, path, DumpRomFSTarget::SDMC);
+ });
connect(verify_integrity, &QAction::triggered,
[this, path]() { emit VerifyIntegrityRequested(path); });
connect(copy_tid, &QAction::triggered,
diff --git a/src/suyu/game_list.h b/src/suyu/game_list.h
index 7568e1b6e0..4adb6403ef 100644
--- a/src/suyu/game_list.h
+++ b/src/suyu/game_list.h
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Modified by palfaiate on <2024/03/07>
+// Reverted palfaiate's changes on <2024/03/25> -Nine-Ball
#pragma once
@@ -52,6 +53,11 @@ enum class GameListRemoveTarget {
CacheStorage,
};
+enum class DumpRomFSTarget {
+ Normal,
+ SDMC,
+};
+
enum class GameListShortcutTarget {
Desktop,
Applications,
@@ -113,6 +119,7 @@ signals:
void RemoveFileRequested(u64 program_id, GameListRemoveTarget target,
const std::string& game_path);
void RemovePlayTimeRequested(u64 program_id);
+ void DumpRomFSRequested(u64 program_id, const std::string& game_path, DumpRomFSTarget target);
void VerifyIntegrityRequested(const std::string& game_path);
void CopyTIDRequested(u64 program_id);
void CreateShortcut(u64 program_id, const std::string& game_path,
diff --git a/src/suyu/main.cpp b/src/suyu/main.cpp
index a23ba9e17d..43511e7b0d 100644
--- a/src/suyu/main.cpp
+++ b/src/suyu/main.cpp
@@ -1,8 +1,6 @@
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-// Modified by palfaiate on <2024/03/07>
-
#include
#include
#include
@@ -10,6 +8,7 @@
#include
#include
#include
+
#include "core/hle/service/am/applet_manager.h"
#include "core/loader/nca.h"
#include "core/loader/nro.h"
@@ -20,6 +19,9 @@
#endif
#ifdef __unix__
#include
+#include
+#include
+#include
#include
#include "common/linux/gamemode.h"
#endif
@@ -55,6 +57,18 @@
#include "suyu/multiplayer/state.h"
#include "suyu/util/controller_navigation.h"
+// These are wrappers to avoid the calls to CreateDirectory and CreateFile because of the Windows
+static FileSys::VirtualDir VfsFilesystemCreateDirectoryWrapper(
+ const FileSys::VirtualFilesystem& vfs, const std::string& path, FileSys::OpenMode mode) {
+ return vfs->CreateDirectory(path, mode);
+}
+
+// Overloaded function, also removed by palafiate
+static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::VirtualDir& dir,
+ const std::string& path) {
+ return dir->CreateFile(path);
+}
+
#include
#include
@@ -271,18 +285,6 @@ static void OverrideWindowsFont() {
}
#endif
-bool GMainWindow::CheckDarkMode() {
-#ifdef __unix__
- const QPalette test_palette(qApp->palette());
- const QColor text_color = test_palette.color(QPalette::Active, QPalette::Text);
- const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window);
- return (text_color.value() > window_color.value());
-#else
- // TODO: Windows
- return false;
-#endif // __unix__
-}
-
GMainWindow::GMainWindow(std::unique_ptr config_, bool has_broken_vulkan)
: ui{std::make_unique()}, system{std::make_unique()},
input_subsystem{std::make_shared()}, config{std::move(config_)},
@@ -303,15 +305,12 @@ GMainWindow::GMainWindow(std::unique_ptr config_, bool has_broken_vulk
ui->setupUi(this);
statusBar()->hide();
- // Check dark mode before a theme is loaded
- os_dark_mode = CheckDarkMode();
startup_icon_theme = QIcon::themeName();
- // fallback can only be set once, colorful theme icons are okay on both light/dark
- QIcon::setFallbackThemeName(QStringLiteral("colorful"));
+ // fallback can only be set once, default theme icons are okay on both light/dark
+ QIcon::setFallbackThemeName(QStringLiteral("default"));
QIcon::setFallbackSearchPaths(QStringList(QStringLiteral(":/icons")));
default_theme_paths = QIcon::themeSearchPaths();
- UpdateUITheme();
SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue());
discord_rpc->Update();
@@ -329,6 +328,7 @@ GMainWindow::GMainWindow(std::unique_ptr config_, bool has_broken_vulk
SetDefaultUIGeometry();
RestoreUIState();
+ UpdateUITheme();
ConnectMenuEvents();
ConnectWidgetEvents();
@@ -449,7 +449,10 @@ GMainWindow::GMainWindow(std::unique_ptr config_, bool has_broken_vulk
SDL_EnableScreenSaver();
#endif
+#ifdef __unix__
SetupPrepareForSleep();
+ ListenColorSchemeChange();
+#endif
QStringList args = QApplication::arguments();
@@ -1465,6 +1468,7 @@ void GMainWindow::ConnectWidgetEvents() {
connect(game_list, &GameList::RemoveFileRequested, this, &GMainWindow::OnGameListRemoveFile);
connect(game_list, &GameList::RemovePlayTimeRequested, this,
&GMainWindow::OnGameListRemovePlayTimeData);
+ connect(game_list, &GameList::DumpRomFSRequested, this, &GMainWindow::OnGameListDumpRomFS);
connect(game_list, &GameList::VerifyIntegrityRequested, this,
&GMainWindow::OnGameListVerifyIntegrity);
connect(game_list, &GameList::CopyTIDRequested, this, &GMainWindow::OnGameListCopyTID);
@@ -1647,8 +1651,8 @@ void GMainWindow::OnDisplayTitleBars(bool show) {
}
}
-void GMainWindow::SetupPrepareForSleep() {
#ifdef __unix__
+void GMainWindow::SetupPrepareForSleep() {
auto bus = QDBusConnection::systemBus();
if (bus.isConnected()) {
const bool success = bus.connect(
@@ -1662,8 +1666,8 @@ void GMainWindow::SetupPrepareForSleep() {
} else {
LOG_WARNING(Frontend, "QDBusConnection system bus is not connected");
}
-#endif // __unix__
}
+#endif // __unix__
void GMainWindow::OnPrepareForSleep(bool prepare_sleep) {
if (emu_thread == nullptr) {
@@ -1844,7 +1848,7 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa
const auto description =
tr("%1 Please follow the "
"suyu quickstart guide to redump your files. You can refer "
- "to the suyu wiki or the suyu Discord for help.",
+ "to the suyu wiki or the suyu Chat for help.",
"%1 signifies an error string.")
.arg(QString::fromStdString(
GetResultStatusString(static_cast(error_id))));
@@ -2369,6 +2373,68 @@ void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path));
}
+static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog& dialog,
+ const FileSys::VirtualDir& src, const FileSys::VirtualDir& dest,
+ bool full) {
+ if (src == nullptr || dest == nullptr || !src->IsReadable() || !dest->IsWritable())
+ return false;
+ if (dialog.wasCanceled())
+ return false;
+
+ std::vector buffer(CopyBufferSize);
+ auto last_timestamp = std::chrono::steady_clock::now();
+
+ const auto QtRawCopy = [&](const FileSys::VirtualFile& src_file,
+ const FileSys::VirtualFile& dest_file) {
+ if (src_file == nullptr || dest_file == nullptr) {
+ return false;
+ }
+ if (!dest_file->Resize(src_file->GetSize())) {
+ return false;
+ }
+
+ for (std::size_t i = 0; i < src_file->GetSize(); i += buffer.size()) {
+ if (dialog.wasCanceled()) {
+ dest_file->Resize(0);
+ return false;
+ }
+
+ using namespace std::literals::chrono_literals;
+ const auto new_timestamp = std::chrono::steady_clock::now();
+
+ if ((new_timestamp - last_timestamp) > 33ms) {
+ last_timestamp = new_timestamp;
+ dialog.setValue(
+ static_cast(std::min(read_size, total_size) * 100 / total_size));
+ QCoreApplication::processEvents();
+ }
+
+ const auto read = src_file->Read(buffer.data(), buffer.size(), i);
+ dest_file->Write(buffer.data(), read, i);
+
+ read_size += read;
+ }
+
+ return true;
+ };
+
+ if (full) {
+ for (const auto& file : src->GetFiles()) {
+ const auto out = VfsDirectoryCreateFileWrapper(dest, file->GetName());
+ if (!QtRawCopy(file, out))
+ return false;
+ }
+ }
+
+ for (const auto& dir : src->GetSubdirectories()) {
+ const auto out = dest->CreateSubdirectory(dir->GetName());
+ if (!RomFSRawCopy(total_size, read_size, dialog, dir, out, full))
+ return false;
+ }
+
+ return true;
+}
+
QString GMainWindow::GetGameListErrorRemoving(InstalledEntryType type) const {
switch (type) {
case InstalledEntryType::Game:
@@ -2610,6 +2676,121 @@ void GMainWindow::RemoveCacheStorage(u64 program_id) {
Common::FS::RemoveDirRecursively(path);
}
+void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_path,
+ DumpRomFSTarget target) {
+ const auto failed = [this] {
+ QMessageBox::warning(this, tr("RomFS Extraction Failed!"),
+ tr("There was an error copying the RomFS files or the user "
+ "cancelled the operation."));
+ };
+
+ const auto loader =
+ Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::OpenMode::Read));
+ if (loader == nullptr) {
+ failed();
+ return;
+ }
+
+ FileSys::VirtualFile packed_update_raw{};
+ loader->ReadUpdateRaw(packed_update_raw);
+
+ const auto& installed = system->GetContentProvider();
+
+ u64 title_id{};
+ u8 raw_type{};
+ if (!SelectRomFSDumpTarget(installed, program_id, &title_id, &raw_type)) {
+ failed();
+ return;
+ }
+
+ const auto type = static_cast(raw_type);
+ const auto base_nca = installed.GetEntry(title_id, type);
+ if (!base_nca) {
+ failed();
+ return;
+ }
+
+ const FileSys::NCA update_nca{packed_update_raw, nullptr};
+ if (type != FileSys::ContentRecordType::Program ||
+ update_nca.GetStatus() != Loader::ResultStatus::ErrorMissingBKTRBaseRomFS ||
+ update_nca.GetTitleId() != FileSys::GetUpdateTitleID(title_id)) {
+ packed_update_raw = {};
+ }
+
+ const auto base_romfs = base_nca->GetRomFS();
+ const auto dump_dir =
+ target == DumpRomFSTarget::Normal
+ ? Common::FS::GetSuyuPath(Common::FS::SuyuPath::DumpDir)
+ : Common::FS::GetSuyuPath(Common::FS::SuyuPath::SDMCDir) / "atmosphere" / "contents";
+ const auto romfs_dir = fmt::format("{:016X}/romfs", title_id);
+
+ const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir);
+
+ const FileSys::PatchManager pm{title_id, system->GetFileSystemController(), installed};
+ auto romfs = pm.PatchRomFS(base_nca.get(), base_romfs, type, packed_update_raw, false);
+
+ const auto out = VfsFilesystemCreateDirectoryWrapper(vfs, path, FileSys::OpenMode::ReadWrite);
+
+ if (out == nullptr) {
+ failed();
+ vfs->DeleteDirectory(path);
+ return;
+ }
+
+ bool ok = false;
+ const QStringList selections{tr("Full"), tr("Skeleton")};
+ const auto res = QInputDialog::getItem(
+ this, tr("Select RomFS Dump Mode"),
+ tr("Please select the how you would like the RomFS dumped. Full will copy all of the "
+ "files into the new directory while skeleton will only create the directory "
+ "structure."),
+ selections, 0, false, &ok);
+ if (!ok) {
+ failed();
+ vfs->DeleteDirectory(path);
+ return;
+ }
+
+ const auto extracted = FileSys::ExtractRomFS(romfs);
+ if (extracted == nullptr) {
+ failed();
+ return;
+ }
+
+ const auto full = res == selections.constFirst();
+
+ // The expected required space is the size of the RomFS + 1 GiB
+ const auto minimum_free_space = romfs->GetSize() + 0x40000000;
+
+ if (full && Common::FS::GetFreeSpaceSize(path) < minimum_free_space) {
+ QMessageBox::warning(this, tr("RomFS Extraction Failed!"),
+ tr("There is not enough free space at %1 to extract the RomFS. Please "
+ "free up space or select a different dump directory at "
+ "Emulation > Configure > System > Filesystem > Dump Root")
+ .arg(QString::fromStdString(path)));
+ return;
+ }
+
+ QProgressDialog progress(tr("Extracting RomFS..."), tr("Cancel"), 0, 100, this);
+ progress.setWindowModality(Qt::WindowModal);
+ progress.setMinimumDuration(100);
+ progress.setAutoClose(false);
+ progress.setAutoReset(false);
+
+ size_t read_size = 0;
+
+ if (RomFSRawCopy(romfs->GetSize(), read_size, progress, extracted, out, full)) {
+ progress.close();
+ QMessageBox::information(this, tr("RomFS Extraction Succeeded!"),
+ tr("The operation completed successfully."));
+ QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(path)));
+ } else {
+ progress.close();
+ failed();
+ vfs->DeleteDirectory(path);
+ }
+}
+
void GMainWindow::OnGameListVerifyIntegrity(const std::string& game_path) {
const auto NotImplemented = [this] {
QMessageBox::warning(this, tr("Integrity verification couldn't be performed!"),
@@ -3542,7 +3723,8 @@ void GMainWindow::ResetWindowSize1080() {
}
void GMainWindow::OnConfigure() {
- const auto old_theme = UISettings::values.theme;
+ const QString old_theme = UISettings::values.theme;
+ DarkModeState old_dark_mode_state = UISettings::values.dark_mode_state;
const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue();
const auto old_language_index = Settings::values.language_index.GetValue();
#ifdef __unix__
@@ -3601,7 +3783,8 @@ void GMainWindow::OnConfigure() {
}
InitializeHotkeys();
- if (UISettings::values.theme != old_theme) {
+ if (UISettings::values.theme != old_theme ||
+ UISettings::values.dark_mode_state != old_dark_mode_state) {
UpdateUITheme();
}
if (UISettings::values.enable_discord_presence.GetValue() != old_discord_presence) {
@@ -3617,8 +3800,6 @@ void GMainWindow::OnConfigure() {
multiplayer_state->UpdateCredentials();
}
- emit UpdateThemedIcons();
-
const auto reload = UISettings::values.is_game_list_reload_pending.exchange(false);
if (reload || Settings::values.language_index.GetValue() != old_language_index) {
game_list->PopulateAsync(UISettings::values.game_dirs);
@@ -4682,6 +4863,66 @@ void GMainWindow::SetFirmwareVersion() {
firmware_label->setToolTip(QString::fromStdString(display_title));
}
+bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, u64 program_id,
+ u64* selected_title_id, u8* selected_content_record_type) {
+ using ContentInfo = std::tuple;
+ boost::container::flat_set available_title_ids;
+
+ const auto RetrieveEntries = [&](FileSys::TitleType title_type,
+ FileSys::ContentRecordType record_type) {
+ const auto entries = installed.ListEntriesFilter(title_type, record_type);
+ for (const auto& entry : entries) {
+ if (FileSys::GetBaseTitleID(entry.title_id) == program_id &&
+ installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success) {
+ available_title_ids.insert({entry.title_id, title_type, record_type});
+ }
+ }
+ };
+
+ RetrieveEntries(FileSys::TitleType::Application, FileSys::ContentRecordType::Program);
+ RetrieveEntries(FileSys::TitleType::Application, FileSys::ContentRecordType::HtmlDocument);
+ RetrieveEntries(FileSys::TitleType::Application, FileSys::ContentRecordType::LegalInformation);
+ RetrieveEntries(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
+
+ if (available_title_ids.empty()) {
+ return false;
+ }
+
+ size_t title_index = 0;
+
+ if (available_title_ids.size() > 1) {
+ QStringList list;
+ for (auto& [title_id, title_type, record_type] : available_title_ids) {
+ const auto hex_title_id = QString::fromStdString(fmt::format("{:X}", title_id));
+ if (record_type == FileSys::ContentRecordType::Program) {
+ list.push_back(QStringLiteral("Program [%1]").arg(hex_title_id));
+ } else if (record_type == FileSys::ContentRecordType::HtmlDocument) {
+ list.push_back(QStringLiteral("HTML document [%1]").arg(hex_title_id));
+ } else if (record_type == FileSys::ContentRecordType::LegalInformation) {
+ list.push_back(QStringLiteral("Legal information [%1]").arg(hex_title_id));
+ } else {
+ list.push_back(
+ QStringLiteral("DLC %1 [%2]").arg(title_id & 0x7FF).arg(hex_title_id));
+ }
+ }
+
+ bool ok;
+ const auto res = QInputDialog::getItem(
+ this, tr("Select RomFS Dump Target"),
+ tr("Please select which RomFS you would like to dump."), list, 0, false, &ok);
+ if (!ok) {
+ return false;
+ }
+
+ title_index = list.indexOf(res);
+ }
+
+ const auto& [title_id, title_type, record_type] = *available_title_ids.nth(title_index);
+ *selected_title_id = title_id;
+ *selected_content_record_type = static_cast(record_type);
+ return true;
+}
+
bool GMainWindow::ConfirmClose() {
if (emu_thread == nullptr ||
UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Never) {
@@ -4801,9 +5042,105 @@ void GMainWindow::filterBarSetChecked(bool state) {
emit(OnToggleFilterBar());
}
+void GMainWindow::UpdateUITheme() {
+ const QString default_theme = QString::fromStdString(UISettings::default_theme.data());
+ QString current_theme = UISettings::values.theme;
+ if (current_theme.isEmpty()) {
+ current_theme = default_theme;
+ }
+
+ UpdateIcons(current_theme);
+
+ /* Find the stylesheet to load */
+ if (TryLoadStylesheet(current_theme)) {
+ return;
+ }
+
+ // Reading new theme failed, loading default stylesheet
+ LOG_ERROR(Frontend, "Unable to open style \"{}\", fallback to the default theme",
+ current_theme.toStdString());
+
+ if (TryLoadStylesheet(QStringLiteral(":/%1").arg(default_theme))) {
+ return;
+ }
+
+ // Reading default failed, loading empty stylesheet
+ LOG_ERROR(Frontend, "Unable to set default style, stylesheet file not found");
+
+ qApp->setStyleSheet({});
+ setStyleSheet({});
+}
+
+void GMainWindow::UpdateIcons(const QString& theme_path) {
+ // Get the theme directory from its path
+ std::size_t last_slash = theme_path.toStdString().find_last_of("/");
+ QString theme_dir = QString::fromStdString(theme_path.toStdString().substr(last_slash + 1));
+
+ // Append _dark to the theme name to use dark variant icons
+ if (CheckDarkMode()) {
+ LOG_DEBUG(Frontend, "Using icons from: {}", theme_dir.toStdString() + "_dark");
+ QIcon::setThemeName(theme_dir + QStringLiteral("_dark"));
+ } else {
+ LOG_DEBUG(Frontend, "Using icons from: {}", theme_dir.toStdString());
+ QIcon::setThemeName(theme_dir);
+ }
+
+ const QString theme_directory{
+ QString::fromStdString(Common::FS::GetSuyuPathString(Common::FS::SuyuPath::ThemesDir))};
+
+ // Set path for default icons
+ // Use icon resources from application binary and current theme local subdirectory, if it exists
+ QStringList theme_paths;
+ theme_paths << QString::fromStdString(":/icons") << QStringLiteral("%1").arg(theme_directory);
+ QIcon::setThemeSearchPaths(theme_paths);
+
+ // Change current directory, to allow user themes to add their own icons
+ QDir::setCurrent(QStringLiteral("%1/%2").arg(theme_directory, UISettings::values.theme));
+
+ emit UpdateThemedIcons();
+}
+
+bool GMainWindow::TryLoadStylesheet(const QString& theme_uri) {
+ LOG_DEBUG(Frontend, "TryLoadStylesheet()");
+ QString style_path;
+
+ // Use themed stylesheet if it exists
+ if (CheckDarkMode()) {
+ style_path = theme_uri + QStringLiteral("/dark.qss");
+ } else {
+ style_path = theme_uri + QStringLiteral("/light.qss");
+ }
+ if (!QFile::exists(style_path)) {
+ LOG_DEBUG(Frontend, "No themed (light/dark) stylesheet, using default one");
+ // Use common stylesheet if themed one does not exist
+ style_path = theme_uri + QStringLiteral("/style.qss");
+ }
+
+ // Loading stylesheet
+ QFile style_file(style_path);
+ if (style_file.open(QFile::ReadOnly | QFile::Text)) {
+ // Update the color palette before applying the stylesheet
+ UpdateThemePalette();
+
+ LOG_DEBUG(Frontend, "Loading stylesheet in: {}", theme_uri.toStdString());
+ QTextStream ts_theme(&style_file);
+ qApp->setStyleSheet(ts_theme.readAll());
+ setStyleSheet(ts_theme.readAll());
+ SetCustomStylesheet();
+
+ return true;
+ }
+ // Opening the file failed
+ return false;
+}
+
+bool GMainWindow::TryLoadStylesheet(const std::filesystem::path& theme_path) {
+ return TryLoadStylesheet(QString::fromStdString(theme_path.string() + "/"));
+}
+
static void AdjustLinkColor() {
QPalette new_pal(qApp->palette());
- if (UISettings::IsDarkTheme()) {
+ if (GMainWindow::CheckDarkMode()) {
new_pal.setColor(QPalette::Link, QColor(0, 190, 255, 255));
} else {
new_pal.setColor(QPalette::Link, QColor(0, 140, 200, 255));
@@ -4813,54 +5150,262 @@ static void AdjustLinkColor() {
}
}
-void GMainWindow::UpdateUITheme() {
- const QString default_theme = QString::fromUtf8(
- UISettings::themes[static_cast(UISettings::default_theme)].second);
- QString current_theme = QString::fromStdString(UISettings::values.theme);
-
- if (current_theme.isEmpty()) {
- current_theme = default_theme;
- }
-
+void GMainWindow::UpdateThemePalette() {
+ LOG_DEBUG(Frontend, "UpdateThemePalette()");
+ QPalette themePalette(qApp->palette());
#ifdef _WIN32
- QIcon::setThemeName(current_theme);
- AdjustLinkColor();
-#else
- if (current_theme == QStringLiteral("default") || current_theme == QStringLiteral("colorful")) {
- QIcon::setThemeName(current_theme == QStringLiteral("colorful") ? current_theme
- : startup_icon_theme);
- QIcon::setThemeSearchPaths(QStringList(default_theme_paths));
- if (CheckDarkMode()) {
- current_theme = QStringLiteral("default_dark");
+ QColor dark(25, 25, 25);
+ QString style_name;
+ if (CheckDarkMode()) {
+ // We check that the dark mode state is "On" and force a dark palette
+ if (UISettings::values.dark_mode_state == DarkModeState::On) {
+ // Set Default Windows Dark palette on Windows platforms to force Dark mode
+ themePalette.setColor(QPalette::Window, Qt::black);
+ themePalette.setColor(QPalette::WindowText, Qt::white);
+ themePalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(127, 127, 127));
+ themePalette.setColor(QPalette::Base, Qt::black);
+ themePalette.setColor(QPalette::AlternateBase, dark);
+ themePalette.setColor(QPalette::ToolTipBase, Qt::white);
+ themePalette.setColor(QPalette::ToolTipText, Qt::black);
+ themePalette.setColor(QPalette::Text, Qt::white);
+ themePalette.setColor(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127));
+ themePalette.setColor(QPalette::Dark, QColor(128, 128, 128));
+ themePalette.setColor(QPalette::Shadow, Qt::white);
+ themePalette.setColor(QPalette::Button, Qt::black);
+ themePalette.setColor(QPalette::ButtonText, Qt::white);
+ themePalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(127, 127, 127));
+ themePalette.setColor(QPalette::BrightText, QColor(192, 192, 192));
+ themePalette.setColor(QPalette::Link, QColor(0, 140, 200));
+ themePalette.setColor(QPalette::Highlight, QColor(24, 70, 93));
+ themePalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(0, 85, 255));
+ themePalette.setColor(QPalette::HighlightedText, QColor(239, 240, 241));
+ themePalette.setColor(QPalette::Disabled, QPalette::HighlightedText,
+ QColor(239, 240, 241));
}
+
+ // AlternateBase is kept at rgb(233, 231, 227) or rgb(245, 245, 245) on Windows dark
+ // palette, fix this. Sometimes, it even is rgb(0, 0, 0), but uses a very light gray for
+ // alternate rows, do not know why
+ if (themePalette.alternateBase().color() == QColor(233, 231, 227) ||
+ themePalette.alternateBase().color() == QColor(245, 245, 245) ||
+ themePalette.alternateBase().color() == QColor(0, 0, 0)) {
+ themePalette.setColor(QPalette::AlternateBase, dark);
+ alternate_base_modified = true;
+ }
+ // Use fusion theme, since its close to windowsvista, but works well with a dark palette
+ style_name = QStringLiteral("fusion");
} else {
- QIcon::setThemeName(current_theme);
- QIcon::setThemeSearchPaths(QStringList(QStringLiteral(":/icons")));
- AdjustLinkColor();
+ // Reset AlternateBase if it has been modified
+ if (alternate_base_modified) {
+ themePalette.setColor(QPalette::AlternateBase, QColor(245, 245, 245));
+ alternate_base_modified = false;
+ }
+ // Reset light palette
+ themePalette = this->style()->standardPalette();
+ // Reset Windows theme to the default
+ style_name = QStringLiteral("windowsvista");
+ }
+ LOG_DEBUG(Frontend, "Using style: {}", style_name.toStdString());
+ qApp->setStyle(style_name);
+#elif defined(__APPLE__)
+ // Force the usage of the light palette in light mode
+ if (CheckDarkMode()) {
+ // Reset dark palette
+ themePalette = this->style()->standardPalette();
+ } else {
+ themePalette.setColor(QPalette::Window, QColor(236, 236, 236));
+ themePalette.setColor(QPalette::WindowText, Qt::black);
+ themePalette.setColor(QPalette::Disabled, QPalette::WindowText, Qt::black);
+ themePalette.setColor(QPalette::Base, Qt::white);
+ themePalette.setColor(QPalette::AlternateBase, QColor(245, 245, 245));
+ themePalette.setColor(QPalette::ToolTipBase, Qt::white);
+ themePalette.setColor(QPalette::ToolTipText, Qt::black);
+ themePalette.setColor(QPalette::Text, Qt::black);
+ themePalette.setColor(QPalette::Disabled, QPalette::Text, Qt::black);
+ themePalette.setColor(QPalette::Dark, QColor(191, 191, 191));
+ themePalette.setColor(QPalette::Shadow, Qt::black);
+ themePalette.setColor(QPalette::Button, QColor(236, 236, 236));
+ themePalette.setColor(QPalette::ButtonText, Qt::black);
+ themePalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(147, 147, 147));
+ themePalette.setColor(QPalette::BrightText, Qt::white);
+ themePalette.setColor(QPalette::Link, QColor(0, 140, 200));
+ themePalette.setColor(QPalette::Highlight, QColor(179, 215, 255));
+ themePalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(220, 220, 220));
+ themePalette.setColor(QPalette::HighlightedText, Qt::black);
+ themePalette.setColor(QPalette::Disabled, QPalette::HighlightedText, Qt::black);
+ }
+#else
+ if (CheckDarkMode()) {
+ // Set Dark palette on non Windows platforms (that may not have a dark palette)
+ themePalette.setColor(QPalette::Window, QColor(53, 53, 53));
+ themePalette.setColor(QPalette::WindowText, Qt::white);
+ themePalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(127, 127, 127));
+ themePalette.setColor(QPalette::Base, QColor(42, 42, 42));
+ themePalette.setColor(QPalette::AlternateBase, QColor(66, 66, 66));
+ themePalette.setColor(QPalette::ToolTipBase, Qt::white);
+ themePalette.setColor(QPalette::ToolTipText, QColor(53, 53, 53));
+ themePalette.setColor(QPalette::Text, Qt::white);
+ themePalette.setColor(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127));
+ themePalette.setColor(QPalette::Dark, QColor(35, 35, 35));
+ themePalette.setColor(QPalette::Shadow, QColor(20, 20, 20));
+ themePalette.setColor(QPalette::Button, QColor(53, 53, 53));
+ themePalette.setColor(QPalette::ButtonText, Qt::white);
+ themePalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(127, 127, 127));
+ themePalette.setColor(QPalette::BrightText, Qt::red);
+ themePalette.setColor(QPalette::Link, QColor(42, 130, 218));
+ themePalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
+ themePalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(80, 80, 80));
+ themePalette.setColor(QPalette::HighlightedText, Qt::white);
+ themePalette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(127, 127, 127));
+ } else {
+ // Reset light palette
+ themePalette = this->style()->standardPalette();
}
#endif
- if (current_theme != default_theme) {
- QString theme_uri{QStringLiteral(":%1/style.qss").arg(current_theme)};
- QFile f(theme_uri);
- if (!f.open(QFile::ReadOnly | QFile::Text)) {
- LOG_ERROR(Frontend, "Unable to open style \"{}\", fallback to the default theme",
- UISettings::values.theme);
- current_theme = default_theme;
+ qApp->setPalette(themePalette);
+ AdjustLinkColor();
+}
+
+void GMainWindow::SetCustomStylesheet() {
+ setStyleSheet(QStringLiteral("QStatusBar::item { border: none; }"));
+
+ // Set "dark" qss property value, that may be used in stylesheets
+ bool is_dark_mode = CheckDarkMode();
+ if (renderer_status_button) {
+ renderer_status_button->setProperty("dark", is_dark_mode);
+ }
+ if (gpu_accuracy_button) {
+ gpu_accuracy_button->setProperty("dark", is_dark_mode);
+ }
+#ifdef _WIN32
+ // Windows dark mode uses "fusion" style. Make it look like more "windowsvista" light style
+ if (is_dark_mode) {
+ /* the groove expands to the size of the slider by default. by giving it a height, it has a
+ fixed size */
+ /* handle is placed by default on the contents rect of the groove. Negative margin expands
+ it outside the groove */
+ setStyleSheet(QStringLiteral("QSlider:horizontal{ height:30px; }\
+ QSlider::sub-page:horizontal { background-color: palette(highlight); }\
+ QSlider::add-page:horizontal { background-color: palette(midlight);}\
+ QSlider::groove:horizontal { border-width: 1px; margin: 1px 0; height: 2px;}\
+ QSlider::handle:horizontal { border-width: 1px; border-style: solid; border-color: palette(dark);\
+ width: 10px; margin: -10px 0px; }\
+ QSlider::handle { background-color: palette(button); }\
+ QSlider::handle:hover { background-color: palette(highlight); }"));
+ }
+#endif
+}
+
+#ifdef __unix__
+bool GMainWindow::ListenColorSchemeChange() {
+ auto bus = QDBusConnection::sessionBus();
+ if (bus.isConnected()) {
+ const QString dbus_service = QStringLiteral("org.freedesktop.portal.Desktop");
+ const QString dbus_path = QStringLiteral("/org/freedesktop/portal/desktop");
+ const QString dbus_interface = QStringLiteral("org.freedesktop.portal.Settings");
+ const QString dbus_method = QStringLiteral("SettingChanged");
+ QStringList dbus_arguments;
+ dbus_arguments << QStringLiteral("org.freedesktop.appearance")
+ << QStringLiteral("color-scheme");
+ const QString dbus_signature = QStringLiteral("ssv");
+
+ LOG_INFO(Frontend, "Connected to DBus, listening for OS theme changes");
+ return bus.connect(dbus_service, dbus_path, dbus_interface, dbus_method, dbus_arguments,
+ dbus_signature, this, SLOT(UpdateUITheme()));
+ }
+ LOG_WARNING(Frontend, "Unable to connect to DBus to listen for OS theme changes");
+ return false;
+}
+#endif
+
+bool GMainWindow::CheckDarkMode() {
+ bool is_dark_mode_auto;
+#ifdef _WIN32
+ // Dark mode cannot be changed after the app started on Windows
+ is_dark_mode_auto = qgetenv("QT_QPA_PLATFORM").contains("darkmode=2");
+#else
+ is_dark_mode_auto = UISettings::values.dark_mode_state == DarkModeState::Auto;
+#endif
+ if (!is_dark_mode_auto) {
+ return UISettings::values.dark_mode_state == DarkModeState::On;
+ } else {
+ const QPalette current_palette(qApp->palette());
+#ifdef __unix__
+ QProcess process;
+
+ // Using the freedesktop specifications for checking dark mode
+ LOG_DEBUG(Frontend, "Retrieving theme from freedesktop color-scheme...");
+ QStringList gdbus_arguments;
+ gdbus_arguments << QStringLiteral("--dest=org.freedesktop.portal.Desktop")
+ << QStringLiteral("--object-path /org/freedesktop/portal/desktop")
+ << QStringLiteral("--method org.freedesktop.portal.Settings.Read")
+ << QStringLiteral("org.freedesktop.appearance color-scheme");
+ process.start(QStringLiteral("gdbus call --session"), gdbus_arguments);
+ process.waitForFinished(1000);
+ QByteArray dbus_output = process.readAllStandardOutput();
+
+ if (!dbus_output.isEmpty()) {
+ const int systemColorSchema = QString::fromUtf8(dbus_output).trimmed().right(1).toInt();
+ return systemColorSchema == 1;
+ }
+
+ // Try alternative for Gnome if the previous one failed
+ QStringList gsettings_arguments;
+ gsettings_arguments << QStringLiteral("get")
+ << QStringLiteral("org.gnome.desktop.interface")
+ << QStringLiteral("color-scheme");
+
+ LOG_DEBUG(Frontend, "failed, retrieving theme from gsettings color-scheme...");
+ process.start(QStringLiteral("gsettings"), gsettings_arguments);
+ process.waitForFinished(1000);
+ QByteArray gsettings_output = process.readAllStandardOutput();
+
+ // Try older gtk-theme method if the previous one failed
+ if (gsettings_output.isEmpty()) {
+ LOG_DEBUG(Frontend, "failed, retrieving theme from gtk-theme...");
+ gsettings_arguments.takeLast();
+ gsettings_arguments << QStringLiteral("gtk-theme");
+
+ process.start(QStringLiteral("gsettings"), gsettings_arguments);
+ process.waitForFinished(1000);
+ gsettings_output = process.readAllStandardOutput();
+ }
+
+ // Interpret gsettings value if it succeeded
+ if (!gsettings_output.isEmpty()) {
+ QString systeme_theme = QString::fromUtf8(gsettings_output);
+ LOG_DEBUG(Frontend, "Gsettings output: {}", systeme_theme.toStdString());
+ return systeme_theme.contains(QStringLiteral("dark"), Qt::CaseInsensitive);
+ }
+ LOG_DEBUG(Frontend, "failed, retrieving theme from palette");
+#endif
+ // Use default method based on palette swap by OS. It is the only method on Windows with
+ // Qt 5. Windows needs QT_QPA_PLATFORM env variable set to windows:darkmode=2 to force
+ // palette change
+ return (current_palette.color(QPalette::WindowText).lightness() >
+ current_palette.color(QPalette::Window).lightness());
+ }
+}
+
+void GMainWindow::changeEvent(QEvent* event) {
+ // PaletteChange event appears to only reach so far into the GUI, explicitly asking to
+ // UpdateUITheme is a decent work around
+ if (event->type() == QEvent::PaletteChange ||
+ event->type() == QEvent::ApplicationPaletteChange) {
+ LOG_DEBUG(Frontend,
+ "Window color palette changed by event: {} (QEvent::PaletteChange is: {})",
+ event->type(), QEvent::PaletteChange);
+ const QPalette test_palette(qApp->palette());
+ // Keeping eye on QPalette::Window to avoid looping. QPalette::Text might be useful too
+ const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window);
+
+ if (last_window_color != window_color) {
+ last_window_color = window_color;
+
+ UpdateUITheme();
}
}
-
- QString theme_uri{QStringLiteral(":%1/style.qss").arg(current_theme)};
- QFile f(theme_uri);
- if (f.open(QFile::ReadOnly | QFile::Text)) {
- QTextStream ts(&f);
- qApp->setStyleSheet(ts.readAll());
- setStyleSheet(ts.readAll());
- } else {
- LOG_ERROR(Frontend, "Unable to set style \"{}\", stylesheet file not found",
- UISettings::values.theme);
- qApp->setStyleSheet({});
- setStyleSheet({});
- }
+ QWidget::changeEvent(event);
}
void GMainWindow::LoadTranslation() {
@@ -4915,26 +5460,6 @@ void GMainWindow::SetGamemodeEnabled(bool state) {
}
#endif
-void GMainWindow::changeEvent(QEvent* event) {
-#ifdef __unix__
- // PaletteChange event appears to only reach so far into the GUI, explicitly asking to
- // UpdateUITheme is a decent work around
- if (event->type() == QEvent::PaletteChange) {
- const QPalette test_palette(qApp->palette());
- const QString current_theme = QString::fromStdString(UISettings::values.theme);
- // Keeping eye on QPalette::Window to avoid looping. QPalette::Text might be useful too
- static QColor last_window_color;
- const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window);
- if (last_window_color != window_color && (current_theme == QStringLiteral("default") ||
- current_theme == QStringLiteral("colorful"))) {
- UpdateUITheme();
- }
- last_window_color = window_color;
- }
-#endif // __unix__
- QWidget::changeEvent(event);
-}
-
Service::AM::FrontendAppletParameters GMainWindow::ApplicationAppletParameters() {
return Service::AM::FrontendAppletParameters{
.applet_id = Service::AM::AppletId::Application,
@@ -5061,6 +5586,31 @@ int main(int argc, char* argv[]) {
QCoreApplication::setApplicationName(QStringLiteral("suyu"));
#ifdef _WIN32
+ QByteArray current_qt_qpa = qgetenv("QT_QPA_PLATFORM");
+ // Follow dark mode setting, if the "-platform" launch option is not set.
+ // Otherwise, just follow dark mode for the window decoration (title bar).
+ if (!current_qt_qpa.contains(":darkmode=")) {
+ if (UISettings::values.dark_mode_state == DarkModeState::Auto) {
+ // When setting is Auto, force adapting window decoration and stylesheet palette to use
+ // Windows theme. Default is darkmode:0, which always uses light palette
+ if (current_qt_qpa.isEmpty()) {
+ // Set the value
+ qputenv("QT_QPA_PLATFORM", QByteArray("windows:darkmode=2"));
+ } else {
+ // Concatenate to the existing value
+ qputenv("QT_QPA_PLATFORM", current_qt_qpa + ",darkmode=2");
+ }
+ } else {
+ // When setting is no Auto, adapt window decoration to the palette used
+ if (current_qt_qpa.isEmpty()) {
+ // Set the value
+ qputenv("QT_QPA_PLATFORM", QByteArray("windows:darkmode=1"));
+ } else {
+ // Concatenate to the existing value
+ qputenv("QT_QPA_PLATFORM", current_qt_qpa + ",darkmode=1");
+ }
+ }
+ }
// Increases the maximum open file limit to 8192
_setmaxstdio(8192);
#endif
@@ -5082,7 +5632,7 @@ int main(int argc, char* argv[]) {
// Fix the Wayland appId. This needs to match the name of the .desktop file without the .desktop
// suffix.
- QGuiApplication::setDesktopFileName(QStringLiteral("org.suyu_emu.suyu"));
+ QGuiApplication::setDesktopFileName(QStringLiteral("dev.suyu_emu.suyu"));
#endif
SetHighDPIAttributes();
diff --git a/src/suyu/main.h b/src/suyu/main.h
index e20950e238..e17c8c0607 100644
--- a/src/suyu/main.h
+++ b/src/suyu/main.h
@@ -25,9 +25,8 @@
#include "suyu/util/controller_navigation.h"
#ifdef __unix__
+#include
#include
-#include
-#include
#endif
class QtConfig;
@@ -51,6 +50,7 @@ class WaitTreeWidget;
enum class GameListOpenTarget;
enum class GameListRemoveTarget;
enum class GameListShortcutTarget;
+enum class DumpRomFSTarget;
enum class InstalledEntryType;
class GameListPlaceholder;
@@ -167,7 +167,7 @@ class GMainWindow : public QMainWindow {
public:
void filterBarSetChecked(bool state);
- void UpdateUITheme();
+ static bool CheckDarkMode();
explicit GMainWindow(std::unique_ptr config_, bool has_broken_vulkan);
~GMainWindow() override;
@@ -259,12 +259,44 @@ private:
void SetDefaultUIGeometry();
void RestoreUIState();
+ /**
+ * Load the icons used by the current theme. Use dark icons if the current mode is dark
+ */
+ void UpdateIcons(const QString& theme_used);
+ /**
+ * Set the palette used by the stylsheet for the dark/light mode selected, according to the OS
+ */
+ void UpdateThemePalette();
+ /**
+ * Try to load a stylesheet from its URI.
+ * If the path starts with ":/", its embedded in the app, otherwise its in a local directory
+ * @returns true if the text file could be opened as read-only
+ */
+ bool TryLoadStylesheet(const QString& theme_uri);
+ /**
+ * Try to load a stylesheet from filesystem path
+ * @returns true if the text file could be opened as read-only
+ */
+ bool TryLoadStylesheet(const std::filesystem::path& theme_path);
+ /**
+ * Default customizations to the stylesheets
+ */
+ void SetCustomStylesheet();
+#ifdef __unix__
+ /**
+ * Create a signal to update the UI theme when the OS color scheme is changed
+ * @returns true if we could connect to dbus
+ */
+ bool ListenColorSchemeChange();
+#endif
void ConnectWidgetEvents();
void ConnectMenuEvents();
void UpdateMenuState();
+#ifdef __unix__
void SetupPrepareForSleep();
+#endif
void PreventOSSleep();
void AllowOSSleep();
@@ -347,6 +379,7 @@ private slots:
void OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target,
const std::string& game_path);
void OnGameListRemovePlayTimeData(u64 program_id);
+ void OnGameListDumpRomFS(u64 program_id, const std::string& game_path, DumpRomFSTarget target);
void OnGameListVerifyIntegrity(const std::string& game_path);
void OnGameListCopyTID(u64 program_id);
void OnGameListNavigateToGamedbEntry(u64 program_id,
@@ -395,6 +428,7 @@ private slots:
void ResetWindowSize720();
void ResetWindowSize900();
void ResetWindowSize1080();
+ void UpdateUITheme();
void OnAlbum();
void OnCabinet(Service::NFP::CabinetMode mode);
void OnMiiEdit();
@@ -441,7 +475,7 @@ private:
void OpenURL(const QUrl& url);
void LoadTranslation();
void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
- bool CheckDarkMode();
+ bool CheckSystemArchiveDecryption();
bool CheckFirmwarePresence();
void SetFirmwareVersion();
void ConfigureFilesystemProvider(const std::string& filepath);
@@ -525,7 +559,8 @@ private:
QTimer update_input_timer;
QString startup_icon_theme;
- bool os_dark_mode = false;
+ bool alternate_base_modified = false;
+ QColor last_window_color;
// FS
std::shared_ptr vfs;
diff --git a/src/suyu/play_time_manager.cpp b/src/suyu/play_time_manager.cpp
index 9a046c69a1..ede966da6e 100644
--- a/src/suyu/play_time_manager.cpp
+++ b/src/suyu/play_time_manager.cpp
@@ -87,7 +87,7 @@ std::optional GetCurrentUserPlayTimePath(
std::vector elements;
elements.reserve(play_time_db.size());
- for (auto& [program_id, play_time] : play_time_db) {
+ for (const auto& [program_id, play_time] : play_time_db) {
if (program_id != 0) {
elements.push_back(PlayTimeElement{program_id, play_time});
}
diff --git a/src/suyu/startup_checks.cpp b/src/suyu/startup_checks.cpp
index 292fbcbbaa..07e8bcb5d8 100644
--- a/src/suyu/startup_checks.cpp
+++ b/src/suyu/startup_checks.cpp
@@ -5,6 +5,7 @@
#ifdef _WIN32
#include
+#include
#include
#include
#elif defined(SUYU_UNIX)
diff --git a/src/suyu/uisettings.cpp b/src/suyu/uisettings.cpp
index 60d4063c8c..7cf32ddd0e 100644
--- a/src/suyu/uisettings.cpp
+++ b/src/suyu/uisettings.cpp
@@ -22,21 +22,15 @@ namespace FS = Common::FS;
namespace UISettings {
-const Themes themes{{
- {"Default", "default"},
- {"Default Colorful", "colorful"},
- {"Dark", "qdarkstyle"},
- {"Dark Colorful", "colorful_dark"},
- {"Midnight Blue", "qdarkstyle_midnight_blue"},
- {"Midnight Blue Colorful", "colorful_midnight_blue"},
+const Themes included_themes{{
+ {"Default", ":/default"},
+ {"Default monochrome", ":/monochrome"},
+ {"Mine Shaft", ":/qdarkstyle"},
+ {"Mine Shaft monochrome", ":/qdarkstyle_monochrome"},
+ {"Midnight Blue", ":/qdarkstyle_midnight_blue"},
+ {"Midnight Blue monochrome", ":/qdarkstyle_midnight_blue_monochrome"},
}};
-bool IsDarkTheme() {
- const auto& theme = UISettings::values.theme;
- return theme == std::string("qdarkstyle") || theme == std::string("qdarkstyle_midnight_blue") ||
- theme == std::string("colorful_dark") || theme == std::string("colorful_midnight_blue");
-}
-
Values values = {};
u32 CalculateWidth(u32 height, Settings::AspectRatio ratio) {
diff --git a/src/suyu/uisettings.h b/src/suyu/uisettings.h
index cab889680f..ded6a42244 100644
--- a/src/suyu/uisettings.h
+++ b/src/suyu/uisettings.h
@@ -18,6 +18,7 @@
using Settings::Category;
using Settings::ConfirmStop;
+using Settings::DarkModeState;
using Settings::Setting;
using Settings::SwitchableSetting;
@@ -35,8 +36,6 @@ extern template class Setting;
namespace UISettings {
-bool IsDarkTheme();
-
struct ContextualShortcut {
std::string keyseq;
std::string controller_keyseq;
@@ -50,25 +49,10 @@ struct Shortcut {
ContextualShortcut shortcut;
};
-enum class Theme {
- Default,
- DefaultColorful,
- Dark,
- DarkColorful,
- MidnightBlue,
- MidnightBlueColorful,
-};
-
-static constexpr Theme default_theme{
-#ifdef _WIN32
- Theme::DarkColorful
-#else
- Theme::DefaultColorful
-#endif
-};
+static constexpr std::string_view default_theme{":/default"};
using Themes = std::array, 6>;
-extern const Themes themes;
+extern const Themes included_themes;
struct GameDir {
std::string path;
@@ -160,7 +144,8 @@ struct Values {
QStringList recent_files;
Setting language{linkage, {}, "language", Category::Paths};
- std::string theme;
+ QString theme;
+ DarkModeState dark_mode_state;
// Shortcut name
std::vector shortcuts;
@@ -278,3 +263,4 @@ Q_DECLARE_METATYPE(Settings::RendererBackend);
Q_DECLARE_METATYPE(Settings::ShaderBackend);
Q_DECLARE_METATYPE(Settings::AstcRecompression);
Q_DECLARE_METATYPE(Settings::AstcDecodeMode);
+Q_DECLARE_METATYPE(Settings::DarkModeState);
diff --git a/src/tests/video_core/memory_tracker.cpp b/src/tests/video_core/memory_tracker.cpp
index 45b1a91dc5..bfdcc8a16c 100644
--- a/src/tests/video_core/memory_tracker.cpp
+++ b/src/tests/video_core/memory_tracker.cpp
@@ -45,7 +45,7 @@ public:
[[nodiscard]] unsigned Count() const noexcept {
unsigned count = 0;
- for (const auto& [index, value] : page_table) {
+ for (const auto& [_, value] : page_table) {
count += value;
}
return count;
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index c816f47fec..b8c07d791a 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -40,10 +40,23 @@ struct GPU::Impl {
explicit Impl(GPU& gpu_, Core::System& system_, bool is_async_, bool use_nvdec_)
: gpu{gpu_}, system{system_}, host1x{system.Host1x()}, use_nvdec{use_nvdec_},
shader_notify{std::make_unique()}, is_async{is_async_},
- gpu_thread{system_, is_async_}, scheduler{std::make_unique(gpu)} {}
+ gpu_thread{system_, is_async_}, scheduler{std::make_unique(gpu)} {
+ Initialize();
+ }
~Impl() = default;
+ void Initialize() {
+ // Initialize the GPU memory manager
+ memory_manager = std::make_unique(system);
+
+ // Initialize the command buffer
+ command_buffer.reserve(COMMAND_BUFFER_SIZE);
+
+ // Initialize the fence manager
+ fence_manager = std::make_unique();
+ }
+
std::shared_ptr CreateChannel(s32 channel_id) {
auto channel_state = std::make_shared(channel_id);
channels.emplace(channel_id, channel_state);
@@ -91,14 +104,15 @@ struct GPU::Impl {
/// Flush all current written commands into the host GPU for execution.
void FlushCommands() {
- rasterizer->FlushCommands();
+ if (!command_buffer.empty()) {
+ rasterizer->ExecuteCommands(command_buffer);
+ command_buffer.clear();
+ }
}
/// Synchronizes CPU writes with Host GPU memory.
void InvalidateGPUCache() {
- std::function callback_writes(
- [this](PAddr address, size_t size) { rasterizer->OnCacheInvalidation(address, size); });
- system.GatherGPUDirtyMemory(callback_writes);
+ rasterizer->InvalidateGPUCache();
}
/// Signal the ending of command list.
@@ -108,11 +122,10 @@ struct GPU::Impl {
}
/// Request a host GPU memory flush from the CPU.
- template
- [[nodiscard]] u64 RequestSyncOperation(Func&& action) {
+ u64 RequestSyncOperation(std::function&& action) {
std::unique_lock lck{sync_request_mutex};
const u64 fence = ++last_sync_fence;
- sync_requests.emplace_back(action);
+ sync_requests.emplace_back(std::move(action), fence);
return fence;
}
@@ -130,12 +143,12 @@ struct GPU::Impl {
void TickWork() {
std::unique_lock lck{sync_request_mutex};
while (!sync_requests.empty()) {
- auto request = std::move(sync_requests.front());
- sync_requests.pop_front();
+ auto& request = sync_requests.front();
sync_request_mutex.unlock();
- request();
+ request.first();
current_sync_fence.fetch_add(1, std::memory_order_release);
sync_request_mutex.lock();
+ sync_requests.pop_front();
sync_request_cv.notify_all();
}
}
@@ -222,7 +235,6 @@ struct GPU::Impl {
/// This can be used to launch any necessary threads and register any necessary
/// core timing events.
void Start() {
- Settings::UpdateGPUAccuracy();
gpu_thread.StartThread(*renderer, renderer->Context(), *scheduler);
}
@@ -252,7 +264,7 @@ struct GPU::Impl {
/// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
void FlushRegion(DAddr addr, u64 size) {
- gpu_thread.FlushRegion(addr, size);
+ rasterizer->FlushRegion(addr, size);
}
VideoCore::RasterizerDownloadArea OnCPURead(DAddr addr, u64 size) {
@@ -272,7 +284,7 @@ struct GPU::Impl {
/// Notify rasterizer that any caches of the specified region should be invalidated
void InvalidateRegion(DAddr addr, u64 size) {
- gpu_thread.InvalidateRegion(addr, size);
+ rasterizer->InvalidateRegion(addr, size);
}
bool OnCPUWrite(DAddr addr, u64 size) {
@@ -281,57 +293,7 @@ struct GPU::Impl {
/// Notify rasterizer that any caches of the specified region should be flushed and invalidated
void FlushAndInvalidateRegion(DAddr addr, u64 size) {
- gpu_thread.FlushAndInvalidateRegion(addr, size);
- }
-
- void RequestComposite(std::vector&& layers,
- std::vector