From 20cc867c62e28153ef8a174373890557c1aabb25 Mon Sep 17 00:00:00 2001 From: swurl Date: Thu, 8 May 2025 22:16:07 +0000 Subject: [PATCH] User Data Migration from Citron, Sudachi, and Yuzu (#91) Includes citron, sudachi, yuzu currently broken, because the eden dir is always made early? Signed-off-by: swurl Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/91 Co-authored-by: swurl Co-committed-by: swurl --- .ci/{android.sh => android/build.sh} | 3 + .ci/android/package.sh | 22 +++ .ci/{linux.sh => linux/build.sh} | 3 + .ci/{ => linux}/eden.dwfsprof | 0 .ci/{package-appimage.sh => linux/package.sh} | 5 +- .ci/windows/build-bqt.bat | 27 +++ .ci/windows/build.bat | 31 ++++ .ci/windows/cygwin.bat | 19 ++ .ci/{ => windows}/install-vulkan-sdk.ps1 | 0 .ci/windows/package.ps1 | 41 +++++ .github/workflows/build.yml | 106 ++--------- .github/workflows/trigger_release.yml | 88 ++------- src/CMakeLists.txt | 2 +- src/android/app/src/main/jni/native.cpp | 4 +- src/android/app/src/main/jni/native_input.cpp | 4 +- src/common/fs/fs_paths.h | 9 +- src/common/fs/path_util.cpp | 164 +++++++++++------ src/common/fs/path_util.h | 76 ++++++-- src/common/logging/backend.cpp | 2 +- src/common/nvidia_flags.cpp | 2 +- src/common/settings.cpp | 10 +- src/common/settings.h | 1 + src/core/crypto/key_manager.cpp | 14 +- src/core/file_sys/bis_factory.cpp | 2 +- src/core/hle/service/acc/acc.cpp | 2 +- src/core/hle/service/acc/profile_manager.cpp | 6 +- .../am/frontend/applet_web_browser.cpp | 4 +- src/core/hle/service/am/process_creation.cpp | 2 +- src/core/hle/service/caps/caps_manager.cpp | 4 +- .../hle/service/filesystem/filesystem.cpp | 14 +- .../hle/service/mii/mii_database_manager.cpp | 4 +- .../hle/service/nfc/common/amiibo_crypto.cpp | 4 +- src/core/hle/service/nfc/common/device.cpp | 6 +- .../service/set/system_settings_server.cpp | 16 +- src/core/perf_stats.cpp | 2 +- src/core/reporter.cpp | 6 +- src/frontend_common/config.cpp | 38 ++-- src/input_common/drivers/tas_input.cpp | 4 +- src/video_core/macro/macro.cpp | 2 +- .../renderer_opengl/gl_shader_cache.cpp | 2 +- .../renderer_vulkan/vk_pipeline_cache.cpp | 2 +- src/video_core/shader_environment.cpp | 2 +- .../nsight_aftermath_tracker.cpp | 2 +- src/yuzu/CMakeLists.txt | 3 + src/yuzu/applets/qt_profile_select.cpp | 2 +- src/yuzu/applets/qt_web_browser.cpp | 4 +- src/yuzu/breakpad.cpp | 2 +- src/yuzu/configuration/configure_debug.cpp | 2 +- .../configuration/configure_filesystem.cpp | 20 +-- .../configure_per_game_addons.cpp | 2 +- .../configure_profile_manager.cpp | 4 +- src/yuzu/configuration/configure_tas.cpp | 4 +- src/yuzu/configuration/configure_ui.cpp | 8 +- src/yuzu/configuration/input_profiles.cpp | 4 +- src/yuzu/configuration/qt_config.cpp | 1 + src/yuzu/game_list_worker.cpp | 4 +- src/yuzu/main.cpp | 63 +++---- src/yuzu/main.h | 4 +- src/yuzu/play_time_manager.cpp | 2 +- src/yuzu/uisettings.cpp | 6 +- src/yuzu/user_data_migration.cpp | 168 ++++++++++++++++++ src/yuzu/user_data_migration.h | 27 +++ 62 files changed, 703 insertions(+), 384 deletions(-) rename .ci/{android.sh => android/build.sh} (79%) create mode 100755 .ci/android/package.sh rename .ci/{linux.sh => linux/build.sh} (95%) rename .ci/{ => linux}/eden.dwfsprof (100%) rename .ci/{package-appimage.sh => linux/package.sh} (95%) create mode 100755 .ci/windows/build-bqt.bat create mode 100755 .ci/windows/build.bat create mode 100755 .ci/windows/cygwin.bat rename .ci/{ => windows}/install-vulkan-sdk.ps1 (100%) mode change 100644 => 100755 create mode 100755 .ci/windows/package.ps1 create mode 100644 src/yuzu/user_data_migration.cpp create mode 100644 src/yuzu/user_data_migration.h diff --git a/.ci/android.sh b/.ci/android/build.sh similarity index 79% rename from .ci/android.sh rename to .ci/android/build.sh index a92e1a0ae8..eaeff11472 100755 --- a/.ci/android.sh +++ b/.ci/android/build.sh @@ -1,5 +1,8 @@ #!/bin/bash -e +# SPDX-FileCopyrightText: 2025 eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + export NDK_CCACHE=$(which ccache) # keystore & pass are stored locally diff --git a/.ci/android/package.sh b/.ci/android/package.sh new file mode 100755 index 0000000000..c2eb975a02 --- /dev/null +++ b/.ci/android/package.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# SPDX-FileCopyrightText: 2025 eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + +GITDATE="$(git show -s --date=short --format='%ad' | sed 's/-//g')" +GITREV="$(git show -s --format='%h')" +ARTIFACTS_DIR="$PWD/artifacts" +mkdir -p "${ARTIFACTS_DIR}/" + +REV_NAME="eden-android-${GITDATE}-${GITREV}" +BUILD_FLAVOR="mainline" +BUILD_TYPE_LOWER="release" +BUILD_TYPE_UPPER="Release" + +cp src/android/app/build/outputs/apk/"${BUILD_FLAVOR}/${BUILD_TYPE_LOWER}/app-${BUILD_FLAVOR}-${BUILD_TYPE_LOWER}.apk" \ + "${ARTIFACTS_DIR}/${REV_NAME}.apk" || echo "APK not found" + +cp src/android/app/build/outputs/bundle/"${BUILD_FLAVOR}${BUILD_TYPE_UPPER}"/"app-${BUILD_FLAVOR}-${BUILD_TYPE_LOWER}.aab" \ + "${ARTIFACTS_DIR}/${REV_NAME}.aab" || echo "AAB not found" + +ls -la "${ARTIFACTS_DIR}/" diff --git a/.ci/linux.sh b/.ci/linux/build.sh similarity index 95% rename from .ci/linux.sh rename to .ci/linux/build.sh index 694e1c5b2a..f620cd1ecb 100755 --- a/.ci/linux.sh +++ b/.ci/linux/build.sh @@ -1,5 +1,8 @@ #!/bin/bash -ex +# SPDX-FileCopyrightText: 2025 eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + export ARCH="$(uname -m)" if [ "$ARCH" = 'x86_64' ]; then diff --git a/.ci/eden.dwfsprof b/.ci/linux/eden.dwfsprof similarity index 100% rename from .ci/eden.dwfsprof rename to .ci/linux/eden.dwfsprof diff --git a/.ci/package-appimage.sh b/.ci/linux/package.sh similarity index 95% rename from .ci/package-appimage.sh rename to .ci/linux/package.sh index 806d3bb802..2e5e3521e4 100755 --- a/.ci/package-appimage.sh +++ b/.ci/linux/package.sh @@ -1,5 +1,8 @@ #!/bin/sh +# SPDX-FileCopyrightText: 2025 eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + # This script assumes you're in the source directory set -ex @@ -113,7 +116,7 @@ echo "Generating AppImage..." ./uruntime --appimage-mkdwarfs -f \ --set-owner 0 --set-group 0 \ --no-history --no-create-timestamp \ - --categorize=hotness --hotness-list=.ci/eden.dwfsprof \ + --categorize=hotness --hotness-list=.ci/linux/eden.dwfsprof \ --compression zstd:level=22 -S26 -B32 \ --header uruntime \ -N 4 \ diff --git a/.ci/windows/build-bqt.bat b/.ci/windows/build-bqt.bat new file mode 100755 index 0000000000..925d420690 --- /dev/null +++ b/.ci/windows/build-bqt.bat @@ -0,0 +1,27 @@ +echo off + +set chain=%1 + +if not defined DevEnvDir ( + "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" %chain% +) + +mkdir build + +cmake -S . -B build\%chain% ^ +-DCMAKE_BUILD_TYPE=Release ^ +-DYUZU_USE_BUNDLED_QT=ON ^ +-DENABLE_QT_TRANSLATION=ON ^ +-DUSE_DISCORD_PRESENCE=ON ^ +-DYUZU_USE_BUNDLED_VCPKG=ON ^ +-DYUZU_USE_BUNDLED_SDL2=ON ^ +-G "Ninja" ^ +-DYUZU_TESTS=OFF ^ +-DCMAKE_C_COMPILER_LAUNCHER=ccache ^ +-DCMAKE_CXX_COMPILER_LAUNCHER=ccache ^ +-DCMAKE_TOOLCHAIN_FILE="%CD%\CMakeModules\MSVCCache.cmake" ^ +-DUSE_CCACHE=ON + +cmake --build build\%chain% + +ccache -s -v \ No newline at end of file diff --git a/.ci/windows/build.bat b/.ci/windows/build.bat new file mode 100755 index 0000000000..4dbe862a94 --- /dev/null +++ b/.ci/windows/build.bat @@ -0,0 +1,31 @@ +echo off + +set chain=%1 +set qt_ver=%2 + +if not defined DevEnvDir ( + CALL "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" %chain% +) + +CALL mkdir build + +CALL cmake -S . -B build\%chain% ^ +-DCMAKE_BUILD_TYPE=Release ^ +-DYUZU_USE_BUNDLED_QT=ON ^ +-DENABLE_QT_TRANSLATION=ON ^ +-DUSE_DISCORD_PRESENCE=ON ^ +-DYUZU_USE_BUNDLED_VCPKG=ON ^ +-DYUZU_USE_BUNDLED_SDL2=ON ^ +-G "Ninja" ^ +-DYUZU_TESTS=OFF ^ +-DUSE_BUNDLED_QT=OFF ^ +-DUSE_SYSTEM_QT=ON ^ +-DCMAKE_PREFIX_PATH=C:\Qt\%qt_ver%\msvc2022_64 ^ +-DCMAKE_C_COMPILER_LAUNCHER=ccache ^ +-DCMAKE_CXX_COMPILER_LAUNCHER=ccache ^ +-DCMAKE_TOOLCHAIN_FILE="%CD%\CMakeModules\MSVCCache.cmake" ^ +-DUSE_CCACHE=ON + +CALL cmake --build build\%chain% + +CALL ccache -s -v \ No newline at end of file diff --git a/.ci/windows/cygwin.bat b/.ci/windows/cygwin.bat new file mode 100755 index 0000000000..e772780fac --- /dev/null +++ b/.ci/windows/cygwin.bat @@ -0,0 +1,19 @@ +echo off + +call C:\tools\cygwin\cygwinsetup.exe -q -P autoconf,automake,libtool,make,pkg-config + +REM Create wrapper batch files for Cygwin tools in a directory that will be in PATH +REM uncomment this for first-run only +REM call mkdir C:\cygwin-wrappers + +REM Create autoconf.bat wrapper +call echo @echo off > C:\cygwin-wrappers\autoconf.bat +call echo C:\tools\cygwin\bin\bash.exe -l -c "autoconf %%*" >> C:\cygwin-wrappers\autoconf.bat + +REM Add other wrappers if needed for other Cygwin tools +call echo @echo off > C:\cygwin-wrappers\automake.bat +call echo C:\tools\cygwin\bin\bash.exe -l -c "automake %%*" >> C:\cygwin-wrappers\automake.bat + +REM Add the wrappers directory to PATH +call echo C:\cygwin-wrappers>>"%GITHUB_PATH%" +call echo C:\tools\cygwin\bin>>"%GITHUB_PATH%" diff --git a/.ci/install-vulkan-sdk.ps1 b/.ci/windows/install-vulkan-sdk.ps1 old mode 100644 new mode 100755 similarity index 100% rename from .ci/install-vulkan-sdk.ps1 rename to .ci/windows/install-vulkan-sdk.ps1 diff --git a/.ci/windows/package.ps1 b/.ci/windows/package.ps1 new file mode 100755 index 0000000000..de7fd051bb --- /dev/null +++ b/.ci/windows/package.ps1 @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: 2025 eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + +$target=$args[0] +$debug=$args[1] + +$GITDATE = $(git show -s --date=short --format='%ad') -replace "-", "" +$GITREV = $(git show -s --format='%h') +$RELEASE_DIST = "eden-windows-msvc" +$ARTIFACTS_DIR = "artifacts" + +New-Item -ItemType Directory -Path $ARTIFACTS_DIR -Force +New-Item -ItemType Directory -Path $RELEASE_DIST -Force + +if ($debug -eq "yes") { + mkdir -p pdb + $BUILD_PDB = "eden-windows-msvc-$GITDATE-$GITREV-debugsymbols.zip" + Get-ChildItem "build/$target/bin/" -Recurse -Filter "*.pdb" | Copy-Item -destination .\pdb -ErrorAction SilentlyContinue + + if (Test-Path -Path ".\pdb\*.pdb") { + 7z a -tzip $BUILD_PDB .\pdb\*.pdb + Move-Item $BUILD_PDB $ARTIFACTS_DIR/ -ErrorAction SilentlyContinue + } +} else { + Get-ChildItem "build/$target/bin/" -Recurse -Filter "*.pdb" | Remove-Item -Force -ErrorAction SilentlyContinue +} + +Copy-Item "build/$target/bin/Release/*" -Destination "$RELEASE_DIST" -Recurse -ErrorAction SilentlyContinue +if (-not $?) { + # Try without Release subfolder if that doesn't exist + Copy-Item "build/$target/bin/*" -Destination "$RELEASE_DIST" -Recurse -ErrorAction SilentlyContinue +} + + +$BUILD_ZIP = "eden-windows-msvc-$GITDATE-$GITREV.zip" + +7z a -tzip $BUILD_ZIP $RELEASE_DIST\* + +Move-Item $BUILD_ZIP $ARTIFACTS_DIR/ -Force #-ErrorAction SilentlyContinue +Copy-Item "LICENSE*" -Destination "$RELEASE_DIST" -ErrorAction SilentlyContinue +Copy-Item "README*" -Destination "$RELEASE_DIST" -ErrorAction SilentlyContinue diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0b7756cd2a..520e9562e7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,7 @@ on: pull_request: branches: [ master ] +# TODO: combine build.yml into trigger_release.yml jobs: source: if: ${{ !github.head_ref }} @@ -23,6 +24,7 @@ jobs: with: name: source.zip path: artifacts/ + windows: runs-on: windows strategy: @@ -42,6 +44,7 @@ jobs: with: submodules: recursive fetch-depth: 0 + fetch-tags: true - name: Set up vcpkg cache uses: actions/cache@v4 @@ -60,86 +63,23 @@ jobs: - name: Cygwin with autoconf # NEEDED FOR LIBUSB shell: cmd - run: | - C:\tools\cygwin\cygwinsetup.exe -q -P autoconf,automake,libtool,make,pkg-config + run: ./.ci/windows/cygwin.bat - REM Create wrapper batch files for Cygwin tools in a directory that will be in PATH - REM mkdir C:\cygwin-wrappers - - REM Create autoconf.bat wrapper - echo @echo off > C:\cygwin-wrappers\autoconf.bat - echo C:\tools\cygwin\bin\bash.exe -l -c "autoconf %%*" >> C:\cygwin-wrappers\autoconf.bat - - REM Add other wrappers if needed for other Cygwin tools - echo @echo off > C:\cygwin-wrappers\automake.bat - echo C:\tools\cygwin\bin\bash.exe -l -c "automake %%*" >> C:\cygwin-wrappers\automake.bat - - REM Add the wrappers directory to PATH - echo C:\cygwin-wrappers>>"%GITHUB_PATH%" - echo C:\tools\cygwin\bin>>"%GITHUB_PATH%" - - - name: CMake Configure + - name: Configure & Build id: cmake shell: cmd - run: | - mkdir build - cd build - cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_TOOLCHAIN_FILE="%CD%\..\CMakeModules\MSVCCache.cmake" -DYUZU_USE_BUNDLED_QT=ON -DENABLE_QT_TRANSLATION=ON -DUSE_DISCORD_PRESENCE=ON -DYUZU_USE_BUNDLED_VCPKG=ON -DYUZU_USE_BUNDLED_SDL2=ON -DUSE_CCACHE=ON - - - name: Build - id: build - shell: cmd - run: | - cd build - ninja yuzu yuzu-cmd yuzu-room tests - ccache -s -v + run: ./.ci/windows/build-bqt.bat amd64 yes - name: Package artifacts - if: steps.build.outcome == 'success' shell: powershell - run: | - $GITDATE = $(git show -s --date=short --format='%ad') -replace "-", "" - $GITREV = $(git show -s --format='%h') - $RELEASE_DIST = "eden-windows-msvc" - $ARTIFACTS_DIR = "${{ github.workspace }}/artifacts" - - mkdir -p $ARTIFACTS_DIR - mkdir -p $RELEASE_DIST - mkdir -p pdb - - Copy-Item "build/bin/Release/*" -Destination "$RELEASE_DIST" -Recurse -ErrorAction SilentlyContinue - if (-not $?) { - # Try without Release subfolder if that doesn't exist - Copy-Item "build/bin/*" -Destination "$RELEASE_DIST" -Recurse -ErrorAction SilentlyContinue - } - - Get-ChildItem "build/bin/" -Recurse -Filter "*.pdb" | Copy-Item -destination .\pdb -ErrorAction SilentlyContinue - - $BUILD_ZIP = "eden-windows-msvc-$GITDATE-$GITREV.zip" - $BUILD_PDB = "eden-windows-msvc-$GITDATE-$GITREV-debugsymbols.zip" - $BUILD_7Z = "eden-windows-msvc-$GITDATE-$GITREV.7z" - - 7z a -tzip $BUILD_ZIP $RELEASE_DIST\* - - if (Test-Path -Path ".\pdb\*.pdb") { - 7z a -tzip $BUILD_PDB .\pdb\*.pdb - Move-Item $BUILD_PDB $ARTIFACTS_DIR/ -ErrorAction SilentlyContinue - } - - 7z a $BUILD_7Z $RELEASE_DIST - - Move-Item $BUILD_ZIP $ARTIFACTS_DIR/ -ErrorAction SilentlyContinue - Move-Item $BUILD_7Z $ARTIFACTS_DIR/ -ErrorAction SilentlyContinue - - Copy-Item "LICENSE*" -Destination "$RELEASE_DIST" -ErrorAction SilentlyContinue - Copy-Item "README*" -Destination "$RELEASE_DIST" -ErrorAction SilentlyContinue + run: ./.ci/windows/package.ps1 amd64 yes - name: Upload Windows artifacts - if: steps.build.outcome == 'success' uses: forgejo/upload-artifact@v4 with: name: ${{ matrix.target }}.zip path: artifacts/* + linux: runs-on: linux env: @@ -152,16 +92,14 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - fetch-depth: 1 + fetch-depth: 0 fetch-tags: true - name: Build - run: | - ./.ci/linux.sh v3 8 + run: ./.ci/linux/build.sh v3 8 - name: Package AppImage - run: | - ./.ci/package-appimage.sh v3 &> /dev/null + run: ./.ci/linux/package.sh v3 &> /dev/null - name: Upload Linux artifacts uses: forgejo/upload-artifact@v4 @@ -184,6 +122,7 @@ jobs: with: submodules: recursive fetch-depth: 0 + fetch-tags: true - name: Set tag name run: | @@ -193,27 +132,10 @@ jobs: echo $GIT_TAG_NAME - name: Build - run: JAVA_HOME=$JAVA_HOME_21_X64 ./.ci/android.sh + run: JAVA_HOME=$JAVA_HOME_21_X64 ./.ci/android/build.sh - name: Package Android artifacts - run: | - GITDATE="$(git show -s --date=short --format='%ad' | sed 's/-//g')" - GITREV="$(git show -s --format='%h')" - ARTIFACTS_DIR="$PWD/artifacts" - mkdir -p "${ARTIFACTS_DIR}/" - - REV_NAME="eden-android-${GITDATE}-${GITREV}" - BUILD_FLAVOR="mainline" - BUILD_TYPE_LOWER="release" - BUILD_TYPE_UPPER="Release" - - cp src/android/app/build/outputs/apk/"${BUILD_FLAVOR}/${BUILD_TYPE_LOWER}/app-${BUILD_FLAVOR}-${BUILD_TYPE_LOWER}.apk" \ - "${ARTIFACTS_DIR}/${REV_NAME}.apk" || echo "APK not found" - - cp src/android/app/build/outputs/bundle/"${BUILD_FLAVOR}${BUILD_TYPE_UPPER}"/"app-${BUILD_FLAVOR}-${BUILD_TYPE_LOWER}.aab" \ - "${ARTIFACTS_DIR}/${REV_NAME}.aab" || echo "AAB not found" - - ls -la "${ARTIFACTS_DIR}/" + run: ./.ci/android/package.sh - name: Upload Android artifacts uses: forgejo/upload-artifact@v4 diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml index a248e14618..f388fcf6c6 100644 --- a/.github/workflows/trigger_release.yml +++ b/.github/workflows/trigger_release.yml @@ -41,6 +41,7 @@ jobs: with: submodules: recursive fetch-depth: 0 + fetch-tags: true - name: Set up vcpkg cache uses: actions/cache@v4 @@ -59,67 +60,18 @@ jobs: - name: Cygwin with autoconf # NEEDED FOR LIBUSB shell: cmd - run: | - C:\tools\cygwin\cygwinsetup.exe -q -P autoconf,automake,libtool,make,pkg-config + run: ./.ci/windows/cygwin.bat - REM Create wrapper batch files for Cygwin tools in a directory that will be in PATH - REM mkdir C:\cygwin-wrappers - - REM Create autoconf.bat wrapper - echo @echo off > C:\cygwin-wrappers\autoconf.bat - echo C:\tools\cygwin\bin\bash.exe -l -c "autoconf %%*" >> C:\cygwin-wrappers\autoconf.bat - - REM Add other wrappers if needed for other Cygwin tools - echo @echo off > C:\cygwin-wrappers\automake.bat - echo C:\tools\cygwin\bin\bash.exe -l -c "automake %%*" >> C:\cygwin-wrappers\automake.bat - - REM Add the wrappers directory to PATH - echo C:\cygwin-wrappers>>"%GITHUB_PATH%" - echo C:\tools\cygwin\bin>>"%GITHUB_PATH%" - - - name: CMake Configure + - name: Configure & Build id: cmake shell: cmd - run: | - mkdir build - cd build - cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_TOOLCHAIN_FILE="%CD%\..\CMakeModules\MSVCCache.cmake" -DYUZU_USE_BUNDLED_QT=ON -DENABLE_QT_TRANSLATION=ON -DUSE_DISCORD_PRESENCE=ON -DYUZU_USE_BUNDLED_VCPKG=ON -DYUZU_USE_BUNDLED_SDL2=ON -DUSE_CCACHE=ON - - - name: Build - id: build - shell: cmd - run: | - cd build - ninja yuzu yuzu-cmd yuzu-room tests - ccache -s -v + run: ./.ci/windows/build-bqt.bat amd64 no - name: Package artifacts - if: steps.build.outcome == 'success' shell: powershell - run: | - $GITDATE = $(git show -s --date=short --format='%ad') -replace "-", "" - $GITREV = $(git show -s --format='%h') - $RELEASE_DIST = "eden-windows-msvc" - $ARTIFACTS_DIR = "${{ github.workspace }}/artifacts" - - mkdir -p $ARTIFACTS_DIR - mkdir -p $RELEASE_DIST - - Copy-Item "build/bin/Release/*" -Destination "$RELEASE_DIST" -Recurse -ErrorAction SilentlyContinue - if (-not $?) { - # Try without Release subfolder if that doesn't exist - Copy-Item "build/bin/*" -Destination "$RELEASE_DIST" -Recurse -ErrorAction SilentlyContinue - } - - $BUILD_ZIP = "eden-windows-msvc-$GITDATE-$GITREV.zip" - 7z a -tzip $BUILD_ZIP $RELEASE_DIST\* - - Move-Item $BUILD_ZIP $ARTIFACTS_DIR/ -ErrorAction SilentlyContinue - Copy-Item "LICENSE*" -Destination "$RELEASE_DIST" -ErrorAction SilentlyContinue - Copy-Item "README*" -Destination "$RELEASE_DIST" -ErrorAction SilentlyContinue + run: ./.ci/windows/package.ps1 amd64 no - name: Upload Windows artifacts - if: steps.build.outcome == 'success' uses: forgejo/upload-artifact@v4 with: name: ${{ matrix.target }}.zip @@ -137,16 +89,14 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - fetch-depth: 1 + fetch-depth: 0 fetch-tags: true - name: Build - run: | - ./.ci/linux.sh v3 8 + run: ./.ci/linux/build.sh v3 8 - name: Package AppImage - run: | - ./.ci/package-appimage.sh v3 &> /dev/null + run: ./.ci/linux/package.sh v3 &> /dev/null - name: Upload Linux artifacts uses: forgejo/upload-artifact@v4 @@ -169,6 +119,7 @@ jobs: with: submodules: recursive fetch-depth: 0 + fetch-tags: true - name: Set tag name run: | @@ -178,27 +129,10 @@ jobs: echo $GIT_TAG_NAME - name: Build - run: JAVA_HOME=$JAVA_HOME_21_X64 ./.ci/android.sh + run: JAVA_HOME=$JAVA_HOME_21_X64 ./.ci/android/build.sh - name: Package Android artifacts - run: | - GITDATE="$(git show -s --date=short --format='%ad' | sed 's/-//g')" - GITREV="$(git show -s --format='%h')" - ARTIFACTS_DIR="$PWD/artifacts" - mkdir -p "${ARTIFACTS_DIR}/" - - REV_NAME="eden-android-${GITDATE}-${GITREV}" - BUILD_FLAVOR="mainline" - BUILD_TYPE_LOWER="release" - BUILD_TYPE_UPPER="Release" - - cp src/android/app/build/outputs/apk/"${BUILD_FLAVOR}/${BUILD_TYPE_LOWER}/app-${BUILD_FLAVOR}-${BUILD_TYPE_LOWER}.apk" \ - "${ARTIFACTS_DIR}/${REV_NAME}.apk" || echo "APK not found" - - cp src/android/app/build/outputs/bundle/"${BUILD_FLAVOR}${BUILD_TYPE_UPPER}"/"app-${BUILD_FLAVOR}-${BUILD_TYPE_LOWER}.aab" \ - "${ARTIFACTS_DIR}/${REV_NAME}.aab" || echo "AAB not found" - - ls -la "${ARTIFACTS_DIR}/" + run: ./.ci/android/package.sh - name: Upload Android artifacts uses: forgejo/upload-artifact@v4 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0e2705cf72..117a0e1265 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -62,7 +62,7 @@ if (MSVC) # Warnings /W4 - /WX + /WX- /we4062 # Enumerator 'identifier' in a switch of enum 'enumeration' is not handled /we4189 # 'identifier': local variable is initialized but not referenced diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 5d852fe92b..6dac1ef84e 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -664,7 +664,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_submitInlineKeyboardInput(JNIEnv* env void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmptyUserDirectory(JNIEnv* env, jobject instance) { - const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir); + const auto nand_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir); auto vfs_nand_dir = EmulationSession::GetInstance().System().GetFilesystem()->OpenDirectory( Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read); @@ -836,7 +836,7 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject j const auto user_id = manager.GetUser(static_cast(0)); ASSERT(user_id); - const auto nandDir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir); + const auto nandDir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir); auto vfsNandDir = system.GetFilesystem()->OpenDirectory(Common::FS::PathToUTF8String(nandDir), FileSys::OpenMode::Read); diff --git a/src/android/app/src/main/jni/native_input.cpp b/src/android/app/src/main/jni/native_input.cpp index 4935a46070..5b69826c75 100644 --- a/src/android/app/src/main/jni/native_input.cpp +++ b/src/android/app/src/main/jni/native_input.cpp @@ -44,7 +44,7 @@ bool IsProfileNameValid(std::string_view profile_name) { } bool ProfileExistsInFilesystem(std::string_view profile_name) { - return Common::FS::Exists(Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir) / "input" / + return Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir) / "input" / fmt::format("{}.ini", profile_name)); } @@ -304,7 +304,7 @@ void Java_org_yuzu_yuzu_1emu_features_input_NativeInput_loadInputProfiles(JNIEnv jobject j_obj) { map_profiles.clear(); const auto input_profile_loc = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir) / "input"; + Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir) / "input"; if (Common::FS::IsDir(input_profile_loc)) { Common::FS::IterateDirEntries( diff --git a/src/common/fs/fs_paths.h b/src/common/fs/fs_paths.h index 5b9579ac29..c1e05577ff 100644 --- a/src/common/fs/fs_paths.h +++ b/src/common/fs/fs_paths.h @@ -1,11 +1,14 @@ // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #pragma once // yuzu data directories -#define YUZU_DIR "yuzu" +#define EDEN_DIR "eden" #define PORTABLE_DIR "user" // Sub-directories contained within a yuzu data directory @@ -25,6 +28,10 @@ #define SHADER_DIR "shader" #define TAS_DIR "tas" #define ICONS_DIR "icons" +#define CITRON_DIR "citron" +#define SUDACHI_DIR "sudachi" +#define YUZU_DIR "yuzu" +#define SUYU_DIR "suyu" // yuzu-specific files diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp index 4f69db6f5c..296ef69b30 100644 --- a/src/common/fs/path_util.cpp +++ b/src/common/fs/path_util.cpp @@ -1,7 +1,11 @@ // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #include +#include #include #include @@ -56,10 +60,10 @@ namespace fs = std::filesystem; /** * The PathManagerImpl is a singleton allowing to manage the mapping of - * YuzuPath enums to real filesystem paths. - * This class provides 2 functions: GetYuzuPathImpl and SetYuzuPathImpl. - * These are used by GetYuzuPath and SetYuzuPath respectively to get or modify - * the path mapped by the YuzuPath enum. + * EdenPath enums to real filesystem paths. + * This class provides 2 functions: GetEdenPathImpl and SetEdenPathImpl. + * These are used by GetEdenPath and SetEdenPath respectively to get or modify + * the path mapped by the EdenPath enum. */ class PathManagerImpl { public: @@ -75,62 +79,99 @@ public: PathManagerImpl(PathManagerImpl&&) = delete; PathManagerImpl& operator=(PathManagerImpl&&) = delete; - [[nodiscard]] const fs::path& GetYuzuPathImpl(YuzuPath yuzu_path) { - return yuzu_paths.at(yuzu_path); + [[nodiscard]] const fs::path& GetEdenPathImpl(EdenPath eden_path) { + return eden_paths.at(eden_path); } - void SetYuzuPathImpl(YuzuPath yuzu_path, const fs::path& new_path) { - yuzu_paths.insert_or_assign(yuzu_path, new_path); + [[nodiscard]] const fs::path& GetLegacyPathImpl(LegacyPath legacy_path) { + return legacy_paths.at(legacy_path); } - void Reinitialize(fs::path yuzu_path = {}) { - fs::path yuzu_path_cache; - fs::path yuzu_path_config; + void CreateEdenPaths() { + std::for_each(eden_paths.begin(), eden_paths.end(), [](auto &path) { + void(FS::CreateDir(path.second)); + }); + } + + void SetEdenPathImpl(EdenPath eden_path, const fs::path& new_path) { + eden_paths.insert_or_assign(eden_path, new_path); + } + + void SetLegacyPathImpl(LegacyPath legacy_path, const fs::path& new_path) { + legacy_paths.insert_or_assign(legacy_path, new_path); + } + + void Reinitialize(fs::path eden_path = {}) { + fs::path eden_path_cache; + fs::path eden_path_config; #ifdef _WIN32 #ifdef YUZU_ENABLE_PORTABLE - yuzu_path = GetExeDirectory() / PORTABLE_DIR; + eden_path = GetExeDirectory() / PORTABLE_DIR; #endif - if (!IsDir(yuzu_path)) { - yuzu_path = GetAppDataRoamingDirectory() / YUZU_DIR; + if (!IsDir(eden_path)) { + eden_path = GetAppDataRoamingDirectory() / EDEN_DIR; } - yuzu_path_cache = yuzu_path / CACHE_DIR; - yuzu_path_config = yuzu_path / CONFIG_DIR; + eden_path_cache = eden_path / CACHE_DIR; + eden_path_config = eden_path / CONFIG_DIR; + +#define LEGACY_PATH(titleName, upperName) GenerateLegacyPath(LegacyPath::titleName##Dir, GetAppDataRoamingDirectory() / upperName##_DIR); \ + GenerateLegacyPath(LegacyPath::titleName##ConfigDir, GetAppDataRoamingDirectory() / upperName##_DIR / CONFIG_DIR); \ + GenerateLegacyPath(LegacyPath::titleName##CacheDir, GetAppDataRoamingDirectory() / upperName##_DIR / CACHE_DIR); + + LEGACY_PATH(Citron, CITRON) + LEGACY_PATH(Sudachi, SUDACHI) + LEGACY_PATH(Yuzu, YUZU) + LEGACY_PATH(Suyu, SUYU) +#undef LEGACY_PATH + #elif ANDROID - ASSERT(!yuzu_path.empty()); - yuzu_path_cache = yuzu_path / CACHE_DIR; - yuzu_path_config = yuzu_path / CONFIG_DIR; + ASSERT(!eden_path.empty()); + eden_path_cache = eden_path / CACHE_DIR; + eden_path_config = eden_path / CONFIG_DIR; #else #ifdef YUZU_ENABLE_PORTABLE - yuzu_path = GetCurrentDir() / PORTABLE_DIR; + eden_path = GetCurrentDir() / PORTABLE_DIR; #endif - if (Exists(yuzu_path) && IsDir(yuzu_path)) { - yuzu_path_cache = yuzu_path / CACHE_DIR; - yuzu_path_config = yuzu_path / CONFIG_DIR; + if (Exists(eden_path) && IsDir(eden_path)) { + eden_path_cache = eden_path / CACHE_DIR; + eden_path_config = eden_path / CONFIG_DIR; } else { - yuzu_path = GetDataDirectory("XDG_DATA_HOME") / YUZU_DIR; - yuzu_path_cache = GetDataDirectory("XDG_CACHE_HOME") / YUZU_DIR; - yuzu_path_config = GetDataDirectory("XDG_CONFIG_HOME") / YUZU_DIR; + eden_path = GetDataDirectory("XDG_DATA_HOME") / EDEN_DIR; + eden_path_cache = GetDataDirectory("XDG_CACHE_HOME") / EDEN_DIR; + eden_path_config = GetDataDirectory("XDG_CONFIG_HOME") / EDEN_DIR; } + +#define LEGACY_PATH(titleName, upperName) GenerateLegacyPath(LegacyPath::titleName##Dir, GetDataDirectory("XDG_DATA_HOME") / upperName##_DIR); \ + GenerateLegacyPath(LegacyPath::titleName##ConfigDir, GetDataDirectory("XDG_CONFIG_HOME") / upperName##_DIR); \ + GenerateLegacyPath(LegacyPath::titleName##CacheDir, GetDataDirectory("XDG_CACHE_HOME") / upperName##_DIR); + + LEGACY_PATH(Citron, CITRON) + LEGACY_PATH(Sudachi, SUDACHI) + LEGACY_PATH(Yuzu, YUZU) + LEGACY_PATH(Suyu, SUYU) + +#undef LEGACY_PATH + #endif - GenerateYuzuPath(YuzuPath::YuzuDir, yuzu_path); - GenerateYuzuPath(YuzuPath::AmiiboDir, yuzu_path / AMIIBO_DIR); - GenerateYuzuPath(YuzuPath::CacheDir, yuzu_path_cache); - GenerateYuzuPath(YuzuPath::ConfigDir, yuzu_path_config); - GenerateYuzuPath(YuzuPath::CrashDumpsDir, yuzu_path / CRASH_DUMPS_DIR); - GenerateYuzuPath(YuzuPath::DumpDir, yuzu_path / DUMP_DIR); - GenerateYuzuPath(YuzuPath::KeysDir, yuzu_path / KEYS_DIR); - GenerateYuzuPath(YuzuPath::LoadDir, yuzu_path / LOAD_DIR); - GenerateYuzuPath(YuzuPath::LogDir, yuzu_path / LOG_DIR); - GenerateYuzuPath(YuzuPath::NANDDir, yuzu_path / NAND_DIR); - GenerateYuzuPath(YuzuPath::PlayTimeDir, yuzu_path / PLAY_TIME_DIR); - GenerateYuzuPath(YuzuPath::ScreenshotsDir, yuzu_path / SCREENSHOTS_DIR); - GenerateYuzuPath(YuzuPath::SDMCDir, yuzu_path / SDMC_DIR); - GenerateYuzuPath(YuzuPath::ShaderDir, yuzu_path / SHADER_DIR); - GenerateYuzuPath(YuzuPath::TASDir, yuzu_path / TAS_DIR); - GenerateYuzuPath(YuzuPath::IconsDir, yuzu_path / ICONS_DIR); + GenerateEdenPath(EdenPath::EdenDir, eden_path); + GenerateEdenPath(EdenPath::AmiiboDir, eden_path / AMIIBO_DIR); + GenerateEdenPath(EdenPath::CacheDir, eden_path_cache); + GenerateEdenPath(EdenPath::ConfigDir, eden_path_config); + GenerateEdenPath(EdenPath::CrashDumpsDir, eden_path / CRASH_DUMPS_DIR); + GenerateEdenPath(EdenPath::DumpDir, eden_path / DUMP_DIR); + GenerateEdenPath(EdenPath::KeysDir, eden_path / KEYS_DIR); + GenerateEdenPath(EdenPath::LoadDir, eden_path / LOAD_DIR); + GenerateEdenPath(EdenPath::LogDir, eden_path / LOG_DIR); + GenerateEdenPath(EdenPath::NANDDir, eden_path / NAND_DIR); + GenerateEdenPath(EdenPath::PlayTimeDir, eden_path / PLAY_TIME_DIR); + GenerateEdenPath(EdenPath::ScreenshotsDir, eden_path / SCREENSHOTS_DIR); + GenerateEdenPath(EdenPath::SDMCDir, eden_path / SDMC_DIR); + GenerateEdenPath(EdenPath::ShaderDir, eden_path / SHADER_DIR); + GenerateEdenPath(EdenPath::TASDir, eden_path / TAS_DIR); + GenerateEdenPath(EdenPath::IconsDir, eden_path / ICONS_DIR); } private: @@ -140,13 +181,17 @@ private: ~PathManagerImpl() = default; - void GenerateYuzuPath(YuzuPath yuzu_path, const fs::path& new_path) { - void(FS::CreateDir(new_path)); - - SetYuzuPathImpl(yuzu_path, new_path); + void GenerateEdenPath(EdenPath eden_path, const fs::path& new_path) { + // Defer path creation + SetEdenPathImpl(eden_path, new_path); } - std::unordered_map yuzu_paths; + void GenerateLegacyPath(LegacyPath legacy_path, const fs::path& new_path) { + SetLegacyPathImpl(legacy_path, new_path); + } + + std::unordered_map eden_paths; + std::unordered_map legacy_paths; }; bool ValidatePath(const fs::path& path) { @@ -230,22 +275,35 @@ void SetAppDirectory(const std::string& app_directory) { PathManagerImpl::GetInstance().Reinitialize(app_directory); } -const fs::path& GetYuzuPath(YuzuPath yuzu_path) { - return PathManagerImpl::GetInstance().GetYuzuPathImpl(yuzu_path); +const fs::path& GetEdenPath(EdenPath eden_path) { + return PathManagerImpl::GetInstance().GetEdenPathImpl(eden_path); } -std::string GetYuzuPathString(YuzuPath yuzu_path) { - return PathToUTF8String(GetYuzuPath(yuzu_path)); +const std::filesystem::path& GetLegacyPath(LegacyPath legacy_path) { + return PathManagerImpl::GetInstance().GetLegacyPathImpl(legacy_path); } -void SetYuzuPath(YuzuPath yuzu_path, const fs::path& new_path) { +std::string GetEdenPathString(EdenPath eden_path) { + return PathToUTF8String(GetEdenPath(eden_path)); +} + +std::string GetLegacyPathString(LegacyPath legacy_path) { + return PathToUTF8String(GetLegacyPath(legacy_path)); +} + +void SetEdenPath(EdenPath eden_path, const fs::path& new_path) { if (!FS::IsDir(new_path)) { LOG_ERROR(Common_Filesystem, "Filesystem object at new_path={} is not a directory", PathToUTF8String(new_path)); return; } - PathManagerImpl::GetInstance().SetYuzuPathImpl(yuzu_path, new_path); + PathManagerImpl::GetInstance().SetEdenPathImpl(eden_path, new_path); +} + +void CreateEdenPaths() +{ + PathManagerImpl::GetInstance().CreateEdenPaths(); } #ifdef _WIN32 diff --git a/src/common/fs/path_util.h b/src/common/fs/path_util.h index 59301e7edd..1dd95391f7 100644 --- a/src/common/fs/path_util.h +++ b/src/common/fs/path_util.h @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #pragma once #include @@ -10,8 +13,8 @@ namespace Common::FS { -enum class YuzuPath { - YuzuDir, // Where yuzu stores its data. +enum class EdenPath { + EdenDir, // Where yuzu stores its data. AmiiboDir, // Where Amiibo backups are stored. CacheDir, // Where cached filesystem data is stored. ConfigDir, // Where config files are stored. @@ -29,6 +32,24 @@ enum class YuzuPath { IconsDir, // Where Icons for Windows shortcuts are stored. }; +enum LegacyPath { + CitronDir, // Citron Directories for migration + CitronConfigDir, + CitronCacheDir, + + SudachiDir, // Sudachi Directories for migration + SudachiConfigDir, + SudachiCacheDir, + + YuzuDir, // Yuzu Directories for migration + YuzuConfigDir, + YuzuCacheDir, + + SuyuDir, // Suyu Directories for migration + SuyuConfigDir, + SuyuCacheDir, +}; + /** * Validates a given path. * @@ -193,39 +214,62 @@ template void SetAppDirectory(const std::string& app_directory); /** - * Gets the filesystem path associated with the YuzuPath enum. + * Gets the filesystem path associated with the EdenPath enum. * - * @param yuzu_path YuzuPath enum + * @param eden_path EdenPath enum * - * @returns The filesystem path associated with the YuzuPath enum. + * @returns The filesystem path associated with the EdenPath enum. */ -[[nodiscard]] const std::filesystem::path& GetYuzuPath(YuzuPath yuzu_path); +[[nodiscard]] const std::filesystem::path& GetEdenPath(EdenPath eden_path); /** - * Gets the filesystem path associated with the YuzuPath enum as a UTF-8 encoded std::string. + * Gets the filesystem path associated with the LegacyPath enum. * - * @param yuzu_path YuzuPath enum + * @param legacy_path LegacyPath enum * - * @returns The filesystem path associated with the YuzuPath enum as a UTF-8 encoded std::string. + * @returns The filesystem path associated with the LegacyPath enum. */ -[[nodiscard]] std::string GetYuzuPathString(YuzuPath yuzu_path); +[[nodiscard]] const std::filesystem::path& GetLegacyPath(LegacyPath legacy_path); /** - * Sets a new filesystem path associated with the YuzuPath enum. + * Gets the filesystem path associated with the EdenPath enum as a UTF-8 encoded std::string. + * + * @param eden_path EdenPath enum + * + * @returns The filesystem path associated with the EdenPath enum as a UTF-8 encoded std::string. + */ +[[nodiscard]] std::string GetEdenPathString(EdenPath eden_path); + +/** + * Gets the filesystem path associated with the LegacyPath enum as a UTF-8 encoded std::string. + * + * @param legacy_path LegacyPath enum + * + * @returns The filesystem path associated with the LegacyPath enum as a UTF-8 encoded std::string. + */ +[[nodiscard]] std::string GetLegacyPathString(LegacyPath legacy_path); + +/** + * Sets a new filesystem path associated with the EdenPath enum. * If the filesystem object at new_path is not a directory, this function will not do anything. * - * @param yuzu_path YuzuPath enum + * @param eden_path EdenPath enum * @param new_path New filesystem path */ -void SetYuzuPath(YuzuPath yuzu_path, const std::filesystem::path& new_path); +void SetEdenPath(EdenPath eden_path, const std::filesystem::path& new_path); + +/** + * Creates all necessary Eden paths in the filesystem. + */ +void CreateEdenPaths(); #ifdef _WIN32 template -void SetYuzuPath(YuzuPath yuzu_path, const Path& new_path) { +void SetEdenPath(EdenPath eden_path, const Path& new_path) { if constexpr (IsChar) { - SetYuzuPath(yuzu_path, ToU8String(new_path)); + SetEdenPath(eden_path, ToU8String(new_path)); } else { - SetYuzuPath(yuzu_path, std::filesystem::path{new_path}); + SetEdenPath(eden_path, std::filesystem::path{new_path}); } } #endif diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 3b400c6566..e5bf6b723a 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -200,7 +200,7 @@ public: return; } using namespace Common::FS; - const auto& log_dir = GetYuzuPath(YuzuPath::LogDir); + const auto& log_dir = GetEdenPath(EdenPath::LogDir); void(CreateDir(log_dir)); Filter filter; filter.ParseFilterString(Settings::values.log_filter.GetValue()); diff --git a/src/common/nvidia_flags.cpp b/src/common/nvidia_flags.cpp index 5e44c0c6ca..baca31b0ac 100644 --- a/src/common/nvidia_flags.cpp +++ b/src/common/nvidia_flags.cpp @@ -14,7 +14,7 @@ namespace Common { void ConfigureNvidiaEnvironmentFlags() { #ifdef _WIN32 const auto nvidia_shader_dir = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir) / "nvidia"; + Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir) / "nvidia"; if (!Common::FS::CreateDirs(nvidia_shader_dir)) { return; diff --git a/src/common/settings.cpp b/src/common/settings.cpp index ee7074b128..cb6431d536 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -131,11 +131,11 @@ void LogSettings() { log_setting(name, setting->Canonicalize()); } } - log_path("DataStorage_CacheDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir)); - log_path("DataStorage_ConfigDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir)); - log_path("DataStorage_LoadDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::LoadDir)); - log_path("DataStorage_NANDDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir)); - log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir)); + log_path("DataStorage_CacheDir", Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir)); + log_path("DataStorage_ConfigDir", Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir)); + log_path("DataStorage_LoadDir", Common::FS::GetEdenPath(Common::FS::EdenPath::LoadDir)); + log_path("DataStorage_NANDDir", Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir)); + log_path("DataStorage_SDMCDir", Common::FS::GetEdenPath(Common::FS::EdenPath::SDMCDir)); } void UpdateGPUAccuracy() { diff --git a/src/common/settings.h b/src/common/settings.h index 709ca03e7c..47dc65afa8 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -629,6 +629,7 @@ struct Values { Setting log_filter{linkage, "*:Info", "log_filter", Category::Miscellaneous}; Setting log_flush_lines{linkage, false, "flush_lines", Category::Miscellaneous}; Setting use_dev_keys{linkage, false, "use_dev_keys", Category::Miscellaneous}; + Setting first_launch{linkage, true, "first_launch", Category::Miscellaneous}; // Network Setting network_interface{linkage, std::string(), "network_interface", diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 43a3c5ffd6..74b1ca04b1 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -372,7 +372,7 @@ Key128 DeriveKeyblobMACKey(const Key128& keyblob_key, const Key128& mac_source) std::optional DeriveSDSeed() { const auto system_save_43_path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000043"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000043"; const Common::FS::IOFile save_43{system_save_43_path, Common::FS::FileAccessMode::Read, Common::FS::FileType::BinaryFile}; @@ -381,7 +381,7 @@ std::optional DeriveSDSeed() { } const auto sd_private_path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "Nintendo/Contents/private"; + Common::FS::GetEdenPath(Common::FS::EdenPath::SDMCDir) / "Nintendo/Contents/private"; const Common::FS::IOFile sd_private{sd_private_path, Common::FS::FileAccessMode::Read, Common::FS::FileType::BinaryFile}; @@ -640,7 +640,7 @@ KeyManager::KeyManager() { void KeyManager::ReloadKeys() { // Initialize keys - const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir); if (!Common::FS::CreateDir(yuzu_keys_dir)) { LOG_ERROR(Core, "Failed to create the keys directory."); @@ -847,7 +847,7 @@ Key256 KeyManager::GetBISKey(u8 partition_id) const { template void KeyManager::WriteKeyToFile(KeyCategory category, std::string_view keyname, const std::array& key) { - const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir); std::string filename = "title.keys_autogenerated"; @@ -947,7 +947,7 @@ void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) { } bool KeyManager::KeyFileExists(bool title) { - const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir); if (title) { return Common::FS::Exists(yuzu_keys_dir / "title.keys"); @@ -1197,7 +1197,7 @@ void KeyManager::PopulateTickets() { std::vector tickets; const auto system_save_e1_path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/80000000000000e1"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/80000000000000e1"; if (Common::FS::Exists(system_save_e1_path)) { const Common::FS::IOFile save_e1{system_save_e1_path, Common::FS::FileAccessMode::Read, Common::FS::FileType::BinaryFile}; @@ -1206,7 +1206,7 @@ void KeyManager::PopulateTickets() { } const auto system_save_e2_path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/80000000000000e2"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/80000000000000e2"; if (Common::FS::Exists(system_save_e2_path)) { const Common::FS::IOFile save_e2{system_save_e2_path, Common::FS::FileAccessMode::Read, Common::FS::FileType::BinaryFile}; diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp index 6326b70492..6facd03f6d 100644 --- a/src/core/file_sys/bis_factory.cpp +++ b/src/core/file_sys/bis_factory.cpp @@ -83,7 +83,7 @@ VirtualFile BISFactory::OpenPartitionStorage(BisPartitionId id, VirtualFilesystem file_system) const { auto& keys = Core::Crypto::KeyManager::Instance(); Core::Crypto::PartitionDataManager pdm{file_system->OpenDirectory( - Common::FS::GetYuzuPathString(Common::FS::YuzuPath::NANDDir), OpenMode::Read)}; + Common::FS::GetEdenPathString(Common::FS::EdenPath::NANDDir), OpenMode::Read)}; keys.PopulateFromPartitionData(pdm); switch (id) { diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 15649e7ccf..7e4001ef92 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -36,7 +36,7 @@ namespace Service::Account { constexpr std::size_t THUMBNAIL_SIZE = 0x24000; static std::filesystem::path GetImagePath(const Common::UUID& uuid) { - return Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / + return Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormattedString()); } diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 39fed63f9d..55f544184b 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -377,7 +377,7 @@ bool ProfileManager::SetProfileBaseAndData(Common::UUID uuid, const ProfileBase& } void ProfileManager::ParseUserSaveFile() { - const auto save_path(FS::GetYuzuPath(FS::YuzuPath::NANDDir) / ACC_SAVE_AVATORS_BASE_PATH / + const auto save_path(FS::GetEdenPath(FS::EdenPath::NANDDir) / ACC_SAVE_AVATORS_BASE_PATH / "profiles.dat"); const FS::IOFile save(save_path, FS::FileAccessMode::Read, FS::FileType::BinaryFile); @@ -429,12 +429,12 @@ void ProfileManager::WriteUserSaveFile() { }; } - const auto raw_path(FS::GetYuzuPath(FS::YuzuPath::NANDDir) / "system/save/8000000000000010"); + const auto raw_path(FS::GetEdenPath(FS::EdenPath::NANDDir) / "system/save/8000000000000010"); if (FS::IsFile(raw_path) && !FS::RemoveFile(raw_path)) { return; } - const auto save_path(FS::GetYuzuPath(FS::YuzuPath::NANDDir) / ACC_SAVE_AVATORS_BASE_PATH / + const auto save_path(FS::GetEdenPath(FS::EdenPath::NANDDir) / ACC_SAVE_AVATORS_BASE_PATH / "profiles.dat"); if (!FS::CreateParentDirs(save_path)) { diff --git a/src/core/hle/service/am/frontend/applet_web_browser.cpp b/src/core/hle/service/am/frontend/applet_web_browser.cpp index 835c20c4e2..e35a1daa1e 100644 --- a/src/core/hle/service/am/frontend/applet_web_browser.cpp +++ b/src/core/hle/service/am/frontend/applet_web_browser.cpp @@ -155,7 +155,7 @@ void ExtractSharedFonts(Core::System& system) { "FontNintendoExtended2.ttf", }; - const auto fonts_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "fonts"; + const auto fonts_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "fonts"; for (std::size_t i = 0; i < NS::SHARED_FONTS.size(); ++i) { const auto font_file_path = fonts_dir / DECRYPTED_SHARED_FONTS[i]; @@ -415,7 +415,7 @@ void WebBrowser::InitializeOffline() { "system_data", }; - offline_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / + offline_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / fmt::format("offline_web_applet_{}/{:016X}", RESOURCE_TYPES[static_cast(document_kind) - 1], title_id); diff --git a/src/core/hle/service/am/process_creation.cpp b/src/core/hle/service/am/process_creation.cpp index 81a8fb0b44..b5e31353a2 100644 --- a/src/core/hle/service/am/process_creation.cpp +++ b/src/core/hle/service/am/process_creation.cpp @@ -106,7 +106,7 @@ std::unique_ptr CreateApplicationProcess(std::vector& out_control, out_control = nacp.GetRawBytes(); } else { out_control.resize(sizeof(FileSys::RawNACP)); - std::fill(out_control.begin(), out_control.end(), 0); + std::fill(out_control.begin(), out_control.end(), (u8) 0); } auto& storage = system.GetContentProviderUnion(); diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp index 7f0bc127f9..e636d90bc4 100644 --- a/src/core/hle/service/caps/caps_manager.cpp +++ b/src/core/hle/service/caps/caps_manager.cpp @@ -303,7 +303,7 @@ void AlbumManager::FindScreenshots() { album_files.clear(); // TODO: Swap this with a blocking operation. - const auto screenshots_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ScreenshotsDir); + const auto screenshots_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ScreenshotsDir); Common::FS::IterateDirEntries( screenshots_dir, [this](const std::filesystem::path& full_path) { @@ -438,7 +438,7 @@ static void PNGToMemory(void* context, void* data, int len) { Result AlbumManager::SaveImage(ApplicationAlbumEntry& out_entry, std::span image, u64 title_id, const AlbumFileDateTime& date) const { const auto screenshot_path = - Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir); + Common::FS::GetEdenPathString(Common::FS::EdenPath::ScreenshotsDir); const std::string formatted_date = fmt::format("{:04}-{:02}-{:02}_{:02}-{:02}-{:02}-{:03}", date.year, date.month, date.day, date.hour, date.minute, date.second, 0); diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index ae230afc0e..9d7de4242e 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -346,12 +346,12 @@ std::shared_ptr FileSystemController::OpenSaveDataController std::shared_ptr FileSystemController::CreateSaveDataFactory( ProgramId program_id) { - using YuzuPath = Common::FS::YuzuPath; + using EdenPath = Common::FS::EdenPath; const auto rw_mode = FileSys::OpenMode::ReadWrite; auto vfs = system.GetFilesystem(); const auto nand_directory = - vfs->OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::NANDDir), rw_mode); + vfs->OpenDirectory(Common::FS::GetEdenPathString(EdenPath::NANDDir), rw_mode); return std::make_shared(system, program_id, std::move(nand_directory)); } @@ -683,20 +683,20 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove sdmc_factory = nullptr; } - using YuzuPath = Common::FS::YuzuPath; - const auto sdmc_dir_path = Common::FS::GetYuzuPath(YuzuPath::SDMCDir); + using EdenPath = Common::FS::EdenPath; + const auto sdmc_dir_path = Common::FS::GetEdenPath(EdenPath::SDMCDir); const auto sdmc_load_dir_path = sdmc_dir_path / "atmosphere/contents"; const auto rw_mode = FileSys::OpenMode::ReadWrite; auto nand_directory = - vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::NANDDir), rw_mode); + vfs.OpenDirectory(Common::FS::GetEdenPathString(EdenPath::NANDDir), rw_mode); auto sd_directory = vfs.OpenDirectory(Common::FS::PathToUTF8String(sdmc_dir_path), rw_mode); - auto load_directory = vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::LoadDir), + auto load_directory = vfs.OpenDirectory(Common::FS::GetEdenPathString(EdenPath::LoadDir), FileSys::OpenMode::Read); auto sd_load_directory = vfs.OpenDirectory(Common::FS::PathToUTF8String(sdmc_load_dir_path), FileSys::OpenMode::Read); auto dump_directory = - vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::DumpDir), rw_mode); + vfs.OpenDirectory(Common::FS::GetEdenPathString(EdenPath::DumpDir), rw_mode); if (bis_factory == nullptr) { bis_factory = std::make_unique( diff --git a/src/core/hle/service/mii/mii_database_manager.cpp b/src/core/hle/service/mii/mii_database_manager.cpp index 0080b67051..a0291d4b55 100644 --- a/src/core/hle/service/mii/mii_database_manager.cpp +++ b/src/core/hle/service/mii/mii_database_manager.cpp @@ -22,9 +22,9 @@ DatabaseManager::DatabaseManager() {} Result DatabaseManager::MountSaveData() { if (!is_save_data_mounted) { system_save_dir = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000030"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000030"; if (is_test_db) { - system_save_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / + system_save_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000031"; } diff --git a/src/core/hle/service/nfc/common/amiibo_crypto.cpp b/src/core/hle/service/nfc/common/amiibo_crypto.cpp index 4274a92c9e..158fa8ed51 100644 --- a/src/core/hle/service/nfc/common/amiibo_crypto.cpp +++ b/src/core/hle/service/nfc/common/amiibo_crypto.cpp @@ -271,7 +271,7 @@ void Cipher(const DerivedKeys& keys, const NTAG215File& in_data, NTAG215File& ou } bool LoadKeys(InternalKey& locked_secret, InternalKey& unfixed_info) { - const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir); const Common::FS::IOFile keys_file{yuzu_keys_dir / "key_retail.bin", Common::FS::FileAccessMode::Read, @@ -295,7 +295,7 @@ bool LoadKeys(InternalKey& locked_secret, InternalKey& unfixed_info) { } bool IsKeyAvailable() { - const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir); return Common::FS::Exists(yuzu_keys_dir / "key_retail.bin"); } diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 96c45b1b51..30eab469a1 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -1261,7 +1261,7 @@ Result NfcDevice::BreakTag(NFP::BreakType break_type) { Result NfcDevice::HasBackup(const UniqueSerialNumber& uid, std::size_t uuid_size) const { ASSERT_MSG(uuid_size < sizeof(UniqueSerialNumber), "Invalid UUID size"); constexpr auto backup_dir = "backup"; - const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir); + const auto yuzu_amiibo_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::AmiiboDir); const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid.begin(), uid.begin() + uuid_size, "")); @@ -1282,7 +1282,7 @@ Result NfcDevice::ReadBackupData(const UniqueSerialNumber& uid, std::size_t uuid std::span data) const { ASSERT_MSG(uuid_size < sizeof(UniqueSerialNumber), "Invalid UUID size"); constexpr auto backup_dir = "backup"; - const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir); + const auto yuzu_amiibo_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::AmiiboDir); const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid.begin(), uid.begin() + uuid_size, "")); @@ -1313,7 +1313,7 @@ Result NfcDevice::WriteBackupData(const UniqueSerialNumber& uid, std::size_t uui std::span data) { ASSERT_MSG(uuid_size < sizeof(UniqueSerialNumber), "Invalid UUID size"); constexpr auto backup_dir = "backup"; - const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir); + const auto yuzu_amiibo_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::AmiiboDir); const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid.begin(), uid.begin() + uuid_size, "")); diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index c155f19695..f327432daa 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -1330,25 +1330,25 @@ Result ISystemSettingsServer::SetPanelCrcMode(s32 panel_crc_mode) { void ISystemSettingsServer::SetupSettings() { auto system_dir = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000050"; if (!LoadSettingsFile(system_dir, []() { return DefaultSystemSettings(); })) { ASSERT(false); } auto private_dir = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000052"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000052"; if (!LoadSettingsFile(private_dir, []() { return DefaultPrivateSettings(); })) { ASSERT(false); } auto device_dir = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000053"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000053"; if (!LoadSettingsFile(device_dir, []() { return DefaultDeviceSettings(); })) { ASSERT(false); } auto appln_dir = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000054"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000054"; if (!LoadSettingsFile(appln_dir, []() { return DefaultApplnSettings(); })) { ASSERT(false); } @@ -1356,25 +1356,25 @@ void ISystemSettingsServer::SetupSettings() { void ISystemSettingsServer::StoreSettings() { auto system_dir = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000050"; if (!StoreSettingsFile(system_dir, m_system_settings)) { LOG_ERROR(Service_SET, "Failed to store System settings"); } auto private_dir = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000052"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000052"; if (!StoreSettingsFile(private_dir, m_private_settings)) { LOG_ERROR(Service_SET, "Failed to store Private settings"); } auto device_dir = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000053"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000053"; if (!StoreSettingsFile(device_dir, m_device_settings)) { LOG_ERROR(Service_SET, "Failed to store Device settings"); } auto appln_dir = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000054"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000054"; if (!StoreSettingsFile(appln_dir, m_appln_settings)) { LOG_ERROR(Service_SET, "Failed to store ApplLn settings"); } diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index f538d83b16..4439611d2e 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -39,7 +39,7 @@ PerfStats::~PerfStats() { std::copy(perf_history.begin() + IgnoreFrames, perf_history.begin() + current_index, std::ostream_iterator(stream, "\n")); - const auto path = Common::FS::GetYuzuPath(Common::FS::YuzuPath::LogDir); + const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::LogDir); // %F Date format expanded is "%Y-%m-%d" const auto filename = fmt::format("{:%F-%H-%M}_{:016X}.csv", *std::localtime(&t), title_id); const auto filepath = path / filename; diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index f70350e739..4bac8142c3 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp @@ -27,7 +27,7 @@ namespace { std::filesystem::path GetPath(std::string_view type, u64 title_id, std::string_view timestamp) { - return Common::FS::GetYuzuPath(Common::FS::YuzuPath::LogDir) / type / + return Common::FS::GetEdenPath(Common::FS::EdenPath::LogDir) / type / fmt::format("{:016X}_{}.json", title_id, timestamp); } @@ -332,7 +332,7 @@ void Reporter::SaveErrorReport(u64 title_id, Result result, void Reporter::SaveFSAccessLog(std::string_view log_message) const { const auto access_log_path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "FsAccessLog.txt"; + Common::FS::GetEdenPath(Common::FS::EdenPath::SDMCDir) / "FsAccessLog.txt"; void(Common::FS::AppendStringToFile(access_log_path, Common::FS::FileType::TextFile, log_message)); @@ -352,7 +352,7 @@ void Reporter::SaveUserReport() const { void Reporter::ClearFSAccessLog() const { const auto access_log_path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "FsAccessLog.txt"; + Common::FS::GetEdenPath(Common::FS::EdenPath::SDMCDir) / "FsAccessLog.txt"; Common::FS::IOFile access_log_file{access_log_path, Common::FS::FileAccessMode::Write, Common::FS::FileType::TextFile}; diff --git a/src/frontend_common/config.cpp b/src/frontend_common/config.cpp index 326267e774..fa1383436e 100644 --- a/src/frontend_common/config.cpp +++ b/src/frontend_common/config.cpp @@ -25,7 +25,7 @@ Config::Config(const ConfigType config_type) : type(config_type), global{config_type == ConfigType::GlobalConfig} {} void Config::Initialize(const std::string& config_name) { - const std::filesystem::path fs_config_loc = FS::GetYuzuPath(FS::YuzuPath::ConfigDir); + const std::filesystem::path fs_config_loc = FS::GetEdenPath(FS::EdenPath::ConfigDir); const auto config_file = fmt::format("{}.ini", config_name); switch (type) { @@ -51,7 +51,7 @@ void Config::Initialize(const std::string& config_name) { void Config::Initialize(const std::optional config_path) { const std::filesystem::path default_sdl_config_path = - FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "sdl2-config.ini"; + FS::GetEdenPath(FS::EdenPath::ConfigDir) / "sdl2-config.ini"; config_loc = config_path.value_or(FS::PathToUTF8String(default_sdl_config_path)); void(FS::CreateParentDir(config_loc)); SetUpIni(); @@ -275,11 +275,11 @@ void Config::ReadCoreValues() { void Config::ReadDataStorageValues() { BeginGroup(Settings::TranslateCategory(Settings::Category::DataStorage)); - FS::SetYuzuPath(FS::YuzuPath::NANDDir, ReadStringSetting(std::string("nand_directory"))); - FS::SetYuzuPath(FS::YuzuPath::SDMCDir, ReadStringSetting(std::string("sdmc_directory"))); - FS::SetYuzuPath(FS::YuzuPath::LoadDir, ReadStringSetting(std::string("load_directory"))); - FS::SetYuzuPath(FS::YuzuPath::DumpDir, ReadStringSetting(std::string("dump_directory"))); - FS::SetYuzuPath(FS::YuzuPath::TASDir, ReadStringSetting(std::string("tas_directory"))); + FS::SetEdenPath(FS::EdenPath::NANDDir, ReadStringSetting(std::string("nand_directory"))); + FS::SetEdenPath(FS::EdenPath::SDMCDir, ReadStringSetting(std::string("sdmc_directory"))); + FS::SetEdenPath(FS::EdenPath::LoadDir, ReadStringSetting(std::string("load_directory"))); + FS::SetEdenPath(FS::EdenPath::DumpDir, ReadStringSetting(std::string("dump_directory"))); + FS::SetEdenPath(FS::EdenPath::TASDir, ReadStringSetting(std::string("tas_directory"))); ReadCategory(Settings::Category::DataStorage); @@ -372,7 +372,7 @@ void Config::ReadScreenshotValues() { BeginGroup(Settings::TranslateCategory(Settings::Category::Screenshots)); ReadCategory(Settings::Category::Screenshots); - FS::SetYuzuPath(FS::YuzuPath::ScreenshotsDir, + FS::SetEdenPath(FS::EdenPath::ScreenshotsDir, ReadStringSetting(std::string("screenshot_path"))); EndGroup(); @@ -578,16 +578,16 @@ void Config::SaveCoreValues() { void Config::SaveDataStorageValues() { BeginGroup(Settings::TranslateCategory(Settings::Category::DataStorage)); - WriteStringSetting(std::string("nand_directory"), FS::GetYuzuPathString(FS::YuzuPath::NANDDir), - std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::NANDDir))); - WriteStringSetting(std::string("sdmc_directory"), FS::GetYuzuPathString(FS::YuzuPath::SDMCDir), - std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::SDMCDir))); - WriteStringSetting(std::string("load_directory"), FS::GetYuzuPathString(FS::YuzuPath::LoadDir), - std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::LoadDir))); - WriteStringSetting(std::string("dump_directory"), FS::GetYuzuPathString(FS::YuzuPath::DumpDir), - std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::DumpDir))); - WriteStringSetting(std::string("tas_directory"), FS::GetYuzuPathString(FS::YuzuPath::TASDir), - std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::TASDir))); + WriteStringSetting(std::string("nand_directory"), FS::GetEdenPathString(FS::EdenPath::NANDDir), + std::make_optional(FS::GetEdenPathString(FS::EdenPath::NANDDir))); + WriteStringSetting(std::string("sdmc_directory"), FS::GetEdenPathString(FS::EdenPath::SDMCDir), + std::make_optional(FS::GetEdenPathString(FS::EdenPath::SDMCDir))); + WriteStringSetting(std::string("load_directory"), FS::GetEdenPathString(FS::EdenPath::LoadDir), + std::make_optional(FS::GetEdenPathString(FS::EdenPath::LoadDir))); + WriteStringSetting(std::string("dump_directory"), FS::GetEdenPathString(FS::EdenPath::DumpDir), + std::make_optional(FS::GetEdenPathString(FS::EdenPath::DumpDir))); + WriteStringSetting(std::string("tas_directory"), FS::GetEdenPathString(FS::EdenPath::TASDir), + std::make_optional(FS::GetEdenPathString(FS::EdenPath::TASDir))); WriteCategory(Settings::Category::DataStorage); @@ -681,7 +681,7 @@ void Config::SaveScreenshotValues() { BeginGroup(Settings::TranslateCategory(Settings::Category::Screenshots)); WriteStringSetting(std::string("screenshot_path"), - FS::GetYuzuPathString(FS::YuzuPath::ScreenshotsDir)); + FS::GetEdenPathString(FS::EdenPath::ScreenshotsDir)); WriteCategory(Settings::Category::Screenshots); EndGroup(); diff --git a/src/input_common/drivers/tas_input.cpp b/src/input_common/drivers/tas_input.cpp index 528d60b130..5a7f858f16 100644 --- a/src/input_common/drivers/tas_input.cpp +++ b/src/input_common/drivers/tas_input.cpp @@ -82,7 +82,7 @@ void Tas::LoadTasFile(size_t player_index, size_t file_index) { commands[player_index].clear(); std::string file = Common::FS::ReadStringFromFile( - Common::FS::GetYuzuPath(Common::FS::YuzuPath::TASDir) / + Common::FS::GetEdenPath(Common::FS::EdenPath::TASDir) / fmt::format("script{}-{}.txt", file_index, player_index + 1), Common::FS::FileType::BinaryFile); std::istringstream command_line(file); @@ -137,7 +137,7 @@ void Tas::WriteTasFile(std::u8string_view file_name) { WriteCommandAxis(line.l_axis), WriteCommandAxis(line.r_axis)); } - const auto tas_file_name = Common::FS::GetYuzuPath(Common::FS::YuzuPath::TASDir) / file_name; + const auto tas_file_name = Common::FS::GetEdenPath(Common::FS::EdenPath::TASDir) / file_name; const auto bytes_written = Common::FS::WriteStringToFile(tas_file_name, Common::FS::FileType::TextFile, output_text); if (bytes_written == output_text.size()) { diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp index 5d0bb9cc45..e476261e3e 100644 --- a/src/video_core/macro/macro.cpp +++ b/src/video_core/macro/macro.cpp @@ -28,7 +28,7 @@ MICROPROFILE_DEFINE(MacroHLE, "GPU", "Execute macro HLE", MP_RGB(128, 192, 192)) namespace Tegra { static void Dump(u64 hash, std::span code, bool decompiled = false) { - const auto base_dir{Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)}; + const auto base_dir{Common::FS::GetEdenPath(Common::FS::EdenPath::DumpDir)}; const auto macro_dir{base_dir / "macros"}; if (!Common::FS::CreateDir(base_dir) || !Common::FS::CreateDir(macro_dir)) { LOG_ERROR(Common_Filesystem, "Failed to create macro dump directories"); diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index c4bad6fca5..ba4e1ac210 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -260,7 +260,7 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading, if (title_id == 0) { return; } - const auto shader_dir{Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir)}; + const auto shader_dir{Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir)}; const auto base_dir{shader_dir / fmt::format("{:016x}", title_id)}; if (!Common::FS::CreateDir(shader_dir) || !Common::FS::CreateDir(base_dir)) { LOG_ERROR(Common_Filesystem, "Failed to create shader cache directories"); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index a7bba4eaba..62578cf306 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -472,7 +472,7 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading if (title_id == 0) { return; } - const auto shader_dir{Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir)}; + const auto shader_dir{Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir)}; const auto base_dir{shader_dir / fmt::format("{:016x}", title_id)}; if (!Common::FS::CreateDir(shader_dir) || !Common::FS::CreateDir(base_dir)) { LOG_ERROR(Common_Filesystem, "Failed to create pipeline cache directories"); diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp index 250fde96cc..baeb8b23a0 100644 --- a/src/video_core/shader_environment.cpp +++ b/src/video_core/shader_environment.cpp @@ -91,7 +91,7 @@ static std::string_view StageToPrefix(Shader::Stage stage) { static void DumpImpl(u64 pipeline_hash, u64 shader_hash, std::span code, [[maybe_unused]] u32 read_highest, [[maybe_unused]] u32 read_lowest, u32 initial_offset, Shader::Stage stage) { - const auto shader_dir{Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)}; + const auto shader_dir{Common::FS::GetEdenPath(Common::FS::EdenPath::DumpDir)}; const auto base_dir{shader_dir / "shaders"}; if (!Common::FS::CreateDir(shader_dir) || !Common::FS::CreateDir(base_dir)) { LOG_ERROR(Common_Filesystem, "Failed to create shader dump directories"); diff --git a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp index aae3d40b62..a185f0a52b 100644 --- a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp +++ b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp @@ -47,7 +47,7 @@ NsightAftermathTracker::NsightAftermathTracker() { LOG_ERROR(Render_Vulkan, "Failed to load Nsight Aftermath function pointers"); return; } - dump_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::LogDir) / "gpucrash"; + dump_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::LogDir) / "gpucrash"; Common::FS::RemoveDirRecursively(dump_dir); if (!Common::FS::CreateDir(dump_dir)) { diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 021b43daf0..ef2dd57044 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -232,6 +232,9 @@ add_executable(yuzu vk_device_info.h compatdb.cpp compatdb.h + user_data_migration.cpp + user_data_migration.h + yuzu.qrc yuzu.rc ) diff --git a/src/yuzu/applets/qt_profile_select.cpp b/src/yuzu/applets/qt_profile_select.cpp index 66edd6acde..59133b82dd 100644 --- a/src/yuzu/applets/qt_profile_select.cpp +++ b/src/yuzu/applets/qt_profile_select.cpp @@ -30,7 +30,7 @@ QString FormatUserEntryText(const QString& username, Common::UUID uuid) { QString GetImagePath(Common::UUID uuid) { const auto path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormattedString()); return QString::fromStdString(Common::FS::PathToUTF8String(path)); } diff --git a/src/yuzu/applets/qt_web_browser.cpp b/src/yuzu/applets/qt_web_browser.cpp index cce9b2efb2..8245c12ba2 100644 --- a/src/yuzu/applets/qt_web_browser.cpp +++ b/src/yuzu/applets/qt_web_browser.cpp @@ -57,7 +57,7 @@ QtNXWebEngineView::QtNXWebEngineView(QWidget* parent, Core::System& system, default_profile{QWebEngineProfile::defaultProfile()}, global_settings{ default_profile->settings()} { default_profile->setPersistentStoragePath(QString::fromStdString(Common::FS::PathToUTF8String( - Common::FS::GetYuzuPath(Common::FS::YuzuPath::YuzuDir) / "qtwebengine"))); + Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir) / "qtwebengine"))); QWebEngineScript gamepad; QWebEngineScript window_nx; @@ -336,7 +336,7 @@ void QtNXWebEngineView::LoadExtractedFonts() { QWebEngineScript load_nx_font; auto fonts_dir_str = Common::FS::PathToUTF8String( - Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "fonts/"); + Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "fonts/"); std::replace(fonts_dir_str.begin(), fonts_dir_str.end(), '\\', '/'); diff --git a/src/yuzu/breakpad.cpp b/src/yuzu/breakpad.cpp index 0f6a71ab08..82b5deb51e 100644 --- a/src/yuzu/breakpad.cpp +++ b/src/yuzu/breakpad.cpp @@ -60,7 +60,7 @@ static void PruneDumpDirectory(const std::filesystem::path& dump_path) { void InstallCrashHandler() { // Write crash dumps to profile directory. - const auto dump_path = GetYuzuPath(Common::FS::YuzuPath::CrashDumpsDir); + const auto dump_path = GetEdenPath(Common::FS::EdenPath::CrashDumpsDir); PruneDumpDirectory(dump_path); #if defined(_WIN32) diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 5f23eea3d3..bcb8d1fc5e 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -21,7 +21,7 @@ ConfigureDebug::ConfigureDebug(const Core::System& system_, QWidget* parent) connect(ui->open_log_button, &QPushButton::clicked, []() { const auto path = - QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::LogDir)); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LogDir)); QDesktopServices::openUrl(QUrl::fromLocalFile(path)); }); diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp index ad19517546..f25f14708b 100644 --- a/src/yuzu/configuration/configure_filesystem.cpp +++ b/src/yuzu/configuration/configure_filesystem.cpp @@ -47,15 +47,15 @@ void ConfigureFilesystem::changeEvent(QEvent* event) { void ConfigureFilesystem::SetConfiguration() { ui->nand_directory_edit->setText( - QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::NANDDir))); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::NANDDir))); ui->sdmc_directory_edit->setText( - QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::SDMCDir))); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir))); ui->gamecard_path_edit->setText( QString::fromStdString(Settings::values.gamecard_path.GetValue())); ui->dump_path_edit->setText( - QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::DumpDir))); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::DumpDir))); ui->load_path_edit->setText( - QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::LoadDir))); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LoadDir))); ui->gamecard_inserted->setChecked(Settings::values.gamecard_inserted.GetValue()); ui->gamecard_current_game->setChecked(Settings::values.gamecard_current_game.GetValue()); @@ -68,13 +68,13 @@ void ConfigureFilesystem::SetConfiguration() { } void ConfigureFilesystem::ApplyConfiguration() { - Common::FS::SetYuzuPath(Common::FS::YuzuPath::NANDDir, + Common::FS::SetEdenPath(Common::FS::EdenPath::NANDDir, ui->nand_directory_edit->text().toStdString()); - Common::FS::SetYuzuPath(Common::FS::YuzuPath::SDMCDir, + Common::FS::SetEdenPath(Common::FS::EdenPath::SDMCDir, ui->sdmc_directory_edit->text().toStdString()); - Common::FS::SetYuzuPath(Common::FS::YuzuPath::DumpDir, + Common::FS::SetEdenPath(Common::FS::EdenPath::DumpDir, ui->dump_path_edit->text().toStdString()); - Common::FS::SetYuzuPath(Common::FS::YuzuPath::LoadDir, + Common::FS::SetEdenPath(Common::FS::EdenPath::LoadDir, ui->load_path_edit->text().toStdString()); Settings::values.gamecard_inserted = ui->gamecard_inserted->isChecked(); @@ -126,12 +126,12 @@ void ConfigureFilesystem::SetDirectory(DirectoryTarget target, QLineEdit* edit) } void ConfigureFilesystem::ResetMetadata() { - if (!Common::FS::Exists(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / + if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list/")) { QMessageBox::information(this, tr("Reset Metadata Cache"), tr("The metadata cache is already empty.")); } else if (Common::FS::RemoveDirRecursively( - Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "game_list")) { + Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) { QMessageBox::information(this, tr("Reset Metadata Cache"), tr("The operation completed successfully.")); UISettings::values.is_game_list_reload_pending.exchange(true); diff --git a/src/yuzu/configuration/configure_per_game_addons.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp index 568775027b..078f2e8288 100644 --- a/src/yuzu/configuration/configure_per_game_addons.cpp +++ b/src/yuzu/configuration/configure_per_game_addons.cpp @@ -80,7 +80,7 @@ void ConfigurePerGameAddons::ApplyConfiguration() { std::sort(disabled_addons.begin(), disabled_addons.end()); std::sort(current.begin(), current.end()); if (disabled_addons != current) { - Common::FS::RemoveFile(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / + Common::FS::RemoveFile(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list" / fmt::format("{:016X}.pv.txt", title_id)); } diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp index 12a04b9a0b..bf3a96b211 100644 --- a/src/yuzu/configuration/configure_profile_manager.cpp +++ b/src/yuzu/configuration/configure_profile_manager.cpp @@ -35,7 +35,7 @@ constexpr std::array backup_jpeg{ QString GetImagePath(const Common::UUID& uuid) { const auto path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormattedString()); return QString::fromStdString(Common::FS::PathToUTF8String(path)); } @@ -288,7 +288,7 @@ void ConfigureProfileManager::SetUserImage() { } const auto raw_path = QString::fromStdString(Common::FS::PathToUTF8String( - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000010")); + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000010")); const QFileInfo raw_info{raw_path}; if (raw_info.exists() && !raw_info.isDir() && !QFile::remove(raw_path)) { QMessageBox::warning(this, tr("Error deleting file"), diff --git a/src/yuzu/configuration/configure_tas.cpp b/src/yuzu/configuration/configure_tas.cpp index 5a545aa706..773658bf22 100644 --- a/src/yuzu/configuration/configure_tas.cpp +++ b/src/yuzu/configuration/configure_tas.cpp @@ -28,14 +28,14 @@ ConfigureTasDialog::~ConfigureTasDialog() = default; void ConfigureTasDialog::LoadConfiguration() { ui->tas_path_edit->setText( - QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::TASDir))); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::TASDir))); ui->tas_enable->setChecked(Settings::values.tas_enable.GetValue()); ui->tas_loop_script->setChecked(Settings::values.tas_loop.GetValue()); ui->tas_pause_on_load->setChecked(Settings::values.pause_tas_on_load.GetValue()); } void ConfigureTasDialog::ApplyConfiguration() { - Common::FS::SetYuzuPath(Common::FS::YuzuPath::TASDir, ui->tas_path_edit->text().toStdString()); + Common::FS::SetEdenPath(Common::FS::EdenPath::TASDir, ui->tas_path_edit->text().toStdString()); Settings::values.tas_enable.SetValue(ui->tas_enable->isChecked()); Settings::values.tas_loop.SetValue(ui->tas_loop_script->isChecked()); Settings::values.pause_tas_on_load.SetValue(ui->tas_pause_on_load->isChecked()); diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp index a75a1b264e..8c3bbf1af4 100644 --- a/src/yuzu/configuration/configure_ui.cpp +++ b/src/yuzu/configuration/configure_ui.cpp @@ -144,8 +144,8 @@ ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent) connect(ui->screenshot_path_button, &QToolButton::pressed, this, [this] { auto dir = QFileDialog::getExistingDirectory(this, tr("Select Screenshots Path..."), - QString::fromStdString(Common::FS::GetYuzuPathString( - Common::FS::YuzuPath::ScreenshotsDir))); + QString::fromStdString(Common::FS::GetEdenPathString( + Common::FS::EdenPath::ScreenshotsDir))); if (!dir.isEmpty()) { if (dir.back() != QChar::fromLatin1('/')) { dir.append(QChar::fromLatin1('/')); @@ -176,7 +176,7 @@ void ConfigureUi::ApplyConfiguration() { UISettings::values.row_2_text_id = ui->row_2_text_combobox->currentData().toUInt(); UISettings::values.enable_screenshot_save_as = ui->enable_screenshot_save_as->isChecked(); - Common::FS::SetYuzuPath(Common::FS::YuzuPath::ScreenshotsDir, + Common::FS::SetEdenPath(Common::FS::EdenPath::ScreenshotsDir, ui->screenshot_path_edit->text().toStdString()); const u32 height = ScreenshotDimensionToInt(ui->screenshot_height->currentText()); @@ -208,7 +208,7 @@ void ConfigureUi::SetConfiguration() { ui->enable_screenshot_save_as->setChecked( UISettings::values.enable_screenshot_save_as.GetValue()); ui->screenshot_path_edit->setText(QString::fromStdString( - Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir))); + Common::FS::GetEdenPathString(Common::FS::EdenPath::ScreenshotsDir))); const auto height = UISettings::values.screenshot_height.GetValue(); if (height == 0) { diff --git a/src/yuzu/configuration/input_profiles.cpp b/src/yuzu/configuration/input_profiles.cpp index 0ff5e18c1c..df80be8252 100644 --- a/src/yuzu/configuration/input_profiles.cpp +++ b/src/yuzu/configuration/input_profiles.cpp @@ -14,7 +14,7 @@ namespace FS = Common::FS; namespace { bool ProfileExistsInFilesystem(std::string_view profile_name) { - return FS::Exists(FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "input" / + return FS::Exists(FS::GetEdenPath(FS::EdenPath::ConfigDir) / "input" / fmt::format("{}.ini", profile_name)); } @@ -29,7 +29,7 @@ std::filesystem::path GetNameWithoutExtension(std::filesystem::path filename) { } // namespace InputProfiles::InputProfiles() { - const auto input_profile_loc = FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "input"; + const auto input_profile_loc = FS::GetEdenPath(FS::EdenPath::ConfigDir) / "input"; if (!FS::IsDir(input_profile_loc)) { return; diff --git a/src/yuzu/configuration/qt_config.cpp b/src/yuzu/configuration/qt_config.cpp index 37951b9c84..ae5b330e23 100644 --- a/src/yuzu/configuration/qt_config.cpp +++ b/src/yuzu/configuration/qt_config.cpp @@ -46,6 +46,7 @@ const std::array QtConfig::default_ringcon_analogs{{ QtConfig::QtConfig(const std::string& config_name, const ConfigType config_type) : Config(config_type) { + Initialize(config_name); if (config_type != ConfigType::InputProfile) { ReadQtValues(); diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp index 0cbf5f45e8..4f977b87be 100644 --- a/src/yuzu/game_list_worker.cpp +++ b/src/yuzu/game_list_worker.cpp @@ -38,7 +38,7 @@ QString GetGameListCachedObject(const std::string& filename, const std::string& } const auto path = - Common::FS::PathToUTF8String(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / + Common::FS::PathToUTF8String(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list" / fmt::format("{}.{}", filename, ext)); void(Common::FS::CreateParentDirs(path)); @@ -70,7 +70,7 @@ std::pair, std::string> GetGameListCachedObject( } const auto game_list_dir = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "game_list"; + Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list"; const auto jpeg_name = fmt::format("{}.jpeg", filename); const auto app_name = fmt::format("{}.appname.txt", filename); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 7f52b8fbc4..8cd20a452d 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -211,7 +211,7 @@ static const QList bad_update_games{ const int GMainWindow::max_recent_files_item; static void RemoveCachedContents() { - const auto cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir); + const auto cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir); const auto offline_fonts = cache_dir / "fonts"; const auto offline_manual = cache_dir / "offline_web_applet_manual"; const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information"; @@ -301,15 +301,20 @@ bool GMainWindow::CheckDarkMode() { #endif // __unix__ } -GMainWindow::GMainWindow(std::unique_ptr config_, bool has_broken_vulkan) +GMainWindow::GMainWindow(bool has_broken_vulkan) : ui{std::make_unique()}, system{std::make_unique()}, - input_subsystem{std::make_shared()}, config{std::move(config_)}, + input_subsystem{std::make_shared()}, + user_data_migrator{this}, vfs{std::make_shared()}, provider{std::make_unique()} { + Common::FS::CreateEdenPaths(); + this->config = std::make_unique(); #ifdef __unix__ SetupSigInterrupts(); SetGamemodeEnabled(Settings::values.enable_gamemode.GetValue()); #endif + UISettings::RestoreWindowState(config); + system->Initialize(); Common::Log::Initialize(); @@ -2322,7 +2327,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target switch (target) { case GameListOpenTarget::SaveData: { open_target = tr("Save Data"); - const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir); + const auto nand_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir); auto vfs_nand_dir = vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read); @@ -2378,7 +2383,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target } case GameListOpenTarget::ModData: { open_target = tr("Mod Data"); - path = Common::FS::GetYuzuPath(Common::FS::YuzuPath::LoadDir) / + path = Common::FS::GetEdenPath(Common::FS::EdenPath::LoadDir) / fmt::format("{:016X}", program_id); break; } @@ -2400,7 +2405,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target } void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) { - const auto shader_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir); + const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir); const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)}; if (!Common::FS::CreateDirs(shader_cache_folder_path)) { QMessageBox::warning(this, tr("Error Opening Transferable Shader Cache"), @@ -2519,7 +2524,7 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT RemoveAddOnContent(program_id, type); break; } - Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / + Common::FS::RemoveDirRecursively(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list"); game_list->PopulateAsync(UISettings::values.game_dirs); } @@ -2625,7 +2630,7 @@ void GMainWindow::RemoveTransferableShaderCache(u64 program_id, GameListRemoveTa return ""; } }(); - const auto shader_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir); + const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir); const auto shader_cache_folder_path = shader_cache_dir / fmt::format("{:016x}", program_id); const auto target_file = shader_cache_folder_path / target_file_name; @@ -2646,7 +2651,7 @@ void GMainWindow::RemoveTransferableShaderCache(u64 program_id, GameListRemoveTa void GMainWindow::RemoveVulkanDriverPipelineCache(u64 program_id) { static constexpr std::string_view target_file_name = "vulkan_pipelines.bin"; - const auto shader_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir); + const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir); const auto shader_cache_folder_path = shader_cache_dir / fmt::format("{:016x}", program_id); const auto target_file = shader_cache_folder_path / target_file_name; @@ -2660,7 +2665,7 @@ void GMainWindow::RemoveVulkanDriverPipelineCache(u64 program_id) { } void GMainWindow::RemoveAllTransferableShaderCaches(u64 program_id) { - const auto shader_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir); + const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir); const auto program_shader_cache_dir = shader_cache_dir / fmt::format("{:016x}", program_id); if (!Common::FS::Exists(program_shader_cache_dir)) { @@ -2683,7 +2688,7 @@ void GMainWindow::RemoveCustomConfiguration(u64 program_id, const std::string& g program_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()).append(".ini") : fmt::format("{:016X}.ini", program_id); const auto custom_config_file_path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir) / "custom" / config_file_name; + Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir) / "custom" / config_file_name; if (!Common::FS::Exists(custom_config_file_path)) { QMessageBox::warning(this, tr("Error Removing Custom Configuration"), @@ -2701,7 +2706,7 @@ void GMainWindow::RemoveCustomConfiguration(u64 program_id, const std::string& g } void GMainWindow::RemoveCacheStorage(u64 program_id) { - const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir); + const auto nand_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir); auto vfs_nand_dir = vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read); @@ -2759,8 +2764,8 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa const auto base_romfs = base_nca->GetRomFS(); const auto dump_dir = target == DumpRomFSTarget::Normal - ? Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir) - : Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "atmosphere" / "contents"; + ? Common::FS::GetEdenPath(Common::FS::EdenPath::DumpDir) + : Common::FS::GetEdenPath(Common::FS::EdenPath::SDMCDir) / "atmosphere" / "contents"; const auto romfs_dir = fmt::format("{:016X}/romfs", title_id); const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir); @@ -3018,7 +3023,7 @@ bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_vi // Get path to Yuzu icons directory & icon extension std::string ico_extension = "png"; #if defined(_WIN32) - out_icon_path = Common::FS::GetYuzuPath(Common::FS::YuzuPath::IconsDir); + out_icon_path = Common::FS::GetEdenPath(Common::FS::EdenPath::IconsDir); ico_extension = "ico"; #elif defined(__linux__) || defined(__FreeBSD__) out_icon_path = Common::FS::GetDataDirectory("XDG_DATA_HOME") / "icons/hicolor/256x256"; @@ -3141,13 +3146,13 @@ void GMainWindow::OnGameListOpenDirectory(const QString& directory) { std::filesystem::path fs_path; if (directory == QStringLiteral("SDMC")) { fs_path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "Nintendo/Contents/registered"; + Common::FS::GetEdenPath(Common::FS::EdenPath::SDMCDir) / "Nintendo/Contents/registered"; } else if (directory == QStringLiteral("UserNAND")) { fs_path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "user/Contents/registered"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "user/Contents/registered"; } else if (directory == QStringLiteral("SysNAND")) { fs_path = - Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/Contents/registered"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/Contents/registered"; } else { fs_path = directory.toStdString(); } @@ -3373,7 +3378,7 @@ void GMainWindow::OnMenuInstallToNAND() { : tr("%n file(s) failed to install\n", "", failed_files.size())); QMessageBox::information(this, tr("Install Results"), install_results); - Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / + Common::FS::RemoveDirRecursively(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list"); game_list->PopulateAsync(UISettings::values.game_dirs); ui->action_Install_File_NAND->setEnabled(true); @@ -3791,11 +3796,11 @@ void GMainWindow::OnConfigure() { LOG_WARNING(Frontend, "Failed to remove configuration file"); } if (!Common::FS::RemoveDirContentsRecursively( - Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir) / "custom")) { + Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir) / "custom")) { LOG_WARNING(Frontend, "Failed to remove custom configuration files"); } if (!Common::FS::RemoveDirRecursively( - Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "game_list")) { + Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) { LOG_WARNING(Frontend, "Failed to remove game metadata cache files"); } @@ -4151,7 +4156,7 @@ void GMainWindow::LoadAmiibo(const QString& filename) { void GMainWindow::OnOpenYuzuFolder() { QDesktopServices::openUrl(QUrl::fromLocalFile( - QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::YuzuDir)))); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::EdenDir)))); } void GMainWindow::OnVerifyInstalledContents() { @@ -4366,7 +4371,7 @@ void GMainWindow::OnInstallDecryptionKeys() { return; } - const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir); for (auto key_file : source_key_files) { std::filesystem::path destination_key_file = yuzu_keys_dir / key_file.filename(); if (!std::filesystem::copy_file(key_file, destination_key_file, @@ -4542,7 +4547,7 @@ void GMainWindow::OnCaptureScreenshot() { const u64 title_id = system->GetApplicationProcessProgramID(); const auto screenshot_path = - QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir)); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::ScreenshotsDir)); const auto date = QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd_hh-mm-ss-zzz")); QString filename = QStringLiteral("%1/%2_%3.png") @@ -4570,7 +4575,7 @@ void GMainWindow::OnCaptureScreenshot() { // TODO: Written 2020-10-01: Remove per-game config migration code when it is irrelevant void GMainWindow::MigrateConfigFiles() { - const auto config_dir_fs_path = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir); + const auto config_dir_fs_path = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir); const QDir config_dir = QDir(QString::fromStdString(Common::FS::PathToUTF8String(config_dir_fs_path))); const QStringList config_dir_list = config_dir.entryList(QStringList(QStringLiteral("*.ini"))); @@ -5289,8 +5294,6 @@ static void SetHighDPIAttributes() { } int main(int argc, char* argv[]) { - std::unique_ptr config = std::make_unique(); - UISettings::RestoreWindowState(config); bool has_broken_vulkan = false; bool is_child = false; if (CheckEnvVars(&is_child)) { @@ -5315,7 +5318,7 @@ int main(int argc, char* argv[]) { Common::ConfigureNvidiaEnvironmentFlags(); // Init settings params - QCoreApplication::setOrganizationName(QStringLiteral("yuzu")); + QCoreApplication::setOrganizationName(QStringLiteral("eden")); QCoreApplication::setApplicationName(QStringLiteral("eden")); #ifdef _WIN32 @@ -5340,7 +5343,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.yuzu_emu.yuzu")); + QGuiApplication::setDesktopFileName(QStringLiteral("org.eden_emu.eden")); #endif SetHighDPIAttributes(); @@ -5374,7 +5377,7 @@ int main(int argc, char* argv[]) { // generating shaders setlocale(LC_ALL, "C"); - GMainWindow main_window{std::move(config), has_broken_vulkan}; + GMainWindow main_window{has_broken_vulkan}; // After settings have been loaded by GMainWindow, apply the filter main_window.show(); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index af01d94e3b..a6e3bbaa6c 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -18,6 +18,7 @@ #include "configuration/qt_config.h" #include "frontend_common/content_manager.h" #include "input_common/drivers/tas_input.h" +#include "user_data_migration.h" #include "yuzu/compatibility_list.h" #include "yuzu/hotkeys.h" #include "yuzu/util/controller_navigation.h" @@ -167,7 +168,7 @@ class GMainWindow : public QMainWindow { public: void filterBarSetChecked(bool state); void UpdateUITheme(); - explicit GMainWindow(std::unique_ptr config_, bool has_broken_vulkan); + explicit GMainWindow(bool has_broken_vulkan); ~GMainWindow() override; bool DropAction(QDropEvent* event); @@ -508,6 +509,7 @@ private: QSlider* volume_slider = nullptr; QTimer status_bar_update_timer; + UserDataMigrator user_data_migrator; std::unique_ptr config; // Whether emulation is currently running in yuzu. diff --git a/src/yuzu/play_time_manager.cpp b/src/yuzu/play_time_manager.cpp index 94c99274dd..2669e3a7ab 100644 --- a/src/yuzu/play_time_manager.cpp +++ b/src/yuzu/play_time_manager.cpp @@ -26,7 +26,7 @@ std::optional GetCurrentUserPlayTimePath( if (!uuid.has_value()) { return std::nullopt; } - return Common::FS::GetYuzuPath(Common::FS::YuzuPath::PlayTimeDir) / + return Common::FS::GetEdenPath(Common::FS::EdenPath::PlayTimeDir) / uuid->RawString().append(".bin"); } diff --git a/src/yuzu/uisettings.cpp b/src/yuzu/uisettings.cpp index 7bb7e95af5..02d6bc9006 100644 --- a/src/yuzu/uisettings.cpp +++ b/src/yuzu/uisettings.cpp @@ -57,7 +57,7 @@ u32 CalculateWidth(u32 height, Settings::AspectRatio ratio) { void SaveWindowState() { const auto window_state_config_loc = - FS::PathToUTF8String(FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "window_state.ini"); + FS::PathToUTF8String(FS::GetEdenPath(FS::EdenPath::ConfigDir) / "window_state.ini"); void(FS::CreateParentDir(window_state_config_loc)); QSettings config(QString::fromStdString(window_state_config_loc), QSettings::IniFormat); @@ -73,12 +73,12 @@ void SaveWindowState() { void RestoreWindowState(std::unique_ptr& qtConfig) { const auto window_state_config_loc = - FS::PathToUTF8String(FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "window_state.ini"); + FS::PathToUTF8String(FS::GetEdenPath(FS::EdenPath::ConfigDir) / "window_state.ini"); // Migrate window state from old location if (!FS::Exists(window_state_config_loc) && qtConfig->Exists("UI", "UILayout\\geometry")) { const auto config_loc = - FS::PathToUTF8String(FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "qt-config.ini"); + FS::PathToUTF8String(FS::GetEdenPath(FS::EdenPath::ConfigDir) / "qt-config.ini"); QSettings config(QString::fromStdString(config_loc), QSettings::IniFormat); config.beginGroup(QStringLiteral("UI")); diff --git a/src/yuzu/user_data_migration.cpp b/src/yuzu/user_data_migration.cpp new file mode 100644 index 0000000000..d890550222 --- /dev/null +++ b/src/yuzu/user_data_migration.cpp @@ -0,0 +1,168 @@ +// Copyright Citra Emulator Project / Azahar Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +// SPDX-FileCopyrightText: Copyright 2025 eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include +#include +#include +#include +#include "common/fs/path_util.h" +#include "user_data_migration.h" + +// Needs to be included at the end due to https://bugreports.qt.io/browse/QTBUG-73263 +#include +#include + +namespace fs = std::filesystem; + +UserDataMigrator::UserDataMigrator(QMainWindow* main_window) { + // NOTE: Logging is not initialized yet, do not produce logs here. + + // Check migration if config directory does not exist + // TODO: ProfileManager messes with us a bit here, and force-creates the /nand/system/save/8000000000000010/su/avators/profiles.dat + // file. Find a way to reorder operations and have it create after this guy runs. + if (!fs::is_directory(Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir))) { + ShowMigrationPrompt(main_window); + } +} + +void UserDataMigrator::ShowMigrationPrompt(QMainWindow* main_window) { + namespace fs = std::filesystem; + + const QString migration_prompt_message = + main_window->tr("Would you like to migrate your data for use in Eden?\n" + "Select the corresponding button to migrate data from that emulator.\n" + "(This may take a while; The old data will not be deleted)\n\n" + "Clearing shader cache is recommended for all users.\nDo not uncheck unless you know what you're doing."); + + bool any_found = false; + + QMessageBox migration_prompt; + migration_prompt.setWindowTitle(main_window->tr("Migration")); + migration_prompt.setIcon(QMessageBox::Information); + + QCheckBox *clear_shaders = new QCheckBox(&migration_prompt); + clear_shaders->setText(main_window->tr("Clear Shader Cache")); + clear_shaders->setChecked(true); + migration_prompt.setCheckBox(clear_shaders); + + // Reflection would make this code 10x better + // but for now... MACRO MADNESS!!!! + QMap found; + QMap legacyMap; + QMap buttonMap; + +#define EMU_MAP(name) const bool name##_found = fs::is_directory(Common::FS::GetLegacyPath(Common::FS::LegacyPath::name##Dir)); \ + legacyMap[main_window->tr(#name)] = LegacyEmu::name; \ + found[main_window->tr(#name)] = name##_found; \ + if (name##_found) any_found = true; + + EMU_MAP(Citron) + EMU_MAP(Sudachi) + EMU_MAP(Yuzu) + EMU_MAP(Suyu) + +#undef EMU_MAP + + if (any_found) { + QString promptText = main_window->tr("Eden has detected user data for the following emulators:"); + QMapIterator iter(found); + + while (iter.hasNext()) { + iter.next(); + if (!iter.value()) continue; + + buttonMap[iter.key()] = migration_prompt.addButton(iter.key(), QMessageBox::YesRole); + promptText.append(main_window->tr("\n- %1").arg(iter.key())); + } + + promptText.append(main_window->tr("\n\n")); + + migration_prompt.setText(promptText + migration_prompt_message); + migration_prompt.addButton(QMessageBox::No); + + migration_prompt.exec(); + + QMapIterator buttonIter(buttonMap); + + while (buttonIter.hasNext()) { + buttonIter.next(); + if (buttonIter.value() == migration_prompt.clickedButton()) { + MigrateUserData(main_window, legacyMap[iter.key()], clear_shaders->isChecked()); + return; + } + } + + // If we're here, the user chose not to migrate + ShowMigrationCancelledMessage(main_window); + } + + else // no other data was found + return; +} + +void UserDataMigrator::ShowMigrationCancelledMessage(QMainWindow* main_window) { + QMessageBox::information( + main_window, main_window->tr("Migration"), + main_window + ->tr("You can manually re-trigger this prompt by deleting the " + "new config directory:\n" + "%1") + .arg(QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::ConfigDir))), + QMessageBox::Ok); +} + +void UserDataMigrator::MigrateUserData(QMainWindow* main_window, + const LegacyEmu selected_legacy_emu, const bool clear_shader_cache) { + namespace fs = std::filesystem; + const auto copy_options = fs::copy_options::update_existing | fs::copy_options::recursive; + + std::string legacy_user_dir; + std::string legacy_config_dir; + std::string legacy_cache_dir; + +#define LEGACY_EMU(emu) case LegacyEmu::emu: \ + legacy_user_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##Dir).string(); \ + legacy_config_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##ConfigDir).string(); \ + legacy_cache_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##CacheDir).string(); \ + break; + + switch (selected_legacy_emu) { + LEGACY_EMU(Citron) + LEGACY_EMU(Sudachi) + LEGACY_EMU(Yuzu) + LEGACY_EMU(Suyu) + } + +#undef LEGACY_EMU + + fs::copy(legacy_user_dir, Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir), copy_options); + + if (fs::is_directory(legacy_config_dir)) { + fs::copy(legacy_config_dir, Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir), + copy_options); + } + if (fs::is_directory(legacy_cache_dir)) { + fs::copy(legacy_cache_dir, Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir), + copy_options); + } + + // Delete and re-create shader dir + if (clear_shader_cache) { + fs::remove_all(Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir)); + fs::create_directory(Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir)); + } + + QMessageBox::information( + main_window, main_window->tr("Migration"), + main_window + ->tr("Data was migrated successfully.\n\n" + "If you wish to clean up the files which were left in the old " + "data location, you can do so by deleting the following directory:\n" + "%1") + .arg(QString::fromStdString(legacy_user_dir)), + QMessageBox::Ok); +} diff --git a/src/yuzu/user_data_migration.h b/src/yuzu/user_data_migration.h new file mode 100644 index 0000000000..098f19280b --- /dev/null +++ b/src/yuzu/user_data_migration.h @@ -0,0 +1,27 @@ +// Copyright Citra Emulator Project / Azahar Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +// SPDX-FileCopyrightText: Copyright 2025 eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include + +class UserDataMigrator { +public: + UserDataMigrator(QMainWindow* main_window); + +private: + enum class LegacyEmu { + Citron, + Sudachi, + Yuzu, + Suyu, + }; + + void ShowMigrationPrompt(QMainWindow* main_window); + void ShowMigrationCancelledMessage(QMainWindow* main_window); + void MigrateUserData(QMainWindow* main_window, const LegacyEmu selected_legacy_emu, const bool clear_shader_cache); +};