mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
151 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e160fca8f | ||
|
|
a0ef82e221 | ||
|
|
3e7ac3d66c | ||
|
|
730e6fa737 | ||
|
|
cdfcd9fddd | ||
|
|
b6930c10b9 | ||
|
|
852734580d | ||
|
|
d1dc6a9c1d | ||
|
|
4fa6d3ed3f | ||
|
|
92e190ad6c | ||
|
|
da4fcffef4 | ||
|
|
1a5731dd8e | ||
|
|
e764c5cd4e | ||
|
|
e23b247947 | ||
|
|
3d7792436f | ||
|
|
d8187fbea4 | ||
|
|
02259ad0a5 | ||
|
|
220a68df9a | ||
|
|
2ced24f69e | ||
|
|
ec91d0dc74 | ||
|
|
46874f4673 | ||
|
|
9eac47dc6c | ||
|
|
9e3fd5c2e0 | ||
|
|
ae4be6e2b1 | ||
|
|
434df49a7d | ||
|
|
c939c0fcd5 | ||
|
|
952c39f324 | ||
|
|
0fea7e2a70 | ||
|
|
c1baab68d0 | ||
|
|
ccef18f7a9 | ||
|
|
8cb056bde3 | ||
|
|
6ecaaee9e0 | ||
|
|
c5f916bda0 | ||
|
|
52a9a4649c | ||
|
|
d2219b4dbd | ||
|
|
155f603245 | ||
|
|
cb7630a6ab | ||
|
|
284fba1ce3 | ||
|
|
aa4bd6c88c | ||
|
|
623993930b | ||
|
|
dbf2c854c6 | ||
|
|
25351bc05c | ||
|
|
27cc5f499c | ||
|
|
b7c2f39a17 | ||
|
|
3541c1ccf8 | ||
|
|
7a05738d11 | ||
|
|
686220ae0c | ||
|
|
cf380d36b9 | ||
|
|
50bc0193ac | ||
|
|
2162a72831 | ||
|
|
313666f85b | ||
|
|
e9d79263b4 | ||
|
|
4ede6d65fd | ||
|
|
14d2eee371 | ||
|
|
717f370be0 | ||
|
|
d05e4b9727 | ||
|
|
697c53b4d8 | ||
|
|
d9b58ec3ce | ||
|
|
6c8b37d7ca | ||
|
|
39f43e766d | ||
|
|
5379a13944 | ||
|
|
cd0c1607ef | ||
|
|
26a4f71385 | ||
|
|
06b3e6ad71 | ||
|
|
79d22a8d77 | ||
|
|
9914212600 | ||
|
|
765f55e67b | ||
|
|
2d922cc035 | ||
|
|
42e0625ab3 | ||
|
|
c72e894fc7 | ||
|
|
5bc2342d47 | ||
|
|
ea2b0b5e59 | ||
|
|
d70cc0221a | ||
|
|
b12587b44e | ||
|
|
c4708bdc35 | ||
|
|
1fa2c0bf50 | ||
|
|
b4c70d357a | ||
|
|
f18262ee96 | ||
|
|
c1f1761482 | ||
|
|
067c3eea16 | ||
|
|
6957cc7001 | ||
|
|
7dea23eea8 | ||
|
|
319ec1f774 | ||
|
|
2079532e83 | ||
|
|
de1d646fe9 | ||
|
|
4bc3ab6285 | ||
|
|
1adc9cbb49 | ||
|
|
7cdf5eefc9 | ||
|
|
c7ee72647d | ||
|
|
5434af348e | ||
|
|
169cea0f01 | ||
|
|
a8f3ec8184 | ||
|
|
7796b2a12b | ||
|
|
d9cffd58ba | ||
|
|
e566386240 | ||
|
|
45af1e172f | ||
|
|
768b2e52a6 | ||
|
|
7abd2009b0 | ||
|
|
46f075e891 | ||
|
|
832c381ac4 | ||
|
|
e021282264 | ||
|
|
2a60d385c6 | ||
|
|
4d37e35675 | ||
|
|
df3868a280 | ||
|
|
0799bb8cf1 | ||
|
|
69048dede4 | ||
|
|
76df6d1f43 | ||
|
|
2d03b21f2b | ||
|
|
62cbd44933 | ||
|
|
44c8f6d8b0 | ||
|
|
f3fc1dd59c | ||
|
|
708931e48b | ||
|
|
81800d2883 | ||
|
|
d0411d7ddf | ||
|
|
70e232cab3 | ||
|
|
f90396bda4 | ||
|
|
ae8808b86e | ||
|
|
8d5b827432 | ||
|
|
cb672697e7 | ||
|
|
0bae9fc29b | ||
|
|
49c8b68700 | ||
|
|
1e2fcd17e0 | ||
|
|
468b9d2655 | ||
|
|
a3305ff791 | ||
|
|
814b0d5873 | ||
|
|
863f3e82ac | ||
|
|
529c756458 | ||
|
|
67b98dbdaa | ||
|
|
a16981cbe5 | ||
|
|
777bf338fa | ||
|
|
3ba8d9ebff | ||
|
|
db5384e19c | ||
|
|
fd3984287b | ||
|
|
31dbea4e0b | ||
|
|
0992e784f1 | ||
|
|
c59cc1fbb7 | ||
|
|
903edc79f7 | ||
|
|
4c94c69f02 | ||
|
|
4c57c214bd | ||
|
|
1cbeea3016 | ||
|
|
0d18738192 | ||
|
|
1e7c7db29b | ||
|
|
7c098a2665 | ||
|
|
3ab539be1e | ||
|
|
b46d5e4efc | ||
|
|
db06e11a7c | ||
|
|
757ed33e4f | ||
|
|
8eb5dfce85 | ||
|
|
f34db72a97 | ||
|
|
3dfdc8ee6f | ||
|
|
5a846296ca |
54
.github/CONTRIBUTING.md
vendored
54
.github/CONTRIBUTING.md
vendored
@@ -1,54 +0,0 @@
|
||||
# So you want to contribute to PCSX2? Great
|
||||
|
||||
As a first step, please review these links as they'll help you understand how the development of PCSX2 works.
|
||||
|
||||
* [Just Starting Out](#just-starting-out)
|
||||
* [Issue Reporting](#issue-reporting)
|
||||
* [Pull Request Guidelines](#pull-request-guidelines)
|
||||
* [General Documentation And Coding Strategies](#general-documentation-and-coding-strategies)
|
||||
* [Tasks](#tasks)
|
||||
|
||||
## Just Starting Out
|
||||
|
||||
* If you're unfamilar with git, check out this [brief introduction to Git](https://github.com/PCSX2/pcsx2/wiki/07-Git-survival-guide)
|
||||
* [How to build PCSX2 for Windows](https://github.com/PCSX2/pcsx2/wiki/12-Building-on-Windows)
|
||||
* [How to build PCSX2 for Linux](https://github.com/PCSX2/pcsx2/wiki/10-Building-on-Linux)
|
||||
|
||||
## Issue Reporting
|
||||
|
||||
* [How to write a useful issue](https://github.com/PCSX2/pcsx2/wiki/How-to-create-useful-and-valid-issues)
|
||||
|
||||
## Pull Request Guidelines
|
||||
|
||||
The following is a list of *general* style recommendations that will make reviewing and merging easier:
|
||||
|
||||
* Commit Messages
|
||||
* Please try to prefix your commit message, indicating what area of the project was modified.
|
||||
* For example `gs: message...`.
|
||||
* Looking at the project's commit history will help with keeping prefixes consistent overtime, *there is no strictly enforced list*.
|
||||
|
||||
* Try to keep messages brief and informative
|
||||
|
||||
* Remove unnecessary commits and squash commits together when appropriate.
|
||||
* If you are not familiar with rebasing with git, check out the following resources:
|
||||
* CLI - https://thoughtbot.com/blog/git-interactive-rebase-squash-amend-rewriting-history
|
||||
* GUI (SourceTree) - https://www.atlassian.com/blog/sourcetree/interactive-rebase-sourcetree
|
||||
|
||||
* Code Styling and Formatting
|
||||
* [Consult the style guide](https://github.com/tadanokojin/pcsx2/blob/coding-guide/pcsx2/Docs/Coding_Guidelines.md)
|
||||
|
||||
* Run `clang-format` using the configuration file in the root of the repository
|
||||
* Visual Studio Setup - https://devblogs.microsoft.com/cppblog/clangformat-support-in-visual-studio-2017-15-7-preview-1/
|
||||
* IMPORTANT - if you are running `clang-format` on unrelated changes (ie. formatting an entire file), please do so in a separate commit.
|
||||
* If you cannot scope your `clang-format` to just your changes and do not want to format unrelated code. Try your best to stick with the existing formatting already established in the file in question.
|
||||
|
||||
## General Documentation And Coding Strategies
|
||||
|
||||
* [Commenting Etiquette](https://github.com/PCSX2/pcsx2/wiki/06-Commenting-Etiquette)
|
||||
|
||||
* [Coding style](https://github.com/PCSX2/pcsx2/wiki/Code-Formatting-Guidelines)
|
||||
* [More comprehensive style-guide (Currently in Draft)](https://github.com/tadanokojin/pcsx2/blob/coding-guide/pcsx2/Docs/Coding_Guidelines.md)
|
||||
|
||||
## Tasks
|
||||
|
||||
* [Issues](https://github.com/PCSX2/pcsx2/issues)
|
||||
4
.github/ISSUE_TEMPLATE/emu_bug_report.yaml
vendored
4
.github/ISSUE_TEMPLATE/emu_bug_report.yaml
vendored
@@ -66,6 +66,10 @@ body:
|
||||
|
||||
Performance issues as a result of not meeting our hardware requirements are not valid.
|
||||
|
||||
Please read our troubleshooting pages and our issue reporting guide.
|
||||
- [Troubleshooting page](https://pcsx2.net/docs/category/troubleshooting).
|
||||
- [Issue reporting guide](https://pcsx2.net/docs/troubleshooting/identify).
|
||||
|
||||
We are **not** accepting issues related to the **libretro** core. The libretro core is being maintained separately at this time
|
||||
- type: input
|
||||
id: rev
|
||||
|
||||
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -6,3 +6,6 @@
|
||||
|
||||
### Suggested Testing Steps
|
||||
<!-- If applicable, including examples you've already tested with / recommendations for how to test further is very helpful! -->
|
||||
|
||||
### Did you use AI to help find, test, or implement this issue or feature?
|
||||
<!-- Answer yes or no. If you answer yes, please provide a brief explanation how. -->
|
||||
|
||||
4
.github/workflows/linux_build_flatpak.yml
vendored
4
.github/workflows/linux_build_flatpak.yml
vendored
@@ -132,7 +132,7 @@ jobs:
|
||||
|
||||
- name: Push to Flathub (beta)
|
||||
if: ${{ inputs.publish == true && (inputs.stableBuild == false || inputs.stableBuild == 'false') }}
|
||||
uses: flatpak/flatpak-github-actions/flatpak-builder@10a3c29f0162516f0f68006be14c92f34bd4fa6c
|
||||
uses: flatpak/flatpak-github-actions/flat-manager@10a3c29f0162516f0f68006be14c92f34bd4fa6c
|
||||
with:
|
||||
flat-manager-url: https://hub.flathub.org/
|
||||
repository: beta
|
||||
@@ -141,7 +141,7 @@ jobs:
|
||||
|
||||
- name: Push to Flathub (stable)
|
||||
if: ${{ inputs.publish == true && (inputs.stableBuild == true || inputs.stableBuild == 'true') }}
|
||||
uses: flatpak/flatpak-github-actions/flatpak-builder@10a3c29f0162516f0f68006be14c92f34bd4fa6c
|
||||
uses: flatpak/flatpak-github-actions/flat-manager@10a3c29f0162516f0f68006be14c92f34bd4fa6c
|
||||
with:
|
||||
flat-manager-url: https://hub.flathub.org/
|
||||
repository: stable
|
||||
|
||||
2
.github/workflows/linux_build_qt.yml
vendored
2
.github/workflows/linux_build_qt.yml
vendored
@@ -140,9 +140,11 @@ jobs:
|
||||
-DCMAKE_CXX_COMPILER=clang++-17 \
|
||||
-DCMAKE_EXE_LINKER_FLAGS_INIT="-fuse-ld=lld" \
|
||||
-DCMAKE_MODULE_LINKER_FLAGS_INIT="-fuse-ld=lld" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DENABLE_SETCAP=OFF \
|
||||
-DDISABLE_ADVANCE_SIMD=TRUE \
|
||||
-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON \
|
||||
$ADDITIONAL_CMAKE_ARGS
|
||||
|
||||
- name: Build PCSX2
|
||||
|
||||
@@ -18,7 +18,7 @@ LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
|
||||
LIBJPEGTURBO=3.1.0
|
||||
LIBPNG=1.6.48
|
||||
LIBWEBP=1.5.0
|
||||
SDL=SDL3-3.2.12
|
||||
SDL=SDL3-3.2.14
|
||||
QT=6.9.0
|
||||
LZ4=1.10.0
|
||||
ZSTD=1.5.7
|
||||
@@ -39,7 +39,7 @@ fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.
|
||||
9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
46fd06ff37db1db64c0dc288d78a3f5efd23ad9ac41561193f983e20937ece03 libpng-$LIBPNG.tar.xz
|
||||
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
|
||||
9734f308e130c64a2b4df6bca5884c5aca577ee6c7c77ab3379474ea85e51f96 $SDL.tar.gz
|
||||
b7e7dc05011b88c69170fe18935487b2559276955e49113f8c1b6b72c9b79c1f $SDL.tar.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
c1800c2ea835801af04a05d4a32321d79a93954ee3ae2172bbeacf13d1f0598c qtbase-everywhere-src-$QT.tar.xz
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://libsdl.org/release/SDL3-3.2.12.tar.gz",
|
||||
"sha256": "9734f308e130c64a2b4df6bca5884c5aca577ee6c7c77ab3379474ea85e51f96"
|
||||
"url": "https://libsdl.org/release/SDL3-3.2.14.tar.gz",
|
||||
"sha256": "b7e7dc05011b88c69170fe18935487b2559276955e49113f8c1b6b72c9b79c1f"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
|
||||
@@ -11,10 +11,9 @@
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"type": "git",
|
||||
"url": "https://github.com/sammycage/plutovg.git",
|
||||
"tag": "v0.0.13",
|
||||
"sha256": "5e4712cf873b0c7829a4a6157763e2ad3ac49164"
|
||||
"tag": "v0.0.13"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
|
||||
@@ -12,10 +12,9 @@
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"type": "git",
|
||||
"url": "https://github.com/sammycage/plutosvg.git",
|
||||
"tag": "v0.0.6",
|
||||
"sha256": "c5388fa96feca1f1376a3d0485d5e35159452707"
|
||||
"tag": "v0.0.6"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
|
||||
@@ -11,7 +11,7 @@ merge_binaries() {
|
||||
"
|
||||
pushd "$X86DIR"
|
||||
for X86BIN in $(find . -type f \( -name '*.dylib' -o -name '*.a' -o -perm +111 \)); do
|
||||
if file "$X86DIR/$X86BIN" | grep "Mach-O " >/dev/null; then
|
||||
if file "$X86DIR/$X86BIN" | grep "Mach-O.*x86_64" >/dev/null; then
|
||||
ARMBIN="${ARMDIR}/${X86BIN}"
|
||||
echo "Merge $ARMBIN to $X86BIN..."
|
||||
lipo -create "$X86BIN" "$ARMBIN" -o "$X86BIN"
|
||||
@@ -40,7 +40,7 @@ fi
|
||||
|
||||
FREETYPE=2.13.3
|
||||
HARFBUZZ=11.2.0
|
||||
SDL=SDL3-3.2.12
|
||||
SDL=SDL3-3.2.14
|
||||
ZSTD=1.5.7
|
||||
LZ4=1.10.0
|
||||
LIBPNG=1.6.48
|
||||
@@ -79,7 +79,7 @@ CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
|
||||
cat > SHASUMS <<EOF
|
||||
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
|
||||
16c0204704f3ebeed057aba100fe7db18d71035505cb10e595ea33d346457fc8 harfbuzz-$HARFBUZZ.tar.gz
|
||||
9734f308e130c64a2b4df6bca5884c5aca577ee6c7c77ab3379474ea85e51f96 $SDL.tar.gz
|
||||
b7e7dc05011b88c69170fe18935487b2559276955e49113f8c1b6b72c9b79c1f $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
46fd06ff37db1db64c0dc288d78a3f5efd23ad9ac41561193f983e20937ece03 libpng-$LIBPNG.tar.xz
|
||||
@@ -112,11 +112,11 @@ curl -C - -L \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
|
||||
-O "https://github.com/KhronosGroup/MoltenVK/archive/refs/tags/v$MOLTENVK.tar.gz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
|
||||
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
|
||||
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
@@ -213,8 +213,11 @@ echo "Installing libjpegturbo..."
|
||||
rm -fr "libjpeg-turbo-$LIBJPEGTURBO"
|
||||
tar xf "libjpeg-turbo-$LIBJPEGTURBO.tar.gz"
|
||||
cd "libjpeg-turbo-$LIBJPEGTURBO"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_ARM64" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build-arm64
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_X64" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build
|
||||
make -C build "-j$NPROCS"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_ARM64" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build-arm64
|
||||
make -C build-arm64 "-j$NPROCS"
|
||||
merge_binaries $(realpath build) $(realpath build-arm64)
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
@@ -380,7 +383,7 @@ echo "Building PlutoVG..."
|
||||
rm -fr "plutovg-$PLUTOVG"
|
||||
tar xf "plutovg-$PLUTOVG.tar.gz"
|
||||
cd "plutovg-$PLUTOVG"
|
||||
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
@@ -389,7 +392,7 @@ echo "Building PlutoSVG..."
|
||||
rm -fr "plutosvg-$PLUTOSVG"
|
||||
tar xf "plutosvg-$PLUTOSVG.tar.gz"
|
||||
cd "plutosvg-$PLUTOSVG"
|
||||
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -DPLUTOSVG_ENABLE_FREETYPE=ON -DPLUTOSVG_BUILD_EXAMPLES=OFF -B build
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DBUILD_SHARED_LIBS=ON -DPLUTOSVG_ENABLE_FREETYPE=ON -DPLUTOSVG_BUILD_EXAMPLES=OFF -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
@@ -22,7 +22,7 @@ fi
|
||||
|
||||
FREETYPE=2.13.3
|
||||
HARFBUZZ=11.2.0
|
||||
SDL=SDL3-3.2.12
|
||||
SDL=SDL3-3.2.14
|
||||
ZSTD=1.5.7
|
||||
LZ4=1.10.0
|
||||
LIBPNG=1.6.48
|
||||
@@ -59,7 +59,7 @@ CMAKE_COMMON=(
|
||||
cat > SHASUMS <<EOF
|
||||
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
|
||||
16c0204704f3ebeed057aba100fe7db18d71035505cb10e595ea33d346457fc8 harfbuzz-$HARFBUZZ.tar.gz
|
||||
9734f308e130c64a2b4df6bca5884c5aca577ee6c7c77ab3379474ea85e51f96 $SDL.tar.gz
|
||||
b7e7dc05011b88c69170fe18935487b2559276955e49113f8c1b6b72c9b79c1f $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
46fd06ff37db1db64c0dc288d78a3f5efd23ad9ac41561193f983e20937ece03 libpng-$LIBPNG.tar.xz
|
||||
|
||||
@@ -66,7 +66,7 @@ const embed = new MessageEmbed()
|
||||
.setDescription("To download the latest or previous builds, [visit the official downloads page](https://pcsx2.net/downloads/).")
|
||||
.addFields(
|
||||
{ name: 'Version', value: releaseInfo.tag_name, inline: true },
|
||||
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true },
|
||||
{ name: 'Installation Steps', value: '[See Here](https://pcsx2.net/docs/category/setup)', inline: true },
|
||||
{ name: 'Included Changes', value: releaseInfo.body, inline: false }
|
||||
);
|
||||
console.log(embed);
|
||||
|
||||
@@ -46,7 +46,7 @@ set FREETYPE=2.13.3
|
||||
set HARFBUZZ=11.2.0
|
||||
set LIBJPEGTURBO=3.1.0
|
||||
set LIBPNG=1648
|
||||
set SDL=SDL3-3.2.12
|
||||
set SDL=SDL3-3.2.14
|
||||
set QT=6.9.0
|
||||
set QTMINOR=6.9
|
||||
set LZ4=1.10.0
|
||||
@@ -68,7 +68,7 @@ call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuz
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1648.zip 2e5f080360f77376eb2bfa9e2ed773b9c7728159aba47b638ad53ca839379040 || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" ebf1efd71527afbca6bdf2b0310caf726d00cc102c0e59ac86c1f8cd201f9593 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 46a17d3ea71fe2580a7f43ca7da286c5b9106dd761e2fd5533bb113e5d86b633 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 513df15a6365a40f6230ec9463ad8c71b824e181d4b661dac9707e103b24ae0c || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" d428fd17a0d3f92c48a30f1d23806bf20352fbce2e80e5bbee27fa80576480ee || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 54bf06afeb67035f1c6afcd00beec755c0d776626b4cce9ab56992a55215ba69 || goto error
|
||||
@@ -246,12 +246,21 @@ cmake --build . --parallel || goto error
|
||||
ninja install || goto error
|
||||
cd ..\.. || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
set KDDOCKWIDGETSBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES="Release;Debug" -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=Release -DCMAKE_DEFAULT_CONFIGS=all -G "Ninja Multi-Config"
|
||||
) else (
|
||||
rem kddockwidgets slightly changes the name of the dll depending on if CMAKE_BUILD_TYPE or CMAKE_CONFIGURATION_TYPES is used
|
||||
rem The dll name being kddockwidgets-qt62.dll or kddockwidgets-qt62.dll respectively
|
||||
rem Always use CMAKE_CONFIGURATION_TYPES to give consistant naming
|
||||
set KDDOCKWIDGETSBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES=Release -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=Release -DCMAKE_DEFAULT_CONFIGS=Release -G "Ninja Multi-Config"
|
||||
)
|
||||
|
||||
echo "Building KDDockWidgets..."
|
||||
rmdir /S /Q "KDDockWidgets-%KDDOCKWIDGETS%"
|
||||
%SEVENZIP% x "KDDockWidgets-%KDDOCKWIDGETS%.zip" || goto error
|
||||
cd "KDDockWidgets-%KDDOCKWIDGETS%" || goto error
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\..\common\kddockwidgets-dodgy-include.patch" || goto error
|
||||
cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build -G Ninja || goto error
|
||||
cmake -B build %ARM64TOOLCHAIN% -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets %KDDOCKWIDGETSBUILDSPEC% || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
@@ -44,7 +44,7 @@ set FREETYPE=2.13.3
|
||||
set HARFBUZZ=11.2.0
|
||||
set LIBJPEGTURBO=3.1.0
|
||||
set LIBPNG=1648
|
||||
set SDL=SDL3-3.2.12
|
||||
set SDL=SDL3-3.2.14
|
||||
set QT=6.9.0
|
||||
set QTMINOR=6.9
|
||||
set LZ4=1.10.0
|
||||
@@ -66,7 +66,7 @@ call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuz
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1648.zip 2e5f080360f77376eb2bfa9e2ed773b9c7728159aba47b638ad53ca839379040 || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" ebf1efd71527afbca6bdf2b0310caf726d00cc102c0e59ac86c1f8cd201f9593 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 46a17d3ea71fe2580a7f43ca7da286c5b9106dd761e2fd5533bb113e5d86b633 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 513df15a6365a40f6230ec9463ad8c71b824e181d4b661dac9707e103b24ae0c || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" d428fd17a0d3f92c48a30f1d23806bf20352fbce2e80e5bbee27fa80576480ee || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 54bf06afeb67035f1c6afcd00beec755c0d776626b4cce9ab56992a55215ba69 || goto error
|
||||
@@ -250,12 +250,21 @@ cmake --build . --parallel || goto error
|
||||
ninja install || goto error
|
||||
cd ..\.. || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
set KDDOCKWIDGETSBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES="Release;Debug" -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=Release -DCMAKE_DEFAULT_CONFIGS=all -G "Ninja Multi-Config"
|
||||
) else (
|
||||
rem kddockwidgets slightly changes the name of the dll depending on if CMAKE_BUILD_TYPE or CMAKE_CONFIGURATION_TYPES is used
|
||||
rem The dll name being kddockwidgets-qt62.dll or kddockwidgets-qt62.dll respectively
|
||||
rem Always use CMAKE_CONFIGURATION_TYPES to give consistant naming
|
||||
set KDDOCKWIDGETSBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES=Release -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=Release -DCMAKE_DEFAULT_CONFIGS=Release -G "Ninja Multi-Config"
|
||||
)
|
||||
|
||||
echo "Building KDDockWidgets..."
|
||||
rmdir /S /Q "KDDockWidgets-%KDDOCKWIDGETS%"
|
||||
%SEVENZIP% x "KDDockWidgets-%KDDOCKWIDGETS%.zip" || goto error
|
||||
cd "KDDockWidgets-%KDDOCKWIDGETS%" || goto error
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\..\common\kddockwidgets-dodgy-include.patch" || goto error
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build -G Ninja || goto error
|
||||
cmake -B build -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets %KDDOCKWIDGETSBUILDSPEC% || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
2
.github/workflows/triage_pr.yml
vendored
2
.github/workflows/triage_pr.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
pr-message: |-
|
||||
## Thank you for submitting a contribution to PCSX2
|
||||
|
||||
As this is your first pull request, [please be aware of the contributing guidelines](https://github.com/PCSX2/pcsx2/blob/master/.github/CONTRIBUTING.md).
|
||||
As this is your first pull request, [please be aware of the contributing guidelines](https://pcsx2.net/docs/contributing/).
|
||||
|
||||
Additionally, as per recent changes in GitHub Actions, your pull request will need to be approved by a maintainer before GitHub Actions can run against it. [You can find more information about this change here.](https://github.blog/2021-04-22-github-actions-update-helping-maintainers-combat-bad-actors/)
|
||||
|
||||
|
||||
@@ -62,10 +62,12 @@ endif()
|
||||
|
||||
# gsrunner
|
||||
if(ENABLE_GSRUNNER)
|
||||
if (NOT WIN32)
|
||||
message(WARNING "GSRunner is only supported on Windows and may not build on your system")
|
||||
if (NOT WIN32 AND NOT APPLE)
|
||||
message(WARNING "GSRunner is only supported on Windows and macOS and may not build on your system")
|
||||
endif()
|
||||
add_subdirectory(pcsx2-gsrunner)
|
||||
else()
|
||||
add_subdirectory(pcsx2-gsrunner EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@@ -24,4 +24,4 @@ Please note that a BIOS dump from a legitimately-owned PS2 console is required t
|
||||
|
||||
PCSX2 supports translation into other languages using [Crowdin](https://crowdin.com/project/pcsx2-emulator).
|
||||
|
||||
See the [Contributing Guidelines](https://github.com/PCSX2/pcsx2/blob/master/.github/CONTRIBUTING.md) or visit the [GitHub Wiki](https://github.com/PCSX2/pcsx2/wiki) for more info on how to contribute.
|
||||
See the [Contribution Guide](https://pcsx2.net/docs/contributing/) for more info on how to contribute.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<h1>Third-Party Licenses</h1>
|
||||
|
||||
<h2>Index</h2>
|
||||
<h2>Table of Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#pcsx2">PCSX2 - PS2 Emulator for PCs</a></li>
|
||||
@@ -37,6 +37,7 @@
|
||||
<li><a href="#llvm">LLVM</a></li>
|
||||
<li><a href="#lz4">LZ4</a></li>
|
||||
<li><a href="#lzmasdk">LZMA SDK</a></li>
|
||||
<li><a href="#notosans">Noto Sans</a></li>
|
||||
<li><a href="#pixevents">PixEvents</a></li>
|
||||
<li><a href="#plutosvg">PlutoSVG</a></li>
|
||||
<li><a href="#plutovg">PlutoVG</a></li>
|
||||
@@ -45,6 +46,7 @@
|
||||
<li><a href="#rapidjson">RapidJSON</a></li>
|
||||
<li><a href="#rcheevos">rcheevos</a></li>
|
||||
<li><a href="#remixicon">Remix Icon</a></li>
|
||||
<li><a href="#roboto">Roboto</a></li>
|
||||
<li><a href="#shaderc">Shaderc</a></li>
|
||||
<li><a href="#simpleini">simpleini</a></li>
|
||||
<li><a href="#soundtouch">SoundTouch audio processing library</a></li>
|
||||
@@ -3636,6 +3638,105 @@ for any purpose, commercial or non-commercial, and by any means.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div id="notosans">
|
||||
<h3>Noto Sans - <a href="https://notofonts.github.io/">https://notofonts.github.io/</a></h3>
|
||||
<pre>
|
||||
Copyright 2022 The Noto Project Authors (https://github.com/notofonts/hebrew)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://openfontlicense.org
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div id="pixevents">
|
||||
<h3>PixEvents - <a href="https://github.com/microsoft/PixEvents">https://github.com/microsoft/PixEvents</a></h3>
|
||||
<pre>
|
||||
@@ -4149,6 +4250,105 @@ SOFTWARE.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div id="roboto">
|
||||
<h3>Roboto - <a href="https://fonts.google.com/specimen/Roboto">https://fonts.google.com/specimen/Roboto</a></h3>
|
||||
<pre>
|
||||
Copyright 2011 The Roboto Project Authors (https://github.com/googlefonts/roboto-classic)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://openfontlicense.org
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div id="shaderc">
|
||||
<h3>Shaderc - <a href="https://github.com/google/shaderc">https://github.com/google/shaderc</a></h3>
|
||||
<pre>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -154,6 +154,7 @@
|
||||
03000000120c0000f10e000000000000,Brook PS2 Adapter,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000120c0000310c000000000000,Brook Super Converter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
|
||||
03000000d81d00000b00000000000000,Buffalo BSGP1601 Series,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,
|
||||
030000005a1c00002400000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
|
||||
030000005b1c00002400000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
|
||||
030000005b1c00002500000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
|
||||
030000006d04000042c2000000000000,ChillStream,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||
@@ -336,6 +337,7 @@
|
||||
03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows,
|
||||
03000000242e00006a48000000000000,Hyperkin RetroN Sq,a:b3,b:b7,back:b5,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b0,rightshoulder:b1,start:b4,x:b2,y:b6,platform:Windows,
|
||||
03000000242f00000a20000000000000,Hyperkin Scout,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
|
||||
03000000242e00000a20000000000000,Hyperkin Scout Premium SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
|
||||
03000000242e00006a38000000000000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Windows,
|
||||
03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows,
|
||||
03000000d81d00000f00000000000000,iBuffalo BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||
@@ -418,7 +420,7 @@
|
||||
03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
|
||||
0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||
03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000242e0000f500000000000000,Mayflash N64 Adapter,a:b2,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows,
|
||||
03000000242f0000f500000000000000,Mayflash N64 Adapter,a:b2,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows,
|
||||
03000000242f0000f400000000000000,Mayflash N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows,
|
||||
03000000790000007918000000000000,Mayflash N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,righttrigger:b7,rightx:a3,righty:a2,start:b8,platform:Windows,
|
||||
030000008f0e00001030000000000000,Mayflash Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b7,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
|
||||
@@ -484,7 +486,7 @@
|
||||
030000008916000000fd000000000000,Onza TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||
03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
||||
0300000009120000072f000000000000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:-a2,leftx:a0,lefty:a1,righttrigger:-a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||
0300000009120000072f000000000000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:-a2,leftx:a0,lefty:a1,righttrigger:-a5,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,
|
||||
03000000120c0000f60e000000000000,P4 Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||
@@ -691,6 +693,7 @@
|
||||
03000000317300000100000000000000,Sony DualShock 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000666600006706000000000000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,
|
||||
03000000e30500009605000000000000,Sony PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||
03000000fe1400002a23000000000000,Sony PlayStation Adapter,a:b0,b:b1,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,x:b2,y:b3,platform:Windows,
|
||||
030000004c050000da0c000000000000,Sony PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
|
||||
03000000632500002306000000000000,Sony PlayStation Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000f0250000c183000000000000,Sony PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
@@ -1008,6 +1011,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000550900001472000025050000,NVIDIA Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,
|
||||
030000004b120000014d000000010000,Nyko Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||
0300000009120000072f000000010000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a2,leftx:a0,lefty:a1,righttrigger:a5,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
030000006f0e00000901000002010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||
03000000d620000011a7000000020000,PowerA Core Plus Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||
@@ -1100,6 +1104,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,
|
||||
050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,
|
||||
030000005e0400008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4~,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
030000006f0e00000104000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000c6240000045d000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
@@ -1278,7 +1283,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000006f0e00008401000011010000,Faceoff Deluxe Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000006f0e00008101000011010000,Faceoff Deluxe Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000006f0e00008001000011010000,Faceoff Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03005036852100000201000010010000,Final Fantasy XIV Online Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000852100000201000010010000,FF GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
05000000b40400001224000001010000,Flydigi APEX 4,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b20,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
03000000b40400001224000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
@@ -1290,6 +1295,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000558500001b06000010010000,GameSir G4 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
05000000ac0500002d0200001b010000,GameSir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
03000000ac0500007a05000011010000,GameSir G5,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
03000000373500009710000001020000,GameSir Kaleid Flux,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000ac0500001a06000011010000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
@@ -1600,6 +1606,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
0300132d9b2800006500000001010000,Raphnet GameCube Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
||||
030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
||||
030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
||||
030000009b2800006100000001010000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Linux,
|
||||
030000009b2800008000000020020000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
|
||||
030000009b2800008000000001010000,Raphnet Wii Classic Adapter V3,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
|
||||
03000000f8270000bf0b000011010000,Razer Kishi,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
@@ -1765,6 +1772,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
050000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
050000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
060000005e040000dd02000003020000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
@@ -1795,6 +1803,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
060000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
060000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
050000005e040000130b000022050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e040000200b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e040000220b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
|
||||
1
bin/resources/icons/AppBanner.svg
Normal file
1
bin/resources/icons/AppBanner.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2675 329.6"><g id="vectorized_by_maxihplay"><path id="_2" d="M2181.5,5.7h438.1c27.8,0,50.4,22.6,50.4,50.4v92.5c0,27.8-22.6,50.4-50.4,50.4h-309.5v46.5h359.9v78.6h-488.5v-145.3c0-27.8,22.6-50.4,50.4-50.4h309.5v-50.8h-315l-44.9-71.9h0Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="10" stroke-width="10"/><g id="X"><polygon points="1619.8 5.7 1769.1 5.7 1867.5 102 1961.6 5.9 2115.8 5.9 2115.8 77.2 2039.6 77.2 1954.7 164 2037.1 245.4 2115.8 245.4 2115.8 324.1 1968.4 324.1 1867.8 224 1767.8 324 1619.8 324 1619.8 244.8 1699.3 244.8 1779.3 165.8 1692.8 77.2 1619.8 77.2 1619.8 5.7" fill="#3caeff" stroke-width="0"/><path d="M1623.2,8.7l17.5,17.5v30.1h57c3.1,0,6,1.2,8.2,3.4l93.8,93.4c7.3,7.3,7.2,19.1-.1,26.3l-86,84.2c-3.1,3-7.3,4.8-11.7,4.8h-61.2l-18.5-21.5,77-2.1,80.1-79.1-86.5-88.5h-73V5.7l3.4,3h0Z" fill="#279ff5" stroke-width="0"/><path d="M1623.9,9.7l16.8,16.5h121.8l93.4,93.4c6.7,6.7,17.6,6.7,24.3,0l92.6-92.5h121.8l19.2-19.2-152.1-2-94.1,96.1-98.3-96.3-145.4,4h0Z" fill="#50b6ff" stroke-width="0"/><path d="M2114.7,247.9l-20.2,20.6h-62.1c-3.8,0-7.4-1.5-10-4.1l-85.5-85.5c-7.7-7.6-7.7-20.1,0-27.7l90-90c3.2-3.2,7.5-5,12-5h55.5v-29l20.3-19.9,1.2,70-76.1,1.4-85,85.5,82.4,81.3h78.8l-1.3,2.4Z" fill="#34a2f2" stroke-width="0"/><path d="M1619.8,323.5l1.7-77.8,19.2,22.7v34h115.6c1.1,0,2.1-.4,2.8-1.2l95.2-95.2c7.8-7.8,20.4-7.7,28.1.1l92.9,94.7c.7.7,1.7,1.2,2.8,1.2h116.9l-.5-33.5,22-24.5-.6,80.1h-147.4l-100.6-100.1-100.1,100.1-148-.6h0Z" fill="#43b9f2" stroke-width="0"/><polygon points="1619.8 5.7 1769.1 5.7 1867.5 102 1961.6 5.9 2115.8 5.9 2115.8 77.2 2039.6 77.2 1954.7 164 2037.1 245.4 2115.8 245.4 2115.8 324.1 1968.4 324.1 1867.8 224 1767.8 324 1619.8 324 1619.8 244.8 1699.3 244.8 1779.3 165.8 1692.8 77.2 1619.8 77.2 1619.8 5.7" fill="none" stroke="#5d73cb" stroke-miterlimit="10" stroke-width="11"/></g><path id="S" d="M1554.7,5.7h-434c-27.8,0-50.4,22.6-50.4,50.4v95.9c0,27.9,22.6,50.4,50.4,50.4h302.8v43.3h-353.2v78.4h434c27.8,0,50.4-22.6,50.4-50.4v-97.6c0-27.9-22.6-50.4-50.4-50.4h-303.9v-48.1h306.3l48-71.9Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="10" stroke-width="10"/><path id="C" d="M1008.1,5.1h-395.5c-27.8,0-50.4,22.6-50.4,50.4v217.9c0,28,22.7,50.8,50.8,50.8h385.2v-79.2h-304.3V78.2h263.3l50.9-73.1Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="10" stroke-width="10"/><path id="P" d="M5,55.5C5,27.6,27.6,5,55.5,5h390.3c27.7,0,50.2,22.5,50.2,50.2v139.4c0,27.9-22.6,50.4-50.5,50.4l-284-.6,64.2-71.9h139.8v-95h-225.4v246.5H5V55.5Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="10" stroke-width="10"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -313,6 +313,127 @@ float ps_convert_rgb5a1_float16_biln(PS_INPUT input) : SV_Depth
|
||||
SAMPLE_RGBA_DEPTH_BILN(rgb5a1_to_depth16);
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_convert_rgb5a1_8i(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
// Convert a RGB5A1 texture into a 8 bits packed texture
|
||||
// Input column: 16x2 RGB5A1 pixels
|
||||
// 0: 16 RGBA
|
||||
// 1: 16 RGBA
|
||||
// Output column: 16x4 Index pixels
|
||||
// 0: 16 R5G2
|
||||
// 1: 16 R5G2
|
||||
// 2: 16 G2B5A1
|
||||
// 3: 16 G2B5A1
|
||||
uint2 pos = uint2(input.p.xy);
|
||||
|
||||
// Collapse separate R G B A areas into their base pixel
|
||||
uint2 column = (pos & ~uint2(0u, 3u)) / uint2(1,2);
|
||||
uint2 subcolumn = (pos & uint2(0u, 1u));
|
||||
column.x -= (column.x / 128) * 64;
|
||||
column.y += (column.y / 32) * 32;
|
||||
|
||||
uint PSM = uint(DOFFSET);
|
||||
|
||||
// Deal with swizzling differences
|
||||
if ((PSM & 0x8) != 0) // PSMCT16S
|
||||
{
|
||||
if ((pos.x & 32) != 0)
|
||||
{
|
||||
column.y += 32; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x &= ~32;
|
||||
}
|
||||
|
||||
if ((pos.x & 64) != 0)
|
||||
{
|
||||
column.x -= 32;
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16S - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 16;
|
||||
}
|
||||
}
|
||||
else // PSMCT16
|
||||
{
|
||||
if ((pos.y & 32) != 0)
|
||||
{
|
||||
column.y -= 16;
|
||||
column.x += 32;
|
||||
}
|
||||
|
||||
if ((pos.x & 96) != 0)
|
||||
{
|
||||
uint multi = (pos.x & 96) / 32;
|
||||
column.y += 16 * multi; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x -= (pos.x & 96);
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16 - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 32;
|
||||
}
|
||||
}
|
||||
|
||||
uint2 coord = column | subcolumn;
|
||||
|
||||
// Compensate for potentially differing page pitch.
|
||||
uint SBW = uint(EMODA);
|
||||
uint DBW = uint(EMODC);
|
||||
uint2 block_xy = coord / uint2(64,64);
|
||||
uint block_num = (block_xy.y * (DBW / 128)) + block_xy.x;
|
||||
uint2 block_offset = uint2((block_num % (SBW / 64)) * 64, (block_num / (SBW / 64)) * 64);
|
||||
coord = (coord % uint2(64, 64)) + block_offset;
|
||||
|
||||
// Apply offset to cols 1 and 2
|
||||
uint is_col23 = pos.y & 4u;
|
||||
uint is_col13 = pos.y & 2u;
|
||||
uint is_col12 = is_col23 ^ (is_col13 << 1);
|
||||
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
|
||||
|
||||
float ScaleFactor = BGColor.x;
|
||||
if (floor(ScaleFactor) != ScaleFactor)
|
||||
coord = uint2(float2(coord) * ScaleFactor);
|
||||
else
|
||||
coord *= uint(ScaleFactor);
|
||||
|
||||
float4 pixel = Texture.Load(int3(int2(coord), 0));
|
||||
uint4 denorm_c = (uint4)(pixel * 255.5f);
|
||||
if ((pos.y & 2u) == 0u)
|
||||
{
|
||||
uint red = (denorm_c.r >> 3) & 0x1Fu;
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
float sel0 = (float)(((green << 5) | red) & 0xFF) / 255.0f;
|
||||
|
||||
output.c = (float4)(sel0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
uint blue = (denorm_c.b >> 3) & 0x1Fu;
|
||||
uint alpha = denorm_c.a & 0x80u;
|
||||
float sel0 = (float)((alpha | (blue << 2) | (green >> 3)) & 0xFF) / 255.0f;
|
||||
|
||||
output.c = (float4)(sel0);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_convert_rgba_8i(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -397,7 +397,11 @@ float4 fetch_raw_color(int2 xy)
|
||||
|
||||
float4 fetch_c(int2 uv)
|
||||
{
|
||||
#if PS_TEX_IS_FB == 1
|
||||
return RtTexture.Load(int3(uv, 0));
|
||||
#else
|
||||
return Texture.Load(int3(uv, 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -237,9 +237,131 @@ void ps_convert_rgb5a1_float16_biln()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_convert_rgb5a1_8i
|
||||
uniform uint SBW;
|
||||
uniform uint DBW;
|
||||
uniform uint PSM;
|
||||
uniform float ScaleFactor;
|
||||
|
||||
void ps_convert_rgb5a1_8i()
|
||||
{
|
||||
// Convert a RGB5A1 texture into a 8 bits packed texture
|
||||
// Input column: 16x2 RGB5A1 pixels
|
||||
// 0: 16 RGBA
|
||||
// 1: 16 RGBA
|
||||
// Output column: 16x4 Index pixels
|
||||
// 0: 16 R5G2
|
||||
// 1: 16 R5G2
|
||||
// 2: 16 G2B5A1
|
||||
// 3: 16 G2B5A1
|
||||
|
||||
uvec2 pos = uvec2(gl_FragCoord.xy);
|
||||
|
||||
// Collapse separate R G B A areas into their base pixel
|
||||
uvec2 column = (pos & ~uvec2(0u, 3u)) / uvec2(1,2);
|
||||
uvec2 subcolumn = (pos & uvec2(0u, 1u));
|
||||
column.x -= (column.x / 128) * 64;
|
||||
column.y += (column.y / 32) * 32;
|
||||
|
||||
// Deal with swizzling differences
|
||||
if ((PSM & 0x8) != 0) // PSMCT16S
|
||||
{
|
||||
if ((pos.x & 32) != 0)
|
||||
{
|
||||
column.y += 32; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x &= ~32;
|
||||
}
|
||||
|
||||
if ((pos.x & 64) != 0)
|
||||
{
|
||||
column.x -= 32;
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16S - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 16;
|
||||
}
|
||||
}
|
||||
else // PSMCT16
|
||||
{
|
||||
if ((pos.y & 32) != 0)
|
||||
{
|
||||
column.y -= 16;
|
||||
column.x += 32;
|
||||
}
|
||||
|
||||
if ((pos.x & 96) != 0)
|
||||
{
|
||||
uint multi = (pos.x & 96) / 32;
|
||||
column.y += 16 * multi; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x -= (pos.x & 96);
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16 - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 32;
|
||||
}
|
||||
}
|
||||
uvec2 coord = column | subcolumn;
|
||||
|
||||
// Compensate for potentially differing page pitch.
|
||||
uvec2 block_xy = coord / uvec2(64u, 64u);
|
||||
uint block_num = (block_xy.y * (DBW / 128u)) + block_xy.x;
|
||||
uvec2 block_offset = uvec2((block_num % (SBW / 64u)) * 64u, (block_num / (SBW / 64u)) * 64u);
|
||||
coord = (coord % uvec2(64u, 64u)) + block_offset;
|
||||
|
||||
// Apply offset to cols 1 and 2
|
||||
uint is_col23 = pos.y & 4u;
|
||||
uint is_col13 = pos.y & 2u;
|
||||
uint is_col12 = is_col23 ^ (is_col13 << 1);
|
||||
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
|
||||
|
||||
if (floor(ScaleFactor) != ScaleFactor)
|
||||
coord = uvec2(vec2(coord) * ScaleFactor);
|
||||
else
|
||||
coord *= uvec2(ScaleFactor);
|
||||
|
||||
vec4 pixel = texelFetch(TextureSampler, ivec2(coord), 0);
|
||||
|
||||
uvec4 denorm_c = uvec4(pixel * 255.5f);
|
||||
if ((pos.y & 2u) == 0u)
|
||||
{
|
||||
uint red = (denorm_c.r >> 3) & 0x1Fu;
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
float sel0 = float(((green << 5) | red) & 0xFF) / 255.0f;
|
||||
|
||||
SV_Target0 = vec4(sel0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
uint blue = (denorm_c.b >> 3) & 0x1Fu;
|
||||
uint alpha = denorm_c.a & 0x80u;
|
||||
float sel0 = float((alpha | (blue << 2) | (green >> 3)) & 0xFF) / 255.0f;
|
||||
|
||||
SV_Target0 = vec4(sel0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_convert_rgba_8i
|
||||
uniform uint SBW;
|
||||
uniform uint DBW;
|
||||
uniform uint PSM;
|
||||
uniform float ScaleFactor;
|
||||
|
||||
void ps_convert_rgba_8i()
|
||||
|
||||
@@ -330,7 +330,11 @@ vec4 fetch_raw_color()
|
||||
|
||||
vec4 fetch_c(ivec2 uv)
|
||||
{
|
||||
#if PS_TEX_IS_FB == 1
|
||||
return sample_from_rt();
|
||||
#else
|
||||
return texelFetch(TextureSampler, ivec2(uv), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -307,12 +307,138 @@ void ps_convert_rgb5a1_float16_biln()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_convert_rgb5a1_8i
|
||||
layout(push_constant) uniform cb10
|
||||
{
|
||||
uint SBW;
|
||||
uint DBW;
|
||||
uint PSM;
|
||||
float cb_pad1;
|
||||
float ScaleFactor;
|
||||
vec3 cb_pad2;
|
||||
};
|
||||
|
||||
void ps_convert_rgb5a1_8i()
|
||||
{
|
||||
// Convert a RGB5A1 texture into a 8 bits packed texture
|
||||
// Input column: 16x2 RGB5A1 pixels
|
||||
// 0: 16 RGBA
|
||||
// 1: 16 RGBA
|
||||
// Output column: 16x4 Index pixels
|
||||
// 0: 16 R5G2
|
||||
// 1: 16 R5G2
|
||||
// 2: 16 G2B5A1
|
||||
// 3: 16 G2B5A1
|
||||
|
||||
uvec2 pos = uvec2(gl_FragCoord.xy);
|
||||
|
||||
// Collapse separate R G B A areas into their base pixel
|
||||
uvec2 column = (pos & ~uvec2(0u, 3u)) / uvec2(1,2);
|
||||
uvec2 subcolumn = (pos & uvec2(0u, 1u));
|
||||
column.x -= (column.x / 128) * 64;
|
||||
column.y += (column.y / 32) * 32;
|
||||
|
||||
// Deal with swizzling differences
|
||||
if ((PSM & 0x8) != 0) // PSMCT16S
|
||||
{
|
||||
if ((pos.x & 32) != 0)
|
||||
{
|
||||
column.y += 32; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x &= ~32;
|
||||
}
|
||||
|
||||
if ((pos.x & 64) != 0)
|
||||
{
|
||||
column.x -= 32;
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16S - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 16;
|
||||
}
|
||||
}
|
||||
else // PSMCT16
|
||||
{
|
||||
if ((pos.y & 32) != 0)
|
||||
{
|
||||
column.y -= 16;
|
||||
column.x += 32;
|
||||
}
|
||||
|
||||
if ((pos.x & 96) != 0)
|
||||
{
|
||||
uint multi = (pos.x & 96) / 32;
|
||||
column.y += 16 * multi; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x -= (pos.x & 96);
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16 - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 32;
|
||||
}
|
||||
}
|
||||
uvec2 coord = column | subcolumn;
|
||||
|
||||
// Compensate for potentially differing page pitch.
|
||||
uvec2 block_xy = coord / uvec2(64u, 64u);
|
||||
uint block_num = (block_xy.y * (DBW / 128u)) + block_xy.x;
|
||||
uvec2 block_offset = uvec2((block_num % (SBW / 64u)) * 64u, (block_num / (SBW / 64u)) * 64u);
|
||||
coord = (coord % uvec2(64u, 64u)) + block_offset;
|
||||
|
||||
// Apply offset to cols 1 and 2
|
||||
uint is_col23 = pos.y & 4u;
|
||||
uint is_col13 = pos.y & 2u;
|
||||
uint is_col12 = is_col23 ^ (is_col13 << 1);
|
||||
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
|
||||
|
||||
if (floor(ScaleFactor) != ScaleFactor)
|
||||
coord = uvec2(vec2(coord) * ScaleFactor);
|
||||
else
|
||||
coord *= uvec2(ScaleFactor);
|
||||
|
||||
vec4 pixel = texelFetch(samp0, ivec2(coord), 0);
|
||||
uvec4 denorm_c = uvec4(pixel * 255.5f);
|
||||
if ((pos.y & 2u) == 0u)
|
||||
{
|
||||
uint red = (denorm_c.r >> 3) & 0x1Fu;
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
float sel0 = float(((green << 5) | red) & 0xFF) / 255.0f;
|
||||
|
||||
o_col0 = vec4(sel0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
uint blue = (denorm_c.b >> 3) & 0x1Fu;
|
||||
uint alpha = denorm_c.a & 0x80u;
|
||||
float sel0 = float((alpha | (blue << 2) | (green >> 3)) & 0xFF) / 255.0f;
|
||||
|
||||
o_col0 = vec4(sel0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_convert_rgba_8i
|
||||
layout(push_constant) uniform cb10
|
||||
{
|
||||
uint SBW;
|
||||
uint DBW;
|
||||
uvec2 cb_pad1;
|
||||
uint PSM;
|
||||
float cb_pad1;
|
||||
float ScaleFactor;
|
||||
vec3 cb_pad2;
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ include(GNUInstallDirs)
|
||||
# Misc option
|
||||
#-------------------------------------------------------------------------------
|
||||
option(ENABLE_TESTS "Enables building the unit tests" ON)
|
||||
option(ENABLE_GSRUNNER "Enables building the GSRunner" OFF)
|
||||
option(ENABLE_GSRUNNER "Enables building the GSRunner by default. It can still be built with `make pcsx2-gsrunner` otherwise." OFF)
|
||||
option(LTO_PCSX2_CORE "Enable LTO/IPO/LTCG on the subset of pcsx2 that benefits most from it but not anything else")
|
||||
option(USE_VTUNE "Plug VTUNE to profile GS JIT.")
|
||||
option(PACKAGE_MODE "Use this option to ease packaging of PCSX2 (developer/distribution option)")
|
||||
@@ -64,10 +64,13 @@ set(CMAKE_SHARED_LINKER_FLAGS_DEVEL "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}
|
||||
CACHE STRING "Flags used for linking shared libraries during development builds" FORCE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEVEL "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}"
|
||||
CACHE STRING "Flags used for linking executables during development builds" FORCE)
|
||||
# Exclude Debug from the configurations we can import from
|
||||
set(CMAKE_MAP_IMPORTED_CONFIG_DEVEL "RelWithDebInfo" "Release" "MinSizeRel" "None" "NoConfig" ""
|
||||
CACHE STRING "Configurations used when importing packages for development builds" FORCE)
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
list(INSERT CMAKE_CONFIGURATION_TYPES 0 Devel)
|
||||
endif()
|
||||
mark_as_advanced(CMAKE_C_FLAGS_DEVEL CMAKE_CXX_FLAGS_DEVEL CMAKE_LINKER_FLAGS_DEVEL CMAKE_SHARED_LINKER_FLAGS_DEVEL CMAKE_EXE_LINKER_FLAGS_DEVEL)
|
||||
mark_as_advanced(CMAKE_C_FLAGS_DEVEL CMAKE_CXX_FLAGS_DEVEL CMAKE_LINKER_FLAGS_DEVEL CMAKE_SHARED_LINKER_FLAGS_DEVEL CMAKE_EXE_LINKER_FLAGS_DEVEL CMAKE_MAP_IMPORTED_CONFIG_DEVEL)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Select the architecture
|
||||
|
||||
@@ -120,7 +120,7 @@ add_subdirectory(3rdparty/demangler EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(3rdparty/ccc EXCLUDE_FROM_ALL)
|
||||
|
||||
# The docking system for the debugger.
|
||||
find_package(KDDockWidgets-qt6 REQUIRED)
|
||||
find_package(KDDockWidgets-qt6 2.0.0 REQUIRED)
|
||||
# Add an extra include path to work around a broken include directive.
|
||||
# TODO: Remove this the next time we update KDDockWidgets.
|
||||
get_target_property(KDDOCKWIDGETS_INCLUDE_DIRECTORY KDAB::kddockwidgets INTERFACE_INCLUDE_DIRECTORIES)
|
||||
|
||||
@@ -31,6 +31,19 @@ namespace CocoaTools
|
||||
bool DelayedLaunch(std::string_view file);
|
||||
/// Open a Finder window to the given URL
|
||||
bool ShowInFinder(std::string_view file);
|
||||
/// Get the path to the resources directory of the current application
|
||||
std::optional<std::string> GetResourcePath();
|
||||
|
||||
/// Create a window
|
||||
void* CreateWindow(std::string_view title, uint32_t width, uint32_t height);
|
||||
/// Destroy a window
|
||||
void DestroyWindow(void* window);
|
||||
/// Make a WindowInfo from the given window
|
||||
void GetWindowInfoFromWindow(WindowInfo* wi, void* window);
|
||||
/// Run cocoa event loop
|
||||
void RunCocoaEventLoop(bool wait_forever = false);
|
||||
/// Posts an event to the main telling `RunCocoaEventLoop(true)` to exit
|
||||
void StopMainThreadEventLoop();
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
@@ -224,5 +224,103 @@ bool CocoaTools::DelayedLaunch(std::string_view file)
|
||||
bool CocoaTools::ShowInFinder(std::string_view file)
|
||||
{
|
||||
return [[NSWorkspace sharedWorkspace] selectFile:NSStringFromStringView(file)
|
||||
inFileViewerRootedAtPath:nil];
|
||||
inFileViewerRootedAtPath:@""];
|
||||
}
|
||||
|
||||
std::optional<std::string> CocoaTools::GetResourcePath()
|
||||
{ @autoreleasepool {
|
||||
if (NSBundle* bundle = [NSBundle mainBundle])
|
||||
{
|
||||
NSString* rsrc = [bundle resourcePath];
|
||||
NSString* root = [bundle bundlePath];
|
||||
if ([rsrc isEqualToString:root])
|
||||
rsrc = [rsrc stringByAppendingString:@"/resources"];
|
||||
return [rsrc UTF8String];
|
||||
}
|
||||
return std::nullopt;
|
||||
}}
|
||||
|
||||
// MARK: - GSRunner
|
||||
|
||||
void* CocoaTools::CreateWindow(std::string_view title, u32 width, u32 height)
|
||||
{
|
||||
if (!NSApp)
|
||||
{
|
||||
[NSApplication sharedApplication];
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
[NSApp finishLaunching];
|
||||
}
|
||||
constexpr NSWindowStyleMask style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable;
|
||||
NSScreen* mainScreen = [NSScreen mainScreen];
|
||||
// Center the window on the screen, because why not
|
||||
NSRect screenFrame = [mainScreen frame];
|
||||
NSRect viewFrame = screenFrame;
|
||||
viewFrame.size = NSMakeSize(width, height);
|
||||
viewFrame.origin.x += (screenFrame.size.width - viewFrame.size.width) / 2;
|
||||
viewFrame.origin.y += (screenFrame.size.height - viewFrame.size.height) / 2;
|
||||
NSWindow* window = [[NSWindow alloc]
|
||||
initWithContentRect:viewFrame
|
||||
styleMask:style
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
[window setTitle:NSStringFromStringView(title)];
|
||||
[window makeKeyAndOrderFront:window];
|
||||
return (__bridge_retained void*)window;
|
||||
}
|
||||
|
||||
void CocoaTools::DestroyWindow(void* window)
|
||||
{
|
||||
(void)(__bridge_transfer NSWindow*)window;
|
||||
}
|
||||
|
||||
void CocoaTools::GetWindowInfoFromWindow(WindowInfo* wi, void* cf_window)
|
||||
{
|
||||
if (cf_window)
|
||||
{
|
||||
NSWindow* window = (__bridge NSWindow*)cf_window;
|
||||
float scale = [window backingScaleFactor];
|
||||
NSView* view = [window contentView];
|
||||
NSRect dims = [view frame];
|
||||
wi->type = WindowInfo::Type::MacOS;
|
||||
wi->window_handle = (__bridge void*)view;
|
||||
wi->surface_width = dims.size.width * scale;
|
||||
wi->surface_height = dims.size.height * scale;
|
||||
wi->surface_scale = scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
wi->type = WindowInfo::Type::Surfaceless;
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr short STOP_EVENT_LOOP = 0x100;
|
||||
|
||||
void CocoaTools::RunCocoaEventLoop(bool forever)
|
||||
{
|
||||
NSDate* end = forever ? [NSDate distantFuture] : [NSDate distantPast];
|
||||
[NSApplication sharedApplication]; // Ensure NSApp is initialized
|
||||
while (true)
|
||||
{ @autoreleasepool {
|
||||
NSEvent* ev = [NSApp nextEventMatchingMask:NSEventMaskAny
|
||||
untilDate:end
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES];
|
||||
if (!ev || ([ev type] == NSEventTypeApplicationDefined && [ev subtype] == STOP_EVENT_LOOP))
|
||||
break;
|
||||
[NSApp sendEvent:ev];
|
||||
}}
|
||||
}
|
||||
|
||||
void CocoaTools::StopMainThreadEventLoop()
|
||||
{ @autoreleasepool {
|
||||
NSEvent* ev = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
|
||||
location:{}
|
||||
modifierFlags:0
|
||||
timestamp:0
|
||||
windowNumber:0
|
||||
context:nil
|
||||
subtype:STOP_EVENT_LOOP
|
||||
data1:0
|
||||
data2:0];
|
||||
[NSApp postEvent:ev atStart:NO];
|
||||
}}
|
||||
|
||||
@@ -437,7 +437,7 @@ std::unique_ptr<SharedMemoryMappingArea> SharedMemoryMappingArea::Create(size_t
|
||||
{
|
||||
pxAssertRel(Common::IsAlignedPow2(size, __pagesize), "Size is page aligned");
|
||||
|
||||
mach_vm_address_t alloc;
|
||||
mach_vm_address_t alloc = 0;
|
||||
const kern_return_t res =
|
||||
mach_vm_map(mach_task_self(), &alloc, size, 0, VM_FLAGS_ANYWHERE,
|
||||
MEMORY_OBJECT_NULL, 0, false, VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_NONE);
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);freetype.lib;jpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL3.lib;zlib.lib;zstd.lib;kddockwidgets-qt62.lib;plutovg.lib;plutosvg.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);freetype.lib;jpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL3.lib;zlib.lib;zstd.lib;plutovg.lib;plutosvg.lib</AdditionalDependencies>
|
||||
<AdditionalDependencies Condition="$(Configuration.Contains(Debug))">%(AdditionalDependencies);kddockwidgets-qt6d.lib;</AdditionalDependencies>
|
||||
<AdditionalDependencies Condition="!$(Configuration.Contains(Debug))">%(AdditionalDependencies);kddockwidgets-qt6.lib;</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<DepsDLLs Include="$(DepsBinDir)freetype.dll" />
|
||||
@@ -19,7 +21,8 @@
|
||||
<DepsDLLs Include="$(DepsBinDir)shaderc_shared.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)zlib1.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)zstd.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)kddockwidgets-qt62.dll" />
|
||||
<DepsDLLs Condition="$(Configuration.Contains(Debug))" Include="$(DepsBinDir)kddockwidgets-qt6d.dll" />
|
||||
<DepsDLLs Condition="!$(Configuration.Contains(Debug))" Include="$(DepsBinDir)kddockwidgets-qt6.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)plutovg.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)plutosvg.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/CocoaTools.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/CrashHandler.h"
|
||||
#include "common/FileSystem.h"
|
||||
@@ -56,7 +57,8 @@ namespace GSRunner
|
||||
static bool CreatePlatformWindow();
|
||||
static void DestroyPlatformWindow();
|
||||
static std::optional<WindowInfo> GetPlatformWindowInfo();
|
||||
static void PumpPlatformMessages();
|
||||
static void PumpPlatformMessages(bool forever = false);
|
||||
static void StopPlatformMessagePump();
|
||||
} // namespace GSRunner
|
||||
|
||||
static constexpr u32 WINDOW_WIDTH = 640;
|
||||
@@ -532,7 +534,7 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa
|
||||
{
|
||||
std::string str(argv[++i]);
|
||||
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "dump", true);
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "DumpGSData", true);
|
||||
|
||||
if (str.find("rt") != std::string::npos)
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveRT", true);
|
||||
@@ -764,7 +766,7 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_settings_interface.GetBoolValue("EmuCore/GS", "dump") && !dumpdir.empty())
|
||||
if (s_settings_interface.GetBoolValue("EmuCore/GS", "DumpGSData") && !dumpdir.empty())
|
||||
{
|
||||
if (s_settings_interface.GetStringValue("EmuCore/GS", "HWDumpDirectory").empty())
|
||||
s_settings_interface.SetStringValue("EmuCore/GS", "HWDumpDirectory", dumpdir.c_str());
|
||||
@@ -809,6 +811,22 @@ void GSRunner::DumpStats()
|
||||
#define main real_main
|
||||
#endif
|
||||
|
||||
static void CPUThreadMain(VMBootParameters* params) {
|
||||
if (VMManager::Initialize(*params))
|
||||
{
|
||||
// run until end
|
||||
GSDumpReplayer::SetLoopCount(s_loop_count);
|
||||
VMManager::SetState(VMState::Running);
|
||||
while (VMManager::GetState() == VMState::Running)
|
||||
VMManager::Execute();
|
||||
VMManager::Shutdown(false);
|
||||
GSRunner::DumpStats();
|
||||
}
|
||||
|
||||
VMManager::Internal::CPUThreadShutdown();
|
||||
GSRunner::StopPlatformMessagePump();
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
CrashHandler::Install();
|
||||
@@ -837,16 +855,9 @@ int main(int argc, char* argv[])
|
||||
VMManager::ApplySettings();
|
||||
GSDumpReplayer::SetIsDumpRunner(true);
|
||||
|
||||
if (VMManager::Initialize(params))
|
||||
{
|
||||
// run until end
|
||||
GSDumpReplayer::SetLoopCount(s_loop_count);
|
||||
VMManager::SetState(VMState::Running);
|
||||
while (VMManager::GetState() == VMState::Running)
|
||||
VMManager::Execute();
|
||||
VMManager::Shutdown(false);
|
||||
GSRunner::DumpStats();
|
||||
}
|
||||
std::thread cputhread(CPUThreadMain, ¶ms);
|
||||
GSRunner::PumpPlatformMessages(/*forever=*/true);
|
||||
cputhread.join();
|
||||
|
||||
VMManager::Internal::CPUThreadShutdown();
|
||||
GSRunner::DestroyPlatformWindow();
|
||||
@@ -859,9 +870,6 @@ void Host::PumpMessagesOnCPUThread()
|
||||
// update GS thread copy of frame number
|
||||
MTGS::RunOnGSThread([frame_number = GSDumpReplayer::GetFrameNumber()]() { s_dump_frame_number = frame_number; });
|
||||
MTGS::RunOnGSThread([loop_number = GSDumpReplayer::GetLoopCount()]() { s_loop_number = loop_number; });
|
||||
|
||||
// process any window messages (but we shouldn't really have any)
|
||||
GSRunner::PumpPlatformMessages();
|
||||
}
|
||||
|
||||
s32 Host::Internal::GetTranslatedStringImpl(
|
||||
@@ -975,16 +983,32 @@ std::optional<WindowInfo> GSRunner::GetPlatformWindowInfo()
|
||||
return wi;
|
||||
}
|
||||
|
||||
void GSRunner::PumpPlatformMessages()
|
||||
static constexpr int SHUTDOWN_MSG = WM_APP + 0x100;
|
||||
static DWORD MainThreadID;
|
||||
|
||||
void GSRunner::PumpPlatformMessages(bool forever)
|
||||
{
|
||||
MSG msg;
|
||||
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
while (true)
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == SHUTDOWN_MSG)
|
||||
return;
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
if (!forever)
|
||||
return;
|
||||
WaitMessage();
|
||||
}
|
||||
}
|
||||
|
||||
void GSRunner::StopPlatformMessagePump()
|
||||
{
|
||||
PostThreadMessageW(MainThreadID, SHUTDOWN_MSG, 0, 0);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
||||
@@ -1003,7 +1027,51 @@ int wmain(int argc, wchar_t** argv)
|
||||
u8_argptrs.push_back(u8_args[i].data());
|
||||
u8_argptrs.push_back(nullptr);
|
||||
|
||||
MainThreadID = GetCurrentThreadId();
|
||||
|
||||
return real_main(argc, u8_argptrs.data());
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
static void* s_window;
|
||||
static WindowInfo s_wi;
|
||||
|
||||
bool GSRunner::CreatePlatformWindow()
|
||||
{
|
||||
pxAssertRel(!s_window, "Tried to create window when there already was one!");
|
||||
s_window = CocoaTools::CreateWindow("PCSX2 GS Runner", WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
CocoaTools::GetWindowInfoFromWindow(&s_wi, s_window);
|
||||
PumpPlatformMessages();
|
||||
return s_window;
|
||||
}
|
||||
|
||||
void GSRunner::DestroyPlatformWindow()
|
||||
{
|
||||
if (s_window) {
|
||||
CocoaTools::DestroyWindow(s_window);
|
||||
s_window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<WindowInfo> GSRunner::GetPlatformWindowInfo()
|
||||
{
|
||||
WindowInfo wi;
|
||||
if (s_window)
|
||||
wi = s_wi;
|
||||
else
|
||||
wi.type = WindowInfo::Type::Surfaceless;
|
||||
return wi;
|
||||
}
|
||||
|
||||
void GSRunner::PumpPlatformMessages(bool forever)
|
||||
{
|
||||
CocoaTools::RunCocoaEventLoop(forever);
|
||||
}
|
||||
|
||||
void GSRunner::StopPlatformMessagePump()
|
||||
{
|
||||
CocoaTools::StopMainThreadEventLoop();
|
||||
}
|
||||
|
||||
#endif // _WIN32 / __APPLE__
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>576</width>
|
||||
<height>294</height>
|
||||
<width>580</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -19,45 +19,42 @@
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Preferred</enum>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="icon">
|
||||
<property name="maximumSize">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>260</width>
|
||||
<height>260</height>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="resources/resources.qrc">:/icons/logo.png</pixmap>
|
||||
<pixmap resource="resources/resources.qrc">:/icons/PCSX2logo.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Preferred</enum>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
@@ -69,7 +66,7 @@
|
||||
<string extracomment="SCM= Source Code Management">SCM Version</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -79,7 +76,7 @@
|
||||
<string><html><head/><body><p>PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a combination of MIPS CPU Interpreters, Recompilers and a Virtual Machine which manages hardware states and PS2 system memory. This allows you to play PS2 games on your PC, with many additional features and benefits.</p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignJustify|Qt::AlignVCenter</set>
|
||||
<set>Qt::AlignmentFlag::AlignJustify|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -89,23 +86,31 @@
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="disclaimer">
|
||||
<property name="font">
|
||||
<font>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not affiliated in any way with Sony Interactive Entertainment.</p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignJustify|Qt::AlignVCenter</set>
|
||||
<set>Qt::AlignmentFlag::AlignJustify|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -115,12 +120,15 @@
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -131,19 +139,22 @@
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -151,7 +162,7 @@
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
<set>QDialogButtonBox::StandardButton::Close</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>true</bool>
|
||||
@@ -162,7 +173,6 @@
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources/resources.qrc"/>
|
||||
<include location="resources/icons.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "CoverDownloadDialog.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "pcsx2/GameList.h"
|
||||
|
||||
@@ -11,7 +12,7 @@ CoverDownloadDialog::CoverDownloadDialog(QWidget* parent /*= nullptr*/)
|
||||
: QDialog(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
m_ui.coverIcon->setPixmap(QIcon::fromTheme("artboard-2-line").pixmap(32));
|
||||
QtUtils::SetScalableIcon(m_ui.coverIcon, QIcon::fromTheme(QStringLiteral("artboard-2-line")), QSize(32, 32));
|
||||
updateEnabled();
|
||||
|
||||
connect(m_ui.start, &QPushButton::clicked, this, &CoverDownloadDialog::onStartClicked);
|
||||
|
||||
@@ -149,7 +149,9 @@ DockTabBar::DockTabBar(KDDockWidgets::Core::TabBar* controller, QWidget* parent)
|
||||
// that ends up taking ownerhsip of the style for the entire application!
|
||||
if (QProxyStyle* proxy_style = qobject_cast<QProxyStyle*>(style()))
|
||||
{
|
||||
proxy_style->baseStyle()->setParent(qApp);
|
||||
if (proxy_style->baseStyle() == qApp->style())
|
||||
proxy_style->baseStyle()->setParent(qApp);
|
||||
|
||||
proxy_style->setBaseStyle(QStyleFactory::create(qApp->style()->name()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <kddockwidgets/Config.h>
|
||||
#include <kddockwidgets/core/Group.h>
|
||||
#include <kddockwidgets/core/Platform.h>
|
||||
#include <kddockwidgets/core/indicators/SegmentedDropIndicatorOverlay.h>
|
||||
#include <kddockwidgets/qtwidgets/ViewFactory.h>
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Array of byte</string>
|
||||
<string>Byte Array</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
|
||||
@@ -65,16 +65,17 @@ void ThreadView::openContextMenu(QPoint pos)
|
||||
|
||||
void ThreadView::onDoubleClick(const QModelIndex& index)
|
||||
{
|
||||
auto real_index = m_proxy_model->mapToSource(index);
|
||||
switch (index.column())
|
||||
{
|
||||
case ThreadModel::ThreadColumns::ENTRY:
|
||||
{
|
||||
goToInMemoryView(m_model->data(index, Qt::UserRole).toUInt(), true);
|
||||
goToInDisassembler(m_model->data(real_index, Qt::UserRole).toUInt(), true);
|
||||
break;
|
||||
}
|
||||
default: // Default to PC
|
||||
{
|
||||
QModelIndex pc_index = m_model->index(index.row(), ThreadModel::ThreadColumns::PC);
|
||||
QModelIndex pc_index = m_model->index(real_index.row(), ThreadModel::ThreadColumns::PC);
|
||||
goToInDisassembler(m_model->data(pc_index, Qt::UserRole).toUInt(), true);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -52,12 +52,12 @@ DisplayWidget::~DisplayWidget()
|
||||
|
||||
int DisplayWidget::scaledWindowWidth() const
|
||||
{
|
||||
return std::max(static_cast<int>(std::ceil(static_cast<qreal>(width()) * QtUtils::GetDevicePixelRatioForWidget(this))), 1);
|
||||
return std::max(static_cast<int>(std::ceil(static_cast<qreal>(width()) * devicePixelRatioF())), 1);
|
||||
}
|
||||
|
||||
int DisplayWidget::scaledWindowHeight() const
|
||||
{
|
||||
return std::max(static_cast<int>(std::ceil(static_cast<qreal>(height()) * QtUtils::GetDevicePixelRatioForWidget(this))), 1);
|
||||
return std::max(static_cast<int>(std::ceil(static_cast<qreal>(height()) * devicePixelRatioF())), 1);
|
||||
}
|
||||
|
||||
std::optional<WindowInfo> DisplayWidget::getWindowInfo()
|
||||
@@ -268,7 +268,7 @@ bool DisplayWidget::event(QEvent* event)
|
||||
|
||||
if (!m_relative_mouse_enabled)
|
||||
{
|
||||
const qreal dpr = QtUtils::GetDevicePixelRatioForWidget(this);
|
||||
const qreal dpr = devicePixelRatioF();
|
||||
const QPoint mouse_pos = mouse_event->pos();
|
||||
|
||||
const float scaled_x = static_cast<float>(static_cast<qreal>(mouse_pos.x()) * dpr);
|
||||
@@ -349,13 +349,12 @@ bool DisplayWidget::event(QEvent* event)
|
||||
return true;
|
||||
}
|
||||
|
||||
// According to https://bugreports.qt.io/browse/QTBUG-95925 the recommended practice for handling DPI change is responding to paint events
|
||||
case QEvent::Paint:
|
||||
case QEvent::DevicePixelRatioChange:
|
||||
case QEvent::Resize:
|
||||
{
|
||||
QWidget::event(event);
|
||||
|
||||
const float dpr = QtUtils::GetDevicePixelRatioForWidget(this);
|
||||
const float dpr = devicePixelRatioF();
|
||||
const u32 scaled_width = static_cast<u32>(std::max(static_cast<int>(std::ceil(static_cast<qreal>(width()) * dpr)), 1));
|
||||
const u32 scaled_height = static_cast<u32>(std::max(static_cast<int>(std::ceil(static_cast<qreal>(height()) * dpr)), 1));
|
||||
|
||||
|
||||
@@ -25,17 +25,17 @@ static constexpr int COVER_ART_HEIGHT = 512;
|
||||
static constexpr int COVER_ART_SPACING = 32;
|
||||
static constexpr int MIN_COVER_CACHE_SIZE = 256;
|
||||
|
||||
static int DPRScale(int size, float dpr)
|
||||
static int DPRScale(int size, qreal dpr)
|
||||
{
|
||||
return static_cast<int>(static_cast<float>(size) * dpr);
|
||||
return static_cast<int>(static_cast<qreal>(size) * dpr);
|
||||
}
|
||||
|
||||
static int DPRUnscale(int size, float dpr)
|
||||
static int DPRUnscale(int size, qreal dpr)
|
||||
{
|
||||
return static_cast<int>(static_cast<float>(size) / dpr);
|
||||
return static_cast<int>(static_cast<qreal>(size) / dpr);
|
||||
}
|
||||
|
||||
static void resizeAndPadPixmap(QPixmap* pm, int expected_width, int expected_height, float dpr)
|
||||
static void resizeAndPadPixmap(QPixmap* pm, int expected_width, int expected_height, qreal dpr)
|
||||
{
|
||||
const int dpr_expected_width = DPRScale(expected_width, dpr);
|
||||
const int dpr_expected_height = DPRScale(expected_height, dpr);
|
||||
@@ -71,9 +71,8 @@ static void resizeAndPadPixmap(QPixmap* pm, int expected_width, int expected_hei
|
||||
}
|
||||
|
||||
static QPixmap createPlaceholderImage(const QPixmap& placeholder_pixmap, int width, int height, float scale,
|
||||
const std::string& title)
|
||||
qreal dpr, const std::string& title)
|
||||
{
|
||||
const float dpr = qApp->devicePixelRatio();
|
||||
QPixmap pm(placeholder_pixmap.copy());
|
||||
pm.setDevicePixelRatio(dpr);
|
||||
if (pm.isNull())
|
||||
@@ -113,9 +112,10 @@ const char* GameListModel::getColumnName(Column col)
|
||||
return s_column_names[static_cast<int>(col)];
|
||||
}
|
||||
|
||||
GameListModel::GameListModel(float cover_scale, bool show_cover_titles, QObject* parent /* = nullptr */)
|
||||
GameListModel::GameListModel(float cover_scale, bool show_cover_titles, qreal dpr, QObject* parent /* = nullptr */)
|
||||
: QAbstractTableModel(parent)
|
||||
, m_show_titles_for_covers(show_cover_titles)
|
||||
, m_dpr{dpr}
|
||||
{
|
||||
loadSettings();
|
||||
loadCommonImages();
|
||||
@@ -160,6 +160,13 @@ void GameListModel::updateCacheSize(int width, int height)
|
||||
m_cover_pixmap_cache.SetMaxCapacity(static_cast<int>(std::max(num_columns * num_rows, MIN_COVER_CACHE_SIZE)));
|
||||
}
|
||||
|
||||
void GameListModel::setDevicePixelRatio(qreal dpr)
|
||||
{
|
||||
m_dpr = dpr;
|
||||
loadCommonImages();
|
||||
refreshCovers();
|
||||
}
|
||||
|
||||
void GameListModel::loadOrGenerateCover(const GameList::Entry* ge)
|
||||
{
|
||||
// Why this counter: Every time we change the cover scale, we increment the counter variable. This way if the scale is changed
|
||||
@@ -173,12 +180,11 @@ void GameListModel::loadOrGenerateCover(const GameList::Entry* ge)
|
||||
const std::string cover_path(GameList::GetCoverImagePathForEntry(&entry));
|
||||
if (!cover_path.empty())
|
||||
{
|
||||
const float dpr = qApp->devicePixelRatio();
|
||||
image = QPixmap(QString::fromStdString(cover_path));
|
||||
if (!image.isNull())
|
||||
{
|
||||
image.setDevicePixelRatio(dpr);
|
||||
resizeAndPadPixmap(&image, getCoverArtWidth(), getCoverArtHeight(), dpr);
|
||||
image.setDevicePixelRatio(m_dpr);
|
||||
resizeAndPadPixmap(&image, getCoverArtWidth(), getCoverArtHeight(), m_dpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,7 +192,7 @@ void GameListModel::loadOrGenerateCover(const GameList::Entry* ge)
|
||||
const std::string& title = entry.GetTitle(m_prefer_english_titles);
|
||||
|
||||
if (image.isNull())
|
||||
image = createPlaceholderImage(m_placeholder_pixmap, getCoverArtWidth(), getCoverArtHeight(), m_cover_scale, title);
|
||||
image = createPlaceholderImage(m_placeholder_pixmap, getCoverArtWidth(), getCoverArtHeight(), m_cover_scale, m_dpr, title);
|
||||
|
||||
if (m_cover_scale_counter.load(std::memory_order_acquire) != counter)
|
||||
image = {};
|
||||
@@ -440,7 +446,7 @@ bool GameListModel::titlesLessThan(int left_row, int right_row) const
|
||||
const GameList::Entry* left = GameList::GetEntryByIndex(left_row);
|
||||
const GameList::Entry* right = GameList::GetEntryByIndex(right_row);
|
||||
return QtHost::LocaleSensitiveCompare(QString::fromStdString(left->GetTitleSort(m_prefer_english_titles)),
|
||||
QString::fromStdString(right->GetTitleSort(m_prefer_english_titles))) < 0;
|
||||
QString::fromStdString(right->GetTitleSort(m_prefer_english_titles))) < 0;
|
||||
}
|
||||
|
||||
bool GameListModel::lessThan(const QModelIndex& left_index, const QModelIndex& right_index, int column) const
|
||||
@@ -569,16 +575,16 @@ QIcon GameListModel::getIconForType(GameList::EntryType type)
|
||||
QIcon GameListModel::getIconForRegion(GameList::Region region)
|
||||
{
|
||||
return QIcon(
|
||||
QStringLiteral("%1/icons/flags/%2.svg").arg(QtHost::GetResourcesBasePath()).arg(GameList::RegionToString(region)));
|
||||
QStringLiteral("%1/icons/flags/%2.svg").arg(QtHost::GetResourcesBasePath()).arg(GameList::RegionToString(region, false)));
|
||||
}
|
||||
|
||||
void GameListModel::loadThemeSpecificImages()
|
||||
{
|
||||
for (u32 type = 0; type < static_cast<u32>(GameList::EntryType::Count); type++)
|
||||
m_type_pixmaps[type] = getIconForType(static_cast<GameList::EntryType>(type)).pixmap(QSize(24, 24));
|
||||
m_type_pixmaps[type] = getIconForType(static_cast<GameList::EntryType>(type)).pixmap(QSize(24, 24), m_dpr);
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(GameList::Region::Count); i++)
|
||||
m_region_pixmaps[i] = getIconForRegion(static_cast<GameList::Region>(i)).pixmap(QSize(36, 26));
|
||||
m_region_pixmaps[i] = getIconForRegion(static_cast<GameList::Region>(i)).pixmap(QSize(36, 26), m_dpr);
|
||||
}
|
||||
|
||||
void GameListModel::loadCommonImages()
|
||||
@@ -587,7 +593,7 @@ void GameListModel::loadCommonImages()
|
||||
|
||||
const QString base_path(QtHost::GetResourcesBasePath());
|
||||
for (u32 i = 1; i < GameList::CompatibilityRatingCount; i++)
|
||||
m_compatibility_pixmaps[i].load(QStringLiteral("%1/icons/star-%2.svg").arg(base_path).arg(i - 1));
|
||||
m_compatibility_pixmaps[i] = QIcon((QStringLiteral("%1/icons/star-%2.svg").arg(base_path).arg(i - 1))).pixmap(QSize(88, 16), m_dpr);
|
||||
|
||||
m_placeholder_pixmap.load(QStringLiteral("%1/cover-placeholder.png").arg(base_path));
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
static QIcon getIconForType(GameList::EntryType type);
|
||||
static QIcon getIconForRegion(GameList::Region region);
|
||||
|
||||
GameListModel(float cover_scale, bool show_cover_titles, QObject* parent = nullptr);
|
||||
GameListModel(float cover_scale, bool show_cover_titles, qreal dpr, QObject* parent = nullptr);
|
||||
~GameListModel();
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
@@ -71,6 +71,8 @@ public:
|
||||
void refreshCovers();
|
||||
void updateCacheSize(int width, int height);
|
||||
|
||||
void setDevicePixelRatio(qreal dpr);
|
||||
|
||||
Q_SIGNALS:
|
||||
void coverScaleChanged();
|
||||
|
||||
@@ -94,6 +96,7 @@ private:
|
||||
std::array<QPixmap, static_cast<u32>(GameList::Region::Count)> m_region_pixmaps;
|
||||
QPixmap m_placeholder_pixmap;
|
||||
QPixmap m_loading_pixmap;
|
||||
qreal m_dpr;
|
||||
|
||||
std::array<QPixmap, static_cast<int>(GameList::CompatibilityRatingCount)> m_compatibility_pixmaps;
|
||||
mutable LRUCache<std::string, QPixmap> m_cover_pixmap_cache;
|
||||
|
||||
@@ -128,22 +128,25 @@ namespace
|
||||
const int pix_width = static_cast<int>(pix.width() / pix.devicePixelRatio());
|
||||
const int pix_height = static_cast<int>(pix.height() / pix.devicePixelRatio());
|
||||
|
||||
// Clip the pixmaps so they don't extend outside the column
|
||||
painter->save();
|
||||
painter->setClipRect(option.rect);
|
||||
|
||||
// Draw the icon, using code derived from QItemDelegate::drawDecoration()
|
||||
const bool enabled = option.state & QStyle::State_Enabled;
|
||||
const QPoint p = QPoint((r.width() - pix_width) / 2, (r.height() - pix_height) / 2);
|
||||
if (option.state & QStyle::State_Selected)
|
||||
{
|
||||
// See QItemDelegate::selectedPixmap()
|
||||
QString key = QString::fromStdString(fmt::format("{:016X}-{:d}", pix.cacheKey(), enabled));
|
||||
// See QItemDelegate::selectedPixmap()
|
||||
QColor color = option.palette.color(enabled ? QPalette::Normal : QPalette::Disabled, QPalette::Highlight);
|
||||
color.setAlphaF(0.3f);
|
||||
|
||||
QString key = QString::fromStdString(fmt::format("{:016X}-{:d}-{:08X}", pix.cacheKey(), enabled, color.rgba()));
|
||||
QPixmap pm;
|
||||
if (!QPixmapCache::find(key, &pm))
|
||||
{
|
||||
QImage img = pix.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
QColor color = option.palette.color(enabled ? QPalette::Normal : QPalette::Disabled,
|
||||
QPalette::Highlight);
|
||||
color.setAlphaF(0.3f);
|
||||
|
||||
QPainter tinted_painter(&img);
|
||||
tinted_painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
|
||||
tinted_painter.fillRect(0, 0, img.width(), img.height(), color);
|
||||
@@ -159,6 +162,9 @@ namespace
|
||||
{
|
||||
painter->drawPixmap(r.topLeft() + p, pix);
|
||||
}
|
||||
|
||||
// Restore the old clip path.
|
||||
painter->restore();
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
@@ -174,22 +180,27 @@ void GameListWidget::initialize()
|
||||
{
|
||||
const float cover_scale = Host::GetBaseFloatSettingValue("UI", "GameListCoverArtScale", 0.45f);
|
||||
const bool show_cover_titles = Host::GetBaseBoolSettingValue("UI", "GameListShowCoverTitles", true);
|
||||
m_model = new GameListModel(cover_scale, show_cover_titles, this);
|
||||
m_model = new GameListModel(cover_scale, show_cover_titles, devicePixelRatioF(), this);
|
||||
m_model->updateCacheSize(width(), height());
|
||||
|
||||
m_sort_model = new GameListSortModel(m_model);
|
||||
m_sort_model->setSourceModel(m_model);
|
||||
|
||||
m_ui.setupUi(this);
|
||||
|
||||
for (u32 type = 0; type < static_cast<u32>(GameList::EntryType::Count); type++)
|
||||
{
|
||||
m_ui.filterType->addItem(GameListModel::getIconForType(static_cast<GameList::EntryType>(type)),
|
||||
qApp->translate("GameList", GameList::EntryTypeToDisplayString(static_cast<GameList::EntryType>(type))));
|
||||
if (type != static_cast<u32>(GameList::EntryType::Invalid))
|
||||
{
|
||||
m_ui.filterType->addItem(GameListModel::getIconForType(static_cast<GameList::EntryType>(type)),
|
||||
GameList::EntryTypeToString(static_cast<GameList::EntryType>(type), true));
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 region = 0; region < static_cast<u32>(GameList::Region::Count); region++)
|
||||
{
|
||||
m_ui.filterRegion->addItem(GameListModel::getIconForRegion(static_cast<GameList::Region>(region)),
|
||||
qApp->translate("GameList", GameList::RegionToString(static_cast<GameList::Region>(region))));
|
||||
GameList::RegionToString(static_cast<GameList::Region>(region), true));
|
||||
}
|
||||
|
||||
connect(m_ui.viewGameList, &QPushButton::clicked, this, &GameListWidget::showGameList);
|
||||
@@ -547,6 +558,18 @@ void GameListWidget::resizeEvent(QResizeEvent* event)
|
||||
m_model->updateCacheSize(width(), height());
|
||||
}
|
||||
|
||||
bool GameListWidget::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::DevicePixelRatioChange)
|
||||
{
|
||||
m_model->setDevicePixelRatio(devicePixelRatioF());
|
||||
QWidget::event(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void GameListWidget::resizeTableViewColumnsToFit()
|
||||
{
|
||||
QtUtils::ResizeColumnsForTableView(m_table_view, {
|
||||
|
||||
@@ -93,6 +93,7 @@ public Q_SLOTS:
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
bool event(QEvent* event) override;
|
||||
|
||||
private:
|
||||
void loadTableViewColumnVisibilitySettings();
|
||||
|
||||
@@ -103,9 +103,9 @@
|
||||
<addaction name="actionMemoryCardSettings"/>
|
||||
<addaction name="actionDEV9Settings"/>
|
||||
<addaction name="actionFolderSettings"/>
|
||||
<addaction name="actionAchievementSettings"/>
|
||||
<addaction name="actionControllerSettings"/>
|
||||
<addaction name="actionHotkeySettings"/>
|
||||
<addaction name="actionAchievementSettings"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionAddGameDirectory"/>
|
||||
<addaction name="actionScanForNewGames"/>
|
||||
|
||||
@@ -254,15 +254,6 @@ namespace QtUtils
|
||||
widget->resize(width, height);
|
||||
}
|
||||
|
||||
qreal GetDevicePixelRatioForWidget(const QWidget* widget)
|
||||
{
|
||||
const QScreen* screen_for_ratio = widget->screen();
|
||||
if (!screen_for_ratio)
|
||||
screen_for_ratio = QGuiApplication::primaryScreen();
|
||||
|
||||
return screen_for_ratio ? screen_for_ratio->devicePixelRatio() : static_cast<qreal>(1);
|
||||
}
|
||||
|
||||
std::optional<WindowInfo> GetWindowInfoForWidget(QWidget* widget)
|
||||
{
|
||||
WindowInfo wi;
|
||||
@@ -303,7 +294,7 @@ namespace QtUtils
|
||||
}
|
||||
#endif
|
||||
|
||||
const qreal dpr = GetDevicePixelRatioForWidget(widget);
|
||||
const qreal dpr = widget->devicePixelRatioF();
|
||||
wi.surface_width = static_cast<u32>(static_cast<qreal>(widget->width()) * dpr);
|
||||
wi.surface_height = static_cast<u32>(static_cast<qreal>(widget->height()) * dpr);
|
||||
wi.surface_scale = static_cast<float>(dpr);
|
||||
@@ -374,4 +365,37 @@ namespace QtUtils
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class IconVariableDpiFilter : QObject
|
||||
{
|
||||
public:
|
||||
explicit IconVariableDpiFilter(QLabel* lbl, const QIcon& icon, const QSize& size, QObject* parent = nullptr)
|
||||
: QObject(parent)
|
||||
, m_lbl{lbl}
|
||||
, m_icn{icon}
|
||||
, m_size{size}
|
||||
{
|
||||
lbl->installEventFilter(this);
|
||||
m_lbl->setPixmap(m_icn.pixmap(m_size, m_lbl->devicePixelRatioF()));
|
||||
}
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* object, QEvent* event) override
|
||||
{
|
||||
if (object == m_lbl && event->type() == QEvent::DevicePixelRatioChange)
|
||||
m_lbl->setPixmap(m_icn.pixmap(m_size, m_lbl->devicePixelRatioF()));
|
||||
// Don't block the event
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
QLabel* m_lbl;
|
||||
QIcon m_icn;
|
||||
QSize m_size;
|
||||
};
|
||||
|
||||
void SetScalableIcon(QLabel* lbl, const QIcon& icon, const QSize& size)
|
||||
{
|
||||
new IconVariableDpiFilter(lbl, icon, size, lbl);
|
||||
}
|
||||
} // namespace QtUtils
|
||||
|
||||
@@ -20,6 +20,7 @@ class QAction;
|
||||
class QComboBox;
|
||||
class QFileInfo;
|
||||
class QFrame;
|
||||
class QIcon;
|
||||
class QLabel;
|
||||
class QKeyEvent;
|
||||
class QSlider;
|
||||
@@ -82,9 +83,6 @@ namespace QtUtils
|
||||
/// Adjusts the fixed size for a window if it's not resizeable.
|
||||
void ResizePotentiallyFixedSizeWindow(QWidget* widget, int width, int height);
|
||||
|
||||
/// Returns the pixel ratio/scaling factor for a widget.
|
||||
qreal GetDevicePixelRatioForWidget(const QWidget* widget);
|
||||
|
||||
/// Returns the common window info structure for a Qt widget.
|
||||
std::optional<WindowInfo> GetWindowInfoForWidget(QWidget* widget);
|
||||
|
||||
@@ -102,4 +100,8 @@ namespace QtUtils
|
||||
bool IsLightTheme(const QPalette& palette);
|
||||
|
||||
bool IsCompositorManagerRunning();
|
||||
|
||||
/// Sets the scalable icon to a given label (svg icons, or icons with multiple size pixmaps)
|
||||
/// The icon will then be reloaded on DPR changes using an event filter
|
||||
void SetScalableIcon(QLabel* lbl, const QIcon& icon, const QSize& size);
|
||||
} // namespace QtUtils
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "AchievementLoginDialog.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "pcsx2/Achievements.h"
|
||||
|
||||
@@ -15,7 +16,7 @@ AchievementLoginDialog::AchievementLoginDialog(QWidget* parent, Achievements::Lo
|
||||
, m_reason(reason)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
m_ui.loginIcon->setPixmap(QIcon::fromTheme("login-box-line").pixmap(32));
|
||||
QtUtils::SetScalableIcon(m_ui.loginIcon, QIcon::fromTheme(QStringLiteral("login-box-line")), QSize(32, 32));
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
// Adjust text if needed based on reason.
|
||||
@@ -116,7 +117,6 @@ void AchievementLoginDialog::processLoginResult(bool result, const QString& mess
|
||||
g_emu_thread->resetVM();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
done(0);
|
||||
|
||||
@@ -342,7 +342,7 @@ void AudioSettingsWidget::onExpansionSettingsClicked()
|
||||
QDialog dlg(QtUtils::GetRootWidget(this));
|
||||
Ui::AudioExpansionSettingsDialog dlgui;
|
||||
dlgui.setupUi(&dlg);
|
||||
dlgui.icon->setPixmap(QIcon::fromTheme(QStringLiteral("volume-up-line")).pixmap(32, 32));
|
||||
QtUtils::SetScalableIcon(dlgui.icon, QIcon::fromTheme(QStringLiteral("volume-up-line")), QSize(32, 32));
|
||||
|
||||
SettingsInterface* sif = m_dialog->getSettingsInterface();
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, dlgui.blockSize, "SPU2/Output", "ExpandBlockSize",
|
||||
@@ -431,7 +431,7 @@ void AudioSettingsWidget::onStretchSettingsClicked()
|
||||
QDialog dlg(QtUtils::GetRootWidget(this));
|
||||
Ui::AudioStretchSettingsDialog dlgui;
|
||||
dlgui.setupUi(&dlg);
|
||||
dlgui.icon->setPixmap(QIcon::fromTheme(QStringLiteral("volume-up-line")).pixmap(32, 32));
|
||||
QtUtils::SetScalableIcon(dlgui.icon, QIcon::fromTheme(QStringLiteral("volume-up-line")), QSize(32, 32));
|
||||
|
||||
SettingsInterface* sif = m_dialog->getSettingsInterface();
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, dlgui.sequenceLength, "SPU2/Output", "StretchSequenceLengthMS",
|
||||
|
||||
@@ -170,7 +170,7 @@ ControllerMouseSettingsDialog::ControllerMouseSettingsDialog(QWidget* parent, Co
|
||||
|
||||
SettingsInterface* sif = dialog->getProfileSettingsInterface();
|
||||
|
||||
m_ui.icon->setPixmap(QIcon::fromTheme(QStringLiteral("mouse-line")).pixmap(32, 32));
|
||||
QtUtils::SetScalableIcon(m_ui.icon, QIcon::fromTheme(QStringLiteral("mouse-line")), QSize(32, 32));
|
||||
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerXSpeedSlider, "Pad", "PointerXSpeed", 40.0f);
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerYSpeedSlider, "Pad", "PointerYSpeed", 40.0f);
|
||||
@@ -202,11 +202,10 @@ ControllerMappingSettingsDialog::ControllerMappingSettingsDialog(ControllerSetti
|
||||
|
||||
SettingsInterface* sif = parent->getProfileSettingsInterface();
|
||||
|
||||
m_ui.icon->setPixmap(QIcon::fromTheme(QStringLiteral("settings-3-line")).pixmap(32, 32));
|
||||
QtUtils::SetScalableIcon(m_ui.icon, QIcon::fromTheme(QStringLiteral("settings-3-line")), QSize(32, 32));
|
||||
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.ignoreInversion, "InputSources", "IgnoreInversion", false);
|
||||
|
||||
connect(m_ui.buttonBox->button(QDialogButtonBox::Close), &QPushButton::clicked, this, &QDialog::accept);
|
||||
}
|
||||
|
||||
ControllerMappingSettingsDialog::~ControllerMappingSettingsDialog() = default;
|
||||
|
||||
@@ -33,7 +33,7 @@ GameSummaryWidget::GameSummaryWidget(const GameList::Entry* entry, SettingsWindo
|
||||
for (int i = 0; i < m_ui.region->count(); i++)
|
||||
{
|
||||
m_ui.region->setItemIcon(i,
|
||||
QIcon(QStringLiteral("%1/icons/flags/%2.svg").arg(base_path).arg(GameList::RegionToString(static_cast<GameList::Region>(i)))));
|
||||
QIcon(QStringLiteral("%1/icons/flags/%2.svg").arg(base_path).arg(GameList::RegionToString(static_cast<GameList::Region>(i), false))));
|
||||
}
|
||||
|
||||
m_entry_path = entry->path;
|
||||
@@ -73,16 +73,17 @@ void GameSummaryWidget::populateDetails(const GameList::Entry* entry)
|
||||
m_ui.type->setCurrentIndex(static_cast<int>(entry->type));
|
||||
m_ui.region->setCurrentIndex(static_cast<int>(entry->region));
|
||||
//: First arg is a GameList compat; second is a string with space followed by star rating OR empty if Unknown compat
|
||||
m_ui.compatibility->setText(tr("%0%1")
|
||||
.arg(GameList::EntryCompatibilityRatingToString(entry->compatibility_rating))
|
||||
.arg([entry]() {
|
||||
if (entry->compatibility_rating == GameList::CompatibilityRating::Unknown)
|
||||
return QStringLiteral("");
|
||||
m_ui.compatibility->setText(
|
||||
tr("%0%1")
|
||||
.arg(GameList::EntryCompatibilityRatingToString(entry->compatibility_rating, true))
|
||||
.arg([entry]() {
|
||||
if (entry->compatibility_rating == GameList::CompatibilityRating::Unknown)
|
||||
return QStringLiteral("");
|
||||
|
||||
const qsizetype compatibility_value = static_cast<qsizetype>(entry->compatibility_rating);
|
||||
//: First arg is filled-in stars for game compatibility; second is empty stars; should be swapped for RTL languages
|
||||
return tr(" %0%1").arg(QStringLiteral("★").repeated(compatibility_value - 1)).arg(QStringLiteral("☆").repeated(6 - compatibility_value));
|
||||
}()));
|
||||
const qsizetype compatibility_value = static_cast<qsizetype>(entry->compatibility_rating);
|
||||
//: First arg is filled-in stars for game compatibility; second is empty stars; should be swapped for RTL languages
|
||||
return tr(" %0%1").arg(QStringLiteral("★").repeated(compatibility_value - 1)).arg(QStringLiteral("☆").repeated(6 - compatibility_value));
|
||||
}()));
|
||||
|
||||
int row = 0;
|
||||
m_ui.detailsFormLayout->getWidgetPosition(m_ui.titleSort, &row, nullptr);
|
||||
@@ -156,7 +157,7 @@ void GameSummaryWidget::onDiscPathChanged(const QString& value)
|
||||
|
||||
// force rescan of elf to update the serial
|
||||
g_main_window->rescanFile(m_entry_path);
|
||||
|
||||
|
||||
auto lock = GameList::GetLock();
|
||||
const GameList::Entry* entry = GameList::GetEntryForPath(m_entry_path.c_str());
|
||||
if (entry)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <QtWidgets/QPushButton>
|
||||
|
||||
#include "Settings/MemoryCardCreateDialog.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "pcsx2/SIO/Memcard/MemoryCardFile.h"
|
||||
|
||||
@@ -16,7 +17,7 @@ MemoryCardCreateDialog::MemoryCardCreateDialog(QWidget* parent /* = nullptr */)
|
||||
: QDialog(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
m_ui.icon->setPixmap(QIcon::fromTheme("memcard-line").pixmap(m_ui.icon->width()));
|
||||
QtUtils::SetScalableIcon(m_ui.icon, QIcon::fromTheme(QStringLiteral("memcard-line")), QSize(m_ui.icon->width(), m_ui.icon->width()));
|
||||
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <QtCore/QFile>
|
||||
#include <QtGui/QPalette>
|
||||
#include <QtGui/QPixmapCache>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QStyle>
|
||||
#include <QtWidgets/QStyleFactory>
|
||||
@@ -43,6 +44,12 @@ void QtHost::UpdateApplicationTheme()
|
||||
|
||||
SetStyleFromSettings();
|
||||
SetIconThemeFromStyle();
|
||||
|
||||
// Qt generates tinted versions of icons and stores them in QPixmapCache
|
||||
// The key used does not seem to include the theme (or tint colour).
|
||||
// This can cause icons tinted for wrong theme to be used for selected/disabled.
|
||||
// As a workaround, reset the pixmap cache to clear icons tinted for the old theme.
|
||||
QPixmapCache::clear();
|
||||
}
|
||||
|
||||
bool QtHost::IsDarkApplicationTheme()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1
pcsx2-qt/resources/icons/PCSX2logo.svg
Normal file
1
pcsx2-qt/resources/icons/PCSX2logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280.11 34.51"><g id="vectorized_by_maxihplay"><path id="_2" d="M228.43.6h45.87c2.91,0,5.28,2.37,5.28,5.28v9.69c0,2.91-2.37,5.28-5.28,5.28h-32.41v4.87h37.69v8.23h-51.15v-15.21c0-2.91,2.37-5.28,5.28-5.28h32.41v-5.32h-32.98l-4.7-7.53Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="1.05" stroke-width="1.05"/><g id="X"><polygon id="polygon1" points="221.55 25.7 221.55 33.94 206.12 33.94 195.58 23.46 185.11 33.93 169.61 33.93 169.61 25.63 177.94 25.63 186.32 17.36 177.26 8.08 169.61 8.08 169.61 .6 185.25 .6 195.55 10.68 205.41 .62 221.55 .62 221.55 8.08 213.57 8.08 204.68 17.17 213.31 25.7 221.55 25.7" fill="#3caeff" stroke-width="0"/><path id="path1" d="M169.97.91l1.83,1.83v3.15h5.97c.32,0,.63.13.86.36l9.82,9.78c.76.76.75,2-.01,2.75l-9.01,8.82c-.32.31-.76.5-1.23.5h-6.41l-1.94-2.25,8.06-.22,8.39-8.28-9.06-9.27h-7.64V.6l.36.31Z" fill="#279ff5" stroke-width="0"/><path id="path2" d="M170.04,1.02l1.76,1.73h12.75l9.78,9.78c.7.7,1.84.7,2.54,0l9.7-9.69h12.75l2.01-2.01-15.93-.21-9.85,10.06-10.29-10.08-15.23.42Z" fill="#50b6ff" stroke-width="0"/><path id="path3" d="M221.44,25.96l-2.12,2.16h-6.5c-.4,0-.77-.16-1.05-.43l-8.95-8.95c-.81-.8-.81-2.1,0-2.9l9.42-9.42c.34-.34.79-.52,1.26-.52h5.81v-3.04l2.13-2.08.13,7.33-7.97.15-8.9,8.95,8.63,8.51h8.25l-.14.25Z" fill="#34a2f2" stroke-width="0"/><path id="path4" d="M169.61,33.87l.18-8.15,2.01,2.38v3.56h12.1c.12,0,.22-.04.29-.13l9.97-9.97c.82-.82,2.14-.81,2.94.01l9.73,9.92c.07.07.18.13.29.13h12.24l-.05-3.51,2.3-2.57-.06,8.39h-15.43l-10.53-10.48-10.48,10.48-15.5-.06Z" fill="#43b9f2" stroke-width="0"/><polygon id="polygon4" points="221.55 25.7 221.55 33.94 206.12 33.94 195.58 23.46 185.11 33.93 169.61 33.93 169.61 25.63 177.94 25.63 186.32 17.36 177.26 8.08 169.61 8.08 169.61 .6 185.25 .6 195.55 10.68 205.41 .62 221.55 .62 221.55 8.08 213.57 8.08 204.68 17.17 213.31 25.7 221.55 25.7" fill="none" stroke="#5d73cb" stroke-miterlimit="1.05" stroke-width="1.15"/></g><path id="S" d="M162.8.6h-45.45c-2.91,0-5.28,2.37-5.28,5.28v10.04c0,2.92,2.37,5.28,5.28,5.28h31.71v4.53h-36.98v8.21h45.45c2.91,0,5.28-2.37,5.28-5.28v-10.22c0-2.92-2.37-5.28-5.28-5.28h-31.82v-5.04h32.07l5.03-7.53Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="1.05" stroke-width="1.05"/><path id="C" d="M105.56.53h-41.41c-2.91,0-5.28,2.37-5.28,5.28v22.82c0,2.93,2.38,5.32,5.32,5.32h40.34v-8.29h-31.86V8.19h27.57l5.33-7.65Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="1.05" stroke-width="1.05"/><path id="P" d="M.52,5.81C.52,2.89,2.89.52,5.81.52h40.87c2.9,0,5.26,2.36,5.26,5.26v14.6c0,2.92-2.37,5.28-5.29,5.28l-29.74-.06,6.72-7.53h14.64v-9.95H14.67v25.81H.52V5.81Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="1.05" stroke-width="1.05"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -103,7 +103,7 @@
|
||||
<file>icons/black/svg/window-2-line.svg</file>
|
||||
<file>icons/black/svg/zoom-in-line.svg</file>
|
||||
<file>icons/black/svg/zoom-out-line.svg</file>
|
||||
<file>icons/logo.png</file>
|
||||
<file>icons/PCSX2logo.svg</file>
|
||||
<file>icons/QT.png</file>
|
||||
<file>icons/update.png</file>
|
||||
<file>icons/white/index.theme</file>
|
||||
|
||||
@@ -1455,7 +1455,7 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode, bool transition_t
|
||||
}
|
||||
isSeeking = true;
|
||||
}
|
||||
else if(!drive_speed_change_cycles)
|
||||
else if (!drive_speed_change_cycles)
|
||||
{
|
||||
CDVD_LOG("CdSeek Begin > Contiguous block without seek - delta=%d sectors", delta);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "common/Pcsx2Defs.h"
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
class Error;
|
||||
|
||||
@@ -222,7 +222,7 @@ bool IOCtlSrc::ReadDVDInfo()
|
||||
{
|
||||
Console.Warning("IOCTL_DVD_READ_STRUCTURE not supported");
|
||||
}
|
||||
else if(GetLastError() != ERROR_UNRECOGNIZED_MEDIA) // ERROR_UNRECOGNIZED_MEDIA means probably a CD or no disc
|
||||
else if (GetLastError() != ERROR_UNRECOGNIZED_MEDIA) // ERROR_UNRECOGNIZED_MEDIA means probably a CD or no disc
|
||||
{
|
||||
Console.Warning("IOCTL Unknown Error %d", GetLastError());
|
||||
}
|
||||
|
||||
@@ -1237,9 +1237,16 @@ fixup_file_properties(PCSX2)
|
||||
force_include_last(PCSX2_FLAGS "/(usr|local)/include/?$")
|
||||
|
||||
if (APPLE)
|
||||
find_library(APPKIT_LIBRARY AppKit)
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
find_library(METAL_LIBRARY Metal)
|
||||
find_library(QUARTZCORE_LIBRARY QuartzCore)
|
||||
target_link_libraries(PCSX2_FLAGS INTERFACE ${METAL_LIBRARY} ${QUARTZCORE_LIBRARY})
|
||||
target_link_libraries(PCSX2_FLAGS INTERFACE
|
||||
${APPKIT_LIBRARY}
|
||||
${IOKIT_LIBRARY}
|
||||
${METAL_LIBRARY}
|
||||
${QUARTZCORE_LIBRARY}
|
||||
)
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL PROPERTY PCSX2_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
@@ -1286,7 +1293,11 @@ function(setup_main_executable target)
|
||||
|
||||
# Copy dependency libraries.
|
||||
set(DEPS_BINDIR "${CMAKE_SOURCE_DIR}/deps/bin")
|
||||
set(DEPS_TO_COPY freetype.dll harfbuzz.dll jpeg62.dll libpng16.dll libsharpyuv.dll libwebp.dll lz4.dll SDL3.dll shaderc_shared.dll zlib1.dll zstd.dll kddockwidgets-qt62.dll plutovg.dll plutosvg.dll)
|
||||
set(DEPS_TO_COPY freetype.dll harfbuzz.dll jpeg62.dll libpng16.dll libsharpyuv.dll libwebp.dll lz4.dll SDL3.dll shaderc_shared.dll zlib1.dll zstd.dll plutovg.dll plutosvg.dll)
|
||||
set(DEPS_TO_COPY
|
||||
$<IF:$<CONFIG:Debug>,kddockwidgets-qt6d.dll,kddockwidgets-qt6.dll>
|
||||
${DEPS_TO_COPY}
|
||||
)
|
||||
foreach(DEP_TO_COPY ${DEPS_TO_COPY})
|
||||
install(FILES "${DEPS_BINDIR}/${DEP_TO_COPY}" DESTINATION "${CMAKE_SOURCE_DIR}/bin")
|
||||
endforeach()
|
||||
|
||||
@@ -33,7 +33,7 @@ struct BreakPoint
|
||||
bool temporary = false;
|
||||
bool stepping = false;
|
||||
|
||||
bool hasCond;
|
||||
bool hasCond = false;
|
||||
BreakPointCond cond;
|
||||
BreakPointCpu cpu;
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ static __ri void DmaExec( void (*func)(), u32 mem, u32 value )
|
||||
cpuClearInt( 10 );
|
||||
QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel
|
||||
}
|
||||
else if(channel == 2)
|
||||
else if (channel == 2)
|
||||
{
|
||||
cpuClearInt( 11 );
|
||||
QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel
|
||||
@@ -274,7 +274,7 @@ static __ri void DmaExec( void (*func)(), u32 mem, u32 value )
|
||||
{
|
||||
func();
|
||||
}
|
||||
else if(reg.chcr.STR)
|
||||
else if (reg.chcr.STR)
|
||||
{
|
||||
//DevCon.Warning(L"32bit %s DMA Start while DMAC Disabled\n", ChcrName(mem));
|
||||
QueuedDMA._u16 |= (1 << ChannelNumber(mem)); //Queue the DMA up to be started then the DMA's are Enabled and or the Suspend is lifted
|
||||
|
||||
@@ -20,7 +20,11 @@ There are a number of ways to help the project, whether it be bug reporting, gam
|
||||
|
||||
* Want to make changes to emulator code? [Check out the issue tracker](https://github.com/PCSX2/pcsx2/issues), or [fork the PCSX2 repository and work on your own ideas](https://github.com/PCSX2/pcsx2).
|
||||
* Want to patch games? [Check out the cheats and patches forum thread for inspiration](https://forums.pcsx2.net/Thread-Post-your-PCSX2-cheats-patches-here). There are other threads to find as well, [such as those dedicated to 60 FPS patches](https://forums.pcsx2.net/Thread-60-fps-codes) or [widescreen patches](https://forums.pcsx2.net/Thread-PCSX2-Widescreen-Game-Patches).
|
||||
<<<<<<< HEAD
|
||||
* Want to report bugs you have discovered in your games? Head over to [the Bug Reporting section of the PCSX2 forums](https://forums.pcsx2.net/Forum-Bug-reporting), to [the PCSX2 Discord](https://pcsx2.net/discord), or to [the GitHub issues section](https://github.com/PCSX2/pcsx2/issues).
|
||||
=======
|
||||
* Want to report bugs you have discovered in your games? [Head over to the Bug Reporting section of the PCSX2 forums](https://forums.pcsx2.net/Forum-Bug-reporting). Also check out our [Issue reporting guide](https://pcsx2.net/docs/troubleshooting/identify) for info on how to better report to us issues.
|
||||
>>>>>>> 091a4ee5a (docs: update in order to redirect from the GH wiki to our website)
|
||||
* Want to update us on the compatibility of your games? [Take a look at the Public Compatibility List on the PCSX2 forums](https://forums.pcsx2.net/Forum-Public-compatibility-list)
|
||||
* Want to improve the PCSX2 wiki? [Here is how to contribute](https://wiki.pcsx2.net/How_to_contribute)
|
||||
|
||||
@@ -120,9 +124,7 @@ If you are using a disc:
|
||||
Fast Boot, enabled by default, will directly mount and launch the game without first launching the PS2 BIOS. You may disable this in Settings > BIOS > Fast Boot if you wish to see the BIOS startup animation or if Fast Boot is causing an issue.
|
||||
|
||||
### Question 18: How do I build the PCSX2 source code?
|
||||
* [Windows build guide](https://github.com/PCSX2/pcsx2/wiki/12-Building-on-Windows)
|
||||
* [Linux build guide](https://github.com/PCSX2/pcsx2/wiki/10-Building-on-Linux)
|
||||
* [macOS build guide](https://github.com/PCSX2/pcsx2/wiki/11-Building-on-MacOS)
|
||||
Have a nice [building guide](https://pcsx2.net/docs/advanced/building) :) .
|
||||
|
||||
### Question 19: When will the next version be released?
|
||||
It will be released when it is ready. Please don't waste your time and ours asking when.
|
||||
|
||||
@@ -249,7 +249,6 @@ void CTC1() {
|
||||
|
||||
void CVT_S() {
|
||||
_FdValf_ = (float)_FsValSl_;
|
||||
_FdValf_ = fpuDouble( _FdValUl_ );
|
||||
}
|
||||
|
||||
void CVT_W() {
|
||||
|
||||
@@ -339,7 +339,7 @@ void GSClut::Read(const GIFRegTEX0& TEX0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(TEX0.CPSM == PSMCT16 || TEX0.CPSM == PSMCT16S)
|
||||
else if (TEX0.CPSM == PSMCT16 || TEX0.CPSM == PSMCT16S)
|
||||
{
|
||||
switch(TEX0.PSM)
|
||||
{
|
||||
@@ -462,7 +462,8 @@ void GSClut::GetAlphaMinMax32(int& amin_out, int& amax_out)
|
||||
{
|
||||
// call only after Read32
|
||||
|
||||
pxAssert(!m_read.dirty);
|
||||
if (m_read.dirty)
|
||||
GL_INS("GSClut: GetAlphaMinMax32 m_read.dirty");
|
||||
|
||||
if (m_read.adirty)
|
||||
{
|
||||
|
||||
@@ -70,6 +70,7 @@ GSLocalMemory::GSLocalMemory()
|
||||
psm.wfa = &GSLocalMemory::WritePixel32;
|
||||
psm.bpp = psm.trbpp = 32;
|
||||
psm.pal = 0;
|
||||
psm.cs = GSVector2i(8, 2);
|
||||
psm.bs = GSVector2i(8, 8);
|
||||
psm.pgs = GSVector2i(64, 32);
|
||||
psm.msk = 0xff;
|
||||
@@ -197,6 +198,11 @@ GSLocalMemory::GSLocalMemory()
|
||||
m_psm[PSMCT16].fmt = m_psm[PSMZ16].fmt = PSM_FMT_16;
|
||||
m_psm[PSMCT16S].fmt = m_psm[PSMZ16S].fmt = PSM_FMT_16;
|
||||
|
||||
m_psm[PSGPU24].cs = GSVector2i(16, 2);
|
||||
m_psm[PSMCT16].cs = m_psm[PSMCT16S].bs = GSVector2i(16, 2);
|
||||
m_psm[PSMT8].cs = GSVector2i(16, 4);
|
||||
m_psm[PSMT4].cs = GSVector2i(32, 4);
|
||||
m_psm[PSMZ16].cs = m_psm[PSMZ16S].bs = GSVector2i(16, 2);
|
||||
|
||||
m_psm[PSGPU24].bs = GSVector2i(16, 8);
|
||||
m_psm[PSMCT16].bs = m_psm[PSMCT16S].bs = GSVector2i(16, 8);
|
||||
|
||||
@@ -460,7 +460,7 @@ public:
|
||||
readTexture rtx, rtxP;
|
||||
readTextureBlock rtxb, rtxbP;
|
||||
u16 bpp, trbpp, pal, fmt;
|
||||
GSVector2i bs, pgs;
|
||||
GSVector2i cs, bs, pgs;
|
||||
u8 msk, depth;
|
||||
u32 fmsk;
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ static __fi bool IsFirstProvokingVertex()
|
||||
return (GSIsHardwareRenderer() && !g_gs_device->Features().provoking_vertex_last);
|
||||
}
|
||||
|
||||
constexpr int GSState::GetSaveStateSize()
|
||||
constexpr int GSState::GetSaveStateSize(int version)
|
||||
{
|
||||
int size = 0;
|
||||
|
||||
@@ -78,6 +78,19 @@ constexpr int GSState::GetSaveStateSize()
|
||||
|
||||
size += sizeof(m_tr.x);
|
||||
size += sizeof(m_tr.y);
|
||||
if (version >= 9)
|
||||
{
|
||||
size += sizeof(m_tr.w);
|
||||
size += sizeof(m_tr.h);
|
||||
size += sizeof(m_tr.m_blit);
|
||||
size += sizeof(m_tr.m_pos);
|
||||
size += sizeof(m_tr.m_reg);
|
||||
size += sizeof(m_tr.rect);
|
||||
size += sizeof(m_tr.total);
|
||||
size += sizeof(m_tr.start);
|
||||
size += sizeof(m_tr.end);
|
||||
size += sizeof(m_tr.write);
|
||||
}
|
||||
size += GSLocalMemory::m_vmsize;
|
||||
size += (sizeof(GIFPath::tag) + sizeof(GIFPath::reg)) * 4 /* std::size(GSState::m_path) */; // std::size won't work without an instance.
|
||||
size += sizeof(m_q);
|
||||
@@ -1445,10 +1458,10 @@ void GSState::GIFRegHandlerTRXDIR(const GIFReg* RESTRICT r)
|
||||
switch (m_env.TRXDIR.XDIR)
|
||||
{
|
||||
case 0: // host -> local
|
||||
m_tr.Init(m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, m_env.BITBLTBUF, true);
|
||||
m_tr.Init(m_env.TRXPOS, m_env.TRXREG, m_env.BITBLTBUF, true);
|
||||
break;
|
||||
case 1: // local -> host
|
||||
m_tr.Init(m_env.TRXPOS.SSAX, m_env.TRXPOS.SSAY, m_env.BITBLTBUF, false);
|
||||
m_tr.Init(m_env.TRXPOS, m_env.TRXREG, m_env.BITBLTBUF, false);
|
||||
break;
|
||||
case 2: // local -> local
|
||||
CheckWriteOverlap(true, true);
|
||||
@@ -1549,16 +1562,13 @@ void GSState::FlushWrite()
|
||||
|
||||
GSVector4i r;
|
||||
|
||||
r.left = m_env.TRXPOS.DSAX;
|
||||
r.top = m_env.TRXPOS.DSAY;
|
||||
r.right = r.left + m_env.TRXREG.RRW;
|
||||
r.bottom = r.top + m_env.TRXREG.RRH;
|
||||
r = m_tr.rect;
|
||||
|
||||
InvalidateVideoMem(m_env.BITBLTBUF, r);
|
||||
|
||||
const GSLocalMemory::writeImage wi = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].wi;
|
||||
|
||||
wi(m_mem, m_tr.x, m_tr.y, &m_tr.buff[m_tr.start], len, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG);
|
||||
wi(m_mem, m_tr.x, m_tr.y, &m_tr.buff[m_tr.start], len, m_tr.m_blit, m_tr.m_pos, m_tr.m_reg);
|
||||
|
||||
m_tr.start += len;
|
||||
|
||||
@@ -1931,12 +1941,9 @@ void GSState::Write(const u8* mem, int len)
|
||||
if (m_env.TRXDIR.XDIR == 3)
|
||||
return;
|
||||
|
||||
const int w = m_env.TRXREG.RRW;
|
||||
const int h = m_env.TRXREG.RRH;
|
||||
|
||||
CheckWriteOverlap(true, false);
|
||||
|
||||
if (!m_tr.Update(w, h, GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].trbpp, len))
|
||||
if (!m_tr.Update(m_tr.w, m_tr.h, GSLocalMemory::m_psm[m_tr.m_blit.DPSM].trbpp, len))
|
||||
{
|
||||
m_env.TRXDIR.XDIR = 3;
|
||||
return;
|
||||
@@ -1949,10 +1956,7 @@ void GSState::Write(const u8* mem, int len)
|
||||
{
|
||||
GSVector4i r;
|
||||
|
||||
r.left = m_env.TRXPOS.DSAX;
|
||||
r.top = m_env.TRXPOS.DSAY;
|
||||
r.right = r.left + m_env.TRXREG.RRW;
|
||||
r.bottom = r.top + m_env.TRXREG.RRH;
|
||||
r = m_tr.rect;
|
||||
|
||||
s_last_transfer_draw_n = s_n;
|
||||
// Store the transfer for preloading new RT's.
|
||||
@@ -1974,15 +1978,15 @@ void GSState::Write(const u8* mem, int len)
|
||||
|
||||
GL_CACHE("Write! %u ... => 0x%x W:%d F:%s (DIR %d%d), dPos(%d %d) size(%d %d) draw %d", s_transfer_n,
|
||||
blit.DBP, blit.DBW, psm_str(blit.DPSM),
|
||||
m_env.TRXPOS.DIRX, m_env.TRXPOS.DIRY,
|
||||
m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, w, h, s_n);
|
||||
m_tr.m_pos.DIRX, m_tr.m_pos.DIRY,
|
||||
m_tr.x, m_tr.y, m_tr.w, m_tr.h, s_n);
|
||||
|
||||
if (len >= m_tr.total)
|
||||
{
|
||||
// received all data in one piece, no need to buffer it
|
||||
InvalidateVideoMem(blit, r);
|
||||
|
||||
psm.wi(m_mem, m_tr.x, m_tr.y, mem, m_tr.total, blit, m_env.TRXPOS, m_env.TRXREG);
|
||||
psm.wi(m_mem, m_tr.x, m_tr.y, mem, m_tr.total, blit, m_tr.m_pos, m_tr.m_reg);
|
||||
|
||||
m_tr.start = m_tr.end = m_tr.total;
|
||||
|
||||
@@ -2260,7 +2264,7 @@ void GSState::Move()
|
||||
vm[doff] = (vm[doff] & 0xff000000) | (vm[soff] & 0x00ffffff);
|
||||
});
|
||||
}
|
||||
else // if(spsm.trbpp == 16)
|
||||
else // if (spsm.trbpp == 16)
|
||||
{
|
||||
u16* vm = m_mem.vm16();
|
||||
copy(dpo.assertSizesMatch(GSLocalMemory::swizzle16), spo.assertSizesMatch(GSLocalMemory::swizzle16), [vm](u32 doff, u32 soff)
|
||||
@@ -2334,7 +2338,7 @@ void GSState::ReadLocalMemoryUnsync(u8* mem, int qwc, GIFRegBITBLTBUF BITBLTBUF,
|
||||
GSTransferBuffer tb;
|
||||
|
||||
if(m_tr.end >= m_tr.total || m_tr.write == true)
|
||||
tb.Init(TRXPOS.SSAX, TRXPOS.SSAY, BITBLTBUF, false);
|
||||
tb.Init(TRXPOS, TRXREG, BITBLTBUF, false);
|
||||
|
||||
int len = qwc * 16;
|
||||
if (!tb.Update(w, h, bpp, len))
|
||||
@@ -2578,13 +2582,14 @@ static void ReadState(T* dst, u8*& src, size_t len = sizeof(T))
|
||||
|
||||
int GSState::Freeze(freezeData* fd, bool sizeonly)
|
||||
{
|
||||
const u32 version = STATE_VERSION;
|
||||
if (sizeonly)
|
||||
{
|
||||
fd->size = GetSaveStateSize();
|
||||
fd->size = GetSaveStateSize(version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!fd->data || fd->size < GetSaveStateSize())
|
||||
if (!fd->data || fd->size < GetSaveStateSize(version))
|
||||
return -1;
|
||||
|
||||
Flush(GSFlushReason::SAVESTATE);
|
||||
@@ -2593,7 +2598,6 @@ int GSState::Freeze(freezeData* fd, bool sizeonly)
|
||||
ReadbackTextureCache();
|
||||
|
||||
u8* data = fd->data;
|
||||
const u32 version = STATE_VERSION;
|
||||
|
||||
WriteState(data, &version);
|
||||
WriteState(data, &m_env.PRIM);
|
||||
@@ -2636,6 +2640,18 @@ int GSState::Freeze(freezeData* fd, bool sizeonly)
|
||||
data += sizeof(GIFReg); // obsolite
|
||||
WriteState(data, &m_tr.x);
|
||||
WriteState(data, &m_tr.y);
|
||||
// Version 9 up.
|
||||
WriteState(data, &m_tr.w);
|
||||
WriteState(data, &m_tr.h);
|
||||
WriteState(data, &m_tr.m_blit);
|
||||
WriteState(data, &m_tr.m_pos);
|
||||
WriteState(data, &m_tr.m_reg);
|
||||
WriteState(data, &m_tr.rect);
|
||||
WriteState(data, &m_tr.total);
|
||||
WriteState(data, &m_tr.start);
|
||||
WriteState(data, &m_tr.end);
|
||||
WriteState(data, &m_tr.write);
|
||||
// End of version 9 changes.
|
||||
WriteState(data, m_mem.m_vm8, m_mem.m_vmsize);
|
||||
|
||||
for (GIFPath& path : m_path)
|
||||
@@ -2663,15 +2679,15 @@ int GSState::Defrost(const freezeData* fd)
|
||||
if (!fd || !fd->data || fd->size == 0)
|
||||
return -1;
|
||||
|
||||
if (fd->size < GetSaveStateSize())
|
||||
return -1;
|
||||
|
||||
u8* data = fd->data;
|
||||
|
||||
u32 version;
|
||||
|
||||
ReadState(&version, data);
|
||||
|
||||
if (fd->size < GetSaveStateSize(version))
|
||||
return -1;
|
||||
|
||||
if (version > STATE_VERSION)
|
||||
{
|
||||
Console.Error("GS: Savestate version is incompatible. Load aborted.");
|
||||
@@ -2701,12 +2717,6 @@ int GSState::Defrost(const freezeData* fd)
|
||||
ReadState(&m_env.TRXPOS, data);
|
||||
ReadState(&m_env.TRXREG, data);
|
||||
ReadState(&m_env.TRXREG, data); // obsolete
|
||||
// Technically this value ought to be saved like m_tr.x/y (break
|
||||
// compatibility) but so far only a single game (Motocross Mania) really
|
||||
// depends on this value (i.e != BITBLTBUF) Savestates are likely done at
|
||||
// VSYNC, so not in the middle of a texture transfer, therefore register
|
||||
// will be set again properly
|
||||
m_tr.m_blit = m_env.BITBLTBUF;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
@@ -2742,9 +2752,36 @@ int GSState::Defrost(const freezeData* fd)
|
||||
data += sizeof(GIFReg); // obsolite
|
||||
ReadState(&m_tr.x, data);
|
||||
ReadState(&m_tr.y, data);
|
||||
ReadState(m_mem.m_vm8, data, m_mem.m_vmsize);
|
||||
|
||||
m_tr.total = 0; // TODO: restore transfer state
|
||||
if (version >= 9)
|
||||
{
|
||||
ReadState(&m_tr.w, data);
|
||||
ReadState(&m_tr.h, data);
|
||||
ReadState(&m_tr.m_blit, data);
|
||||
ReadState(&m_tr.m_pos, data);
|
||||
ReadState(&m_tr.m_reg, data);
|
||||
ReadState(&m_tr.rect, data);
|
||||
ReadState(&m_tr.total, data);
|
||||
ReadState(&m_tr.start, data);
|
||||
ReadState(&m_tr.end, data);
|
||||
ReadState(&m_tr.write, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tr.w = m_env.TRXREG.RRW;
|
||||
m_tr.h = m_env.TRXREG.RRH;
|
||||
m_tr.m_blit = m_env.BITBLTBUF;
|
||||
m_tr.m_pos = m_env.TRXPOS;
|
||||
m_tr.m_reg = m_env.TRXREG;
|
||||
// Assume the last transfer was a write (but nuke it).
|
||||
m_tr.rect = GSVector4i(m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, m_env.TRXPOS.DSAX + m_tr.w, m_env.TRXPOS.DSAY + m_tr.h);
|
||||
m_tr.total = 0;
|
||||
m_tr.start = 0;
|
||||
m_tr.end = 0;
|
||||
m_tr.write = true;
|
||||
}
|
||||
|
||||
ReadState(m_mem.m_vm8, data, m_mem.m_vmsize);
|
||||
|
||||
for (GIFPath& path : m_path)
|
||||
{
|
||||
@@ -3140,7 +3177,8 @@ bool GSState::SpriteDrawWithoutGaps()
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((std::abs(dpX - first_dpX) >= 16 && (i + 2) < m_vertex.next) || std::abs(this_start_X - last_pX) >= 16)
|
||||
const int dpY = v[i + 1].XYZ.Y - v[i].XYZ.Y;
|
||||
if ((std::abs(dpY - first_dpY) >= 16 && (i + 2) < m_vertex.next) || std::abs(this_start_X - last_pX) >= 16)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -3996,8 +4034,14 @@ GSState::TextureMinMaxResult GSState::GetTextureMinMax(GIFRegTEX0 TEX0, GIFRegCL
|
||||
// If it's the start of the texture and our little adjustment is all that pushed it over, clamp it to 0.
|
||||
// This stops the border check failing when using repeat but needed less than the full texture
|
||||
// since this was making it take the full texture even though it wasn't needed.
|
||||
if (!clamp_to_tsize && ((m_vt.m_min.t.floor() == GSVector4::zero()).mask() & 0x3) == 0x3)
|
||||
st = st.max(GSVector4::zero());
|
||||
if (!clamp_to_tsize)
|
||||
{
|
||||
const u32 mask = (m_vt.m_min.t.floor() == GSVector4::zero()).mask();
|
||||
if (mask & 1) // X == 0
|
||||
st.x = st.max(GSVector4::zero()).x;
|
||||
if (mask & 2) // Y == 0
|
||||
st.y = st.max(GSVector4::zero()).y;
|
||||
}
|
||||
}
|
||||
|
||||
// draw will get scissored, adjust UVs to suit
|
||||
@@ -4556,14 +4600,19 @@ GSState::GSTransferBuffer::~GSTransferBuffer()
|
||||
_aligned_free(buff);
|
||||
}
|
||||
|
||||
void GSState::GSTransferBuffer::Init(int tx, int ty, const GIFRegBITBLTBUF& blit, bool is_write)
|
||||
void GSState::GSTransferBuffer::Init(GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG, const GIFRegBITBLTBUF& blit, bool is_write)
|
||||
{
|
||||
x = tx;
|
||||
y = ty;
|
||||
x = is_write ? TRXPOS.DSAX : TRXPOS.SSAX;
|
||||
y = is_write ? TRXPOS.DSAY : TRXPOS.SSAY;
|
||||
w = TRXREG.RRW;
|
||||
h = TRXREG.RRH;
|
||||
rect = GSVector4i(x, y, x + w, y + h);
|
||||
total = 0;
|
||||
start = 0;
|
||||
end = 0;
|
||||
m_blit = blit;
|
||||
m_pos = TRXPOS;
|
||||
m_reg = TRXREG;
|
||||
write = is_write;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
GSState();
|
||||
virtual ~GSState();
|
||||
|
||||
static constexpr int GetSaveStateSize();
|
||||
static constexpr int GetSaveStateSize(int version);
|
||||
|
||||
private:
|
||||
// RESTRICT prevents multiple loads of the same part of the register when accessing its bitfields (the compiler is happy to know that memory writes in-between will not go there)
|
||||
@@ -108,15 +108,19 @@ private:
|
||||
struct GSTransferBuffer
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
int w = 0, h = 0;
|
||||
int start = 0, end = 0, total = 0;
|
||||
u8* buff = nullptr;
|
||||
GSVector4i rect = GSVector4i::zero();
|
||||
GIFRegBITBLTBUF m_blit = {};
|
||||
GIFRegTRXPOS m_pos = {};
|
||||
GIFRegTRXREG m_reg = {};
|
||||
bool write = false;
|
||||
|
||||
GSTransferBuffer();
|
||||
~GSTransferBuffer();
|
||||
|
||||
void Init(int tx, int ty, const GIFRegBITBLTBUF& blit, bool write);
|
||||
void Init(GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG, const GIFRegBITBLTBUF& blit, bool is_write);
|
||||
bool Update(int tw, int th, int bpp, int& len);
|
||||
|
||||
} m_tr;
|
||||
@@ -259,7 +263,7 @@ public:
|
||||
static int s_last_transfer_draw_n;
|
||||
static int s_transfer_n;
|
||||
|
||||
static constexpr u32 STATE_VERSION = 8;
|
||||
static constexpr u32 STATE_VERSION = 9;
|
||||
|
||||
enum REG_DIRTY
|
||||
{
|
||||
|
||||
@@ -68,6 +68,7 @@ const char* shaderName(ShaderConvert value)
|
||||
case ShaderConvert::DEPTH_COPY: return "ps_depth_copy";
|
||||
case ShaderConvert::DOWNSAMPLE_COPY: return "ps_downsample_copy";
|
||||
case ShaderConvert::RGBA_TO_8I: return "ps_convert_rgba_8i";
|
||||
case ShaderConvert::RGB5A1_TO_8I: return "ps_convert_rgb5a1_8i";
|
||||
case ShaderConvert::CLUT_4: return "ps_convert_clut_4";
|
||||
case ShaderConvert::CLUT_8: return "ps_convert_clut_8";
|
||||
case ShaderConvert::YUV: return "ps_yuv";
|
||||
@@ -493,6 +494,7 @@ GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int width, int height, i
|
||||
{
|
||||
ERROR_LOG("GS: Memory allocation failure for {}x{} texture. Purging pool and retrying.", size.x, size.y);
|
||||
PurgePool();
|
||||
t = CreateSurface(type, size.x, size.y, levels, format);
|
||||
if (!t)
|
||||
{
|
||||
ERROR_LOG("GS: Memory allocation failure for {}x{} texture after purging pool.", size.x, size.y);
|
||||
|
||||
@@ -44,6 +44,7 @@ enum class ShaderConvert
|
||||
DEPTH_COPY,
|
||||
DOWNSAMPLE_COPY,
|
||||
RGBA_TO_8I,
|
||||
RGB5A1_TO_8I,
|
||||
CLUT_4,
|
||||
CLUT_8,
|
||||
YUV,
|
||||
@@ -372,6 +373,7 @@ struct alignas(16) GSHWDrawConfig
|
||||
|
||||
// Others ways to fetch the texture
|
||||
u32 channel : 3;
|
||||
u32 channel_fb : 1;
|
||||
|
||||
// Dithering
|
||||
u32 dither : 2;
|
||||
@@ -410,7 +412,7 @@ struct alignas(16) GSHWDrawConfig
|
||||
{
|
||||
const u32 sw_blend_bits = blend_a | blend_b | blend_d;
|
||||
const bool sw_blend_needs_rt = (sw_blend_bits != 0 && ((sw_blend_bits | blend_c) & 1u)) || ((a_masked & blend_c) != 0);
|
||||
return tex_is_fb || fbmask || (date > 0 && date != 3) || sw_blend_needs_rt;
|
||||
return channel_fb || tex_is_fb || fbmask || (date > 0 && date != 3) || sw_blend_needs_rt;
|
||||
}
|
||||
|
||||
/// Disables color output from the pixel shader, this is done when all channels are masked.
|
||||
@@ -934,7 +936,8 @@ public:
|
||||
__fi bool IsPresentThrottleAllowed() const { return m_allow_present_throttle; }
|
||||
|
||||
__fi GSTexture* GetCurrent() const { return m_current; }
|
||||
|
||||
__fi GSTexture* GetMAD() const { return m_mad; }
|
||||
|
||||
void Recycle(GSTexture* t);
|
||||
|
||||
/// Returns true if it's an OpenGL-based renderer.
|
||||
|
||||
@@ -118,6 +118,18 @@ bool GSRenderer::Merge(int field)
|
||||
if (!tex[0] && !tex[1])
|
||||
{
|
||||
m_real_size = GSVector2i(0, 0);
|
||||
|
||||
// Clear out the MAD buffer as some remnants of the previously shown frame came be left over, causing a flash for one frame.
|
||||
if (GSConfig.InterlaceMode == GSInterlaceMode::Automatic || GSConfig.InterlaceMode >= GSInterlaceMode::AdaptiveTFF)
|
||||
{
|
||||
GSTexture* mad_tex = g_gs_device->GetMAD();
|
||||
|
||||
if (mad_tex)
|
||||
{
|
||||
g_gs_device->ClearRenderTarget(mad_tex, 0);
|
||||
mad_tex = nullptr;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1236,36 +1236,18 @@ void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
|
||||
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
|
||||
D3D11_BOX box = {(UINT)r.left, (UINT)r.top, 0U, (UINT)r.right, (UINT)r.bottom, 1U};
|
||||
D3D11_BOX box = {static_cast<UINT>(r.left), static_cast<UINT>(r.top), 0U, static_cast<UINT>(r.right), static_cast<UINT>(r.bottom), 1U};
|
||||
|
||||
// DX api isn't happy if we pass a box for depth copy
|
||||
// It complains that depth/multisample must be a full copy
|
||||
// and asks us to use a NULL for the box
|
||||
// DX11 doesn't support partial depth copy so we need to
|
||||
// either pass a nullptr D3D11_BOX for a full depth copy or use CopyResource instead.
|
||||
// Alternatively use shader copy StretchRect, or full depth copy with
|
||||
// adjusting the scissor and UVs in the shader.
|
||||
const bool depth = (sTex->GetType() == GSTexture::Type::DepthStencil);
|
||||
auto pBox = depth ? nullptr : &box;
|
||||
const u32 x = depth ? 0 : destX;
|
||||
const u32 y = depth ? 0 : destY;
|
||||
|
||||
m_ctx->CopySubresourceRegion(*(GSTexture11*)dTex, 0, destX, destY, 0, *(GSTexture11*)sTex, 0, pBox);
|
||||
}
|
||||
|
||||
void GSDevice11::CloneTexture(GSTexture* src, GSTexture** dest, const GSVector4i& rect)
|
||||
{
|
||||
pxAssertMsg(src->GetType() == GSTexture::Type::DepthStencil || src->GetType() == GSTexture::Type::RenderTarget, "Source is RT or DS.");
|
||||
CommitClear(src);
|
||||
|
||||
const int w = src->GetWidth();
|
||||
const int h = src->GetHeight();
|
||||
|
||||
if (src->GetType() == GSTexture::Type::DepthStencil)
|
||||
{
|
||||
// DX11 requires that you copy the entire depth buffer.
|
||||
*dest = CreateDepthStencil(w, h, src->GetFormat(), false);
|
||||
CopyRect(src, *dest, GSVector4i(0, 0, w, h), 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest = CreateRenderTarget(w, h, src->GetFormat(), false);
|
||||
CopyRect(src, *dest, rect, rect.left, rect.top);
|
||||
}
|
||||
m_ctx->CopySubresourceRegion(*(GSTexture11*)dTex, 0, x, y, 0, *(GSTexture11*)sTex, 0, pBox);
|
||||
}
|
||||
|
||||
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
|
||||
@@ -1435,14 +1417,14 @@ void GSDevice11::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offs
|
||||
{
|
||||
float scale;
|
||||
float pad1[3];
|
||||
u32 SBW, DBW, pad3;
|
||||
u32 SBW, DBW, SPSM;
|
||||
};
|
||||
|
||||
const Uniforms cb = {sScale, {}, SBW, DBW};
|
||||
const Uniforms cb = {sScale, {}, SBW, DBW, SPSM};
|
||||
m_ctx->UpdateSubresource(m_merge.cb.get(), 0, nullptr, &cb, 0, 0);
|
||||
|
||||
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
|
||||
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
|
||||
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
|
||||
StretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
|
||||
}
|
||||
|
||||
@@ -2495,20 +2477,9 @@ D3D_SHADER_MACRO* GSDevice11::ShaderMacro::GetPtr()
|
||||
return (D3D_SHADER_MACRO*)mout.data();
|
||||
}
|
||||
|
||||
/// Checks that we weren't sent things we declared we don't support
|
||||
/// Clears things we don't support that can be quietly disabled
|
||||
static void preprocessSel(GSDevice11::PSSelector& sel)
|
||||
{
|
||||
pxAssert(sel.write_rg == 0); // Not supported, shouldn't be sent
|
||||
}
|
||||
|
||||
void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
{
|
||||
pxAssert(!config.require_full_barrier); // We always specify no support so it shouldn't request this
|
||||
preprocessSel(config.ps);
|
||||
|
||||
GSVector2i rtsize = (config.rt ? config.rt : config.ds)->GetSize();
|
||||
|
||||
const GSVector2i rtsize = (config.rt ? config.rt : config.ds)->GetSize();
|
||||
GSTexture* colclip_rt = g_gs_device->GetColorClipTexture();
|
||||
|
||||
if (colclip_rt)
|
||||
@@ -2536,15 +2507,17 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
{
|
||||
config.colclip_update_area = config.drawarea;
|
||||
|
||||
const GSVector4 dRect = GSVector4((config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly) ? GSVector4i::loadh(rtsize) : config.drawarea);
|
||||
const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy();
|
||||
colclip_rt = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::ColorClip);
|
||||
if (!colclip_rt)
|
||||
{
|
||||
Console.Warning("D3D11: Failed to allocate ColorClip render target, aborting draw.");
|
||||
return;
|
||||
}
|
||||
|
||||
g_gs_device->SetColorClipTexture(colclip_rt);
|
||||
// Warning: StretchRect must be called before BeginScene otherwise
|
||||
// vertices will be overwritten. Trust me you don't want to do that.
|
||||
|
||||
const GSVector4 dRect = GSVector4((config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly) ? GSVector4i::loadh(rtsize) : config.drawarea);
|
||||
const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy();
|
||||
StretchRect(config.rt, sRect, colclip_rt, dRect, ShaderConvert::COLCLIP_INIT, false);
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
}
|
||||
@@ -2555,12 +2528,16 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
{
|
||||
primid_tex = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::PrimID, false);
|
||||
if (!primid_tex)
|
||||
{
|
||||
Console.WriteLn("D3D11: Failed to allocate DATE image, aborting draw.");
|
||||
return;
|
||||
}
|
||||
|
||||
StretchRect(colclip_rt ? colclip_rt : config.rt, GSVector4(config.drawarea) / GSVector4(rtsize).xyxy(),
|
||||
primid_tex, GSVector4(config.drawarea), m_date.primid_init_ps[static_cast<u8>(config.datm)].get(), nullptr, false);
|
||||
}
|
||||
else if (config.destination_alpha != GSHWDrawConfig::DestinationAlphaMode::Off)
|
||||
else if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
|
||||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne)
|
||||
{
|
||||
const GSVector4 src = GSVector4(config.drawarea) / GSVector4(config.ds->GetSize()).xyxy();
|
||||
const GSVector4 dst = src * 2.0f - 1.0f;
|
||||
@@ -2630,21 +2607,39 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
PSSetShaderResource(1, config.pal);
|
||||
}
|
||||
|
||||
GSTexture* rt_copy = nullptr;
|
||||
if (config.require_one_barrier || (config.tex && config.tex == config.rt)) // Used as "bind rt" flag when texture barrier is unsupported.
|
||||
GSTexture* draw_rt_clone = nullptr;
|
||||
|
||||
if (config.require_one_barrier || (config.tex && config.tex == config.rt))
|
||||
{
|
||||
// Bind the RT.This way special effect can use it.
|
||||
// Do not always bind the rt when it's not needed,
|
||||
// only bind it when effects use it such as fbmask emulation currently
|
||||
// because we copy the frame buffer and it is quite slow.
|
||||
CloneTexture(colclip_rt ? colclip_rt : config.rt, &rt_copy, config.drawarea);
|
||||
if (rt_copy)
|
||||
// Requires a copy of the RT.
|
||||
// Used as "bind rt" flag when texture barrier is unsupported for tex is fb.
|
||||
draw_rt_clone = CreateTexture(rtsize.x, rtsize.y, 1, colclip_rt ? GSTexture::Format::ColorClip : GSTexture::Format::Color, true);
|
||||
if (draw_rt_clone)
|
||||
{
|
||||
CopyRect(colclip_rt ? colclip_rt : config.rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
|
||||
if (config.require_one_barrier)
|
||||
PSSetShaderResource(2, rt_copy);
|
||||
PSSetShaderResource(2, draw_rt_clone);
|
||||
if (config.tex && config.tex == config.rt)
|
||||
PSSetShaderResource(0, rt_copy);
|
||||
PSSetShaderResource(0, draw_rt_clone);
|
||||
}
|
||||
else
|
||||
Console.Warning("D3D11: Failed to allocate temp texture for RT copy.");
|
||||
|
||||
}
|
||||
|
||||
GSTexture* draw_ds_clone = nullptr;
|
||||
|
||||
if (config.tex && config.tex == config.ds)
|
||||
{
|
||||
// DX requires a copy when sampling the depth buffer.
|
||||
draw_ds_clone = CreateDepthStencil(rtsize.x, rtsize.y, config.ds->GetFormat(), false);
|
||||
if (draw_ds_clone)
|
||||
{
|
||||
CopyRect(config.ds, draw_ds_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
|
||||
PSSetShaderResource(0, draw_ds_clone);
|
||||
}
|
||||
else
|
||||
Console.Warning("D3D11: Failed to allocate temp texture for DS copy.");
|
||||
}
|
||||
|
||||
SetupVS(config.vs, &config.cb_vs);
|
||||
@@ -2681,7 +2676,6 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
|
||||
if (config.alpha_second_pass.enable)
|
||||
{
|
||||
preprocessSel(config.alpha_second_pass.ps);
|
||||
if (config.cb_ps.FogColor_AREF.a != config.alpha_second_pass.ps_aref)
|
||||
{
|
||||
config.cb_ps.FogColor_AREF.a = config.alpha_second_pass.ps_aref;
|
||||
@@ -2697,8 +2691,12 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
|
||||
if (rt_copy)
|
||||
Recycle(rt_copy);
|
||||
if (draw_rt_clone)
|
||||
Recycle(draw_rt_clone);
|
||||
|
||||
if (draw_ds_clone)
|
||||
Recycle(draw_ds_clone);
|
||||
|
||||
if (primid_tex)
|
||||
Recycle(primid_tex);
|
||||
|
||||
|
||||
@@ -291,7 +291,6 @@ public:
|
||||
std::unique_ptr<GSDownloadTexture> CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format) override;
|
||||
|
||||
void CommitClear(GSTexture* t);
|
||||
void CloneTexture(GSTexture* src, GSTexture** dest, const GSVector4i& rect);
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
|
||||
|
||||
|
||||
@@ -703,11 +703,17 @@ bool GSDevice12::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
if (!AcquireWindow(true) || (m_window_info.type != WindowInfo::Type::Surfaceless && !CreateSwapChain()))
|
||||
return false;
|
||||
|
||||
if (!CreateNullTexture())
|
||||
{
|
||||
Host::ReportErrorAsync("GS", "Failed to create dummy texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
std::optional<std::string> shader = ReadShaderSource("shaders/dx11/tfx.fx");
|
||||
if (!shader.has_value())
|
||||
{
|
||||
Host::ReportErrorAsync("GS", "Failed to read shaders/dx11/tfx.fxf.");
|
||||
Host::ReportErrorAsync("GS", "Failed to read shaders/dx11/tfx.fx.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -717,12 +723,6 @@ bool GSDevice12::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
if (!m_shader_cache.Open(m_feature_level, GSConfig.UseDebugDevice))
|
||||
Console.Warning("D3D12: Shader cache failed to open.");
|
||||
|
||||
if (!CreateNullTexture())
|
||||
{
|
||||
Host::ReportErrorAsync("GS", "Failed to create dummy texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CreateRootSignatures())
|
||||
{
|
||||
Host::ReportErrorAsync("GS", "Failed to create pipeline layouts");
|
||||
@@ -1087,7 +1087,14 @@ GSDevice::PresentResult GSDevice12::BeginPresent(bool frame_skip)
|
||||
return PresentResult::DeviceLost;
|
||||
|
||||
if (frame_skip || !m_swap_chain)
|
||||
{
|
||||
if (!m_swap_chain)
|
||||
{
|
||||
ExecuteCommandList(WaitType::None);
|
||||
InvalidateCachedState();
|
||||
}
|
||||
return PresentResult::FrameSkipped;
|
||||
}
|
||||
|
||||
// Check if we lost exclusive fullscreen. If so, notify the host, so it can switch to windowed mode.
|
||||
// This might get called repeatedly if it takes a while to switch back, that's the host's problem.
|
||||
@@ -1479,15 +1486,15 @@ void GSDevice12::ConvertToIndexedTexture(
|
||||
{
|
||||
float scale;
|
||||
float pad1[3];
|
||||
u32 SBW, DBW, pad2;
|
||||
u32 SBW, DBW, SPSM;
|
||||
};
|
||||
|
||||
const Uniforms cb = {sScale, {}, SBW, DBW};
|
||||
const Uniforms cb = {sScale, {}, SBW, DBW, SPSM};
|
||||
SetUtilityRootSignature();
|
||||
SetUtilityPushConstants(&cb, sizeof(cb));
|
||||
|
||||
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
|
||||
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
|
||||
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
|
||||
DoStretchRect(static_cast<GSTexture12*>(sTex), GSVector4::zero(), static_cast<GSTexture12*>(dTex), dRect,
|
||||
m_convert[static_cast<int>(shader)].get(), false, true);
|
||||
}
|
||||
@@ -3821,6 +3828,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
GSTexture12* draw_rt = static_cast<GSTexture12*>(config.rt);
|
||||
GSTexture12* draw_ds = static_cast<GSTexture12*>(config.ds);
|
||||
GSTexture12* draw_rt_clone = nullptr;
|
||||
GSTexture12* draw_ds_clone = nullptr;
|
||||
|
||||
// Align the render area to 128x128, hopefully avoiding render pass restarts for small render area changes (e.g. Ratchet and Clank).
|
||||
const GSVector2i rtsize(config.rt ? config.rt->GetSize() : config.ds->GetSize());
|
||||
@@ -3841,7 +3849,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
colclip_rt->TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
|
||||
draw_rt = static_cast<GSTexture12*>(config.rt);
|
||||
OMSetRenderTargets(draw_rt, draw_ds, config.scissor);
|
||||
OMSetRenderTargets(draw_rt, draw_ds, config.colclip_update_area);
|
||||
|
||||
// if this target was cleared and never drawn to, perform the clear as part of the resolve here.
|
||||
BeginRenderPass(GetLoadOpForTexture(draw_rt), D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||
@@ -3876,7 +3884,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
// bind textures before checking the render pass, in case we need to transition them
|
||||
if (config.tex)
|
||||
{
|
||||
PSSetShaderResource(0, config.tex, config.tex != config.rt);
|
||||
PSSetShaderResource(0, config.tex, config.tex != config.rt && config.tex != config.ds);
|
||||
PSSetSampler(config.sampler);
|
||||
}
|
||||
if (config.pal)
|
||||
@@ -3900,15 +3908,16 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
}
|
||||
}
|
||||
|
||||
if (config.require_one_barrier || (config.tex && config.tex == config.rt)) // Used as "bind rt" flag when texture barrier is unsupported.
|
||||
if (config.require_one_barrier || (config.tex && config.tex == config.rt))
|
||||
{
|
||||
// requires a copy of the RT
|
||||
// Requires a copy of the RT.
|
||||
// Used as "bind rt" flag when texture barrier is unsupported for tex is fb.
|
||||
draw_rt_clone = static_cast<GSTexture12*>(CreateTexture(rtsize.x, rtsize.y, 1, colclip_rt ? GSTexture::Format::ColorClip : GSTexture::Format::Color, true));
|
||||
if (draw_rt_clone)
|
||||
{
|
||||
EndRenderPass();
|
||||
|
||||
GL_PUSH("Copy RT to temp texture for fbmask {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
|
||||
GL_PUSH("D3D12: Copy RT to temp texture {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
|
||||
config.drawarea.width(), config.drawarea.height());
|
||||
|
||||
draw_rt_clone->SetState(GSTexture::State::Invalidated);
|
||||
@@ -3918,6 +3927,27 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
if (config.tex && config.tex == config.rt)
|
||||
PSSetShaderResource(0, draw_rt_clone, true);
|
||||
}
|
||||
else
|
||||
Console.Warning("D3D12: Failed to allocate temp texture for RT copy.");
|
||||
}
|
||||
|
||||
if (config.tex && config.tex == config.ds)
|
||||
{
|
||||
// DX requires a copy when sampling the depth buffer.
|
||||
draw_ds_clone = static_cast<GSTexture12*>(CreateDepthStencil(rtsize.x, rtsize.y, config.ds->GetFormat(), false));
|
||||
if (draw_ds_clone)
|
||||
{
|
||||
EndRenderPass();
|
||||
|
||||
GL_PUSH("D3D12: Copy DS to temp texture {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
|
||||
config.drawarea.width(), config.drawarea.height());
|
||||
|
||||
draw_ds_clone->SetState(GSTexture::State::Invalidated);
|
||||
CopyRect(config.ds, draw_ds_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
|
||||
PSSetShaderResource(0, draw_ds_clone, true);
|
||||
}
|
||||
else
|
||||
Console.Warning("D3D12: Failed to allocate temp texture for DS copy.");
|
||||
}
|
||||
|
||||
// Switch to colclip target for colclip hw rendering
|
||||
@@ -3932,7 +3962,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
colclip_rt = static_cast<GSTexture12*>(CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::ColorClip, false));
|
||||
if (!colclip_rt)
|
||||
{
|
||||
Console.WriteLn("D3D12: Failed to allocate ColorClip render target, aborting draw.");
|
||||
Console.Warning("D3D12: Failed to allocate ColorClip render target, aborting draw.");
|
||||
|
||||
if (date_image)
|
||||
Recycle(date_image);
|
||||
@@ -4012,6 +4042,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
// rt -> colclip hw blit if enabled
|
||||
if (colclip_rt && (config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly || config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertAndResolve) && config.rt->GetState() == GSTexture::State::Dirty)
|
||||
{
|
||||
OMSetRenderTargets(draw_rt, draw_ds, GSVector4i::loadh(rtsize));
|
||||
SetUtilityTexture(static_cast<GSTexture12*>(config.rt), m_point_sampler_cpu);
|
||||
SetPipeline(m_colclip_setup_pipelines[pipe.ds].get());
|
||||
|
||||
@@ -4021,8 +4052,10 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// Restore original scissor, not sure if needed since the render pass has already been started. But to be safe.
|
||||
OMSetRenderTargets(draw_rt, draw_ds, config.scissor);
|
||||
}
|
||||
// VB/IB upload, if we did DATE setup and it's not colclip hw this has already been done
|
||||
SetPrimitiveTopology(s_primitive_topology_mapping[static_cast<u8>(config.topology)]);
|
||||
if (!date_image || colclip_rt)
|
||||
@@ -4066,6 +4099,9 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
if (draw_rt_clone)
|
||||
Recycle(draw_rt_clone);
|
||||
|
||||
if (draw_ds_clone)
|
||||
Recycle(draw_ds_clone);
|
||||
|
||||
if (date_image)
|
||||
Recycle(date_image);
|
||||
|
||||
@@ -4082,7 +4118,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
colclip_rt->TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
|
||||
draw_rt = static_cast<GSTexture12*>(config.rt);
|
||||
OMSetRenderTargets(draw_rt, draw_ds, config.scissor);
|
||||
OMSetRenderTargets(draw_rt, draw_ds, config.colclip_update_area);
|
||||
|
||||
// if this target was cleared and never drawn to, perform the clear as part of the resolve here.
|
||||
BeginRenderPass(GetLoadOpForTexture(draw_rt), D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||
|
||||
@@ -557,26 +557,6 @@ bool GSHwHack::GSC_TalesofSymphonia(GSRendererHW& r, int& skip)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSHwHack::GSC_Simple2000Vol114(GSRendererHW& r, int& skip)
|
||||
{
|
||||
if (skip == 0)
|
||||
{
|
||||
if (!s_nativeres && RTME == 0 && (RFBP == 0x1500) && (RTBP0 == 0x2c97 || RTBP0 == 0x2ace || RTBP0 == 0x03d0 || RTBP0 == 0x2448) && (RFBMSK == 0x0000))
|
||||
{
|
||||
// Don't enable hack on native res if crc is below aggressive.
|
||||
// Upscaling issues, removes glow/blur effect which fixes ghosting.
|
||||
skip = 1;
|
||||
}
|
||||
if (RTME && (RFBP == 0x0e00) && (RTBP0 == 0x1000) && (RFBMSK == 0x0000))
|
||||
{
|
||||
// Depth shadows.
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSHwHack::GSC_UrbanReign(GSRendererHW& r, int& skip)
|
||||
{
|
||||
if (skip == 0)
|
||||
@@ -1419,7 +1399,6 @@ const GSHwHack::Entry<GSRendererHW::GSC_Ptr> GSHwHack::s_get_skip_count_function
|
||||
CRC_F(GSC_SacredBlaze),
|
||||
CRC_F(GSC_GuitarHero),
|
||||
CRC_F(GSC_SakuraWarsSoLongMyLove),
|
||||
CRC_F(GSC_Simple2000Vol114),
|
||||
CRC_F(GSC_SFEX3),
|
||||
CRC_F(GSC_DTGames),
|
||||
CRC_F(GSC_TalesOfLegendia),
|
||||
|
||||
@@ -21,7 +21,6 @@ public:
|
||||
static bool GSC_SakuraWarsSoLongMyLove(GSRendererHW& r, int& skip);
|
||||
static bool GSC_UltramanFightingEvolution(GSRendererHW& r, int& skip);
|
||||
static bool GSC_TalesofSymphonia(GSRendererHW& r, int& skip);
|
||||
static bool GSC_Simple2000Vol114(GSRendererHW& r, int& skip);
|
||||
static bool GSC_UrbanReign(GSRendererHW& r, int& skip);
|
||||
static bool GSC_SteambotChronicles(GSRendererHW& r, int& skip);
|
||||
static bool GSC_BlueTongueGames(GSRendererHW& r, int& skip);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -129,6 +129,7 @@ private:
|
||||
bool ContinueSplitClear();
|
||||
void FinishSplitClear();
|
||||
|
||||
bool NeedsBlending();
|
||||
bool IsRTWritten();
|
||||
bool IsDepthAlwaysPassing();
|
||||
bool IsUsingCsInBlend();
|
||||
@@ -222,8 +223,8 @@ public:
|
||||
GSVector4i ComputeBoundingBox(const GSVector2i& rtsize, float rtscale);
|
||||
void MergeSprite(GSTextureCache::Source* tex);
|
||||
float GetTextureScaleFactor() override;
|
||||
GSVector2i GetValidSize(const GSTextureCache::Source* tex = nullptr);
|
||||
GSVector2i GetTargetSize(const GSTextureCache::Source* tex = nullptr, const bool can_expand = true);
|
||||
GSVector2i GetValidSize(const GSTextureCache::Source* tex = nullptr, const bool is_shuffle = false);
|
||||
GSVector2i GetTargetSize(const GSTextureCache::Source* tex = nullptr, const bool can_expand = true, const bool is_shuffle = false);
|
||||
|
||||
void Reset(bool hardware_reset) override;
|
||||
void UpdateSettings(const Pcsx2Config::GSOptions& old_config) override;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -209,7 +209,7 @@ public:
|
||||
struct TempZAddress
|
||||
{
|
||||
u32 ZBP;
|
||||
u32 offset;
|
||||
int offset;
|
||||
GSVector4i rect_since;
|
||||
};
|
||||
|
||||
@@ -441,7 +441,7 @@ protected:
|
||||
std::unique_ptr<GSDownloadTexture> m_uint16_download_texture;
|
||||
std::unique_ptr<GSDownloadTexture> m_uint32_download_texture;
|
||||
|
||||
Source* CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* t, bool half_right, int x_offset, int y_offset, const GSVector2i* lod, const GSVector4i* src_range, GSTexture* gpu_clut, SourceRegion region);
|
||||
Source* CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* t, int x_offset, int y_offset, const GSVector2i* lod, const GSVector4i* src_range, GSTexture* gpu_clut, SourceRegion region);
|
||||
|
||||
bool PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, const GSVector2i& valid_size, bool is_frame,
|
||||
bool preload, bool preserve_target, const GSVector4i draw_rect, Target* dst, GSTextureCache::Source* src = nullptr);
|
||||
@@ -494,8 +494,8 @@ public:
|
||||
GSTexture* LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVector2i& offset, float* scale, const GSVector2i& size);
|
||||
std::shared_ptr<Palette> LookupPaletteObject(const u32* clut, u16 pal, bool need_gs_texture);
|
||||
|
||||
Source* LookupSource(const bool is_color, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const GSVector2i* lod, const bool possible_shuffle, const bool linear, const u32 frame_fbp = 0xFFFFFFFF, bool req_color = true, bool req_alpha = true);
|
||||
Source* LookupDepthSource(const bool is_depth, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const bool possible_shuffle, const bool linear, const u32 frame_fbp = 0xFFFFFFFF, bool req_color = true, bool req_alpha = true, bool palette = false);
|
||||
Source* LookupSource(const bool is_color, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const GSVector2i* lod, const bool possible_shuffle, const bool linear, const GIFRegFRAME& frame, bool req_color = true, bool req_alpha = true);
|
||||
Source* LookupDepthSource(const bool is_depth, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const bool possible_shuffle, const bool linear, const GIFRegFRAME& frame, bool req_color = true, bool req_alpha = true, bool palette = false);
|
||||
|
||||
Target* FindTargetOverlap(Target* target, int type, int psm);
|
||||
void CombineAlignedInsideTargets(Target* target, GSTextureCache::Source* src = nullptr);
|
||||
|
||||
@@ -270,56 +270,57 @@ std::string GSTextureReplacements::GetDumpFilename(const TextureName& name, u32
|
||||
return ret;
|
||||
|
||||
const std::string game_dir(GetGameTextureDirectory());
|
||||
if (!FileSystem::DirectoryExists(game_dir.c_str()))
|
||||
const std::string game_subdir(Path::Combine(game_dir, TEXTURE_DUMP_SUBDIRECTORY_NAME));
|
||||
|
||||
if (!FileSystem::DirectoryExists(game_subdir.c_str()))
|
||||
{
|
||||
// create both dumps and replacements
|
||||
if (!FileSystem::CreateDirectoryPath(game_dir.c_str(), false) ||
|
||||
!FileSystem::EnsureDirectoryExists(Path::Combine(game_dir, "dumps").c_str(), false) ||
|
||||
!FileSystem::EnsureDirectoryExists(Path::Combine(game_dir, "replacements").c_str(), false))
|
||||
!FileSystem::EnsureDirectoryExists(game_subdir.c_str(), false) ||
|
||||
!FileSystem::EnsureDirectoryExists(Path::Combine(game_dir, TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME).c_str(), false))
|
||||
{
|
||||
// if it fails to create, we're not going to be able to use it anyway
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string game_subdir(Path::Combine(game_dir, TEXTURE_DUMP_SUBDIRECTORY_NAME));
|
||||
|
||||
std::string filename;
|
||||
if (name.HasRegion())
|
||||
{
|
||||
if (name.HasPalette())
|
||||
{
|
||||
filename = (level > 0) ?
|
||||
StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_CLUT_FORMAT_STRING "-mip%u.png",
|
||||
name.TEX0Hash, name.CLUTHash, name.region_width, name.region_height, name.bits, level) :
|
||||
StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_CLUT_FORMAT_STRING ".png",
|
||||
name.TEX0Hash, name.CLUTHash, name.region_width, name.region_height, name.bits);
|
||||
filename = (level > 0)
|
||||
? StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_CLUT_FORMAT_STRING "-mip%u.png",
|
||||
name.TEX0Hash, name.CLUTHash, name.region_width, name.region_height, name.bits, level)
|
||||
: StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_CLUT_FORMAT_STRING ".png",
|
||||
name.TEX0Hash, name.CLUTHash, name.region_width, name.region_height, name.bits);
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = (level > 0) ? StringUtil::StdStringFromFormat(
|
||||
TEXTURE_FILENAME_REGION_FORMAT_STRING "-mip%u.png", name.TEX0Hash,
|
||||
name.region_width, name.region_height, name.bits, level) :
|
||||
StringUtil::StdStringFromFormat(
|
||||
TEXTURE_FILENAME_REGION_FORMAT_STRING ".png", name.TEX0Hash,
|
||||
name.region_width, name.region_height, name.bits);
|
||||
filename = (level > 0)
|
||||
? StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_FORMAT_STRING "-mip%u.png",
|
||||
name.TEX0Hash, name.region_width, name.region_height, name.bits, level)
|
||||
: StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_FORMAT_STRING ".png",
|
||||
name.TEX0Hash, name.region_width, name.region_height, name.bits);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (name.HasPalette())
|
||||
{
|
||||
filename = (level > 0) ? StringUtil::StdStringFromFormat(TEXTURE_FILENAME_CLUT_FORMAT_STRING "-mip%u.png",
|
||||
name.TEX0Hash, name.CLUTHash, name.bits, level) :
|
||||
StringUtil::StdStringFromFormat(TEXTURE_FILENAME_CLUT_FORMAT_STRING ".png",
|
||||
name.TEX0Hash, name.CLUTHash, name.bits);
|
||||
filename = (level > 0)
|
||||
? StringUtil::StdStringFromFormat(TEXTURE_FILENAME_CLUT_FORMAT_STRING "-mip%u.png",
|
||||
name.TEX0Hash, name.CLUTHash, name.bits, level)
|
||||
: StringUtil::StdStringFromFormat(TEXTURE_FILENAME_CLUT_FORMAT_STRING ".png",
|
||||
name.TEX0Hash, name.CLUTHash, name.bits);
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = (level > 0) ? StringUtil::StdStringFromFormat(
|
||||
TEXTURE_FILENAME_FORMAT_STRING "-mip%u.png", name.TEX0Hash, name.bits, level) :
|
||||
StringUtil::StdStringFromFormat(
|
||||
TEXTURE_FILENAME_FORMAT_STRING ".png", name.TEX0Hash, name.bits);
|
||||
filename = (level > 0)
|
||||
? StringUtil::StdStringFromFormat(TEXTURE_FILENAME_FORMAT_STRING "-mip%u.png",
|
||||
name.TEX0Hash, name.bits, level)
|
||||
: StringUtil::StdStringFromFormat(TEXTURE_FILENAME_FORMAT_STRING ".png",
|
||||
name.TEX0Hash, name.bits);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,6 +350,28 @@ void GSTextureReplacements::GameChanged()
|
||||
ClearDumpedTextureList();
|
||||
}
|
||||
|
||||
/// If the given file exists in the given directory, but with a different case than the original file, write its path to `*output` and return true.
|
||||
static bool GetWrongCasePath(std::string* output, const char* dir, std::string_view file, FileSystem::FindResultsArray* reuseme)
|
||||
{
|
||||
if (FileSystem::FindFiles(dir, "*", FILESYSTEM_FIND_FOLDERS | FILESYSTEM_FIND_HIDDEN_FILES, reuseme))
|
||||
{
|
||||
for (const FILESYSTEM_FIND_DATA& fd : *reuseme)
|
||||
{
|
||||
std::string_view name = Path::GetFileName(fd.FileName);
|
||||
if (name.size() != file.size())
|
||||
continue;
|
||||
if (0 == strncmp(name.data(), file.data(), name.size()))
|
||||
continue;
|
||||
if (0 == StringUtil::Strncasecmp(name.data(), file.data(), name.size()))
|
||||
{
|
||||
*output = fd.FileName;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GSTextureReplacements::ReloadReplacementMap()
|
||||
{
|
||||
SyncWorkerThread();
|
||||
@@ -368,9 +391,27 @@ void GSTextureReplacements::ReloadReplacementMap()
|
||||
if (s_current_serial.empty() || !GSConfig.LoadTextureReplacements)
|
||||
return;
|
||||
|
||||
const std::string replacement_dir(Path::Combine(GetGameTextureDirectory(), TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME));
|
||||
const std::string texture_dir = GetGameTextureDirectory();
|
||||
const std::string replacement_dir(Path::Combine(texture_dir, TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME));
|
||||
|
||||
FileSystem::FindResultsArray files;
|
||||
|
||||
// For some reason texture pack authors think it's a good idea to rename the replacements directory to something with the wrong case...
|
||||
std::string wrong_case_path;
|
||||
const std::string* right_case_path = nullptr;
|
||||
if (GetWrongCasePath(&wrong_case_path, EmuFolders::Textures.c_str(), s_current_serial, &files))
|
||||
right_case_path = &texture_dir;
|
||||
else if (GetWrongCasePath(&wrong_case_path, texture_dir.c_str(), TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME, &files))
|
||||
right_case_path = &replacement_dir;
|
||||
if (right_case_path)
|
||||
{
|
||||
Host::AddKeyedOSDMessage("TextureReplacementDirCaseMismatch",
|
||||
fmt::format(TRANSLATE_FS("TextureReplacement", "Texture replacement directory {} will not work on case sensitive filesystems.\n"
|
||||
"Rename it to {} to remove this warning."),
|
||||
wrong_case_path, *right_case_path),
|
||||
Host::OSD_WARNING_DURATION);
|
||||
}
|
||||
|
||||
if (!FileSystem::FindFiles(replacement_dir.c_str(), "*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RECURSIVE, &files))
|
||||
return;
|
||||
|
||||
|
||||
@@ -1713,12 +1713,12 @@ void GSDeviceMTL::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX,
|
||||
|
||||
void GSDeviceMTL::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM)
|
||||
{ @autoreleasepool {
|
||||
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
|
||||
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
|
||||
id<MTLRenderPipelineState> pipeline = m_convert_pipeline[static_cast<int>(shader)];
|
||||
if (!pipeline)
|
||||
[NSException raise:@"StretchRect Missing Pipeline" format:@"No pipeline for %d", static_cast<int>(shader)];
|
||||
|
||||
GSMTLIndexedConvertPSUniform uniform = { sScale, SBW, DBW };
|
||||
GSMTLIndexedConvertPSUniform uniform = { sScale, SBW, DBW, SPSM };
|
||||
|
||||
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
|
||||
DoStretchRect(sTex, GSVector4::zero(), dTex, dRect, pipeline, false, LoadAction::DontCareIfFull, &uniform, sizeof(uniform));
|
||||
|
||||
@@ -4,12 +4,19 @@
|
||||
#include "GSMTLDeviceInfo.h"
|
||||
#include "GS/GS.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/Path.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
static id<MTLLibrary> loadMainLibrary(id<MTLDevice> dev, NSString* name)
|
||||
{
|
||||
NSString* path = [[NSBundle mainBundle] pathForResource:name ofType:@"metallib"];
|
||||
if (!path)
|
||||
{
|
||||
std::string ssname = std::string([name UTF8String]) + ".metallib";
|
||||
std::string sspath = Path::Combine(EmuFolders::Resources, ssname);
|
||||
path = [[NSString alloc] initWithBytes:sspath.data() length:sspath.length() encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
return path ? [dev newLibraryWithFile:path error:nullptr] : nullptr;
|
||||
}
|
||||
|
||||
@@ -24,6 +31,8 @@ static MRCOwned<id<MTLLibrary>> loadMainLibrary(id<MTLDevice> dev)
|
||||
if (@available(macOS 10.14, iOS 12.0, *))
|
||||
if (id<MTLLibrary> lib = loadMainLibrary(dev, @"Metal21"))
|
||||
return MRCTransfer(lib);
|
||||
if (id<MTLLibrary> lib = loadMainLibrary(dev, @"default"))
|
||||
return MRCTransfer(lib);
|
||||
return MRCTransfer([dev newDefaultLibrary]);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ struct GSMTLIndexedConvertPSUniform
|
||||
float scale;
|
||||
uint sbw;
|
||||
uint dbw;
|
||||
uint psm;
|
||||
};
|
||||
|
||||
struct GSMTLDownsamplePSUniform
|
||||
|
||||
@@ -296,6 +296,121 @@ fragment DepthOut ps_convert_rgb5a1_float16_biln(ConvertShaderData data [[stage_
|
||||
return res.sample_biln<rgb5a1_to_depth16>(data.t);
|
||||
}
|
||||
|
||||
fragment float4 ps_convert_rgb5a1_8i(ConvertShaderData data [[stage_in]], DirectReadTextureIn<float> res,
|
||||
constant GSMTLIndexedConvertPSUniform& uniform [[buffer(GSMTLBufferIndexUniforms)]])
|
||||
{
|
||||
// Convert a RGB5A1 texture into a 8 bits packed texture
|
||||
// Input column: 16x2 RGB5A1 pixels
|
||||
// 0: 16 RGBA
|
||||
// 1: 16 RGBA
|
||||
// Output column: 16x4 Index pixels
|
||||
// 0: 16 R5G2
|
||||
// 1: 16 R5G2
|
||||
// 2: 16 G2B5A1
|
||||
// 3: 16 G2B5A1
|
||||
uint2 pos = uint2(data.p.xy);
|
||||
|
||||
// Collapse separate R G B A areas into their base pixel
|
||||
uint2 column = (pos & ~uint2(0u, 3u)) / uint2(1,2);
|
||||
uint2 subcolumn = (pos & uint2(0u, 1u));
|
||||
column.x -= (column.x / 128) * 64;
|
||||
column.y += (column.y / 32) * 32;
|
||||
|
||||
// Deal with swizzling differences
|
||||
if ((uniform.psm & 0x8) != 0) // PSMCT16S
|
||||
{
|
||||
if ((pos.x & 32) != 0)
|
||||
{
|
||||
column.y += 32; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x &= ~32;
|
||||
}
|
||||
|
||||
if ((pos.x & 64) != 0)
|
||||
{
|
||||
column.x -= 32;
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((uniform.psm & 0x30) != 0) // PSMZ16S - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 16;
|
||||
}
|
||||
}
|
||||
else // PSMCT16
|
||||
{
|
||||
if ((pos.y & 32) != 0)
|
||||
{
|
||||
column.y -= 16;
|
||||
column.x += 32;
|
||||
}
|
||||
|
||||
if ((pos.x & 96) != 0)
|
||||
{
|
||||
uint multi = (pos.x & 96) / 32;
|
||||
column.y += 16 * multi; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x -= (pos.x & 96);
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((uniform.psm & 0x30) != 0) // PSMZ16 - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 32;
|
||||
}
|
||||
}
|
||||
|
||||
uint2 coord = column | subcolumn;
|
||||
|
||||
// Compensate for potentially differing page pitch.
|
||||
uint2 block_xy = coord / uint2(64, 64);
|
||||
uint block_num = (block_xy.y * (uniform.dbw / 128)) + block_xy.x;
|
||||
uint2 block_offset = uint2((block_num % (uniform.sbw / 64)) * 64, (block_num / (uniform.sbw / 64)) * 64);
|
||||
coord = (coord % uint2(64, 64)) + block_offset;
|
||||
|
||||
// Apply offset to cols 1 and 2
|
||||
uint is_col23 = pos.y & 4;
|
||||
uint is_col13 = pos.y & 2;
|
||||
uint is_col12 = is_col23 ^ (is_col13 << 1);
|
||||
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
|
||||
|
||||
if (any(floor(uniform.scale) != uniform.scale))
|
||||
coord = uint2(float2(coord) * uniform.scale);
|
||||
else
|
||||
coord = mul24(coord, uint2(uniform.scale));
|
||||
|
||||
float4 pixel = res.tex.read(coord);
|
||||
|
||||
uint4 denorm_c = (uint4)(pixel * 255.5f);
|
||||
if ((pos.y & 2u) == 0u)
|
||||
{
|
||||
uint red = (denorm_c.r >> 3) & 0x1Fu;
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
float sel0 = (float)(((green << 5) | red) & 0xFF) / 255.0f;
|
||||
|
||||
return float4(sel0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
uint blue = (denorm_c.b >> 3) & 0x1Fu;
|
||||
uint alpha = denorm_c.a & 0x80u;
|
||||
float sel0 = (float)((alpha | (blue << 2) | (green >> 3)) & 0xFF) / 255.0f;
|
||||
|
||||
return float4(sel0);
|
||||
}
|
||||
}
|
||||
|
||||
fragment float4 ps_convert_rgba_8i(ConvertShaderData data [[stage_in]], DirectReadTextureIn<float> res,
|
||||
constant GSMTLIndexedConvertPSUniform& uniform [[buffer(GSMTLBufferIndexUniforms)]])
|
||||
{
|
||||
|
||||
@@ -350,10 +350,11 @@ bool GSDeviceOGL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
return false;
|
||||
m_convert.ps[i].SetFormattedName("Convert pipe %s", name);
|
||||
|
||||
if (static_cast<ShaderConvert>(i) == ShaderConvert::RGBA_TO_8I)
|
||||
if (static_cast<ShaderConvert>(i) == ShaderConvert::RGBA_TO_8I || static_cast<ShaderConvert>(i) == ShaderConvert::RGB5A1_TO_8I)
|
||||
{
|
||||
m_convert.ps[i].RegisterUniform("SBW");
|
||||
m_convert.ps[i].RegisterUniform("DBW");
|
||||
m_convert.ps[i].RegisterUniform("PSM");
|
||||
m_convert.ps[i].RegisterUniform("ScaleFactor");
|
||||
}
|
||||
else if (static_cast<ShaderConvert>(i) == ShaderConvert::YUV)
|
||||
@@ -1594,12 +1595,13 @@ void GSDeviceOGL::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 off
|
||||
{
|
||||
CommitClear(sTex, false);
|
||||
|
||||
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
|
||||
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
|
||||
GLProgram& prog = m_convert.ps[static_cast<int>(shader)];
|
||||
prog.Bind();
|
||||
prog.Uniform1ui(0, SBW);
|
||||
prog.Uniform1ui(1, DBW);
|
||||
prog.Uniform1f(2, sScale);
|
||||
prog.Uniform1ui(2, SPSM);
|
||||
prog.Uniform1f(3, sScale);
|
||||
|
||||
OMSetDepthStencilState(m_convert.dss);
|
||||
OMSetBlendState(false);
|
||||
@@ -2424,7 +2426,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
const GSVector4 dRect(config.colclip_update_area);
|
||||
const GSVector4 sRect = dRect / GSVector4(size.x, size.y).xyxy();
|
||||
StretchRect(colclip_rt, sRect, config.rt, dRect, ShaderConvert::COLCLIP_RESOLVE, false);
|
||||
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
Recycle(colclip_rt);
|
||||
|
||||
g_gs_device->SetColorClipTexture(nullptr);
|
||||
@@ -2444,6 +2446,14 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
config.colclip_update_area = config.drawarea;
|
||||
|
||||
colclip_rt = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::ColorClip, false);
|
||||
|
||||
if (!colclip_rt)
|
||||
{
|
||||
Console.Warning("GL: Failed to allocate ColorClip render target, aborting draw.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OMSetRenderTargets(colclip_rt, config.ds, nullptr);
|
||||
|
||||
g_gs_device->SetColorClipTexture(colclip_rt);
|
||||
@@ -2451,6 +2461,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
const GSVector4 dRect = GSVector4((config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly) ? GSVector4i::loadh(rtsize) : config.drawarea);
|
||||
const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy();
|
||||
StretchRect(config.rt, sRect, colclip_rt, dRect, ShaderConvert::COLCLIP_INIT, false);
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2462,6 +2473,11 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
break; // No setup
|
||||
case GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking:
|
||||
primid_texture = InitPrimDateTexture(colclip_rt ? colclip_rt : config.rt, config.drawarea, config.datm);
|
||||
if (!primid_texture)
|
||||
{
|
||||
Console.WriteLn("GL: Failed to allocate DATE image, aborting draw.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case GSHWDrawConfig::DestinationAlphaMode::StencilOne:
|
||||
if (m_features.texture_barrier)
|
||||
@@ -2489,12 +2505,17 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
|
||||
if (config.require_one_barrier && !m_features.texture_barrier)
|
||||
{
|
||||
// Requires a copy of the RT
|
||||
// Requires a copy of the RT.
|
||||
draw_rt_clone = CreateTexture(rtsize.x, rtsize.y, 1, colclip_rt ? GSTexture::Format::ColorClip : GSTexture::Format::Color, true);
|
||||
GL_PUSH("Copy RT to temp texture for fbmask {%d,%d %dx%d}",
|
||||
config.drawarea.left, config.drawarea.top,
|
||||
config.drawarea.width(), config.drawarea.height());
|
||||
CopyRect(colclip_rt ? colclip_rt : config.rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
|
||||
if (draw_rt_clone)
|
||||
{
|
||||
GL_PUSH("GL: Copy RT to temp texture {%d,%d %dx%d}",
|
||||
config.drawarea.left, config.drawarea.top,
|
||||
config.drawarea.width(), config.drawarea.height());
|
||||
CopyRect(colclip_rt ? colclip_rt : config.rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
|
||||
}
|
||||
else
|
||||
Console.Warning("GL: Failed to allocate temp texture for RT copy.");
|
||||
}
|
||||
|
||||
IASetVertexBuffer(config.verts, config.nverts);
|
||||
@@ -2563,7 +2584,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
if (check_barrier && ((config.tex && (config.tex == config.ds || config.tex == config.rt)) || ((psel.ps.IsFeedbackLoop() || psel.ps.blend_c == 1) && GLState::rt == config.rt)))
|
||||
{
|
||||
// Ensure all depth writes are finished before sampling
|
||||
GL_INS("Texture barrier to flush depth or rt before reading");
|
||||
GL_INS("GL: Texture barrier to flush depth or rt before reading");
|
||||
glTextureBarrier();
|
||||
}
|
||||
// additional non-pipeline config stuff
|
||||
@@ -2710,7 +2731,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
const GSVector4 dRect(config.colclip_update_area);
|
||||
const GSVector4 sRect = dRect / GSVector4(size.x, size.y).xyxy();
|
||||
StretchRect(colclip_rt, sRect, config.rt, dRect, ShaderConvert::COLCLIP_RESOLVE, false);
|
||||
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
Recycle(colclip_rt);
|
||||
|
||||
g_gs_device->SetColorClipTexture(nullptr);
|
||||
|
||||
@@ -1491,7 +1491,7 @@ __ri void GSDrawScanline::CDrawScanline(int pixels, int left, int top, const GSV
|
||||
case 2: break;
|
||||
}
|
||||
|
||||
if(!(sel.fpsm == 1 && sel.abc == 1))
|
||||
if (!(sel.fpsm == 1 && sel.abc == 1))
|
||||
{
|
||||
switch(sel.abc)
|
||||
{
|
||||
|
||||
@@ -562,7 +562,7 @@ L("loop");
|
||||
|
||||
L("step");
|
||||
|
||||
// if(steps <= 0) break;
|
||||
// if (steps <= 0) break;
|
||||
|
||||
if (!m_sel.edge)
|
||||
{
|
||||
@@ -768,7 +768,7 @@ void GSDrawScanlineCodeGenerator::Init()
|
||||
cvttps2dq(xym6, vt);
|
||||
|
||||
// s = vti.xxxx() + m_local.d[skip].s;
|
||||
// t = vti.yyyy(); if(!sprite) t += m_local.d[skip].t;
|
||||
// t = vti.yyyy(); if (!sprite) t += m_local.d[skip].t;
|
||||
|
||||
pshufd(s, xym6, _MM_SHUFFLE(0, 0, 0, 0));
|
||||
pshufd(t, xym6, _MM_SHUFFLE(1, 1, 1, 1));
|
||||
@@ -925,7 +925,7 @@ void GSDrawScanlineCodeGenerator::Step()
|
||||
// GSVector4i stq = m_local.d4.stq;
|
||||
|
||||
// s += stq.xxxx();
|
||||
// if(!sprite) t += st.yyyy();
|
||||
// if (!sprite) t += st.yyyy();
|
||||
|
||||
broadcasti128(stq, _rip_local_d(stq));
|
||||
|
||||
@@ -2096,7 +2096,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
|
||||
|
||||
clamp16(_ga, tmp);
|
||||
|
||||
// if(!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
// if (!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
|
||||
if (!m_sel.tcc)
|
||||
{
|
||||
@@ -2109,7 +2109,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
|
||||
|
||||
case TFX_DECAL:
|
||||
|
||||
// if(!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
// if (!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
if (!m_sel.tcc)
|
||||
{
|
||||
// GSVector4i ga = iip ? gaf : m_local.c.ga;
|
||||
@@ -2139,7 +2139,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
|
||||
|
||||
case TFX_HIGHLIGHT2:
|
||||
|
||||
// if(!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
// if (!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
|
||||
if (!m_sel.tcc)
|
||||
{
|
||||
@@ -2990,8 +2990,8 @@ void GSDrawScanlineCodeGenerator::WritePixel(const XYm& src_, const AddressReg&
|
||||
{
|
||||
if (fast)
|
||||
{
|
||||
// if(fzm & 0x0f) GSVector4i::storel(&vm16[addr + 0], fs);
|
||||
// if(fzm & 0xf0) GSVector4i::storeh(&vm16[addr + 8], fs);
|
||||
// if (fzm & 0x0f) GSVector4i::storel(&vm16[addr + 0], fs);
|
||||
// if (fzm & 0xf0) GSVector4i::storeh(&vm16[addr + 8], fs);
|
||||
|
||||
test(mask, 0x0000000f << shift);
|
||||
je("@f");
|
||||
@@ -3020,10 +3020,10 @@ void GSDrawScanlineCodeGenerator::WritePixel(const XYm& src_, const AddressReg&
|
||||
}
|
||||
else
|
||||
{
|
||||
// if(fzm & 0x03) WritePixel(fpsm, &vm16[addr + 0], fs.extract32<0>());
|
||||
// if(fzm & 0x0c) WritePixel(fpsm, &vm16[addr + 2], fs.extract32<1>());
|
||||
// if(fzm & 0x30) WritePixel(fpsm, &vm16[addr + 8], fs.extract32<2>());
|
||||
// if(fzm & 0xc0) WritePixel(fpsm, &vm16[addr + 10], fs.extract32<3>());
|
||||
// if (fzm & 0x03) WritePixel(fpsm, &vm16[addr + 0], fs.extract32<0>());
|
||||
// if (fzm & 0x0c) WritePixel(fpsm, &vm16[addr + 2], fs.extract32<1>());
|
||||
// if (fzm & 0x30) WritePixel(fpsm, &vm16[addr + 8], fs.extract32<2>());
|
||||
// if (fzm & 0xc0) WritePixel(fpsm, &vm16[addr + 10], fs.extract32<3>());
|
||||
|
||||
test(mask, 0x00000003 << shift);
|
||||
je("@f");
|
||||
|
||||
@@ -158,7 +158,7 @@ void GSDrawScanlineCodeGenerator::Generate()
|
||||
Label exit;
|
||||
armAsm->Bind(&m_step_label);
|
||||
|
||||
// if(steps <= 0) break;
|
||||
// if (steps <= 0) break;
|
||||
|
||||
if (!m_sel.edge)
|
||||
{
|
||||
@@ -332,7 +332,7 @@ void GSDrawScanlineCodeGenerator::Init()
|
||||
armAsm->Fcvtzs(v6.V4S(), v4.V4S());
|
||||
|
||||
// s = vti.xxxx() + m_local.d[skip].s;
|
||||
// t = vti.yyyy(); if(!sprite) t += m_local.d[skip].t;
|
||||
// t = vti.yyyy(); if (!sprite) t += m_local.d[skip].t;
|
||||
|
||||
armAsm->Dup(_temp_s.V4S(), v6.V4S(), 0);
|
||||
armAsm->Dup(_temp_t.V4S(), v6.V4S(), 1);
|
||||
@@ -485,7 +485,7 @@ void GSDrawScanlineCodeGenerator::Step()
|
||||
// GSVector4i stq = m_local.d4.stq;
|
||||
|
||||
// s += stq.xxxx();
|
||||
// if(!sprite) t += stq.yyyy();
|
||||
// if (!sprite) t += stq.yyyy();
|
||||
|
||||
armAsm->Dup(_vscratch.V4S(), _d4_stq.V4S(), 0);
|
||||
if (m_sel.prim != GS_SPRITE_CLASS || m_sel.mmin)
|
||||
@@ -1394,7 +1394,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
|
||||
modulate16(v6, _temp_ga, 1);
|
||||
clamp16(v6, v3);
|
||||
|
||||
// if(!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
// if (!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
|
||||
if (!m_sel.tcc)
|
||||
{
|
||||
@@ -1407,7 +1407,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
|
||||
|
||||
case TFX_DECAL:
|
||||
|
||||
// if(!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
// if (!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
|
||||
if (!m_sel.tcc)
|
||||
{
|
||||
@@ -1435,7 +1435,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
|
||||
|
||||
case TFX_HIGHLIGHT2:
|
||||
|
||||
// if(!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
// if (!tcc) gat = gat.mix16(ga.srl16(7));
|
||||
|
||||
if (!m_sel.tcc)
|
||||
{
|
||||
@@ -2158,8 +2158,8 @@ void GSDrawScanlineCodeGenerator::WritePixel(const VRegister& src, const Registe
|
||||
{
|
||||
if (fast)
|
||||
{
|
||||
// if(fzm & 0x0f) GSVector4i::storel(&vm16[addr + 0], fs);
|
||||
// if(fzm & 0xf0) GSVector4i::storeh(&vm16[addr + 8], fs);
|
||||
// if (fzm & 0x0f) GSVector4i::storel(&vm16[addr + 0], fs);
|
||||
// if (fzm & 0xf0) GSVector4i::storeh(&vm16[addr + 8], fs);
|
||||
|
||||
Label skip_low, skip_high;
|
||||
armAsm->Lsl(_wscratch, addr, 1); // *2
|
||||
@@ -2177,10 +2177,10 @@ void GSDrawScanlineCodeGenerator::WritePixel(const VRegister& src, const Registe
|
||||
}
|
||||
else
|
||||
{
|
||||
// if(fzm & 0x03) WritePixel(fpsm, &vm16[addr + 0], fs.extract32<0>());
|
||||
// if(fzm & 0x0c) WritePixel(fpsm, &vm16[addr + 2], fs.extract32<1>());
|
||||
// if(fzm & 0x30) WritePixel(fpsm, &vm16[addr + 8], fs.extract32<2>());
|
||||
// if(fzm & 0xc0) WritePixel(fpsm, &vm16[addr + 10], fs.extract32<3>());
|
||||
// if (fzm & 0x03) WritePixel(fpsm, &vm16[addr + 0], fs.extract32<0>());
|
||||
// if (fzm & 0x0c) WritePixel(fpsm, &vm16[addr + 2], fs.extract32<1>());
|
||||
// if (fzm & 0x30) WritePixel(fpsm, &vm16[addr + 8], fs.extract32<2>());
|
||||
// if (fzm & 0xc0) WritePixel(fpsm, &vm16[addr + 10], fs.extract32<3>());
|
||||
|
||||
Label skip_0, skip_1, skip_2, skip_3;
|
||||
|
||||
|
||||
@@ -444,9 +444,9 @@ void GSRasterizer::DrawTriangle(const GSVertexSW* vertex, const u16* index)
|
||||
|
||||
m1 = (y0011 == y1221).mask() & 7;
|
||||
|
||||
// if(i == 0) => y0 < y1 < y2
|
||||
// if(i == 1) => y0 == y1 < y2
|
||||
// if(i == 4) => y0 < y1 == y2
|
||||
// if (i == 0) => y0 < y1 < y2
|
||||
// if (i == 1) => y0 == y1 < y2
|
||||
// if (i == 4) => y0 < y1 == y2
|
||||
|
||||
if (m1 == 7) // y0 == y1 == y2
|
||||
return;
|
||||
@@ -623,9 +623,9 @@ void GSRasterizer::DrawTriangle(const GSVertexSW* vertex, const u16* index)
|
||||
|
||||
m1 = (y0011 == y1221).mask() & 7;
|
||||
|
||||
// if(i == 0) => y0 < y1 < y2
|
||||
// if(i == 1) => y0 == y1 < y2
|
||||
// if(i == 4) => y0 < y1 == y2
|
||||
// if (i == 0) => y0 < y1 < y2
|
||||
// if (i == 1) => y0 == y1 < y2
|
||||
// if (i == 4) => y0 < y1 == y2
|
||||
|
||||
if (m1 == 7)
|
||||
return; // y0 == y1 == y2
|
||||
|
||||
@@ -94,7 +94,7 @@ void GSRendererSW::VSync(u32 field, bool registers_written, bool idle_frame)
|
||||
m_tc->IncAge();
|
||||
|
||||
m_draw_transfers.clear();
|
||||
// if((m_perfmon.GetFrame() & 255) == 0) m_rl->PrintStats();
|
||||
// if ((m_perfmon.GetFrame() & 255) == 0) m_rl->PrintStats();
|
||||
}
|
||||
|
||||
GSTexture* GSRendererSW::GetOutput(int i, float& scale, int& y_offset)
|
||||
|
||||
@@ -515,7 +515,7 @@ void GSSetupPrimCodeGenerator::Color()
|
||||
pshufd(xym1, xym0, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
punpcklwd(xym0, xym1);
|
||||
|
||||
// if(!tme) c = c.srl16(7);
|
||||
// if (!tme) c = c.srl16(7);
|
||||
|
||||
if (m_sel.tfx == TFX_NONE)
|
||||
{
|
||||
|
||||
@@ -322,7 +322,7 @@ void GSSetupPrimCodeGenerator::Color()
|
||||
armAsm->Ext(v1.V16B(), v0.V16B(), v0.V16B(), 8);
|
||||
armAsm->Zip1(v0.V8H(), v0.V8H(), v1.V8H());
|
||||
|
||||
// if(!tme) c = c.srl16(7);
|
||||
// if (!tme) c = c.srl16(7);
|
||||
|
||||
if (m_sel.tfx == TFX_NONE)
|
||||
armAsm->Ushr(v0.V8H(), v0.V8H(), 7);
|
||||
|
||||
@@ -2059,6 +2059,12 @@ bool GSDeviceVK::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CreateNullTexture())
|
||||
{
|
||||
Host::ReportErrorAsync("GS", "Failed to create dummy texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
std::optional<std::string> shader = ReadShaderSource("shaders/vulkan/tfx.glsl");
|
||||
if (!shader.has_value())
|
||||
@@ -2070,12 +2076,6 @@ bool GSDeviceVK::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
m_tfx_source = std::move(*shader);
|
||||
}
|
||||
|
||||
if (!CreateNullTexture())
|
||||
{
|
||||
Host::ReportErrorAsync("GS", "Failed to create dummy texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CreatePipelineLayouts())
|
||||
{
|
||||
Host::ReportErrorAsync("GS", "Failed to create pipeline layouts");
|
||||
@@ -3158,15 +3158,16 @@ void GSDeviceVK::ConvertToIndexedTexture(
|
||||
{
|
||||
u32 SBW;
|
||||
u32 DBW;
|
||||
u32 pad1[2];
|
||||
u32 PSM;
|
||||
u32 pad1[1];
|
||||
float ScaleFactor;
|
||||
float pad2[3];
|
||||
};
|
||||
|
||||
const Uniforms uniforms = {SBW, DBW, {}, sScale, {}};
|
||||
const Uniforms uniforms = {SBW, DBW, SPSM, {}, sScale, {}};
|
||||
SetUtilityPushConstants(&uniforms, sizeof(uniforms));
|
||||
|
||||
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
|
||||
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
|
||||
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
|
||||
DoStretchRect(static_cast<GSTextureVK*>(sTex), GSVector4::zero(), static_cast<GSTextureVK*>(dTex), dRect,
|
||||
m_convert[static_cast<int>(shader)], false, true);
|
||||
@@ -5291,8 +5292,12 @@ void GSDeviceVK::SetPipeline(VkPipeline pipeline)
|
||||
|
||||
void GSDeviceVK::SetInitialState(VkCommandBuffer cmdbuf)
|
||||
{
|
||||
const VkDeviceSize buffer_offset = 0;
|
||||
vkCmdBindVertexBuffers(cmdbuf, 0, 1, m_vertex_stream_buffer.GetBufferPtr(), &buffer_offset);
|
||||
VkBuffer buffer = *m_vertex_stream_buffer.GetBufferPtr();
|
||||
if (buffer != VK_NULL_HANDLE)
|
||||
{
|
||||
constexpr VkDeviceSize buffer_offset = 0;
|
||||
vkCmdBindVertexBuffers(cmdbuf, 0, 1, &buffer, &buffer_offset);
|
||||
}
|
||||
}
|
||||
|
||||
__ri void GSDeviceVK::ApplyBaseState(u32 flags, VkCommandBuffer cmdbuf)
|
||||
@@ -5625,7 +5630,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
||||
date_image = SetupPrimitiveTrackingDATE(config);
|
||||
if (!date_image)
|
||||
{
|
||||
Console.WriteLn("Failed to allocate DATE image, aborting draw.");
|
||||
Console.WriteLn("VK: Failed to allocate DATE image, aborting draw.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5726,12 +5731,14 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
||||
{
|
||||
EndRenderPass();
|
||||
|
||||
GL_PUSH("Copy RT to temp texture for fbmask {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
|
||||
GL_PUSH("VK: Copy RT to temp texture for fbmask {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
|
||||
config.drawarea.width(), config.drawarea.height());
|
||||
|
||||
CopyRect(draw_rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
|
||||
PSSetShaderResource(2, draw_rt_clone, true);
|
||||
}
|
||||
else
|
||||
Console.Warning("VK: Failed to allocate temp texture for RT copy.");
|
||||
}
|
||||
|
||||
// Switch to colclip target for colclip hw rendering
|
||||
@@ -5744,7 +5751,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
||||
colclip_rt = static_cast<GSTextureVK*>(CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::ColorClip, false));
|
||||
if (!colclip_rt)
|
||||
{
|
||||
Console.WriteLn("Failed to allocate ColorClip render target, aborting draw.");
|
||||
Console.Warning("VK: Failed to allocate ColorClip render target, aborting draw.");
|
||||
|
||||
if (date_image)
|
||||
Recycle(date_image);
|
||||
|
||||
@@ -379,8 +379,8 @@ void GSDumpReplayer::RenderUI()
|
||||
do \
|
||||
{ \
|
||||
text_size = font->CalcTextSizeA(font->FontSize, std::numeric_limits<float>::max(), -1.0f, (text), nullptr, nullptr); \
|
||||
dl->AddText(font, font->FontSize, ImVec2(margin + shadow_offset, position_y + shadow_offset), IM_COL32(0, 0, 0, 100), (text)); \
|
||||
dl->AddText(font, font->FontSize, ImVec2(margin, position_y), color, (text)); \
|
||||
dl->AddText(font, font->FontSize, ImVec2(GSConfig.OsdPerformancePos == OsdOverlayPos::TopLeft ? ImGuiManager::GetWindowWidth() - margin - text_size.x + shadow_offset : margin + shadow_offset, position_y + shadow_offset), IM_COL32(0, 0, 0, 100), (text)); \
|
||||
dl->AddText(font, font->FontSize, ImVec2(GSConfig.OsdPerformancePos == OsdOverlayPos::TopLeft ? ImGuiManager::GetWindowWidth() - margin - text_size.x : margin, position_y), color, (text)); \
|
||||
position_y += text_size.y + spacing; \
|
||||
} while (0)
|
||||
|
||||
|
||||
@@ -91,42 +91,98 @@ static std::recursive_mutex s_mutex;
|
||||
static GameList::CacheMap s_cache_map;
|
||||
static std::FILE* s_cache_write_stream = nullptr;
|
||||
|
||||
const char* GameList::EntryTypeToString(EntryType type)
|
||||
const char* GameList::EntryTypeToString(EntryType type, bool translate)
|
||||
{
|
||||
static std::array<const char*, static_cast<int>(EntryType::Count)> names = {{"PS2Disc", "PS1Disc", "ELF"}};
|
||||
return names[static_cast<int>(type)];
|
||||
static constexpr std::array<const char*, static_cast<int>(EntryType::Count)> names = {
|
||||
TRANSLATE_NOOP("GameList", "PS2 Disc"),
|
||||
TRANSLATE_NOOP("GameList", "PS1 Disc"),
|
||||
TRANSLATE_NOOP("GameList", "ELF"),
|
||||
TRANSLATE_NOOP("GameList", "Invalid"),
|
||||
};
|
||||
|
||||
const char* name = names.at(static_cast<int>(type));
|
||||
if (translate)
|
||||
name = TRANSLATE("GameList", name);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
const char* GameList::EntryTypeToDisplayString(EntryType type)
|
||||
const char* GameList::RegionToString(Region region, bool translate)
|
||||
{
|
||||
static std::array<const char*, static_cast<int>(EntryType::Count)> names = {{TRANSLATE("GameList", "PS2 Disc"), TRANSLATE("GameList", "PS1 Disc"), TRANSLATE("GameList", "ELF")}};
|
||||
return names[static_cast<int>(type)];
|
||||
static constexpr std::array<const char*, static_cast<int>(Region::Count)> names = {
|
||||
TRANSLATE_NOOP("GameList", "NTSC-B"),
|
||||
TRANSLATE_NOOP("GameList", "NTSC-C"),
|
||||
TRANSLATE_NOOP("GameList", "NTSC-HK"),
|
||||
TRANSLATE_NOOP("GameList", "NTSC-J"),
|
||||
TRANSLATE_NOOP("GameList", "NTSC-K"),
|
||||
TRANSLATE_NOOP("GameList", "NTSC-T"),
|
||||
TRANSLATE_NOOP("GameList", "NTSC-U"),
|
||||
TRANSLATE_NOOP("GameList", "Other"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-A"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-AF"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-AU"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-BE"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-E"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-F"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-FI"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-G"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-GR"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-I"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-IN"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-M"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-NL"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-NO"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-P"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-PL"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-R"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-S"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-SC"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-SW"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-SWI"),
|
||||
TRANSLATE_NOOP("GameList", "PAL-UK"),
|
||||
};
|
||||
|
||||
const char* name = names.at(static_cast<int>(region));
|
||||
if (translate)
|
||||
name = TRANSLATE("GameList", name);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
const char* GameList::RegionToString(Region region)
|
||||
const char* GameList::EntryCompatibilityRatingToString(CompatibilityRating rating, bool translate)
|
||||
{
|
||||
static std::array<const char*, static_cast<int>(Region::Count)> names = {{"NTSC-B", "NTSC-C", "NTSC-HK", "NTSC-J", "NTSC-K", "NTSC-T",
|
||||
"NTSC-U", TRANSLATE("GameList", "Other"), "PAL-A", "PAL-AF", "PAL-AU", "PAL-BE", "PAL-E", "PAL-F", "PAL-FI", "PAL-G", "PAL-GR", "PAL-I", "PAL-IN", "PAL-M",
|
||||
"PAL-NL", "PAL-NO", "PAL-P", "PAL-PL", "PAL-R", "PAL-S", "PAL-SC", "PAL-SW", "PAL-SWI", "PAL-UK"}};
|
||||
|
||||
return names[static_cast<int>(region)];
|
||||
}
|
||||
|
||||
const char* GameList::EntryCompatibilityRatingToString(CompatibilityRating rating)
|
||||
{
|
||||
// clang-format off
|
||||
const char* name = "";
|
||||
switch (rating)
|
||||
{
|
||||
case CompatibilityRating::Unknown: return TRANSLATE("GameList", "Unknown");
|
||||
case CompatibilityRating::Nothing: return TRANSLATE("GameList", "Nothing");
|
||||
case CompatibilityRating::Intro: return TRANSLATE("GameList", "Intro");
|
||||
case CompatibilityRating::Menu: return TRANSLATE("GameList", "Menu");
|
||||
case CompatibilityRating::InGame: return TRANSLATE("GameList", "In-Game");
|
||||
case CompatibilityRating::Playable: return TRANSLATE("GameList", "Playable");
|
||||
case CompatibilityRating::Perfect: return TRANSLATE("GameList", "Perfect");
|
||||
default: return "";
|
||||
case CompatibilityRating::Unknown:
|
||||
name = TRANSLATE_NOOP("GameList", "Unknown");
|
||||
break;
|
||||
case CompatibilityRating::Nothing:
|
||||
name = TRANSLATE_NOOP("GameList", "Nothing");
|
||||
break;
|
||||
case CompatibilityRating::Intro:
|
||||
name = TRANSLATE_NOOP("GameList", "Intro");
|
||||
break;
|
||||
case CompatibilityRating::Menu:
|
||||
name = TRANSLATE_NOOP("GameList", "Menu");
|
||||
break;
|
||||
case CompatibilityRating::InGame:
|
||||
name = TRANSLATE_NOOP("GameList", "In-Game");
|
||||
break;
|
||||
case CompatibilityRating::Playable:
|
||||
name = TRANSLATE_NOOP("GameList", "Playable");
|
||||
break;
|
||||
case CompatibilityRating::Perfect:
|
||||
name = TRANSLATE_NOOP("GameList", "Perfect");
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
if (translate)
|
||||
name = TRANSLATE("GameList", name);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
bool GameList::IsScannableFilename(const std::string_view path)
|
||||
@@ -591,15 +647,18 @@ void GameList::ScanDirectory(const char* path, bool recursive, bool only_cache,
|
||||
Console.WriteLn("Scanning %s%s", path, recursive ? " (recursively)" : "");
|
||||
|
||||
progress->PushState();
|
||||
progress->SetStatusText(fmt::format(
|
||||
recursive ? TRANSLATE_FS("GameList", "Scanning directory {} (recursively)...") :
|
||||
TRANSLATE_FS("GameList", "Scanning directory {}..."),
|
||||
path).c_str());
|
||||
|
||||
if (recursive)
|
||||
progress->SetStatusText(
|
||||
fmt::format(TRANSLATE_FS("GameList", "Scanning directory {} (recursively)..."), path).c_str());
|
||||
else
|
||||
progress->SetStatusText(
|
||||
fmt::format(TRANSLATE_FS("GameList", "Scanning directory {}..."), path).c_str());
|
||||
|
||||
FileSystem::FindResultsArray files;
|
||||
FileSystem::FindFiles(path, "*",
|
||||
recursive ? (FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RECURSIVE) :
|
||||
(FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES),
|
||||
(FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES),
|
||||
&files, progress);
|
||||
|
||||
u32 files_scanned = 0;
|
||||
@@ -622,7 +681,7 @@ void GameList::ScanDirectory(const char* path, bool recursive, bool only_cache,
|
||||
}
|
||||
|
||||
const std::string_view filename = Path::GetFileName(ffd.FileName);
|
||||
progress->SetStatusText(fmt::format(TRANSLATE_FS("GameList","Scanning {}..."), filename.data()).c_str());
|
||||
progress->SetStatusText(fmt::format(TRANSLATE_FS("GameList", "Scanning {}..."), filename.data()).c_str());
|
||||
ScanFile(std::move(ffd.FileName), ffd.ModificationTime, lock, played_time_map, custom_attributes_ini);
|
||||
progress->SetProgressValue(files_scanned);
|
||||
}
|
||||
@@ -1300,7 +1359,7 @@ bool GameList::DownloadCovers(const std::vector<std::string>& url_templates, boo
|
||||
continue;
|
||||
}
|
||||
|
||||
progress->SetStatusText(fmt::format(TRANSLATE_FS("GameList","Downloading cover for {0} [{1}]..."), entry->title, entry->serial).c_str());
|
||||
progress->SetStatusText(fmt::format(TRANSLATE_FS("GameList", "Downloading cover for {0} [{1}]..."), entry->title, entry->serial).c_str());
|
||||
}
|
||||
|
||||
// we could actually do a few in parallel here...
|
||||
|
||||
@@ -104,10 +104,9 @@ namespace GameList
|
||||
__fi bool IsDisc() const { return (type == EntryType::PS1Disc || type == EntryType::PS2Disc); }
|
||||
};
|
||||
|
||||
const char* EntryTypeToString(EntryType type);
|
||||
const char* EntryTypeToDisplayString(EntryType type);
|
||||
const char* RegionToString(Region region);
|
||||
const char* EntryCompatibilityRatingToString(CompatibilityRating rating);
|
||||
const char* EntryTypeToString(EntryType type, bool translate);
|
||||
const char* RegionToString(Region region, bool translate);
|
||||
const char* EntryCompatibilityRatingToString(CompatibilityRating rating, bool translate);
|
||||
|
||||
/// Fills in boot parameters (iso or elf) based on the game list entry.
|
||||
void FillBootParametersForEntry(VMBootParameters* params, const Entry* entry);
|
||||
|
||||
@@ -857,7 +857,7 @@ void AudioStreamParameters::LoadSave(SettingsWrapper& wrap, const char* section)
|
||||
wrap.EnumEntry(section, "ExpansionMode", expansion_mode, &AudioStream::ParseExpansionMode, &AudioStream::GetExpansionModeName, DEFAULT_EXPANSION_MODE);
|
||||
minimal_output_latency = wrap.EntryBitBool(section, "OutputLatencyMinimal", DEFAULT_OUTPUT_LATENCY_MINIMAL);
|
||||
buffer_ms = static_cast<u16>(std::clamp<int>(wrap.EntryBitfield(section, "BufferMS", buffer_ms, DEFAULT_BUFFER_MS), 0, std::numeric_limits<u16>::max()));
|
||||
output_latency_ms = static_cast<u16>(std::clamp<int>(wrap.EntryBitfield(section, "OutputLatencyMS", buffer_ms, DEFAULT_OUTPUT_LATENCY_MS), 0, std::numeric_limits<u16>::max()));
|
||||
output_latency_ms = static_cast<u16>(std::clamp<int>(wrap.EntryBitfield(section, "OutputLatencyMS", output_latency_ms, DEFAULT_OUTPUT_LATENCY_MS), 0, std::numeric_limits<u16>::max()));
|
||||
|
||||
stretch_sequence_length_ms = static_cast<u16>(std::clamp<int>(wrap.EntryBitfield(section, "StretchSequenceLengthMS", DEFAULT_STRETCH_SEQUENCE_LENGTH), 0, std::numeric_limits<u16>::max()));
|
||||
stretch_seekwindow_ms = static_cast<u16>(std::clamp<int>(wrap.EntryBitfield(section, "StretchSeekWindowMS", DEFAULT_STRETCH_SEEKWINDOW), 0, std::numeric_limits<u16>::max()));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user