Compare commits
140 Commits
vertex_spi
...
fs-fixes
Author | SHA1 | Date | |
---|---|---|---|
c02b0a0113 | |||
97cbcc6e49 | |||
9d6aa2db81 | |||
0675bd946c | |||
281f2926bb | |||
349ac6ac05 | |||
16571a96a2 | |||
a0e9836386 | |||
fb10d05f97 | |||
182bebf272 | |||
7626804a90 | |||
20496e8ca4 | |||
b4184a3c2b | |||
2251d96d4d | |||
c028a8c7c5 | |||
359f97be22 | |||
748f8a0658 | |||
a7611bb2d3 | |||
6f35a3bf37 | |||
58573dd7b3 | |||
11728d6772 | |||
a99be221b2 | |||
f656610a41 | |||
cfa1a7b91c | |||
52b1fc4889 | |||
01e2b6cdaa | |||
f75380fc93 | |||
18af49a0ca | |||
c7e64f6c7b | |||
0a40a513a6 | |||
a4dc6a55b7 | |||
7dce5be263 | |||
3f7d97da4c | |||
a11b4dd051 | |||
c78847b2b6 | |||
8faa7a6e02 | |||
acf4b4e5fb | |||
3a0ca63d91 | |||
1e96775203 | |||
6d27e8be8d | |||
c357a8b9b6 | |||
7ad982f123 | |||
dd3d24bfec | |||
489bbb98b2 | |||
5c9543e39d | |||
49085d400c | |||
8be9ea4f4a | |||
a71c288252 | |||
159809eb32 | |||
2a4f0ce8de | |||
4c8f1c83c8 | |||
98f6d697d8 | |||
4636735783 | |||
8a2770bf83 | |||
f1e09c1ea1 | |||
2423e645f1 | |||
0eaae31f9f | |||
4f9b545296 | |||
628d70e112 | |||
9991b9b12b | |||
e4bcf73c5a | |||
b693d205e4 | |||
91621ec202 | |||
948f72d320 | |||
8c5b417486 | |||
51685ee2db | |||
079e4aa205 | |||
48edfb891b | |||
915406354c | |||
6f3fc32a93 | |||
ebfa98d31d | |||
3095ee91a8 | |||
fadeecfe6d | |||
2a1598036e | |||
58f01112c5 | |||
7e7b3dc18c | |||
d4a3f60575 | |||
f8cbf783cb | |||
dc0cddb7de | |||
9cef9d4c58 | |||
dada05801f | |||
9bc71a3307 | |||
98274273b1 | |||
269db2bfb8 | |||
d27c1c8606 | |||
891b4bff18 | |||
eeccdc02fc | |||
29ee94c3f5 | |||
8936641841 | |||
e1f6b88e7b | |||
64d809f06a | |||
ebd23026a0 | |||
6e1bfe9949 | |||
854092ce4f | |||
90d24caaf8 | |||
65400936c7 | |||
3f9e5a2b42 | |||
34ba320c3d | |||
ec9f1902f5 | |||
c72a365d78 | |||
8f211613a3 | |||
30885b72be | |||
beb078a71b | |||
a65f9ea5a8 | |||
f9c11eab96 | |||
794f6e4a67 | |||
c85731f3ae | |||
e1542cea84 | |||
887ef51f04 | |||
d809687aeb | |||
96ec85a72e | |||
0ed4d493ad | |||
78be1e7c17 | |||
2963682722 | |||
98eea4dcca | |||
98a4a18201 | |||
3619bd33b1 | |||
fa870be263 | |||
3a6d19f51f | |||
73d6a9d585 | |||
5d48107dd6 | |||
a306931e1c | |||
b3803c5002 | |||
c412c116d8 | |||
6ce4493e14 | |||
d6e545932a | |||
542bae4581 | |||
307154a06f | |||
725afe33ef | |||
bb58056ebe | |||
f69a33574c | |||
1a48cf7e7d | |||
2833d94a3b | |||
9b0aa5135e | |||
9787efc7ee | |||
623293d272 | |||
5ab5fdcc22 | |||
1b1988a37a | |||
f584d143ff | |||
56c679595f |
@ -17,7 +17,7 @@ then
|
|||||||
echo "Signing apk..."
|
echo "Signing apk..."
|
||||||
base64 --decode <<< "${ANDROID_KEYSTORE_B64}" > ks.jks
|
base64 --decode <<< "${ANDROID_KEYSTORE_B64}" > ks.jks
|
||||||
|
|
||||||
apksigner sign --ks ks.jks \
|
java -jar $(which apksigner) sign --ks ks.jks \
|
||||||
--ks-key-alias "${ANDROID_KEY_ALIAS}" \
|
--ks-key-alias "${ANDROID_KEY_ALIAS}" \
|
||||||
--ks-pass env:ANDROID_KEYSTORE_PASS "artifacts/${REV_NAME}.apk"
|
--ks-pass env:ANDROID_KEYSTORE_PASS "artifacts/${REV_NAME}.apk"
|
||||||
fi
|
fi
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
brew update
|
brew update
|
||||||
brew unlink python@2 || true
|
brew unlink python@2 || true
|
||||||
rm '/usr/local/bin/2to3' || true
|
rm '/usr/local/bin/2to3' || true
|
||||||
brew install qt5 molten-vk glslang vulkan-loader p7zip ccache ninja || true
|
brew install qt5 p7zip ccache ninja || true
|
||||||
pip3 install macpack
|
pip3 install macpack
|
||||||
|
|
||||||
export SDL_VER=2.0.16
|
export SDL_VER=2.0.16
|
||||||
|
@ -12,37 +12,20 @@ cp build/bin/Release/citra "$REV_NAME"
|
|||||||
cp -r build/bin/Release/citra-qt.app "$REV_NAME"
|
cp -r build/bin/Release/citra-qt.app "$REV_NAME"
|
||||||
cp build/bin/Release/citra-room "$REV_NAME"
|
cp build/bin/Release/citra-room "$REV_NAME"
|
||||||
|
|
||||||
BUNDLE_PATH="$REV_NAME/citra-qt.app"
|
|
||||||
BUNDLE_CONTENTS_PATH="$BUNDLE_PATH/Contents"
|
|
||||||
BUNDLE_EXECUTABLE_PATH="$BUNDLE_CONTENTS_PATH/MacOS/citra-qt"
|
|
||||||
BUNDLE_LIB_PATH="$BUNDLE_CONTENTS_PATH/lib"
|
|
||||||
BUNDLE_RESOURCES_PATH="$BUNDLE_CONTENTS_PATH/Resources"
|
|
||||||
|
|
||||||
CITRA_STANDALONE_PATH="$REV_NAME/citra"
|
|
||||||
|
|
||||||
# move libs into folder for deployment
|
# move libs into folder for deployment
|
||||||
macpack $BUNDLE_EXECUTABLE_PATH -d "../Frameworks"
|
macpack "${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt" -d "../Frameworks"
|
||||||
# move qt frameworks into app bundle for deployment
|
# move qt frameworks into app bundle for deployment
|
||||||
$(brew --prefix)/opt/qt5/bin/macdeployqt $BUNDLE_PATH -executable=$BUNDLE_EXECUTABLE_PATH
|
$(brew --prefix)/opt/qt5/bin/macdeployqt "${REV_NAME}/citra-qt.app" -executable="${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt"
|
||||||
|
|
||||||
# move libs into folder for deployment
|
# move libs into folder for deployment
|
||||||
macpack $CITRA_STANDALONE_PATH -d "libs"
|
macpack "${REV_NAME}/citra" -d "libs"
|
||||||
|
|
||||||
# bundle MoltenVK
|
|
||||||
VULKAN_LOADER_PATH=$(brew --prefix vulkan-loader)
|
|
||||||
MOLTENVK_PATH=$(brew --prefix molten-vk)
|
|
||||||
mkdir $BUNDLE_LIB_PATH
|
|
||||||
cp $VULKAN_LOADER_PATH/lib/libvulkan.dylib $BUNDLE_LIB_PATH
|
|
||||||
cp $MOLTENVK_PATH/lib/libMoltenVK.dylib $BUNDLE_LIB_PATH
|
|
||||||
cp -r $MOLTENVK_PATH/share/vulkan $BUNDLE_RESOURCES_PATH
|
|
||||||
install_name_tool -add_rpath "@loader_path/../lib/" $BUNDLE_EXECUTABLE_PATH
|
|
||||||
|
|
||||||
# workaround for libc++
|
# workaround for libc++
|
||||||
install_name_tool -change @loader_path/../Frameworks/libc++.1.0.dylib /usr/lib/libc++.1.dylib $BUNDLE_EXECUTABLE_PATH
|
install_name_tool -change @loader_path/../Frameworks/libc++.1.0.dylib /usr/lib/libc++.1.dylib "${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt"
|
||||||
install_name_tool -change @loader_path/libs/libc++.1.0.dylib /usr/lib/libc++.1.dylib $CITRA_STANDALONE_PATH
|
install_name_tool -change @loader_path/libs/libc++.1.0.dylib /usr/lib/libc++.1.dylib "${REV_NAME}/citra"
|
||||||
|
|
||||||
# Make the launching script executable
|
# Make the launching script executable
|
||||||
chmod +x $BUNDLE_EXECUTABLE_PATH
|
chmod +x ${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt
|
||||||
|
|
||||||
# Verify loader instructions
|
# Verify loader instructions
|
||||||
find "$REV_NAME" -type f -exec otool -L {} \;
|
find "$REV_NAME" -type f -exec otool -L {} \;
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
#!/bin/sh -ex
|
#!/bin/sh -ex
|
||||||
|
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. \
|
cmake .. -DCMAKE_BUILD_TYPE=Release -G Ninja -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MSVCCache.cmake" -DCITRA_USE_CCACHE=ON -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_MF=ON -DENABLE_FFMPEG_VIDEO_DUMPER=ON
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-G Ninja \
|
|
||||||
-DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MSVCCache.cmake" \
|
|
||||||
-DCITRA_USE_CCACHE=ON \
|
|
||||||
-DCITRA_USE_BUNDLED_QT=1 \
|
|
||||||
-DENABLE_QT_TRANSLATION=OFF \
|
|
||||||
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \
|
|
||||||
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
|
||||||
-DUSE_DISCORD_PRESENCE=ON \
|
|
||||||
-DENABLE_MF=ON \
|
|
||||||
-DENABLE_FFMPEG_VIDEO_DUMPER=ON
|
|
||||||
|
|
||||||
ninja
|
ninja
|
||||||
# show the caching efficiency
|
# show the caching efficiency
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
|
|
||||||
$GITDATE = $(git show -s --date=short --format='%ad') -replace "-", ""
|
|
||||||
$GITREV = $(git show -s --format='%h')
|
|
||||||
|
|
||||||
# Find out what release we are building
|
|
||||||
if ( $GIT_TAG_NAME ) {
|
|
||||||
$RELEASE_NAME = ${GIT_TAG_NAME}.split("-")[0]
|
|
||||||
$RELEASE_NAME = "${RELEASE_NAME}-msvc"
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$RELEASE_NAME = "head"
|
|
||||||
}
|
|
||||||
|
|
||||||
$MSVC_BUILD_ZIP = "citra-windows-msvc-$GITDATE-$GITREV.zip" -replace " ", ""
|
|
||||||
$MSVC_SEVENZIP = "citra-windows-msvc-$GITDATE-$GITREV.7z" -replace " ", ""
|
|
||||||
|
|
||||||
$BUILD_DIR = ".\build\bin\Release"
|
|
||||||
|
|
||||||
# Create artifact directories
|
|
||||||
mkdir $RELEASE_NAME
|
|
||||||
mkdir "artifacts"
|
|
||||||
|
|
||||||
echo "Starting to pack ${RELEASE_NAME}"
|
|
||||||
|
|
||||||
Copy-Item $BUILD_DIR\* -Destination $RELEASE_NAME -Recurse
|
|
||||||
Remove-Item $RELEASE_NAME\tests.* -ErrorAction ignore
|
|
||||||
Remove-Item $RELEASE_NAME\*.pdb -ErrorAction ignore
|
|
||||||
|
|
||||||
# Copy documentation
|
|
||||||
Copy-Item license.txt -Destination $RELEASE_NAME
|
|
||||||
Copy-Item README.md -Destination $RELEASE_NAME
|
|
||||||
|
|
||||||
# Copy cross-platform scripting support
|
|
||||||
Copy-Item dist\scripting -Destination $RELEASE_NAME -Recurse
|
|
||||||
|
|
||||||
# Build the final release artifacts
|
|
||||||
7z a -tzip $MSVC_BUILD_ZIP $RELEASE_NAME\*
|
|
||||||
7z a $MSVC_SEVENZIP $RELEASE_NAME
|
|
||||||
|
|
||||||
Copy-Item $MSVC_BUILD_ZIP -Destination "artifacts"
|
|
||||||
Copy-Item $MSVC_SEVENZIP -Destination "artifacts"
|
|
29
.github/workflows/ci.yml
vendored
29
.github/workflows/ci.yml
vendored
@ -95,13 +95,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
MACOSX_DEPLOYMENT_TARGET: "10.13"
|
MACOSX_DEPLOYMENT_TARGET: "10.13"
|
||||||
ENABLE_COMPATIBILITY_REPORTING: "ON"
|
ENABLE_COMPATIBILITY_REPORTING: "ON"
|
||||||
- name: Pack
|
|
||||||
run: ./.ci/macos/upload.sh
|
|
||||||
- name: Upload
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: macos
|
|
||||||
path: artifacts/
|
|
||||||
windows:
|
windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
@ -115,34 +108,16 @@ jobs:
|
|||||||
key: ${{ runner.os }}-win-${{ github.sha }}
|
key: ${{ runner.os }}-win-${{ github.sha }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-win-
|
${{ runner.os }}-win-
|
||||||
- name: Query tag name
|
|
||||||
uses: little-core-labs/get-git-tag@v3.0.2
|
|
||||||
id: tagName
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: ./.ci/windows-msvc/deps.sh
|
run: ./.ci/windows-msvc/deps.sh
|
||||||
shell: bash
|
shell: bash
|
||||||
- name: Set up MSVC
|
- name: Set up MSVC
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
- name: Setup Vulkan SDK
|
|
||||||
uses: humbletim/setup-vulkan-sdk@v1.2.0
|
|
||||||
with:
|
|
||||||
vulkan-query-version: latest
|
|
||||||
vulkan-components: Glslang
|
|
||||||
vulkan-use-cache: true
|
|
||||||
- name: Test glslangValidator
|
|
||||||
run: glslangValidator --version
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: ./.ci/windows-msvc/build.sh
|
run: ./.ci/windows-msvc/build.sh
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
ENABLE_COMPATIBILITY_REPORTING: "ON"
|
ENABLE_COMPATIBILITY_REPORTING: "ON"
|
||||||
- name: Pack
|
|
||||||
run: ./.ci/windows-msvc/upload.ps1
|
|
||||||
- name: Upload
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: msvc
|
|
||||||
path: artifacts/
|
|
||||||
android:
|
android:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@ -165,7 +140,7 @@ jobs:
|
|||||||
- name: Deps
|
- name: Deps
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install glslang-tools ccache apksigner -y
|
sudo apt-get install ccache apksigner -y
|
||||||
- name: Build
|
- name: Build
|
||||||
run: ./.ci/android/build.sh
|
run: ./.ci/android/build.sh
|
||||||
- name: Copy and sign artifacts
|
- name: Copy and sign artifacts
|
||||||
@ -193,7 +168,7 @@ jobs:
|
|||||||
TRANSIFEX_API_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
|
TRANSIFEX_API_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
|
||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build, android, macos, source, windows]
|
needs: [build, android, macos, source]
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -67,6 +67,3 @@
|
|||||||
[submodule "glm"]
|
[submodule "glm"]
|
||||||
path = externals/glm
|
path = externals/glm
|
||||||
url = https://github.com/g-truc/glm
|
url = https://github.com/g-truc/glm
|
||||||
[submodule "sirit"]
|
|
||||||
path = externals/sirit
|
|
||||||
url = https://github.com/GPUCode/sirit
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# CMake 3.12 required for 20 to be a valid value for CXX_STANDARD
|
# CMake 3.12 required for 20 to be a valid value for CXX_STANDARD
|
||||||
cmake_minimum_required(VERSION 3.15)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
# Don't override the warning flags in MSVC:
|
# Don't override the warning flags in MSVC:
|
||||||
cmake_policy(SET CMP0092 NEW)
|
cmake_policy(SET CMP0092 NEW)
|
||||||
@ -43,8 +43,6 @@ CMAKE_DEPENDENT_OPTION(CITRA_USE_BUNDLED_FFMPEG "Download bundled FFmpeg binarie
|
|||||||
|
|
||||||
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
|
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
|
||||||
|
|
||||||
option(CITRA_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
|
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_MF "Use Media Foundation decoder (preferred over FFmpeg)" ON "WIN32" OFF)
|
CMAKE_DEPENDENT_OPTION(ENABLE_MF "Use Media Foundation decoder (preferred over FFmpeg)" ON "WIN32" OFF)
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ON "MINGW" OFF)
|
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ON "MINGW" OFF)
|
||||||
@ -53,23 +51,6 @@ option(USE_SYSTEM_BOOST "Use the system Boost libs (instead of the bundled ones)
|
|||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_FDK "Use FDK AAC decoder" OFF "NOT ENABLE_FFMPEG_AUDIO_DECODER;NOT ENABLE_MF" OFF)
|
CMAKE_DEPENDENT_OPTION(ENABLE_FDK "Use FDK AAC decoder" OFF "NOT ENABLE_FFMPEG_AUDIO_DECODER;NOT ENABLE_MF" OFF)
|
||||||
|
|
||||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
|
||||||
if (MSVC AND CCACHE)
|
|
||||||
# buildcache does not properly cache PCH files, leading to compilation errors.
|
|
||||||
# See https://github.com/mbitsnbites/buildcache/discussions/230
|
|
||||||
message(WARNING "Buildcache does not properly support Precompiled Headers. Disabling PCH")
|
|
||||||
set(CITRA_USE_PRECOMPILED_HEADERS OFF)
|
|
||||||
endif()
|
|
||||||
if(APPLE)
|
|
||||||
message(WARNING "Precompiled Headers currently do not work on Apple. Disabling PCH")
|
|
||||||
set(CITRA_USE_PRECOMPILED_HEADERS OFF)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
|
||||||
message(STATUS "Using Precompiled Headers.")
|
|
||||||
set(CMAKE_PCH_INSTANTIATE_TEMPLATES ON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit)
|
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit)
|
||||||
message(STATUS "Copying pre-commit hook")
|
message(STATUS "Copying pre-commit hook")
|
||||||
file(COPY hooks/pre-commit
|
file(COPY hooks/pre-commit
|
||||||
@ -177,8 +158,6 @@ message(STATUS "Target architecture: ${ARCHITECTURE}")
|
|||||||
# Configure C++ standard
|
# Configure C++ standard
|
||||||
# ===========================
|
# ===========================
|
||||||
|
|
||||||
# boost asio's concept usage doesn't play nicely with some compilers yet.
|
|
||||||
add_definitions(-DBOOST_ASIO_DISABLE_CONCEPTS)
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
@ -195,8 +174,8 @@ find_package(Threads REQUIRED)
|
|||||||
|
|
||||||
if (ENABLE_QT)
|
if (ENABLE_QT)
|
||||||
if (CITRA_USE_BUNDLED_QT)
|
if (CITRA_USE_BUNDLED_QT)
|
||||||
if (MSVC_VERSION GREATER_EQUAL 1920 AND ARCHITECTURE_x86_64)
|
if (MSVC_VERSION GREATER_EQUAL 1930 AND ARCHITECTURE_x86_64)
|
||||||
set(QT_VER qt-5.15.7-msvc2019_64)
|
set(QT_VER qt-5.15.5-msvc2022_64)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable CITRA_USE_BUNDLED_QT and provide your own.")
|
message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable CITRA_USE_BUNDLED_QT and provide your own.")
|
||||||
endif()
|
endif()
|
||||||
@ -316,15 +295,13 @@ if (CLANG_FORMAT)
|
|||||||
set(SRCS ${PROJECT_SOURCE_DIR}/src)
|
set(SRCS ${PROJECT_SOURCE_DIR}/src)
|
||||||
set(CCOMMENT "Running clang format against all the .h and .cpp files in src/")
|
set(CCOMMENT "Running clang format against all the .h and .cpp files in src/")
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
if(MINGW)
|
|
||||||
add_custom_target(clang-format
|
|
||||||
COMMAND find `cygpath -u ${SRCS}` -iname *.h -o -iname *.cpp -o -iname *.mm | xargs `cygpath -u ${CLANG_FORMAT}` -i
|
|
||||||
COMMENT ${CCOMMENT})
|
|
||||||
else()
|
|
||||||
add_custom_target(clang-format
|
add_custom_target(clang-format
|
||||||
COMMAND powershell.exe -Command "Get-ChildItem '${SRCS}/*' -Include *.cpp,*.h,*.mm -Recurse | Foreach {&'${CLANG_FORMAT}' -i $_.fullname}"
|
COMMAND powershell.exe -Command "Get-ChildItem '${SRCS}/*' -Include *.cpp,*.h,*.mm -Recurse | Foreach {&'${CLANG_FORMAT}' -i $_.fullname}"
|
||||||
COMMENT ${CCOMMENT})
|
COMMENT ${CCOMMENT})
|
||||||
endif()
|
elseif(MINGW)
|
||||||
|
add_custom_target(clang-format
|
||||||
|
COMMAND find `cygpath -u ${SRCS}` -iname *.h -o -iname *.cpp -o -iname *.mm | xargs `cygpath -u ${CLANG_FORMAT}` -i
|
||||||
|
COMMENT ${CCOMMENT})
|
||||||
else()
|
else()
|
||||||
add_custom_target(clang-format
|
add_custom_target(clang-format
|
||||||
COMMAND find ${SRCS} -iname *.h -o -iname *.cpp -o -iname *.mm | xargs ${CLANG_FORMAT} -i
|
COMMAND find ${SRCS} -iname *.h -o -iname *.cpp -o -iname *.mm | xargs ${CLANG_FORMAT} -i
|
||||||
|
3
externals/CMakeLists.txt
vendored
3
externals/CMakeLists.txt
vendored
@ -67,9 +67,6 @@ set(ENABLE_SPVREMAPPER OFF)
|
|||||||
set(ENABLE_CTEST OFF)
|
set(ENABLE_CTEST OFF)
|
||||||
add_subdirectory(glslang)
|
add_subdirectory(glslang)
|
||||||
|
|
||||||
# Sirit
|
|
||||||
add_subdirectory(sirit)
|
|
||||||
|
|
||||||
# glm
|
# glm
|
||||||
add_subdirectory(glm)
|
add_subdirectory(glm)
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ function(windows_copy_files TARGET SOURCE_DIR DEST_DIR)
|
|||||||
# cmake adds an extra check for command success which doesn't work too well with robocopy
|
# cmake adds an extra check for command success which doesn't work too well with robocopy
|
||||||
# so trick it into thinking the command was successful with the || cmd /c "exit /b 0"
|
# so trick it into thinking the command was successful with the || cmd /c "exit /b 0"
|
||||||
add_custom_command(TARGET ${TARGET} POST_BUILD
|
add_custom_command(TARGET ${TARGET} POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEST_DIR}
|
COMMAND if not exist ${DEST_DIR} mkdir ${DEST_DIR} 2> nul
|
||||||
COMMAND robocopy ${SOURCE_DIR} ${DEST_DIR} ${ARGN} /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0"
|
COMMAND robocopy ${SOURCE_DIR} ${DEST_DIR} ${ARGN} /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0"
|
||||||
)
|
)
|
||||||
endfunction()
|
endfunction()
|
2
externals/dynarmic
vendored
2
externals/dynarmic
vendored
Submodule externals/dynarmic updated: 7a926d689b...3946dcf005
38
externals/microprofile/microprofile.h
vendored
38
externals/microprofile/microprofile.h
vendored
@ -834,7 +834,7 @@ struct MicroProfile
|
|||||||
|
|
||||||
inline int MicroProfileLogType(MicroProfileLogEntry Index)
|
inline int MicroProfileLogType(MicroProfileLogEntry Index)
|
||||||
{
|
{
|
||||||
return (int)(((MP_LOG_BEGIN_MASK & Index)>>62) & 0x3ULL);
|
return ((MP_LOG_BEGIN_MASK & Index)>>62) & 0x3;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint64_t MicroProfileLogTimerIndex(MicroProfileLogEntry Index)
|
inline uint64_t MicroProfileLogTimerIndex(MicroProfileLogEntry Index)
|
||||||
@ -881,12 +881,12 @@ T MicroProfileMax(T a, T b)
|
|||||||
|
|
||||||
inline int64_t MicroProfileMsToTick(float fMs, int64_t nTicksPerSecond)
|
inline int64_t MicroProfileMsToTick(float fMs, int64_t nTicksPerSecond)
|
||||||
{
|
{
|
||||||
return (int64_t)(fMs*0.001f*(float)nTicksPerSecond);
|
return (int64_t)(fMs*0.001f*nTicksPerSecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float MicroProfileTickToMsMultiplier(int64_t nTicksPerSecond)
|
inline float MicroProfileTickToMsMultiplier(int64_t nTicksPerSecond)
|
||||||
{
|
{
|
||||||
return 1000.f / (float)nTicksPerSecond;
|
return 1000.f / nTicksPerSecond;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16_t MicroProfileGetGroupIndex(MicroProfileToken t)
|
inline uint16_t MicroProfileGetGroupIndex(MicroProfileToken t)
|
||||||
@ -902,10 +902,8 @@ inline uint16_t MicroProfileGetGroupIndex(MicroProfileToken t)
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable: 4244)
|
#pragma warning(disable: 4244)
|
||||||
#endif
|
|
||||||
int64_t MicroProfileTicksPerSecondCpu()
|
int64_t MicroProfileTicksPerSecondCpu()
|
||||||
{
|
{
|
||||||
static int64_t nTicksPerSecond = 0;
|
static int64_t nTicksPerSecond = 0;
|
||||||
@ -931,14 +929,14 @@ typedef void* (*MicroProfileThreadFunc)(void*);
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
typedef pthread_t MicroProfileThread;
|
typedef pthread_t MicroProfileThread;
|
||||||
inline void MicroProfileThreadStart(MicroProfileThread* pThread, MicroProfileThreadFunc Func)
|
void MicroProfileThreadStart(MicroProfileThread* pThread, MicroProfileThreadFunc Func)
|
||||||
{
|
{
|
||||||
pthread_attr_t Attr;
|
pthread_attr_t Attr;
|
||||||
int r = pthread_attr_init(&Attr);
|
int r = pthread_attr_init(&Attr);
|
||||||
MP_ASSERT(r == 0);
|
MP_ASSERT(r == 0);
|
||||||
pthread_create(pThread, &Attr, Func, 0);
|
pthread_create(pThread, &Attr, Func, 0);
|
||||||
}
|
}
|
||||||
inline void MicroProfileThreadJoin(MicroProfileThread* pThread)
|
void MicroProfileThreadJoin(MicroProfileThread* pThread)
|
||||||
{
|
{
|
||||||
int r = pthread_join(*pThread, 0);
|
int r = pthread_join(*pThread, 0);
|
||||||
MP_ASSERT(r == 0);
|
MP_ASSERT(r == 0);
|
||||||
@ -955,11 +953,11 @@ DWORD _stdcall ThreadTrampoline(void* pFunc)
|
|||||||
return static_cast<DWORD>(reinterpret_cast<uint64_t>(F(0)));
|
return static_cast<DWORD>(reinterpret_cast<uint64_t>(F(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MicroProfileThreadStart(MicroProfileThread* pThread, MicroProfileThreadFunc Func)
|
void MicroProfileThreadStart(MicroProfileThread* pThread, MicroProfileThreadFunc Func)
|
||||||
{
|
{
|
||||||
*pThread = CreateThread(0, 0, ThreadTrampoline, Func, 0, 0);
|
*pThread = CreateThread(0, 0, ThreadTrampoline, Func, 0, 0);
|
||||||
}
|
}
|
||||||
inline void MicroProfileThreadJoin(MicroProfileThread* pThread)
|
void MicroProfileThreadJoin(MicroProfileThread* pThread)
|
||||||
{
|
{
|
||||||
WaitForSingleObject(*pThread, INFINITE);
|
WaitForSingleObject(*pThread, INFINITE);
|
||||||
CloseHandle(*pThread);
|
CloseHandle(*pThread);
|
||||||
@ -1156,7 +1154,7 @@ inline void MicroProfileSetThreadLog(MicroProfileThreadLog* pLog)
|
|||||||
pthread_setspecific(g_MicroProfileThreadLogKey, pLog);
|
pthread_setspecific(g_MicroProfileThreadLogKey, pLog);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inline MicroProfileThreadLog* MicroProfileGetThreadLog()
|
MicroProfileThreadLog* MicroProfileGetThreadLog()
|
||||||
{
|
{
|
||||||
return g_MicroProfileThreadLog;
|
return g_MicroProfileThreadLog;
|
||||||
}
|
}
|
||||||
@ -1272,7 +1270,7 @@ MicroProfileToken MicroProfileFindToken(const char* pGroup, const char* pName)
|
|||||||
return MICROPROFILE_INVALID_TOKEN;
|
return MICROPROFILE_INVALID_TOKEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16_t MicroProfileGetGroup(const char* pGroup, MicroProfileTokenType Type)
|
uint16_t MicroProfileGetGroup(const char* pGroup, MicroProfileTokenType Type)
|
||||||
{
|
{
|
||||||
for(uint32_t i = 0; i < S.nGroupCount; ++i)
|
for(uint32_t i = 0; i < S.nGroupCount; ++i)
|
||||||
{
|
{
|
||||||
@ -1301,7 +1299,7 @@ inline uint16_t MicroProfileGetGroup(const char* pGroup, MicroProfileTokenType T
|
|||||||
return nGroupIndex;
|
return nGroupIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MicroProfileRegisterGroup(const char* pGroup, const char* pCategory, uint32_t nColor)
|
void MicroProfileRegisterGroup(const char* pGroup, const char* pCategory, uint32_t nColor)
|
||||||
{
|
{
|
||||||
int nCategoryIndex = -1;
|
int nCategoryIndex = -1;
|
||||||
for(uint32_t i = 0; i < S.nCategoryCount; ++i)
|
for(uint32_t i = 0; i < S.nCategoryCount; ++i)
|
||||||
@ -1467,7 +1465,7 @@ void MicroProfileGpuLeave(MicroProfileToken nToken_, uint64_t nTickStart)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MicroProfileContextSwitchPut(MicroProfileContextSwitch* pContextSwitch)
|
void MicroProfileContextSwitchPut(MicroProfileContextSwitch* pContextSwitch)
|
||||||
{
|
{
|
||||||
if(S.nRunning || pContextSwitch->nTicks <= S.nPauseTicks)
|
if(S.nRunning || pContextSwitch->nTicks <= S.nPauseTicks)
|
||||||
{
|
{
|
||||||
@ -1748,10 +1746,10 @@ void MicroProfileFlip()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(uint32_t j = 0; j < MICROPROFILE_MAX_GROUPS; ++j)
|
for(uint32_t i = 0; i < MICROPROFILE_MAX_GROUPS; ++i)
|
||||||
{
|
{
|
||||||
pLog->nGroupTicks[j] += nGroupTicks[j];
|
pLog->nGroupTicks[i] += nGroupTicks[i];
|
||||||
pFrameGroup[j] += nGroupTicks[j];
|
pFrameGroup[i] += nGroupTicks[i];
|
||||||
}
|
}
|
||||||
pLog->nStackPos = nStackPos;
|
pLog->nStackPos = nStackPos;
|
||||||
}
|
}
|
||||||
@ -1919,7 +1917,7 @@ void MicroProfileSetEnableAllGroups(bool bEnableAllGroups)
|
|||||||
S.nAllGroupsWanted = bEnableAllGroups ? 1 : 0;
|
S.nAllGroupsWanted = bEnableAllGroups ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MicroProfileEnableCategory(const char* pCategory, bool bEnabled)
|
void MicroProfileEnableCategory(const char* pCategory, bool bEnabled)
|
||||||
{
|
{
|
||||||
int nCategoryIndex = -1;
|
int nCategoryIndex = -1;
|
||||||
for(uint32_t i = 0; i < S.nCategoryCount; ++i)
|
for(uint32_t i = 0; i < S.nCategoryCount; ++i)
|
||||||
@ -2029,7 +2027,7 @@ void MicroProfileForceDisableGroup(const char* pGroup, MicroProfileTokenType Typ
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void MicroProfileCalcAllTimers(float* pTimers, float* pAverage, float* pMax, float* pCallAverage, float* pExclusive, float* pAverageExclusive, float* pMaxExclusive, float* pTotal, uint32_t nSize)
|
void MicroProfileCalcAllTimers(float* pTimers, float* pAverage, float* pMax, float* pCallAverage, float* pExclusive, float* pAverageExclusive, float* pMaxExclusive, float* pTotal, uint32_t nSize)
|
||||||
{
|
{
|
||||||
for(uint32_t i = 0; i < S.nTotalTimers && i < nSize; ++i)
|
for(uint32_t i = 0; i < S.nTotalTimers && i < nSize; ++i)
|
||||||
{
|
{
|
||||||
@ -3334,7 +3332,7 @@ bool MicroProfileIsLocalThread(uint32_t nThreadId)
|
|||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
|
||||||
bool MicroProfileIsLocalThread([[maybe_unused]] uint32_t nThreadId) { return false; }
|
bool MicroProfileIsLocalThread(uint32_t nThreadId){return false;}
|
||||||
void MicroProfileStopContextSwitchTrace(){}
|
void MicroProfileStopContextSwitchTrace(){}
|
||||||
void MicroProfileStartContextSwitchTrace(){}
|
void MicroProfileStartContextSwitchTrace(){}
|
||||||
|
|
||||||
@ -3582,7 +3580,7 @@ int MicroProfileGetGpuTickReference(int64_t* pOutCpu, int64_t* pOutGpu)
|
|||||||
|
|
||||||
#undef S
|
#undef S
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _WIN32
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
1
externals/sirit
vendored
1
externals/sirit
vendored
Submodule externals/sirit deleted from f0b6bbe55b
@ -46,21 +46,11 @@ if (MSVC)
|
|||||||
|
|
||||||
# Warnings
|
# Warnings
|
||||||
/W3
|
/W3
|
||||||
/we4062 # enumerator 'identifier' in a switch of enum 'enumeration' is not handled
|
|
||||||
/we4101 # 'identifier': unreferenced local variable
|
|
||||||
/we4265 # 'class': class has virtual functions, but destructor is not virtual
|
|
||||||
/we4267 # 'var': conversion from 'size_t' to 'type', possible loss of data
|
/we4267 # 'var': conversion from 'size_t' to 'type', possible loss of data
|
||||||
/we4388 # signed/unsigned mismatch
|
|
||||||
/we4547 # 'operator' : operator before comma has no effect; expected operator with side-effect
|
|
||||||
/we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'?
|
|
||||||
/we4555 # Expression has no effect; expected expression with side-effect
|
|
||||||
/we4834 # Discarding return value of function with 'nodiscard' attribute
|
|
||||||
/we5038 # data member 'member1' will be initialized after data member 'member2'
|
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
/MP
|
/MP
|
||||||
/Zo
|
|
||||||
/permissive-
|
/permissive-
|
||||||
/EHsc
|
/EHsc
|
||||||
/volatile:iso
|
/volatile:iso
|
||||||
@ -74,26 +64,17 @@ if (MSVC)
|
|||||||
|
|
||||||
# Warnings
|
# Warnings
|
||||||
/W3
|
/W3
|
||||||
/we4062 # enumerator 'identifier' in a switch of enum 'enumeration' is not handled
|
|
||||||
/we4101 # 'identifier': unreferenced local variable
|
|
||||||
/we4265 # 'class': class has virtual functions, but destructor is not virtual
|
|
||||||
/we4267 # 'var': conversion from 'size_t' to 'type', possible loss of data
|
/we4267 # 'var': conversion from 'size_t' to 'type', possible loss of data
|
||||||
/we4388 # signed/unsigned mismatch
|
|
||||||
/we4547 # 'operator' : operator before comma has no effect; expected operator with side-effect
|
|
||||||
/we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'?
|
|
||||||
/we4555 # Expression has no effect; expected expression with side-effect
|
|
||||||
/we4834 # Discarding return value of function with 'nodiscard' attribute
|
|
||||||
/we5038 # data member 'member1' will be initialized after data member 'member2'
|
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Since MSVC's debugging information is not very deterministic, so we have to disable it
|
# Since MSVC's debugging information is not very deterministic, so we have to disable it
|
||||||
# when using ccache or other caching tools
|
# when using ccache or other caching tools
|
||||||
if (CITRA_USE_CCACHE OR CITRA_USE_PRECOMPILED_HEADERS)
|
if (NOT CITRA_USE_CCACHE)
|
||||||
# Precompiled headers are deleted if not using /Z7. See https://github.com/nanoant/CMakePCHCompiler/issues/21
|
add_compile_options(
|
||||||
add_compile_options(/Z7)
|
/Zi
|
||||||
else()
|
/Zo
|
||||||
add_compile_options(/Zi)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# /GS- - No stack buffer overflow checks
|
# /GS- - No stack buffer overflow checks
|
||||||
|
@ -30,8 +30,7 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:isGame="true"
|
android:isGame="true"
|
||||||
android:banner="@mipmap/ic_launcher"
|
android:banner="@mipmap/ic_launcher"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true">
|
||||||
android:debuggable="true">
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="org.citra.citra_emu.ui.main.MainActivity"
|
android:name="org.citra.citra_emu.ui.main.MainActivity"
|
||||||
|
@ -192,15 +192,11 @@ public final class SettingsFragmentPresenter {
|
|||||||
Setting language = systemSection.getSetting(SettingsFile.KEY_LANGUAGE);
|
Setting language = systemSection.getSetting(SettingsFile.KEY_LANGUAGE);
|
||||||
Setting systemClock = systemSection.getSetting(SettingsFile.KEY_INIT_CLOCK);
|
Setting systemClock = systemSection.getSetting(SettingsFile.KEY_INIT_CLOCK);
|
||||||
Setting dateTime = systemSection.getSetting(SettingsFile.KEY_INIT_TIME);
|
Setting dateTime = systemSection.getSetting(SettingsFile.KEY_INIT_TIME);
|
||||||
Setting pluginLoader = systemSection.getSetting(SettingsFile.KEY_PLUGIN_LOADER);
|
|
||||||
Setting allowPluginLoader = systemSection.getSetting(SettingsFile.KEY_ALLOW_PLUGIN_LOADER);
|
|
||||||
|
|
||||||
sl.add(new SingleChoiceSetting(SettingsFile.KEY_REGION_VALUE, Settings.SECTION_SYSTEM, R.string.emulated_region, 0, R.array.regionNames, R.array.regionValues, -1, region));
|
sl.add(new SingleChoiceSetting(SettingsFile.KEY_REGION_VALUE, Settings.SECTION_SYSTEM, R.string.emulated_region, 0, R.array.regionNames, R.array.regionValues, -1, region));
|
||||||
sl.add(new SingleChoiceSetting(SettingsFile.KEY_LANGUAGE, Settings.SECTION_SYSTEM, R.string.emulated_language, 0, R.array.languageNames, R.array.languageValues, 1, language));
|
sl.add(new SingleChoiceSetting(SettingsFile.KEY_LANGUAGE, Settings.SECTION_SYSTEM, R.string.emulated_language, 0, R.array.languageNames, R.array.languageValues, 1, language));
|
||||||
sl.add(new SingleChoiceSetting(SettingsFile.KEY_INIT_CLOCK, Settings.SECTION_SYSTEM, R.string.init_clock, R.string.init_clock_description, R.array.systemClockNames, R.array.systemClockValues, 0, systemClock));
|
sl.add(new SingleChoiceSetting(SettingsFile.KEY_INIT_CLOCK, Settings.SECTION_SYSTEM, R.string.init_clock, R.string.init_clock_description, R.array.systemClockNames, R.array.systemClockValues, 0, systemClock));
|
||||||
sl.add(new DateTimeSetting(SettingsFile.KEY_INIT_TIME, Settings.SECTION_SYSTEM, R.string.init_time, R.string.init_time_description, "2000-01-01 00:00:01", dateTime));
|
sl.add(new DateTimeSetting(SettingsFile.KEY_INIT_TIME, Settings.SECTION_SYSTEM, R.string.init_time, R.string.init_time_description, "2000-01-01 00:00:01", dateTime));
|
||||||
sl.add(new CheckBoxSetting(SettingsFile.KEY_PLUGIN_LOADER, Settings.SECTION_SYSTEM, R.string.plugin_loader, R.string.plugin_loader_description, false, pluginLoader));
|
|
||||||
sl.add(new CheckBoxSetting(SettingsFile.KEY_ALLOW_PLUGIN_LOADER, Settings.SECTION_SYSTEM, R.string.allow_plugin_loader, R.string.allow_plugin_loader_description, true, allowPluginLoader));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCameraSettings(ArrayList<SettingsItem> sl) {
|
private void addCameraSettings(ArrayList<SettingsItem> sl) {
|
||||||
|
@ -78,8 +78,6 @@ public final class SettingsFile {
|
|||||||
public static final String KEY_IS_NEW_3DS = "is_new_3ds";
|
public static final String KEY_IS_NEW_3DS = "is_new_3ds";
|
||||||
public static final String KEY_REGION_VALUE = "region_value";
|
public static final String KEY_REGION_VALUE = "region_value";
|
||||||
public static final String KEY_LANGUAGE = "language";
|
public static final String KEY_LANGUAGE = "language";
|
||||||
public static final String KEY_PLUGIN_LOADER = "plugin_loader";
|
|
||||||
public static final String KEY_ALLOW_PLUGIN_LOADER = "allow_plugin_loader";
|
|
||||||
|
|
||||||
public static final String KEY_INIT_CLOCK = "init_clock";
|
public static final String KEY_INIT_CLOCK = "init_clock";
|
||||||
public static final String KEY_INIT_TIME = "init_time";
|
public static final String KEY_INIT_TIME = "init_time";
|
||||||
|
@ -8,7 +8,7 @@ import org.citra.citra_emu.CitraApplication;
|
|||||||
public class EmulationMenuSettings {
|
public class EmulationMenuSettings {
|
||||||
private static SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(CitraApplication.getAppContext());
|
private static SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(CitraApplication.getAppContext());
|
||||||
|
|
||||||
// These must match what is defined in src/common/settings.h
|
// These must match what is defined in src/core/settings.h
|
||||||
public static final int LayoutOption_Default = 0;
|
public static final int LayoutOption_Default = 0;
|
||||||
public static final int LayoutOption_SingleScreen = 1;
|
public static final int LayoutOption_SingleScreen = 1;
|
||||||
public static final int LayoutOption_LargeScreen = 2;
|
public static final int LayoutOption_LargeScreen = 2;
|
||||||
|
@ -19,8 +19,6 @@ add_library(citra-android SHARED
|
|||||||
default_ini.h
|
default_ini.h
|
||||||
emu_window/emu_window.cpp
|
emu_window/emu_window.cpp
|
||||||
emu_window/emu_window.h
|
emu_window/emu_window.h
|
||||||
emu_window/emu_window_vk.cpp
|
|
||||||
emu_window/emu_window_vk.h
|
|
||||||
game_info.cpp
|
game_info.cpp
|
||||||
game_info.h
|
game_info.h
|
||||||
game_settings.cpp
|
game_settings.cpp
|
||||||
|
@ -11,10 +11,10 @@
|
|||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/service/cfg/cfg.h"
|
#include "core/hle/service/cfg/cfg.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/udp/client.h"
|
#include "input_common/udp/client.h"
|
||||||
#include "jni/camera/ndk_camera.h"
|
#include "jni/camera/ndk_camera.h"
|
||||||
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
Config::Config() {
|
Config::Config() {
|
||||||
// TODO: Don't hardcode the path; let the frontend decide where to put the config files.
|
// TODO: Don't hardcode the path; let the frontend decide where to put the config files.
|
||||||
sdl2_config_loc = FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + "config.ini";
|
sdl2_config_loc = Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir) + "config.ini";
|
||||||
sdl2_config = std::make_unique<INIReader>(sdl2_config_loc);
|
sdl2_config = std::make_unique<INIReader>(sdl2_config_loc);
|
||||||
|
|
||||||
Reload();
|
Reload();
|
||||||
@ -38,8 +38,8 @@ bool Config::LoadINI(const std::string& default_contents, bool retry) {
|
|||||||
if (sdl2_config->ParseError() < 0) {
|
if (sdl2_config->ParseError() < 0) {
|
||||||
if (retry) {
|
if (retry) {
|
||||||
LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", location);
|
LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", location);
|
||||||
FileUtil::CreateFullPath(location);
|
Common::FS::CreateFullPath(location);
|
||||||
FileUtil::WriteStringToFile(true, location, default_contents);
|
Common::FS::WriteStringToFile(true, location, default_contents);
|
||||||
sdl2_config = std::make_unique<INIReader>(location); // Reopen file
|
sdl2_config = std::make_unique<INIReader>(location); // Reopen file
|
||||||
|
|
||||||
return LoadINI(default_contents, false);
|
return LoadINI(default_contents, false);
|
||||||
@ -114,13 +114,7 @@ void Config::ReadValues() {
|
|||||||
sdl2_config->GetString("Premium", "texture_filter_name", "none");
|
sdl2_config->GetString("Premium", "texture_filter_name", "none");
|
||||||
|
|
||||||
// Renderer
|
// Renderer
|
||||||
Settings::values.graphics_api =
|
Settings::values.use_gles = sdl2_config->GetBoolean("Renderer", "use_gles", true);
|
||||||
static_cast<Settings::GraphicsAPI>(sdl2_config->GetInteger("Renderer", "graphics_api", 2));
|
|
||||||
Settings::values.async_command_recording =
|
|
||||||
sdl2_config->GetBoolean("Renderer", "async_command_recording", true);
|
|
||||||
Settings::values.spirv_shader_gen =
|
|
||||||
sdl2_config->GetBoolean("Renderer", "spirv_shader_gen", true);
|
|
||||||
Settings::values.renderer_debug = sdl2_config->GetBoolean("Renderer", "renderer_debug", false);
|
|
||||||
Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true);
|
Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true);
|
||||||
Settings::values.use_hw_shader = sdl2_config->GetBoolean("Renderer", "use_hw_shader", true);
|
Settings::values.use_hw_shader = sdl2_config->GetBoolean("Renderer", "use_hw_shader", true);
|
||||||
Settings::values.shaders_accurate_mul =
|
Settings::values.shaders_accurate_mul =
|
||||||
@ -145,9 +139,9 @@ void Config::ReadValues() {
|
|||||||
Settings::values.factor_3d =
|
Settings::values.factor_3d =
|
||||||
static_cast<u8>(sdl2_config->GetInteger("Renderer", "factor_3d", 0));
|
static_cast<u8>(sdl2_config->GetInteger("Renderer", "factor_3d", 0));
|
||||||
std::string default_shader = "none (builtin)";
|
std::string default_shader = "none (builtin)";
|
||||||
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph)
|
if (Settings::values.render_3d == Settings::StereoRenderOption::Anaglyph)
|
||||||
default_shader = "dubois (builtin)";
|
default_shader = "dubois (builtin)";
|
||||||
else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced)
|
else if (Settings::values.render_3d == Settings::StereoRenderOption::Interlaced)
|
||||||
default_shader = "horizontal (builtin)";
|
default_shader = "horizontal (builtin)";
|
||||||
Settings::values.pp_shader_name =
|
Settings::values.pp_shader_name =
|
||||||
sdl2_config->GetString("Renderer", "pp_shader_name", default_shader);
|
sdl2_config->GetString("Renderer", "pp_shader_name", default_shader);
|
||||||
@ -192,9 +186,9 @@ void Config::ReadValues() {
|
|||||||
sdl2_config->GetBoolean("Utility", "preload_textures", false);
|
sdl2_config->GetBoolean("Utility", "preload_textures", false);
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
Settings::values.audio_emulation =
|
Settings::values.enable_dsp_lle = sdl2_config->GetBoolean("Audio", "enable_dsp_lle", false);
|
||||||
static_cast<Settings::AudioEmulation>(sdl2_config->GetInteger(
|
Settings::values.enable_dsp_lle_multithread =
|
||||||
"Audio", "audio_emulation", static_cast<int>(Settings::AudioEmulation::HLE)));
|
sdl2_config->GetBoolean("Audio", "enable_dsp_lle_multithread", false);
|
||||||
Settings::values.sink_id = sdl2_config->GetString("Audio", "output_engine", "auto");
|
Settings::values.sink_id = sdl2_config->GetString("Audio", "output_engine", "auto");
|
||||||
Settings::values.enable_audio_stretching =
|
Settings::values.enable_audio_stretching =
|
||||||
sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true);
|
sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true);
|
||||||
@ -235,10 +229,6 @@ void Config::ReadValues() {
|
|||||||
std::chrono::system_clock::from_time_t(std::mktime(&t)).time_since_epoch())
|
std::chrono::system_clock::from_time_t(std::mktime(&t)).time_since_epoch())
|
||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
Settings::values.plugin_loader_enabled =
|
|
||||||
sdl2_config->GetBoolean("System", "plugin_loader", false);
|
|
||||||
Settings::values.allow_plugin_loader =
|
|
||||||
sdl2_config->GetBoolean("System", "allow_plugin_loader", true);
|
|
||||||
|
|
||||||
// Camera
|
// Camera
|
||||||
using namespace Service::CAM;
|
using namespace Service::CAM;
|
||||||
|
@ -281,11 +281,6 @@ init_clock =
|
|||||||
# Note: 3DS can only handle times later then Jan 1 2000
|
# Note: 3DS can only handle times later then Jan 1 2000
|
||||||
init_time =
|
init_time =
|
||||||
|
|
||||||
# Plugin loader state, if enabled plugins will be loaded from the SD card.
|
|
||||||
# You can also set if homebrew apps are allowed to enable the plugin loader
|
|
||||||
plugin_loader =
|
|
||||||
allow_plugin_loader =
|
|
||||||
|
|
||||||
[Camera]
|
[Camera]
|
||||||
# Which camera engine to use for the right outer camera
|
# Which camera engine to use for the right outer camera
|
||||||
# blank: a dummy camera that always returns black image
|
# blank: a dummy camera that always returns black image
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "jni/emu_window/emu_window.h"
|
#include "jni/emu_window/emu_window.h"
|
||||||
#include "jni/id_cache.h"
|
#include "jni/id_cache.h"
|
||||||
|
@ -1,176 +0,0 @@
|
|||||||
// Copyright 2019 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <array>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <string>
|
|
||||||
#include <android/native_window_jni.h>
|
|
||||||
#include "common/logging/log.h"
|
|
||||||
#include "common/settings.h"
|
|
||||||
#include "input_common/main.h"
|
|
||||||
#include "jni/emu_window/emu_window_vk.h"
|
|
||||||
#include "jni/id_cache.h"
|
|
||||||
#include "jni/input_manager.h"
|
|
||||||
#include "network/network.h"
|
|
||||||
#include "video_core/renderer_base.h"
|
|
||||||
#include "video_core/video_core.h"
|
|
||||||
|
|
||||||
static bool IsPortraitMode() {
|
|
||||||
return JNI_FALSE != IDCache::GetEnvForThread()->CallStaticBooleanMethod(
|
|
||||||
IDCache::GetNativeLibraryClass(), IDCache::GetIsPortraitMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UpdateLandscapeScreenLayout() {
|
|
||||||
Settings::values.layout_option =
|
|
||||||
static_cast<Settings::LayoutOption>(IDCache::GetEnvForThread()->CallStaticIntMethod(
|
|
||||||
IDCache::GetNativeLibraryClass(), IDCache::GetLandscapeScreenLayout()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_Android_Vulkan::OnSurfaceChanged(ANativeWindow* surface) {
|
|
||||||
render_window = surface;
|
|
||||||
StopPresenting();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EmuWindow_Android_Vulkan::OnTouchEvent(int x, int y, bool pressed) {
|
|
||||||
if (pressed) {
|
|
||||||
return TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
TouchReleased();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_Android_Vulkan::OnTouchMoved(int x, int y) {
|
|
||||||
TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_Android_Vulkan::OnFramebufferSizeChanged() {
|
|
||||||
UpdateLandscapeScreenLayout();
|
|
||||||
const bool is_portrait_mode{IsPortraitMode()};
|
|
||||||
const int bigger{window_width > window_height ? window_width : window_height};
|
|
||||||
const int smaller{window_width < window_height ? window_width : window_height};
|
|
||||||
if (is_portrait_mode) {
|
|
||||||
UpdateCurrentFramebufferLayout(smaller, bigger, is_portrait_mode);
|
|
||||||
} else {
|
|
||||||
UpdateCurrentFramebufferLayout(bigger, smaller, is_portrait_mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EmuWindow_Android_Vulkan::EmuWindow_Android_Vulkan(ANativeWindow* surface) {
|
|
||||||
LOG_DEBUG(Frontend, "Initializing EmuWindow_Android_Vulkan");
|
|
||||||
|
|
||||||
if (!surface) {
|
|
||||||
LOG_CRITICAL(Frontend, "surface is nullptr");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Network::Init();
|
|
||||||
|
|
||||||
host_window = surface;
|
|
||||||
CreateWindowSurface();
|
|
||||||
|
|
||||||
if (core_context = CreateSharedContext(); !core_context) {
|
|
||||||
LOG_CRITICAL(Frontend, "CreateSharedContext() failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OnFramebufferSizeChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EmuWindow_Android_Vulkan::CreateWindowSurface() {
|
|
||||||
if (!host_window) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
window_info.type = Frontend::WindowSystemType::Android;
|
|
||||||
window_info.render_surface = host_window;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_Android_Vulkan::DestroyWindowSurface() {
|
|
||||||
/*if (!egl_surface) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (eglGetCurrentSurface(EGL_DRAW) == egl_surface) {
|
|
||||||
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
||||||
}
|
|
||||||
if (!eglDestroySurface(egl_display, egl_surface)) {
|
|
||||||
LOG_CRITICAL(Frontend, "eglDestroySurface() failed");
|
|
||||||
}
|
|
||||||
egl_surface = EGL_NO_SURFACE;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_Android_Vulkan::DestroyContext() {
|
|
||||||
/*if (!egl_context) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (eglGetCurrentContext() == egl_context) {
|
|
||||||
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
||||||
}
|
|
||||||
if (!eglDestroyContext(egl_display, egl_context)) {
|
|
||||||
LOG_CRITICAL(Frontend, "eglDestroySurface() failed");
|
|
||||||
}
|
|
||||||
if (!eglTerminate(egl_display)) {
|
|
||||||
LOG_CRITICAL(Frontend, "eglTerminate() failed");
|
|
||||||
}
|
|
||||||
egl_context = EGL_NO_CONTEXT;
|
|
||||||
egl_display = EGL_NO_DISPLAY;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
EmuWindow_Android_Vulkan::~EmuWindow_Android_Vulkan() {
|
|
||||||
DestroyWindowSurface();
|
|
||||||
DestroyContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Frontend::GraphicsContext> EmuWindow_Android_Vulkan::CreateSharedContext() const {
|
|
||||||
return std::make_unique<SharedContext_Android>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_Android_Vulkan::StopPresenting() {
|
|
||||||
/*if (presenting_state == PresentingState::Running) {
|
|
||||||
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
||||||
}*/
|
|
||||||
presenting_state = PresentingState::Stopped;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_Android_Vulkan::TryPresenting() {
|
|
||||||
if (presenting_state != PresentingState::Running) {
|
|
||||||
if (presenting_state == PresentingState::Initial) {
|
|
||||||
/*eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);*/
|
|
||||||
presenting_state = PresentingState::Running;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*eglSwapInterval(egl_display, Settings::values.use_vsync_new ? 1 : 0);
|
|
||||||
if (VideoCore::g_renderer) {
|
|
||||||
VideoCore::g_renderer->TryPresent(0);
|
|
||||||
eglSwapBuffers(egl_display, egl_surface);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_Android_Vulkan::PollEvents() {
|
|
||||||
if (!render_window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
host_window = render_window;
|
|
||||||
render_window = nullptr;
|
|
||||||
|
|
||||||
DestroyWindowSurface();
|
|
||||||
CreateWindowSurface();
|
|
||||||
OnFramebufferSizeChanged();
|
|
||||||
presenting_state = PresentingState::Initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_Android_Vulkan::MakeCurrent() {
|
|
||||||
core_context->MakeCurrent();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_Android_Vulkan::DoneCurrent() {
|
|
||||||
core_context->DoneCurrent();
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
// Copyright 2022 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include "core/frontend/emu_window.h"
|
|
||||||
|
|
||||||
struct ANativeWindow;
|
|
||||||
|
|
||||||
class SharedContext_Android : public Frontend::GraphicsContext {};
|
|
||||||
|
|
||||||
class EmuWindow_Android_Vulkan : public Frontend::EmuWindow {
|
|
||||||
public:
|
|
||||||
EmuWindow_Android_Vulkan(ANativeWindow* surface);
|
|
||||||
~EmuWindow_Android_Vulkan();
|
|
||||||
|
|
||||||
void Present();
|
|
||||||
|
|
||||||
/// Called by the onSurfaceChanges() method to change the surface
|
|
||||||
void OnSurfaceChanged(ANativeWindow* surface);
|
|
||||||
|
|
||||||
/// Handles touch event that occur.(Touched or released)
|
|
||||||
bool OnTouchEvent(int x, int y, bool pressed);
|
|
||||||
|
|
||||||
/// Handles movement of touch pointer
|
|
||||||
void OnTouchMoved(int x, int y);
|
|
||||||
|
|
||||||
void PollEvents() override;
|
|
||||||
void MakeCurrent() override;
|
|
||||||
void DoneCurrent() override;
|
|
||||||
|
|
||||||
void TryPresenting();
|
|
||||||
void StopPresenting();
|
|
||||||
|
|
||||||
std::unique_ptr<GraphicsContext> CreateSharedContext() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void OnFramebufferSizeChanged();
|
|
||||||
bool CreateWindowSurface();
|
|
||||||
void DestroyWindowSurface();
|
|
||||||
void DestroyContext();
|
|
||||||
|
|
||||||
ANativeWindow* render_window{};
|
|
||||||
ANativeWindow* host_window{};
|
|
||||||
|
|
||||||
int window_width{1080};
|
|
||||||
int window_height{2220};
|
|
||||||
|
|
||||||
std::unique_ptr<Frontend::GraphicsContext> core_context;
|
|
||||||
|
|
||||||
enum class PresentingState {
|
|
||||||
Initial,
|
|
||||||
Running,
|
|
||||||
Stopped,
|
|
||||||
};
|
|
||||||
PresentingState presenting_state{};
|
|
||||||
};
|
|
@ -35,7 +35,7 @@ std::vector<u8> GetSMDHData(std::string physical_name) {
|
|||||||
std::string update_path = Service::AM::GetTitleContentPath(
|
std::string update_path = Service::AM::GetTitleContentPath(
|
||||||
Service::FS::MediaType::SDMC, program_id + 0x0000000E'00000000);
|
Service::FS::MediaType::SDMC, program_id + 0x0000000E'00000000);
|
||||||
|
|
||||||
if (!FileUtil::Exists(update_path))
|
if (!Common::FS::Exists(update_path))
|
||||||
return original_smdh;
|
return original_smdh;
|
||||||
|
|
||||||
std::unique_ptr<Loader::AppLoader> update_loader = Loader::GetLoader(update_path);
|
std::unique_ptr<Loader::AppLoader> update_loader = Loader::GetLoader(update_path);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
|
|
||||||
namespace GameSettings {
|
namespace GameSettings {
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "common/logging/backend.h"
|
#include "common/logging/backend.h"
|
||||||
#include "common/logging/filter.h"
|
#include "common/logging/filter.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
#include "jni/applets/mii_selector.h"
|
#include "jni/applets/mii_selector.h"
|
||||||
#include "jni/applets/swkbd.h"
|
#include "jni/applets/swkbd.h"
|
||||||
#include "jni/camera/still_image_camera.h"
|
#include "jni/camera/still_image_camera.h"
|
||||||
@ -156,12 +156,12 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
|||||||
|
|
||||||
// Initialize Logger
|
// Initialize Logger
|
||||||
Log::Filter log_filter;
|
Log::Filter log_filter;
|
||||||
log_filter.ParseFilterString(Settings::values.log_filter.GetValue());
|
log_filter.ParseFilterString(Settings::values.log_filter);
|
||||||
Log::SetGlobalFilter(log_filter);
|
Log::SetGlobalFilter(log_filter);
|
||||||
Log::AddBackend(std::make_unique<Log::LogcatBackend>());
|
Log::AddBackend(std::make_unique<Log::LogcatBackend>());
|
||||||
FileUtil::CreateFullPath(FileUtil::GetUserPath(FileUtil::UserPath::LogDir));
|
Common::FS::CreateFullPath(Common::FS::GetUserPath(Common::FS::UserPath::LogDir));
|
||||||
Log::AddBackend(std::make_unique<Log::FileBackend>(
|
Log::AddBackend(std::make_unique<Log::FileBackend>(
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::LogDir) + LOG_FILE));
|
Common::FS::GetUserPath(Common::FS::UserPath::LogDir) + LOG_FILE));
|
||||||
LOG_INFO(Frontend, "Logging backend initialised");
|
LOG_INFO(Frontend, "Logging backend initialised");
|
||||||
|
|
||||||
// Initialize misc classes
|
// Initialize misc classes
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/frontend/applets/default_applets.h"
|
#include "core/frontend/applets/default_applets.h"
|
||||||
@ -26,13 +25,14 @@
|
|||||||
#include "core/hle/service/am/am.h"
|
#include "core/hle/service/am/am.h"
|
||||||
#include "core/hle/service/nfc/nfc.h"
|
#include "core/hle/service/nfc/nfc.h"
|
||||||
#include "core/savestate.h"
|
#include "core/savestate.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "jni/android_common/android_common.h"
|
#include "jni/android_common/android_common.h"
|
||||||
#include "jni/applets/mii_selector.h"
|
#include "jni/applets/mii_selector.h"
|
||||||
#include "jni/applets/swkbd.h"
|
#include "jni/applets/swkbd.h"
|
||||||
#include "jni/camera/ndk_camera.h"
|
#include "jni/camera/ndk_camera.h"
|
||||||
#include "jni/camera/still_image_camera.h"
|
#include "jni/camera/still_image_camera.h"
|
||||||
#include "jni/config.h"
|
#include "jni/config.h"
|
||||||
#include "jni/emu_window/emu_window_vk.h"
|
#include "jni/emu_window/emu_window.h"
|
||||||
#include "jni/game_info.h"
|
#include "jni/game_info.h"
|
||||||
#include "jni/game_settings.h"
|
#include "jni/game_settings.h"
|
||||||
#include "jni/id_cache.h"
|
#include "jni/id_cache.h"
|
||||||
@ -48,7 +48,7 @@ namespace {
|
|||||||
|
|
||||||
ANativeWindow* s_surf;
|
ANativeWindow* s_surf;
|
||||||
|
|
||||||
std::unique_ptr<EmuWindow_Android_Vulkan> window;
|
std::unique_ptr<EmuWindow_Android> window;
|
||||||
|
|
||||||
std::atomic<bool> stop_run{true};
|
std::atomic<bool> stop_run{true};
|
||||||
std::atomic<bool> pause_emulation{false};
|
std::atomic<bool> pause_emulation{false};
|
||||||
@ -146,7 +146,7 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
|||||||
return Core::System::ResultStatus::ErrorLoader;
|
return Core::System::ResultStatus::ErrorLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
window = std::make_unique<EmuWindow_Android_Vulkan>(s_surf);
|
window = std::make_unique<EmuWindow_Android>(s_surf);
|
||||||
|
|
||||||
Core::System& system{Core::System::GetInstance()};
|
Core::System& system{Core::System::GetInstance()};
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
|||||||
Config{};
|
Config{};
|
||||||
// Replace with game-specific settings
|
// Replace with game-specific settings
|
||||||
u64 program_id{};
|
u64 program_id{};
|
||||||
FileUtil::SetCurrentRomPath(filepath);
|
Common::FS::SetCurrentRomPath(filepath);
|
||||||
auto app_loader = Loader::GetLoader(filepath);
|
auto app_loader = Loader::GetLoader(filepath);
|
||||||
if (app_loader) {
|
if (app_loader) {
|
||||||
app_loader->ReadProgramId(program_id);
|
app_loader->ReadProgramId(program_id);
|
||||||
@ -237,7 +237,7 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Ensure no audio bleeds out while game is paused
|
// Ensure no audio bleeds out while game is paused
|
||||||
const float volume = Settings::values.volume.GetValue();
|
const float volume = Settings::values.volume;
|
||||||
SCOPE_EXIT({ Settings::values.volume = volume; });
|
SCOPE_EXIT({ Settings::values.volume = volume; });
|
||||||
Settings::values.volume = 0;
|
Settings::values.volume = 0;
|
||||||
|
|
||||||
@ -305,18 +305,18 @@ void Java_org_citra_citra_1emu_NativeLibrary_SwapScreens(JNIEnv* env, [[maybe_un
|
|||||||
void Java_org_citra_citra_1emu_NativeLibrary_SetUserDirectory(JNIEnv* env,
|
void Java_org_citra_citra_1emu_NativeLibrary_SetUserDirectory(JNIEnv* env,
|
||||||
[[maybe_unused]] jclass clazz,
|
[[maybe_unused]] jclass clazz,
|
||||||
jstring j_directory) {
|
jstring j_directory) {
|
||||||
FileUtil::SetCurrentDir(GetJString(env, j_directory));
|
Common::FS::SetCurrentDir(GetJString(env, j_directory));
|
||||||
}
|
}
|
||||||
|
|
||||||
jobjectArray Java_org_citra_citra_1emu_NativeLibrary_GetInstalledGamePaths(
|
jobjectArray Java_org_citra_citra_1emu_NativeLibrary_GetInstalledGamePaths(
|
||||||
JNIEnv* env, [[maybe_unused]] jclass clazz) {
|
JNIEnv* env, [[maybe_unused]] jclass clazz) {
|
||||||
std::vector<std::string> games;
|
std::vector<std::string> games;
|
||||||
const FileUtil::DirectoryEntryCallable ScanDir =
|
const Common::FS::DirectoryEntryCallable ScanDir =
|
||||||
[&games, &ScanDir](u64*, const std::string& directory, const std::string& virtual_name) {
|
[&games, &ScanDir](u64*, const std::string& directory, const std::string& virtual_name) {
|
||||||
std::string path = directory + virtual_name;
|
std::string path = directory + virtual_name;
|
||||||
if (FileUtil::IsDirectory(path)) {
|
if (Common::FS::IsDirectory(path)) {
|
||||||
path += '/';
|
path += '/';
|
||||||
FileUtil::ForeachDirectoryEntry(nullptr, path, ScanDir);
|
Common::FS::ForeachDirectoryEntry(nullptr, path, ScanDir);
|
||||||
} else {
|
} else {
|
||||||
auto loader = Loader::GetLoader(path);
|
auto loader = Loader::GetLoader(path);
|
||||||
if (loader) {
|
if (loader) {
|
||||||
@ -330,12 +330,12 @@ jobjectArray Java_org_citra_citra_1emu_NativeLibrary_GetInstalledGamePaths(
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
ScanDir(nullptr, "",
|
ScanDir(nullptr, "",
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) +
|
Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir) +
|
||||||
"Nintendo "
|
"Nintendo "
|
||||||
"3DS/00000000000000000000000000000000/"
|
"3DS/00000000000000000000000000000000/"
|
||||||
"00000000000000000000000000000000/title/00040000");
|
"00000000000000000000000000000000/title/00040000");
|
||||||
ScanDir(nullptr, "",
|
ScanDir(nullptr, "",
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
|
Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) +
|
||||||
"00000000000000000000000000000000/title/00040010");
|
"00000000000000000000000000000000/title/00040010");
|
||||||
jobjectArray jgames = env->NewObjectArray(static_cast<jsize>(games.size()),
|
jobjectArray jgames = env->NewObjectArray(static_cast<jsize>(games.size()),
|
||||||
env->FindClass("java/lang/String"), nullptr);
|
env->FindClass("java/lang/String"), nullptr);
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -37,10 +37,6 @@
|
|||||||
<string name="init_time_description">Si el \"Tipo del reloj del sistema\" está en \"Reloj emulado\", ésto cambia la fecha y hora de inicio.</string>
|
<string name="init_time_description">Si el \"Tipo del reloj del sistema\" está en \"Reloj emulado\", ésto cambia la fecha y hora de inicio.</string>
|
||||||
<string name="emulated_region">Región emulada</string>
|
<string name="emulated_region">Región emulada</string>
|
||||||
<string name="emulated_language">Idioma emulado</string>
|
<string name="emulated_language">Idioma emulado</string>
|
||||||
<string name="plugin_loader">Activar \"3GX Plugin Loader\"</string>
|
|
||||||
<string name="plugin_loader_description">Carga \"3GX plugins\" de la SD emulada si están disponibles.</string>
|
|
||||||
<string name="allow_plugin_loader">Permiter que apps cambien el estado del \"plugin loader\"</string>
|
|
||||||
<string name="allow_plugin_loader_description">Permite a las aplicaciones homebrew activar el \"plugin loader\" incluso si está desactivado.</string>
|
|
||||||
|
|
||||||
<!-- Camera settings strings -->
|
<!-- Camera settings strings -->
|
||||||
<string name="inner_camera">Cámara interior</string>
|
<string name="inner_camera">Cámara interior</string>
|
||||||
|
@ -51,10 +51,6 @@
|
|||||||
<string name="init_time_description">If the \"System clock type\" setting is set to \"Simulated clock\", this changes the fixed date and time to start at.</string>
|
<string name="init_time_description">If the \"System clock type\" setting is set to \"Simulated clock\", this changes the fixed date and time to start at.</string>
|
||||||
<string name="emulated_region">Emulated region</string>
|
<string name="emulated_region">Emulated region</string>
|
||||||
<string name="emulated_language">Emulated language</string>
|
<string name="emulated_language">Emulated language</string>
|
||||||
<string name="plugin_loader">Enable 3GX Plugin Loader</string>
|
|
||||||
<string name="plugin_loader_description">Loads 3GX plugins from the emulated SD if they are available.</string>
|
|
||||||
<string name="allow_plugin_loader">Allow apps to change plugin loader state</string>
|
|
||||||
<string name="allow_plugin_loader_description">Allow homebrew apps to enable the plugin loader even when it is disabled.</string>
|
|
||||||
|
|
||||||
<!-- Camera settings strings -->
|
<!-- Camera settings strings -->
|
||||||
<string name="inner_camera">Inner Camera</string>
|
<string name="inner_camera">Inner Camera</string>
|
||||||
|
@ -7,7 +7,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.3.1'
|
classpath 'com.android.tools.build:gradle:7.2.0'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
@ -23,7 +23,6 @@ add_library(audio_core STATIC
|
|||||||
interpolate.cpp
|
interpolate.cpp
|
||||||
interpolate.h
|
interpolate.h
|
||||||
null_sink.h
|
null_sink.h
|
||||||
precompiled_headers.h
|
|
||||||
sink.h
|
sink.h
|
||||||
sink_details.cpp
|
sink_details.cpp
|
||||||
sink_details.h
|
sink_details.h
|
||||||
@ -90,7 +89,3 @@ if(ENABLE_CUBEB)
|
|||||||
target_link_libraries(audio_core PRIVATE cubeb)
|
target_link_libraries(audio_core PRIVATE cubeb)
|
||||||
target_compile_definitions(audio_core PUBLIC HAVE_CUBEB)
|
target_compile_definitions(audio_core PUBLIC HAVE_CUBEB)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
|
||||||
target_precompile_headers(audio_core PRIVATE precompiled_headers.h)
|
|
||||||
endif()
|
|
||||||
|
@ -7,18 +7,17 @@
|
|||||||
#include "audio_core/sink.h"
|
#include "audio_core/sink.h"
|
||||||
#include "audio_core/sink_details.h"
|
#include "audio_core/sink_details.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/dumping/backend.h"
|
#include "core/dumping/backend.h"
|
||||||
|
#include "core/settings.h"
|
||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
|
|
||||||
DspInterface::DspInterface() = default;
|
DspInterface::DspInterface() = default;
|
||||||
DspInterface::~DspInterface() = default;
|
DspInterface::~DspInterface() = default;
|
||||||
|
|
||||||
void DspInterface::SetSink(std::string_view sink_id, std::string_view audio_device) {
|
void DspInterface::SetSink(const std::string& sink_id, const std::string& audio_device) {
|
||||||
sink = CreateSinkFromID(Settings::values.sink_id.GetValue(),
|
sink = CreateSinkFromID(Settings::values.sink_id, Settings::values.audio_device_id);
|
||||||
Settings::values.audio_device_id.GetValue());
|
|
||||||
sink->SetCallback(
|
sink->SetCallback(
|
||||||
[this](s16* buffer, std::size_t num_frames) { OutputCallback(buffer, num_frames); });
|
[this](s16* buffer, std::size_t num_frames) { OutputCallback(buffer, num_frames); });
|
||||||
time_stretcher.SetOutputSampleRate(sink->GetNativeSampleRate());
|
time_stretcher.SetOutputSampleRate(sink->GetNativeSampleRate());
|
||||||
@ -87,7 +86,7 @@ void DspInterface::OutputCallback(s16* buffer, std::size_t num_frames) {
|
|||||||
|
|
||||||
// Implementation of the hardware volume slider
|
// Implementation of the hardware volume slider
|
||||||
// A cubic curve is used to approximate a linear change in human-perceived loudness
|
// A cubic curve is used to approximate a linear change in human-perceived loudness
|
||||||
const float linear_volume = std::clamp(Settings::Volume(), 0.0f, 1.0f);
|
const float linear_volume = std::clamp(Settings::values.volume, 0.0f, 1.0f);
|
||||||
if (linear_volume != 1.0) {
|
if (linear_volume != 1.0) {
|
||||||
const float volume_scale_factor = linear_volume * linear_volume * linear_volume;
|
const float volume_scale_factor = linear_volume * linear_volume * linear_volume;
|
||||||
for (std::size_t i = 0; i < num_frames; i++) {
|
for (std::size_t i = 0; i < num_frames; i++) {
|
||||||
|
@ -94,7 +94,7 @@ public:
|
|||||||
virtual void UnloadComponent() = 0;
|
virtual void UnloadComponent() = 0;
|
||||||
|
|
||||||
/// Select the sink to use based on sink id.
|
/// Select the sink to use based on sink id.
|
||||||
void SetSink(std::string_view sink_id, std::string_view audio_device);
|
void SetSink(const std::string& sink_id, const std::string& audio_device);
|
||||||
/// Get the current sink
|
/// Get the current sink
|
||||||
Sink& GetSink();
|
Sink& GetSink();
|
||||||
/// Enable/Disable audio stretching.
|
/// Enable/Disable audio stretching.
|
||||||
|
@ -43,8 +43,8 @@ FuncDL<int(AVCodecParserContext*, AVCodecContext*, uint8_t**, int*, const uint8_
|
|||||||
FuncDL<void(AVCodecParserContext*)> av_parser_close_dl;
|
FuncDL<void(AVCodecParserContext*)> av_parser_close_dl;
|
||||||
|
|
||||||
bool InitFFmpegDL() {
|
bool InitFFmpegDL() {
|
||||||
std::string dll_path = FileUtil::GetUserPath(FileUtil::UserPath::DLLDir);
|
std::string dll_path = Common::FS::GetUserPath(Common::FS::UserPath::DLLDir);
|
||||||
FileUtil::CreateDir(dll_path);
|
Common::FS::CreateDir(dll_path);
|
||||||
std::wstring w_dll_path = Common::UTF8ToUTF16W(dll_path);
|
std::wstring w_dll_path = Common::UTF8ToUTF16W(dll_path);
|
||||||
SetDllDirectoryW(w_dll_path.c_str());
|
SetDllDirectoryW(w_dll_path.c_str());
|
||||||
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
// Copyright 2022 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/common_precompiled_headers.h"
|
|
@ -10,7 +10,6 @@ add_executable(citra
|
|||||||
emu_window/emu_window_sdl2.h
|
emu_window/emu_window_sdl2.h
|
||||||
lodepng_image_interface.cpp
|
lodepng_image_interface.cpp
|
||||||
lodepng_image_interface.h
|
lodepng_image_interface.h
|
||||||
precompiled_headers.h
|
|
||||||
resource.h
|
resource.h
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,7 +30,3 @@ if (MSVC)
|
|||||||
include(CopyCitraSDLDeps)
|
include(CopyCitraSDLDeps)
|
||||||
copy_citra_SDL_deps(citra)
|
copy_citra_SDL_deps(citra)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
|
||||||
target_precompile_headers(citra PRIVATE precompiled_headers.h)
|
|
||||||
endif()
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/dumping/backend.h"
|
#include "core/dumping/backend.h"
|
||||||
@ -28,7 +27,7 @@
|
|||||||
#include "core/hle/service/am/am.h"
|
#include "core/hle/service/am/am.h"
|
||||||
#include "core/hle/service/cfg/cfg.h"
|
#include "core/hle/service/cfg/cfg.h"
|
||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "input_common/main.h"
|
#include "core/settings.h"
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
|
|
||||||
@ -133,8 +132,7 @@ static void OnNetworkError(const Network::RoomMember::Error& error) {
|
|||||||
LOG_ERROR(Network, "You have been banned by the host");
|
LOG_ERROR(Network, "You have been banned by the host");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Network, "Unknown network error: {}", error);
|
LOG_ERROR(Network, "Unknown network error {}", error);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,13 +165,13 @@ static void OnStatusMessageReceived(const Network::StatusMessageEntry& msg) {
|
|||||||
|
|
||||||
static void InitializeLogging() {
|
static void InitializeLogging() {
|
||||||
Log::Filter log_filter(Log::Level::Debug);
|
Log::Filter log_filter(Log::Level::Debug);
|
||||||
log_filter.ParseFilterString(Settings::values.log_filter.GetValue());
|
log_filter.ParseFilterString(Settings::values.log_filter);
|
||||||
Log::SetGlobalFilter(log_filter);
|
Log::SetGlobalFilter(log_filter);
|
||||||
|
|
||||||
Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());
|
Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());
|
||||||
|
|
||||||
const std::string& log_dir = FileUtil::GetUserPath(FileUtil::UserPath::LogDir);
|
const std::string& log_dir = Common::FS::GetUserPath(Common::FS::UserPath::LogDir);
|
||||||
FileUtil::CreateFullPath(log_dir);
|
Common::FS::CreateFullPath(log_dir);
|
||||||
Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE));
|
Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE));
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
Log::AddBackend(std::make_unique<Log::DebuggerBackend>());
|
Log::AddBackend(std::make_unique<Log::DebuggerBackend>());
|
||||||
@ -185,8 +183,8 @@ int main(int argc, char** argv) {
|
|||||||
Common::DetachedTasks detached_tasks;
|
Common::DetachedTasks detached_tasks;
|
||||||
Config config;
|
Config config;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
bool use_gdbstub = Settings::values.use_gdbstub.GetValue();
|
bool use_gdbstub = Settings::values.use_gdbstub;
|
||||||
u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port.GetValue());
|
u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port);
|
||||||
std::string movie_record;
|
std::string movie_record;
|
||||||
std::string movie_record_author;
|
std::string movie_record_author;
|
||||||
std::string movie_play;
|
std::string movie_play;
|
||||||
@ -353,23 +351,11 @@ int main(int argc, char** argv) {
|
|||||||
// Register generic image interface
|
// Register generic image interface
|
||||||
Core::System::GetInstance().RegisterImageInterface(std::make_shared<LodePNGImageInterface>());
|
Core::System::GetInstance().RegisterImageInterface(std::make_shared<LodePNGImageInterface>());
|
||||||
|
|
||||||
EmuWindow_SDL2::InitializeSDL2();
|
std::unique_ptr<EmuWindow_SDL2> emu_window{std::make_unique<EmuWindow_SDL2>(fullscreen)};
|
||||||
|
|
||||||
const auto emu_window{std::make_unique<EmuWindow_SDL2>(fullscreen, false)};
|
|
||||||
const bool use_secondary_window{Settings::values.layout_option.GetValue() ==
|
|
||||||
Settings::LayoutOption::SeparateWindows};
|
|
||||||
const auto secondary_window =
|
|
||||||
use_secondary_window ? std::make_unique<EmuWindow_SDL2>(false, true) : nullptr;
|
|
||||||
|
|
||||||
const auto scope = emu_window->Acquire();
|
const auto scope = emu_window->Acquire();
|
||||||
|
|
||||||
LOG_INFO(Frontend, "Citra Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch,
|
|
||||||
Common::g_scm_desc);
|
|
||||||
Settings::LogSettings();
|
|
||||||
|
|
||||||
Core::System& system = Core::System::GetInstance();
|
Core::System& system = Core::System::GetInstance();
|
||||||
const Core::System::ResultStatus load_result{
|
|
||||||
system.Load(*emu_window, filepath, secondary_window.get())};
|
const Core::System::ResultStatus load_result{system.Load(*emu_window, filepath)};
|
||||||
|
|
||||||
switch (load_result) {
|
switch (load_result) {
|
||||||
case Core::System::ResultStatus::ErrorGetLoader:
|
case Core::System::ResultStatus::ErrorGetLoader:
|
||||||
@ -437,12 +423,7 @@ int main(int argc, char** argv) {
|
|||||||
system.VideoDumper().StartDumping(dump_video, layout);
|
system.VideoDumper().StartDumping(dump_video, layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::thread main_render_thread([&emu_window] { emu_window->Present(); });
|
std::thread render_thread([&emu_window] { emu_window->Present(); });
|
||||||
std::thread secondary_render_thread([&secondary_window] {
|
|
||||||
if (secondary_window) {
|
|
||||||
secondary_window->Present();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
std::atomic_bool stop_run;
|
std::atomic_bool stop_run;
|
||||||
system.Renderer().Rasterizer()->LoadDiskResources(
|
system.Renderer().Rasterizer()->LoadDiskResources(
|
||||||
@ -451,11 +432,7 @@ int main(int argc, char** argv) {
|
|||||||
total);
|
total);
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto secondary_is_open = [&secondary_window] {
|
while (emu_window->IsOpen()) {
|
||||||
// if the secondary window isn't created, it shouldn't affect the main loop
|
|
||||||
return secondary_window ? secondary_window->IsOpen() : true;
|
|
||||||
};
|
|
||||||
while (emu_window->IsOpen() && secondary_is_open()) {
|
|
||||||
const auto result = system.RunLoop();
|
const auto result = system.RunLoop();
|
||||||
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
@ -469,21 +446,13 @@ int main(int argc, char** argv) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emu_window->RequestClose();
|
render_thread.join();
|
||||||
if (secondary_window) {
|
|
||||||
secondary_window->RequestClose();
|
|
||||||
}
|
|
||||||
main_render_thread.join();
|
|
||||||
secondary_render_thread.join();
|
|
||||||
|
|
||||||
Core::Movie::GetInstance().Shutdown();
|
Core::Movie::GetInstance().Shutdown();
|
||||||
if (system.VideoDumper().IsDumping()) {
|
if (system.VideoDumper().IsDumping()) {
|
||||||
system.VideoDumper().StopDumping();
|
system.VideoDumper().StopDumping();
|
||||||
}
|
}
|
||||||
|
|
||||||
Network::Shutdown();
|
|
||||||
InputCommon::Shutdown();
|
|
||||||
|
|
||||||
system.Shutdown();
|
system.Shutdown();
|
||||||
|
|
||||||
detached_tasks.WaitForAllTasks();
|
detached_tasks.WaitForAllTasks();
|
||||||
|
@ -13,16 +13,16 @@
|
|||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/frontend/mic.h"
|
#include "core/frontend/mic.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/udp/client.h"
|
#include "input_common/udp/client.h"
|
||||||
#include "network/network_settings.h"
|
#include "network/network_settings.h"
|
||||||
|
|
||||||
Config::Config() {
|
Config::Config() {
|
||||||
// TODO: Don't hardcode the path; let the frontend decide where to put the config files.
|
// TODO: Don't hardcode the path; let the frontend decide where to put the config files.
|
||||||
sdl2_config_loc = FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + "sdl2-config.ini";
|
sdl2_config_loc = Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir) + "sdl2-config.ini";
|
||||||
sdl2_config = std::make_unique<INIReader>(sdl2_config_loc);
|
sdl2_config = std::make_unique<INIReader>(sdl2_config_loc);
|
||||||
|
|
||||||
Reload();
|
Reload();
|
||||||
@ -35,8 +35,8 @@ bool Config::LoadINI(const std::string& default_contents, bool retry) {
|
|||||||
if (sdl2_config->ParseError() < 0) {
|
if (sdl2_config->ParseError() < 0) {
|
||||||
if (retry) {
|
if (retry) {
|
||||||
LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", location);
|
LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", location);
|
||||||
FileUtil::CreateFullPath(location);
|
Common::FS::CreateFullPath(location);
|
||||||
FileUtil::WriteStringToFile(true, location, default_contents);
|
Common::FS::WriteStringToFile(true, location, default_contents);
|
||||||
sdl2_config = std::make_unique<INIReader>(location); // Reopen file
|
sdl2_config = std::make_unique<INIReader>(location); // Reopen file
|
||||||
|
|
||||||
return LoadINI(default_contents, false);
|
return LoadINI(default_contents, false);
|
||||||
@ -129,23 +129,24 @@ void Config::ReadValues() {
|
|||||||
sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", true);
|
sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", true);
|
||||||
Settings::values.frame_limit =
|
Settings::values.frame_limit =
|
||||||
static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100));
|
static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100));
|
||||||
|
Settings::values.use_frame_limit_alternate =
|
||||||
|
sdl2_config->GetBoolean("Renderer", "use_frame_limit_alternate", false);
|
||||||
|
Settings::values.frame_limit_alternate =
|
||||||
|
static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit_alternate", 200));
|
||||||
Settings::values.use_vsync_new =
|
Settings::values.use_vsync_new =
|
||||||
static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync_new", 1));
|
static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync_new", 1));
|
||||||
Settings::values.texture_filter_name =
|
Settings::values.texture_filter_name =
|
||||||
sdl2_config->GetString("Renderer", "texture_filter_name", "none");
|
sdl2_config->GetString("Renderer", "texture_filter_name", "none");
|
||||||
|
|
||||||
Settings::values.mono_render_option = static_cast<Settings::MonoRenderOption>(
|
|
||||||
sdl2_config->GetInteger("Renderer", "mono_render_option", 0));
|
|
||||||
Settings::values.render_3d = static_cast<Settings::StereoRenderOption>(
|
Settings::values.render_3d = static_cast<Settings::StereoRenderOption>(
|
||||||
sdl2_config->GetInteger("Renderer", "render_3d", 0));
|
sdl2_config->GetInteger("Renderer", "render_3d", 0));
|
||||||
Settings::values.factor_3d =
|
Settings::values.factor_3d =
|
||||||
static_cast<u8>(sdl2_config->GetInteger("Renderer", "factor_3d", 0));
|
static_cast<u8>(sdl2_config->GetInteger("Renderer", "factor_3d", 0));
|
||||||
std::string default_shader = "none (builtin)";
|
std::string default_shader = "none (builtin)";
|
||||||
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph)
|
if (Settings::values.render_3d == Settings::StereoRenderOption::Anaglyph)
|
||||||
default_shader = "dubois (builtin)";
|
default_shader = "dubois (builtin)";
|
||||||
else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced ||
|
else if (Settings::values.render_3d == Settings::StereoRenderOption::Interlaced ||
|
||||||
Settings::values.render_3d.GetValue() ==
|
Settings::values.render_3d == Settings::StereoRenderOption::ReverseInterlaced)
|
||||||
Settings::StereoRenderOption::ReverseInterlaced)
|
|
||||||
default_shader = "horizontal (builtin)";
|
default_shader = "horizontal (builtin)";
|
||||||
Settings::values.pp_shader_name =
|
Settings::values.pp_shader_name =
|
||||||
sdl2_config->GetString("Renderer", "pp_shader_name", default_shader);
|
sdl2_config->GetString("Renderer", "pp_shader_name", default_shader);
|
||||||
@ -186,8 +187,9 @@ void Config::ReadValues() {
|
|||||||
sdl2_config->GetBoolean("Utility", "preload_textures", false);
|
sdl2_config->GetBoolean("Utility", "preload_textures", false);
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
Settings::values.audio_emulation = static_cast<Settings::AudioEmulation>(
|
Settings::values.enable_dsp_lle = sdl2_config->GetBoolean("Audio", "enable_dsp_lle", false);
|
||||||
sdl2_config->GetInteger("Audio", "audio_emulation", 0));
|
Settings::values.enable_dsp_lle_multithread =
|
||||||
|
sdl2_config->GetBoolean("Audio", "enable_dsp_lle_multithread", false);
|
||||||
Settings::values.sink_id = sdl2_config->GetString("Audio", "output_engine", "auto");
|
Settings::values.sink_id = sdl2_config->GetString("Audio", "output_engine", "auto");
|
||||||
Settings::values.enable_audio_stretching =
|
Settings::values.enable_audio_stretching =
|
||||||
sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true);
|
sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true);
|
||||||
@ -206,9 +208,9 @@ void Config::ReadValues() {
|
|||||||
sdl2_config->GetBoolean("Data Storage", "use_custom_storage", false);
|
sdl2_config->GetBoolean("Data Storage", "use_custom_storage", false);
|
||||||
|
|
||||||
if (Settings::values.use_custom_storage) {
|
if (Settings::values.use_custom_storage) {
|
||||||
FileUtil::UpdateUserPath(FileUtil::UserPath::NANDDir,
|
Common::FS::UpdateUserPath(Common::FS::UserPath::NANDDir,
|
||||||
sdl2_config->GetString("Data Storage", "nand_directory", ""));
|
sdl2_config->GetString("Data Storage", "nand_directory", ""));
|
||||||
FileUtil::UpdateUserPath(FileUtil::UserPath::SDMCDir,
|
Common::FS::UpdateUserPath(Common::FS::UserPath::SDMCDir,
|
||||||
sdl2_config->GetString("Data Storage", "sdmc_directory", ""));
|
sdl2_config->GetString("Data Storage", "sdmc_directory", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,58 +241,6 @@ void Config::ReadValues() {
|
|||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
constexpr const char* default_init_time_offset = "0 00:00:00";
|
|
||||||
|
|
||||||
std::string offset_string =
|
|
||||||
sdl2_config->GetString("System", "init_time_offset", default_init_time_offset);
|
|
||||||
|
|
||||||
size_t sep_index = offset_string.find(' ');
|
|
||||||
|
|
||||||
if (sep_index == std::string::npos) {
|
|
||||||
LOG_ERROR(Config, "Failed to parse init_time_offset. Using 0 00:00:00");
|
|
||||||
offset_string = default_init_time_offset;
|
|
||||||
|
|
||||||
sep_index = offset_string.find(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string day_string = offset_string.substr(0, sep_index);
|
|
||||||
long long days = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
days = std::stoll(day_string);
|
|
||||||
} catch (std::logic_error&) {
|
|
||||||
LOG_ERROR(Config, "Failed to parse days in init_time_offset. Using 0");
|
|
||||||
days = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
long long days_in_seconds = days * 86400;
|
|
||||||
|
|
||||||
std::tm t;
|
|
||||||
t.tm_sec = 0;
|
|
||||||
t.tm_min = 0;
|
|
||||||
t.tm_hour = 0;
|
|
||||||
t.tm_mday = 1;
|
|
||||||
t.tm_mon = 0;
|
|
||||||
t.tm_year = 100;
|
|
||||||
t.tm_isdst = 0;
|
|
||||||
|
|
||||||
std::istringstream string_stream(offset_string.substr(sep_index + 1));
|
|
||||||
string_stream >> std::get_time(&t, "%H:%M:%S");
|
|
||||||
|
|
||||||
if (string_stream.fail()) {
|
|
||||||
LOG_ERROR(Config,
|
|
||||||
"Failed to parse hours, minutes and seconds in init_time_offset. 00:00:00");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto time_offset =
|
|
||||||
std::chrono::system_clock::from_time_t(std::mktime(&t)).time_since_epoch();
|
|
||||||
|
|
||||||
auto secs = std::chrono::duration_cast<std::chrono::seconds>(time_offset).count();
|
|
||||||
|
|
||||||
Settings::values.init_time_offset = static_cast<long long>(secs) + days_in_seconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Camera
|
// Camera
|
||||||
using namespace Service::CAM;
|
using namespace Service::CAM;
|
||||||
Settings::values.camera_name[OuterRightCamera] =
|
Settings::values.camera_name[OuterRightCamera] =
|
||||||
|
@ -166,10 +166,6 @@ render_3d =
|
|||||||
# 0 - 100: Intensity. 0 (default)
|
# 0 - 100: Intensity. 0 (default)
|
||||||
factor_3d =
|
factor_3d =
|
||||||
|
|
||||||
# Change Default Eye to Render When in Monoscopic Mode
|
|
||||||
# 0 (default): Left, 1: Right
|
|
||||||
mono_render_option =
|
|
||||||
|
|
||||||
# The name of the post processing shader to apply.
|
# The name of the post processing shader to apply.
|
||||||
# Loaded from shaders if render_3d is off or side by side.
|
# Loaded from shaders if render_3d is off or side by side.
|
||||||
# Loaded from shaders/anaglyph if render_3d is anaglyph
|
# Loaded from shaders/anaglyph if render_3d is anaglyph
|
||||||
@ -182,11 +178,7 @@ filter_mode =
|
|||||||
|
|
||||||
[Layout]
|
[Layout]
|
||||||
# Layout for the screen inside the render window.
|
# Layout for the screen inside the render window.
|
||||||
# 0 (default): Default Top Bottom Screen
|
# 0 (default): Default Top Bottom Screen, 1: Single Screen Only, 2: Large Screen Small Screen, 3: Side by Side
|
||||||
# 1: Single Screen Only
|
|
||||||
# 2: Large Screen Small Screen
|
|
||||||
# 3: Side by Side
|
|
||||||
# 4: Separate Windows
|
|
||||||
layout_option =
|
layout_option =
|
||||||
|
|
||||||
# Toggle custom layout (using the settings below) on or off.
|
# Toggle custom layout (using the settings below) on or off.
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
#include "citra/emu_window/emu_window_sdl2.h"
|
#include "citra/emu_window/emu_window_sdl2.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/3ds.h"
|
#include "core/3ds.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "input_common/keyboard.h"
|
#include "input_common/keyboard.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/motion_emu.h"
|
#include "input_common/motion_emu.h"
|
||||||
@ -135,10 +135,19 @@ void EmuWindow_SDL2::Fullscreen() {
|
|||||||
SDL_MaximizeWindow(render_window);
|
SDL_MaximizeWindow(render_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen, bool is_secondary) : EmuWindow(is_secondary) {
|
EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) {
|
||||||
// Initialize the window
|
// Initialize the window
|
||||||
const bool is_opengles =
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0) {
|
||||||
Settings::values.graphics_api.GetValue() == Settings::GraphicsAPI::OpenGLES;
|
LOG_CRITICAL(Frontend, "Failed to initialize SDL2: {}! Exiting...", SDL_GetError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputCommon::Init();
|
||||||
|
Network::Init();
|
||||||
|
|
||||||
|
SDL_SetMainReady();
|
||||||
|
|
||||||
|
const bool is_opengles = Settings::values.graphics_api == Settings::GraphicsAPI::OpenGLES;
|
||||||
if (is_opengles) {
|
if (is_opengles) {
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||||
@ -193,7 +202,6 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen, bool is_secondary) : EmuWindow(i
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
render_window_id = SDL_GetWindowID(render_window);
|
|
||||||
auto gl_load_func = is_opengles ? gladLoadGLES2Loader : gladLoadGLLoader;
|
auto gl_load_func = is_opengles ? gladLoadGLES2Loader : gladLoadGLLoader;
|
||||||
|
|
||||||
if (!gl_load_func(static_cast<GLADloadproc>(SDL_GL_GetProcAddress))) {
|
if (!gl_load_func(static_cast<GLADloadproc>(SDL_GL_GetProcAddress))) {
|
||||||
@ -204,26 +212,19 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen, bool is_secondary) : EmuWindow(i
|
|||||||
OnResize();
|
OnResize();
|
||||||
OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size);
|
OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size);
|
||||||
SDL_PumpEvents();
|
SDL_PumpEvents();
|
||||||
|
LOG_INFO(Frontend, "Citra Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch,
|
||||||
|
Common::g_scm_desc);
|
||||||
|
Settings::LogSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
EmuWindow_SDL2::~EmuWindow_SDL2() {
|
EmuWindow_SDL2::~EmuWindow_SDL2() {
|
||||||
core_context.reset();
|
core_context.reset();
|
||||||
|
Network::Shutdown();
|
||||||
|
InputCommon::Shutdown();
|
||||||
SDL_GL_DeleteContext(window_context);
|
SDL_GL_DeleteContext(window_context);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuWindow_SDL2::InitializeSDL2() {
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0) {
|
|
||||||
LOG_CRITICAL(Frontend, "Failed to initialize SDL2: {}! Exiting...", SDL_GetError());
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
InputCommon::Init();
|
|
||||||
Network::Init();
|
|
||||||
|
|
||||||
SDL_SetMainReady();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Frontend::GraphicsContext> EmuWindow_SDL2::CreateSharedContext() const {
|
std::unique_ptr<Frontend::GraphicsContext> EmuWindow_SDL2::CreateSharedContext() const {
|
||||||
return std::make_unique<SharedContext_SDL2>();
|
return std::make_unique<SharedContext_SDL2>();
|
||||||
}
|
}
|
||||||
@ -240,7 +241,7 @@ void EmuWindow_SDL2::Present() {
|
|||||||
SDL_GL_MakeCurrent(render_window, window_context);
|
SDL_GL_MakeCurrent(render_window, window_context);
|
||||||
SDL_GL_SetSwapInterval(1);
|
SDL_GL_SetSwapInterval(1);
|
||||||
while (IsOpen()) {
|
while (IsOpen()) {
|
||||||
VideoCore::g_renderer->TryPresent(100, is_secondary);
|
VideoCore::g_renderer->TryPresent(100);
|
||||||
SDL_GL_SwapWindow(render_window);
|
SDL_GL_SwapWindow(render_window);
|
||||||
}
|
}
|
||||||
SDL_GL_MakeCurrent(render_window, nullptr);
|
SDL_GL_MakeCurrent(render_window, nullptr);
|
||||||
@ -248,14 +249,9 @@ void EmuWindow_SDL2::Present() {
|
|||||||
|
|
||||||
void EmuWindow_SDL2::PollEvents() {
|
void EmuWindow_SDL2::PollEvents() {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
std::vector<SDL_Event> other_window_events;
|
|
||||||
|
|
||||||
// SDL_PollEvent returns 0 when there are no more events in the event queue
|
// SDL_PollEvent returns 0 when there are no more events in the event queue
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
if (event.window.windowID != render_window_id) {
|
|
||||||
other_window_events.push_back(event);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
switch (event.window.event) {
|
switch (event.window.event) {
|
||||||
@ -304,13 +300,16 @@ void EmuWindow_SDL2::PollEvents() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto& e : other_window_events) {
|
|
||||||
// This is a somewhat hacky workaround to re-emit window events meant for another window
|
const u32 current_time = SDL_GetTicks();
|
||||||
// since SDL_PollEvent() is global but we poll events per window.
|
if (current_time > last_time + 2000) {
|
||||||
SDL_PushEvent(&e);
|
const auto results = Core::System::GetInstance().GetAndResetPerfStats();
|
||||||
}
|
const auto title =
|
||||||
if (!is_secondary) {
|
fmt::format("Citra {} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname,
|
||||||
UpdateFramerateCounter();
|
Common::g_scm_branch, Common::g_scm_desc, results.game_fps,
|
||||||
|
results.emulation_speed * 100.0f);
|
||||||
|
SDL_SetWindowTitle(render_window, title.c_str());
|
||||||
|
last_time = current_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,16 +324,3 @@ void EmuWindow_SDL2::DoneCurrent() {
|
|||||||
void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) {
|
void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) {
|
||||||
SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second);
|
SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuWindow_SDL2::UpdateFramerateCounter() {
|
|
||||||
const u32 current_time = SDL_GetTicks();
|
|
||||||
if (current_time > last_time + 2000) {
|
|
||||||
const auto results = Core::System::GetInstance().GetAndResetPerfStats();
|
|
||||||
const auto title =
|
|
||||||
fmt::format("Citra {} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname,
|
|
||||||
Common::g_scm_branch, Common::g_scm_desc, results.game_fps,
|
|
||||||
results.emulation_speed * 100.0f);
|
|
||||||
SDL_SetWindowTitle(render_window, title.c_str());
|
|
||||||
last_time = current_time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -29,11 +29,9 @@ private:
|
|||||||
|
|
||||||
class EmuWindow_SDL2 : public Frontend::EmuWindow {
|
class EmuWindow_SDL2 : public Frontend::EmuWindow {
|
||||||
public:
|
public:
|
||||||
explicit EmuWindow_SDL2(bool fullscreen, bool is_secondary);
|
explicit EmuWindow_SDL2(bool fullscreen);
|
||||||
~EmuWindow_SDL2();
|
~EmuWindow_SDL2();
|
||||||
|
|
||||||
static void InitializeSDL2();
|
|
||||||
|
|
||||||
void Present();
|
void Present();
|
||||||
|
|
||||||
/// Polls window events
|
/// Polls window events
|
||||||
@ -90,18 +88,12 @@ private:
|
|||||||
/// Called when a configuration change affects the minimal size of the window
|
/// Called when a configuration change affects the minimal size of the window
|
||||||
void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override;
|
void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override;
|
||||||
|
|
||||||
/// Called when polling to update framerate
|
|
||||||
void UpdateFramerateCounter();
|
|
||||||
|
|
||||||
/// Is the window still open?
|
/// Is the window still open?
|
||||||
bool is_open = true;
|
bool is_open = true;
|
||||||
|
|
||||||
/// Internal SDL2 render window
|
/// Internal SDL2 render window
|
||||||
SDL_Window* render_window;
|
SDL_Window* render_window;
|
||||||
|
|
||||||
/// Internal SDL2 window ID
|
|
||||||
int render_window_id{};
|
|
||||||
|
|
||||||
/// Fake hidden window for the core context
|
/// Fake hidden window for the core context
|
||||||
SDL_Window* dummy_window;
|
SDL_Window* dummy_window;
|
||||||
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
// Copyright 2022 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/common_precompiled_headers.h"
|
|
@ -38,8 +38,6 @@ add_executable(citra-qt
|
|||||||
configuration/config.cpp
|
configuration/config.cpp
|
||||||
configuration/config.h
|
configuration/config.h
|
||||||
configuration/configure.ui
|
configuration/configure.ui
|
||||||
configuration/configuration_shared.cpp
|
|
||||||
configuration/configuration_shared.h
|
|
||||||
configuration/configure_audio.cpp
|
configuration/configure_audio.cpp
|
||||||
configuration/configure_audio.h
|
configuration/configure_audio.h
|
||||||
configuration/configure_audio.ui
|
configuration/configure_audio.ui
|
||||||
@ -69,9 +67,6 @@ add_executable(citra-qt
|
|||||||
configuration/configure_motion_touch.cpp
|
configuration/configure_motion_touch.cpp
|
||||||
configuration/configure_motion_touch.h
|
configuration/configure_motion_touch.h
|
||||||
configuration/configure_motion_touch.ui
|
configuration/configure_motion_touch.ui
|
||||||
configuration/configure_per_game.cpp
|
|
||||||
configuration/configure_per_game.h
|
|
||||||
configuration/configure_per_game.ui
|
|
||||||
configuration/configure_storage.cpp
|
configuration/configure_storage.cpp
|
||||||
configuration/configure_storage.h
|
configuration/configure_storage.h
|
||||||
configuration/configure_storage.ui
|
configuration/configure_storage.ui
|
||||||
@ -164,7 +159,6 @@ add_executable(citra-qt
|
|||||||
multiplayer/state.cpp
|
multiplayer/state.cpp
|
||||||
multiplayer/state.h
|
multiplayer/state.h
|
||||||
multiplayer/validation.h
|
multiplayer/validation.h
|
||||||
precompiled_headers.h
|
|
||||||
uisettings.cpp
|
uisettings.cpp
|
||||||
uisettings.h
|
uisettings.h
|
||||||
qt_image_interface.cpp
|
qt_image_interface.cpp
|
||||||
@ -250,8 +244,6 @@ if (APPLE)
|
|||||||
set_target_properties(citra-qt PROPERTIES MACOSX_BUNDLE TRUE)
|
set_target_properties(citra-qt PROPERTIES MACOSX_BUNDLE TRUE)
|
||||||
set_target_properties(citra-qt PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
|
set_target_properties(citra-qt PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
|
||||||
target_sources(citra-qt PRIVATE
|
target_sources(citra-qt PRIVATE
|
||||||
applesurfacehelper.h
|
|
||||||
applesurfacehelper.mm
|
|
||||||
macos_authorization.h
|
macos_authorization.h
|
||||||
macos_authorization.mm
|
macos_authorization.mm
|
||||||
)
|
)
|
||||||
@ -326,7 +318,3 @@ if (MSVC)
|
|||||||
copy_citra_FFmpeg_deps(citra-qt)
|
copy_citra_FFmpeg_deps(citra-qt)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
|
||||||
target_precompile_headers(citra-qt PRIVATE precompiled_headers.h)
|
|
||||||
endif()
|
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
// Copyright 2022 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace AppleSurfaceHelper {
|
|
||||||
|
|
||||||
void* GetSurfaceLayer(void* surface);
|
|
||||||
|
|
||||||
} // namespace AppleSurfaceHelper
|
|
@ -1,16 +0,0 @@
|
|||||||
// Copyright 2022 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
|
|
||||||
#include "citra_qt/applesurfacehelper.h"
|
|
||||||
|
|
||||||
namespace AppleSurfaceHelper {
|
|
||||||
|
|
||||||
void* GetSurfaceLayer(void* surface) {
|
|
||||||
NSView* view = static_cast<NSView*>(surface);
|
|
||||||
return view.layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // AppleSurfaceHelper
|
|
@ -15,19 +15,15 @@
|
|||||||
#include "citra_qt/main.h"
|
#include "citra_qt/main.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/3ds.h"
|
#include "core/3ds.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "input_common/keyboard.h"
|
#include "input_common/keyboard.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/motion_emu.h"
|
#include "input_common/motion_emu.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#include "citra_qt/applesurfacehelper.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
#include <qpa/qplatformnativeinterface.h>
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
#endif
|
#endif
|
||||||
@ -148,7 +144,7 @@ public:
|
|||||||
|
|
||||||
// disable vsync for any shared contexts
|
// disable vsync for any shared contexts
|
||||||
auto format = share_context->format();
|
auto format = share_context->format();
|
||||||
format.setSwapInterval(main_surface ? Settings::values.use_vsync_new.GetValue() : 0);
|
format.setSwapInterval(main_surface ? Settings::values.use_vsync_new : 0);
|
||||||
|
|
||||||
context = std::make_unique<QOpenGLContext>();
|
context = std::make_unique<QOpenGLContext>();
|
||||||
context->setShareContext(share_context);
|
context->setShareContext(share_context);
|
||||||
@ -281,8 +277,7 @@ private:
|
|||||||
|
|
||||||
class OpenGLRenderWidget : public RenderWidget {
|
class OpenGLRenderWidget : public RenderWidget {
|
||||||
public:
|
public:
|
||||||
explicit OpenGLRenderWidget(GRenderWindow* parent, bool is_secondary)
|
explicit OpenGLRenderWidget(GRenderWindow* parent) : RenderWidget(parent) {
|
||||||
: RenderWidget(parent), is_secondary(is_secondary) {
|
|
||||||
windowHandle()->setSurfaceType(QWindow::OpenGLSurface);
|
windowHandle()->setSurfaceType(QWindow::OpenGLSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,14 +295,13 @@ public:
|
|||||||
context->MakeCurrent();
|
context->MakeCurrent();
|
||||||
const auto f = context->GetShareContext()->extraFunctions();
|
const auto f = context->GetShareContext()->extraFunctions();
|
||||||
f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
VideoCore::g_renderer->TryPresent(100, is_secondary);
|
VideoCore::g_renderer->TryPresent(100);
|
||||||
context->SwapBuffers();
|
context->SwapBuffers();
|
||||||
f->glFinish();
|
f->glFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<OpenGLSharedContext> context{};
|
std::unique_ptr<OpenGLSharedContext> context{};
|
||||||
bool is_secondary;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class VulkanRenderWidget : public RenderWidget {
|
class VulkanRenderWidget : public RenderWidget {
|
||||||
@ -326,8 +320,6 @@ static Frontend::WindowSystemType GetWindowSystemType() {
|
|||||||
return Frontend::WindowSystemType::X11;
|
return Frontend::WindowSystemType::X11;
|
||||||
else if (platform_name == QStringLiteral("wayland"))
|
else if (platform_name == QStringLiteral("wayland"))
|
||||||
return Frontend::WindowSystemType::Wayland;
|
return Frontend::WindowSystemType::Wayland;
|
||||||
else if (platform_name == QStringLiteral("cocoa"))
|
|
||||||
return Frontend::WindowSystemType::MacOS;
|
|
||||||
|
|
||||||
LOG_CRITICAL(Frontend, "Unknown Qt platform!");
|
LOG_CRITICAL(Frontend, "Unknown Qt platform!");
|
||||||
return Frontend::WindowSystemType::Windows;
|
return Frontend::WindowSystemType::Windows;
|
||||||
@ -338,12 +330,8 @@ static Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window
|
|||||||
wsi.type = GetWindowSystemType();
|
wsi.type = GetWindowSystemType();
|
||||||
|
|
||||||
// Our Win32 Qt external doesn't have the private API.
|
// Our Win32 Qt external doesn't have the private API.
|
||||||
#if defined(WIN32)
|
#if defined(WIN32) || defined(__APPLE__)
|
||||||
wsi.render_surface = window ? reinterpret_cast<void*>(window->winId()) : nullptr;
|
wsi.render_surface = window ? reinterpret_cast<void*>(window->winId()) : nullptr;
|
||||||
#elif defined(__APPLE__)
|
|
||||||
wsi.render_surface =
|
|
||||||
window ? AppleSurfaceHelper::GetSurfaceLayer(reinterpret_cast<void*>(window->winId()))
|
|
||||||
: nullptr;
|
|
||||||
#else
|
#else
|
||||||
QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface();
|
QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface();
|
||||||
wsi.display_connection = pni->nativeResourceForWindow("display", window);
|
wsi.display_connection = pni->nativeResourceForWindow("display", window);
|
||||||
@ -357,8 +345,8 @@ static Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window
|
|||||||
return wsi;
|
return wsi;
|
||||||
}
|
}
|
||||||
|
|
||||||
GRenderWindow::GRenderWindow(QWidget* parent_, EmuThread* emu_thread, bool is_secondary_)
|
GRenderWindow::GRenderWindow(QWidget* parent_, EmuThread* emu_thread)
|
||||||
: QWidget(parent_), EmuWindow(is_secondary_), emu_thread(emu_thread) {
|
: QWidget(parent_), emu_thread(emu_thread) {
|
||||||
|
|
||||||
setWindowTitle(QStringLiteral("Citra %1 | %2-%3")
|
setWindowTitle(QStringLiteral("Citra %1 | %2-%3")
|
||||||
.arg(QString::fromUtf8(Common::g_build_name),
|
.arg(QString::fromUtf8(Common::g_build_name),
|
||||||
@ -368,6 +356,7 @@ GRenderWindow::GRenderWindow(QWidget* parent_, EmuThread* emu_thread, bool is_se
|
|||||||
auto layout = new QHBoxLayout(this);
|
auto layout = new QHBoxLayout(this);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
InputCommon::Init();
|
||||||
|
|
||||||
this->setMouseTracking(true);
|
this->setMouseTracking(true);
|
||||||
|
|
||||||
@ -375,7 +364,9 @@ GRenderWindow::GRenderWindow(QWidget* parent_, EmuThread* emu_thread, bool is_se
|
|||||||
connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete);
|
connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
GRenderWindow::~GRenderWindow() = default;
|
GRenderWindow::~GRenderWindow() {
|
||||||
|
InputCommon::Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
void GRenderWindow::MakeCurrent() {
|
void GRenderWindow::MakeCurrent() {
|
||||||
main_context->MakeCurrent();
|
main_context->MakeCurrent();
|
||||||
@ -540,12 +531,6 @@ bool GRenderWindow::event(QEvent* event) {
|
|||||||
void GRenderWindow::focusOutEvent(QFocusEvent* event) {
|
void GRenderWindow::focusOutEvent(QFocusEvent* event) {
|
||||||
QWidget::focusOutEvent(event);
|
QWidget::focusOutEvent(event);
|
||||||
InputCommon::GetKeyboard()->ReleaseAllKeys();
|
InputCommon::GetKeyboard()->ReleaseAllKeys();
|
||||||
has_focus = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GRenderWindow::focusInEvent(QFocusEvent* event) {
|
|
||||||
QWidget::focusInEvent(event);
|
|
||||||
has_focus = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::resizeEvent(QResizeEvent* event) {
|
void GRenderWindow::resizeEvent(QResizeEvent* event) {
|
||||||
@ -554,7 +539,7 @@ void GRenderWindow::resizeEvent(QResizeEvent* event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Frontend::GraphicsContext> GRenderWindow::CreateSharedContext() const {
|
std::unique_ptr<Frontend::GraphicsContext> GRenderWindow::CreateSharedContext() const {
|
||||||
const Settings::GraphicsAPI graphics_api = Settings::values.graphics_api.GetValue();
|
const Settings::GraphicsAPI graphics_api = Settings::values.graphics_api;
|
||||||
if (graphics_api == Settings::GraphicsAPI::OpenGL ||
|
if (graphics_api == Settings::GraphicsAPI::OpenGL ||
|
||||||
graphics_api == Settings::GraphicsAPI::OpenGLES) {
|
graphics_api == Settings::GraphicsAPI::OpenGLES) {
|
||||||
auto c = static_cast<OpenGLSharedContext*>(main_context.get());
|
auto c = static_cast<OpenGLSharedContext*>(main_context.get());
|
||||||
@ -578,7 +563,7 @@ bool GRenderWindow::InitRenderTarget() {
|
|||||||
|
|
||||||
first_frame = false;
|
first_frame = false;
|
||||||
|
|
||||||
const Settings::GraphicsAPI graphics_api = Settings::values.graphics_api.GetValue();
|
const Settings::GraphicsAPI graphics_api = Settings::values.graphics_api;
|
||||||
switch (graphics_api) {
|
switch (graphics_api) {
|
||||||
case Settings::GraphicsAPI::OpenGL:
|
case Settings::GraphicsAPI::OpenGL:
|
||||||
case Settings::GraphicsAPI::OpenGLES:
|
case Settings::GraphicsAPI::OpenGLES:
|
||||||
@ -622,11 +607,11 @@ void GRenderWindow::ReleaseRenderTarget() {
|
|||||||
void GRenderWindow::CaptureScreenshot(u32 res_scale, const QString& screenshot_path) {
|
void GRenderWindow::CaptureScreenshot(u32 res_scale, const QString& screenshot_path) {
|
||||||
if (res_scale == 0)
|
if (res_scale == 0)
|
||||||
res_scale = VideoCore::GetResolutionScaleFactor();
|
res_scale = VideoCore::GetResolutionScaleFactor();
|
||||||
const auto layout{Layout::FrameLayoutFromResolutionScale(res_scale, is_secondary)};
|
const Layout::FramebufferLayout layout{Layout::FrameLayoutFromResolutionScale(res_scale)};
|
||||||
screenshot_image = QImage(QSize(layout.width, layout.height), QImage::Format_RGB32);
|
screenshot_image = QImage(QSize(layout.width, layout.height), QImage::Format_RGB32);
|
||||||
VideoCore::RequestScreenshot(
|
VideoCore::RequestScreenshot(
|
||||||
screenshot_image.bits(),
|
screenshot_image.bits(),
|
||||||
[this, screenshot_path] {
|
[this, &screenshot_path] {
|
||||||
const std::string std_screenshot_path = screenshot_path.toStdString();
|
const std::string std_screenshot_path = screenshot_path.toStdString();
|
||||||
if (screenshot_image.mirrored(false, true).save(screenshot_path)) {
|
if (screenshot_image.mirrored(false, true).save(screenshot_path)) {
|
||||||
LOG_INFO(Frontend, "Screenshot saved to \"{}\"", std_screenshot_path);
|
LOG_INFO(Frontend, "Screenshot saved to \"{}\"", std_screenshot_path);
|
||||||
@ -644,7 +629,7 @@ void GRenderWindow::OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal
|
|||||||
bool GRenderWindow::InitializeOpenGL() {
|
bool GRenderWindow::InitializeOpenGL() {
|
||||||
// TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground,
|
// TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground,
|
||||||
// WA_DontShowOnScreen, WA_DeleteOnClose
|
// WA_DontShowOnScreen, WA_DeleteOnClose
|
||||||
auto child = new OpenGLRenderWidget(this, is_secondary);
|
auto child = new OpenGLRenderWidget(this);
|
||||||
child_widget = child;
|
child_widget = child;
|
||||||
child_widget->windowHandle()->create();
|
child_widget->windowHandle()->create();
|
||||||
auto context = std::make_shared<OpenGLSharedContext>(child->windowHandle());
|
auto context = std::make_shared<OpenGLSharedContext>(child->windowHandle());
|
||||||
|
@ -117,7 +117,7 @@ class GRenderWindow : public QWidget, public Frontend::EmuWindow {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GRenderWindow(QWidget* parent, EmuThread* emu_thread, bool is_secondary);
|
GRenderWindow(QWidget* parent, EmuThread* emu_thread);
|
||||||
~GRenderWindow() override;
|
~GRenderWindow() override;
|
||||||
|
|
||||||
// EmuWindow implementation.
|
// EmuWindow implementation.
|
||||||
@ -147,10 +147,6 @@ public:
|
|||||||
bool event(QEvent* event) override;
|
bool event(QEvent* event) override;
|
||||||
|
|
||||||
void focusOutEvent(QFocusEvent* event) override;
|
void focusOutEvent(QFocusEvent* event) override;
|
||||||
void focusInEvent(QFocusEvent* event) override;
|
|
||||||
bool HasFocus() const {
|
|
||||||
return has_focus;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitRenderTarget();
|
bool InitRenderTarget();
|
||||||
|
|
||||||
@ -204,7 +200,6 @@ private:
|
|||||||
QWidget* child_widget = nullptr;
|
QWidget* child_widget = nullptr;
|
||||||
|
|
||||||
bool first_frame = false;
|
bool first_frame = false;
|
||||||
bool has_focus = false;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void showEvent(QShowEvent* event) override;
|
void showEvent(QShowEvent* event) override;
|
||||||
|
@ -19,31 +19,25 @@ namespace Camera {
|
|||||||
QList<QVideoFrame::PixelFormat> QtCameraSurface::supportedPixelFormats(
|
QList<QVideoFrame::PixelFormat> QtCameraSurface::supportedPixelFormats(
|
||||||
[[maybe_unused]] QAbstractVideoBuffer::HandleType handleType) const {
|
[[maybe_unused]] QAbstractVideoBuffer::HandleType handleType) const {
|
||||||
return QList<QVideoFrame::PixelFormat>()
|
return QList<QVideoFrame::PixelFormat>()
|
||||||
<< QVideoFrame::Format_RGB32 << QVideoFrame::Format_RGB24
|
<< QVideoFrame::Format_ARGB32 << QVideoFrame::Format_ARGB32_Premultiplied
|
||||||
<< QVideoFrame::Format_ARGB32_Premultiplied << QVideoFrame::Format_ARGB32
|
<< QVideoFrame::Format_RGB32 << QVideoFrame::Format_RGB24 << QVideoFrame::Format_RGB565
|
||||||
<< QVideoFrame::Format_RGB565 << QVideoFrame::Format_RGB555
|
<< QVideoFrame::Format_RGB555 << QVideoFrame::Format_ARGB8565_Premultiplied
|
||||||
<< QVideoFrame::Format_Jpeg
|
<< QVideoFrame::Format_BGRA32 << QVideoFrame::Format_BGRA32_Premultiplied
|
||||||
// the following formats are supported via Qt internal conversions
|
<< QVideoFrame::Format_BGR32 << QVideoFrame::Format_BGR24 << QVideoFrame::Format_BGR565
|
||||||
<< QVideoFrame::Format_ARGB8565_Premultiplied << QVideoFrame::Format_BGRA32
|
<< QVideoFrame::Format_BGR555 << QVideoFrame::Format_BGRA5658_Premultiplied
|
||||||
<< QVideoFrame::Format_BGRA32_Premultiplied << QVideoFrame::Format_BGR32
|
<< QVideoFrame::Format_AYUV444 << QVideoFrame::Format_AYUV444_Premultiplied
|
||||||
<< QVideoFrame::Format_BGR24 << QVideoFrame::Format_BGR565 << QVideoFrame::Format_BGR555
|
<< QVideoFrame::Format_YUV444 << QVideoFrame::Format_YUV420P << QVideoFrame::Format_YV12
|
||||||
<< QVideoFrame::Format_AYUV444 << QVideoFrame::Format_YUV444
|
<< QVideoFrame::Format_UYVY << QVideoFrame::Format_YUYV << QVideoFrame::Format_NV12
|
||||||
<< QVideoFrame::Format_YUV420P << QVideoFrame::Format_YV12 << QVideoFrame::Format_UYVY
|
<< QVideoFrame::Format_NV21 << QVideoFrame::Format_IMC1 << QVideoFrame::Format_IMC2
|
||||||
<< QVideoFrame::Format_YUYV << QVideoFrame::Format_NV12
|
<< QVideoFrame::Format_IMC3 << QVideoFrame::Format_IMC4 << QVideoFrame::Format_Y8
|
||||||
<< QVideoFrame::Format_NV21; // Supporting all the QImage convertible formats, ordered by
|
<< QVideoFrame::Format_Y16 << QVideoFrame::Format_Jpeg << QVideoFrame::Format_CameraRaw
|
||||||
// QImage decoding performance
|
<< QVideoFrame::Format_AdobeDng; // Supporting all the formats
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QtCameraSurface::present(const QVideoFrame& frame) {
|
bool QtCameraSurface::present(const QVideoFrame& frame) {
|
||||||
if (!frame.isValid()) {
|
if (!frame.isValid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
// In Qt 5.15, the image is already flipped
|
|
||||||
current_frame = frame.image();
|
|
||||||
locker.unlock();
|
|
||||||
#else
|
|
||||||
QVideoFrame cloneFrame(frame);
|
QVideoFrame cloneFrame(frame);
|
||||||
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
|
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
|
||||||
const QImage image(cloneFrame.bits(), cloneFrame.width(), cloneFrame.height(),
|
const QImage image(cloneFrame.bits(), cloneFrame.width(), cloneFrame.height(),
|
||||||
@ -52,7 +46,6 @@ bool QtCameraSurface::present(const QVideoFrame& frame) {
|
|||||||
current_frame = image.mirrored(true, true);
|
current_frame = image.mirrored(true, true);
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
cloneFrame.unmap();
|
cloneFrame.unmap();
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +199,6 @@ void QtMultimediaCameraHandler::StartCamera() {
|
|||||||
camera->setViewfinderSettings(settings);
|
camera->setViewfinderSettings(settings);
|
||||||
camera->start();
|
camera->start();
|
||||||
started = true;
|
started = true;
|
||||||
paused = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QtMultimediaCameraHandler::CameraAvailable() const {
|
bool QtMultimediaCameraHandler::CameraAvailable() const {
|
||||||
@ -218,14 +210,13 @@ void QtMultimediaCameraHandler::StopCameras() {
|
|||||||
for (auto& handler : handlers) {
|
for (auto& handler : handlers) {
|
||||||
if (handler && handler->started) {
|
if (handler && handler->started) {
|
||||||
handler->StopCamera();
|
handler->StopCamera();
|
||||||
handler->paused = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtMultimediaCameraHandler::ResumeCameras() {
|
void QtMultimediaCameraHandler::ResumeCameras() {
|
||||||
for (auto& handler : handlers) {
|
for (auto& handler : handlers) {
|
||||||
if (handler && handler->paused) {
|
if (handler && handler->started) {
|
||||||
handler->StartCamera();
|
handler->StartCamera();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +228,6 @@ void QtMultimediaCameraHandler::ReleaseHandlers() {
|
|||||||
for (std::size_t i = 0; i < handlers.size(); i++) {
|
for (std::size_t i = 0; i < handlers.size(); i++) {
|
||||||
status[i] = false;
|
status[i] = false;
|
||||||
handlers[i]->started = false;
|
handlers[i]->started = false;
|
||||||
handlers[i]->paused = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,6 @@ private:
|
|||||||
QtCameraSurface camera_surface{};
|
QtCameraSurface camera_surface{};
|
||||||
QCameraViewfinderSettings settings;
|
QCameraViewfinderSettings settings;
|
||||||
bool started = false;
|
bool started = false;
|
||||||
bool paused = false; // was previously started but was paused, to be resumed
|
|
||||||
|
|
||||||
static std::array<std::shared_ptr<QtMultimediaCameraHandler>, 3> handlers;
|
static std::array<std::shared_ptr<QtMultimediaCameraHandler>, 3> handlers;
|
||||||
static std::array<bool, 3> status;
|
static std::array<bool, 3> status;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,16 +8,13 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
|
|
||||||
class QSettings;
|
class QSettings;
|
||||||
|
|
||||||
class Config {
|
class Config {
|
||||||
public:
|
public:
|
||||||
enum class ConfigType : u32 { GlobalConfig, PerGameConfig };
|
Config();
|
||||||
|
|
||||||
explicit Config(const std::string& config_name = "qt-config",
|
|
||||||
ConfigType config_type = ConfigType::GlobalConfig);
|
|
||||||
~Config();
|
~Config();
|
||||||
|
|
||||||
void Reload();
|
void Reload();
|
||||||
@ -27,8 +24,6 @@ public:
|
|||||||
static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs;
|
static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Initialize(const std::string& config_name);
|
|
||||||
|
|
||||||
void ReadValues();
|
void ReadValues();
|
||||||
void ReadAudioValues();
|
void ReadAudioValues();
|
||||||
void ReadCameraValues();
|
void ReadCameraValues();
|
||||||
@ -73,78 +68,11 @@ private:
|
|||||||
void SaveWebServiceValues();
|
void SaveWebServiceValues();
|
||||||
void SaveVideoDumpingValues();
|
void SaveVideoDumpingValues();
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a setting from the qt_config.
|
|
||||||
*
|
|
||||||
* @param name The setting's identifier
|
|
||||||
* @param default_value The value to use when the setting is not already present in the config
|
|
||||||
*/
|
|
||||||
QVariant ReadSetting(const QString& name) const;
|
QVariant ReadSetting(const QString& name) const;
|
||||||
QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
|
QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Only reads a setting from the qt_config if the current config is a global config, or if the
|
|
||||||
* current config is a custom config and the setting is overriding the global setting. Otherwise
|
|
||||||
* it does nothing.
|
|
||||||
*
|
|
||||||
* @param setting The variable to be modified
|
|
||||||
* @param name The setting's identifier
|
|
||||||
* @param default_value The value to use when the setting is not already present in the config
|
|
||||||
*/
|
|
||||||
template <typename Type>
|
|
||||||
void ReadSettingGlobal(Type& setting, const QString& name, const QVariant& default_value) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a setting to the qt_config.
|
|
||||||
*
|
|
||||||
* @param name The setting's idetentifier
|
|
||||||
* @param value Value of the setting
|
|
||||||
* @param default_value Default of the setting if not present in qt_config
|
|
||||||
* @param use_global Specifies if the custom or global config should be in use, for custom
|
|
||||||
* configs
|
|
||||||
*/
|
|
||||||
void WriteSetting(const QString& name, const QVariant& value);
|
void WriteSetting(const QString& name, const QVariant& value);
|
||||||
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value);
|
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value);
|
||||||
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value,
|
|
||||||
bool use_global);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a value from the qt_config and applies it to the setting, using its label and default
|
|
||||||
* value. If the config is a custom config, this will also read the global state of the setting
|
|
||||||
* and apply that information to it.
|
|
||||||
*
|
|
||||||
* @param The setting
|
|
||||||
*/
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void ReadGlobalSetting(Settings::SwitchableSetting<Type, ranged>& setting);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a value to the qt_config using the setting's label and default value. If the config is a
|
|
||||||
* custom config, it will apply the global state, and the custom value if needed.
|
|
||||||
*
|
|
||||||
* @param The setting
|
|
||||||
*/
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void WriteGlobalSetting(const Settings::SwitchableSetting<Type, ranged>& setting);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a value from the qt_config using the setting's label and default value and applies the
|
|
||||||
* value to the setting.
|
|
||||||
*
|
|
||||||
* @param The setting
|
|
||||||
*/
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void ReadBasicSetting(Settings::Setting<Type, ranged>& setting);
|
|
||||||
|
|
||||||
/** Sets a value from the setting in the qt_config using the setting's label and default value.
|
|
||||||
*
|
|
||||||
* @param The setting
|
|
||||||
*/
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void WriteBasicSetting(const Settings::Setting<Type, ranged>& setting);
|
|
||||||
|
|
||||||
ConfigType type;
|
|
||||||
std::unique_ptr<QSettings> qt_config;
|
std::unique_ptr<QSettings> qt_config;
|
||||||
std::string qt_config_loc;
|
std::string qt_config_loc;
|
||||||
bool global;
|
|
||||||
};
|
};
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
// Copyright 2020 yuzu Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include "citra_qt/configuration/configuration_shared.h"
|
|
||||||
#include "citra_qt/configuration/configure_per_game.h"
|
|
||||||
#include "common/settings.h"
|
|
||||||
|
|
||||||
void ConfigurationShared::ApplyPerGameSetting(Settings::SwitchableSetting<bool>* setting,
|
|
||||||
const QCheckBox* checkbox,
|
|
||||||
const CheckState& tracker) {
|
|
||||||
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
|
|
||||||
setting->SetValue(checkbox->checkState());
|
|
||||||
} else if (!Settings::IsConfiguringGlobal()) {
|
|
||||||
if (tracker == CheckState::Global) {
|
|
||||||
setting->SetGlobal(true);
|
|
||||||
} else {
|
|
||||||
setting->SetGlobal(false);
|
|
||||||
setting->SetValue(checkbox->checkState());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox,
|
|
||||||
const Settings::SwitchableSetting<bool>* setting) {
|
|
||||||
if (setting->UsingGlobal()) {
|
|
||||||
checkbox->setCheckState(Qt::PartiallyChecked);
|
|
||||||
} else {
|
|
||||||
checkbox->setCheckState(setting->GetValue() ? Qt::Checked : Qt::Unchecked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationShared::SetHighlight(QWidget* widget, bool highlighted) {
|
|
||||||
if (highlighted) {
|
|
||||||
widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,203,255,0.5) }")
|
|
||||||
.arg(widget->objectName()));
|
|
||||||
} else {
|
|
||||||
widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,0,0,0) }")
|
|
||||||
.arg(widget->objectName()));
|
|
||||||
}
|
|
||||||
widget->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox,
|
|
||||||
const Settings::SwitchableSetting<bool>& setting,
|
|
||||||
CheckState& tracker) {
|
|
||||||
if (setting.UsingGlobal()) {
|
|
||||||
tracker = CheckState::Global;
|
|
||||||
} else {
|
|
||||||
tracker = (setting.GetValue() == setting.GetValue(true)) ? CheckState::On : CheckState::Off;
|
|
||||||
}
|
|
||||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
|
||||||
QObject::connect(checkbox, &QCheckBox::clicked, checkbox, [checkbox, setting, &tracker] {
|
|
||||||
tracker = static_cast<CheckState>((static_cast<int>(tracker) + 1) %
|
|
||||||
static_cast<int>(CheckState::Count));
|
|
||||||
if (tracker == CheckState::Global) {
|
|
||||||
checkbox->setChecked(setting.GetValue(true));
|
|
||||||
}
|
|
||||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox, bool global, bool state,
|
|
||||||
bool global_state, CheckState& tracker) {
|
|
||||||
if (global) {
|
|
||||||
tracker = CheckState::Global;
|
|
||||||
} else {
|
|
||||||
tracker = (state == global_state) ? CheckState::On : CheckState::Off;
|
|
||||||
}
|
|
||||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
|
||||||
QObject::connect(checkbox, &QCheckBox::clicked, checkbox, [checkbox, global_state, &tracker] {
|
|
||||||
tracker = static_cast<CheckState>((static_cast<int>(tracker) + 1) %
|
|
||||||
static_cast<int>(CheckState::Count));
|
|
||||||
if (tracker == CheckState::Global) {
|
|
||||||
checkbox->setChecked(global_state);
|
|
||||||
}
|
|
||||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationShared::SetColoredComboBox(QComboBox* combobox, QWidget* target, int global) {
|
|
||||||
InsertGlobalItem(combobox, global);
|
|
||||||
QObject::connect(combobox, qOverload<int>(&QComboBox::activated), target,
|
|
||||||
[target](int index) { SetHighlight(target, index != 0); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationShared::InsertGlobalItem(QComboBox* combobox, int global_index) {
|
|
||||||
const QString use_global_text =
|
|
||||||
ConfigurePerGame::tr("Use global configuration (%1)").arg(combobox->itemText(global_index));
|
|
||||||
combobox->insertItem(ConfigurationShared::USE_GLOBAL_INDEX, use_global_text);
|
|
||||||
combobox->insertSeparator(ConfigurationShared::USE_GLOBAL_SEPARATOR_INDEX);
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
// Copyright 2020 yuzu Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QComboBox>
|
|
||||||
#include "common/settings.h"
|
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
|
||||||
|
|
||||||
constexpr int USE_GLOBAL_INDEX =
|
|
||||||
0; ///< The index of the "Use global configuration" option in checkboxes
|
|
||||||
constexpr int USE_GLOBAL_SEPARATOR_INDEX = 1;
|
|
||||||
constexpr int USE_GLOBAL_OFFSET = 2;
|
|
||||||
|
|
||||||
/// CheckBoxes require a tracker for their state since we emulate a tristate CheckBox
|
|
||||||
enum class CheckState {
|
|
||||||
Off, ///< Checkbox overrides to off/false
|
|
||||||
On, ///< Checkbox overrides to on/true
|
|
||||||
Global, ///< Checkbox defers to the global state
|
|
||||||
Count, ///< Simply the number of states, not a valid checkbox state
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief ApplyPerGameSetting given a setting and a Qt UI element, properly applies a Setting
|
|
||||||
* taking into account the global/per-game check state. This is used for configuring checkboxes
|
|
||||||
* @param setting
|
|
||||||
* @param checkbox
|
|
||||||
* @param tracker
|
|
||||||
*/
|
|
||||||
void ApplyPerGameSetting(Settings::SwitchableSetting<bool>* setting, const QCheckBox* checkbox,
|
|
||||||
const CheckState& tracker);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief ApplyPerGameSetting given a setting and a Qt UI element, properly applies a Setting
|
|
||||||
* taking into account the global/per-game check state. This is used for both combo boxes
|
|
||||||
* as well as any other widget that is accompanied by a combo box in per-game settings.
|
|
||||||
* @param setting The setting class that stores the desired option
|
|
||||||
* @param combobox The Qt combo box that stores the value/per-game status
|
|
||||||
* @param transform A function that accepts the combo box index and transforms it to the
|
|
||||||
* desired settings value. When used with sliders/edit the user can ignore the input value
|
|
||||||
* and set a custom value this making this function useful for these widgets as well
|
|
||||||
*/
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void ApplyPerGameSetting(Settings::SwitchableSetting<Type, ranged>* setting,
|
|
||||||
const QComboBox* combobox, auto transform) {
|
|
||||||
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
|
|
||||||
setting->SetValue(static_cast<Type>(transform(combobox->currentIndex())));
|
|
||||||
} else if (!Settings::IsConfiguringGlobal()) {
|
|
||||||
if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
|
||||||
setting->SetGlobal(true);
|
|
||||||
} else {
|
|
||||||
setting->SetGlobal(false);
|
|
||||||
setting->SetValue(static_cast<Type>(
|
|
||||||
transform(combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Simpler version of ApplyPerGameSetting without a transform parameter
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void ApplyPerGameSetting(Settings::SwitchableSetting<Type, ranged>* setting,
|
|
||||||
const QComboBox* combobox) {
|
|
||||||
const auto transform = [](s32 index) { return index; };
|
|
||||||
return ApplyPerGameSetting(setting, combobox, transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets a Qt UI element given a Settings::Setting
|
|
||||||
void SetPerGameSetting(QCheckBox* checkbox, const Settings::SwitchableSetting<bool>* setting);
|
|
||||||
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void SetPerGameSetting(QComboBox* combobox,
|
|
||||||
const Settings::SwitchableSetting<Type, ranged>* setting) {
|
|
||||||
combobox->setCurrentIndex(setting->UsingGlobal() ? ConfigurationShared::USE_GLOBAL_INDEX
|
|
||||||
: static_cast<int>(setting->GetValue()) +
|
|
||||||
ConfigurationShared::USE_GLOBAL_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given a Qt widget sets the background color to indicate whether the setting
|
|
||||||
/// is per-game overriden (highlighted) or global (non-highlighted)
|
|
||||||
void SetHighlight(QWidget* widget, bool highlighted);
|
|
||||||
|
|
||||||
/// Sets up a QCheckBox like a tristate one, given a Setting
|
|
||||||
void SetColoredTristate(QCheckBox* checkbox, const Settings::SwitchableSetting<bool>& setting,
|
|
||||||
CheckState& tracker);
|
|
||||||
void SetColoredTristate(QCheckBox* checkbox, bool global, bool state, bool global_state,
|
|
||||||
CheckState& tracker);
|
|
||||||
|
|
||||||
/// Sets up coloring of a QWidget `target` based on the state of a QComboBox, and calls
|
|
||||||
/// InsertGlobalItem
|
|
||||||
void SetColoredComboBox(QComboBox* combobox, QWidget* target, int global);
|
|
||||||
|
|
||||||
/// Adds the "Use Global Configuration" selection and separator to the beginning of a QComboBox
|
|
||||||
void InsertGlobalItem(QComboBox* combobox, int global_index);
|
|
||||||
|
|
||||||
} // namespace ConfigurationShared
|
|
@ -9,11 +9,10 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "audio_core/sink.h"
|
#include "audio_core/sink.h"
|
||||||
#include "audio_core/sink_details.h"
|
#include "audio_core/sink_details.h"
|
||||||
#include "citra_qt/configuration/configuration_shared.h"
|
|
||||||
#include "citra_qt/configuration/configure_audio.h"
|
#include "citra_qt/configuration/configure_audio.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/frontend/mic.h"
|
#include "core/frontend/mic.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "ui_configure_audio.h"
|
#include "ui_configure_audio.h"
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
@ -32,30 +31,25 @@ ConfigureAudio::ConfigureAudio(QWidget* parent)
|
|||||||
ui->output_sink_combo_box->addItem(QString::fromUtf8(id));
|
ui->output_sink_combo_box->addItem(QString::fromUtf8(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool is_running = Core::System::GetInstance().IsPoweredOn();
|
ui->emulation_combo_box->addItem(tr("HLE (fast)"));
|
||||||
ui->emulation_combo_box->setEnabled(!is_running);
|
ui->emulation_combo_box->addItem(tr("LLE (accurate)"));
|
||||||
|
ui->emulation_combo_box->addItem(tr("LLE multi-core"));
|
||||||
|
ui->emulation_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
||||||
|
|
||||||
connect(ui->volume_slider, &QSlider::valueChanged, this,
|
connect(ui->volume_slider, &QSlider::valueChanged, this,
|
||||||
&ConfigureAudio::SetVolumeIndicatorText);
|
&ConfigureAudio::SetVolumeIndicatorText);
|
||||||
|
|
||||||
ui->input_device_combo_box->clear();
|
ui->input_device_combo_box->clear();
|
||||||
ui->input_device_combo_box->addItem(tr("Default"));
|
ui->input_device_combo_box->addItem(tr("Default"));
|
||||||
|
|
||||||
#ifdef HAVE_CUBEB
|
#ifdef HAVE_CUBEB
|
||||||
for (const auto& device : AudioCore::ListCubebInputDevices()) {
|
for (const auto& device : AudioCore::ListCubebInputDevices()) {
|
||||||
ui->input_device_combo_box->addItem(QString::fromStdString(device));
|
ui->input_device_combo_box->addItem(QString::fromStdString(device));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
connect(ui->input_type_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
connect(ui->input_type_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
&ConfigureAudio::UpdateAudioInputDevices);
|
&ConfigureAudio::UpdateAudioInputDevices);
|
||||||
|
|
||||||
ui->volume_label->setVisible(Settings::IsConfiguringGlobal());
|
|
||||||
ui->volume_combo_box->setVisible(!Settings::IsConfiguringGlobal());
|
|
||||||
|
|
||||||
SetupPerGameUI();
|
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
&ConfigureAudio::UpdateAudioOutputDevices);
|
&ConfigureAudio::UpdateAudioOutputDevices);
|
||||||
}
|
}
|
||||||
@ -67,35 +61,27 @@ void ConfigureAudio::SetConfiguration() {
|
|||||||
|
|
||||||
// The device list cannot be pre-populated (nor listed) until the output sink is known.
|
// The device list cannot be pre-populated (nor listed) until the output sink is known.
|
||||||
UpdateAudioOutputDevices(ui->output_sink_combo_box->currentIndex());
|
UpdateAudioOutputDevices(ui->output_sink_combo_box->currentIndex());
|
||||||
|
|
||||||
SetAudioDeviceFromDeviceID();
|
SetAudioDeviceFromDeviceID();
|
||||||
|
|
||||||
ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching.GetValue());
|
ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching);
|
||||||
|
ui->volume_slider->setValue(
|
||||||
const s32 volume =
|
static_cast<int>(Settings::values.volume * ui->volume_slider->maximum()));
|
||||||
static_cast<s32>(Settings::values.volume.GetValue() * ui->volume_slider->maximum());
|
|
||||||
ui->volume_slider->setValue(volume);
|
|
||||||
SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
|
SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
|
||||||
|
|
||||||
if (!Settings::IsConfiguringGlobal()) {
|
int selection;
|
||||||
if (Settings::values.volume.UsingGlobal()) {
|
if (Settings::values.enable_dsp_lle) {
|
||||||
ui->volume_combo_box->setCurrentIndex(0);
|
if (Settings::values.enable_dsp_lle_multithread) {
|
||||||
ui->volume_slider->setEnabled(false);
|
selection = 2;
|
||||||
} else {
|
} else {
|
||||||
ui->volume_combo_box->setCurrentIndex(1);
|
selection = 1;
|
||||||
ui->volume_slider->setEnabled(true);
|
|
||||||
}
|
}
|
||||||
ConfigurationShared::SetHighlight(ui->volume_layout,
|
|
||||||
!Settings::values.volume.UsingGlobal());
|
|
||||||
ConfigurationShared::SetHighlight(ui->widget_emulation,
|
|
||||||
!Settings::values.audio_emulation.UsingGlobal());
|
|
||||||
ConfigurationShared::SetPerGameSetting(ui->emulation_combo_box,
|
|
||||||
&Settings::values.audio_emulation);
|
|
||||||
} else {
|
} else {
|
||||||
s32 selection = static_cast<s32>(Settings::values.audio_emulation.GetValue());
|
selection = 0;
|
||||||
|
}
|
||||||
ui->emulation_combo_box->setCurrentIndex(selection);
|
ui->emulation_combo_box->setCurrentIndex(selection);
|
||||||
}
|
|
||||||
|
|
||||||
s32 index = static_cast<s32>(Settings::values.mic_input_type.GetValue());
|
int index = static_cast<int>(Settings::values.mic_input_type);
|
||||||
ui->input_type_combo_box->setCurrentIndex(index);
|
ui->input_type_combo_box->setCurrentIndex(index);
|
||||||
|
|
||||||
UpdateAudioInputDevices(index);
|
UpdateAudioInputDevices(index);
|
||||||
@ -104,7 +90,7 @@ void ConfigureAudio::SetConfiguration() {
|
|||||||
void ConfigureAudio::SetOutputSinkFromSinkID() {
|
void ConfigureAudio::SetOutputSinkFromSinkID() {
|
||||||
int new_sink_index = 0;
|
int new_sink_index = 0;
|
||||||
|
|
||||||
const QString sink_id = QString::fromStdString(Settings::values.sink_id.GetValue());
|
const QString sink_id = QString::fromStdString(Settings::values.sink_id);
|
||||||
for (int index = 0; index < ui->output_sink_combo_box->count(); index++) {
|
for (int index = 0; index < ui->output_sink_combo_box->count(); index++) {
|
||||||
if (ui->output_sink_combo_box->itemText(index) == sink_id) {
|
if (ui->output_sink_combo_box->itemText(index) == sink_id) {
|
||||||
new_sink_index = index;
|
new_sink_index = index;
|
||||||
@ -118,7 +104,7 @@ void ConfigureAudio::SetOutputSinkFromSinkID() {
|
|||||||
void ConfigureAudio::SetAudioDeviceFromDeviceID() {
|
void ConfigureAudio::SetAudioDeviceFromDeviceID() {
|
||||||
int new_device_index = -1;
|
int new_device_index = -1;
|
||||||
|
|
||||||
const QString device_id = QString::fromStdString(Settings::values.audio_device_id.GetValue());
|
const QString device_id = QString::fromStdString(Settings::values.audio_device_id);
|
||||||
for (int index = 0; index < ui->audio_device_combo_box->count(); index++) {
|
for (int index = 0; index < ui->audio_device_combo_box->count(); index++) {
|
||||||
if (ui->audio_device_combo_box->itemText(index) == device_id) {
|
if (ui->audio_device_combo_box->itemText(index) == device_id) {
|
||||||
new_device_index = index;
|
new_device_index = index;
|
||||||
@ -134,31 +120,24 @@ void ConfigureAudio::SetVolumeIndicatorText(int percentage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::ApplyConfiguration() {
|
void ConfigureAudio::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_audio_stretching,
|
|
||||||
ui->toggle_audio_stretching, audio_stretching);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.audio_emulation,
|
|
||||||
ui->emulation_combo_box);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(
|
|
||||||
&Settings::values.volume, ui->volume_combo_box, [this](s32) {
|
|
||||||
return static_cast<float>(ui->volume_slider->value()) / ui->volume_slider->maximum();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
Settings::values.sink_id =
|
Settings::values.sink_id =
|
||||||
ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
|
ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
|
||||||
.toStdString();
|
.toStdString();
|
||||||
|
Settings::values.enable_audio_stretching = ui->toggle_audio_stretching->isChecked();
|
||||||
Settings::values.audio_device_id =
|
Settings::values.audio_device_id =
|
||||||
ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
|
ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
|
||||||
.toStdString();
|
.toStdString();
|
||||||
|
Settings::values.volume =
|
||||||
|
static_cast<float>(ui->volume_slider->sliderPosition()) / ui->volume_slider->maximum();
|
||||||
|
Settings::values.enable_dsp_lle = ui->emulation_combo_box->currentIndex() != 0;
|
||||||
|
Settings::values.enable_dsp_lle_multithread = ui->emulation_combo_box->currentIndex() == 2;
|
||||||
Settings::values.mic_input_type =
|
Settings::values.mic_input_type =
|
||||||
static_cast<Settings::MicInputType>(ui->input_type_combo_box->currentIndex());
|
static_cast<Settings::MicInputType>(ui->input_type_combo_box->currentIndex());
|
||||||
|
|
||||||
if (ui->input_device_combo_box->currentIndex() == DEFAULT_INPUT_DEVICE_INDEX) {
|
if (ui->input_device_combo_box->currentIndex() == DEFAULT_INPUT_DEVICE_INDEX) {
|
||||||
Settings::values.mic_input_device = Frontend::Mic::default_device_name;
|
Settings::values.mic_input_device = Frontend::Mic::default_device_name;
|
||||||
} else {
|
} else {
|
||||||
Settings::values.mic_input_device =
|
Settings::values.mic_input_device = ui->input_device_combo_box->currentText().toStdString();
|
||||||
ui->input_device_combo_box->currentText().toStdString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,41 +157,12 @@ void ConfigureAudio::UpdateAudioInputDevices(int index) {
|
|||||||
AppleAuthorization::CheckAuthorizationForMicrophone();
|
AppleAuthorization::CheckAuthorizationForMicrophone();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (Settings::values.mic_input_device.GetValue() != Frontend::Mic::default_device_name) {
|
if (Settings::values.mic_input_device != Frontend::Mic::default_device_name) {
|
||||||
ui->input_device_combo_box->setCurrentText(
|
ui->input_device_combo_box->setCurrentText(
|
||||||
QString::fromStdString(Settings::values.mic_input_device.GetValue()));
|
QString::fromStdString(Settings::values.mic_input_device));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::RetranslateUI() {
|
void ConfigureAudio::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::SetupPerGameUI() {
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
ui->volume_slider->setEnabled(Settings::values.volume.UsingGlobal());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->output_sink_combo_box->setVisible(false);
|
|
||||||
ui->output_sink_label->setVisible(false);
|
|
||||||
ui->audio_device_combo_box->setVisible(false);
|
|
||||||
ui->audio_device_label->setVisible(false);
|
|
||||||
ui->input_type_label->setVisible(false);
|
|
||||||
ui->input_type_combo_box->setVisible(false);
|
|
||||||
ui->input_device_label->setVisible(false);
|
|
||||||
ui->input_device_combo_box->setVisible(false);
|
|
||||||
ui->microphone_layout->setVisible(false);
|
|
||||||
|
|
||||||
connect(ui->volume_combo_box, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
|
||||||
ui->volume_slider->setEnabled(index == 1);
|
|
||||||
ConfigurationShared::SetHighlight(ui->volume_layout, index == 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredComboBox(
|
|
||||||
ui->emulation_combo_box, ui->widget_emulation,
|
|
||||||
static_cast<u32>(Settings::values.audio_emulation.GetValue(true)));
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredTristate(
|
|
||||||
ui->toggle_audio_stretching, Settings::values.enable_audio_stretching, audio_stretching);
|
|
||||||
}
|
|
||||||
|
@ -11,10 +11,6 @@ namespace Ui {
|
|||||||
class ConfigureAudio;
|
class ConfigureAudio;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
|
||||||
enum class CheckState;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConfigureAudio : public QWidget {
|
class ConfigureAudio : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -34,8 +30,5 @@ private:
|
|||||||
void SetAudioDeviceFromDeviceID();
|
void SetAudioDeviceFromDeviceID();
|
||||||
void SetVolumeIndicatorText(int percentage);
|
void SetVolumeIndicatorText(int percentage);
|
||||||
|
|
||||||
void SetupPerGameUI();
|
|
||||||
|
|
||||||
ConfigurationShared::CheckState audio_stretching;
|
|
||||||
std::unique_ptr<Ui::ConfigureAudio> ui;
|
std::unique_ptr<Ui::ConfigureAudio> ui;
|
||||||
};
|
};
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>696</width>
|
<width>329</width>
|
||||||
<height>527</height>
|
<height>344</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout">
|
||||||
@ -18,17 +18,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widget_emulation" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_emulation">
|
<layout class="QHBoxLayout" name="horizontalLayout_emulation">
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@ -40,31 +30,14 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="emulation_combo_box">
|
<widget class="QComboBox" name="emulation_combo_box"/>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>HLE (fast)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>LLE (accurate)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>LLE multi-core</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="output_engine_layout">
|
<layout class="QHBoxLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="output_sink_label">
|
<widget class="QLabel" name="label1">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Output Engine</string>
|
<string>Output Engine</string>
|
||||||
</property>
|
</property>
|
||||||
@ -86,9 +59,9 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="audio_device_layout">
|
<layout class="QHBoxLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="audio_device_label">
|
<widget class="QLabel" name="label2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Audio Device</string>
|
<string>Audio Device</string>
|
||||||
</property>
|
</property>
|
||||||
@ -100,36 +73,12 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="volume_layout" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="volume_combo_box">
|
<widget class="QLabel" name="label">
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use global volume</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Set volume:</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="volume_label">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Volume:</string>
|
<string>Volume:</string>
|
||||||
</property>
|
</property>
|
||||||
@ -142,7 +91,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>30</width>
|
<width>40</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
@ -160,7 +109,7 @@
|
|||||||
<number>100</number>
|
<number>100</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="pageStep">
|
<property name="pageStep">
|
||||||
<number>5</number>
|
<number>10</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
@ -184,13 +133,12 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="microphone_layout">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Microphone</string>
|
<string>Microphone</string>
|
||||||
</property>
|
</property>
|
||||||
@ -198,7 +146,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="input_type_label">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Input Type</string>
|
<string>Input Type</string>
|
||||||
</property>
|
</property>
|
||||||
@ -228,7 +176,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="input_device_label">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Input Device</string>
|
<string>Input Device</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include "citra_qt/configuration/configure_camera.h"
|
#include "citra_qt/configuration/configure_camera.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/frontend/camera/factory.h"
|
#include "core/frontend/camera/factory.h"
|
||||||
#include "core/frontend/camera/interface.h"
|
#include "core/frontend/camera/interface.h"
|
||||||
#include "core/hle/service/cam/cam.h"
|
#include "core/hle/service/cam/cam.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "ui_configure_camera.h"
|
#include "ui_configure_camera.h"
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <QMessageBox>
|
||||||
#include "citra_qt/configuration/configure_debug.h"
|
#include "citra_qt/configuration/configure_debug.h"
|
||||||
#include "citra_qt/debugger/console.h"
|
#include "citra_qt/debugger/console.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "qcheckbox.h"
|
#include "qcheckbox.h"
|
||||||
#include "ui_configure_debug.h"
|
#include "ui_configure_debug.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
@ -22,36 +22,36 @@ ConfigureDebug::ConfigureDebug(QWidget* parent)
|
|||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
connect(ui->open_log_button, &QPushButton::clicked, []() {
|
connect(ui->open_log_button, &QPushButton::clicked, []() {
|
||||||
QString path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::LogDir));
|
QString path = QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::LogDir));
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->toggle_renderer_debug, &QCheckBox::clicked, this, [this](bool checked) {
|
connect(ui->toggle_renderer_debug, &QCheckBox::clicked, this, [this](bool checked) {
|
||||||
if (checked && Settings::values.graphics_api.GetValue() == Settings::GraphicsAPI::Vulkan) {
|
if (checked && Settings::values.graphics_api == Settings::GraphicsAPI::Vulkan) {
|
||||||
try {
|
try {
|
||||||
Vulkan::Instance debug_inst{true};
|
Vulkan::Instance debug_inst{true};
|
||||||
} catch (vk::LayerNotPresentError&) {
|
} catch (vk::LayerNotPresentError& err) {
|
||||||
ui->toggle_renderer_debug->toggle();
|
ui->toggle_renderer_debug->toggle();
|
||||||
QMessageBox::warning(this, tr("Validation layer not available"),
|
QMessageBox::warning(
|
||||||
|
this, tr("Validation layer not available"),
|
||||||
tr("Unable to enable debug renderer because the layer "
|
tr("Unable to enable debug renderer because the layer "
|
||||||
"<strong>VK_LAYER_KHRONOS_validation</strong> is missing. "
|
"<strong>VK_LAYER_KHRONOS_validation</strong> is missing. "
|
||||||
"Please install the Vulkan SDK or the appropriate package "
|
"Please install the Vulkan SDK or the appropriate package of your distribution"));
|
||||||
"of your distribution"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->toggle_dump_command_buffers, &QCheckBox::clicked, this, [this](bool checked) {
|
connect(ui->toggle_dump_command_buffers, &QCheckBox::clicked, this, [this](bool checked) {
|
||||||
if (checked && Settings::values.graphics_api.GetValue() == Settings::GraphicsAPI::Vulkan) {
|
if (checked && Settings::values.graphics_api == Settings::GraphicsAPI::Vulkan) {
|
||||||
try {
|
try {
|
||||||
Vulkan::Instance debug_inst{false, true};
|
Vulkan::Instance debug_inst{false, true};
|
||||||
} catch (vk::LayerNotPresentError&) {
|
} catch (vk::LayerNotPresentError& err) {
|
||||||
ui->toggle_dump_command_buffers->toggle();
|
ui->toggle_dump_command_buffers->toggle();
|
||||||
QMessageBox::warning(this, tr("Command buffer dumping not available"),
|
QMessageBox::warning(
|
||||||
|
this, tr("Command buffer dumping not available"),
|
||||||
tr("Unable to enable command buffer dumping because the layer "
|
tr("Unable to enable command buffer dumping because the layer "
|
||||||
"<strong>VK_LAYER_LUNARG_api_dump</strong> is missing. "
|
"<strong>VK_LAYER_LUNARG_api_dump</strong> is missing. "
|
||||||
"Please install the Vulkan SDK or the appropriate package "
|
"Please install the Vulkan SDK or the appropriate package of your distribution"));
|
||||||
"of your distribution"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -65,15 +65,15 @@ ConfigureDebug::ConfigureDebug(QWidget* parent)
|
|||||||
ConfigureDebug::~ConfigureDebug() = default;
|
ConfigureDebug::~ConfigureDebug() = default;
|
||||||
|
|
||||||
void ConfigureDebug::SetConfiguration() {
|
void ConfigureDebug::SetConfiguration() {
|
||||||
ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub.GetValue());
|
ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub);
|
||||||
ui->gdbport_spinbox->setEnabled(Settings::values.use_gdbstub.GetValue());
|
ui->gdbport_spinbox->setEnabled(Settings::values.use_gdbstub);
|
||||||
ui->gdbport_spinbox->setValue(Settings::values.gdbstub_port.GetValue());
|
ui->gdbport_spinbox->setValue(Settings::values.gdbstub_port);
|
||||||
ui->toggle_console->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
ui->toggle_console->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
||||||
ui->toggle_console->setChecked(UISettings::values.show_console.GetValue());
|
ui->toggle_console->setChecked(UISettings::values.show_console);
|
||||||
ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue()));
|
ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter));
|
||||||
ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue());
|
ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit);
|
||||||
ui->toggle_renderer_debug->setChecked(Settings::values.renderer_debug.GetValue());
|
ui->toggle_renderer_debug->setChecked(Settings::values.renderer_debug);
|
||||||
ui->toggle_dump_command_buffers->setChecked(Settings::values.dump_command_buffers.GetValue());
|
ui->toggle_dump_command_buffers->setChecked(Settings::values.dump_command_buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureDebug::ApplyConfiguration() {
|
void ConfigureDebug::ApplyConfiguration() {
|
||||||
@ -83,7 +83,7 @@ void ConfigureDebug::ApplyConfiguration() {
|
|||||||
Settings::values.log_filter = ui->log_filter_edit->text().toStdString();
|
Settings::values.log_filter = ui->log_filter_edit->text().toStdString();
|
||||||
Debugger::ToggleConsole();
|
Debugger::ToggleConsole();
|
||||||
Log::Filter filter;
|
Log::Filter filter;
|
||||||
filter.ParseFilterString(Settings::values.log_filter.GetValue());
|
filter.ParseFilterString(Settings::values.log_filter);
|
||||||
Log::SetGlobalFilter(filter);
|
Log::SetGlobalFilter(filter);
|
||||||
Settings::values.use_cpu_jit = ui->toggle_cpu_jit->isChecked();
|
Settings::values.use_cpu_jit = ui->toggle_cpu_jit->isChecked();
|
||||||
Settings::values.renderer_debug = ui->toggle_renderer_debug->isChecked();
|
Settings::values.renderer_debug = ui->toggle_renderer_debug->isChecked();
|
||||||
|
@ -7,13 +7,11 @@
|
|||||||
#include "citra_qt/configuration/config.h"
|
#include "citra_qt/configuration/config.h"
|
||||||
#include "citra_qt/configuration/configure_dialog.h"
|
#include "citra_qt/configuration/configure_dialog.h"
|
||||||
#include "citra_qt/hotkeys.h"
|
#include "citra_qt/hotkeys.h"
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
#include "ui_configure.h"
|
#include "ui_configure.h"
|
||||||
|
|
||||||
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, bool enable_web_config)
|
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, bool enable_web_config)
|
||||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigureDialog>()), registry(registry) {
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigureDialog>()), registry(registry) {
|
||||||
Settings::SetConfiguringGlobal(true);
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->hotkeysTab->Populate(registry);
|
ui->hotkeysTab->Populate(registry);
|
||||||
ui->webTab->SetWebServiceConfigEnabled(enable_web_config);
|
ui->webTab->SetWebServiceConfigEnabled(enable_web_config);
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
#include <QColorDialog>
|
#include <QColorDialog>
|
||||||
#include "citra_qt/configuration/configure_enhancements.h"
|
#include "citra_qt/configuration/configure_enhancements.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "ui_configure_enhancements.h"
|
#include "ui_configure_enhancements.h"
|
||||||
#include "video_core/renderer_opengl/post_processing_opengl.h"
|
#include "video_core/renderer_opengl/post_processing_opengl.h"
|
||||||
#include "video_core/renderer_opengl/texture_filters/texture_filterer.h"
|
#include "video_core/renderer_opengl/texture_filters/texture_filterer.h"
|
||||||
@ -21,7 +21,7 @@ ConfigureEnhancements::ConfigureEnhancements(QWidget* parent)
|
|||||||
|
|
||||||
ui->layoutBox->setEnabled(!Settings::values.custom_layout);
|
ui->layoutBox->setEnabled(!Settings::values.custom_layout);
|
||||||
|
|
||||||
ui->resolution_factor_combobox->setEnabled(Settings::values.use_hw_renderer.GetValue());
|
ui->resolution_factor_combobox->setEnabled(Settings::values.use_hw_renderer);
|
||||||
|
|
||||||
connect(ui->render_3d_combobox,
|
connect(ui->render_3d_combobox,
|
||||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||||
@ -50,31 +50,26 @@ ConfigureEnhancements::ConfigureEnhancements(QWidget* parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureEnhancements::SetConfiguration() {
|
void ConfigureEnhancements::SetConfiguration() {
|
||||||
ui->resolution_factor_combobox->setCurrentIndex(Settings::values.resolution_factor.GetValue());
|
ui->resolution_factor_combobox->setCurrentIndex(Settings::values.resolution_factor);
|
||||||
ui->render_3d_combobox->setCurrentIndex(
|
ui->render_3d_combobox->setCurrentIndex(static_cast<int>(Settings::values.render_3d));
|
||||||
static_cast<int>(Settings::values.render_3d.GetValue()));
|
ui->factor_3d->setValue(Settings::values.factor_3d);
|
||||||
ui->factor_3d->setValue(Settings::values.factor_3d.GetValue());
|
updateShaders(Settings::values.render_3d);
|
||||||
ui->mono_rendering_eye->setCurrentIndex(
|
ui->toggle_linear_filter->setChecked(Settings::values.filter_mode);
|
||||||
static_cast<int>(Settings::values.mono_render_option.GetValue()));
|
|
||||||
updateShaders(Settings::values.render_3d.GetValue());
|
|
||||||
ui->toggle_linear_filter->setChecked(Settings::values.filter_mode.GetValue());
|
|
||||||
int tex_filter_idx = ui->texture_filter_combobox->findText(
|
int tex_filter_idx = ui->texture_filter_combobox->findText(
|
||||||
QString::fromStdString(Settings::values.texture_filter_name.GetValue()));
|
QString::fromStdString(Settings::values.texture_filter_name));
|
||||||
if (tex_filter_idx == -1) {
|
if (tex_filter_idx == -1) {
|
||||||
ui->texture_filter_combobox->setCurrentIndex(0);
|
ui->texture_filter_combobox->setCurrentIndex(0);
|
||||||
} else {
|
} else {
|
||||||
ui->texture_filter_combobox->setCurrentIndex(tex_filter_idx);
|
ui->texture_filter_combobox->setCurrentIndex(tex_filter_idx);
|
||||||
}
|
}
|
||||||
ui->layout_combobox->setCurrentIndex(
|
ui->layout_combobox->setCurrentIndex(static_cast<int>(Settings::values.layout_option));
|
||||||
static_cast<int>(Settings::values.layout_option.GetValue()));
|
ui->swap_screen->setChecked(Settings::values.swap_screen);
|
||||||
ui->swap_screen->setChecked(Settings::values.swap_screen.GetValue());
|
ui->upright_screen->setChecked(Settings::values.upright_screen);
|
||||||
ui->upright_screen->setChecked(Settings::values.upright_screen.GetValue());
|
ui->toggle_dump_textures->setChecked(Settings::values.dump_textures);
|
||||||
ui->toggle_dump_textures->setChecked(Settings::values.dump_textures.GetValue());
|
ui->toggle_custom_textures->setChecked(Settings::values.custom_textures);
|
||||||
ui->toggle_custom_textures->setChecked(Settings::values.custom_textures.GetValue());
|
ui->toggle_preload_textures->setChecked(Settings::values.preload_textures);
|
||||||
ui->toggle_preload_textures->setChecked(Settings::values.preload_textures.GetValue());
|
bg_color = QColor::fromRgbF(Settings::values.bg_red, Settings::values.bg_green,
|
||||||
bg_color =
|
Settings::values.bg_blue);
|
||||||
QColor::fromRgbF(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(),
|
|
||||||
Settings::values.bg_blue.GetValue());
|
|
||||||
QPixmap pixmap(ui->bg_button->size());
|
QPixmap pixmap(ui->bg_button->size());
|
||||||
pixmap.fill(bg_color);
|
pixmap.fill(bg_color);
|
||||||
const QIcon color_icon(pixmap);
|
const QIcon color_icon(pixmap);
|
||||||
@ -97,7 +92,7 @@ void ConfigureEnhancements::updateShaders(Settings::StereoRenderOption stereo_op
|
|||||||
for (const auto& shader : OpenGL::GetPostProcessingShaderList(
|
for (const auto& shader : OpenGL::GetPostProcessingShaderList(
|
||||||
stereo_option == Settings::StereoRenderOption::Anaglyph)) {
|
stereo_option == Settings::StereoRenderOption::Anaglyph)) {
|
||||||
ui->shader_combobox->addItem(QString::fromStdString(shader));
|
ui->shader_combobox->addItem(QString::fromStdString(shader));
|
||||||
if (Settings::values.pp_shader_name.GetValue() == shader)
|
if (Settings::values.pp_shader_name == shader)
|
||||||
ui->shader_combobox->setCurrentIndex(ui->shader_combobox->count() - 1);
|
ui->shader_combobox->setCurrentIndex(ui->shader_combobox->count() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,8 +107,6 @@ void ConfigureEnhancements::ApplyConfiguration() {
|
|||||||
Settings::values.render_3d =
|
Settings::values.render_3d =
|
||||||
static_cast<Settings::StereoRenderOption>(ui->render_3d_combobox->currentIndex());
|
static_cast<Settings::StereoRenderOption>(ui->render_3d_combobox->currentIndex());
|
||||||
Settings::values.factor_3d = ui->factor_3d->value();
|
Settings::values.factor_3d = ui->factor_3d->value();
|
||||||
Settings::values.mono_render_option =
|
|
||||||
static_cast<Settings::MonoRenderOption>(ui->mono_rendering_eye->currentIndex());
|
|
||||||
Settings::values.pp_shader_name =
|
Settings::values.pp_shader_name =
|
||||||
ui->shader_combobox->itemText(ui->shader_combobox->currentIndex()).toStdString();
|
ui->shader_combobox->itemText(ui->shader_combobox->currentIndex()).toStdString();
|
||||||
Settings::values.filter_mode = ui->toggle_linear_filter->isChecked();
|
Settings::values.filter_mode = ui->toggle_linear_filter->isChecked();
|
||||||
|
@ -6,10 +6,9 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
enum class StereoRenderOption : u32;
|
enum class StereoRenderOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -207,31 +207,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>Eye to Render in Monoscopic Mode</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="mono_rendering_eye">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Left Eye (default)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Right Eye</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -272,11 +247,6 @@
|
|||||||
<string>Side by Side</string>
|
<string>Side by Side</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Separate Windows</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@ -380,7 +350,6 @@
|
|||||||
<tabstop>texture_filter_combobox</tabstop>
|
<tabstop>texture_filter_combobox</tabstop>
|
||||||
<tabstop>render_3d_combobox</tabstop>
|
<tabstop>render_3d_combobox</tabstop>
|
||||||
<tabstop>factor_3d</tabstop>
|
<tabstop>factor_3d</tabstop>
|
||||||
<tabstop>mono_rendering_eye</tabstop>
|
|
||||||
<tabstop>layout_combobox</tabstop>
|
<tabstop>layout_combobox</tabstop>
|
||||||
<tabstop>swap_screen</tabstop>
|
<tabstop>swap_screen</tabstop>
|
||||||
<tabstop>upright_screen</tabstop>
|
<tabstop>upright_screen</tabstop>
|
||||||
|
@ -6,11 +6,10 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include "citra_qt/configuration/configuration_shared.h"
|
|
||||||
#include "citra_qt/configuration/configure_general.h"
|
#include "citra_qt/configuration/configure_general.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "common/file_util.h"
|
#include "core/core.h"
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
#include "ui_configure_general.h"
|
#include "ui_configure_general.h"
|
||||||
|
|
||||||
// The QSlider doesn't have an easy way to set a custom step amount,
|
// The QSlider doesn't have an easy way to set a custom step amount,
|
||||||
@ -32,17 +31,14 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
|||||||
// Set a minimum width for the label to prevent the slider from changing size.
|
// Set a minimum width for the label to prevent the slider from changing size.
|
||||||
// This scales across DPIs, and is acceptable for uncapitalized strings.
|
// This scales across DPIs, and is acceptable for uncapitalized strings.
|
||||||
ui->emulation_speed_display_label->setMinimumWidth(tr("unthrottled").size() * 6);
|
ui->emulation_speed_display_label->setMinimumWidth(tr("unthrottled").size() * 6);
|
||||||
ui->emulation_speed_combo->setVisible(!Settings::IsConfiguringGlobal());
|
|
||||||
ui->screenshot_combo->setVisible(!Settings::IsConfiguringGlobal());
|
|
||||||
|
|
||||||
SetupPerGameUI();
|
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
ui->updateBox->setVisible(UISettings::values.updater_found);
|
ui->updateBox->setVisible(UISettings::values.updater_found);
|
||||||
connect(ui->button_reset_defaults, &QPushButton::clicked, this,
|
connect(ui->button_reset_defaults, &QPushButton::clicked, this,
|
||||||
&ConfigureGeneral::ResetDefaults);
|
&ConfigureGeneral::ResetDefaults);
|
||||||
|
|
||||||
connect(ui->frame_limit, &QSlider::valueChanged, this, [&](int value) {
|
connect(ui->frame_limit, &QSlider::valueChanged, [&](int value) {
|
||||||
if (value == ui->frame_limit->maximum()) {
|
if (value == ui->frame_limit->maximum()) {
|
||||||
ui->emulation_speed_display_label->setText(tr("unthrottled"));
|
ui->emulation_speed_display_label->setText(tr("unthrottled"));
|
||||||
} else {
|
} else {
|
||||||
@ -53,6 +49,17 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(ui->frame_limit_alternate, &QSlider::valueChanged, [&](int value) {
|
||||||
|
if (value == ui->frame_limit_alternate->maximum()) {
|
||||||
|
ui->emulation_speed_alternate_display_label->setText(tr("unthrottled"));
|
||||||
|
} else {
|
||||||
|
ui->emulation_speed_alternate_display_label->setText(
|
||||||
|
QStringLiteral("%1%")
|
||||||
|
.arg(SliderToSettings(value))
|
||||||
|
.rightJustified(tr("unthrottled").size()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
connect(ui->change_screenshot_dir, &QToolButton::clicked, this, [this] {
|
connect(ui->change_screenshot_dir, &QToolButton::clicked, this, [this] {
|
||||||
const QString dir_path = QFileDialog::getExistingDirectory(
|
const QString dir_path = QFileDialog::getExistingDirectory(
|
||||||
this, tr("Select Screenshot Directory"), ui->screenshot_dir_path->text(),
|
this, tr("Select Screenshot Directory"), ui->screenshot_dir_path->text(),
|
||||||
@ -66,21 +73,20 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
|||||||
ConfigureGeneral::~ConfigureGeneral() = default;
|
ConfigureGeneral::~ConfigureGeneral() = default;
|
||||||
|
|
||||||
void ConfigureGeneral::SetConfiguration() {
|
void ConfigureGeneral::SetConfiguration() {
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing);
|
||||||
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing.GetValue());
|
ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background);
|
||||||
ui->toggle_background_pause->setChecked(
|
ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse);
|
||||||
UISettings::values.pause_when_in_background.GetValue());
|
|
||||||
ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse.GetValue());
|
|
||||||
|
|
||||||
ui->toggle_update_check->setChecked(
|
ui->toggle_update_check->setChecked(UISettings::values.check_for_update_on_start);
|
||||||
UISettings::values.check_for_update_on_start.GetValue());
|
ui->toggle_auto_update->setChecked(UISettings::values.update_on_close);
|
||||||
ui->toggle_auto_update->setChecked(UISettings::values.update_on_close.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings::values.frame_limit.GetValue() == 0) {
|
// The first item is "auto-select" with actual value -1, so plus one here will do the trick
|
||||||
|
ui->region_combobox->setCurrentIndex(Settings::values.region_value + 1);
|
||||||
|
|
||||||
|
if (Settings::values.frame_limit == 0) {
|
||||||
ui->frame_limit->setValue(ui->frame_limit->maximum());
|
ui->frame_limit->setValue(ui->frame_limit->maximum());
|
||||||
} else {
|
} else {
|
||||||
ui->frame_limit->setValue(SettingsToSlider(Settings::values.frame_limit.GetValue()));
|
ui->frame_limit->setValue(SettingsToSlider(Settings::values.frame_limit));
|
||||||
}
|
}
|
||||||
if (ui->frame_limit->value() == ui->frame_limit->maximum()) {
|
if (ui->frame_limit->value() == ui->frame_limit->maximum()) {
|
||||||
ui->emulation_speed_display_label->setText(tr("unthrottled"));
|
ui->emulation_speed_display_label->setText(tr("unthrottled"));
|
||||||
@ -91,48 +97,32 @@ void ConfigureGeneral::SetConfiguration() {
|
|||||||
.rightJustified(tr("unthrottled").size()));
|
.rightJustified(tr("unthrottled").size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Settings::IsConfiguringGlobal()) {
|
ui->toggle_alternate_speed->setChecked(Settings::values.use_frame_limit_alternate);
|
||||||
if (Settings::values.frame_limit.UsingGlobal()) {
|
|
||||||
ui->emulation_speed_combo->setCurrentIndex(0);
|
if (Settings::values.frame_limit_alternate == 0) {
|
||||||
ui->frame_limit->setEnabled(false);
|
ui->frame_limit_alternate->setValue(ui->frame_limit_alternate->maximum());
|
||||||
} else {
|
} else {
|
||||||
ui->emulation_speed_combo->setCurrentIndex(1);
|
ui->frame_limit_alternate->setValue(
|
||||||
ui->frame_limit->setEnabled(true);
|
SettingsToSlider(Settings::values.frame_limit_alternate));
|
||||||
}
|
}
|
||||||
if (UISettings::values.screenshot_path.UsingGlobal()) {
|
if (ui->frame_limit_alternate->value() == ui->frame_limit_alternate->maximum()) {
|
||||||
ui->screenshot_combo->setCurrentIndex(0);
|
ui->emulation_speed_alternate_display_label->setText(tr("unthrottled"));
|
||||||
ui->screenshot_dir_path->setEnabled(false);
|
|
||||||
ui->change_screenshot_dir->setEnabled(false);
|
|
||||||
} else {
|
} else {
|
||||||
ui->screenshot_combo->setCurrentIndex(1);
|
ui->emulation_speed_alternate_display_label->setText(
|
||||||
ui->screenshot_dir_path->setEnabled(true);
|
QStringLiteral("%1%")
|
||||||
ui->change_screenshot_dir->setEnabled(true);
|
.arg(SliderToSettings(ui->frame_limit_alternate->value()))
|
||||||
}
|
.rightJustified(tr("unthrottled").size()));
|
||||||
ConfigurationShared::SetHighlight(ui->widget_screenshot,
|
|
||||||
!UISettings::values.screenshot_path.UsingGlobal());
|
|
||||||
ConfigurationShared::SetHighlight(ui->emulation_speed_layout,
|
|
||||||
!Settings::values.frame_limit.UsingGlobal());
|
|
||||||
ConfigurationShared::SetHighlight(ui->widget_region,
|
|
||||||
!Settings::values.region_value.UsingGlobal());
|
|
||||||
const bool is_region_global = Settings::values.region_value.UsingGlobal();
|
|
||||||
ui->region_combobox->setCurrentIndex(
|
|
||||||
is_region_global ? ConfigurationShared::USE_GLOBAL_INDEX
|
|
||||||
: static_cast<int>(Settings::values.region_value.GetValue()) +
|
|
||||||
ConfigurationShared::USE_GLOBAL_OFFSET + 1);
|
|
||||||
} else {
|
|
||||||
// The first item is "auto-select" with actual value -1, so plus one here will do the trick
|
|
||||||
ui->region_combobox->setCurrentIndex(Settings::values.region_value.GetValue() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UISettings::values.screenshot_path.SetGlobal(ui->screenshot_combo->currentIndex() ==
|
QString screenshot_path = UISettings::values.screenshot_path;
|
||||||
ConfigurationShared::USE_GLOBAL_INDEX);
|
if (screenshot_path.isEmpty()) {
|
||||||
std::string screenshot_path = UISettings::values.screenshot_path.GetValue();
|
screenshot_path =
|
||||||
if (screenshot_path.empty()) {
|
QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::UserDir));
|
||||||
screenshot_path = FileUtil::GetUserPath(FileUtil::UserPath::UserDir) + "screenshots/";
|
screenshot_path.append(QStringLiteral("screenshots/"));
|
||||||
FileUtil::CreateFullPath(screenshot_path);
|
Common::FS::CreateFullPath(screenshot_path.toStdString());
|
||||||
UISettings::values.screenshot_path = screenshot_path;
|
UISettings::values.screenshot_path = screenshot_path;
|
||||||
}
|
}
|
||||||
ui->screenshot_dir_path->setText(QString::fromStdString(screenshot_path));
|
ui->screenshot_dir_path->setText(screenshot_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::ResetDefaults() {
|
void ConfigureGeneral::ResetDefaults() {
|
||||||
@ -141,67 +131,39 @@ void ConfigureGeneral::ResetDefaults() {
|
|||||||
tr("Are you sure you want to <b>reset your settings</b> and close Citra?"),
|
tr("Are you sure you want to <b>reset your settings</b> and close Citra?"),
|
||||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||||
|
|
||||||
if (answer == QMessageBox::No) {
|
if (answer == QMessageBox::No)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + "qt-config.ini");
|
Common::FS::Delete(Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir) + "qt-config.ini");
|
||||||
FileUtil::DeleteDirRecursively(FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + "custom");
|
|
||||||
std::exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::ApplyConfiguration() {
|
void ConfigureGeneral::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.region_value, ui->region_combobox,
|
|
||||||
[](s32 index) { return index - 1; });
|
|
||||||
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(
|
|
||||||
&Settings::values.frame_limit, ui->emulation_speed_combo, [this](s32) {
|
|
||||||
const bool is_maximum = ui->frame_limit->value() == ui->frame_limit->maximum();
|
|
||||||
return is_maximum ? 0 : SliderToSettings(ui->frame_limit->value());
|
|
||||||
});
|
|
||||||
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(
|
|
||||||
&UISettings::values.screenshot_path, ui->screenshot_combo,
|
|
||||||
[this](s32) { return ui->screenshot_dir_path->text().toStdString(); });
|
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
|
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
|
||||||
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
|
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
|
||||||
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
|
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
|
||||||
|
|
||||||
UISettings::values.check_for_update_on_start = ui->toggle_update_check->isChecked();
|
UISettings::values.check_for_update_on_start = ui->toggle_update_check->isChecked();
|
||||||
UISettings::values.update_on_close = ui->toggle_auto_update->isChecked();
|
UISettings::values.update_on_close = ui->toggle_auto_update->isChecked();
|
||||||
|
|
||||||
|
UISettings::values.screenshot_path = ui->screenshot_dir_path->text();
|
||||||
|
|
||||||
|
Settings::values.region_value = ui->region_combobox->currentIndex() - 1;
|
||||||
|
|
||||||
|
if (ui->frame_limit->value() == ui->frame_limit->maximum()) {
|
||||||
|
Settings::values.frame_limit = 0;
|
||||||
|
} else {
|
||||||
|
Settings::values.frame_limit = SliderToSettings(ui->frame_limit->value());
|
||||||
|
}
|
||||||
|
Settings::values.use_frame_limit_alternate = ui->toggle_alternate_speed->isChecked();
|
||||||
|
if (ui->frame_limit_alternate->value() == ui->frame_limit_alternate->maximum()) {
|
||||||
|
Settings::values.frame_limit_alternate = 0;
|
||||||
|
} else {
|
||||||
|
Settings::values.frame_limit_alternate =
|
||||||
|
SliderToSettings(ui->frame_limit_alternate->value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::RetranslateUI() {
|
void ConfigureGeneral::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::SetupPerGameUI() {
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
ui->region_combobox->setEnabled(Settings::values.region_value.UsingGlobal());
|
|
||||||
ui->frame_limit->setEnabled(Settings::values.frame_limit.UsingGlobal());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(ui->emulation_speed_combo, qOverload<int>(&QComboBox::activated), this,
|
|
||||||
[this](int index) {
|
|
||||||
ui->frame_limit->setEnabled(index == 1);
|
|
||||||
ConfigurationShared::SetHighlight(ui->emulation_speed_layout, index == 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(ui->screenshot_combo, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
|
||||||
ui->screenshot_dir_path->setEnabled(index == 1);
|
|
||||||
ui->change_screenshot_dir->setEnabled(index == 1);
|
|
||||||
ConfigurationShared::SetHighlight(ui->widget_screenshot, index == 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
ui->general_group->setVisible(false);
|
|
||||||
ui->updateBox->setVisible(false);
|
|
||||||
ui->button_reset_defaults->setVisible(false);
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredComboBox(
|
|
||||||
ui->region_combobox, ui->widget_region,
|
|
||||||
static_cast<u32>(Settings::values.region_value.GetValue(true) + 1));
|
|
||||||
}
|
|
||||||
|
@ -25,8 +25,6 @@ public:
|
|||||||
void RetranslateUI();
|
void RetranslateUI();
|
||||||
void SetConfiguration();
|
void SetConfiguration();
|
||||||
|
|
||||||
void SetupPerGameUI();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::ConfigureGeneral> ui;
|
std::unique_ptr<Ui::ConfigureGeneral> ui;
|
||||||
};
|
};
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>524</width>
|
<width>408</width>
|
||||||
<height>578</height>
|
<height>436</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="general_group">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>General</string>
|
<string>General</string>
|
||||||
</property>
|
</property>
|
||||||
@ -70,34 +70,12 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="emulation_group">
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Emulation</string>
|
<string>Emulation</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item>
|
<item row="0" column="2">
|
||||||
<widget class="QWidget" name="widget_region" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="region_layout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="region_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Region:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="region_combobox">
|
<widget class="QComboBox" name="region_combobox">
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -141,46 +119,21 @@
|
|||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<item row="1" column="0">
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="emulation_speed_layout" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="emulation_speed_layout_inner">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="emulation_speed_combo">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use global emulation speed</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Set emulation speed:</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_emulation_speed">
|
<widget class="QLabel" name="label_emulation_speed">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Emulation Speed:</string>
|
<string>Emulation Speed:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="toggle_alternate_speed">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use Alternate Speed:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
<widget class="QSlider" name="frame_limit">
|
<widget class="QSlider" name="frame_limit">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
@ -205,7 +158,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="1" column="1">
|
||||||
<widget class="QLabel" name="emulation_speed_display_label">
|
<widget class="QLabel" name="emulation_speed_display_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
@ -215,59 +168,67 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Region:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QSlider" name="frame_limit_alternate">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>199</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>39</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickPosition">
|
||||||
|
<enum>QSlider::TicksBelow</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="emulation_speed_alternate_display_label">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="screenshot_group">
|
<widget class="QGroupBox" name="screenshot_group">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Screenshots</string>
|
<string>Screenshots</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="verticalSpacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QWidget" name="widget_screenshot" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="screenshot_layout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="screenshot_combo">
|
<widget class="QLabel" name="label_2">
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use global screenshot path</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Set screenshot path:</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="screenshot_dir_label">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Save Screenshots To</string>
|
<string>Save Screenshots To</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="screenshot_dir_path"/>
|
<widget class="QLineEdit" name="screenshot_dir_path">
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="change_screenshot_dir">
|
<widget class="QToolButton" name="change_screenshot_dir">
|
||||||
@ -279,9 +240,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item alignment="Qt::AlignRight">
|
<item alignment="Qt::AlignRight">
|
||||||
<widget class="QPushButton" name="button_reset_defaults">
|
<widget class="QPushButton" name="button_reset_defaults">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -312,6 +270,12 @@
|
|||||||
<tabstop>toggle_hide_mouse</tabstop>
|
<tabstop>toggle_hide_mouse</tabstop>
|
||||||
<tabstop>toggle_update_check</tabstop>
|
<tabstop>toggle_update_check</tabstop>
|
||||||
<tabstop>toggle_auto_update</tabstop>
|
<tabstop>toggle_auto_update</tabstop>
|
||||||
|
<tabstop>region_combobox</tabstop>
|
||||||
|
<tabstop>frame_limit</tabstop>
|
||||||
|
<tabstop>toggle_alternate_speed</tabstop>
|
||||||
|
<tabstop>frame_limit_alternate</tabstop>
|
||||||
|
<tabstop>screenshot_dir_path</tabstop>
|
||||||
|
<tabstop>change_screenshot_dir</tabstop>
|
||||||
<tabstop>button_reset_defaults</tabstop>
|
<tabstop>button_reset_defaults</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
@ -6,19 +6,16 @@
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#endif
|
#endif
|
||||||
#include "citra_qt/configuration/configuration_shared.h"
|
|
||||||
#include "citra_qt/configuration/configure_graphics.h"
|
#include "citra_qt/configuration/configure_graphics.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "ui_configure_graphics.h"
|
#include "ui_configure_graphics.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
|
|
||||||
ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureGraphics>()) {
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureGraphics>()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
DiscoverPhysicalDevices();
|
DiscoverPhysicalDevices();
|
||||||
SetupPerGameUI();
|
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
const bool not_running = !Core::System::GetInstance().IsPoweredOn();
|
const bool not_running = !Core::System::GetInstance().IsPoweredOn();
|
||||||
@ -29,6 +26,7 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
|||||||
ui->graphics_api_combo->setEnabled(not_running);
|
ui->graphics_api_combo->setEnabled(not_running);
|
||||||
ui->toggle_shader_jit->setEnabled(not_running);
|
ui->toggle_shader_jit->setEnabled(not_running);
|
||||||
ui->toggle_disk_shader_cache->setEnabled(hw_renderer_enabled && not_running);
|
ui->toggle_disk_shader_cache->setEnabled(hw_renderer_enabled && not_running);
|
||||||
|
ui->toggle_async_recording->setEnabled(hw_renderer_enabled && not_running);
|
||||||
ui->physical_device_combo->setEnabled(not_running);
|
ui->physical_device_combo->setEnabled(not_running);
|
||||||
SetPhysicalDeviceComboVisibility(ui->graphics_api_combo->currentIndex());
|
SetPhysicalDeviceComboVisibility(ui->graphics_api_combo->currentIndex());
|
||||||
|
|
||||||
@ -36,7 +34,7 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
|||||||
&ConfigureGraphics::SetPhysicalDeviceComboVisibility);
|
&ConfigureGraphics::SetPhysicalDeviceComboVisibility);
|
||||||
|
|
||||||
connect(ui->toggle_hw_renderer, &QCheckBox::toggled, this, [this] {
|
connect(ui->toggle_hw_renderer, &QCheckBox::toggled, this, [this] {
|
||||||
const bool checked = ui->toggle_hw_renderer->isChecked();
|
auto checked = ui->toggle_hw_renderer->isChecked();
|
||||||
ui->hw_renderer_group->setEnabled(checked);
|
ui->hw_renderer_group->setEnabled(checked);
|
||||||
ui->toggle_disk_shader_cache->setEnabled(checked && ui->toggle_hw_shader->isChecked());
|
ui->toggle_disk_shader_cache->setEnabled(checked && ui->toggle_hw_shader->isChecked());
|
||||||
});
|
});
|
||||||
@ -77,85 +75,36 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
|||||||
ConfigureGraphics::~ConfigureGraphics() = default;
|
ConfigureGraphics::~ConfigureGraphics() = default;
|
||||||
|
|
||||||
void ConfigureGraphics::SetConfiguration() {
|
void ConfigureGraphics::SetConfiguration() {
|
||||||
ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer.GetValue());
|
ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer);
|
||||||
ui->toggle_hw_shader->setChecked(Settings::values.use_hw_shader.GetValue());
|
ui->toggle_hw_shader->setChecked(Settings::values.use_hw_shader);
|
||||||
ui->toggle_separable_shader->setChecked(Settings::values.separable_shader.GetValue());
|
ui->toggle_separable_shader->setChecked(Settings::values.separable_shader);
|
||||||
ui->toggle_accurate_mul->setChecked(Settings::values.shaders_accurate_mul.GetValue());
|
ui->toggle_accurate_mul->setChecked(Settings::values.shaders_accurate_mul);
|
||||||
ui->toggle_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue());
|
ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit);
|
||||||
ui->toggle_vsync_new->setChecked(Settings::values.use_vsync_new.GetValue());
|
ui->toggle_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache);
|
||||||
ui->graphics_api_combo->setCurrentIndex(
|
ui->toggle_vsync_new->setChecked(Settings::values.use_vsync_new);
|
||||||
static_cast<int>(Settings::values.graphics_api.GetValue()));
|
ui->graphics_api_combo->setCurrentIndex(static_cast<int>(Settings::values.graphics_api));
|
||||||
ui->physical_device_combo->setCurrentIndex(
|
ui->physical_device_combo->setCurrentIndex(static_cast<int>(Settings::values.physical_device));
|
||||||
static_cast<int>(Settings::values.physical_device.GetValue()));
|
ui->toggle_async_recording->setChecked(Settings::values.async_command_recording);
|
||||||
ui->toggle_async_recording->setChecked(Settings::values.async_command_recording.GetValue());
|
|
||||||
ui->spirv_shader_gen->setChecked(Settings::values.spirv_shader_gen.GetValue());
|
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit.GetValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGraphics::ApplyConfiguration() {
|
void ConfigureGraphics::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_hw_renderer,
|
Settings::values.use_hw_renderer = ui->toggle_hw_renderer->isChecked();
|
||||||
ui->toggle_hw_renderer, use_hw_renderer);
|
Settings::values.use_hw_shader = ui->toggle_hw_shader->isChecked();
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_hw_shader, ui->toggle_hw_shader,
|
Settings::values.separable_shader = ui->toggle_separable_shader->isChecked();
|
||||||
use_hw_shader);
|
Settings::values.shaders_accurate_mul = ui->toggle_accurate_mul->isChecked();
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.separable_shader,
|
|
||||||
ui->toggle_separable_shader, separable_shader);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.shaders_accurate_mul,
|
|
||||||
ui->toggle_accurate_mul, shaders_accurate_mul);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_disk_shader_cache,
|
|
||||||
ui->toggle_disk_shader_cache, use_disk_shader_cache);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync_new, ui->toggle_vsync_new,
|
|
||||||
use_vsync_new);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.graphics_api,
|
|
||||||
ui->graphics_api_combo);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.physical_device,
|
|
||||||
ui->physical_device_combo);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_command_recording,
|
|
||||||
ui->toggle_async_recording, async_command_recording);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.spirv_shader_gen,
|
|
||||||
ui->spirv_shader_gen, spirv_shader_gen);
|
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked();
|
Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked();
|
||||||
}
|
Settings::values.use_disk_shader_cache = ui->toggle_disk_shader_cache->isChecked();
|
||||||
|
Settings::values.use_vsync_new = ui->toggle_vsync_new->isChecked();
|
||||||
|
Settings::values.graphics_api =
|
||||||
|
static_cast<Settings::GraphicsAPI>(ui->graphics_api_combo->currentIndex());
|
||||||
|
Settings::values.physical_device = static_cast<u16>(ui->physical_device_combo->currentIndex());
|
||||||
|
Settings::values.async_command_recording = ui->toggle_async_recording->isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGraphics::RetranslateUI() {
|
void ConfigureGraphics::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGraphics::SetupPerGameUI() {
|
|
||||||
// Block the global settings if a game is currently running that overrides them
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
ui->toggle_hw_renderer->setEnabled(Settings::values.use_hw_renderer.UsingGlobal());
|
|
||||||
ui->toggle_hw_shader->setEnabled(Settings::values.use_hw_shader.UsingGlobal());
|
|
||||||
ui->toggle_separable_shader->setEnabled(Settings::values.separable_shader.UsingGlobal());
|
|
||||||
ui->toggle_accurate_mul->setEnabled(Settings::values.shaders_accurate_mul.UsingGlobal());
|
|
||||||
ui->toggle_disk_shader_cache->setEnabled(
|
|
||||||
Settings::values.use_disk_shader_cache.UsingGlobal());
|
|
||||||
ui->toggle_vsync_new->setEnabled(Settings::values.use_vsync_new.UsingGlobal());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->toggle_shader_jit->setVisible(false);
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->toggle_hw_renderer,
|
|
||||||
Settings::values.use_hw_renderer, use_hw_renderer);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->toggle_hw_shader, Settings::values.use_hw_shader,
|
|
||||||
use_hw_shader);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->toggle_separable_shader,
|
|
||||||
Settings::values.separable_shader, separable_shader);
|
|
||||||
ConfigurationShared::SetColoredTristate(
|
|
||||||
ui->toggle_accurate_mul, Settings::values.shaders_accurate_mul, shaders_accurate_mul);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->toggle_disk_shader_cache,
|
|
||||||
Settings::values.use_disk_shader_cache,
|
|
||||||
use_disk_shader_cache);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->toggle_vsync_new, Settings::values.use_vsync_new,
|
|
||||||
use_vsync_new);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureGraphics::DiscoverPhysicalDevices() {
|
void ConfigureGraphics::DiscoverPhysicalDevices() {
|
||||||
Vulkan::Instance instance{};
|
Vulkan::Instance instance{};
|
||||||
const auto physical_devices = instance.GetPhysicalDevices();
|
const auto physical_devices = instance.GetPhysicalDevices();
|
||||||
@ -172,5 +121,4 @@ void ConfigureGraphics::SetPhysicalDeviceComboVisibility(int index) {
|
|||||||
const bool is_visible = graphics_api == Settings::GraphicsAPI::Vulkan;
|
const bool is_visible = graphics_api == Settings::GraphicsAPI::Vulkan;
|
||||||
ui->physical_device_label->setVisible(is_visible);
|
ui->physical_device_label->setVisible(is_visible);
|
||||||
ui->physical_device_combo->setVisible(is_visible);
|
ui->physical_device_combo->setVisible(is_visible);
|
||||||
ui->spirv_shader_gen->setVisible(is_visible);
|
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,6 @@ namespace Ui {
|
|||||||
class ConfigureGraphics;
|
class ConfigureGraphics;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
|
||||||
enum class CheckState;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConfigureGraphics : public QWidget {
|
class ConfigureGraphics : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -28,20 +24,11 @@ public:
|
|||||||
|
|
||||||
void UpdateBackgroundColorButton(const QColor& color);
|
void UpdateBackgroundColorButton(const QColor& color);
|
||||||
|
|
||||||
void SetupPerGameUI();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DiscoverPhysicalDevices();
|
void DiscoverPhysicalDevices();
|
||||||
void SetPhysicalDeviceComboVisibility(int index);
|
void SetPhysicalDeviceComboVisibility(int index);
|
||||||
|
|
||||||
ConfigurationShared::CheckState use_hw_renderer;
|
private:
|
||||||
ConfigurationShared::CheckState use_hw_shader;
|
|
||||||
ConfigurationShared::CheckState separable_shader;
|
|
||||||
ConfigurationShared::CheckState shaders_accurate_mul;
|
|
||||||
ConfigurationShared::CheckState use_disk_shader_cache;
|
|
||||||
ConfigurationShared::CheckState use_vsync_new;
|
|
||||||
ConfigurationShared::CheckState async_command_recording;
|
|
||||||
ConfigurationShared::CheckState spirv_shader_gen;
|
|
||||||
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
||||||
QColor bg_color;
|
QColor bg_color;
|
||||||
};
|
};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>400</width>
|
<width>400</width>
|
||||||
<height>513</height>
|
<height>430</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
@ -70,13 +70,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="spirv_shader_gen">
|
|
||||||
<property name="text">
|
|
||||||
<string>SPIR-V Shader Generation</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "citra_qt/configuration/configure_hotkeys.h"
|
#include "citra_qt/configuration/configure_hotkeys.h"
|
||||||
#include "citra_qt/hotkeys.h"
|
#include "citra_qt/hotkeys.h"
|
||||||
#include "citra_qt/util/sequence_dialog/sequence_dialog.h"
|
#include "citra_qt/util/sequence_dialog/sequence_dialog.h"
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
#include "ui_configure_hotkeys.h"
|
#include "ui_configure_hotkeys.h"
|
||||||
|
|
||||||
ConfigureHotkeys::ConfigureHotkeys(QWidget* parent)
|
ConfigureHotkeys::ConfigureHotkeys(QWidget* parent)
|
||||||
|
@ -195,21 +195,8 @@ ConfigureInput::ConfigureInput(QWidget* parent)
|
|||||||
connect(button_map[button_id], &QPushButton::clicked, [this, button_id]() {
|
connect(button_map[button_id], &QPushButton::clicked, [this, button_id]() {
|
||||||
HandleClick(
|
HandleClick(
|
||||||
button_map[button_id],
|
button_map[button_id],
|
||||||
[this, button_id](Common::ParamPackage params) {
|
[this, button_id](const Common::ParamPackage& params) {
|
||||||
// Workaround for ZL & ZR for analog triggers like on XBOX controllors.
|
buttons_param[button_id] = params;
|
||||||
// Analog triggers (from controllers like the XBOX controller) would not
|
|
||||||
// work due to a different range of their signals (from 0 to 255 on
|
|
||||||
// analog triggers instead of -32768 to 32768 on analog joysticks). The
|
|
||||||
// SDL driver misinterprets analog triggers as analog joysticks.
|
|
||||||
// TODO: reinterpret the signal range for analog triggers to map the
|
|
||||||
// values correctly. This is required for the correct emulation of the
|
|
||||||
// analog triggers of the GameCube controller.
|
|
||||||
if (button_id == Settings::NativeButton::ZL ||
|
|
||||||
button_id == Settings::NativeButton::ZR) {
|
|
||||||
params.Set("direction", "+");
|
|
||||||
params.Set("threshold", "0.5");
|
|
||||||
}
|
|
||||||
buttons_param[button_id] = std::move(params);
|
|
||||||
// If the user closes the dialog, the changes are reverted in
|
// If the user closes the dialog, the changes are reverted in
|
||||||
// `GMainWindow::OnConfigure()`
|
// `GMainWindow::OnConfigure()`
|
||||||
ApplyConfiguration();
|
ApplyConfiguration();
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
|
|
||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
|
@ -23,9 +23,8 @@ CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent,
|
|||||||
status_label = new QLabel(tr("Communicating with the server..."));
|
status_label = new QLabel(tr("Communicating with the server..."));
|
||||||
cancel_button = new QPushButton(tr("Cancel"));
|
cancel_button = new QPushButton(tr("Cancel"));
|
||||||
connect(cancel_button, &QPushButton::clicked, this, [this] {
|
connect(cancel_button, &QPushButton::clicked, this, [this] {
|
||||||
if (!completed) {
|
if (!completed)
|
||||||
job->Stop();
|
job->Stop();
|
||||||
}
|
|
||||||
accept();
|
accept();
|
||||||
});
|
});
|
||||||
layout->addWidget(status_label);
|
layout->addWidget(status_label);
|
||||||
@ -67,33 +66,31 @@ CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent,
|
|||||||
|
|
||||||
CalibrationConfigurationDialog::~CalibrationConfigurationDialog() = default;
|
CalibrationConfigurationDialog::~CalibrationConfigurationDialog() = default;
|
||||||
|
|
||||||
void CalibrationConfigurationDialog::UpdateLabelText(const QString& text) {
|
void CalibrationConfigurationDialog::UpdateLabelText(QString text) {
|
||||||
status_label->setText(text);
|
status_label->setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalibrationConfigurationDialog::UpdateButtonText(const QString& text) {
|
void CalibrationConfigurationDialog::UpdateButtonText(QString text) {
|
||||||
cancel_button->setText(text);
|
cancel_button->setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr std::array<std::pair<const char*, const char*>, 3> MotionProviders = {{
|
const std::array<std::pair<const char*, const char*>, 3> MotionProviders = {
|
||||||
{"motion_emu", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Mouse (Right Click)")},
|
{{"motion_emu", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Mouse (Right Click)")},
|
||||||
{"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")},
|
{"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")},
|
||||||
{"sdl", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "SDL")},
|
{"sdl", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "SDL")}}};
|
||||||
}};
|
|
||||||
|
|
||||||
constexpr std::array<std::pair<const char*, const char*>, 2> TouchProviders = {{
|
const std::array<std::pair<const char*, const char*>, 2> TouchProviders = {
|
||||||
{"emu_window", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Emulator Window")},
|
{{"emu_window", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Emulator Window")},
|
||||||
{"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")},
|
{"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")}}};
|
||||||
}};
|
|
||||||
|
|
||||||
ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent)
|
ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent)
|
||||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigureMotionTouch>()),
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigureMotionTouch>()),
|
||||||
timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) {
|
timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
for (const auto& [provider, name] : MotionProviders) {
|
for (auto [provider, name] : MotionProviders) {
|
||||||
ui->motion_provider->addItem(tr(name), QString::fromUtf8(provider));
|
ui->motion_provider->addItem(tr(name), QString::fromUtf8(provider));
|
||||||
}
|
}
|
||||||
for (const auto& [provider, name] : TouchProviders) {
|
for (auto [provider, name] : TouchProviders) {
|
||||||
ui->touch_provider->addItem(tr(name), QString::fromUtf8(provider));
|
ui->touch_provider->addItem(tr(name), QString::fromUtf8(provider));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,10 +125,10 @@ ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent)
|
|||||||
ConfigureMotionTouch::~ConfigureMotionTouch() = default;
|
ConfigureMotionTouch::~ConfigureMotionTouch() = default;
|
||||||
|
|
||||||
void ConfigureMotionTouch::SetConfiguration() {
|
void ConfigureMotionTouch::SetConfiguration() {
|
||||||
const Common::ParamPackage motion_param(Settings::values.current_input_profile.motion_device);
|
Common::ParamPackage motion_param(Settings::values.current_input_profile.motion_device);
|
||||||
const Common::ParamPackage touch_param(Settings::values.current_input_profile.touch_device);
|
Common::ParamPackage touch_param(Settings::values.current_input_profile.touch_device);
|
||||||
const std::string motion_engine = motion_param.Get("engine", "motion_emu");
|
std::string motion_engine = motion_param.Get("engine", "motion_emu");
|
||||||
const std::string touch_engine = touch_param.Get("engine", "emu_window");
|
std::string touch_engine = touch_param.Get("engine", "emu_window");
|
||||||
|
|
||||||
ui->motion_provider->setCurrentIndex(
|
ui->motion_provider->setCurrentIndex(
|
||||||
ui->motion_provider->findData(QString::fromStdString(motion_engine)));
|
ui->motion_provider->findData(QString::fromStdString(motion_engine)));
|
||||||
@ -162,8 +159,8 @@ void ConfigureMotionTouch::SetConfiguration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureMotionTouch::UpdateUiDisplay() {
|
void ConfigureMotionTouch::UpdateUiDisplay() {
|
||||||
const std::string motion_engine = ui->motion_provider->currentData().toString().toStdString();
|
std::string motion_engine = ui->motion_provider->currentData().toString().toStdString();
|
||||||
const std::string touch_engine = ui->touch_provider->currentData().toString().toStdString();
|
std::string touch_engine = ui->touch_provider->currentData().toString().toStdString();
|
||||||
|
|
||||||
if (motion_engine == "motion_emu") {
|
if (motion_engine == "motion_emu") {
|
||||||
ui->motion_sensitivity_label->setVisible(true);
|
ui->motion_sensitivity_label->setVisible(true);
|
||||||
@ -185,8 +182,9 @@ void ConfigureMotionTouch::UpdateUiDisplay() {
|
|||||||
ui->touch_calibration->setVisible(true);
|
ui->touch_calibration->setVisible(true);
|
||||||
ui->touch_calibration_config->setVisible(true);
|
ui->touch_calibration_config->setVisible(true);
|
||||||
ui->touch_calibration_label->setVisible(true);
|
ui->touch_calibration_label->setVisible(true);
|
||||||
ui->touch_calibration->setText(
|
ui->touch_calibration->setText(QStringLiteral("(%1, %2) - (%3, %4)")
|
||||||
QStringLiteral("(%1, %2) - (%3, %4)").arg(min_x).arg(min_y).arg(max_x).arg(max_y));
|
.arg(QString::number(min_x), QString::number(min_y),
|
||||||
|
QString::number(max_x), QString::number(max_y)));
|
||||||
} else {
|
} else {
|
||||||
ui->touch_calibration->setVisible(false);
|
ui->touch_calibration->setVisible(false);
|
||||||
ui->touch_calibration_config->setVisible(false);
|
ui->touch_calibration_config->setVisible(false);
|
||||||
@ -201,9 +199,11 @@ void ConfigureMotionTouch::UpdateUiDisplay() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureMotionTouch::ConnectEvents() {
|
void ConfigureMotionTouch::ConnectEvents() {
|
||||||
connect(ui->motion_provider, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
connect(ui->motion_provider,
|
||||||
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||||
[this]([[maybe_unused]] int index) { UpdateUiDisplay(); });
|
[this]([[maybe_unused]] int index) { UpdateUiDisplay(); });
|
||||||
connect(ui->touch_provider, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
connect(ui->touch_provider,
|
||||||
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||||
[this]([[maybe_unused]] int index) { UpdateUiDisplay(); });
|
[this]([[maybe_unused]] int index) { UpdateUiDisplay(); });
|
||||||
connect(ui->motion_controller_button, &QPushButton::clicked, this, [this]() {
|
connect(ui->motion_controller_button, &QPushButton::clicked, this, [this]() {
|
||||||
if (QMessageBox::information(this, tr("Information"),
|
if (QMessageBox::information(this, tr("Information"),
|
||||||
@ -235,9 +235,8 @@ void ConfigureMotionTouch::ConnectEvents() {
|
|||||||
connect(ui->touch_from_button_config_btn, &QPushButton::clicked, this,
|
connect(ui->touch_from_button_config_btn, &QPushButton::clicked, this,
|
||||||
&ConfigureMotionTouch::OnConfigureTouchFromButton);
|
&ConfigureMotionTouch::OnConfigureTouchFromButton);
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, [this] {
|
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, [this] {
|
||||||
if (CanCloseDialog()) {
|
if (CanCloseDialog())
|
||||||
reject();
|
reject();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,15 +275,15 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() {
|
|||||||
void ConfigureMotionTouch::OnConfigureTouchCalibration() {
|
void ConfigureMotionTouch::OnConfigureTouchCalibration() {
|
||||||
ui->touch_calibration_config->setEnabled(false);
|
ui->touch_calibration_config->setEnabled(false);
|
||||||
ui->touch_calibration_config->setText(tr("Configuring"));
|
ui->touch_calibration_config->setText(tr("Configuring"));
|
||||||
CalibrationConfigurationDialog dialog(
|
CalibrationConfigurationDialog* dialog = new CalibrationConfigurationDialog(
|
||||||
this, ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toUInt()),
|
this, ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toUInt()),
|
||||||
static_cast<u8>(ui->udp_pad_index->currentIndex()), 24872);
|
static_cast<u8>(ui->udp_pad_index->currentIndex()), 24872);
|
||||||
dialog.exec();
|
dialog->exec();
|
||||||
if (dialog.completed) {
|
if (dialog->completed) {
|
||||||
min_x = dialog.min_x;
|
min_x = dialog->min_x;
|
||||||
min_y = dialog.min_y;
|
min_y = dialog->min_y;
|
||||||
max_x = dialog.max_x;
|
max_x = dialog->max_x;
|
||||||
max_y = dialog.max_y;
|
max_y = dialog->max_y;
|
||||||
LOG_INFO(Frontend,
|
LOG_INFO(Frontend,
|
||||||
"UDP touchpad calibration config success: min_x={}, min_y={}, max_x={}, max_y={}",
|
"UDP touchpad calibration config success: min_x={}, min_y={}, max_x={}, max_y={}",
|
||||||
min_x, min_y, max_x, max_y);
|
min_x, min_y, max_x, max_y);
|
||||||
@ -297,12 +296,11 @@ void ConfigureMotionTouch::OnConfigureTouchCalibration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureMotionTouch::closeEvent(QCloseEvent* event) {
|
void ConfigureMotionTouch::closeEvent(QCloseEvent* event) {
|
||||||
if (CanCloseDialog()) {
|
if (CanCloseDialog())
|
||||||
event->accept();
|
event->accept();
|
||||||
} else {
|
else
|
||||||
event->ignore();
|
event->ignore();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureMotionTouch::ShowUDPTestResult(bool result) {
|
void ConfigureMotionTouch::ShowUDPTestResult(bool result) {
|
||||||
udp_test_in_progress = false;
|
udp_test_in_progress = false;
|
||||||
@ -347,15 +345,16 @@ bool ConfigureMotionTouch::CanCloseDialog() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureMotionTouch::ApplyConfiguration() {
|
void ConfigureMotionTouch::ApplyConfiguration() {
|
||||||
if (!CanCloseDialog()) {
|
if (!CanCloseDialog())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
std::string motion_engine = ui->motion_provider->currentData().toString().toStdString();
|
std::string motion_engine = ui->motion_provider->currentData().toString().toStdString();
|
||||||
std::string touch_engine = ui->touch_provider->currentData().toString().toStdString();
|
std::string touch_engine = ui->touch_provider->currentData().toString().toStdString();
|
||||||
|
|
||||||
Common::ParamPackage motion_param{};
|
Common::ParamPackage motion_param{}, touch_param{};
|
||||||
motion_param.Set("engine", motion_engine);
|
motion_param.Set("engine", motion_engine);
|
||||||
|
touch_param.Set("engine", touch_engine);
|
||||||
|
|
||||||
if (motion_engine == "motion_emu") {
|
if (motion_engine == "motion_emu") {
|
||||||
motion_param.Set("sensitivity", static_cast<float>(ui->motion_sensitivity->value()));
|
motion_param.Set("sensitivity", static_cast<float>(ui->motion_sensitivity->value()));
|
||||||
} else if (motion_engine == "sdl") {
|
} else if (motion_engine == "sdl") {
|
||||||
@ -363,8 +362,6 @@ void ConfigureMotionTouch::ApplyConfiguration() {
|
|||||||
motion_param.Set("port", port);
|
motion_param.Set("port", port);
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::ParamPackage touch_param{};
|
|
||||||
touch_param.Set("engine", touch_engine);
|
|
||||||
if (touch_engine == "cemuhookudp") {
|
if (touch_engine == "cemuhookudp") {
|
||||||
touch_param.Set("min_x", min_x);
|
touch_param.Set("min_x", min_x);
|
||||||
touch_param.Set("min_y", min_y);
|
touch_param.Set("min_y", min_y);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/udp/udp.h"
|
#include "input_common/udp/udp.h"
|
||||||
|
|
||||||
@ -26,11 +26,11 @@ class CalibrationConfigurationDialog : public QDialog {
|
|||||||
public:
|
public:
|
||||||
explicit CalibrationConfigurationDialog(QWidget* parent, const std::string& host, u16 port,
|
explicit CalibrationConfigurationDialog(QWidget* parent, const std::string& host, u16 port,
|
||||||
u8 pad_index, u16 client_id);
|
u8 pad_index, u16 client_id);
|
||||||
~CalibrationConfigurationDialog() override;
|
~CalibrationConfigurationDialog();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_INVOKABLE void UpdateLabelText(const QString& text);
|
Q_INVOKABLE void UpdateLabelText(QString text);
|
||||||
Q_INVOKABLE void UpdateButtonText(const QString& text);
|
Q_INVOKABLE void UpdateButtonText(QString text);
|
||||||
|
|
||||||
QVBoxLayout* layout;
|
QVBoxLayout* layout;
|
||||||
QLabel* status_label;
|
QLabel* status_label;
|
||||||
@ -39,10 +39,7 @@ private:
|
|||||||
|
|
||||||
// Configuration results
|
// Configuration results
|
||||||
bool completed{};
|
bool completed{};
|
||||||
u16 min_x{};
|
u16 min_x, min_y, max_x, max_y;
|
||||||
u16 min_y{};
|
|
||||||
u16 max_x{};
|
|
||||||
u16 max_y{};
|
|
||||||
|
|
||||||
friend class ConfigureMotionTouch;
|
friend class ConfigureMotionTouch;
|
||||||
};
|
};
|
||||||
@ -84,10 +81,7 @@ private:
|
|||||||
std::optional<std::function<void(const Common::ParamPackage&)>> input_setter;
|
std::optional<std::function<void(const Common::ParamPackage&)>> input_setter;
|
||||||
|
|
||||||
// Coordinate system of the CemuhookUDP touch provider
|
// Coordinate system of the CemuhookUDP touch provider
|
||||||
int min_x{};
|
int min_x, min_y, max_x, max_y;
|
||||||
int min_y{};
|
|
||||||
int max_x{};
|
|
||||||
int max_y{};
|
|
||||||
|
|
||||||
bool udp_test_in_progress{};
|
bool udp_test_in_progress{};
|
||||||
|
|
||||||
|
@ -1,149 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QString>
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include "citra_qt/configuration/config.h"
|
|
||||||
#include "citra_qt/configuration/configure_audio.h"
|
|
||||||
#include "citra_qt/configuration/configure_general.h"
|
|
||||||
#include "citra_qt/configuration/configure_graphics.h"
|
|
||||||
#include "citra_qt/configuration/configure_per_game.h"
|
|
||||||
#include "citra_qt/configuration/configure_system.h"
|
|
||||||
#include "citra_qt/util/util.h"
|
|
||||||
#include "common/file_util.h"
|
|
||||||
#include "core/core.h"
|
|
||||||
#include "core/loader/loader.h"
|
|
||||||
#include "core/loader/smdh.h"
|
|
||||||
#include "ui_configure_per_game.h"
|
|
||||||
|
|
||||||
ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString& file_name,
|
|
||||||
Core::System& system_)
|
|
||||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()),
|
|
||||||
filename{file_name.toStdString()}, title_id{title_id_}, system{system_} {
|
|
||||||
const auto config_file_name = title_id == 0 ? filename : fmt::format("{:016X}", title_id);
|
|
||||||
game_config = std::make_unique<Config>(config_file_name, Config::ConfigType::PerGameConfig);
|
|
||||||
|
|
||||||
audio_tab = std::make_unique<ConfigureAudio>(this);
|
|
||||||
general_tab = std::make_unique<ConfigureGeneral>(this);
|
|
||||||
graphics_tab = std::make_unique<ConfigureGraphics>(this);
|
|
||||||
system_tab = std::make_unique<ConfigureSystem>(this);
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
|
||||||
|
|
||||||
ui->tabWidget->addTab(general_tab.get(), tr("General"));
|
|
||||||
ui->tabWidget->addTab(system_tab.get(), tr("System"));
|
|
||||||
ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
|
|
||||||
ui->tabWidget->addTab(audio_tab.get(), tr("Audio"));
|
|
||||||
|
|
||||||
setFocusPolicy(Qt::ClickFocus);
|
|
||||||
setWindowTitle(tr("Properties"));
|
|
||||||
// remove Help question mark button from the title bar
|
|
||||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
|
||||||
|
|
||||||
scene = new QGraphicsScene;
|
|
||||||
ui->icon_view->setScene(scene);
|
|
||||||
|
|
||||||
if (system.IsPoweredOn()) {
|
|
||||||
QPushButton* apply_button = ui->buttonBox->addButton(QDialogButtonBox::Apply);
|
|
||||||
connect(apply_button, &QAbstractButton::clicked, this,
|
|
||||||
&ConfigurePerGame::HandleApplyButtonClicked);
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(ui->button_reset_per_game, &QPushButton::clicked, this,
|
|
||||||
&ConfigurePerGame::ResetDefaults);
|
|
||||||
|
|
||||||
LoadConfiguration();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigurePerGame::~ConfigurePerGame() = default;
|
|
||||||
|
|
||||||
void ConfigurePerGame::ResetDefaults() {
|
|
||||||
const auto config_file_name = title_id == 0 ? filename : fmt::format("{:016X}", title_id);
|
|
||||||
QMessageBox::StandardButton answer = QMessageBox::question(
|
|
||||||
this, tr("Citra"), tr("Are you sure you want to <b>reset your settings for this game</b>?"),
|
|
||||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
|
||||||
|
|
||||||
if (answer == QMessageBox::No) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileUtil::Delete(fmt::format("{}/custom/{}.ini",
|
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir),
|
|
||||||
config_file_name));
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurePerGame::ApplyConfiguration() {
|
|
||||||
general_tab->ApplyConfiguration();
|
|
||||||
system_tab->ApplyConfiguration();
|
|
||||||
graphics_tab->ApplyConfiguration();
|
|
||||||
audio_tab->ApplyConfiguration();
|
|
||||||
|
|
||||||
Settings::LogSettings();
|
|
||||||
|
|
||||||
game_config->Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurePerGame::changeEvent(QEvent* event) {
|
|
||||||
if (event->type() == QEvent::LanguageChange) {
|
|
||||||
RetranslateUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
QDialog::changeEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurePerGame::RetranslateUI() {
|
|
||||||
ui->retranslateUi(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurePerGame::HandleApplyButtonClicked() {
|
|
||||||
ApplyConfiguration();
|
|
||||||
}
|
|
||||||
|
|
||||||
static QPixmap GetQPixmapFromSMDH(std::vector<u8>& smdh_data) {
|
|
||||||
Loader::SMDH smdh;
|
|
||||||
memcpy(&smdh, smdh_data.data(), sizeof(Loader::SMDH));
|
|
||||||
|
|
||||||
bool large = true;
|
|
||||||
std::vector<u16> icon_data = smdh.GetIcon(large);
|
|
||||||
const uchar* data = reinterpret_cast<const uchar*>(icon_data.data());
|
|
||||||
int size = large ? 48 : 24;
|
|
||||||
QImage icon(data, size, size, QImage::Format::Format_RGB16);
|
|
||||||
return QPixmap::fromImage(icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurePerGame::LoadConfiguration() {
|
|
||||||
if (filename.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->display_title_id->setText(
|
|
||||||
QStringLiteral("%1").arg(title_id, 16, 16, QLatin1Char{'0'}).toUpper());
|
|
||||||
|
|
||||||
const auto loader = Loader::GetLoader(filename);
|
|
||||||
|
|
||||||
std::string title;
|
|
||||||
if (loader->ReadTitle(title) == Loader::ResultStatus::Success)
|
|
||||||
ui->display_name->setText(QString::fromStdString(title));
|
|
||||||
|
|
||||||
std::vector<u8> bytes;
|
|
||||||
if (loader->ReadIcon(bytes) == Loader::ResultStatus::Success) {
|
|
||||||
scene->clear();
|
|
||||||
|
|
||||||
QPixmap map = GetQPixmapFromSMDH(bytes);
|
|
||||||
scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(),
|
|
||||||
Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->display_filepath->setText(QString::fromStdString(filename));
|
|
||||||
|
|
||||||
ui->display_format->setText(
|
|
||||||
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())));
|
|
||||||
|
|
||||||
const auto valueText = ReadableByteSize(FileUtil::GetSize(filename));
|
|
||||||
ui->display_size->setText(valueText);
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QList>
|
|
||||||
#include "citra_qt/configuration/config.h"
|
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConfigureAudio;
|
|
||||||
class ConfigureGeneral;
|
|
||||||
class ConfigureGraphics;
|
|
||||||
class ConfigureSystem;
|
|
||||||
|
|
||||||
class QGraphicsScene;
|
|
||||||
class QStandardItem;
|
|
||||||
class QStandardItemModel;
|
|
||||||
class QTreeView;
|
|
||||||
class QVBoxLayout;
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class ConfigurePerGame;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConfigurePerGame : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Cannot use std::filesystem::path due to https://bugreports.qt.io/browse/QTBUG-73263
|
|
||||||
explicit ConfigurePerGame(QWidget* parent, u64 title_id_, const QString& file_name,
|
|
||||||
Core::System& system_);
|
|
||||||
~ConfigurePerGame() override;
|
|
||||||
|
|
||||||
/// Loads all button configurations to settings file
|
|
||||||
void LoadConfiguration();
|
|
||||||
|
|
||||||
/// Save all button configurations to settings file
|
|
||||||
void ApplyConfiguration();
|
|
||||||
|
|
||||||
/// Reset the settings for this game
|
|
||||||
void ResetDefaults();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void changeEvent(QEvent* event) override;
|
|
||||||
void RetranslateUI();
|
|
||||||
|
|
||||||
void HandleApplyButtonClicked();
|
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigurePerGame> ui;
|
|
||||||
std::string filename;
|
|
||||||
u64 title_id;
|
|
||||||
|
|
||||||
QGraphicsScene* scene;
|
|
||||||
|
|
||||||
std::unique_ptr<Config> game_config;
|
|
||||||
|
|
||||||
Core::System& system;
|
|
||||||
|
|
||||||
std::unique_ptr<ConfigureAudio> audio_tab;
|
|
||||||
std::unique_ptr<ConfigureGeneral> general_tab;
|
|
||||||
std::unique_ptr<ConfigureGraphics> graphics_tab;
|
|
||||||
std::unique_ptr<ConfigureSystem> system_tab;
|
|
||||||
};
|
|
@ -1,271 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>ConfigurePerGame</class>
|
|
||||||
<widget class="QDialog" name="ConfigurePerGame">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>900</width>
|
|
||||||
<height>661</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>900</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Dialog</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Info</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QGraphicsView" name="icon_view">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>128</width>
|
|
||||||
<height>128</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>128</width>
|
|
||||||
<height>128</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="verticalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="interactive">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>Size</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QLineEdit" name="display_filepath">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>160</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>Format</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Name</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QLineEdit" name="display_size">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="label_7">
|
|
||||||
<property name="text">
|
|
||||||
<string>Filepath</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Title ID</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLineEdit" name="display_title_id">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="display_name">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QLineEdit" name="display_format">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="button_reset_per_game">
|
|
||||||
<property name="text">
|
|
||||||
<string>Reset Game Settings</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="VerticalLayout">
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>-1</number>
|
|
||||||
</property>
|
|
||||||
<property name="usesScrollButtons">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="documentMode">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="tabsClosable">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>ConfigurePerGame</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>20</x>
|
|
||||||
<y>20</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>20</x>
|
|
||||||
<y>20</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>ConfigurePerGame</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>20</x>
|
|
||||||
<y>20</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>20</x>
|
|
||||||
<y>20</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
@ -6,8 +6,8 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include "citra_qt/configuration/configure_storage.h"
|
#include "citra_qt/configuration/configure_storage.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "ui_configure_storage.h"
|
#include "ui_configure_storage.h"
|
||||||
|
|
||||||
ConfigureStorage::ConfigureStorage(QWidget* parent)
|
ConfigureStorage::ConfigureStorage(QWidget* parent)
|
||||||
@ -16,33 +16,33 @@ ConfigureStorage::ConfigureStorage(QWidget* parent)
|
|||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
connect(ui->open_nand_dir, &QPushButton::clicked, []() {
|
connect(ui->open_nand_dir, &QPushButton::clicked, []() {
|
||||||
QString path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
|
QString path = QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir));
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->change_nand_dir, &QPushButton::clicked, this, [this]() {
|
connect(ui->change_nand_dir, &QPushButton::clicked, this, [this]() {
|
||||||
const QString dir_path = QFileDialog::getExistingDirectory(
|
const QString dir_path = QFileDialog::getExistingDirectory(
|
||||||
this, tr("Select NAND Directory"),
|
this, tr("Select NAND Directory"),
|
||||||
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)),
|
QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir)),
|
||||||
QFileDialog::ShowDirsOnly);
|
QFileDialog::ShowDirsOnly);
|
||||||
if (!dir_path.isEmpty()) {
|
if (!dir_path.isEmpty()) {
|
||||||
FileUtil::UpdateUserPath(FileUtil::UserPath::NANDDir, dir_path.toStdString());
|
Common::FS::UpdateUserPath(Common::FS::UserPath::NANDDir, dir_path.toStdString());
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->open_sdmc_dir, &QPushButton::clicked, []() {
|
connect(ui->open_sdmc_dir, &QPushButton::clicked, []() {
|
||||||
QString path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir));
|
QString path = QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir));
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->change_sdmc_dir, &QPushButton::clicked, this, [this]() {
|
connect(ui->change_sdmc_dir, &QPushButton::clicked, this, [this]() {
|
||||||
const QString dir_path = QFileDialog::getExistingDirectory(
|
const QString dir_path = QFileDialog::getExistingDirectory(
|
||||||
this, tr("Select SDMC Directory"),
|
this, tr("Select SDMC Directory"),
|
||||||
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)),
|
QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir)),
|
||||||
QFileDialog::ShowDirsOnly);
|
QFileDialog::ShowDirsOnly);
|
||||||
if (!dir_path.isEmpty()) {
|
if (!dir_path.isEmpty()) {
|
||||||
FileUtil::UpdateUserPath(FileUtil::UserPath::SDMCDir, dir_path.toStdString());
|
Common::FS::UpdateUserPath(Common::FS::UserPath::SDMCDir, dir_path.toStdString());
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -60,19 +60,19 @@ ConfigureStorage::ConfigureStorage(QWidget* parent)
|
|||||||
ConfigureStorage::~ConfigureStorage() = default;
|
ConfigureStorage::~ConfigureStorage() = default;
|
||||||
|
|
||||||
void ConfigureStorage::SetConfiguration() {
|
void ConfigureStorage::SetConfiguration() {
|
||||||
ui->nand_group->setVisible(Settings::values.use_custom_storage.GetValue());
|
ui->nand_group->setVisible(Settings::values.use_custom_storage);
|
||||||
QString nand_path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
|
QString nand_path = QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir));
|
||||||
ui->nand_dir_path->setText(nand_path);
|
ui->nand_dir_path->setText(nand_path);
|
||||||
ui->open_nand_dir->setEnabled(!nand_path.isEmpty());
|
ui->open_nand_dir->setEnabled(!nand_path.isEmpty());
|
||||||
|
|
||||||
ui->sdmc_group->setVisible(Settings::values.use_virtual_sd &&
|
ui->sdmc_group->setVisible(Settings::values.use_virtual_sd &&
|
||||||
Settings::values.use_custom_storage);
|
Settings::values.use_custom_storage);
|
||||||
QString sdmc_path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir));
|
QString sdmc_path = QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir));
|
||||||
ui->sdmc_dir_path->setText(sdmc_path);
|
ui->sdmc_dir_path->setText(sdmc_path);
|
||||||
ui->open_sdmc_dir->setEnabled(!sdmc_path.isEmpty());
|
ui->open_sdmc_dir->setEnabled(!sdmc_path.isEmpty());
|
||||||
|
|
||||||
ui->toggle_virtual_sd->setChecked(Settings::values.use_virtual_sd.GetValue());
|
ui->toggle_virtual_sd->setChecked(Settings::values.use_virtual_sd);
|
||||||
ui->toggle_custom_storage->setChecked(Settings::values.use_custom_storage.GetValue());
|
ui->toggle_custom_storage->setChecked(Settings::values.use_custom_storage);
|
||||||
|
|
||||||
ui->storage_group->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
ui->storage_group->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
||||||
}
|
}
|
||||||
@ -82,10 +82,10 @@ void ConfigureStorage::ApplyConfiguration() {
|
|||||||
Settings::values.use_custom_storage = ui->toggle_custom_storage->isChecked();
|
Settings::values.use_custom_storage = ui->toggle_custom_storage->isChecked();
|
||||||
|
|
||||||
if (!Settings::values.use_custom_storage) {
|
if (!Settings::values.use_custom_storage) {
|
||||||
FileUtil::UpdateUserPath(FileUtil::UserPath::NANDDir,
|
Common::FS::UpdateUserPath(Common::FS::UserPath::NANDDir,
|
||||||
GetDefaultUserPath(FileUtil::UserPath::NANDDir));
|
GetDefaultUserPath(Common::FS::UserPath::NANDDir));
|
||||||
FileUtil::UpdateUserPath(FileUtil::UserPath::SDMCDir,
|
Common::FS::UpdateUserPath(Common::FS::UserPath::SDMCDir,
|
||||||
GetDefaultUserPath(FileUtil::UserPath::SDMCDir));
|
GetDefaultUserPath(Common::FS::UserPath::SDMCDir));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include "citra_qt/configuration/configuration_shared.h"
|
|
||||||
#include "citra_qt/configuration/configure_system.h"
|
#include "citra_qt/configuration/configure_system.h"
|
||||||
#include "common/settings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/service/cfg/cfg.h"
|
#include "core/hle/service/cfg/cfg.h"
|
||||||
#include "core/hle/service/ptm/ptm.h"
|
#include "core/hle/service/ptm/ptm.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "ui_configure_system.h"
|
#include "ui_configure_system.h"
|
||||||
|
|
||||||
static const std::array<int, 12> days_in_month = {{
|
static const std::array<int, 12> days_in_month = {{
|
||||||
@ -249,14 +249,10 @@ ConfigureSystem::ConfigureSystem(QWidget* parent)
|
|||||||
// This scales across DPIs. (This value should be enough for "xxx%")
|
// This scales across DPIs. (This value should be enough for "xxx%")
|
||||||
ui->clock_display_label->setMinimumWidth(40);
|
ui->clock_display_label->setMinimumWidth(40);
|
||||||
|
|
||||||
connect(ui->slider_clock_speed, &QSlider::valueChanged, this, [&](int value) {
|
connect(ui->slider_clock_speed, &QSlider::valueChanged, [&](int value) {
|
||||||
ui->clock_display_label->setText(QStringLiteral("%1%").arg(SliderToSettings(value)));
|
ui->clock_display_label->setText(QStringLiteral("%1%").arg(SliderToSettings(value)));
|
||||||
});
|
});
|
||||||
|
|
||||||
ui->clock_speed_label->setVisible(Settings::IsConfiguringGlobal());
|
|
||||||
ui->clock_speed_combo->setVisible(!Settings::IsConfiguringGlobal());
|
|
||||||
|
|
||||||
SetupPerGameUI();
|
|
||||||
ConfigureTime();
|
ConfigureTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,19 +261,11 @@ ConfigureSystem::~ConfigureSystem() = default;
|
|||||||
void ConfigureSystem::SetConfiguration() {
|
void ConfigureSystem::SetConfiguration() {
|
||||||
enabled = !Core::System::GetInstance().IsPoweredOn();
|
enabled = !Core::System::GetInstance().IsPoweredOn();
|
||||||
|
|
||||||
ui->combo_init_clock->setCurrentIndex(static_cast<u8>(Settings::values.init_clock.GetValue()));
|
ui->combo_init_clock->setCurrentIndex(static_cast<u8>(Settings::values.init_clock));
|
||||||
QDateTime date_time;
|
QDateTime date_time;
|
||||||
date_time.setTime_t(Settings::values.init_time.GetValue());
|
date_time.setTime_t(Settings::values.init_time);
|
||||||
ui->edit_init_time->setDateTime(date_time);
|
ui->edit_init_time->setDateTime(date_time);
|
||||||
|
|
||||||
long long init_time_offset = Settings::values.init_time_offset.GetValue();
|
|
||||||
long long days_offset = init_time_offset / 86400;
|
|
||||||
ui->edit_init_time_offset_days->setValue(days_offset);
|
|
||||||
|
|
||||||
unsigned long long time_offset = std::abs(init_time_offset) - std::abs(days_offset * 86400);
|
|
||||||
QTime time = QTime::fromMSecsSinceStartOfDay(time_offset * 1000);
|
|
||||||
ui->edit_init_time_offset_time->setTime(time);
|
|
||||||
|
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
cfg = Service::CFG::GetModule(Core::System::GetInstance());
|
cfg = Service::CFG::GetModule(Core::System::GetInstance());
|
||||||
ASSERT_MSG(cfg, "CFG Module missing!");
|
ASSERT_MSG(cfg, "CFG Module missing!");
|
||||||
@ -291,31 +279,20 @@ void ConfigureSystem::SetConfiguration() {
|
|||||||
ui->label_disable_info->hide();
|
ui->label_disable_info->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Settings::IsConfiguringGlobal()) {
|
ui->slider_clock_speed->setValue(SettingsToSlider(Settings::values.cpu_clock_percentage));
|
||||||
if (Settings::values.cpu_clock_percentage.UsingGlobal()) {
|
|
||||||
ui->clock_speed_combo->setCurrentIndex(0);
|
|
||||||
ui->slider_clock_speed->setEnabled(false);
|
|
||||||
} else {
|
|
||||||
ui->clock_speed_combo->setCurrentIndex(1);
|
|
||||||
ui->slider_clock_speed->setEnabled(true);
|
|
||||||
}
|
|
||||||
ConfigurationShared::SetHighlight(ui->clock_speed_widget,
|
|
||||||
!Settings::values.cpu_clock_percentage.UsingGlobal());
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->slider_clock_speed->setValue(
|
|
||||||
SettingsToSlider(Settings::values.cpu_clock_percentage.GetValue()));
|
|
||||||
ui->clock_display_label->setText(
|
ui->clock_display_label->setText(
|
||||||
QStringLiteral("%1%").arg(Settings::values.cpu_clock_percentage.GetValue()));
|
QStringLiteral("%1%").arg(Settings::values.cpu_clock_percentage));
|
||||||
ui->toggle_new_3ds->setChecked(Settings::values.is_new_3ds.GetValue());
|
|
||||||
ui->plugin_loader->setChecked(Settings::values.plugin_loader_enabled.GetValue());
|
ui->toggle_new_3ds->setChecked(Settings::values.is_new_3ds);
|
||||||
ui->allow_plugin_loader->setChecked(Settings::values.allow_plugin_loader.GetValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::ReadSystemSettings() {
|
void ConfigureSystem::ReadSystemSettings() {
|
||||||
// set username
|
// set username
|
||||||
username = cfg->GetUsername();
|
username = cfg->GetUsername();
|
||||||
ui->edit_username->setText(QString::fromStdU16String(username));
|
// TODO(wwylele): Use this when we move to Qt 5.5
|
||||||
|
// ui->edit_username->setText(QString::fromStdU16String(username));
|
||||||
|
ui->edit_username->setText(
|
||||||
|
QString::fromUtf16(reinterpret_cast<const ushort*>(username.data())));
|
||||||
|
|
||||||
// set birthday
|
// set birthday
|
||||||
std::tie(birthmonth, birthday) = cfg->GetBirthday();
|
std::tie(birthmonth, birthday) = cfg->GetBirthday();
|
||||||
@ -352,29 +329,32 @@ void ConfigureSystem::ApplyConfiguration() {
|
|||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
// apply username
|
// apply username
|
||||||
std::u16string new_username = ui->edit_username->text().toStdU16String();
|
// TODO(wwylele): Use this when we move to Qt 5.5
|
||||||
|
// std::u16string new_username = ui->edit_username->text().toStdU16String();
|
||||||
|
std::u16string new_username(
|
||||||
|
reinterpret_cast<const char16_t*>(ui->edit_username->text().utf16()));
|
||||||
if (new_username != username) {
|
if (new_username != username) {
|
||||||
cfg->SetUsername(new_username);
|
cfg->SetUsername(new_username);
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply birthday
|
// apply birthday
|
||||||
s32 new_birthmonth = ui->combo_birthmonth->currentIndex() + 1;
|
int new_birthmonth = ui->combo_birthmonth->currentIndex() + 1;
|
||||||
s32 new_birthday = ui->combo_birthday->currentIndex() + 1;
|
int new_birthday = ui->combo_birthday->currentIndex() + 1;
|
||||||
if (birthmonth != new_birthmonth || birthday != new_birthday) {
|
if (birthmonth != new_birthmonth || birthday != new_birthday) {
|
||||||
cfg->SetBirthday(new_birthmonth, new_birthday);
|
cfg->SetBirthday(new_birthmonth, new_birthday);
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply language
|
// apply language
|
||||||
s32 new_language = ui->combo_language->currentIndex();
|
int new_language = ui->combo_language->currentIndex();
|
||||||
if (language_index != new_language) {
|
if (language_index != new_language) {
|
||||||
cfg->SetSystemLanguage(static_cast<Service::CFG::SystemLanguage>(new_language));
|
cfg->SetSystemLanguage(static_cast<Service::CFG::SystemLanguage>(new_language));
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply sound
|
// apply sound
|
||||||
s32 new_sound = ui->combo_sound->currentIndex();
|
int new_sound = ui->combo_sound->currentIndex();
|
||||||
if (sound_index != new_sound) {
|
if (sound_index != new_sound) {
|
||||||
cfg->SetSoundOutputMode(static_cast<Service::CFG::SoundOutputMode>(new_sound));
|
cfg->SetSoundOutputMode(static_cast<Service::CFG::SoundOutputMode>(new_sound));
|
||||||
modified = true;
|
modified = true;
|
||||||
@ -398,30 +378,15 @@ void ConfigureSystem::ApplyConfiguration() {
|
|||||||
cfg->UpdateConfigNANDSavegame();
|
cfg->UpdateConfigNANDSavegame();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.is_new_3ds, ui->toggle_new_3ds,
|
|
||||||
is_new_3ds);
|
|
||||||
|
|
||||||
Settings::values.init_clock =
|
Settings::values.init_clock =
|
||||||
static_cast<Settings::InitClock>(ui->combo_init_clock->currentIndex());
|
static_cast<Settings::InitClock>(ui->combo_init_clock->currentIndex());
|
||||||
Settings::values.init_time = ui->edit_init_time->dateTime().toTime_t();
|
Settings::values.init_time = ui->edit_init_time->dateTime().toTime_t();
|
||||||
|
|
||||||
s64 time_offset_time = ui->edit_init_time_offset_time->time().msecsSinceStartOfDay() / 1000;
|
|
||||||
s64 time_offset_days = ui->edit_init_time_offset_days->value() * 86400;
|
|
||||||
|
|
||||||
if (time_offset_days < 0) {
|
|
||||||
time_offset_time = -time_offset_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings::values.init_time_offset = time_offset_days + time_offset_time;
|
|
||||||
Settings::values.is_new_3ds = ui->toggle_new_3ds->isChecked();
|
Settings::values.is_new_3ds = ui->toggle_new_3ds->isChecked();
|
||||||
|
|
||||||
Settings::values.plugin_loader_enabled.SetValue(ui->plugin_loader->isChecked());
|
|
||||||
Settings::values.allow_plugin_loader.SetValue(ui->allow_plugin_loader->isChecked());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(
|
Settings::values.cpu_clock_percentage = SliderToSettings(ui->slider_clock_speed->value());
|
||||||
&Settings::values.cpu_clock_percentage, ui->clock_speed_combo,
|
Settings::Apply();
|
||||||
[this](s32) { return SliderToSettings(ui->slider_clock_speed->value()); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
|
void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
|
||||||
@ -429,10 +394,10 @@ void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// store current day selection
|
// store current day selection
|
||||||
s32 birthday_index = ui->combo_birthday->currentIndex();
|
int birthday_index = ui->combo_birthday->currentIndex();
|
||||||
|
|
||||||
// get number of days in the new selected month
|
// get number of days in the new selected month
|
||||||
s32 days = days_in_month[birthmonth_index];
|
int days = days_in_month[birthmonth_index];
|
||||||
|
|
||||||
// if the selected day is out of range,
|
// if the selected day is out of range,
|
||||||
// reset it to 1st
|
// reset it to 1st
|
||||||
@ -441,7 +406,7 @@ void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
|
|||||||
|
|
||||||
// update the day combo box
|
// update the day combo box
|
||||||
ui->combo_birthday->clear();
|
ui->combo_birthday->clear();
|
||||||
for (s32 i = 1; i <= days; ++i) {
|
for (int i = 1; i <= days; ++i) {
|
||||||
ui->combo_birthday->addItem(QString::number(i));
|
ui->combo_birthday->addItem(QString::number(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,10 +415,10 @@ void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::ConfigureTime() {
|
void ConfigureSystem::ConfigureTime() {
|
||||||
|
ui->edit_init_time->setCalendarPopup(true);
|
||||||
QDateTime dt;
|
QDateTime dt;
|
||||||
dt.fromString(QStringLiteral("2000-01-01 00:00:01"), QStringLiteral("yyyy-MM-dd hh:mm:ss"));
|
dt.fromString(QStringLiteral("2000-01-01 00:00:01"), QStringLiteral("yyyy-MM-dd hh:mm:ss"));
|
||||||
ui->edit_init_time->setMinimumDateTime(dt);
|
ui->edit_init_time->setMinimumDateTime(dt);
|
||||||
ui->edit_init_time->setCalendarPopup(true);
|
|
||||||
|
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
@ -461,16 +426,10 @@ void ConfigureSystem::ConfigureTime() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::UpdateInitTime(int init_clock) {
|
void ConfigureSystem::UpdateInitTime(int init_clock) {
|
||||||
const bool is_global = Settings::IsConfiguringGlobal();
|
|
||||||
const bool is_fixed_time =
|
const bool is_fixed_time =
|
||||||
static_cast<Settings::InitClock>(init_clock) == Settings::InitClock::FixedTime;
|
static_cast<Settings::InitClock>(init_clock) == Settings::InitClock::FixedTime;
|
||||||
|
ui->label_init_time->setVisible(is_fixed_time);
|
||||||
ui->label_init_time->setVisible(is_fixed_time && is_global);
|
ui->edit_init_time->setVisible(is_fixed_time);
|
||||||
ui->edit_init_time->setVisible(is_fixed_time && is_global);
|
|
||||||
|
|
||||||
ui->label_init_time_offset->setVisible(!is_fixed_time && is_global);
|
|
||||||
ui->edit_init_time_offset_days->setVisible(!is_fixed_time && is_global);
|
|
||||||
ui->edit_init_time_offset_time->setVisible(!is_fixed_time && is_global);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::RefreshConsoleID() {
|
void ConfigureSystem::RefreshConsoleID() {
|
||||||
@ -495,50 +454,3 @@ void ConfigureSystem::RefreshConsoleID() {
|
|||||||
void ConfigureSystem::RetranslateUI() {
|
void ConfigureSystem::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::SetupPerGameUI() {
|
|
||||||
// Block the global settings if a game is currently running that overrides them
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
ui->toggle_new_3ds->setEnabled(Settings::values.is_new_3ds.UsingGlobal());
|
|
||||||
ui->slider_clock_speed->setEnabled(Settings::values.cpu_clock_percentage.UsingGlobal());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide most settings for now, we can implement them later
|
|
||||||
ui->label_username->setVisible(false);
|
|
||||||
ui->label_birthday->setVisible(false);
|
|
||||||
ui->label_init_clock->setVisible(false);
|
|
||||||
ui->label_init_time->setVisible(false);
|
|
||||||
ui->label_console_id->setVisible(false);
|
|
||||||
ui->label_sound->setVisible(false);
|
|
||||||
ui->label_language->setVisible(false);
|
|
||||||
ui->label_country->setVisible(false);
|
|
||||||
ui->label_play_coins->setVisible(false);
|
|
||||||
ui->edit_username->setVisible(false);
|
|
||||||
ui->spinBox_play_coins->setVisible(false);
|
|
||||||
ui->combo_birthday->setVisible(false);
|
|
||||||
ui->combo_birthmonth->setVisible(false);
|
|
||||||
ui->combo_init_clock->setVisible(false);
|
|
||||||
ui->combo_sound->setVisible(false);
|
|
||||||
ui->combo_language->setVisible(false);
|
|
||||||
ui->combo_country->setVisible(false);
|
|
||||||
ui->label_init_time_offset->setVisible(false);
|
|
||||||
ui->edit_init_time_offset_days->setVisible(false);
|
|
||||||
ui->edit_init_time_offset_time->setVisible(false);
|
|
||||||
ui->button_regenerate_console_id->setVisible(false);
|
|
||||||
// Apps can change the state of the plugin loader, so plugins load
|
|
||||||
// to a chainloaded app with specific parameters. Don't allow
|
|
||||||
// the plugin loader state to be configured per-game as it may
|
|
||||||
// mess things up.
|
|
||||||
ui->label_plugin_loader->setVisible(false);
|
|
||||||
ui->plugin_loader->setVisible(false);
|
|
||||||
ui->allow_plugin_loader->setVisible(false);
|
|
||||||
|
|
||||||
connect(ui->clock_speed_combo, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
|
||||||
ui->slider_clock_speed->setEnabled(index == 1);
|
|
||||||
ConfigurationShared::SetHighlight(ui->clock_speed_widget, index == 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->toggle_new_3ds, Settings::values.is_new_3ds,
|
|
||||||
is_new_3ds);
|
|
||||||
}
|
|
||||||
|
@ -12,10 +12,6 @@ namespace Ui {
|
|||||||
class ConfigureSystem;
|
class ConfigureSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
|
||||||
enum class CheckState;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Service {
|
namespace Service {
|
||||||
namespace CFG {
|
namespace CFG {
|
||||||
class Module;
|
class Module;
|
||||||
@ -41,9 +37,6 @@ private:
|
|||||||
void UpdateInitTime(int init_clock);
|
void UpdateInitTime(int init_clock);
|
||||||
void RefreshConsoleID();
|
void RefreshConsoleID();
|
||||||
|
|
||||||
void SetupPerGameUI();
|
|
||||||
|
|
||||||
ConfigurationShared::CheckState is_new_3ds;
|
|
||||||
std::unique_ptr<Ui::ConfigureSystem> ui;
|
std::unique_ptr<Ui::ConfigureSystem> ui;
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>525</width>
|
<width>520</width>
|
||||||
<height>619</height>
|
<height>564</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -258,44 +258,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="1">
|
|
||||||
<widget class="QDateTimeEdit" name="edit_init_time">
|
|
||||||
<property name="displayFormat">
|
|
||||||
<string>yyyy-MM-ddTHH:mm:ss</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="0">
|
|
||||||
<widget class="QLabel" name="label_init_time_offset">
|
|
||||||
<property name="text">
|
|
||||||
<string>Offset time</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="1">
|
|
||||||
<layout class="QGridLayout" name="edit_init_time_offset_grid">
|
|
||||||
<item column="0">
|
|
||||||
<widget class="QSpinBox" name="edit_init_time_offset_days">
|
|
||||||
<property name="suffix">
|
|
||||||
<string> days</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>-2147483648</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>2147483647</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item column="1">
|
|
||||||
<widget class="QTimeEdit" name="edit_init_time_offset_time">
|
|
||||||
<property name="displayFormat">
|
|
||||||
<string>HH:mm:ss</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="1">
|
<item row="9" column="1">
|
||||||
<widget class="QSpinBox" name="spinBox_play_coins">
|
<widget class="QSpinBox" name="spinBox_play_coins">
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
@ -333,6 +295,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="8" column="1">
|
||||||
|
<widget class="QDateTimeEdit" name="edit_init_time">
|
||||||
|
<property name="displayFormat">
|
||||||
|
<string>yyyy-MM-ddTHH:mm:ss</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="toggle_new_3ds">
|
<widget class="QCheckBox" name="toggle_new_3ds">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -340,64 +309,23 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="13" column="0">
|
|
||||||
<widget class="QLabel" name="label_plugin_loader">
|
|
||||||
<property name="text">
|
|
||||||
<string>3GX Plugin Loader:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="13" column="1">
|
|
||||||
<widget class="QCheckBox" name="plugin_loader">
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable 3GX plugin loader</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="14" column="1">
|
|
||||||
<widget class="QCheckBox" name="allow_plugin_loader">
|
|
||||||
<property name="text">
|
|
||||||
<string>Allow games to change plugin loader state</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="group_advanced">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Advanced</string>
|
<string>Advanced</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QWidget" name="clock_speed_widget" native="true">
|
<widget class="QLabel" name="label_3">
|
||||||
<layout class="QHBoxLayout" name="clock_speed_layout">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>7</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="clock_speed_combo">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use global clock speed</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Set clock speed:</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="clock_speed_label">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>CPU Clock Speed</string>
|
<string>CPU Clock Speed</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="0" column="2">
|
||||||
<widget class="QSlider" name="slider_clock_speed">
|
<widget class="QSlider" name="slider_clock_speed">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><body>Changes the emulated CPU clock frequency.<br>Underclocking can increase performance but may cause the game to freeze.<br>Overclocking may reduce in game lag but also might cause freezes</body></html></string>
|
<string><html><body>Changes the emulated CPU clock frequency.<br>Underclocking can increase performance but may cause the game to freeze.<br>Overclocking may reduce in game lag but also might cause freezes</body></html></string>
|
||||||
@ -425,7 +353,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="clock_display_label">
|
<widget class="QLabel" name="clock_display_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
@ -438,9 +366,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2"/>
|
<layout class="QHBoxLayout" name="horizontalLayout_2"/>
|
||||||
</item>
|
</item>
|
||||||
@ -493,6 +418,7 @@
|
|||||||
<tabstop>edit_init_time</tabstop>
|
<tabstop>edit_init_time</tabstop>
|
||||||
<tabstop>spinBox_play_coins</tabstop>
|
<tabstop>spinBox_play_coins</tabstop>
|
||||||
<tabstop>button_regenerate_console_id</tabstop>
|
<tabstop>button_regenerate_console_id</tabstop>
|
||||||
|
<tabstop>slider_clock_speed</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
@ -73,11 +73,11 @@ ConfigureTouchFromButton::ConfigureTouchFromButton(
|
|||||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigureTouchFromButton>()), touch_maps(touch_maps),
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigureTouchFromButton>()), touch_maps(touch_maps),
|
||||||
selected_index(default_index), timeout_timer(std::make_unique<QTimer>()),
|
selected_index(default_index), timeout_timer(std::make_unique<QTimer>()),
|
||||||
poll_timer(std::make_unique<QTimer>()) {
|
poll_timer(std::make_unique<QTimer>()) {
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
binding_list_model = new QStandardItemModel(0, 3, this);
|
binding_list_model = std::make_unique<QStandardItemModel>(0, 3, this);
|
||||||
binding_list_model->setHorizontalHeaderLabels(
|
binding_list_model->setHorizontalHeaderLabels({tr("Button"), tr("X"), tr("Y")});
|
||||||
{tr("Button"), tr("X", "X axis"), tr("Y", "Y axis")});
|
ui->binding_list->setModel(binding_list_model.get());
|
||||||
ui->binding_list->setModel(binding_list_model);
|
|
||||||
ui->bottom_screen->SetCoordLabel(ui->coord_label);
|
ui->bottom_screen->SetCoordLabel(ui->coord_label);
|
||||||
|
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
@ -93,13 +93,12 @@ void ConfigureTouchFromButton::showEvent(QShowEvent* ev) {
|
|||||||
// width values are not valid in the constructor
|
// width values are not valid in the constructor
|
||||||
const int w =
|
const int w =
|
||||||
ui->binding_list->viewport()->contentsRect().width() / binding_list_model->columnCount();
|
ui->binding_list->viewport()->contentsRect().width() / binding_list_model->columnCount();
|
||||||
if (w <= 0) {
|
if (w > 0) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
ui->binding_list->setColumnWidth(0, w);
|
ui->binding_list->setColumnWidth(0, w);
|
||||||
ui->binding_list->setColumnWidth(1, w);
|
ui->binding_list->setColumnWidth(1, w);
|
||||||
ui->binding_list->setColumnWidth(2, w);
|
ui->binding_list->setColumnWidth(2, w);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ConfigureTouchFromButton::SetConfiguration() {
|
void ConfigureTouchFromButton::SetConfiguration() {
|
||||||
for (const auto& touch_map : touch_maps) {
|
for (const auto& touch_map : touch_maps) {
|
||||||
@ -124,7 +123,7 @@ void ConfigureTouchFromButton::UpdateUiDisplay() {
|
|||||||
QStandardItem* ycoord = new QStandardItem(QString::number(package.Get("y", 0)));
|
QStandardItem* ycoord = new QStandardItem(QString::number(package.Get("y", 0)));
|
||||||
binding_list_model->appendRow({button, xcoord, ycoord});
|
binding_list_model->appendRow({button, xcoord, ycoord});
|
||||||
|
|
||||||
const int dot = ui->bottom_screen->AddDot(package.Get("x", 0), package.Get("y", 0));
|
int dot = ui->bottom_screen->AddDot(package.Get("x", 0), package.Get("y", 0));
|
||||||
button->setData(dot, DataRoleDot);
|
button->setData(dot, DataRoleDot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,7 +145,7 @@ void ConfigureTouchFromButton::ConnectEvents() {
|
|||||||
&ConfigureTouchFromButton::EditBinding);
|
&ConfigureTouchFromButton::EditBinding);
|
||||||
connect(ui->binding_list->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
connect(ui->binding_list->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||||
&ConfigureTouchFromButton::OnBindingSelection);
|
&ConfigureTouchFromButton::OnBindingSelection);
|
||||||
connect(binding_list_model, &QStandardItemModel::itemChanged, this,
|
connect(binding_list_model.get(), &QStandardItemModel::itemChanged, this,
|
||||||
&ConfigureTouchFromButton::OnBindingChanged);
|
&ConfigureTouchFromButton::OnBindingChanged);
|
||||||
connect(ui->binding_list->model(), &QStandardItemModel::rowsAboutToBeRemoved, this,
|
connect(ui->binding_list->model(), &QStandardItemModel::rowsAboutToBeRemoved, this,
|
||||||
&ConfigureTouchFromButton::OnBindingDeleted);
|
&ConfigureTouchFromButton::OnBindingDeleted);
|
||||||
@ -233,7 +232,7 @@ void ConfigureTouchFromButton::GetButtonInput(const int row_index, const bool is
|
|||||||
|
|
||||||
input_setter = [this, row_index, is_new](const Common::ParamPackage& params,
|
input_setter = [this, row_index, is_new](const Common::ParamPackage& params,
|
||||||
const bool cancel) {
|
const bool cancel) {
|
||||||
auto* cell = binding_list_model->item(row_index, 0);
|
auto cell = binding_list_model->item(row_index, 0);
|
||||||
if (cancel) {
|
if (cancel) {
|
||||||
if (is_new) {
|
if (is_new) {
|
||||||
binding_list_model->removeRow(row_index);
|
binding_list_model->removeRow(row_index);
|
||||||
@ -261,15 +260,15 @@ void ConfigureTouchFromButton::GetButtonInput(const int row_index, const bool is
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureTouchFromButton::NewBinding(const QPoint& pos) {
|
void ConfigureTouchFromButton::NewBinding(const QPoint& pos) {
|
||||||
auto* button = new QStandardItem();
|
QStandardItem* button = new QStandardItem();
|
||||||
button->setEditable(false);
|
button->setEditable(false);
|
||||||
auto* x_coord = new QStandardItem(QString::number(pos.x()));
|
QStandardItem* xcoord = new QStandardItem(QString::number(pos.x()));
|
||||||
auto* y_coord = new QStandardItem(QString::number(pos.y()));
|
QStandardItem* ycoord = new QStandardItem(QString::number(pos.y()));
|
||||||
|
|
||||||
const int dot_id = ui->bottom_screen->AddDot(pos.x(), pos.y());
|
const int dot_id = ui->bottom_screen->AddDot(pos.x(), pos.y());
|
||||||
button->setData(dot_id, DataRoleDot);
|
button->setData(dot_id, DataRoleDot);
|
||||||
|
|
||||||
binding_list_model->appendRow({button, x_coord, y_coord});
|
binding_list_model->appendRow({button, xcoord, ycoord});
|
||||||
ui->binding_list->setFocus();
|
ui->binding_list->setFocus();
|
||||||
ui->binding_list->setCurrentIndex(button->index());
|
ui->binding_list->setCurrentIndex(button->index());
|
||||||
|
|
||||||
@ -284,12 +283,12 @@ void ConfigureTouchFromButton::EditBinding(const QModelIndex& qi) {
|
|||||||
|
|
||||||
void ConfigureTouchFromButton::DeleteBinding() {
|
void ConfigureTouchFromButton::DeleteBinding() {
|
||||||
const int row_index = ui->binding_list->currentIndex().row();
|
const int row_index = ui->binding_list->currentIndex().row();
|
||||||
if (row_index < 0) {
|
if (row_index >= 0) {
|
||||||
return;
|
ui->bottom_screen->RemoveDot(
|
||||||
}
|
binding_list_model->index(row_index, 0).data(DataRoleDot).toInt());
|
||||||
ui->bottom_screen->RemoveDot(binding_list_model->index(row_index, 0).data(DataRoleDot).toInt());
|
|
||||||
binding_list_model->removeRow(row_index);
|
binding_list_model->removeRow(row_index);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ConfigureTouchFromButton::OnBindingSelection(const QItemSelection& selected,
|
void ConfigureTouchFromButton::OnBindingSelection(const QItemSelection& selected,
|
||||||
const QItemSelection& deselected) {
|
const QItemSelection& deselected) {
|
||||||
@ -330,7 +329,7 @@ void ConfigureTouchFromButton::OnBindingChanged(QStandardItem* item) {
|
|||||||
void ConfigureTouchFromButton::OnBindingDeleted([[maybe_unused]] const QModelIndex& parent,
|
void ConfigureTouchFromButton::OnBindingDeleted([[maybe_unused]] const QModelIndex& parent,
|
||||||
int first, int last) {
|
int first, int last) {
|
||||||
for (int i = first; i <= last; ++i) {
|
for (int i = first; i <= last; ++i) {
|
||||||
const auto ix = binding_list_model->index(i, 0);
|
auto ix = binding_list_model->index(i, 0);
|
||||||
if (!ix.isValid()) {
|
if (!ix.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -423,7 +422,7 @@ int TouchScreenPreview::AddDot(const int device_x, const int device_y) {
|
|||||||
dot_font.setStyleHint(QFont::Monospace);
|
dot_font.setStyleHint(QFont::Monospace);
|
||||||
dot_font.setPointSize(20);
|
dot_font.setPointSize(20);
|
||||||
|
|
||||||
auto* dot = new QLabel(this);
|
QLabel* dot = new QLabel(this);
|
||||||
dot->setAttribute(Qt::WA_TranslucentBackground);
|
dot->setAttribute(Qt::WA_TranslucentBackground);
|
||||||
dot->setFont(dot_font);
|
dot->setFont(dot_font);
|
||||||
dot->setText(QChar(0xD7)); // U+00D7 Multiplication Sign
|
dot->setText(QChar(0xD7)); // U+00D7 Multiplication Sign
|
||||||
@ -441,14 +440,13 @@ int TouchScreenPreview::AddDot(const int device_x, const int device_y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TouchScreenPreview::RemoveDot(const int id) {
|
void TouchScreenPreview::RemoveDot(const int id) {
|
||||||
const auto iter = std::find_if(dots.begin(), dots.end(),
|
for (auto dot_it = dots.begin(); dot_it != dots.end(); ++dot_it) {
|
||||||
[id](const auto& entry) { return entry.first == id; });
|
if (dot_it->first == id) {
|
||||||
if (iter == dots.cend()) {
|
dot_it->second->deleteLater();
|
||||||
|
dots.erase(dot_it);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
iter->second->deleteLater();
|
|
||||||
dots.erase(iter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchScreenPreview::HighlightDot(const int id, const bool active) const {
|
void TouchScreenPreview::HighlightDot(const int id, const bool active) const {
|
||||||
@ -472,15 +470,14 @@ void TouchScreenPreview::HighlightDot(const int id, const bool active) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TouchScreenPreview::MoveDot(const int id, const int device_x, const int device_y) const {
|
void TouchScreenPreview::MoveDot(const int id, const int device_x, const int device_y) const {
|
||||||
const auto iter = std::find_if(dots.begin(), dots.end(),
|
for (const auto& dot : dots) {
|
||||||
[id](const auto& entry) { return entry.first == id; });
|
if (dot.first == id) {
|
||||||
if (iter == dots.cend()) {
|
dot.second->setProperty(PropX, device_x);
|
||||||
|
dot.second->setProperty(PropY, device_y);
|
||||||
|
PositionDot(dot.second, device_x, device_y);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
iter->second->setProperty(PropX, device_x);
|
|
||||||
iter->second->setProperty(PropY, device_y);
|
|
||||||
PositionDot(iter->second, device_x, device_y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchScreenPreview::resizeEvent(QResizeEvent* event) {
|
void TouchScreenPreview::resizeEvent(QResizeEvent* event) {
|
||||||
@ -524,14 +521,13 @@ void TouchScreenPreview::leaveEvent([[maybe_unused]] QEvent* event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TouchScreenPreview::mousePressEvent(QMouseEvent* event) {
|
void TouchScreenPreview::mousePressEvent(QMouseEvent* event) {
|
||||||
if (event->button() != Qt::MouseButton::LeftButton) {
|
if (event->button() == Qt::MouseButton::LeftButton) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto pos = MapToDeviceCoords(event->x(), event->y());
|
const auto pos = MapToDeviceCoords(event->x(), event->y());
|
||||||
if (pos) {
|
if (pos) {
|
||||||
emit DotAdded(*pos);
|
emit DotAdded(*pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool TouchScreenPreview::eventFilter(QObject* obj, QEvent* event) {
|
bool TouchScreenPreview::eventFilter(QObject* obj, QEvent* event) {
|
||||||
switch (event->type()) {
|
switch (event->type()) {
|
||||||
@ -604,17 +600,12 @@ std::optional<QPoint> TouchScreenPreview::MapToDeviceCoords(const int screen_x,
|
|||||||
|
|
||||||
void TouchScreenPreview::PositionDot(QLabel* const dot, const int device_x,
|
void TouchScreenPreview::PositionDot(QLabel* const dot, const int device_x,
|
||||||
const int device_y) const {
|
const int device_y) const {
|
||||||
const float device_coord_x =
|
dot->move(static_cast<int>(
|
||||||
static_cast<float>(device_x >= 0 ? device_x : dot->property(PropX).toInt());
|
static_cast<float>(device_x >= 0 ? device_x : dot->property(PropX).toInt()) *
|
||||||
const int x_coord = static_cast<int>(
|
(contentsRect().width() - 1) / (Core::kScreenBottomWidth - 1) +
|
||||||
device_coord_x * (contentsRect().width() - 1) / (Core::kScreenBottomWidth - 1) +
|
contentsMargins().left() - static_cast<float>(dot->width()) / 2 + 0.5f),
|
||||||
contentsMargins().left() - static_cast<float>(dot->width()) / 2 + 0.5f);
|
static_cast<int>(
|
||||||
|
static_cast<float>(device_y >= 0 ? device_y : dot->property(PropY).toInt()) *
|
||||||
const float device_coord_y =
|
(contentsRect().height() - 1) / (Core::kScreenBottomHeight - 1) +
|
||||||
static_cast<float>(device_y >= 0 ? device_y : dot->property(PropY).toInt());
|
contentsMargins().top() - static_cast<float>(dot->height()) / 2 + 0.5f));
|
||||||
const int y_coord = static_cast<int>(
|
|
||||||
device_coord_y * (contentsRect().height() - 1) / (Core::kScreenBottomHeight - 1) +
|
|
||||||
contentsMargins().top() - static_cast<float>(dot->height()) / 2 + 0.5f);
|
|
||||||
|
|
||||||
dot->move(x_coord, y_coord);
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
|
|
||||||
class QItemSelection;
|
class QItemSelection;
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
@ -50,8 +50,8 @@ public slots:
|
|||||||
void SetCoordinates(int dot_id, const QPoint& pos);
|
void SetCoordinates(int dot_id, const QPoint& pos);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void showEvent(QShowEvent* ev) override;
|
virtual void showEvent(QShowEvent* ev) override;
|
||||||
void keyPressEvent(QKeyEvent* event) override;
|
virtual void keyPressEvent(QKeyEvent* event) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void NewMapping();
|
void NewMapping();
|
||||||
@ -72,7 +72,7 @@ private:
|
|||||||
void SaveCurrentMapping();
|
void SaveCurrentMapping();
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureTouchFromButton> ui;
|
std::unique_ptr<Ui::ConfigureTouchFromButton> ui;
|
||||||
QStandardItemModel* binding_list_model;
|
std::unique_ptr<QStandardItemModel> binding_list_model;
|
||||||
std::vector<Settings::TouchFromButtonMap> touch_maps;
|
std::vector<Settings::TouchFromButtonMap> touch_maps;
|
||||||
int selected_index;
|
int selected_index;
|
||||||
|
|
||||||
|
@ -33,11 +33,11 @@ signals:
|
|||||||
void DotMoved(int dot_id, const QPoint& pos);
|
void DotMoved(int dot_id, const QPoint& pos);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent*) override;
|
virtual void resizeEvent(QResizeEvent*) override;
|
||||||
void mouseMoveEvent(QMouseEvent*) override;
|
virtual void mouseMoveEvent(QMouseEvent*) override;
|
||||||
void leaveEvent(QEvent*) override;
|
virtual void leaveEvent(QEvent*) override;
|
||||||
void mousePressEvent(QMouseEvent*) override;
|
virtual void mousePressEvent(QMouseEvent*) override;
|
||||||
bool eventFilter(QObject*, QEvent*) override;
|
virtual bool eventFilter(QObject*, QEvent*) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<QPoint> MapToDeviceCoords(int screen_x, int screen_y) const;
|
std::optional<QPoint> MapToDeviceCoords(int screen_x, int screen_y) const;
|
||||||
@ -53,10 +53,9 @@ private:
|
|||||||
static constexpr char PropX[] = "device_x";
|
static constexpr char PropX[] = "device_x";
|
||||||
static constexpr char PropY[] = "device_y";
|
static constexpr char PropY[] = "device_y";
|
||||||
|
|
||||||
struct DragState {
|
struct {
|
||||||
bool active = false;
|
bool active = false;
|
||||||
QPointer<QLabel> dot;
|
QPointer<QLabel> dot;
|
||||||
QPoint start_pos;
|
QPoint start_pos;
|
||||||
};
|
} drag_state;
|
||||||
DragState drag_state;
|
|
||||||
};
|
};
|
||||||
|
@ -46,14 +46,12 @@ void ConfigureUi::SetConfiguration() {
|
|||||||
ui->language_combobox->setCurrentIndex(
|
ui->language_combobox->setCurrentIndex(
|
||||||
ui->language_combobox->findData(UISettings::values.language));
|
ui->language_combobox->findData(UISettings::values.language));
|
||||||
ui->icon_size_combobox->setCurrentIndex(
|
ui->icon_size_combobox->setCurrentIndex(
|
||||||
static_cast<int>(UISettings::values.game_list_icon_size.GetValue()));
|
static_cast<int>(UISettings::values.game_list_icon_size));
|
||||||
ui->row_1_text_combobox->setCurrentIndex(
|
ui->row_1_text_combobox->setCurrentIndex(static_cast<int>(UISettings::values.game_list_row_1));
|
||||||
static_cast<int>(UISettings::values.game_list_row_1.GetValue()));
|
ui->row_2_text_combobox->setCurrentIndex(static_cast<int>(UISettings::values.game_list_row_2) +
|
||||||
ui->row_2_text_combobox->setCurrentIndex(
|
1);
|
||||||
static_cast<int>(UISettings::values.game_list_row_2.GetValue()) + 1);
|
ui->toggle_hide_no_icon->setChecked(UISettings::values.game_list_hide_no_icon);
|
||||||
ui->toggle_hide_no_icon->setChecked(UISettings::values.game_list_hide_no_icon.GetValue());
|
ui->toggle_single_line_mode->setChecked(UISettings::values.game_list_single_line_mode);
|
||||||
ui->toggle_single_line_mode->setChecked(
|
|
||||||
UISettings::values.game_list_single_line_mode.GetValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureUi::ApplyConfiguration() {
|
void ConfigureUi::ApplyConfiguration() {
|
||||||
|
@ -87,7 +87,7 @@ void ConfigureWeb::SetConfiguration() {
|
|||||||
tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper()));
|
tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper()));
|
||||||
user_verified = true;
|
user_verified = true;
|
||||||
|
|
||||||
ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence.GetValue());
|
ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureWeb::ApplyConfiguration() {
|
void ConfigureWeb::ApplyConfiguration() {
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
void ToggleConsole() {
|
void ToggleConsole() {
|
||||||
static bool console_shown = false;
|
static bool console_shown = false;
|
||||||
if (console_shown == UISettings::values.show_console.GetValue()) {
|
if (console_shown == UISettings::values.show_console) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
console_shown = UISettings::values.show_console.GetValue();
|
console_shown = UISettings::values.show_console;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -314,31 +314,31 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
|
|||||||
auto GetText = [offset](Format format, const u8* pixel) {
|
auto GetText = [offset](Format format, const u8* pixel) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case Format::RGBA8: {
|
case Format::RGBA8: {
|
||||||
auto value = Common::Color::DecodeRGBA8(pixel) / 255.0f;
|
auto value = Color::DecodeRGBA8(pixel) / 255.0f;
|
||||||
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||||
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
|
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
|
||||||
}
|
}
|
||||||
case Format::RGB8: {
|
case Format::RGB8: {
|
||||||
auto value = Common::Color::DecodeRGB8(pixel) / 255.0f;
|
auto value = Color::DecodeRGB8(pixel) / 255.0f;
|
||||||
return QStringLiteral("Red: %1, Green: %2, Blue: %3")
|
return QStringLiteral("Red: %1, Green: %2, Blue: %3")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||||
QString::number(value.b(), 'f', 2));
|
QString::number(value.b(), 'f', 2));
|
||||||
}
|
}
|
||||||
case Format::RGB5A1: {
|
case Format::RGB5A1: {
|
||||||
auto value = Common::Color::DecodeRGB5A1(pixel) / 255.0f;
|
auto value = Color::DecodeRGB5A1(pixel) / 255.0f;
|
||||||
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||||
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
|
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
|
||||||
}
|
}
|
||||||
case Format::RGB565: {
|
case Format::RGB565: {
|
||||||
auto value = Common::Color::DecodeRGB565(pixel) / 255.0f;
|
auto value = Color::DecodeRGB565(pixel) / 255.0f;
|
||||||
return QStringLiteral("Red: %1, Green: %2, Blue: %3")
|
return QStringLiteral("Red: %1, Green: %2, Blue: %3")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||||
QString::number(value.b(), 'f', 2));
|
QString::number(value.b(), 'f', 2));
|
||||||
}
|
}
|
||||||
case Format::RGBA4: {
|
case Format::RGBA4: {
|
||||||
auto value = Common::Color::DecodeRGBA4(pixel) / 255.0f;
|
auto value = Color::DecodeRGBA4(pixel) / 255.0f;
|
||||||
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||||
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
|
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
|
||||||
@ -346,7 +346,7 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
|
|||||||
case Format::IA8:
|
case Format::IA8:
|
||||||
return QStringLiteral("Index: %1, Alpha: %2").arg(pixel[0], pixel[1]);
|
return QStringLiteral("Index: %1, Alpha: %2").arg(pixel[0], pixel[1]);
|
||||||
case Format::RG8: {
|
case Format::RG8: {
|
||||||
auto value = Common::Color::DecodeRG8(pixel) / 255.0f;
|
auto value = Color::DecodeRG8(pixel) / 255.0f;
|
||||||
return QStringLiteral("Red: %1, Green: %2")
|
return QStringLiteral("Red: %1, Green: %2")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2));
|
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2));
|
||||||
}
|
}
|
||||||
@ -369,17 +369,17 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
|
|||||||
// TODO: Display block information or channel values?
|
// TODO: Display block information or channel values?
|
||||||
return QStringLiteral("Compressed data");
|
return QStringLiteral("Compressed data");
|
||||||
case Format::D16: {
|
case Format::D16: {
|
||||||
auto value = Common::Color::DecodeD16(pixel);
|
auto value = Color::DecodeD16(pixel);
|
||||||
return QStringLiteral("Depth: %1").arg(QString::number(value / (float)0xFFFF, 'f', 4));
|
return QStringLiteral("Depth: %1").arg(QString::number(value / (float)0xFFFF, 'f', 4));
|
||||||
}
|
}
|
||||||
case Format::D24: {
|
case Format::D24: {
|
||||||
auto value = Common::Color::DecodeD24(pixel);
|
auto value = Color::DecodeD24(pixel);
|
||||||
return QStringLiteral("Depth: %1")
|
return QStringLiteral("Depth: %1")
|
||||||
.arg(QString::number(value / (float)0xFFFFFF, 'f', 4));
|
.arg(QString::number(value / (float)0xFFFFFF, 'f', 4));
|
||||||
}
|
}
|
||||||
case Format::D24X8:
|
case Format::D24X8:
|
||||||
case Format::X24S8: {
|
case Format::X24S8: {
|
||||||
auto values = Common::Color::DecodeD24S8(pixel);
|
auto values = Color::DecodeD24S8(pixel);
|
||||||
return QStringLiteral("Depth: %1, Stencil: %2")
|
return QStringLiteral("Depth: %1, Stencil: %2")
|
||||||
.arg(QString::number(values[0] / (float)0xFFFFFF, 'f', 4), values[1]);
|
.arg(QString::number(values[0] / (float)0xFFFFFF, 'f', 4), values[1]);
|
||||||
}
|
}
|
||||||
@ -603,27 +603,27 @@ void GraphicsSurfaceWidget::OnUpdate() {
|
|||||||
|
|
||||||
switch (surface_format) {
|
switch (surface_format) {
|
||||||
case Format::D16: {
|
case Format::D16: {
|
||||||
u32 data = Common::Color::DecodeD16(pixel);
|
u32 data = Color::DecodeD16(pixel);
|
||||||
color.r() = data & 0xFF;
|
color.r() = data & 0xFF;
|
||||||
color.g() = (data >> 8) & 0xFF;
|
color.g() = (data >> 8) & 0xFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Format::D24: {
|
case Format::D24: {
|
||||||
u32 data = Common::Color::DecodeD24(pixel);
|
u32 data = Color::DecodeD24(pixel);
|
||||||
color.r() = data & 0xFF;
|
color.r() = data & 0xFF;
|
||||||
color.g() = (data >> 8) & 0xFF;
|
color.g() = (data >> 8) & 0xFF;
|
||||||
color.b() = (data >> 16) & 0xFF;
|
color.b() = (data >> 16) & 0xFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Format::D24X8: {
|
case Format::D24X8: {
|
||||||
Common::Vec2<u32> data = Common::Color::DecodeD24S8(pixel);
|
Common::Vec2<u32> data = Color::DecodeD24S8(pixel);
|
||||||
color.r() = data.x & 0xFF;
|
color.r() = data.x & 0xFF;
|
||||||
color.g() = (data.x >> 8) & 0xFF;
|
color.g() = (data.x >> 8) & 0xFF;
|
||||||
color.b() = (data.x >> 16) & 0xFF;
|
color.b() = (data.x >> 16) & 0xFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Format::X24S8: {
|
case Format::X24S8: {
|
||||||
Common::Vec2<u32> data = Common::Color::DecodeD24S8(pixel);
|
Common::Vec2<u32> data = Color::DecodeD24S8(pixel);
|
||||||
color.r() = color.g() = color.b() = data.y;
|
color.r() = color.g() = color.b() = data.y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include "citra_qt/debugger/lle_service_modules.h"
|
#include "citra_qt/debugger/lle_service_modules.h"
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
|
|
||||||
LLEServiceModulesWidget::LLEServiceModulesWidget(QWidget* parent)
|
LLEServiceModulesWidget::LLEServiceModulesWidget(QWidget* parent)
|
||||||
: QDockWidget(tr("Toggle LLE Service Modules"), parent) {
|
: QDockWidget(tr("Toggle LLE Service Modules"), parent) {
|
||||||
|
@ -7,13 +7,13 @@
|
|||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "citra_qt/util/util.h"
|
#include "citra_qt/util/util.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
#include "core/hle/kernel/mutex.h"
|
#include "core/hle/kernel/mutex.h"
|
||||||
#include "core/hle/kernel/semaphore.h"
|
#include "core/hle/kernel/semaphore.h"
|
||||||
#include "core/hle/kernel/thread.h"
|
#include "core/hle/kernel/thread.h"
|
||||||
#include "core/hle/kernel/timer.h"
|
#include "core/hle/kernel/timer.h"
|
||||||
#include "core/hle/kernel/wait_object.h"
|
#include "core/hle/kernel/wait_object.h"
|
||||||
|
#include "core/settings.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "citra_qt/dumping/dumping_dialog.h"
|
#include "citra_qt/dumping/dumping_dialog.h"
|
||||||
#include "citra_qt/dumping/options_dialog.h"
|
#include "citra_qt/dumping/options_dialog.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "common/settings.h"
|
#include "core/settings.h"
|
||||||
#include "ui_dumping_dialog.h"
|
#include "ui_dumping_dialog.h"
|
||||||
|
|
||||||
DumpingDialog::DumpingDialog(QWidget* parent)
|
DumpingDialog::DumpingDialog(QWidget* parent)
|
||||||
|
@ -29,10 +29,10 @@
|
|||||||
#include "citra_qt/main.h"
|
#include "citra_qt/main.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/file_sys/archive_extsavedata.h"
|
#include "core/file_sys/archive_extsavedata.h"
|
||||||
#include "core/file_sys/archive_source_sd_savedata.h"
|
#include "core/file_sys/archive_source_sd_savedata.h"
|
||||||
#include "core/hle/service/fs/archive.h"
|
#include "core/hle/service/fs/archive.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "qcursor.h"
|
#include "qcursor.h"
|
||||||
|
|
||||||
GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist, QObject* parent)
|
GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist, QObject* parent)
|
||||||
@ -469,16 +469,6 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
|
|||||||
context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location));
|
context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForEachOpenGLCacheFile(u64 program_id, auto func) {
|
|
||||||
for (const std::string_view cache_type : {"separable", "conventional"}) {
|
|
||||||
const std::string path = fmt::format("{}opengl/precompiled/{}/{:016X}.bin",
|
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir),
|
|
||||||
cache_type, program_id);
|
|
||||||
QFile file{QString::fromStdString(path)};
|
|
||||||
func(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameList::AddGamePopup(QMenu& context_menu, const QString& path, u64 program_id,
|
void GameList::AddGamePopup(QMenu& context_menu, const QString& path, u64 program_id,
|
||||||
u64 extdata_id) {
|
u64 extdata_id) {
|
||||||
QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
|
QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
|
||||||
@ -489,34 +479,29 @@ void GameList::AddGamePopup(QMenu& context_menu, const QString& path, u64 progra
|
|||||||
QAction* open_texture_load_location =
|
QAction* open_texture_load_location =
|
||||||
context_menu.addAction(tr("Open Custom Texture Location"));
|
context_menu.addAction(tr("Open Custom Texture Location"));
|
||||||
QAction* open_mods_location = context_menu.addAction(tr("Open Mods Location"));
|
QAction* open_mods_location = context_menu.addAction(tr("Open Mods Location"));
|
||||||
QAction* open_dlc_location = context_menu.addAction(tr("Open DLC Data Location"));
|
|
||||||
QMenu* shader_menu = context_menu.addMenu(tr("Disk Shader Cache"));
|
QMenu* shader_menu = context_menu.addMenu(tr("Disk Shader Cache"));
|
||||||
QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS"));
|
QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS"));
|
||||||
QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry"));
|
QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry"));
|
||||||
context_menu.addSeparator();
|
|
||||||
QAction* properties = context_menu.addAction(tr("Properties"));
|
|
||||||
|
|
||||||
QAction* open_shader_cache_location = shader_menu->addAction(tr("Open Shader Cache Location"));
|
QAction* open_shader_cache_location = shader_menu->addAction(tr("Open Shader Cache Location"));
|
||||||
shader_menu->addSeparator();
|
shader_menu->addSeparator();
|
||||||
QAction* delete_opengl_disk_shader_cache =
|
QAction* delete_opengl_disk_shader_cache =
|
||||||
shader_menu->addAction(tr("Delete OpenGL Shader Cache"));
|
shader_menu->addAction(tr("Delete OpenGL Shader Cache"));
|
||||||
|
QAction* delete_vulkan_disk_shader_cache =
|
||||||
|
shader_menu->addAction(tr("Delete Vulkan Shader Cache"));
|
||||||
|
|
||||||
const bool is_application =
|
const bool is_application =
|
||||||
0x0004000000000000 <= program_id && program_id <= 0x00040000FFFFFFFF;
|
0x0004000000000000 <= program_id && program_id <= 0x00040000FFFFFFFF;
|
||||||
|
|
||||||
bool opengl_cache_exists = false;
|
std::string sdmc_dir = Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir);
|
||||||
ForEachOpenGLCacheFile(
|
|
||||||
program_id, [&opengl_cache_exists](QFile& file) { opengl_cache_exists |= file.exists(); });
|
|
||||||
|
|
||||||
std::string sdmc_dir = FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir);
|
|
||||||
open_save_location->setEnabled(
|
open_save_location->setEnabled(
|
||||||
is_application && FileUtil::Exists(FileSys::ArchiveSource_SDSaveData::GetSaveDataPathFor(
|
is_application && Common::FS::Exists(FileSys::ArchiveSource_SDSaveData::GetSaveDataPathFor(
|
||||||
sdmc_dir, program_id)));
|
sdmc_dir, program_id)));
|
||||||
|
|
||||||
if (extdata_id) {
|
if (extdata_id) {
|
||||||
open_extdata_location->setEnabled(
|
open_extdata_location->setEnabled(
|
||||||
is_application &&
|
is_application &&
|
||||||
FileUtil::Exists(FileSys::GetExtDataPathFromId(sdmc_dir, extdata_id)));
|
Common::FS::Exists(FileSys::GetExtDataPathFromId(sdmc_dir, extdata_id)));
|
||||||
} else {
|
} else {
|
||||||
open_extdata_location->setVisible(false);
|
open_extdata_location->setVisible(false);
|
||||||
}
|
}
|
||||||
@ -525,17 +510,15 @@ void GameList::AddGamePopup(QMenu& context_menu, const QString& path, u64 progra
|
|||||||
open_application_location->setEnabled(path.toStdString() ==
|
open_application_location->setEnabled(path.toStdString() ==
|
||||||
Service::AM::GetTitleContentPath(media_type, program_id));
|
Service::AM::GetTitleContentPath(media_type, program_id));
|
||||||
open_update_location->setEnabled(
|
open_update_location->setEnabled(
|
||||||
is_application && FileUtil::Exists(Service::AM::GetTitlePath(Service::FS::MediaType::SDMC,
|
is_application && Common::FS::Exists(Service::AM::GetTitlePath(Service::FS::MediaType::SDMC,
|
||||||
program_id + 0xe00000000) +
|
program_id + 0xe00000000) +
|
||||||
"content/"));
|
"content/"));
|
||||||
auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
||||||
|
|
||||||
open_texture_dump_location->setEnabled(is_application);
|
open_texture_dump_location->setVisible(is_application);
|
||||||
open_texture_load_location->setEnabled(is_application);
|
open_texture_load_location->setVisible(is_application);
|
||||||
open_mods_location->setEnabled(is_application);
|
open_mods_location->setVisible(is_application);
|
||||||
open_dlc_location->setEnabled(is_application);
|
dump_romfs->setVisible(is_application);
|
||||||
dump_romfs->setEnabled(is_application);
|
|
||||||
delete_opengl_disk_shader_cache->setEnabled(opengl_cache_exists);
|
|
||||||
|
|
||||||
navigate_to_gamedb_entry->setVisible(it != compatibility_list.end());
|
navigate_to_gamedb_entry->setVisible(it != compatibility_list.end());
|
||||||
|
|
||||||
@ -552,51 +535,57 @@ void GameList::AddGamePopup(QMenu& context_menu, const QString& path, u64 progra
|
|||||||
emit OpenFolderRequested(program_id, GameListOpenTarget::UPDATE_DATA);
|
emit OpenFolderRequested(program_id, GameListOpenTarget::UPDATE_DATA);
|
||||||
});
|
});
|
||||||
connect(open_texture_dump_location, &QAction::triggered, this, [this, program_id] {
|
connect(open_texture_dump_location, &QAction::triggered, this, [this, program_id] {
|
||||||
if (FileUtil::CreateFullPath(fmt::format("{}textures/{:016X}/",
|
if (Common::FS::CreateFullPath(fmt::format("{}textures/{:016X}/",
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::DumpDir),
|
Common::FS::GetUserPath(Common::FS::UserPath::DumpDir),
|
||||||
program_id))) {
|
program_id))) {
|
||||||
emit OpenFolderRequested(program_id, GameListOpenTarget::TEXTURE_DUMP);
|
emit OpenFolderRequested(program_id, GameListOpenTarget::TEXTURE_DUMP);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(open_texture_load_location, &QAction::triggered, this, [this, program_id] {
|
connect(open_texture_load_location, &QAction::triggered, this, [this, program_id] {
|
||||||
if (FileUtil::CreateFullPath(fmt::format("{}textures/{:016X}/",
|
if (Common::FS::CreateFullPath(fmt::format("{}textures/{:016X}/",
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::LoadDir),
|
Common::FS::GetUserPath(Common::FS::UserPath::LoadDir),
|
||||||
|
program_id))) {
|
||||||
|
emit OpenFolderRequested(program_id, GameListOpenTarget::TEXTURE_LOAD);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(open_texture_load_location, &QAction::triggered, this, [this, program_id] {
|
||||||
|
if (Common::FS::CreateFullPath(fmt::format("{}textures/{:016X}/",
|
||||||
|
Common::FS::GetUserPath(Common::FS::UserPath::LoadDir),
|
||||||
program_id))) {
|
program_id))) {
|
||||||
emit OpenFolderRequested(program_id, GameListOpenTarget::TEXTURE_LOAD);
|
emit OpenFolderRequested(program_id, GameListOpenTarget::TEXTURE_LOAD);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(open_mods_location, &QAction::triggered, this, [this, program_id] {
|
connect(open_mods_location, &QAction::triggered, this, [this, program_id] {
|
||||||
if (FileUtil::CreateFullPath(fmt::format("{}mods/{:016X}/",
|
if (Common::FS::CreateFullPath(fmt::format("{}mods/{:016X}/",
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::LoadDir),
|
Common::FS::GetUserPath(Common::FS::UserPath::LoadDir),
|
||||||
program_id))) {
|
program_id))) {
|
||||||
emit OpenFolderRequested(program_id, GameListOpenTarget::MODS);
|
emit OpenFolderRequested(program_id, GameListOpenTarget::MODS);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(open_dlc_location, &QAction::triggered, this, [this, program_id] {
|
|
||||||
const u64 trimmed_id = program_id & 0xFFFFFFF;
|
|
||||||
const std::string dlc_path =
|
|
||||||
fmt::format("{}Nintendo 3DS/00000000000000000000000000000000/"
|
|
||||||
"00000000000000000000000000000000/title/0004008c/{:08x}/content/",
|
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), trimmed_id);
|
|
||||||
fmt::print("DLC path {}\n", dlc_path);
|
|
||||||
if (FileUtil::CreateFullPath(dlc_path)) {
|
|
||||||
emit OpenFolderRequested(trimmed_id, GameListOpenTarget::DLC_DATA);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(dump_romfs, &QAction::triggered, this,
|
connect(dump_romfs, &QAction::triggered, this,
|
||||||
[this, path, program_id] { emit DumpRomFSRequested(path, program_id); });
|
[this, path, program_id] { emit DumpRomFSRequested(path, program_id); });
|
||||||
connect(navigate_to_gamedb_entry, &QAction::triggered, this, [this, program_id]() {
|
connect(navigate_to_gamedb_entry, &QAction::triggered, this, [this, program_id]() {
|
||||||
emit NavigateToGamedbEntryRequested(program_id, compatibility_list);
|
emit NavigateToGamedbEntryRequested(program_id, compatibility_list);
|
||||||
});
|
});
|
||||||
connect(properties, &QAction::triggered, this,
|
|
||||||
[this, path]() { emit OpenPerGameGeneralRequested(path); });
|
|
||||||
connect(open_shader_cache_location, &QAction::triggered, this, [this, program_id] {
|
connect(open_shader_cache_location, &QAction::triggered, this, [this, program_id] {
|
||||||
if (FileUtil::CreateFullPath(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir))) {
|
if (Common::FS::CreateFullPath(Common::FS::GetUserPath(Common::FS::UserPath::ShaderDir))) {
|
||||||
emit OpenFolderRequested(program_id, GameListOpenTarget::SHADER_CACHE);
|
emit OpenFolderRequested(program_id, GameListOpenTarget::SHADER_CACHE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(delete_opengl_disk_shader_cache, &QAction::triggered, this, [program_id] {
|
connect(delete_opengl_disk_shader_cache, &QAction::triggered, this, [program_id] {
|
||||||
ForEachOpenGLCacheFile(program_id, [](QFile& file) { file.remove(); });
|
const std::string_view cache_type =
|
||||||
|
Settings::values.separable_shader ? "separable" : "conventional";
|
||||||
|
const std::string path = fmt::format("{}opengl/precompiled/{}/{:016X}.bin",
|
||||||
|
Common::FS::GetUserPath(Common::FS::UserPath::ShaderDir),
|
||||||
|
cache_type, program_id);
|
||||||
|
QFile file{QString::fromStdString(path)};
|
||||||
|
file.remove();
|
||||||
|
});
|
||||||
|
connect(delete_vulkan_disk_shader_cache, &QAction::triggered, this, [] {
|
||||||
|
const std::string path =
|
||||||
|
fmt::format("{}vulkan", Common::FS::GetUserPath(Common::FS::UserPath::ShaderDir));
|
||||||
|
QDir dir{QString::fromStdString(path)};
|
||||||
|
dir.removeRecursively();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,8 +37,7 @@ enum class GameListOpenTarget {
|
|||||||
TEXTURE_DUMP = 4,
|
TEXTURE_DUMP = 4,
|
||||||
TEXTURE_LOAD = 5,
|
TEXTURE_LOAD = 5,
|
||||||
MODS = 6,
|
MODS = 6,
|
||||||
DLC_DATA = 7,
|
SHADER_CACHE = 7
|
||||||
SHADER_CACHE = 8
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameList : public QWidget {
|
class GameList : public QWidget {
|
||||||
@ -84,7 +83,6 @@ signals:
|
|||||||
void OpenFolderRequested(u64 program_id, GameListOpenTarget target);
|
void OpenFolderRequested(u64 program_id, GameListOpenTarget target);
|
||||||
void NavigateToGamedbEntryRequested(u64 program_id,
|
void NavigateToGamedbEntryRequested(u64 program_id,
|
||||||
const CompatibilityList& compatibility_list);
|
const CompatibilityList& compatibility_list);
|
||||||
void OpenPerGameGeneralRequested(const QString file);
|
|
||||||
void DumpRomFSRequested(QString game_path, u64 program_id);
|
void DumpRomFSRequested(QString game_path, u64 program_id);
|
||||||
void OpenDirectory(const QString& directory);
|
void OpenDirectory(const QString& directory);
|
||||||
void AddDirectory();
|
void AddDirectory();
|
||||||
|
@ -160,19 +160,17 @@ public:
|
|||||||
setData(qulonglong(program_id), ProgramIdRole);
|
setData(qulonglong(program_id), ProgramIdRole);
|
||||||
setData(qulonglong(extdata_id), ExtdataIdRole);
|
setData(qulonglong(extdata_id), ExtdataIdRole);
|
||||||
|
|
||||||
if (UISettings::values.game_list_icon_size.GetValue() ==
|
if (UISettings::values.game_list_icon_size == UISettings::GameListIconSize::NoIcon) {
|
||||||
UISettings::GameListIconSize::NoIcon) {
|
|
||||||
// Do not display icons
|
// Do not display icons
|
||||||
setData(QPixmap(), Qt::DecorationRole);
|
setData(QPixmap(), Qt::DecorationRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool large = UISettings::values.game_list_icon_size.GetValue() ==
|
bool large =
|
||||||
UISettings::GameListIconSize::LargeIcon;
|
UISettings::values.game_list_icon_size == UISettings::GameListIconSize::LargeIcon;
|
||||||
|
|
||||||
if (!Loader::IsValidSMDH(smdh_data)) {
|
if (!Loader::IsValidSMDH(smdh_data)) {
|
||||||
// SMDH is not valid, set a default icon
|
// SMDH is not valid, set a default icon
|
||||||
if (UISettings::values.game_list_icon_size.GetValue() !=
|
if (UISettings::values.game_list_icon_size != UISettings::GameListIconSize::NoIcon)
|
||||||
UISettings::GameListIconSize::NoIcon)
|
|
||||||
setData(GetDefaultIcon(large), Qt::DecorationRole);
|
setData(GetDefaultIcon(large), Qt::DecorationRole);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -181,8 +179,7 @@ public:
|
|||||||
memcpy(&smdh, smdh_data.data(), sizeof(Loader::SMDH));
|
memcpy(&smdh, smdh_data.data(), sizeof(Loader::SMDH));
|
||||||
|
|
||||||
// Get icon from SMDH
|
// Get icon from SMDH
|
||||||
if (UISettings::values.game_list_icon_size.GetValue() !=
|
if (UISettings::values.game_list_icon_size != UISettings::GameListIconSize::NoIcon) {
|
||||||
UISettings::GameListIconSize::NoIcon) {
|
|
||||||
setData(GetQPixmapFromSMDH(smdh, large), Qt::DecorationRole);
|
setData(GetQPixmapFromSMDH(smdh, large), Qt::DecorationRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,17 +211,16 @@ public:
|
|||||||
QString::fromStdString(fmt::format("{:016X}", data(ProgramIdRole).toULongLong()))},
|
QString::fromStdString(fmt::format("{:016X}", data(ProgramIdRole).toULongLong()))},
|
||||||
};
|
};
|
||||||
|
|
||||||
const QString& row1 =
|
const QString& row1 = display_texts.at(UISettings::values.game_list_row_1).simplified();
|
||||||
display_texts.at(UISettings::values.game_list_row_1.GetValue()).simplified();
|
|
||||||
|
|
||||||
if (role == SortRole)
|
if (role == SortRole)
|
||||||
return row1.toLower();
|
return row1.toLower();
|
||||||
|
|
||||||
QString row2;
|
QString row2;
|
||||||
const auto row_2_id = UISettings::values.game_list_row_2.GetValue();
|
auto row_2_id = UISettings::values.game_list_row_2;
|
||||||
if (row_2_id != UISettings::GameListText::NoText) {
|
if (row_2_id != UISettings::GameListText::NoText) {
|
||||||
if (!row1.isEmpty()) {
|
if (!row1.isEmpty()) {
|
||||||
row2 = UISettings::values.game_list_single_line_mode.GetValue()
|
row2 = UISettings::values.game_list_single_line_mode
|
||||||
? QStringLiteral(" ")
|
? QStringLiteral(" ")
|
||||||
: QStringLiteral("\n ");
|
: QStringLiteral("\n ");
|
||||||
}
|
}
|
||||||
@ -320,12 +316,6 @@ public:
|
|||||||
setData(type(), TypeRole);
|
setData(type(), TypeRole);
|
||||||
setData(size_bytes, SizeRole);
|
setData(size_bytes, SizeRole);
|
||||||
}
|
}
|
||||||
explicit GameListItemSize(const QString& string) {
|
|
||||||
// This is required to avoid incorrect virtual function call in
|
|
||||||
// GameListItem's constructor
|
|
||||||
setText(string);
|
|
||||||
setData(string, SortRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setData(const QVariant& value, int role) override {
|
void setData(const QVariant& value, int role) override {
|
||||||
// By specializing setData for SizeRole, we can ensure that the numerical and string
|
// By specializing setData for SizeRole, we can ensure that the numerical and string
|
||||||
@ -365,7 +355,7 @@ public:
|
|||||||
UISettings::GameDir* game_dir = &directory;
|
UISettings::GameDir* game_dir = &directory;
|
||||||
setData(QVariant(UISettings::values.game_dirs.indexOf(directory)), GameDirRole);
|
setData(QVariant(UISettings::values.game_dirs.indexOf(directory)), GameDirRole);
|
||||||
|
|
||||||
const int icon_size = IconSizes.at(UISettings::values.game_list_icon_size.GetValue());
|
const int icon_size = IconSizes.at(UISettings::values.game_list_icon_size);
|
||||||
switch (dir_type) {
|
switch (dir_type) {
|
||||||
case GameListItemType::InstalledDir:
|
case GameListItemType::InstalledDir:
|
||||||
setData(QIcon::fromTheme(QStringLiteral("sd_card")).pixmap(icon_size),
|
setData(QIcon::fromTheme(QStringLiteral("sd_card")).pixmap(icon_size),
|
||||||
@ -408,7 +398,7 @@ public:
|
|||||||
explicit GameListAddDir() {
|
explicit GameListAddDir() {
|
||||||
setData(type(), TypeRole);
|
setData(type(), TypeRole);
|
||||||
|
|
||||||
int icon_size = IconSizes.at(UISettings::values.game_list_icon_size.GetValue());
|
int icon_size = IconSizes.at(UISettings::values.game_list_icon_size);
|
||||||
setData(QIcon::fromTheme(QStringLiteral("plus")).pixmap(icon_size), Qt::DecorationRole);
|
setData(QIcon::fromTheme(QStringLiteral("plus")).pixmap(icon_size), Qt::DecorationRole);
|
||||||
setData(QObject::tr("Add New Game Directory"), Qt::DisplayRole);
|
setData(QObject::tr("Add New Game Directory"), Qt::DisplayRole);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
|||||||
}
|
}
|
||||||
|
|
||||||
const std::string physical_name = directory + DIR_SEP + virtual_name;
|
const std::string physical_name = directory + DIR_SEP + virtual_name;
|
||||||
const bool is_dir = FileUtil::IsDirectory(physical_name);
|
const bool is_dir = Common::FS::IsDirectory(physical_name);
|
||||||
if (!is_dir && HasSupportedFileExtension(physical_name)) {
|
if (!is_dir && HasSupportedFileExtension(physical_name)) {
|
||||||
std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name);
|
std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name);
|
||||||
if (!loader) {
|
if (!loader) {
|
||||||
@ -67,7 +67,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
|||||||
if (!(program_id & ~0x00040000FFFFFFFF)) {
|
if (!(program_id & ~0x00040000FFFFFFFF)) {
|
||||||
std::string update_path = Service::AM::GetTitleContentPath(
|
std::string update_path = Service::AM::GetTitleContentPath(
|
||||||
Service::FS::MediaType::SDMC, program_id | 0x0000000E00000000);
|
Service::FS::MediaType::SDMC, program_id | 0x0000000E00000000);
|
||||||
if (FileUtil::Exists(update_path)) {
|
if (Common::FS::Exists(update_path)) {
|
||||||
std::unique_ptr<Loader::AppLoader> update_loader =
|
std::unique_ptr<Loader::AppLoader> update_loader =
|
||||||
Loader::GetLoader(update_path);
|
Loader::GetLoader(update_path);
|
||||||
if (update_loader) {
|
if (update_loader) {
|
||||||
@ -101,7 +101,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
|||||||
new GameListItemRegion(smdh),
|
new GameListItemRegion(smdh),
|
||||||
new GameListItem(
|
new GameListItem(
|
||||||
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
|
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
|
||||||
new GameListItemSize(FileUtil::GetSize(physical_name)),
|
new GameListItemSize(Common::FS::GetSize(physical_name)),
|
||||||
},
|
},
|
||||||
parent_dir);
|
parent_dir);
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
FileUtil::ForeachDirectoryEntry(nullptr, dir_path, callback);
|
Common::FS::ForeachDirectoryEntry(nullptr, dir_path, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameListWorker::run() {
|
void GameListWorker::run() {
|
||||||
@ -121,12 +121,12 @@ void GameListWorker::run() {
|
|||||||
for (UISettings::GameDir& game_dir : game_dirs) {
|
for (UISettings::GameDir& game_dir : game_dirs) {
|
||||||
if (game_dir.path == QStringLiteral("INSTALLED")) {
|
if (game_dir.path == QStringLiteral("INSTALLED")) {
|
||||||
QString games_path =
|
QString games_path =
|
||||||
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)) +
|
QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir)) +
|
||||||
QStringLiteral("Nintendo "
|
QStringLiteral("Nintendo "
|
||||||
"3DS/00000000000000000000000000000000/"
|
"3DS/00000000000000000000000000000000/"
|
||||||
"00000000000000000000000000000000/title/00040000");
|
"00000000000000000000000000000000/title/00040000");
|
||||||
QString demos_path =
|
QString demos_path =
|
||||||
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)) +
|
QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir)) +
|
||||||
QStringLiteral(
|
QStringLiteral(
|
||||||
"Nintendo "
|
"Nintendo "
|
||||||
"3DS/00000000000000000000000000000000/00000000000000000000000000000000/title/"
|
"3DS/00000000000000000000000000000000/00000000000000000000000000000000/title/"
|
||||||
@ -139,7 +139,7 @@ void GameListWorker::run() {
|
|||||||
AddFstEntriesToGameList(demos_path.toStdString(), 2, game_list_dir);
|
AddFstEntriesToGameList(demos_path.toStdString(), 2, game_list_dir);
|
||||||
} else if (game_dir.path == QStringLiteral("SYSTEM")) {
|
} else if (game_dir.path == QStringLiteral("SYSTEM")) {
|
||||||
QString path =
|
QString path =
|
||||||
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)) +
|
QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir)) +
|
||||||
QStringLiteral("00000000000000000000000000000000/title/00040010");
|
QStringLiteral("00000000000000000000000000000000/title/00040010");
|
||||||
watch_list.append(path);
|
watch_list.append(path);
|
||||||
auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SystemDir);
|
auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SystemDir);
|
||||||
|
@ -9,19 +9,13 @@
|
|||||||
|
|
||||||
namespace AppleAuthorization {
|
namespace AppleAuthorization {
|
||||||
|
|
||||||
static bool authorized_camera = false;
|
|
||||||
static bool authorized_microphone = false;
|
|
||||||
|
|
||||||
static bool authorized = false;
|
static bool authorized = false;
|
||||||
|
|
||||||
enum class AuthMediaType { Camera, Microphone };
|
enum class AuthMediaType { Camera, Microphone };
|
||||||
|
|
||||||
// Based on
|
// Based on
|
||||||
// https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_macos
|
// https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_macos
|
||||||
// TODO: This could be rewritten to return the authorization state, having pure c++ code deal with
|
|
||||||
// it, log information and possibly wait for the camera access request.
|
|
||||||
void CheckAuthorization(AuthMediaType type) {
|
void CheckAuthorization(AuthMediaType type) {
|
||||||
authorized = false;
|
|
||||||
if (@available(macOS 10.14, *)) {
|
if (@available(macOS 10.14, *)) {
|
||||||
NSString* media_type;
|
NSString* media_type;
|
||||||
if (type == AuthMediaType::Camera) {
|
if (type == AuthMediaType::Camera) {
|
||||||
@ -75,19 +69,13 @@ void CheckAuthorization(AuthMediaType type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CheckAuthorizationForCamera() {
|
bool CheckAuthorizationForCamera() {
|
||||||
if (!authorized_camera) {
|
|
||||||
CheckAuthorization(AuthMediaType::Camera);
|
CheckAuthorization(AuthMediaType::Camera);
|
||||||
authorized_camera = authorized;
|
return authorized;
|
||||||
}
|
|
||||||
return authorized_camera;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckAuthorizationForMicrophone() {
|
bool CheckAuthorizationForMicrophone() {
|
||||||
if (!authorized_microphone) {
|
|
||||||
CheckAuthorization(AuthMediaType::Microphone);
|
CheckAuthorization(AuthMediaType::Microphone);
|
||||||
authorized_microphone = authorized;
|
return authorized;
|
||||||
}
|
|
||||||
return authorized_microphone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // AppleAuthorization
|
} // AppleAuthorization
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
#include <filesystem>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@ -12,7 +11,6 @@
|
|||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QOpenGLFunctions_4_3_Core>
|
|
||||||
#include <QSysInfo>
|
#include <QSysInfo>
|
||||||
#include <QtConcurrent/QtConcurrentRun>
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
@ -29,7 +27,6 @@
|
|||||||
#include "citra_qt/compatibility_list.h"
|
#include "citra_qt/compatibility_list.h"
|
||||||
#include "citra_qt/configuration/config.h"
|
#include "citra_qt/configuration/config.h"
|
||||||
#include "citra_qt/configuration/configure_dialog.h"
|
#include "citra_qt/configuration/configure_dialog.h"
|
||||||
#include "citra_qt/configuration/configure_per_game.h"
|
|
||||||
#include "citra_qt/debugger/console.h"
|
#include "citra_qt/debugger/console.h"
|
||||||
#include "citra_qt/debugger/graphics/graphics.h"
|
#include "citra_qt/debugger/graphics/graphics.h"
|
||||||
#include "citra_qt/debugger/graphics/graphics_breakpoints.h"
|
#include "citra_qt/debugger/graphics/graphics_breakpoints.h"
|
||||||
@ -57,10 +54,8 @@
|
|||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
#include "common/detached_tasks.h"
|
#include "common/detached_tasks.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/literals.h"
|
|
||||||
#include "common/logging/backend.h"
|
#include "common/logging/backend.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/memory_detect.h"
|
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
@ -68,7 +63,6 @@
|
|||||||
#ifdef ARCHITECTURE_x86_64
|
#ifdef ARCHITECTURE_x86_64
|
||||||
#include "common/x64/cpu_detect.h"
|
#include "common/x64/cpu_detect.h"
|
||||||
#endif
|
#endif
|
||||||
#include "common/settings.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/dumping/backend.h"
|
#include "core/dumping/backend.h"
|
||||||
#include "core/file_sys/archive_extsavedata.h"
|
#include "core/file_sys/archive_extsavedata.h"
|
||||||
@ -79,8 +73,7 @@
|
|||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "core/savestate.h"
|
#include "core/savestate.h"
|
||||||
#include "game_list_p.h"
|
#include "core/settings.h"
|
||||||
#include "input_common/main.h"
|
|
||||||
#include "network/network_settings.h"
|
#include "network/network_settings.h"
|
||||||
#include "ui_main.h"
|
#include "ui_main.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
@ -123,13 +116,11 @@ enum class CalloutFlag : uint32_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void GMainWindow::ShowTelemetryCallout() {
|
void GMainWindow::ShowTelemetryCallout() {
|
||||||
if (UISettings::values.callout_flags.GetValue() &
|
if (UISettings::values.callout_flags & static_cast<uint32_t>(CalloutFlag::Telemetry)) {
|
||||||
static_cast<uint32_t>(CalloutFlag::Telemetry)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UISettings::values.callout_flags =
|
UISettings::values.callout_flags |= static_cast<uint32_t>(CalloutFlag::Telemetry);
|
||||||
UISettings::values.callout_flags.GetValue() | static_cast<uint32_t>(CalloutFlag::Telemetry);
|
|
||||||
const QString telemetry_message =
|
const QString telemetry_message =
|
||||||
tr("<a href='https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/'>Anonymous "
|
tr("<a href='https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/'>Anonymous "
|
||||||
"data is collected</a> to help improve Citra. "
|
"data is collected</a> to help improve Citra. "
|
||||||
@ -144,11 +135,11 @@ const int GMainWindow::max_recent_files_item;
|
|||||||
|
|
||||||
static void InitializeLogging() {
|
static void InitializeLogging() {
|
||||||
Log::Filter log_filter;
|
Log::Filter log_filter;
|
||||||
log_filter.ParseFilterString(Settings::values.log_filter.GetValue());
|
log_filter.ParseFilterString(Settings::values.log_filter);
|
||||||
Log::SetGlobalFilter(log_filter);
|
Log::SetGlobalFilter(log_filter);
|
||||||
|
|
||||||
const std::string& log_dir = FileUtil::GetUserPath(FileUtil::UserPath::LogDir);
|
const std::string& log_dir = Common::FS::GetUserPath(Common::FS::UserPath::LogDir);
|
||||||
FileUtil::CreateFullPath(log_dir);
|
Common::FS::CreateFullPath(log_dir);
|
||||||
Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE));
|
Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE));
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
Log::AddBackend(std::make_unique<Log::DebuggerBackend>());
|
Log::AddBackend(std::make_unique<Log::DebuggerBackend>());
|
||||||
@ -176,7 +167,7 @@ GMainWindow::GMainWindow()
|
|||||||
default_theme_paths = QIcon::themeSearchPaths();
|
default_theme_paths = QIcon::themeSearchPaths();
|
||||||
UpdateUITheme();
|
UpdateUITheme();
|
||||||
|
|
||||||
SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue());
|
SetDiscordEnabled(UISettings::values.enable_discord_presence);
|
||||||
discord_rpc->Update();
|
discord_rpc->Update();
|
||||||
|
|
||||||
Network::Init();
|
Network::Init();
|
||||||
@ -217,10 +208,6 @@ GMainWindow::GMainWindow()
|
|||||||
LOG_INFO(Frontend, "Host CPU: {}", cpu_string);
|
LOG_INFO(Frontend, "Host CPU: {}", cpu_string);
|
||||||
#endif
|
#endif
|
||||||
LOG_INFO(Frontend, "Host OS: {}", QSysInfo::prettyProductName().toStdString());
|
LOG_INFO(Frontend, "Host OS: {}", QSysInfo::prettyProductName().toStdString());
|
||||||
const auto& mem_info = Common::GetMemInfo();
|
|
||||||
using namespace Common::Literals;
|
|
||||||
LOG_INFO(Frontend, "Host RAM: {:.2f} GiB", mem_info.total_physical_memory / f64{1_GiB});
|
|
||||||
LOG_INFO(Frontend, "Host Swap: {:.2f} GiB", mem_info.total_swap_memory / f64{1_GiB});
|
|
||||||
UpdateWindowTitle();
|
UpdateWindowTitle();
|
||||||
|
|
||||||
show();
|
show();
|
||||||
@ -258,11 +245,8 @@ void GMainWindow::InitializeWidgets() {
|
|||||||
#ifdef CITRA_ENABLE_COMPATIBILITY_REPORTING
|
#ifdef CITRA_ENABLE_COMPATIBILITY_REPORTING
|
||||||
ui->action_Report_Compatibility->setVisible(true);
|
ui->action_Report_Compatibility->setVisible(true);
|
||||||
#endif
|
#endif
|
||||||
render_window = new GRenderWindow(this, emu_thread.get(), false);
|
render_window = new GRenderWindow(this, emu_thread.get());
|
||||||
secondary_window = new GRenderWindow(this, emu_thread.get(), true);
|
|
||||||
render_window->hide();
|
render_window->hide();
|
||||||
secondary_window->hide();
|
|
||||||
secondary_window->setParent(nullptr);
|
|
||||||
|
|
||||||
game_list = new GameList(this);
|
game_list = new GameList(this);
|
||||||
ui->horizontalLayout->addWidget(game_list);
|
ui->horizontalLayout->addWidget(game_list);
|
||||||
@ -282,7 +266,6 @@ void GMainWindow::InitializeWidgets() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
InputCommon::Init();
|
|
||||||
multiplayer_state = new MultiplayerState(this, game_list->GetModel(), ui->action_Leave_Room,
|
multiplayer_state = new MultiplayerState(this, game_list->GetModel(), ui->action_Leave_Room,
|
||||||
ui->action_Show_Room);
|
ui->action_Show_Room);
|
||||||
multiplayer_state->setVisible(false);
|
multiplayer_state->setVisible(false);
|
||||||
@ -350,7 +333,6 @@ void GMainWindow::InitializeWidgets() {
|
|||||||
actionGroup_ScreenLayouts->addAction(ui->action_Screen_Layout_Single_Screen);
|
actionGroup_ScreenLayouts->addAction(ui->action_Screen_Layout_Single_Screen);
|
||||||
actionGroup_ScreenLayouts->addAction(ui->action_Screen_Layout_Large_Screen);
|
actionGroup_ScreenLayouts->addAction(ui->action_Screen_Layout_Large_Screen);
|
||||||
actionGroup_ScreenLayouts->addAction(ui->action_Screen_Layout_Side_by_Side);
|
actionGroup_ScreenLayouts->addAction(ui->action_Screen_Layout_Side_by_Side);
|
||||||
actionGroup_ScreenLayouts->addAction(ui->action_Screen_Layout_Separate_Windows);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::InitializeDebugWidgets() {
|
void GMainWindow::InitializeDebugWidgets() {
|
||||||
@ -491,9 +473,6 @@ void GMainWindow::InitializeHotkeys() {
|
|||||||
const QString toggle_filter_bar = QStringLiteral("Toggle Filter Bar");
|
const QString toggle_filter_bar = QStringLiteral("Toggle Filter Bar");
|
||||||
const QString toggle_status_bar = QStringLiteral("Toggle Status Bar");
|
const QString toggle_status_bar = QStringLiteral("Toggle Status Bar");
|
||||||
const QString fullscreen = QStringLiteral("Fullscreen");
|
const QString fullscreen = QStringLiteral("Fullscreen");
|
||||||
const QString toggle_screen_layout = QStringLiteral("Toggle Screen Layout");
|
|
||||||
const QString swap_screens = QStringLiteral("Swap Screens");
|
|
||||||
const QString rotate_screens = QStringLiteral("Rotate Screens Upright");
|
|
||||||
|
|
||||||
ui->action_Show_Filter_Bar->setShortcut(
|
ui->action_Show_Filter_Bar->setShortcut(
|
||||||
hotkey_registry.GetKeySequence(main_window, toggle_filter_bar));
|
hotkey_registry.GetKeySequence(main_window, toggle_filter_bar));
|
||||||
@ -531,40 +510,18 @@ void GMainWindow::InitializeHotkeys() {
|
|||||||
return;
|
return;
|
||||||
BootGame(QString(game_path));
|
BootGame(QString(game_path));
|
||||||
});
|
});
|
||||||
connect(hotkey_registry.GetHotkey(main_window, swap_screens, render_window),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Swap Screens"), render_window),
|
||||||
&QShortcut::activated, ui->action_Screen_Layout_Swap_Screens, &QAction::trigger);
|
&QShortcut::activated, ui->action_Screen_Layout_Swap_Screens, &QAction::trigger);
|
||||||
connect(hotkey_registry.GetHotkey(main_window, rotate_screens, render_window),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Rotate Screens Upright"),
|
||||||
|
render_window),
|
||||||
&QShortcut::activated, ui->action_Screen_Layout_Upright_Screens, &QAction::trigger);
|
&QShortcut::activated, ui->action_Screen_Layout_Upright_Screens, &QAction::trigger);
|
||||||
connect(hotkey_registry.GetHotkey(main_window, toggle_screen_layout, render_window),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Screen Layout"),
|
||||||
|
render_window),
|
||||||
&QShortcut::activated, this, &GMainWindow::ToggleScreenLayout);
|
&QShortcut::activated, this, &GMainWindow::ToggleScreenLayout);
|
||||||
connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window),
|
connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window),
|
||||||
&QShortcut::activated, ui->action_Fullscreen, &QAction::trigger);
|
&QShortcut::activated, ui->action_Fullscreen, &QAction::trigger);
|
||||||
connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window),
|
connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window),
|
||||||
&QShortcut::activatedAmbiguously, ui->action_Fullscreen, &QAction::trigger);
|
&QShortcut::activatedAmbiguously, ui->action_Fullscreen, &QAction::trigger);
|
||||||
|
|
||||||
const auto add_secondary_window_hotkey = [this](QKeySequence hotkey, const char* slot) {
|
|
||||||
// This action will fire specifically when secondary_window is in focus
|
|
||||||
QAction* secondary_window_action = new QAction(secondary_window);
|
|
||||||
secondary_window_action->setShortcut(hotkey);
|
|
||||||
|
|
||||||
connect(secondary_window_action, SIGNAL(triggered()), this, slot);
|
|
||||||
secondary_window->addAction(secondary_window_action);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use the same fullscreen hotkey as the main window
|
|
||||||
const auto fullscreen_hotkey = hotkey_registry.GetKeySequence(main_window, fullscreen);
|
|
||||||
add_secondary_window_hotkey(fullscreen_hotkey, SLOT(ToggleSecondaryFullscreen()));
|
|
||||||
|
|
||||||
const auto toggle_screen_hotkey =
|
|
||||||
hotkey_registry.GetKeySequence(main_window, toggle_screen_layout);
|
|
||||||
add_secondary_window_hotkey(toggle_screen_hotkey, SLOT(ToggleScreenLayout()));
|
|
||||||
|
|
||||||
const auto swap_screen_hotkey = hotkey_registry.GetKeySequence(main_window, swap_screens);
|
|
||||||
add_secondary_window_hotkey(swap_screen_hotkey, SLOT(TriggerSwapScreens()));
|
|
||||||
|
|
||||||
const auto rotate_screen_hotkey = hotkey_registry.GetKeySequence(main_window, rotate_screens);
|
|
||||||
add_secondary_window_hotkey(rotate_screen_hotkey, SLOT(TriggerRotateScreens()));
|
|
||||||
|
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Exit Fullscreen"), this),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Exit Fullscreen"), this),
|
||||||
&QShortcut::activated, this, [&] {
|
&QShortcut::activated, this, [&] {
|
||||||
if (emulation_running) {
|
if (emulation_running) {
|
||||||
@ -574,7 +531,8 @@ void GMainWindow::InitializeHotkeys() {
|
|||||||
});
|
});
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Alternate Speed"), this),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Alternate Speed"), this),
|
||||||
&QShortcut::activated, this, [&] {
|
&QShortcut::activated, this, [&] {
|
||||||
Settings::values.frame_limit.SetGlobal(!Settings::values.frame_limit.UsingGlobal());
|
Settings::values.use_frame_limit_alternate =
|
||||||
|
!Settings::values.use_frame_limit_alternate;
|
||||||
UpdateStatusBar();
|
UpdateStatusBar();
|
||||||
});
|
});
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Texture Dumping"), this),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Texture Dumping"), this),
|
||||||
@ -585,26 +543,43 @@ void GMainWindow::InitializeHotkeys() {
|
|||||||
static constexpr u16 SPEED_LIMIT_STEP = 5;
|
static constexpr u16 SPEED_LIMIT_STEP = 5;
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this),
|
||||||
&QShortcut::activated, this, [&] {
|
&QShortcut::activated, this, [&] {
|
||||||
if (Settings::values.frame_limit.GetValue() == 0) {
|
if (Settings::values.use_frame_limit_alternate) {
|
||||||
|
if (Settings::values.frame_limit_alternate == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Settings::values.frame_limit.GetValue() < 995 - SPEED_LIMIT_STEP) {
|
if (Settings::values.frame_limit_alternate < 995 - SPEED_LIMIT_STEP) {
|
||||||
Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() +
|
Settings::values.frame_limit_alternate += SPEED_LIMIT_STEP;
|
||||||
SPEED_LIMIT_STEP);
|
} else {
|
||||||
|
Settings::values.frame_limit_alternate = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Settings::values.frame_limit == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Settings::values.frame_limit < 995 - SPEED_LIMIT_STEP) {
|
||||||
|
Settings::values.frame_limit += SPEED_LIMIT_STEP;
|
||||||
} else {
|
} else {
|
||||||
Settings::values.frame_limit = 0;
|
Settings::values.frame_limit = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
UpdateStatusBar();
|
UpdateStatusBar();
|
||||||
});
|
});
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this),
|
||||||
&QShortcut::activated, this, [&] {
|
&QShortcut::activated, this, [&] {
|
||||||
if (Settings::values.frame_limit.GetValue() == 0) {
|
if (Settings::values.use_frame_limit_alternate) {
|
||||||
|
if (Settings::values.frame_limit_alternate == 0) {
|
||||||
|
Settings::values.frame_limit_alternate = 995;
|
||||||
|
} else if (Settings::values.frame_limit_alternate > SPEED_LIMIT_STEP) {
|
||||||
|
Settings::values.frame_limit_alternate -= SPEED_LIMIT_STEP;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Settings::values.frame_limit == 0) {
|
||||||
Settings::values.frame_limit = 995;
|
Settings::values.frame_limit = 995;
|
||||||
} else if (Settings::values.frame_limit.GetValue() > SPEED_LIMIT_STEP) {
|
} else if (Settings::values.frame_limit > SPEED_LIMIT_STEP) {
|
||||||
Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() -
|
Settings::values.frame_limit -= SPEED_LIMIT_STEP;
|
||||||
SPEED_LIMIT_STEP);
|
|
||||||
UpdateStatusBar();
|
UpdateStatusBar();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
UpdateStatusBar();
|
UpdateStatusBar();
|
||||||
});
|
});
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Frame Advancing"), this),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Frame Advancing"), this),
|
||||||
@ -633,9 +608,6 @@ void GMainWindow::InitializeHotkeys() {
|
|||||||
&QShortcut::activated, ui->action_Load_from_Newest_Slot, &QAction::trigger);
|
&QShortcut::activated, ui->action_Load_from_Newest_Slot, &QAction::trigger);
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Save to Oldest Slot"), this),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Save to Oldest Slot"), this),
|
||||||
&QShortcut::activated, ui->action_Save_to_Oldest_Slot, &QAction::trigger);
|
&QShortcut::activated, ui->action_Save_to_Oldest_Slot, &QAction::trigger);
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this),
|
|
||||||
&QShortcut::activated, this,
|
|
||||||
[] { Settings::values.audio_muted = !Settings::values.audio_muted; });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::ShowUpdaterWidgets() {
|
void GMainWindow::ShowUpdaterWidgets() {
|
||||||
@ -663,26 +635,25 @@ void GMainWindow::RestoreUIState() {
|
|||||||
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
|
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
|
||||||
#if MICROPROFILE_ENABLED
|
#if MICROPROFILE_ENABLED
|
||||||
microProfileDialog->restoreGeometry(UISettings::values.microprofile_geometry);
|
microProfileDialog->restoreGeometry(UISettings::values.microprofile_geometry);
|
||||||
microProfileDialog->setVisible(UISettings::values.microprofile_visible.GetValue());
|
microProfileDialog->setVisible(UISettings::values.microprofile_visible);
|
||||||
#endif
|
#endif
|
||||||
ui->action_Cheats->setEnabled(false);
|
ui->action_Cheats->setEnabled(false);
|
||||||
|
|
||||||
game_list->LoadInterfaceLayout();
|
game_list->LoadInterfaceLayout();
|
||||||
|
|
||||||
ui->action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode.GetValue());
|
ui->action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode);
|
||||||
ToggleWindowMode();
|
ToggleWindowMode();
|
||||||
|
|
||||||
ui->action_Fullscreen->setChecked(UISettings::values.fullscreen.GetValue());
|
ui->action_Fullscreen->setChecked(UISettings::values.fullscreen);
|
||||||
SyncMenuUISettings();
|
SyncMenuUISettings();
|
||||||
|
|
||||||
ui->action_Display_Dock_Widget_Headers->setChecked(
|
ui->action_Display_Dock_Widget_Headers->setChecked(UISettings::values.display_titlebar);
|
||||||
UISettings::values.display_titlebar.GetValue());
|
|
||||||
OnDisplayTitleBars(ui->action_Display_Dock_Widget_Headers->isChecked());
|
OnDisplayTitleBars(ui->action_Display_Dock_Widget_Headers->isChecked());
|
||||||
|
|
||||||
ui->action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar.GetValue());
|
ui->action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar);
|
||||||
game_list->SetFilterVisible(ui->action_Show_Filter_Bar->isChecked());
|
game_list->SetFilterVisible(ui->action_Show_Filter_Bar->isChecked());
|
||||||
|
|
||||||
ui->action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar.GetValue());
|
ui->action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar);
|
||||||
statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked());
|
statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -718,17 +689,10 @@ void GMainWindow::ConnectWidgetEvents() {
|
|||||||
connect(game_list, &GameList::PopulatingCompleted, this,
|
connect(game_list, &GameList::PopulatingCompleted, this,
|
||||||
[this] { multiplayer_state->UpdateGameList(game_list->GetModel()); });
|
[this] { multiplayer_state->UpdateGameList(game_list->GetModel()); });
|
||||||
|
|
||||||
connect(game_list, &GameList::OpenPerGameGeneralRequested, this,
|
|
||||||
&GMainWindow::OnGameListOpenPerGameProperties);
|
|
||||||
|
|
||||||
connect(this, &GMainWindow::EmulationStarting, render_window,
|
connect(this, &GMainWindow::EmulationStarting, render_window,
|
||||||
&GRenderWindow::OnEmulationStarting);
|
&GRenderWindow::OnEmulationStarting);
|
||||||
connect(this, &GMainWindow::EmulationStopping, render_window,
|
connect(this, &GMainWindow::EmulationStopping, render_window,
|
||||||
&GRenderWindow::OnEmulationStopping);
|
&GRenderWindow::OnEmulationStopping);
|
||||||
connect(this, &GMainWindow::EmulationStarting, secondary_window,
|
|
||||||
&GRenderWindow::OnEmulationStarting);
|
|
||||||
connect(this, &GMainWindow::EmulationStopping, secondary_window,
|
|
||||||
&GRenderWindow::OnEmulationStopping);
|
|
||||||
|
|
||||||
connect(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar);
|
connect(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar);
|
||||||
|
|
||||||
@ -756,8 +720,6 @@ void GMainWindow::ConnectMenuEvents() {
|
|||||||
connect(ui->action_Report_Compatibility, &QAction::triggered, this,
|
connect(ui->action_Report_Compatibility, &QAction::triggered, this,
|
||||||
&GMainWindow::OnMenuReportCompatibility);
|
&GMainWindow::OnMenuReportCompatibility);
|
||||||
connect(ui->action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure);
|
connect(ui->action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure);
|
||||||
connect(ui->action_Configure_Current_Game, &QAction::triggered, this,
|
|
||||||
&GMainWindow::OnConfigurePerGame);
|
|
||||||
connect(ui->action_Cheats, &QAction::triggered, this, &GMainWindow::OnCheats);
|
connect(ui->action_Cheats, &QAction::triggered, this, &GMainWindow::OnCheats);
|
||||||
|
|
||||||
// View
|
// View
|
||||||
@ -804,8 +766,6 @@ void GMainWindow::ConnectMenuEvents() {
|
|||||||
&GMainWindow::ChangeScreenLayout);
|
&GMainWindow::ChangeScreenLayout);
|
||||||
connect(ui->action_Screen_Layout_Side_by_Side, &QAction::triggered, this,
|
connect(ui->action_Screen_Layout_Side_by_Side, &QAction::triggered, this,
|
||||||
&GMainWindow::ChangeScreenLayout);
|
&GMainWindow::ChangeScreenLayout);
|
||||||
connect(ui->action_Screen_Layout_Separate_Windows, &QAction::triggered, this,
|
|
||||||
&GMainWindow::ChangeScreenLayout);
|
|
||||||
connect(ui->action_Screen_Layout_Swap_Screens, &QAction::triggered, this,
|
connect(ui->action_Screen_Layout_Swap_Screens, &QAction::triggered, this,
|
||||||
&GMainWindow::OnSwapScreens);
|
&GMainWindow::OnSwapScreens);
|
||||||
connect(ui->action_Screen_Layout_Upright_Screens, &QAction::triggered, this,
|
connect(ui->action_Screen_Layout_Upright_Screens, &QAction::triggered, this,
|
||||||
@ -965,14 +925,11 @@ bool GMainWindow::LoadROM(const QString& filename) {
|
|||||||
ShutdownGame();
|
ShutdownGame();
|
||||||
|
|
||||||
render_window->InitRenderTarget();
|
render_window->InitRenderTarget();
|
||||||
secondary_window->InitRenderTarget();
|
|
||||||
|
|
||||||
const auto scope = render_window->Acquire();
|
const auto scope = render_window->Acquire();
|
||||||
|
|
||||||
Core::System& system{Core::System::GetInstance()};
|
Core::System& system = Core::System::GetInstance();
|
||||||
|
const Core::System::ResultStatus result = system.Load(*render_window, filename.toStdString());
|
||||||
const Core::System::ResultStatus result{
|
|
||||||
system.Load(*render_window, filename.toStdString(), secondary_window)};
|
|
||||||
|
|
||||||
if (result != Core::System::ResultStatus::Success) {
|
if (result != Core::System::ResultStatus::Success) {
|
||||||
switch (result) {
|
switch (result) {
|
||||||
@ -1079,22 +1036,6 @@ void GMainWindow::BootGame(const QString& filename) {
|
|||||||
Core::Movie::GetInstance().PrepareForPlayback(movie_playback_path.toStdString());
|
Core::Movie::GetInstance().PrepareForPlayback(movie_playback_path.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 title_id{0};
|
|
||||||
const std::string path = filename.toStdString();
|
|
||||||
const auto loader = Loader::GetLoader(path);
|
|
||||||
|
|
||||||
if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success) {
|
|
||||||
// Load per game settings
|
|
||||||
const std::string name{FileUtil::GetFilename(filename.toStdString())};
|
|
||||||
const std::string config_file_name =
|
|
||||||
title_id == 0 ? name : fmt::format("{:016X}", title_id);
|
|
||||||
Config per_game_config(config_file_name, Config::ConfigType::PerGameConfig);
|
|
||||||
Settings::Apply();
|
|
||||||
|
|
||||||
LOG_INFO(Frontend, "Using per game config file for title id {}", config_file_name);
|
|
||||||
Settings::LogSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save configurations
|
// Save configurations
|
||||||
UpdateUISettings();
|
UpdateUISettings();
|
||||||
game_list->SaveInterfaceLayout();
|
game_list->SaveInterfaceLayout();
|
||||||
@ -1146,8 +1087,6 @@ void GMainWindow::BootGame(const QString& filename) {
|
|||||||
|
|
||||||
connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
|
connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
|
||||||
connect(render_window, &GRenderWindow::MouseActivity, this, &GMainWindow::OnMouseActivity);
|
connect(render_window, &GRenderWindow::MouseActivity, this, &GMainWindow::OnMouseActivity);
|
||||||
connect(secondary_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
|
|
||||||
connect(secondary_window, &GRenderWindow::MouseActivity, this, &GMainWindow::OnMouseActivity);
|
|
||||||
|
|
||||||
// BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views
|
// BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views
|
||||||
// before the CPU continues
|
// before the CPU continues
|
||||||
@ -1239,7 +1178,6 @@ void GMainWindow::ShutdownGame() {
|
|||||||
|
|
||||||
// The emulation is stopped, so closing the window or not does not matter anymore
|
// The emulation is stopped, so closing the window or not does not matter anymore
|
||||||
disconnect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
|
disconnect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
|
||||||
disconnect(secondary_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
|
|
||||||
|
|
||||||
// Update the GUI
|
// Update the GUI
|
||||||
ui->action_Start->setEnabled(false);
|
ui->action_Start->setEnabled(false);
|
||||||
@ -1248,14 +1186,12 @@ void GMainWindow::ShutdownGame() {
|
|||||||
ui->action_Stop->setEnabled(false);
|
ui->action_Stop->setEnabled(false);
|
||||||
ui->action_Restart->setEnabled(false);
|
ui->action_Restart->setEnabled(false);
|
||||||
ui->action_Cheats->setEnabled(false);
|
ui->action_Cheats->setEnabled(false);
|
||||||
ui->action_Configure_Current_Game->setEnabled(false);
|
|
||||||
ui->action_Load_Amiibo->setEnabled(false);
|
ui->action_Load_Amiibo->setEnabled(false);
|
||||||
ui->action_Remove_Amiibo->setEnabled(false);
|
ui->action_Remove_Amiibo->setEnabled(false);
|
||||||
ui->action_Report_Compatibility->setEnabled(false);
|
ui->action_Report_Compatibility->setEnabled(false);
|
||||||
ui->action_Advance_Frame->setEnabled(false);
|
ui->action_Advance_Frame->setEnabled(false);
|
||||||
ui->action_Capture_Screenshot->setEnabled(false);
|
ui->action_Capture_Screenshot->setEnabled(false);
|
||||||
render_window->hide();
|
render_window->hide();
|
||||||
secondary_window->hide();
|
|
||||||
loading_screen->hide();
|
loading_screen->hide();
|
||||||
loading_screen->Clear();
|
loading_screen->Clear();
|
||||||
if (game_list->IsEmpty())
|
if (game_list->IsEmpty())
|
||||||
@ -1288,7 +1224,6 @@ void GMainWindow::ShutdownGame() {
|
|||||||
|
|
||||||
// When closing the game, destroy the GLWindow to clear the context after the game is closed
|
// When closing the game, destroy the GLWindow to clear the context after the game is closed
|
||||||
render_window->ReleaseRenderTarget();
|
render_window->ReleaseRenderTarget();
|
||||||
secondary_window->ReleaseRenderTarget();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::StoreRecentFile(const QString& filename) {
|
void GMainWindow::StoreRecentFile(const QString& filename) {
|
||||||
@ -1379,10 +1314,8 @@ void GMainWindow::UpdateSaveStates() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnGameListLoadFile(QString game_path) {
|
void GMainWindow::OnGameListLoadFile(QString game_path) {
|
||||||
if (ConfirmChangeGame()) {
|
|
||||||
BootGame(game_path);
|
BootGame(game_path);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void GMainWindow::OnGameListOpenFolder(u64 data_id, GameListOpenTarget target) {
|
void GMainWindow::OnGameListOpenFolder(u64 data_id, GameListOpenTarget target) {
|
||||||
std::string path;
|
std::string path;
|
||||||
@ -1391,13 +1324,13 @@ void GMainWindow::OnGameListOpenFolder(u64 data_id, GameListOpenTarget target) {
|
|||||||
switch (target) {
|
switch (target) {
|
||||||
case GameListOpenTarget::SAVE_DATA: {
|
case GameListOpenTarget::SAVE_DATA: {
|
||||||
open_target = "Save Data";
|
open_target = "Save Data";
|
||||||
std::string sdmc_dir = FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir);
|
std::string sdmc_dir = Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir);
|
||||||
path = FileSys::ArchiveSource_SDSaveData::GetSaveDataPathFor(sdmc_dir, data_id);
|
path = FileSys::ArchiveSource_SDSaveData::GetSaveDataPathFor(sdmc_dir, data_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GameListOpenTarget::EXT_DATA: {
|
case GameListOpenTarget::EXT_DATA: {
|
||||||
open_target = "Extra Data";
|
open_target = "Extra Data";
|
||||||
std::string sdmc_dir = FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir);
|
std::string sdmc_dir = Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir);
|
||||||
path = FileSys::GetExtDataPathFromId(sdmc_dir, data_id);
|
path = FileSys::GetExtDataPathFromId(sdmc_dir, data_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1416,31 +1349,24 @@ void GMainWindow::OnGameListOpenFolder(u64 data_id, GameListOpenTarget target) {
|
|||||||
case GameListOpenTarget::TEXTURE_DUMP: {
|
case GameListOpenTarget::TEXTURE_DUMP: {
|
||||||
open_target = "Dumped Textures";
|
open_target = "Dumped Textures";
|
||||||
path = fmt::format("{}textures/{:016X}/",
|
path = fmt::format("{}textures/{:016X}/",
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::DumpDir), data_id);
|
Common::FS::GetUserPath(Common::FS::UserPath::DumpDir), data_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GameListOpenTarget::TEXTURE_LOAD: {
|
case GameListOpenTarget::TEXTURE_LOAD: {
|
||||||
open_target = "Custom Textures";
|
open_target = "Custom Textures";
|
||||||
path = fmt::format("{}textures/{:016X}/",
|
path = fmt::format("{}textures/{:016X}/",
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::LoadDir), data_id);
|
Common::FS::GetUserPath(Common::FS::UserPath::LoadDir), data_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GameListOpenTarget::MODS: {
|
case GameListOpenTarget::MODS: {
|
||||||
open_target = "Mods";
|
open_target = "Mods";
|
||||||
path = fmt::format("{}mods/{:016X}/", FileUtil::GetUserPath(FileUtil::UserPath::LoadDir),
|
path = fmt::format("{}mods/{:016X}/", Common::FS::GetUserPath(Common::FS::UserPath::LoadDir),
|
||||||
data_id);
|
data_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GameListOpenTarget::DLC_DATA: {
|
|
||||||
open_target = "DLC Data";
|
|
||||||
path = fmt::format("{}Nintendo 3DS/00000000000000000000000000000000/"
|
|
||||||
"00000000000000000000000000000000/title/0004008c/{:08x}/content/",
|
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), data_id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GameListOpenTarget::SHADER_CACHE: {
|
case GameListOpenTarget::SHADER_CACHE: {
|
||||||
open_target = "Shader Cache";
|
open_target = "Shader Cache";
|
||||||
path = FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir);
|
path = Common::FS::GetUserPath(Common::FS::UserPath::ShaderDir);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -1484,9 +1410,9 @@ void GMainWindow::OnGameListDumpRomFS(QString game_path, u64 program_id) {
|
|||||||
dialog->setValue(0);
|
dialog->setValue(0);
|
||||||
|
|
||||||
const auto base_path = fmt::format(
|
const auto base_path = fmt::format(
|
||||||
"{}romfs/{:016X}", FileUtil::GetUserPath(FileUtil::UserPath::DumpDir), program_id);
|
"{}romfs/{:016X}", Common::FS::GetUserPath(Common::FS::UserPath::DumpDir), program_id);
|
||||||
const auto update_path =
|
const auto update_path =
|
||||||
fmt::format("{}romfs/{:016X}", FileUtil::GetUserPath(FileUtil::UserPath::DumpDir),
|
fmt::format("{}romfs/{:016X}", Common::FS::GetUserPath(Common::FS::UserPath::DumpDir),
|
||||||
program_id | 0x0004000e00000000);
|
program_id | 0x0004000e00000000);
|
||||||
using FutureWatcher = QFutureWatcher<std::pair<Loader::ResultStatus, Loader::ResultStatus>>;
|
using FutureWatcher = QFutureWatcher<std::pair<Loader::ResultStatus, Loader::ResultStatus>>;
|
||||||
auto* future_watcher = new FutureWatcher(this);
|
auto* future_watcher = new FutureWatcher(this);
|
||||||
@ -1517,12 +1443,12 @@ void GMainWindow::OnGameListDumpRomFS(QString game_path, u64 program_id) {
|
|||||||
void GMainWindow::OnGameListOpenDirectory(const QString& directory) {
|
void GMainWindow::OnGameListOpenDirectory(const QString& directory) {
|
||||||
QString path;
|
QString path;
|
||||||
if (directory == QStringLiteral("INSTALLED")) {
|
if (directory == QStringLiteral("INSTALLED")) {
|
||||||
path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) +
|
path = QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir) +
|
||||||
"Nintendo "
|
"Nintendo "
|
||||||
"3DS/00000000000000000000000000000000/"
|
"3DS/00000000000000000000000000000000/"
|
||||||
"00000000000000000000000000000000/title/00040000");
|
"00000000000000000000000000000000/title/00040000");
|
||||||
} else if (directory == QStringLiteral("SYSTEM")) {
|
} else if (directory == QStringLiteral("SYSTEM")) {
|
||||||
path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
|
path = QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) +
|
||||||
"00000000000000000000000000000000/title/00040010");
|
"00000000000000000000000000000000/title/00040010");
|
||||||
} else {
|
} else {
|
||||||
path = directory;
|
path = directory;
|
||||||
@ -1554,19 +1480,6 @@ void GMainWindow::OnGameListShowList(bool show) {
|
|||||||
game_list_placeholder->setVisible(!show);
|
game_list_placeholder->setVisible(!show);
|
||||||
};
|
};
|
||||||
|
|
||||||
void GMainWindow::OnGameListOpenPerGameProperties(const QString& file) {
|
|
||||||
const auto loader = Loader::GetLoader(file.toStdString());
|
|
||||||
|
|
||||||
u64 title_id{};
|
|
||||||
if (!loader || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) {
|
|
||||||
QMessageBox::information(this, tr("Properties"),
|
|
||||||
tr("The game properties could not be loaded."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenPerGameConfiguration(title_id, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GMainWindow::OnMenuLoadFile() {
|
void GMainWindow::OnMenuLoadFile() {
|
||||||
const QString extensions = QStringLiteral("*.").append(
|
const QString extensions = QStringLiteral("*.").append(
|
||||||
GameList::supported_file_extensions.join(QStringLiteral(" *.")));
|
GameList::supported_file_extensions.join(QStringLiteral(" *.")));
|
||||||
@ -1692,7 +1605,6 @@ void GMainWindow::OnStartGame() {
|
|||||||
ui->action_Stop->setEnabled(true);
|
ui->action_Stop->setEnabled(true);
|
||||||
ui->action_Restart->setEnabled(true);
|
ui->action_Restart->setEnabled(true);
|
||||||
ui->action_Cheats->setEnabled(true);
|
ui->action_Cheats->setEnabled(true);
|
||||||
ui->action_Configure_Current_Game->setEnabled(true);
|
|
||||||
ui->action_Load_Amiibo->setEnabled(true);
|
ui->action_Load_Amiibo->setEnabled(true);
|
||||||
ui->action_Report_Compatibility->setEnabled(true);
|
ui->action_Report_Compatibility->setEnabled(true);
|
||||||
ui->action_Capture_Screenshot->setEnabled(true);
|
ui->action_Capture_Screenshot->setEnabled(true);
|
||||||
@ -1715,12 +1627,10 @@ void GMainWindow::OnPauseGame() {
|
|||||||
|
|
||||||
void GMainWindow::OnStopGame() {
|
void GMainWindow::OnStopGame() {
|
||||||
ShutdownGame();
|
ShutdownGame();
|
||||||
Settings::RestoreGlobalState(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnLoadComplete() {
|
void GMainWindow::OnLoadComplete() {
|
||||||
loading_screen->OnLoadComplete();
|
loading_screen->OnLoadComplete();
|
||||||
UpdateSecondaryWindowVisibility();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnMenuReportCompatibility() {
|
void GMainWindow::OnMenuReportCompatibility() {
|
||||||
@ -1745,17 +1655,6 @@ void GMainWindow::ToggleFullscreen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::ToggleSecondaryFullscreen() {
|
|
||||||
if (!emulation_running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (secondary_window->isFullScreen()) {
|
|
||||||
secondary_window->showNormal();
|
|
||||||
} else {
|
|
||||||
secondary_window->showFullScreen();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GMainWindow::ShowFullscreen() {
|
void GMainWindow::ShowFullscreen() {
|
||||||
if (ui->action_Single_Window_Mode->isChecked()) {
|
if (ui->action_Single_Window_Mode->isChecked()) {
|
||||||
UISettings::values.geometry = saveGeometry();
|
UISettings::values.geometry = saveGeometry();
|
||||||
@ -1805,19 +1704,6 @@ void GMainWindow::ToggleWindowMode() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::UpdateSecondaryWindowVisibility() {
|
|
||||||
if (!emulation_running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows) {
|
|
||||||
secondary_window->RestoreGeometry();
|
|
||||||
secondary_window->show();
|
|
||||||
} else {
|
|
||||||
secondary_window->BackupGeometry();
|
|
||||||
secondary_window->hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GMainWindow::ChangeScreenLayout() {
|
void GMainWindow::ChangeScreenLayout() {
|
||||||
Settings::LayoutOption new_layout = Settings::LayoutOption::Default;
|
Settings::LayoutOption new_layout = Settings::LayoutOption::Default;
|
||||||
|
|
||||||
@ -1829,39 +1715,35 @@ void GMainWindow::ChangeScreenLayout() {
|
|||||||
new_layout = Settings::LayoutOption::LargeScreen;
|
new_layout = Settings::LayoutOption::LargeScreen;
|
||||||
} else if (ui->action_Screen_Layout_Side_by_Side->isChecked()) {
|
} else if (ui->action_Screen_Layout_Side_by_Side->isChecked()) {
|
||||||
new_layout = Settings::LayoutOption::SideScreen;
|
new_layout = Settings::LayoutOption::SideScreen;
|
||||||
} else if (ui->action_Screen_Layout_Separate_Windows->isChecked()) {
|
|
||||||
new_layout = Settings::LayoutOption::SeparateWindows;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::values.layout_option = new_layout;
|
Settings::values.layout_option = new_layout;
|
||||||
Settings::Apply();
|
Settings::Apply();
|
||||||
UpdateSecondaryWindowVisibility();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::ToggleScreenLayout() {
|
void GMainWindow::ToggleScreenLayout() {
|
||||||
const Settings::LayoutOption new_layout = []() {
|
Settings::LayoutOption new_layout = Settings::LayoutOption::Default;
|
||||||
switch (Settings::values.layout_option.GetValue()) {
|
|
||||||
|
switch (Settings::values.layout_option) {
|
||||||
case Settings::LayoutOption::Default:
|
case Settings::LayoutOption::Default:
|
||||||
return Settings::LayoutOption::SingleScreen;
|
new_layout = Settings::LayoutOption::SingleScreen;
|
||||||
|
break;
|
||||||
case Settings::LayoutOption::SingleScreen:
|
case Settings::LayoutOption::SingleScreen:
|
||||||
return Settings::LayoutOption::LargeScreen;
|
new_layout = Settings::LayoutOption::LargeScreen;
|
||||||
|
break;
|
||||||
case Settings::LayoutOption::LargeScreen:
|
case Settings::LayoutOption::LargeScreen:
|
||||||
return Settings::LayoutOption::SideScreen;
|
new_layout = Settings::LayoutOption::SideScreen;
|
||||||
|
break;
|
||||||
case Settings::LayoutOption::SideScreen:
|
case Settings::LayoutOption::SideScreen:
|
||||||
return Settings::LayoutOption::SeparateWindows;
|
new_layout = Settings::LayoutOption::Default;
|
||||||
case Settings::LayoutOption::SeparateWindows:
|
break;
|
||||||
return Settings::LayoutOption::Default;
|
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Frontend, "Unknown layout option {}",
|
LOG_ERROR(Frontend, "Unknown layout option {}", Settings::values.layout_option);
|
||||||
Settings::values.layout_option.GetValue());
|
|
||||||
return Settings::LayoutOption::Default;
|
|
||||||
}
|
}
|
||||||
}();
|
|
||||||
|
|
||||||
Settings::values.layout_option = new_layout;
|
Settings::values.layout_option = new_layout;
|
||||||
SyncMenuUISettings();
|
SyncMenuUISettings();
|
||||||
Settings::Apply();
|
Settings::Apply();
|
||||||
UpdateSecondaryWindowVisibility();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnSwapScreens() {
|
void GMainWindow::OnSwapScreens() {
|
||||||
@ -1874,14 +1756,6 @@ void GMainWindow::OnRotateScreens() {
|
|||||||
Settings::Apply();
|
Settings::Apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::TriggerSwapScreens() {
|
|
||||||
ui->action_Screen_Layout_Swap_Screens->trigger();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GMainWindow::TriggerRotateScreens() {
|
|
||||||
ui->action_Screen_Layout_Upright_Screens->trigger();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GMainWindow::OnCheats() {
|
void GMainWindow::OnCheats() {
|
||||||
CheatDialog cheat_dialog(this);
|
CheatDialog cheat_dialog(this);
|
||||||
cheat_dialog.exec();
|
cheat_dialog.exec();
|
||||||
@ -1905,7 +1779,6 @@ void GMainWindow::OnLoadState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnConfigure() {
|
void GMainWindow::OnConfigure() {
|
||||||
Settings::SetConfiguringGlobal(true);
|
|
||||||
ConfigureDialog configureDialog(this, hotkey_registry,
|
ConfigureDialog configureDialog(this, hotkey_registry,
|
||||||
!multiplayer_state->IsHostingPublicRoom());
|
!multiplayer_state->IsHostingPublicRoom());
|
||||||
connect(&configureDialog, &ConfigureDialog::LanguageChanged, this,
|
connect(&configureDialog, &ConfigureDialog::LanguageChanged, this,
|
||||||
@ -1914,15 +1787,15 @@ void GMainWindow::OnConfigure() {
|
|||||||
const int old_input_profile_index = Settings::values.current_input_profile_index;
|
const int old_input_profile_index = Settings::values.current_input_profile_index;
|
||||||
const auto old_input_profiles = Settings::values.input_profiles;
|
const auto old_input_profiles = Settings::values.input_profiles;
|
||||||
const auto old_touch_from_button_maps = Settings::values.touch_from_button_maps;
|
const auto old_touch_from_button_maps = Settings::values.touch_from_button_maps;
|
||||||
const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue();
|
const bool old_discord_presence = UISettings::values.enable_discord_presence;
|
||||||
auto result = configureDialog.exec();
|
auto result = configureDialog.exec();
|
||||||
if (result == QDialog::Accepted) {
|
if (result == QDialog::Accepted) {
|
||||||
configureDialog.ApplyConfiguration();
|
configureDialog.ApplyConfiguration();
|
||||||
InitializeHotkeys();
|
InitializeHotkeys();
|
||||||
if (UISettings::values.theme != old_theme)
|
if (UISettings::values.theme != old_theme)
|
||||||
UpdateUITheme();
|
UpdateUITheme();
|
||||||
if (UISettings::values.enable_discord_presence.GetValue() != old_discord_presence)
|
if (UISettings::values.enable_discord_presence != old_discord_presence)
|
||||||
SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue());
|
SetDiscordEnabled(UISettings::values.enable_discord_presence);
|
||||||
if (!multiplayer_state->IsHostingPublicRoom())
|
if (!multiplayer_state->IsHostingPublicRoom())
|
||||||
multiplayer_state->UpdateCredentials();
|
multiplayer_state->UpdateCredentials();
|
||||||
emit UpdateThemedIcons();
|
emit UpdateThemedIcons();
|
||||||
@ -1935,7 +1808,6 @@ void GMainWindow::OnConfigure() {
|
|||||||
} else {
|
} else {
|
||||||
setMouseTracking(false);
|
setMouseTracking(false);
|
||||||
}
|
}
|
||||||
UpdateSecondaryWindowVisibility();
|
|
||||||
UpdateAPIIndicator(false);
|
UpdateAPIIndicator(false);
|
||||||
} else {
|
} else {
|
||||||
Settings::values.input_profiles = old_input_profiles;
|
Settings::values.input_profiles = old_input_profiles;
|
||||||
@ -2001,7 +1873,7 @@ void GMainWindow::OnRemoveAmiibo() {
|
|||||||
|
|
||||||
void GMainWindow::OnOpenCitraFolder() {
|
void GMainWindow::OnOpenCitraFolder() {
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
||||||
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::UserDir))));
|
QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::UserDir))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnToggleFilterBar() {
|
void GMainWindow::OnToggleFilterBar() {
|
||||||
@ -2100,26 +1972,22 @@ void GMainWindow::OnSaveMovie() {
|
|||||||
|
|
||||||
void GMainWindow::OnCaptureScreenshot() {
|
void GMainWindow::OnCaptureScreenshot() {
|
||||||
OnPauseGame();
|
OnPauseGame();
|
||||||
std::string path = UISettings::values.screenshot_path.GetValue();
|
QString path = UISettings::values.screenshot_path;
|
||||||
if (!FileUtil::IsDirectory(path)) {
|
if (!Common::FS::IsDirectory(path.toStdString())) {
|
||||||
if (!FileUtil::CreateFullPath(path)) {
|
if (!Common::FS::CreateFullPath(path.toStdString())) {
|
||||||
QMessageBox::information(this, tr("Invalid Screenshot Directory"),
|
QMessageBox::information(this, tr("Invalid Screenshot Directory"),
|
||||||
tr("Cannot create specified screenshot directory. Screenshot "
|
tr("Cannot create specified screenshot directory. Screenshot "
|
||||||
"path is set back to its default value."));
|
"path is set back to its default value."));
|
||||||
path = FileUtil::GetUserPath(FileUtil::UserPath::UserDir);
|
path = QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::UserDir));
|
||||||
path.append("screenshots/");
|
path.append(QStringLiteral("screenshots/"));
|
||||||
UISettings::values.screenshot_path = path;
|
UISettings::values.screenshot_path = path;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const std::string filename =
|
const QString filename = game_title.remove(QRegularExpression(QStringLiteral("[\\/:?\"<>|]")));
|
||||||
game_title.remove(QRegularExpression(QStringLiteral("[\\/:?\"<>|]"))).toStdString();
|
const QString timestamp =
|
||||||
const std::string timestamp =
|
QDateTime::currentDateTime().toString(QStringLiteral("dd.MM.yy_hh.mm.ss.z"));
|
||||||
QDateTime::currentDateTime().toString(QStringLiteral("dd.MM.yy_hh.mm.ss.z")).toStdString();
|
path.append(QStringLiteral("/%1_%2.png").arg(filename, timestamp));
|
||||||
path.append(fmt::format("/{}_{}.png", filename, timestamp));
|
render_window->CaptureScreenshot(UISettings::values.screenshot_resolution_factor, path);
|
||||||
|
|
||||||
auto* const screenshot_window = secondary_window->HasFocus() ? secondary_window : render_window;
|
|
||||||
screenshot_window->CaptureScreenshot(UISettings::values.screenshot_resolution_factor.GetValue(),
|
|
||||||
QString::fromStdString(path));
|
|
||||||
OnStartGame();
|
OnStartGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2211,12 +2079,22 @@ void GMainWindow::UpdateStatusBar() {
|
|||||||
|
|
||||||
auto results = Core::System::GetInstance().GetAndResetPerfStats();
|
auto results = Core::System::GetInstance().GetAndResetPerfStats();
|
||||||
|
|
||||||
if (Settings::values.frame_limit.GetValue() == 0) {
|
if (Settings::values.use_frame_limit_alternate) {
|
||||||
|
if (Settings::values.frame_limit_alternate == 0) {
|
||||||
|
emu_speed_label->setText(
|
||||||
|
tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
emu_speed_label->setText(tr("Speed: %1% / %2%")
|
||||||
|
.arg(results.emulation_speed * 100.0, 0, 'f', 0)
|
||||||
|
.arg(Settings::values.frame_limit_alternate));
|
||||||
|
}
|
||||||
|
} else if (Settings::values.frame_limit == 0) {
|
||||||
emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
|
emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
|
||||||
} else {
|
} else {
|
||||||
emu_speed_label->setText(tr("Speed: %1% / %2%")
|
emu_speed_label->setText(tr("Speed: %1% / %2%")
|
||||||
.arg(results.emulation_speed * 100.0, 0, 'f', 0)
|
.arg(results.emulation_speed * 100.0, 0, 'f', 0)
|
||||||
.arg(Settings::values.frame_limit.GetValue()));
|
.arg(Settings::values.frame_limit));
|
||||||
}
|
}
|
||||||
game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0));
|
game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0));
|
||||||
emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));
|
emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));
|
||||||
@ -2227,22 +2105,16 @@ void GMainWindow::UpdateStatusBar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::HideMouseCursor() {
|
void GMainWindow::HideMouseCursor() {
|
||||||
if (emu_thread == nullptr || !UISettings::values.hide_mouse.GetValue()) {
|
if (emu_thread == nullptr || UISettings::values.hide_mouse == false) {
|
||||||
mouse_hide_timer.stop();
|
mouse_hide_timer.stop();
|
||||||
ShowMouseCursor();
|
ShowMouseCursor();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
render_window->setCursor(QCursor(Qt::BlankCursor));
|
render_window->setCursor(QCursor(Qt::BlankCursor));
|
||||||
secondary_window->setCursor(QCursor(Qt::BlankCursor));
|
|
||||||
if (UISettings::values.single_window_mode.GetValue()) {
|
|
||||||
setCursor(QCursor(Qt::BlankCursor));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::ShowMouseCursor() {
|
void GMainWindow::ShowMouseCursor() {
|
||||||
unsetCursor();
|
|
||||||
render_window->unsetCursor();
|
render_window->unsetCursor();
|
||||||
secondary_window->unsetCursor();
|
|
||||||
if (emu_thread != nullptr && UISettings::values.hide_mouse) {
|
if (emu_thread != nullptr && UISettings::values.hide_mouse) {
|
||||||
mouse_hide_timer.start();
|
mouse_hide_timer.start();
|
||||||
}
|
}
|
||||||
@ -2255,7 +2127,7 @@ void GMainWindow::UpdateAPIIndicator(bool override) {
|
|||||||
static std::array graphics_api_colors = {QStringLiteral("#00ccdd"), QStringLiteral("#ba2a8d"),
|
static std::array graphics_api_colors = {QStringLiteral("#00ccdd"), QStringLiteral("#ba2a8d"),
|
||||||
QStringLiteral("#91242a")};
|
QStringLiteral("#91242a")};
|
||||||
|
|
||||||
u32 api_index = static_cast<u32>(Settings::values.graphics_api.GetValue());
|
u32 api_index = static_cast<u32>(Settings::values.graphics_api);
|
||||||
if (override) {
|
if (override) {
|
||||||
api_index = (api_index + 1) % graphics_apis.size();
|
api_index = (api_index + 1) % graphics_apis.size();
|
||||||
Settings::values.graphics_api = static_cast<Settings::GraphicsAPI>(api_index);
|
Settings::values.graphics_api = static_cast<Settings::GraphicsAPI>(api_index);
|
||||||
@ -2371,9 +2243,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
|
|||||||
ShutdownGame();
|
ShutdownGame();
|
||||||
|
|
||||||
render_window->close();
|
render_window->close();
|
||||||
secondary_window->close();
|
|
||||||
multiplayer_state->Close();
|
multiplayer_state->Close();
|
||||||
InputCommon::Shutdown();
|
|
||||||
QWidget::closeEvent(event);
|
QWidget::closeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2524,35 +2394,6 @@ void GMainWindow::OnLanguageChanged(const QString& locale) {
|
|||||||
ui->action_Start->setText(tr("Continue"));
|
ui->action_Start->setText(tr("Continue"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnConfigurePerGame() {
|
|
||||||
u64 title_id{};
|
|
||||||
Core::System::GetInstance().GetAppLoader().ReadProgramId(title_id);
|
|
||||||
OpenPerGameConfiguration(title_id, game_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GMainWindow::OpenPerGameConfiguration(u64 title_id, const QString& file_name) {
|
|
||||||
Core::System& system = Core::System::GetInstance();
|
|
||||||
|
|
||||||
Settings::SetConfiguringGlobal(false);
|
|
||||||
ConfigurePerGame dialog(this, title_id, file_name, system);
|
|
||||||
const auto result = dialog.exec();
|
|
||||||
|
|
||||||
if (result != QDialog::Accepted) {
|
|
||||||
Settings::RestoreGlobalState(system.IsPoweredOn());
|
|
||||||
return;
|
|
||||||
} else if (result == QDialog::Accepted) {
|
|
||||||
dialog.ApplyConfiguration();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not cause the global config to write local settings into the config file
|
|
||||||
const bool is_powered_on = system.IsPoweredOn();
|
|
||||||
Settings::RestoreGlobalState(system.IsPoweredOn());
|
|
||||||
|
|
||||||
if (!is_powered_on) {
|
|
||||||
config->Save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GMainWindow::OnMoviePlaybackCompleted() {
|
void GMainWindow::OnMoviePlaybackCompleted() {
|
||||||
OnPauseGame();
|
OnPauseGame();
|
||||||
QMessageBox::information(this, tr("Playback Completed"), tr("Movie playback completed."));
|
QMessageBox::information(this, tr("Playback Completed"), tr("Movie playback completed."));
|
||||||
@ -2587,19 +2428,16 @@ void GMainWindow::UpdateUISettings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::SyncMenuUISettings() {
|
void GMainWindow::SyncMenuUISettings() {
|
||||||
ui->action_Screen_Layout_Default->setChecked(Settings::values.layout_option.GetValue() ==
|
ui->action_Screen_Layout_Default->setChecked(Settings::values.layout_option ==
|
||||||
Settings::LayoutOption::Default);
|
Settings::LayoutOption::Default);
|
||||||
ui->action_Screen_Layout_Single_Screen->setChecked(Settings::values.layout_option.GetValue() ==
|
ui->action_Screen_Layout_Single_Screen->setChecked(Settings::values.layout_option ==
|
||||||
Settings::LayoutOption::SingleScreen);
|
Settings::LayoutOption::SingleScreen);
|
||||||
ui->action_Screen_Layout_Large_Screen->setChecked(Settings::values.layout_option.GetValue() ==
|
ui->action_Screen_Layout_Large_Screen->setChecked(Settings::values.layout_option ==
|
||||||
Settings::LayoutOption::LargeScreen);
|
Settings::LayoutOption::LargeScreen);
|
||||||
ui->action_Screen_Layout_Side_by_Side->setChecked(Settings::values.layout_option.GetValue() ==
|
ui->action_Screen_Layout_Side_by_Side->setChecked(Settings::values.layout_option ==
|
||||||
Settings::LayoutOption::SideScreen);
|
Settings::LayoutOption::SideScreen);
|
||||||
ui->action_Screen_Layout_Separate_Windows->setChecked(
|
ui->action_Screen_Layout_Swap_Screens->setChecked(Settings::values.swap_screen);
|
||||||
Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows);
|
ui->action_Screen_Layout_Upright_Screens->setChecked(Settings::values.upright_screen);
|
||||||
ui->action_Screen_Layout_Swap_Screens->setChecked(Settings::values.swap_screen.GetValue());
|
|
||||||
ui->action_Screen_Layout_Upright_Screens->setChecked(
|
|
||||||
Settings::values.upright_screen.GetValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::RetranslateStatusBar() {
|
void GMainWindow::RetranslateStatusBar() {
|
||||||
@ -2644,7 +2482,7 @@ int main(int argc, char* argv[]) {
|
|||||||
QCoreApplication::setApplicationName(QStringLiteral("Citra"));
|
QCoreApplication::setApplicationName(QStringLiteral("Citra"));
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
std::string bin_path = FileUtil::GetBundleDirectory() + DIR_SEP + "..";
|
std::string bin_path = Common::FS::GetBundleDirectory() + DIR_SEP + "..";
|
||||||
chdir(bin_path.c_str());
|
chdir(bin_path.c_str());
|
||||||
#endif
|
#endif
|
||||||
QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
|
QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
|
||||||
@ -2664,13 +2502,11 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
// Register frontend applets
|
// Register frontend applets
|
||||||
Frontend::RegisterDefaultApplets();
|
Frontend::RegisterDefaultApplets();
|
||||||
|
Core::System::GetInstance().RegisterMiiSelector(std::make_shared<QtMiiSelector>(main_window));
|
||||||
Core::System& system = Core::System::GetInstance();
|
Core::System::GetInstance().RegisterSoftwareKeyboard(std::make_shared<QtKeyboard>(main_window));
|
||||||
system.RegisterMiiSelector(std::make_shared<QtMiiSelector>(main_window));
|
|
||||||
system.RegisterSoftwareKeyboard(std::make_shared<QtKeyboard>(main_window));
|
|
||||||
|
|
||||||
// Register Qt image interface
|
// Register Qt image interface
|
||||||
system.RegisterImageInterface(std::make_shared<QtImageInterface>());
|
Core::System::GetInstance().RegisterImageInterface(std::make_shared<QtImageInterface>());
|
||||||
|
|
||||||
main_window.show();
|
main_window.show();
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user