Compare commits

..

49 Commits

Author SHA1 Message Date
refractionpcsx2
be5e98b47f GS/HW: Small improvement to texture shuffle heuristics 2026-01-12 13:49:15 +01:00
JordanTheToaster
293b60a85c Deps: Update SDL3 to v3.4.0 2026-01-12 12:17:03 +01:00
KamFretoZ
3e8c2ef9a9 FSUI: Adds more icons 2026-01-12 12:05:17 +01:00
KamFretoZ
213569f3d7 Deps: Remove version number from fontawesome 2026-01-12 12:05:17 +01:00
KamFretoZ
0edcdf91db Deps: Bump FontAwesome to 7.1.0 2026-01-12 12:05:17 +01:00
Léane GRASSER
8253207bd2 UI: Rename Limit Depth to 24 Bits option values 2026-01-12 12:03:58 +01:00
Léane GRASSER
bc00be2ce5 Qt: Rename Limit 24 Bit Depth to Limit Depth to 24 Bits 2026-01-12 12:03:58 +01:00
refractionpcsx2
89c7463eb5 GS: Correct scaling of image for screenshots when Bilinear Sharp is enabled 2026-01-12 09:24:21 +01:00
PCSX2 Bot
93027c1e2e [ci skip] Qt: Update Base Translation. 2026-01-12 02:59:52 +01:00
TheLastRar
ee15846dd4 USB: Fix missing Train Mascon case warning 2026-01-11 16:45:05 -05:00
Ty
de03d2f672 Debugger: Properly reset the breakpoint skip first when skipped 2026-01-11 14:32:21 -05:00
YukiXXL
ae33c3d991 GameDB: SFOS cop2 fixes. (#13460)
SCES-52033:
Fixed "Cop2 problems." code that. Second address was wrong and was producing a bug.

SCUS-97264:
added fixes for Review Prototype (cop2, other languages)

SCUS-97397:
added fixes (cop2)

TCES-52033:
added fixes (cop2)
2026-01-11 10:12:31 +01:00
refractionpcsx2
61280a945d GS/HW: Tweak Native Scale Upscaled to work in more scenarios 2026-01-11 09:36:00 +01:00
PCSX2 Bot
e82712bf52 [ci skip] Qt: Update Base Translation. 2026-01-11 09:28:44 +01:00
refractionpcsx2
06307abd03 GS/HW: Only enable depth writes/floor calculation if depth is output 2026-01-11 02:36:55 +01:00
refractionpcsx2
daf735b047 GS/HW: Floor depth writes to improve Z testing 2026-01-11 02:36:55 +01:00
JordanTheToaster
f591c88aff GS/HW: Add Limit 24 Bit Depth Hack 2026-01-10 15:53:25 -05:00
refractionpcsx2
ca47a08882 GS: Fix up adding GS_to_GS transfers to the draw_transfers list 2026-01-10 15:50:59 -05:00
refractionpcsx2
92adacf99e GS: Disallow flipped GS->GS transfer when destination overwrites source 2026-01-10 15:50:59 -05:00
JordanTheToaster
43e5ec25ab microVU: Ignore MAC flags in block match if not required 2026-01-10 15:49:57 -05:00
KamFretoZ
1018b75847 DiscordRPC: Simplify Game Icon Retrieval 2026-01-10 15:49:45 -05:00
Shiva9361
3871d1bd5d Qt: Patch for distinguishing left and right variants of shift/alt/ctrl keys 2026-01-10 15:49:18 -05:00
Mrlinkwii
976d4a8dbb Revert "CI/Windows: Disable Qt's PCRE2 JIT"
This reverts commit 1ec4c248fb.
2026-01-10 15:47:32 -05:00
Ty
40b1b9b717 Qt: Add an EE SIO RX input textbox to the log window 2026-01-10 15:46:59 -05:00
Ty
a3b817cb1f Core: Use deque for EE SIO RX/TX FIFOs 2026-01-10 15:46:59 -05:00
SternXD
83e152cd21 GameDB: Add post-bloom alignment and native scaling for Urban Reign 2026-01-10 17:18:43 +01:00
TheLastRar
50a9568d65 GS/DX12: Backport DATE stencil one single pass from DX11/VK
Co-Authored-By: lightningterror <18107717+lightningterror@users.noreply.github.com>
2026-01-09 03:36:58 +01:00
KamFretoZ
a33cbdee09 Qt: Fix alternate row colors for Ruby/Emerald/Sapphire theme
For consistency
2026-01-08 20:18:11 +01:00
KamFretoZ
b02bcc5690 Qt: Cobalt Sky theme refresh 2026-01-08 20:18:11 +01:00
KamFretoZ
2e60a1d081 Qt: AMOLED theme refresh 2026-01-08 20:18:11 +01:00
oltolm
28da984b01 UI: remove unnecessary uses of QOverload 2026-01-07 15:23:29 +01:00
oltolm
967987b25f GS, UI: use u32 instead of s32 for width and height 2026-01-07 14:15:00 +01:00
PCSX2 Bot
e41f63b821 [ci skip] Qt: Update Base Translation. 2026-01-07 01:03:59 +01:00
SilentHeII
0f82503cf7 GameDB: Added various memory card filters
Reads Twisted Metal Black for bonus unlockable.

Adds memcardFilters for Shadow Hearts: Covenant

Ignore my previous pull request. I have no idea why it formatted it so obnoxiously.

Anyway, you get extra ingame items if you have a save file from Shadow Hearts 1.

GameIndex changes

Added memcardFilters for Biohazard Outbreak & Biohazard Outbreak File 2 to allow for creation of network configurations.

Added missing titles

Added missing titles to allow games to load their own saves.
2026-01-06 20:56:26 +01:00
Christopher Obbard
33f625a4e2 cmake: only require Qt modules when Qt UI is enabled
The Qt6 CorePrivate/GuiPrivate/WidgetsPrivate components are only needed
for the Qt UI build. Move their find_package() call under ENABLE_QT_UI
to avoid requiring private Qt modules when building without the UI.

Signed-off-by: Christopher Obbard <obbardc@gmail.com>
2026-01-06 20:44:35 +01:00
JordanTheToaster
5b0c22c343 Mac: Update MoltenVK to v1.4.1 2026-01-06 20:37:29 +01:00
Florin9doi
ea963ffd72 USB: Train Mascon and Master Controller emulation 2026-01-06 20:18:15 +01:00
lightningterror
bd9dcbe441 GS/D3D: Default to DX12 on older GCN amd cards. 2026-01-06 20:09:04 +01:00
PCSX2 Bot
2a1f29c641 [ci skip] Qt: Update Base Translation. 2026-01-06 20:08:18 +01:00
TheLastRar
38883e8df4 GS/DX12: Use cmdlist parameter for read depth transitions 2026-01-06 20:08:02 +01:00
PCSX2 Bot
f971040912 [ci skip] PAD: Update to latest controller database. 2026-01-06 20:07:43 +01:00
Jordan
9aac7e8426 [ci skip] GameDB: CMR 2005 Fixes (#13782)
hotpatch!!!
2026-01-05 17:44:44 -05:00
Ty Lamontagne
96284205a1 [ci skip] Release 2.6 2026-01-04 14:20:16 -05:00
RedPanda4552
4a1d9d31d0 Achievements: Store token to separate ini 2026-01-04 13:56:14 -05:00
Ty
12d6087f2a Translations: Syncing Crowdin translations 2026-01-04 13:55:43 -05:00
Ty
251962c415 Qt: Don't show the dev name if it equals the displayname 2026-01-04 13:49:18 -05:00
Ty
1bdd7d2352 FSUI: Don't show the name if it equals the displayname when listing 2026-01-04 13:49:18 -05:00
SternXD
7b98259ea1 FullscreenUI: Update auto mapping to include device names with display names 2026-01-03 23:59:57 -05:00
Ty
ee8166d1fe Debugger: Check PC instead of cycles when stopping for a breakpoint 2026-01-03 10:14:21 -05:00
143 changed files with 204452 additions and 154040 deletions

View File

@@ -4,6 +4,17 @@ on:
schedule:
- cron: "0 0 * * *" # Every day at 12am UTC.
workflow_dispatch: # As well as manually.
inputs:
stableBuild:
description: 'Build stable version'
required: false
type: boolean
default: false
publish:
description: 'Publish to Flathub'
required: false
type: boolean
default: true
jobs:
@@ -52,8 +63,8 @@ jobs:
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak"
compiler: clang
cmakeflags: ""
publish: true
publish: ${{ inputs.publish || true }}
fetchTags: true
stableBuild: false
stableBuild: ${{ inputs.stableBuild || false }}
secrets: inherit

View File

@@ -12,7 +12,7 @@ on:
- master
workflow_dispatch:
inputs:
is_prelease:
is_prerelease:
description: 'Should be a pre-release?'
required: true
default: 'true'
@@ -73,7 +73,7 @@ jobs:
with:
body_path: ./release-notes.md
draft: true
prerelease: ${{ github.event_name != 'workflow_dispatch' || inputs.is_prelease == 'true' }}
prerelease: ${{ github.event_name != 'workflow_dispatch' || inputs.is_prerelease == 'true' }}
tag_name: ${{ steps.tag_version.outputs.new_tag }}
- name: Create a GitHub Release (Push)
@@ -100,7 +100,7 @@ jobs:
cmakeflags: ""
buildAppImage: true
fetchTags: true
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prerelease == 'false' }}
secrets: inherit
build_linux_flatpak:
@@ -114,9 +114,9 @@ jobs:
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak"
compiler: clang
cmakeflags: ""
publish: false
publish: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prerelease == 'false' }} # prerelease builds are published by the cron job
fetchTags: true
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
stableBuild: ${{ inputs.is_prerelease == 'false' }}
secrets: inherit
# Windows
@@ -133,7 +133,7 @@ jobs:
buildSystem: cmake
cmakeFlags: -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl
fetchTags: true
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prerelease == 'false' }}
secrets: inherit
# MacOS
@@ -147,7 +147,7 @@ jobs:
jobName: "MacOS Build"
artifactPrefixName: "PCSX2-macos-Qt"
fetchTags: true
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prerelease == 'false' }}
sign_and_notarize: true
secrets: inherit

View File

@@ -26,7 +26,7 @@ LIBJPEGTURBO=3.1.2
LIBPNG=1.6.53
LIBWEBP=1.6.0
NVENC=11.1.5.3
SDL=SDL3-3.2.26
SDL=SDL3-3.4.0
QT=6.10.1
QTAPNG=1.3.0
LZ4=1.10.0
@@ -54,7 +54,7 @@ fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
1d3fb8ccc2932d04aa3663e22ef5ef490244370f4e568d7850165068778d98d4 libpng-$LIBPNG.tar.xz
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
dad488474a51a0b01d547cd2834893d6299328d2e30f479a3564088b5476bae2 $SDL.tar.gz
082cbf5f429e0d80820f68dc2b507a94d4cc1b4e70817b119bbb8ec6a69584b8 $SDL.tar.gz
452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c libpng-$LIBPNG-apng.patch.gz
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
2974b91062197e0527dffa3aadd8fe3bfa6681ae45f5ff9181bc0ca6479abd59 nv-codec-headers-$NVENC.tar.gz
@@ -231,7 +231,7 @@ echo "Building SDL..."
rm -fr "$SDL"
tar xf "$SDL.tar.gz"
cd "$SDL"
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -DSDL_X11_XSCRNSAVER=OFF -DSDL_TESTS=OFF -G Ninja
cmake --build build --parallel
ninja -C build install
cd ..

View File

@@ -14,8 +14,8 @@
"sources": [
{
"type": "archive",
"url": "https://libsdl.org/release/SDL3-3.2.26.tar.gz",
"sha256": "dad488474a51a0b01d547cd2834893d6299328d2e30f479a3564088b5476bae2"
"url": "https://libsdl.org/release/SDL3-3.4.0.tar.gz",
"sha256": "082cbf5f429e0d80820f68dc2b507a94d4cc1b4e70817b119bbb8ec6a69584b8"
}
],
"cleanup": [

View File

@@ -40,14 +40,14 @@ fi
FREETYPE=2.14.1
HARFBUZZ=12.2.0
SDL=SDL3-3.2.26
SDL=SDL3-3.4.0
ZSTD=1.5.7
LZ4=1.10.0
LIBPNG=1.6.53
LIBJPEGTURBO=3.1.2
LIBWEBP=1.6.0
FFMPEG=8.0
MOLTENVK=1.2.9
MOLTENVK=1.4.1
QT=6.10.1
QTAPNG=1.3.0
KDDOCKWIDGETS=2.4.0
@@ -80,7 +80,7 @@ CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
cat > SHASUMS <<EOF
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
dad488474a51a0b01d547cd2834893d6299328d2e30f479a3564088b5476bae2 $SDL.tar.gz
082cbf5f429e0d80820f68dc2b507a94d4cc1b4e70817b119bbb8ec6a69584b8 $SDL.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
1d3fb8ccc2932d04aa3663e22ef5ef490244370f4e568d7850165068778d98d4 libpng-$LIBPNG.tar.xz
@@ -88,7 +88,7 @@ e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWE
452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c libpng-$LIBPNG-apng.patch.gz
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
9985f141902a17de818e264d17c1ce334b748e499ee02fcb4703e4dc0038f89c v$MOLTENVK.tar.gz
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
@@ -277,7 +277,7 @@ rm -fr "MoltenVK-${MOLTENVK}"
tar xf "v$MOLTENVK.tar.gz"
cd "MoltenVK-${MOLTENVK}"
./fetchDependencies --macos
make macos
make macos MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=0 MVK_CONFIG_USE_METAL_PRIVATE_API=1
cp Package/Latest/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib "$INSTALLDIR/lib/"
cd ..

View File

@@ -22,14 +22,14 @@ fi
FREETYPE=2.14.1
HARFBUZZ=12.2.0
SDL=SDL3-3.2.26
SDL=SDL3-3.4.0
ZSTD=1.5.7
LZ4=1.10.0
LIBPNG=1.6.53
LIBJPEGTURBO=3.1.2
LIBWEBP=1.6.0
FFMPEG=8.0
MOLTENVK=1.2.9
MOLTENVK=1.4.1
QT=6.10.1
QTAPNG=1.3.0
KDDOCKWIDGETS=2.4.0
@@ -61,7 +61,7 @@ CMAKE_COMMON=(
cat > SHASUMS <<EOF
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
dad488474a51a0b01d547cd2834893d6299328d2e30f479a3564088b5476bae2 $SDL.tar.gz
082cbf5f429e0d80820f68dc2b507a94d4cc1b4e70817b119bbb8ec6a69584b8 $SDL.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
1d3fb8ccc2932d04aa3663e22ef5ef490244370f4e568d7850165068778d98d4 libpng-$LIBPNG.tar.xz
@@ -69,7 +69,7 @@ e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWE
452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c libpng-$LIBPNG-apng.patch.gz
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
9985f141902a17de818e264d17c1ce334b748e499ee02fcb4703e4dc0038f89c v$MOLTENVK.tar.gz
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
@@ -225,7 +225,7 @@ cd "MoltenVK-${MOLTENVK}"
sed -i '' 's/xcodebuild "$@"/xcodebuild $XCODEBUILD_EXTRA_ARGS "$@"/g' fetchDependencies
sed -i '' 's/XCODEBUILD :=/XCODEBUILD ?=/g' Makefile
XCODEBUILD_EXTRA_ARGS="VALID_ARCHS=x86_64" ./fetchDependencies --macos
XCODEBUILD="set -o pipefail && xcodebuild VALID_ARCHS=x86_64" make macos
XCODEBUILD="set -o pipefail && xcodebuild VALID_ARCHS=x86_64" make macos MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=0 MVK_CONFIG_USE_METAL_PRIVATE_API=1
cp Package/Latest/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib "$INSTALLDIR/lib/"
cd ..

View File

@@ -47,7 +47,7 @@ set HARFBUZZ=12.2.0
set LIBJPEGTURBO=3.1.2
set LIBPNG=1653
set LIBPNGLONG=1.6.53
set SDL=SDL3-3.2.26
set SDL=SDL3-3.4.0
set QT=6.10.1
set QTMINOR=6.10
set QTAPNG=1.3.0
@@ -71,7 +71,7 @@ call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lp
call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net/libpng-apng/libpng-%LIBPNGLONG%-apng.patch.gz 452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c || goto error
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 739356eef1192fff9d641c320a8f5ef4a10506b8927def4b9ceb764c7e947369 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 9ac2debb493e0d3e13dbd2729fb91f4bfeb00a0f4dff5e04b73cc9bac276b38d || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" c43f471a808b07fc541528410e94ce89c6745bdc1d744492e19911d35fbf7d33 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 2d828d8c999fdd18167937c071781c22321c643b04a106c714411c2356cdb26d || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" ddd74a417d2397eb085d047a9b6ba52b76e748055817f728fe691f8456035d23 || goto error

View File

@@ -45,7 +45,7 @@ set HARFBUZZ=12.2.0
set LIBJPEGTURBO=3.1.2
set LIBPNG=1653
set LIBPNGLONG=1.6.53
set SDL=SDL3-3.2.26
set SDL=SDL3-3.4.0
set QT=6.10.1
set QTMINOR=6.10
set QTAPNG=1.3.0
@@ -69,7 +69,7 @@ call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lp
call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net/libpng-apng/libpng-%LIBPNGLONG%-apng.patch.gz 452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c || goto error
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 739356eef1192fff9d641c320a8f5ef4a10506b8927def4b9ceb764c7e947369 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 9ac2debb493e0d3e13dbd2729fb91f4bfeb00a0f4dff5e04b73cc9bac276b38d || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" c43f471a808b07fc541528410e94ce89c6745bdc1d744492e19911d35fbf7d33 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 2d828d8c999fdd18167937c071781c22321c643b04a106c714411c2356cdb26d || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" ddd74a417d2397eb085d047a9b6ba52b76e748055817f728fe691f8456035d23 || goto error
@@ -201,10 +201,6 @@ echo Building Qt base...
rmdir /S /Q "qtbase-everywhere-src-%QT%"
%SEVENZIP% x "qtbase-everywhere-src-%QT%.zip" || goto error
cd "qtbase-everywhere-src-%QT%" || goto error
rem Disable the PCRE2 JIT, it doesn't properly verify AVX2 support.
%PATCH% -p1 < "%SCRIPTDIR%\qtbase-disable-pcre2-jit.patch" || goto error
cmake -B build -DFEATURE_sql=OFF -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" %FORCEPDB% -DINPUT_gui=yes -DINPUT_widgets=yes -DINPUT_ssl=yes -DINPUT_openssl=no -DINPUT_schannel=yes -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON %QTBUILDSPEC% || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error

View File

@@ -1,35 +0,0 @@
--- qtbase/src/3rdparty/pcre2/CMakeLists.txt 2024-03-19 08:46:43.000000000 -0700
+++ qtbase/src/3rdparty/pcre2/CMakeLists.txt 2024-06-06 21:52:20.539619500 -0700
@@ -41,6 +41,7 @@
src/pcre2_xclass.c
DEFINES
HAVE_CONFIG_H
+ PCRE2_DISABLE_JIT
PUBLIC_DEFINES
PCRE2_CODE_UNIT_WIDTH=16
PUBLIC_INCLUDE_DIRECTORIES
@@ -52,23 +53,8 @@
## Scopes:
#####################################################################
-qt_internal_extend_target(BundledPcre2 CONDITION QNX OR UIKIT
- DEFINES
- PCRE2_DISABLE_JIT
-)
-
-qt_internal_extend_target(BundledPcre2 CONDITION (TEST_architecture_arch STREQUAL "arm") AND WIN32
- DEFINES
- PCRE2_DISABLE_JIT
-)
-
-qt_internal_extend_target(BundledPcre2 CONDITION (TEST_architecture_arch STREQUAL "arm64") AND WIN32
- DEFINES
- PCRE2_DISABLE_JIT
-)
-
if (APPLE)
- target_compile_options(BundledPcre2 PRIVATE "SHELL:-Xarch_arm64 -DPCRE2_DISABLE_JIT")
+ target_compile_options(BundledPcre2 PRIVATE "SHELL:-Xarch_arm64")
endif()
qt_internal_extend_target(BundledPcre2 CONDITION WIN32

View File

@@ -1,7 +1,7 @@
// Generated by https://github.com/juliettef/IconFontCppHeaders script GenerateIconFontCppHeaders.py
// for C and C++
// from codepoints https://github.com/FortAwesome/Font-Awesome/raw/6.x/metadata/icons.yml
// for use with font https://github.com/FortAwesome/Font-Awesome/blob/6.x/webfonts/fa-regular-400.ttf, https://github.com/FortAwesome/Font-Awesome/blob/6.x/webfonts/fa-solid-900.ttf
// from codepoints https://github.com/FortAwesome/Font-Awesome/raw/7.x/metadata/icons.yml
// for use with font https://github.com/FortAwesome/Font-Awesome/blob/7.x/webfonts/fa-regular-400.woff2 (You may need to convert the .woff2 files to .ttf depending upon your loader.), https://github.com/FortAwesome/Font-Awesome/blob/7.x/webfonts/fa-solid-900.woff2 (You may need to convert the .woff2 files to .ttf depending upon your loader.)
#pragma once
@@ -25,6 +25,7 @@
#define ICON_FA_A "A" // U+0041
#define ICON_FA_ADDRESS_BOOK "\xef\x8a\xb9" // U+f2b9
#define ICON_FA_ADDRESS_CARD "\xef\x8a\xbb" // U+f2bb
#define ICON_FA_ALARM_CLOCK "\xef\x8d\x8e" // U+f34e
#define ICON_FA_ALIGN_CENTER "\xef\x80\xb7" // U+f037
#define ICON_FA_ALIGN_JUSTIFY "\xef\x80\xb9" // U+f039
#define ICON_FA_ALIGN_LEFT "\xef\x80\xb6" // U+f036
@@ -218,6 +219,7 @@
#define ICON_FA_BURGER "\xef\xa0\x85" // U+f805
#define ICON_FA_BURST "\xee\x93\x9c" // U+e4dc
#define ICON_FA_BUS "\xef\x88\x87" // U+f207
#define ICON_FA_BUS_SIDE "\xee\xa0\x9d" // U+e81d
#define ICON_FA_BUS_SIMPLE "\xef\x95\x9e" // U+f55e
#define ICON_FA_BUSINESS_TIME "\xef\x99\x8a" // U+f64a
#define ICON_FA_C "C" // U+0043
@@ -650,8 +652,6 @@
#define ICON_FA_HANDS_PRAYING "\xef\x9a\x84" // U+f684
#define ICON_FA_HANDSHAKE "\xef\x8a\xb5" // U+f2b5
#define ICON_FA_HANDSHAKE_ANGLE "\xef\x93\x84" // U+f4c4
#define ICON_FA_HANDSHAKE_SIMPLE "\xef\x93\x86" // U+f4c6
#define ICON_FA_HANDSHAKE_SIMPLE_SLASH "\xee\x81\x9f" // U+e05f
#define ICON_FA_HANDSHAKE_SLASH "\xee\x81\xa0" // U+e060
#define ICON_FA_HANUKIAH "\xef\x9b\xa6" // U+f6e6
#define ICON_FA_HARD_DRIVE "\xef\x82\xa0" // U+f0a0
@@ -665,7 +665,6 @@
#define ICON_FA_HEAD_SIDE_VIRUS "\xee\x81\xa4" // U+e064
#define ICON_FA_HEADING "\xef\x87\x9c" // U+f1dc
#define ICON_FA_HEADPHONES "\xef\x80\xa5" // U+f025
#define ICON_FA_HEADPHONES_SIMPLE "\xef\x96\x8f" // U+f58f
#define ICON_FA_HEADSET "\xef\x96\x90" // U+f590
#define ICON_FA_HEART "\xef\x80\x84" // U+f004
#define ICON_FA_HEART_CIRCLE_BOLT "\xee\x93\xbc" // U+e4fc
@@ -680,6 +679,7 @@
#define ICON_FA_HELICOPTER_SYMBOL "\xee\x94\x82" // U+e502
#define ICON_FA_HELMET_SAFETY "\xef\xa0\x87" // U+f807
#define ICON_FA_HELMET_UN "\xee\x94\x83" // U+e503
#define ICON_FA_HEXAGON "\xef\x8c\x92" // U+f312
#define ICON_FA_HEXAGON_NODES "\xee\x9a\x99" // U+e699
#define ICON_FA_HEXAGON_NODES_BOLT "\xee\x9a\x9a" // U+e69a
#define ICON_FA_HIGHLIGHTER "\xef\x96\x91" // U+f591
@@ -852,6 +852,7 @@
#define ICON_FA_MOBILE_RETRO "\xee\x94\xa7" // U+e527
#define ICON_FA_MOBILE_SCREEN "\xef\x8f\x8f" // U+f3cf
#define ICON_FA_MOBILE_SCREEN_BUTTON "\xef\x8f\x8d" // U+f3cd
#define ICON_FA_MOBILE_VIBRATE "\xee\xa0\x96" // U+e816
#define ICON_FA_MONEY_BILL "\xef\x83\x96" // U+f0d6
#define ICON_FA_MONEY_BILL_1 "\xef\x8f\x91" // U+f3d1
#define ICON_FA_MONEY_BILL_1_WAVE "\xef\x94\xbb" // U+f53b
@@ -881,6 +882,7 @@
#define ICON_FA_NETWORK_WIRED "\xef\x9b\xbf" // U+f6ff
#define ICON_FA_NEUTER "\xef\x88\xac" // U+f22c
#define ICON_FA_NEWSPAPER "\xef\x87\xaa" // U+f1ea
#define ICON_FA_NON_BINARY "\xee\xa0\x87" // U+e807
#define ICON_FA_NOT_EQUAL "\xef\x94\xbe" // U+f53e
#define ICON_FA_NOTDEF "\xee\x87\xbe" // U+e1fe
#define ICON_FA_NOTE_STICKY "\xef\x89\x89" // U+f249
@@ -888,6 +890,7 @@
#define ICON_FA_O "O" // U+004f
#define ICON_FA_OBJECT_GROUP "\xef\x89\x87" // U+f247
#define ICON_FA_OBJECT_UNGROUP "\xef\x89\x88" // U+f248
#define ICON_FA_OCTAGON "\xef\x8c\x86" // U+f306
#define ICON_FA_OIL_CAN "\xef\x98\x93" // U+f613
#define ICON_FA_OIL_WELL "\xee\x94\xb2" // U+e532
#define ICON_FA_OM "\xef\x99\xb9" // U+f679
@@ -916,6 +919,7 @@
#define ICON_FA_PEN_RULER "\xef\x96\xae" // U+f5ae
#define ICON_FA_PEN_TO_SQUARE "\xef\x81\x84" // U+f044
#define ICON_FA_PENCIL "\xef\x8c\x83" // U+f303
#define ICON_FA_PENTAGON "\xee\x9e\x90" // U+e790
#define ICON_FA_PEOPLE_ARROWS "\xee\x81\xa8" // U+e068
#define ICON_FA_PEOPLE_CARRY_BOX "\xef\x93\x8e" // U+f4ce
#define ICON_FA_PEOPLE_GROUP "\xee\x94\xb3" // U+e533
@@ -1090,6 +1094,7 @@
#define ICON_FA_SD_CARD "\xef\x9f\x82" // U+f7c2
#define ICON_FA_SECTION "\xee\x91\x87" // U+e447
#define ICON_FA_SEEDLING "\xef\x93\x98" // U+f4d8
#define ICON_FA_SEPTAGON "\xee\xa0\xa0" // U+e820
#define ICON_FA_SERVER "\xef\x88\xb3" // U+f233
#define ICON_FA_SHAPES "\xef\x98\x9f" // U+f61f
#define ICON_FA_SHARE "\xef\x81\xa4" // U+f064
@@ -1118,6 +1123,8 @@
#define ICON_FA_SIGNATURE "\xef\x96\xb7" // U+f5b7
#define ICON_FA_SIGNS_POST "\xef\x89\xb7" // U+f277
#define ICON_FA_SIM_CARD "\xef\x9f\x84" // U+f7c4
#define ICON_FA_SINGLE_QUOTE_LEFT "\xee\xa0\x9b" // U+e81b
#define ICON_FA_SINGLE_QUOTE_RIGHT "\xee\xa0\x9c" // U+e81c
#define ICON_FA_SINK "\xee\x81\xad" // U+e06d
#define ICON_FA_SITEMAP "\xef\x83\xa8" // U+f0e8
#define ICON_FA_SKULL "\xef\x95\x8c" // U+f54c
@@ -1141,6 +1148,7 @@
#define ICON_FA_SPELL_CHECK "\xef\xa2\x91" // U+f891
#define ICON_FA_SPIDER "\xef\x9c\x97" // U+f717
#define ICON_FA_SPINNER "\xef\x84\x90" // U+f110
#define ICON_FA_SPIRAL "\xee\xa0\x8a" // U+e80a
#define ICON_FA_SPLOTCH "\xef\x96\xbc" // U+f5bc
#define ICON_FA_SPOON "\xef\x8b\xa5" // U+f2e5
#define ICON_FA_SPRAY_CAN "\xef\x96\xbd" // U+f5bd
@@ -1325,8 +1333,6 @@
#define ICON_FA_USER_GRADUATE "\xef\x94\x81" // U+f501
#define ICON_FA_USER_GROUP "\xef\x94\x80" // U+f500
#define ICON_FA_USER_INJURED "\xef\x9c\xa8" // U+f728
#define ICON_FA_USER_LARGE "\xef\x90\x86" // U+f406
#define ICON_FA_USER_LARGE_SLASH "\xef\x93\xba" // U+f4fa
#define ICON_FA_USER_LOCK "\xef\x94\x82" // U+f502
#define ICON_FA_USER_MINUS "\xef\x94\x83" // U+f503
#define ICON_FA_USER_NINJA "\xef\x94\x84" // U+f504
@@ -1351,7 +1357,6 @@
#define ICON_FA_V "V" // U+0056
#define ICON_FA_VAN_SHUTTLE "\xef\x96\xb6" // U+f5b6
#define ICON_FA_VAULT "\xee\x8b\x85" // U+e2c5
#define ICON_FA_VECTOR_SQUARE "\xef\x97\x8b" // U+f5cb
#define ICON_FA_VENUS "\xef\x88\xa1" // U+f221
#define ICON_FA_VENUS_DOUBLE "\xef\x88\xa6" // U+f226
#define ICON_FA_VENUS_MARS "\xef\x88\xa8" // U+f228

View File

@@ -2239,6 +2239,8 @@ SCAJ-20152:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SCAJ-20153:
name: "コード・エイジ コマンダーズ"
@@ -5600,7 +5602,7 @@ SCES-52033:
author=refraction
// Cop2 problems.
patch=0,EE,003953F8,word,48438000
patch=0,EE,003735FC,word,4B06521B
patch=0,EE,003953FC,word,4B06521B
author=YukiXXL
// Speed Correction (25 FPS)
patch=1,EE,00175E1C,extended,00000019
@@ -6229,6 +6231,8 @@ SCES-53688:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SCES-53795:
name: "SingStar - '80s"
@@ -7698,6 +7702,8 @@ SCKA-20065:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SCKA-20066:
name: "아이토이 - 플레이 3"
@@ -11384,6 +11390,10 @@ SCUS-97197:
name: "War of the Monsters"
region: "NTSC-U"
compat: 5
memcardFilters: # Reads Twisted Metal Black for bonus unlockable.
- "SCUS-97101"
- "SCUS-97179"
- "SCUS-97197"
SCUS-97198:
name: "Sly Cooper and the Thievius Raccoonus"
region: "NTSC-U"
@@ -11682,6 +11692,15 @@ SCUS-97264:
// Cop2 problems.
patch=0,EE,003735F8,word,48438000
patch=0,EE,003735FC,word,4B06521B
062BC79E:
content: |-
author=YukiXXL
// Cop2 problems.
patch=0,EE,00395D28,word,48438000
patch=0,EE,00395D2C,word,4B06521B
// Other languages SNDVAG fix
patch=1,EE,204A0C3C,word,482E7325
patch=1,EE,204A0C40,word,0000474F
SCUS-97265:
name: "Jak II"
region: "NTSC-U"
@@ -12069,12 +12088,21 @@ SCUS-97396:
gsHWFixes:
PCRTCOffsets: 1 # Fixes boot videos screen size.
SCUS-97397:
name: "Syphon Filter - The Omega Strain"
name: "Syphon Filter - The Omega Strain Public Beta 1.0"
region: "NTSC-U"
gsHWFixes:
autoFlush: 2 # Fixes lights going through walls.
preloadFrameData: 1 # Fixes light flicker.
halfPixelOffset: 2 # Corrects light position.
gameFixes:
- EETimingHack # Fixes random hangs.
patches:
C909A32E:
content: |-
author=YukiXXL
// Cop2 problems.
patch=0,EE,00367798,word,48438000
patch=0,EE,0036779C,word,4B06521B
SCUS-97398:
name: "Siren [Demo]"
region: "NTSC-U"
@@ -20894,10 +20922,8 @@ SLES-52636:
gameFixes:
- FullVU0SyncHack # Fixes in-game timer.
gsHWFixes:
recommendedBlendingLevel: 3 # Fixes missing lighting and car reflections.
halfPixelOffset: 1 # Fixes 4 split lines in stage intros.
autoFlush: 1 # Fixes incorrect colors.
alignSprite: 1 # Fixes vertical lines such as in FMVs.
minimumBlendingLevel: 3 # Fixes missing lighting and car reflections.
halfPixelOffset: 4 # Fixes lines in game and FMVs.
SLES-52637:
name: "TOCA Race Driver 2"
region: "PAL-M5"
@@ -30585,6 +30611,11 @@ SLES-82030:
halfPixelOffset: 5 # Fixes shadow positioning.
autoFlush: 2 # Makes the shadow monsters appear.
nativeScaling: 2 # Aligns post processing and bloom.
memcardFilters: # Reads Shadow Hearts for extra items.
- "SLES-82030"
- "SLES-82031"
- "SLES-50677"
- "SLES-50822"
SLES-82031:
name: "Shadow Hearts - Covenant [Disc 2 of 2]"
region: "PAL-M3"
@@ -30592,8 +30623,11 @@ SLES-82031:
halfPixelOffset: 5 # Fixes shadow positioning.
autoFlush: 2 # Makes the shadow monsters appear.
nativeScaling: 2 # Aligns post processing and bloom.
memcardFilters:
memcardFilters: # Reads Shadow Hearts for extra items.
- "SLES-82030"
- "SLES-82031"
- "SLES-50677"
- "SLES-50822"
SLES-82032:
name: "Metal Gear Solid 3 - Snake Eater"
region: "PAL-G"
@@ -35942,6 +35976,8 @@ SLPM-60272:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SLPM-60273:
name: "絶体絶命都市2 -凍てついた記憶たち- [体験版 Type-B]"
@@ -43475,6 +43511,11 @@ SLPM-65428:
name-en: "BioHazard Outbreak"
region: "NTSC-J"
compat: 5
memcardFilters:
- "SLPM-65428"
- "SLPM-74201"
- "SLPM-65286"
- "BWNETCNF"
SLPM-65429:
name: "ギャラクシーエンジェル Moonlit Lovers [初回限定版ファーストパッケージ]"
name-sort: "ぎゃらくしーえんじぇる Moonlit Lovers [しょかいげんていばんふぁーすとぱっけーじ]"
@@ -44975,6 +45016,8 @@ SLPM-65692:
- "SLPM-65692"
- "SLPM-65428"
- "SLPM-74201"
- "SLPM-65286"
- "BWNETCNF"
SLPM-65693:
name: "ときめきメモリアル3 ~約束のあの場所で~ [コナミ殿堂セレクション]"
name-sort: "ときめきめもりある3 やくそくのあのばしょで [こなみでんどうせれくしょん]"
@@ -53682,6 +53725,11 @@ SLPM-74201:
name-sort: "ばいおはざーど あうとぶれいく [PlayStation2 the Best]"
name-en: "BioHazard Outbreak [PlayStation2 the Best]"
region: "NTSC-J"
memcardFilters:
- "SLPM-65428"
- "SLPM-74201"
- "SLPM-65286"
- "BWNETCNF"
SLPM-74202:
name: "風雲 新撰組 [PlayStation2 the Best]"
name-sort: "ふううん しんせんぐみ [PlayStation2 the Best]"
@@ -58847,6 +58895,11 @@ SLPS-25317:
halfPixelOffset: 5 # Fixes shadow positioning.
autoFlush: 2 # Makes the shadow monsters appear.
nativeScaling: 2 # Aligns post processing and bloom.
memcardFilters: # Reads Shadow Hearts for extra items.
- "SLPS-25317"
- "SLPS-25318"
- "SLPS-25041"
- "SLPS-73418"
SLPS-25318:
name: "シャドウハーツⅡ [DXパック] [ディスク2/2]"
name-sort: "しゃどうはーつ2 [DXぱっく] [でぃすく2/2]"
@@ -58856,8 +58909,11 @@ SLPS-25318:
halfPixelOffset: 5 # Fixes shadow positioning.
autoFlush: 2 # Makes the shadow monsters appear.
nativeScaling: 2 # Aligns post processing and bloom.
memcardFilters:
memcardFilters: # Reads Shadow Hearts for extra items.
- "SLPS-25317"
- "SLPS-25318"
- "SLPS-25041"
- "SLPS-73418"
SLPS-25319:
name: "ケロケロキング スーパーDX"
name-sort: "けろけろきんぐ すーぱーDX"
@@ -58936,6 +58992,11 @@ SLPS-25334:
halfPixelOffset: 5 # Fixes shadow positioning.
autoFlush: 2 # Makes the shadow monsters appear.
nativeScaling: 2 # Aligns post processing and bloom.
memcardFilters: # Reads Shadow Hearts for extra items.
- "SLPS-25334"
- "SLPS-25335"
- "SLPS-25041"
- "SLPS-73418"
SLPS-25335:
name: "シャドウハーツⅡ [通常版] [ディスク2/2]"
name-sort: "しゃどうはーつ2 [つうじょうばん] [でぃすく2/2]"
@@ -58945,8 +59006,11 @@ SLPS-25335:
halfPixelOffset: 5 # Fixes shadow positioning.
autoFlush: 2 # Makes the shadow monsters appear.
nativeScaling: 2 # Aligns post processing and bloom.
memcardFilters:
memcardFilters: # Reads Shadow Hearts for extra items.
- "SLPS-25334"
- "SLPS-25335"
- "SLPS-25041"
- "SLPS-73418"
SLPS-25336:
name: "バスランディング3 [Sammy best] [つりコン2+ 同梱版]"
name-sort: "ばすらんでぃんぐ3 [Sammy best] [つりこん2 どうこんばん]"
@@ -60302,6 +60366,8 @@ SLPS-25557:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SLPS-25558:
name: "ネオジオ バトルコロシアム"
@@ -63244,6 +63310,11 @@ SLPS-73214:
halfPixelOffset: 5 # Fixes shadow positioning.
autoFlush: 2 # Makes the shadow monsters appear.
nativeScaling: 2 # Aligns post processing and bloom.
memcardFilters: # Reads Shadow Hearts for extra items.
- "SLPS-73214"
- "SLPS-73215"
- "SLPS-25041"
- "SLPS-73418"
SLPS-73215:
name: "シャドウハーツⅡ ディレクターズカット [PlayStation2 the Best] [ディスク2/2]"
name-sort: "しゃどうはーつ2 でぃれくたーずかっと [PlayStation2 the Best] [でぃすく2/2]"
@@ -63253,8 +63324,11 @@ SLPS-73215:
halfPixelOffset: 5 # Fixes shadow positioning.
autoFlush: 2 # Makes the shadow monsters appear.
nativeScaling: 2 # Aligns post processing and bloom.
memcardFilters:
memcardFilters: # Reads Shadow Hearts for extra items.
- "SLPS-73214"
- "SLPS-73215"
- "SLPS-25041"
- "SLPS-73418"
SLPS-73216:
name: "マグナカルタ [PlayStation2 the Best]"
name-sort: "まぐなかるた [PlayStation2 the Best]"
@@ -69323,6 +69397,10 @@ SLUS-21041:
halfPixelOffset: 5 # Fixes shadow positioning.
autoFlush: 2 # Makes the shadow monsters appear.
nativeScaling: 2 # Aligns post processing and bloom.
memcardFilters: # Reads Shadow Hearts for extra items.
- "SLUS-21041"
- "SLUS-21044"
- "SLUS-20347"
SLUS-21042:
name: "Darkwatch"
region: "NTSC-U"
@@ -69341,8 +69419,10 @@ SLUS-21044:
halfPixelOffset: 5 # Fixes shadow positioning.
autoFlush: 2 # Makes the shadow monsters appear.
nativeScaling: 2 # Aligns post processing and bloom.
memcardFilters:
memcardFilters: # Reads Shadow Hearts for extra items.
- "SLUS-21041"
- "SLUS-21044"
- "SLUS-20347"
SLUS-21045:
name: "Conflict - Vietnam"
region: "NTSC-U"
@@ -70308,6 +70388,8 @@ SLUS-21209:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SLUS-21212:
name: "Spartan - Total Warrior"
@@ -75716,6 +75798,9 @@ TCES-52033:
0DDA2728:
content: |-
author=YukiXXL
// Cop2 problems.
patch=0,EE,0038E8E8,word,48438000
patch=0,EE,0038E8EC,word,4B06521B
// Speed Correction (25 FPS)
patch=1,EE,00175a7c,extended,00000019
patch=1,EE,00175848,extended,00000019

Binary file not shown.

View File

@@ -245,7 +245,8 @@
03000000b62500000100000000000000,Gametel GT004 01,a:b3,b:b0,dpdown:b10,dpleft:b9,dpright:b8,dpup:b11,leftshoulder:b4,rightshoulder:b5,start:b7,x:b1,y:b2,platform:Windows,
030000008f0e00001411000000000000,Gamo2 Divaller,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:Windows,
03000000120c0000a857000000000000,Gator Claw,a:b1,b:b2,back:b8,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,
03000000c9110000f055000000000000,GC100XF,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:Windows,
03000000c21100000791000000000000,Be1 GC101 Controller 1.03,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,
03000000c9110000f055000000000000,Be1 GC100XF Controller,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:Windows,
030000008305000009a0000000000000,Genius,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:Windows,
030000008305000031b0000000000000,Genius Maxfire Blaze 3,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:Windows,
03000000451300000010000000000000,Genius Maxfire Grandias 12,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:Windows,

View File

@@ -71,6 +71,7 @@
#define PS_DITHER 0
#define PS_DITHER_ADJUST 0
#define PS_ZCLAMP 0
#define PS_ZFLOOR 0
#define PS_SCANMSK 0
#define PS_AUTOMATIC_LOD 0
#define PS_MANUAL_LOD 0
@@ -138,7 +139,7 @@ struct PS_OUTPUT
#endif
#endif
#endif
#if PS_ZCLAMP
#if PS_ZCLAMP || PS_ZFLOOR
float depth : SV_Depth;
#endif
};
@@ -1209,8 +1210,16 @@ PS_OUTPUT ps_main(PS_INPUT input)
#endif // PS_DATE != 1/2
#if PS_ZFLOOR
float depth_value = floor(input.p.z * exp2(32.0f)) * exp2(-32.0f);
#else
float depth_value = input.p.z;
#endif
#if PS_ZCLAMP
output.depth = min(input.p.z, MaxDepthPS);
output.depth = min(depth_value, MaxDepthPS);
#elif PS_ZFLOOR
output.depth = depth_value;
#endif
return output;

View File

@@ -1143,7 +1143,16 @@ void ps_main()
#endif
#endif
#if PS_ZCLAMP
gl_FragDepth = min(gl_FragCoord.z, MaxDepthPS);
#if PS_ZFLOOR
float depth_value = floor(gl_FragCoord.z * exp2(32.0f)) * exp2(-32.0f);
#else
float depth_value = gl_FragCoord.z;
#endif
#if PS_ZCLAMP
gl_FragDepth = min(depth_value, MaxDepthPS);
#elif PS_ZFLOOR
gl_FragDepth = depth_value;
#endif
}

View File

@@ -288,6 +288,7 @@ void main()
#define PS_DITHER 0
#define PS_DITHER_ADJUST 0
#define PS_ZCLAMP 0
#define PS_ZFLOOR 0
#define PS_FEEDBACK_LOOP 0
#define PS_TEX_IS_FB 0
#endif
@@ -1400,8 +1401,16 @@ void main()
#endif
#endif
#if PS_ZFLOOR
float depth_value = floor(gl_FragCoord.z * exp2(32.0f)) * exp2(-32.0f);;
#else
float depth_value = gl_FragCoord.z;
#endif
#if PS_ZCLAMP
gl_FragDepth = min(gl_FragCoord.z, MaxDepthPS);
#elif PS_ZFLOOR
gl_FragDepth = depth_value;
#endif
#endif // PS_DATE

View File

@@ -109,14 +109,14 @@ disable_compiler_warnings_for_target(speex)
# Find the Qt components that we need.
if(ENABLE_QT_UI)
find_package(Qt6 6.10.0 COMPONENTS CoreTools Core GuiTools Gui WidgetsTools Widgets LinguistTools REQUIRED)
endif()
if (Qt6_VERSION VERSION_GREATER_EQUAL 6.10.0)
find_package(Qt6 COMPONENTS CorePrivate GuiPrivate WidgetsPrivate REQUIRED)
endif()
if (Qt6_VERSION VERSION_GREATER_EQUAL 6.10.0)
find_package(Qt6 COMPONENTS CorePrivate GuiPrivate WidgetsPrivate REQUIRED)
endif()
# The docking system for the debugger.
# The docking system for the debugger.
find_package(KDDockWidgets-qt6 2.3.0 REQUIRED)
endif()
if(WIN32)
add_subdirectory(3rdparty/rainterface EXCLUDE_FROM_ALL)

View File

@@ -11,7 +11,6 @@
#include "common/Threading.h"
#include "common/WindowInfo.h"
#include "common/HostSys.h"
#include "fmt/format.h"
#include <csignal>
#include <cstring>
@@ -20,15 +19,12 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <thread>
#include <time.h>
#include <mach/mach_init.h>
#include <mach/mach_port.h>
#include <mach/mach_time.h>
#include <mach/mach_vm.h>
#include <mach/message.h>
#include <mach/task.h>
#include <mach/thread_state.h>
#include <mach/vm_map.h>
#include <mutex>
#include <ApplicationServices/ApplicationServices.h>
@@ -298,7 +294,7 @@ static CPUInfo CalcCPUInfo()
std::vector<DarwinMisc::CPUClass> classes = DarwinMisc::GetCPUClasses();
out.num_clusters = static_cast<u32>(classes.size());
out.num_big_cores = classes.empty() ? 0 : classes[0].num_physical;
out.num_threads = classes.empty() ? 0 : classes[0].num_logical;
out.num_threads = classes.empty() ? 0 : classes[0].num_logical;
out.num_small_cores = 0;
for (std::size_t i = 1; i < classes.size(); i++)
{
@@ -572,206 +568,15 @@ void HostSys::EndCodeWrite()
#endif // _M_ARM64
#define USE_MACH_EXCEPTION_PORTS
namespace PageFaultHandler
{
#ifdef USE_MACH_EXCEPTION_PORTS
static void SignalHandler(mach_port_t port);
#else
static void SignalHandler(int sig, siginfo_t* info, void* ctx);
#endif
static std::recursive_mutex s_exception_handler_mutex;
static bool s_in_exception_handler = false;
static bool s_installed = false;
} // namespace PageFaultHandler
#ifdef USE_MACH_EXCEPTION_PORTS
#if defined(_M_X86)
#define THREAD_STATE64_COUNT x86_THREAD_STATE64_COUNT
#define THREAD_STATE64 x86_THREAD_STATE64
#define thread_state64_t x86_thread_state64_t
#elif defined(_M_ARM64)
#define THREAD_STATE64_COUNT ARM_THREAD_STATE64_COUNT
#define THREAD_STATE64 ARM_THREAD_STATE64
#define thread_state64_t arm_thread_state64_t
#else
#error Unknown Darwin Platform
#endif
void PageFaultHandler::SignalHandler(mach_port_t port)
{
Threading::SetNameOfCurrentThread("Mach Exception Thread");
#pragma pack(4)
struct
{
mach_msg_header_t Head;
NDR_record_t NDR;
exception_type_t exception;
mach_msg_type_number_t codeCnt;
int64_t code[2];
int flavor;
mach_msg_type_number_t old_stateCnt;
natural_t old_state[THREAD_STATE64_COUNT];
mach_msg_trailer_t trailer;
} msg_in;
struct
{
mach_msg_header_t Head;
NDR_record_t NDR;
kern_return_t RetCode;
int flavor;
mach_msg_type_number_t new_stateCnt;
natural_t new_state[THREAD_STATE64_COUNT];
} msg_out;
#pragma pack()
memset(&msg_in, 0xee, sizeof(msg_in));
memset(&msg_out, 0xee, sizeof(msg_out));
mach_msg_size_t send_size = 0;
mach_msg_option_t option = MACH_RCV_MSG;
while (true)
{
kern_return_t r;
if ((r = mach_msg_overwrite(&msg_out.Head, option, send_size, sizeof(msg_in), port,
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL, &msg_in.Head, 0)))
{
pxFail(fmt::format("CRITICAL: mach_msg_overwrite: {:x}", r).c_str());
}
if (msg_in.Head.msgh_id == MACH_NOTIFY_NO_SENDERS)
{
// the other thread exited
mach_port_deallocate(mach_task_self(), port);
return;
}
if (msg_in.Head.msgh_id != 2406)
{
pxFailRel("unknown message received");
return;
}
if (msg_in.flavor != THREAD_STATE64)
{
pxFailRel(fmt::format("unknown flavour {}, expected {}", msg_in.flavor, THREAD_STATE64).c_str());
return;
}
s_exception_handler_mutex.lock();
thread_state64_t* state = (thread_state64_t*)msg_in.old_state;
HandlerResult result = HandlerResult::ExecuteNextHandler;
if (!s_in_exception_handler)
{
s_in_exception_handler = true;
#ifdef _M_ARM64
result = HandlePageFault(reinterpret_cast<void*>(state->__pc), reinterpret_cast<void*>(msg_in.code[1]), (msg_in.code[0] & 2) != 0);
#else
result = HandlePageFault(reinterpret_cast<void*>(state->__rip), reinterpret_cast<void*>(msg_in.code[1]), (msg_in.code[0] & 2) != 0);
#endif
s_in_exception_handler = false;
}
// Set up the reply.
msg_out.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(msg_in.Head.msgh_bits), 0);
msg_out.Head.msgh_remote_port = msg_in.Head.msgh_remote_port;
msg_out.Head.msgh_local_port = MACH_PORT_NULL;
msg_out.Head.msgh_id = msg_in.Head.msgh_id + 100;
msg_out.NDR = msg_in.NDR;
if (result != HandlerResult::ContinueExecution) // cooked
{
msg_out.RetCode = KERN_FAILURE;
msg_out.flavor = 0;
msg_out.new_stateCnt = 0;
// The crash handler on macOS or Linux doesn't use context passed to it
// Stubbing it here is fine
CrashHandler::CrashSignalHandler(-1, nullptr, nullptr);
pxFailRel("CrashSignalHandler returned when it should have terminated us!");
}
else
{
// Resumes execution right where we left off (re-executes instruction that caused the SIGSEGV)
msg_out.RetCode = KERN_SUCCESS;
msg_out.flavor = THREAD_STATE64;
msg_out.new_stateCnt = THREAD_STATE64_COUNT;
memcpy(msg_out.new_state, msg_in.old_state, THREAD_STATE64_COUNT * sizeof(natural_t));
}
msg_out.Head.msgh_size =
offsetof(__typeof__(msg_out), new_state) + msg_out.new_stateCnt * sizeof(natural_t);
send_size = msg_out.Head.msgh_size;
option |= MACH_SEND_MSG;
s_exception_handler_mutex.unlock();
}
}
bool PageFaultHandler::Install(Error* error)
{
exception_mask_t masks[EXC_TYPES_COUNT];
mach_port_t ports[EXC_TYPES_COUNT];
exception_behavior_t behaviors[EXC_TYPES_COUNT];
thread_state_flavor_t flavors[EXC_TYPES_COUNT];
mach_msg_type_number_t count = EXC_TYPES_COUNT;
kern_return_t r = task_get_exception_ports(mach_task_self(), EXC_MASK_ALL,
masks, &count, ports, behaviors, flavors);
mach_port_t port;
if ((r = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port)))
{
pxFailRel(fmt::format("mach_port_allocate: {:x}", r).c_str());
return false;
}
std::thread sig_thread(PageFaultHandler::SignalHandler, port);
sig_thread.detach();
if ((r = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
{
mach_port_deallocate(mach_task_self(), port);
pxFailRel(fmt::format("mach_port_insert_right: {:x}", r).c_str());
return false;
}
task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, MACH_PORT_NULL, EXCEPTION_DEFAULT, THREAD_STATE_NONE);
if ((r = thread_set_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS, port, EXCEPTION_STATE | MACH_EXCEPTION_CODES, THREAD_STATE64)))
{
mach_port_deallocate(mach_task_self(), port);
pxFailRel(fmt::format("thread_set_exception_ports: {:x}", r).c_str());
return false;
}
if ((r = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, -1)))
{
mach_port_deallocate(mach_task_self(), port);
pxFailRel(fmt::format("mach_port_mod_refs: {:x}", r).c_str());
return false;
}
mach_port_t previous;
if ((r = mach_port_request_notification(mach_task_self(), port, MACH_NOTIFY_NO_SENDERS, 0, port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous)))
{
mach_port_deallocate(mach_task_self(), port);
pxFailRel(fmt::format("mach_port_mod_refs: {:x}", r).c_str());
return false;
}
s_installed = true;
return true;
}
#else
void PageFaultHandler::SignalHandler(int sig, siginfo_t* info, void* ctx)
{
#if defined(_M_X86)
@@ -839,4 +644,3 @@ bool PageFaultHandler::Install(Error* error)
s_installed = true;
return true;
}
#endif

View File

@@ -37,7 +37,7 @@ public:
void restoreGeometry(const QByteArray& geometry);
Q_SIGNALS:
void windowResizedEvent(int width, int height, float scale);
void windowResizedEvent(u32 width, u32 height, float scale);
void windowRestoredEvent();
void dragEnterEvent(QDragEnterEvent* event);

View File

@@ -5,10 +5,14 @@
#include "MainWindow.h"
#include "QtHost.h"
#include "SettingWidgetBinder.h"
#include "VMManager.h"
#include <QtCore/QLatin1StringView>
#include <QtCore/QUtf8StringView>
#include <QtGui/QIcon>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QScrollBar>
@@ -46,6 +50,12 @@ void LogWindow::updateSettings()
const bool new_enabled = Host::GetBaseBoolSettingValue("Logging", "EnableLogWindow", false) && !Host::InNoGUIMode();
const bool attach_to_main = Host::GetBaseBoolSettingValue("Logging", "AttachLogWindowToMainWindow", true);
const bool curr_enabled = Log::IsHostOutputEnabled();
const bool input_enabled = Host::GetBaseBoolSettingValue("Logging", "ShowEESIOInput");
if(g_log_window && g_log_window->m_line_input)
{
g_log_window->m_input_widget->setVisible(input_enabled);
}
if (new_enabled == curr_enabled)
{
@@ -171,6 +181,10 @@ void LogWindow::createUi()
action->setCheckable(true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "EnableTimestamps", true);
action = settings_menu->addAction(tr("Show EE SIO &Input"));
action->setCheckable(true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "ShowEESIOInput", false);
settings_menu->addSeparator();
// TODO: Log Level
@@ -181,6 +195,30 @@ void LogWindow::createUi()
m_text->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
m_text->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
m_text->setWordWrapMode(QTextOption::WrapAnywhere);
m_text->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_line_input = new QLineEdit(this);
connect(m_line_input, &QLineEdit::returnPressed, this, &LogWindow::onInputEntered);
m_local_echo_checkbox = new QCheckBox(tr("Local Echo"), this);
m_local_echo_checkbox->setChecked(m_local_echo);
connect(m_local_echo_checkbox, &QCheckBox::checkStateChanged, this, [&](Qt::CheckState state)
{
m_local_echo = state == Qt::CheckState::Checked;
});
m_newline_on_enter_checkbox = new QCheckBox(tr("Newline on send"), this);
m_newline_on_enter_checkbox->setChecked(m_newline_on_enter);
connect(m_newline_on_enter_checkbox, &QCheckBox::checkStateChanged, this, [&](Qt::CheckState state)
{
m_newline_on_enter = state == Qt::CheckState::Checked;
});
m_input_hbox = new QHBoxLayout(this);
m_input_hbox->addWidget(m_line_input, 1);
m_input_hbox->addWidget(m_local_echo_checkbox);
m_input_hbox->addWidget(m_newline_on_enter_checkbox);
m_input_hbox->setSpacing(8);
#if defined(_WIN32)
QFont font("Consolas");
@@ -194,7 +232,19 @@ void LogWindow::createUi()
#endif
m_text->setFont(font);
setCentralWidget(m_text);
QWidget* central_widget = new QWidget(this);
m_input_widget = new QWidget(this);
m_input_widget->setVisible(Host::GetBaseBoolSettingValue("Logging", "ShowEESIOInput"));
m_input_widget->setLayout(m_input_hbox);
QVBoxLayout* vlayout = new QVBoxLayout(central_widget);
vlayout->setContentsMargins(0, 0, 0, 0);
vlayout->setSpacing(0);
vlayout->addWidget(m_text);
vlayout->addWidget(m_input_widget);
central_widget->setLayout(vlayout);
setCentralWidget(central_widget);
}
void LogWindow::onClearTriggered()
@@ -361,6 +411,31 @@ void LogWindow::appendMessage(quint32 level, quint32 color, const QString& messa
}
}
void LogWindow::onInputEntered()
{
QString text = m_line_input->text();
if (text.isEmpty() && !m_newline_on_enter)
return;
if(m_newline_on_enter)
text.append('\n');
std::string str = text.toUtf8().toStdString();
if(VMManager::WriteBytesToEESIORXFIFO({reinterpret_cast<const u8*>(str.data()), str.size()}))
{
m_line_input->clear();
if(m_local_echo)
// appendMessage expects a newline to be at the end of the string
appendMessage(0, 0, m_newline_on_enter ? text : (text + '\n') );
QTextCursor cursor(m_text->textCursor());
cursor.movePosition(QTextCursor::End);
m_text->setTextCursor(cursor);
}
}
void LogWindow::saveSize()
{
const int current_width = Host::GetBaseIntSettingValue("UI", "LogWindowWidth", DEFAULT_WIDTH);

View File

@@ -5,6 +5,9 @@
#include "common/Console.h"
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QPlainTextEdit>
@@ -36,6 +39,7 @@ private Q_SLOTS:
void onClearTriggered();
void onSaveTriggered();
void appendMessage(quint32 level, quint32 color, const QString& message);
void onInputEntered();
private:
static constexpr int DEFAULT_WIDTH = 750;
@@ -45,8 +49,15 @@ private:
void restoreSize();
QPlainTextEdit* m_text;
QLineEdit* m_line_input;
QMenu* m_level_menu;
QWidget* m_input_widget;
QHBoxLayout* m_input_hbox;
QCheckBox* m_local_echo_checkbox;
QCheckBox* m_newline_on_enter_checkbox;
bool m_local_echo = false;
bool m_newline_on_enter = true;
bool m_attached_to_main_window = true;
bool m_destroying = false;
};

View File

@@ -86,6 +86,7 @@ namespace QtHost
//////////////////////////////////////////////////////////////////////////
static QTimer* s_settings_save_timer = nullptr;
static std::unique_ptr<INISettingsInterface> s_base_settings_interface;
static std::unique_ptr<INISettingsInterface> s_secrets_settings_interface;
static bool s_batch_mode = false;
static bool s_nogui_mode = false;
static bool s_start_big_picture_mode = false;
@@ -776,7 +777,7 @@ void EmuThread::connectDisplaySignals(DisplaySurface* widget)
connect(widget, &DisplaySurface::windowRestoredEvent, this, &EmuThread::redrawDisplayWindow);
}
void EmuThread::onDisplayWindowResized(int width, int height, float scale)
void EmuThread::onDisplayWindowResized(u32 width, u32 height, float scale)
{
if (!MTGS::IsOpen())
return;
@@ -1307,6 +1308,7 @@ bool QtHost::InitializeConfig()
// Write crash dumps to the data directory, since that'll be accessible for certain.
CrashHandler::SetWriteDirectory(EmuFolders::DataRoot);
// Load main settings ini
const std::string path = Path::Combine(EmuFolders::Settings, "PCSX2.ini");
const bool settings_exists = FileSystem::FileExists(path.c_str());
Console.WriteLnFmt("Loading config from {}.", path);
@@ -1347,6 +1349,29 @@ bool QtHost::InitializeConfig()
SaveSettings();
}
// Layer secrets ini on top
const std::string secrets_path = Path::Combine(EmuFolders::Settings, "secrets.ini");
const bool secrets_settings_exists = FileSystem::FileExists(secrets_path.c_str());
Console.WriteLnFmt("Loading secrets from {}.", secrets_path);
s_secrets_settings_interface = std::make_unique<INISettingsInterface>(std::move(secrets_path));
Host::Internal::SetSecretsSettingsLayer(s_secrets_settings_interface.get());
if (!secrets_settings_exists || !s_secrets_settings_interface->Load())
{
if (!s_base_settings_interface->Save(&error))
{
QMessageBox::critical(
nullptr, QStringLiteral("PCSX2"),
QStringLiteral(
"Failed to save secrets to\n\n%1\n\nThe error was: %2\n\nPlease ensure this directory is writable. You "
"can also try portable mode by creating portable.txt in the same directory you installed PCSX2 into.")
.arg(QString::fromStdString(s_secrets_settings_interface->GetFileName()))
.arg(QString::fromStdString(error.GetDescription())));
return false;
}
}
// Setup wizard was incomplete last time?
s_run_setup_wizard =
s_run_setup_wizard || s_base_settings_interface->GetBoolValue("UI", "SetupWizardIncomplete", false);

View File

@@ -191,7 +191,7 @@ private:
private Q_SLOTS:
void stopInThread();
void doBackgroundControllerPoll();
void onDisplayWindowResized(int width, int height, float scale);
void onDisplayWindowResized(u32 width, u32 height, float scale);
void onApplicationStateChanged(Qt::ApplicationState state);
void redrawDisplayWindow();

View File

@@ -67,6 +67,17 @@ struct KeyCodeName
const char* icon_name;
};
// Extended keys for left/right versions, Non conflicting with Qt::Key enum
enum ExtendedKeys
{
Key_RightShift = 0x01100022,
Key_LeftShift = 0x01100023,
Key_RightControl = 0x01100024,
Key_LeftControl = 0x01100025,
Key_RightAlt = 0x01100026,
Key_LeftAlt = 0x01100027,
};
static constexpr const KeyCodeName s_qt_key_names[] = {
{Qt::Key_Escape, "Escape", ICON_PF_ESC},
{Qt::Key_Tab, "Tab", ICON_PF_TAB},
@@ -92,6 +103,13 @@ static constexpr const KeyCodeName s_qt_key_names[] = {
{Qt::Key_Control, "Control", ICON_PF_CTRL},
{Qt::Key_Meta, "Meta", ICON_PF_SUPER},
{Qt::Key_Alt, "Alt", ICON_PF_ALT},
// patch for left and right versions of the keys
{ExtendedKeys::Key_LeftShift, "LShift", ICON_PF_SHIFT},
{ExtendedKeys::Key_RightShift, "RShift", ICON_PF_SHIFT},
{ExtendedKeys::Key_LeftControl, "LCtrl", ICON_PF_CTRL},
{ExtendedKeys::Key_RightControl, "RCtrl", ICON_PF_CTRL},
{ExtendedKeys::Key_LeftAlt, "LAlt", ICON_PF_ALT},
{ExtendedKeys::Key_RightAlt, "RAlt", ICON_PF_ALT},
{Qt::Key_CapsLock, "CapsLock", ICON_PF_CAPS},
{Qt::Key_NumLock, "NumLock", ICON_PF_NUMLOCK},
{Qt::Key_ScrollLock, "ScrollLock", ICON_PF_SCRLK},
@@ -575,6 +593,41 @@ u32 QtUtils::KeyEventToCode(const QKeyEvent* ev)
const u8 keycode = set_keycode ? map_text_to_keycode(text) : 0;
int key = ev->key();
if (key == Qt::Key_Shift || key == Qt::Key_Alt || key == Qt::Key_Control)
{
#if defined(Q_OS_WIN) or defined(Q_OS_LINUX)
// Scan codes (Tested it)
// 0x2A : Left shift
// 0x36 : Right shift
// 0x1D : Left ctrl
// 0xE01D : Right ctrl
// 0x38 : Left alt
// right alt can become ctrl + right alt in some keyboard layouts (windows)
// but thats fine for our use case
switch (ev->nativeScanCode())
{
case 0x2A:
key = ExtendedKeys::Key_LeftShift;
break;
case 0x36:
key = ExtendedKeys::Key_RightShift;
break;
case 0x1D:
key = ExtendedKeys::Key_LeftControl;
break;
case 0xE01D:
key = ExtendedKeys::Key_RightControl;
break;
case 0x38:
key = ExtendedKeys::Key_LeftAlt;
break;
default:
break;
}
#endif
}
if (keycode != 0)
key = keycode; // Override key if mapped

View File

@@ -463,7 +463,7 @@ namespace SettingWidgetBinder
{
if (!isNullable(widget))
{
widget->connect(widget, QOverload<int>::of(&QSpinBox::valueChanged), func);
widget->connect(widget, &QSpinBox::valueChanged, func);
}
else
{
@@ -591,7 +591,7 @@ namespace SettingWidgetBinder
{
if (!isNullable(widget))
{
widget->connect(widget, QOverload<double>::of(&QDoubleSpinBox::valueChanged), func);
widget->connect(widget, &QDoubleSpinBox::valueChanged, func);
}
else
{
@@ -608,7 +608,7 @@ namespace SettingWidgetBinder
});
menu.exec(widget->mapToGlobal(pt));
});
widget->connect(widget, QOverload<double>::of(&QDoubleSpinBox::valueChanged), widget, [widget, func = std::move(func)]() {
widget->connect(widget, &QDoubleSpinBox::valueChanged, widget, [widget, func = std::move(func)]() {
if (widget->property(IS_NULL_PROPERTY).toBool())
{
widget->setProperty(IS_NULL_PROPERTY, QVariant(false));

View File

@@ -42,9 +42,9 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* settings_dialog,
m_ui.eeClampMode->setCurrentIndex(getClampingModeIndex(-1));
m_ui.vu0ClampMode->setCurrentIndex(getClampingModeIndex(0));
m_ui.vu1ClampMode->setCurrentIndex(getClampingModeIndex(1));
connect(m_ui.eeClampMode, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) { setClampingMode(-1, index); });
connect(m_ui.vu0ClampMode, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) { setClampingMode(0, index); });
connect(m_ui.vu1ClampMode, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) { setClampingMode(1, index); });
connect(m_ui.eeClampMode, &QComboBox::currentIndexChanged, [this](int index) { setClampingMode(-1, index); });
connect(m_ui.vu0ClampMode, &QComboBox::currentIndexChanged, [this](int index) { setClampingMode(0, index); });
connect(m_ui.vu1ClampMode, &QComboBox::currentIndexChanged, [this](int index) { setClampingMode(1, index); });
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.iopRecompiler, "EmuCore/CPU/Recompiler", "EnableIOP", true);
@@ -60,7 +60,7 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* settings_dialog,
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_ui.savestateCompressionLevel, "EmuCore", "SavestateCompressionRatio", static_cast<int>(SavestateCompressionLevel::Medium));
connect(m_ui.savestateCompressionMethod, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
connect(m_ui.savestateCompressionMethod, &QComboBox::currentIndexChanged, this,
&AdvancedSettingsWidget::onSavestateCompressionTypeChanged);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.backupSaveStates, "EmuCore", "BackupSavestate", true);

View File

@@ -49,7 +49,7 @@ ControllerBindingWidget::ControllerBindingWidget(QWidget* parent, ControllerSett
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(m_dialog->getProfileSettingsInterface(),
m_ui.controllerType, m_config_section, "Type", Pad::GetControllerInfo(Pad::GetDefaultPadType(port))->name);
connect(m_ui.controllerType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ControllerBindingWidget::onTypeChanged);
connect(m_ui.controllerType, &QComboBox::currentIndexChanged, this, &ControllerBindingWidget::onTypeChanged);
connect(m_ui.bindings, &QPushButton::clicked, this, &ControllerBindingWidget::onBindingsClicked);
connect(m_ui.settings, &QPushButton::clicked, this, &ControllerBindingWidget::onSettingsClicked);
connect(m_ui.macros, &QPushButton::clicked, this, &ControllerBindingWidget::onMacrosClicked);
@@ -202,7 +202,11 @@ void ControllerBindingWidget::onAutomaticBindingClicked()
for (const QPair<QString, QString>& dev : m_dialog->getDeviceList())
{
// we set it as data, because the device list could get invalidated while the menu is up
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(dev.first).arg(dev.second));
QAction* action;
if(dev.first.compare(dev.second, Qt::CaseInsensitive) == 0)
action = menu.addAction(dev.first);
else
action = menu.addAction(QStringLiteral("%1: %2").arg(dev.first).arg(dev.second));
action->setData(dev.first);
connect(action, &QAction::triggered, this, [this, action]() { doDeviceAutomaticBinding(action->data().toString()); });
added = true;
@@ -998,8 +1002,8 @@ USBDeviceWidget::USBDeviceWidget(QWidget* parent, ControllerSettingsWindow* dial
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(
m_dialog->getProfileSettingsInterface(), m_ui.deviceType, m_config_section, "Type", "None");
connect(m_ui.deviceType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &USBDeviceWidget::onTypeChanged);
connect(m_ui.deviceSubtype, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &USBDeviceWidget::onSubTypeChanged);
connect(m_ui.deviceType, &QComboBox::currentIndexChanged, this, &USBDeviceWidget::onTypeChanged);
connect(m_ui.deviceSubtype, &QComboBox::currentIndexChanged, this, &USBDeviceWidget::onSubTypeChanged);
connect(m_ui.bindings, &QPushButton::clicked, this, &USBDeviceWidget::onBindingsClicked);
connect(m_ui.settings, &QPushButton::clicked, this, &USBDeviceWidget::onSettingsClicked);
connect(m_ui.automaticBinding, &QPushButton::clicked, this, &USBDeviceWidget::onAutomaticBindingClicked);
@@ -1152,7 +1156,11 @@ void USBDeviceWidget::onAutomaticBindingClicked()
for (const QPair<QString, QString>& dev : m_dialog->getDeviceList())
{
// we set it as data, because the device list could get invalidated while the menu is up
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(dev.first).arg(dev.second));
QAction* action;
if(dev.first.compare(dev.second, Qt::CaseInsensitive) == 0)
action = menu.addAction(dev.first);
else
action = menu.addAction(QStringLiteral("%1: %2").arg(dev.first).arg(dev.second));
action->setData(dev.first);
connect(action, &QAction::triggered, this, [this, action]() { doDeviceAutomaticBinding(action->data().toString()); });
added = true;

View File

@@ -88,7 +88,11 @@ ControllerGlobalSettingsWidget::~ControllerGlobalSettingsWidget() = default;
void ControllerGlobalSettingsWidget::addDeviceToList(const QString& identifier, const QString& name)
{
QListWidgetItem* item = new QListWidgetItem();
item->setText(QStringLiteral("%1: %2").arg(identifier).arg(name));
if(identifier.compare(name,Qt::CaseInsensitive) == 0)
item->setText(identifier);
else
item->setText(QStringLiteral("%1: %2").arg(identifier).arg(name));
item->setData(Qt::UserRole, identifier);
m_ui.deviceList->addItem(item);
}

View File

@@ -62,8 +62,8 @@ DEV9SettingsWidget::DEV9SettingsWidget(SettingsWindow* settings_dialog, QWidget*
//////////////////////////////////////////////////////////////////////////
// Eth Device Settings
//////////////////////////////////////////////////////////////////////////
connect(m_ui.ethDevType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DEV9SettingsWidget::onEthDeviceTypeChanged);
connect(m_ui.ethDev, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DEV9SettingsWidget::onEthDeviceChanged);
connect(m_ui.ethDevType, &QComboBox::currentIndexChanged, this, &DEV9SettingsWidget::onEthDeviceTypeChanged);
connect(m_ui.ethDev, &QComboBox::currentIndexChanged, this, &DEV9SettingsWidget::onEthDeviceChanged);
//Comboboxes populated in show event
//////////////////////////////////////////////////////////////////////////
@@ -125,12 +125,12 @@ DEV9SettingsWidget::DEV9SettingsWidget(SettingsWindow* settings_dialog, QWidget*
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.ethDNS1Mode, "DEV9/Eth", "ModeDNS1",
s_dns_name, Pcsx2Config::DEV9Options::DnsModeNames, Pcsx2Config::DEV9Options::DnsModeNames[static_cast<int>(Pcsx2Config::DEV9Options::DnsMode::Auto)], "DEV9SettingsWidget");
onEthDNSModeChanged(m_ui.ethDNS1Mode, m_ui.ethDNS1Mode->currentIndex(), m_ui.ethDNS1Addr, "DEV9/Eth", "ModeDNS1");
connect(m_ui.ethDNS1Mode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [&](int index) { onEthDNSModeChanged(m_ui.ethDNS1Mode, index, m_ui.ethDNS1Addr, "DEV9/Eth", "ModeDNS1"); });
connect(m_ui.ethDNS1Mode, &QComboBox::currentIndexChanged, this, [&](int index) { onEthDNSModeChanged(m_ui.ethDNS1Mode, index, m_ui.ethDNS1Addr, "DEV9/Eth", "ModeDNS1"); });
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.ethDNS2Mode, "DEV9/Eth", "ModeDNS2",
s_dns_name, Pcsx2Config::DEV9Options::DnsModeNames, Pcsx2Config::DEV9Options::DnsModeNames[static_cast<int>(Pcsx2Config::DEV9Options::DnsMode::Auto)], "DEV9SettingsWidget");
onEthDNSModeChanged(m_ui.ethDNS2Mode, m_ui.ethDNS2Mode->currentIndex(), m_ui.ethDNS2Addr, "DEV9/Eth", "ModeDNS2");
connect(m_ui.ethDNS2Mode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [&](int index) { onEthDNSModeChanged(m_ui.ethDNS2Mode, index, m_ui.ethDNS2Addr, "DEV9/Eth", "ModeDNS2"); });
connect(m_ui.ethDNS2Mode, &QComboBox::currentIndexChanged, this, [&](int index) { onEthDNSModeChanged(m_ui.ethDNS2Mode, index, m_ui.ethDNS2Addr, "DEV9/Eth", "ModeDNS2"); });
//////////////////////////////////////////////////////////////////////////
// DNS Settings
@@ -144,7 +144,7 @@ DEV9SettingsWidget::DEV9SettingsWidget(SettingsWindow* settings_dialog, QWidget*
headers.push_back(tr("Enabled"));
m_ethHost_model->setHorizontalHeaderLabels(headers);
connect(m_ethHost_model, QOverload<QStandardItem*>::of(&QStandardItemModel::itemChanged), this, &DEV9SettingsWidget::onEthHostEdit);
connect(m_ethHost_model, &QStandardItemModel::itemChanged, this, &DEV9SettingsWidget::onEthHostEdit);
m_ethHosts_proxy = new QSortFilterProxyModel(m_ui.ethHosts);
m_ethHosts_proxy->setSourceModel(m_ethHost_model);
@@ -186,7 +186,7 @@ DEV9SettingsWidget::DEV9SettingsWidget(SettingsWindow* settings_dialog, QWidget*
connect(m_ui.hddFile, &QLineEdit::editingFinished, this, &DEV9SettingsWidget::onHddFileEdit);
connect(m_ui.hddBrowseFile, &QPushButton::clicked, this, &DEV9SettingsWidget::onHddBrowseFileClicked);
connect(m_ui.hddSizeSlider, QOverload<int>::of(&QSlider::valueChanged), this, &DEV9SettingsWidget::onHddSizeSlide);
connect(m_ui.hddSizeSlider, &QSlider::valueChanged, this, &DEV9SettingsWidget::onHddSizeSlide);
SettingWidgetBinder::SettingAccessor<QSpinBox>::connectValueChanged(m_ui.hddSizeSpinBox, [&]() { onHddSizeAccessorSpin(); });
connect(m_ui.hddCreate, &QPushButton::clicked, this, &DEV9SettingsWidget::onHddCreateClicked);

View File

@@ -94,7 +94,7 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsWindow* settings_dialog
const std::optional<int> cycle_rate =
dialog()->getIntValue("EmuCore/Speedhacks", "EECycleRate", sif ? std::nullopt : std::optional<int>(DEFAULT_EE_CYCLE_RATE));
m_ui.eeCycleRate->setCurrentIndex(cycle_rate.has_value() ? (std::clamp(cycle_rate.value(), MINIMUM_EE_CYCLE_RATE, MAXIMUM_EE_CYCLE_RATE) + (0 - MINIMUM_EE_CYCLE_RATE) + static_cast<int>(dialog()->isPerGameSettings())) : 0);
connect(m_ui.eeCycleRate, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [&](int index) {
connect(m_ui.eeCycleRate, &QComboBox::currentIndexChanged, this, [&](int index) {
std::optional<int> value;
if (!dialog()->isPerGameSettings() || index > 0)
value = MINIMUM_EE_CYCLE_RATE + index - static_cast<int>(dialog()->isPerGameSettings());
@@ -218,7 +218,7 @@ void EmulationSettingsWidget::initializeSpeedCombo(QComboBox* cb, const char* se
cb->setCurrentIndex(custom_index);
}
connect(cb, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
connect(cb, &QComboBox::currentIndexChanged, this,
[this, cb, section, key](int index) { handleSpeedComboChange(cb, section, key); });
}

View File

@@ -14,8 +14,31 @@
<string/>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
<item row="3" column="1">
<widget class="QComboBox" name="hwAutoFlush">
<item row="8" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="0">
<widget class="QLabel" name="skipDrawLabel">
<property name="text">
<string>Skip Draw Range:</string>
</property>
<property name="buddy">
<cstring>skipDrawStart</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="textureInsideRt">
<item>
<property name="text">
<string>Disabled (Default)</string>
@@ -23,12 +46,12 @@
</item>
<item>
<property name="text">
<string>Enabled (Sprites Only)</string>
<string>Inside Target</string>
</property>
</item>
<item>
<property name="text">
<string>Enabled (All Primitives)</string>
<string>Merge Targets</string>
</property>
</item>
</widget>
@@ -43,41 +66,6 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="skipDrawLabel">
<property name="text">
<string>Skip Draw Range:</string>
</property>
<property name="buddy">
<cstring>skipDrawStart</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cpuCLUTRender">
<property name="currentText">
<string extracomment="0 (Disabled)">0 (Disabled)</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>0 (Disabled)</string>
</property>
</item>
<item>
<property name="text">
<string>1 (Normal)</string>
</property>
</item>
<item>
<property name="text">
<string>2 (Aggressive)</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="cpuCLUTRenderLayout" stretch="0,0">
<item>
@@ -160,8 +148,36 @@
</item>
</layout>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="textureInsideRt">
<item row="3" column="0">
<widget class="QLabel" name="hwAutoFlushLabel">
<property name="text">
<string>Auto Flush:</string>
</property>
<property name="buddy">
<cstring>hwAutoFlush</cstring>
</property>
</widget>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="skipDrawLayout">
<item>
<widget class="QSpinBox" name="skipDrawStart">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="skipDrawEnd">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="gpuTargetCLUTMode">
<item>
<property name="text">
<string>Disabled (Default)</string>
@@ -169,12 +185,57 @@
</item>
<item>
<property name="text">
<string>Inside Target</string>
<string>Enabled (Exact Match)</string>
</property>
</item>
<item>
<property name="text">
<string>Merge Targets</string>
<string>Enabled (Check Inside Target)</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="cpuCLUTRenderLabel">
<property name="text">
<string>CPU Sprite Render Size:</string>
</property>
<property name="buddy">
<cstring>cpuSpriteRenderBW</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="gpuTargetCLUTLabel">
<property name="text">
<string extracomment="CLUT: Color Look Up Table, often referred to as a palette in non-PS2 things. GPU Target CLUT: GPU handling of when a game uses data from a render target as a CLUT.">GPU Target CLUT:</string>
</property>
<property name="buddy">
<cstring>gpuTargetCLUTMode</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cpuCLUTRender">
<property name="currentText">
<string extracomment="0 (Disabled)">0 (Disabled)</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>0 (Disabled)</string>
</property>
</item>
<item>
<property name="text">
<string>1 (Normal)</string>
</property>
</item>
<item>
<property name="text">
<string>2 (Aggressive)</string>
</property>
</item>
</widget>
@@ -189,7 +250,26 @@
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<item row="3" column="1">
<widget class="QComboBox" name="hwAutoFlush">
<item>
<property name="text">
<string>Disabled (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Enabled (Sprites Only)</string>
</property>
</item>
<item>
<property name="text">
<string>Enabled (All Primitives)</string>
</property>
</item>
</widget>
</item>
<item row="7" column="0" colspan="2">
<layout class="QGridLayout" name="hwFixesLayout">
<item row="4" column="0">
<widget class="QCheckBox" name="estimateTextureRegion">
@@ -256,28 +336,8 @@
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="hwAutoFlushLabel">
<property name="text">
<string>Auto Flush:</string>
</property>
<property name="buddy">
<cstring>hwAutoFlush</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="gpuTargetCLUTLabel">
<property name="text">
<string extracomment="CLUT: Color Look Up Table, often referred to as a palette in non-PS2 things. GPU Target CLUT: GPU handling of when a game uses data from a render target as a CLUT.">GPU Target CLUT:</string>
</property>
<property name="buddy">
<cstring>gpuTargetCLUTMode</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="gpuTargetCLUTMode">
<item row="5" column="1">
<widget class="QComboBox" name="limit24BitDepth">
<item>
<property name="text">
<string>Disabled (Default)</string>
@@ -285,57 +345,23 @@
</item>
<item>
<property name="text">
<string>Enabled (Exact Match)</string>
<string>Prioritize Upper Bits</string>
</property>
</item>
<item>
<property name="text">
<string>Enabled (Check Inside Target)</string>
<string>Prioritize Lower Bits</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="cpuCLUTRenderLabel">
<item row="5" column="0">
<widget class="QLabel" name="limitDepthLabel">
<property name="text">
<string>CPU Sprite Render Size:</string>
</property>
<property name="buddy">
<cstring>cpuSpriteRenderBW</cstring>
<string>Limit Depth to 24 Bits</string>
</property>
</widget>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="skipDrawLayout">
<item>
<widget class="QSpinBox" name="skipDrawStart">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="skipDrawEnd">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>

View File

@@ -99,7 +99,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_display.cropBottom, "EmuCore/GS", "CropBottom", 0);
connect(
m_display.fullscreenModes, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &GraphicsSettingsWidget::onFullscreenModeChanged);
m_display.fullscreenModes, &QComboBox::currentIndexChanged, this, &GraphicsSettingsWidget::onFullscreenModeChanged);
//////////////////////////////////////////////////////////////////////////
// HW Settings
@@ -114,9 +114,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_hw.blending, "EmuCore/GS", "accurate_blending_unit", static_cast<int>(AccBlendLevel::Basic));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_hw.enableHWFixes, "EmuCore/GS", "UserHacks", false);
connect(m_hw.upscaleMultiplier, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
connect(m_hw.upscaleMultiplier, &QComboBox::currentIndexChanged, this,
&GraphicsSettingsWidget::onUpscaleMultiplierChanged);
connect(m_hw.trilinearFiltering, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
connect(m_hw.trilinearFiltering, &QComboBox::currentIndexChanged, this,
&GraphicsSettingsWidget::onTrilinearFilteringChanged);
onTrilinearFilteringChanged();
@@ -147,10 +147,12 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
sif, m_fixes.disablePartialInvalidation, "EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_fixes.textureInsideRt, "EmuCore/GS", "UserHacks_TextureInsideRt", static_cast<int>(GSTextureInRtMode::Disabled));
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_fixes.limit24BitDepth, "EmuCore/GS", "UserHacks_Limit24BitDepth", static_cast<int>(GSLimit24BitDepth::Disabled));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_fixes.readTCOnClose, "EmuCore/GS", "UserHacks_ReadTCOnClose", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_fixes.estimateTextureRegion, "EmuCore/GS", "UserHacks_EstimateTextureRegion", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_fixes.gpuPaletteConversion, "EmuCore/GS", "paltex", false);
connect(m_fixes.cpuSpriteRenderBW, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
connect(m_fixes.cpuSpriteRenderBW, &QComboBox::currentIndexChanged, this,
&GraphicsSettingsWidget::onCPUSpriteRenderBWChanged);
connect(m_fixes.gpuPaletteConversion, &QCheckBox::checkStateChanged, this, &GraphicsSettingsWidget::onGpuPaletteConversionChanged);
onCPUSpriteRenderBWChanged();
@@ -295,8 +297,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
m_header.rendererDropdown->setCurrentIndex(0);
}
connect(m_header.rendererDropdown, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &GraphicsSettingsWidget::onRendererChanged);
connect(m_header.adapterDropdown, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &GraphicsSettingsWidget::onAdapterChanged);
connect(m_header.rendererDropdown, &QComboBox::currentIndexChanged, this, &GraphicsSettingsWidget::onRendererChanged);
connect(m_header.adapterDropdown, &QComboBox::currentIndexChanged, this, &GraphicsSettingsWidget::onAdapterChanged);
connect(m_hw.enableHWFixes, &QCheckBox::checkStateChanged, this, &GraphicsSettingsWidget::updateRendererDependentOptions);
connect(m_advanced.extendedUpscales, &QCheckBox::checkStateChanged, this, &GraphicsSettingsWidget::updateRendererDependentOptions);
connect(m_hw.textureFiltering, &QComboBox::currentIndexChanged, this, &GraphicsSettingsWidget::onTextureFilteringChange);
@@ -624,6 +626,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
dialog()->registerWidgetHelp(m_fixes.textureInsideRt, tr("Texture Inside RT"), tr("Disabled"),
tr("Allows the texture cache to reuse as an input texture the inner portion of a previous framebuffer."));
dialog()->registerWidgetHelp(m_fixes.limit24BitDepth, tr("Limit Depth to 24 Bits"), tr("Disabled"),
tr("Truncate 32-bit depth values to 24 bits. Helps games struggling with Z-fighting."));
dialog()->registerWidgetHelp(m_fixes.readTCOnClose, tr("Read Targets When Closing"), tr("Unchecked"),
tr("Flushes all targets in the texture cache back to local memory when shutting down. Can prevent lost visuals when saving "
"state or switching graphics APIs, but can also cause graphical corruption."));

View File

@@ -133,18 +133,18 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* settings_dialog
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.theme, "UI", "Theme", THEME_NAMES, THEME_VALUES,
QtHost::GetDefaultThemeName(), "InterfaceSettingsWidget");
connect(m_ui.theme, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]() { emit themeChanged(); });
connect(m_ui.theme, &QComboBox::currentIndexChanged, [this]() { emit themeChanged(); });
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.backgroundOpacity, "UI", "GameListBackgroundOpacity", 100.0f);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.backgroundScale, "UI", "GameListBackgroundMode", BACKGROUND_SCALE_NAMES, QtUtils::ScalingMode::Fit);
connect(m_ui.backgroundBrowse, &QPushButton::clicked, [this]() { onSetGameListBackgroundTriggered(); });
connect(m_ui.backgroundReset, &QPushButton::clicked, [this]() { onClearGameListBackgroundTriggered(); });
connect(m_ui.backgroundOpacity, &QSpinBox::editingFinished, [this]() { emit backgroundChanged(); });
connect(m_ui.backgroundScale, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]() { emit backgroundChanged(); });
connect(m_ui.backgroundScale, &QComboBox::currentIndexChanged, [this]() { emit backgroundChanged(); });
populateLanguages();
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.language, "UI", "Language", QtHost::GetDefaultLanguage());
connect(m_ui.language, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]() { emit languageChanged(); });
connect(m_ui.language, &QComboBox::currentIndexChanged, [this]() { emit languageChanged(); });
// Per-game settings is special, we don't want to bind it if we're editing per-game settings.
if (!dialog()->isPerGameSettings())

View File

@@ -176,7 +176,7 @@ void SetupWizardDialog::setupLanguagePage()
{
SettingWidgetBinder::BindWidgetToEnumSetting(nullptr, m_ui.theme, "UI", "Theme",
InterfaceSettingsWidget::THEME_NAMES, InterfaceSettingsWidget::THEME_VALUES, QtHost::GetDefaultThemeName(), "InterfaceSettingsWidget");
connect(m_ui.theme, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SetupWizardDialog::themeChanged);
connect(m_ui.theme, &QComboBox::currentIndexChanged, this, &SetupWizardDialog::themeChanged);
for (const std::pair<QString, QString>& it : QtHost::GetAvailableLanguageList())
{
@@ -189,7 +189,7 @@ void SetupWizardDialog::setupLanguagePage()
SettingWidgetBinder::BindWidgetToStringSetting(
nullptr, m_ui.language, "UI", "Language", QtHost::GetDefaultLanguage());
connect(
m_ui.language, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SetupWizardDialog::languageChanged);
m_ui.language, &QComboBox::currentIndexChanged, this, &SetupWizardDialog::languageChanged);
SettingWidgetBinder::BindWidgetToBoolSetting(
nullptr, m_ui.autoUpdateEnabled, "AutoUpdater", "CheckAtStartup", true);

View File

@@ -437,26 +437,26 @@ void QtHost::SetStyleFromSettings()
// Alternative dark theme.
qApp->setStyle(QStyleFactory::create("Fusion"));
const QColor gray(150, 150, 150);
const QColor royalBlue(29, 41, 81);
const QColor darkishBlue(17, 30, 108);
const QColor abyssBlue(39, 58, 114);
const QColor darkishBlue(29, 41, 81);
const QColor lighterBlue(25, 32, 130);
const QColor highlight(36, 93, 218);
const QColor link(0, 202, 255);
const QColor blue(198, 238, 255);
const QColor gray(150, 150, 150);
QPalette cobaltSkyPalette;
cobaltSkyPalette.setColor(QPalette::Window, royalBlue);
cobaltSkyPalette.setColor(QPalette::Window, abyssBlue);
cobaltSkyPalette.setColor(QPalette::WindowText, Qt::white);
cobaltSkyPalette.setColor(QPalette::Base, royalBlue.lighter());
cobaltSkyPalette.setColor(QPalette::AlternateBase, darkishBlue);
cobaltSkyPalette.setColor(QPalette::Base, darkishBlue);
cobaltSkyPalette.setColor(QPalette::AlternateBase, darkishBlue.darker());
cobaltSkyPalette.setColor(QPalette::ToolTipBase, darkishBlue);
cobaltSkyPalette.setColor(QPalette::ToolTipText, Qt::white);
cobaltSkyPalette.setColor(QPalette::Text, Qt::white);
cobaltSkyPalette.setColor(QPalette::Button, lighterBlue);
cobaltSkyPalette.setColor(QPalette::ButtonText, Qt::white);
cobaltSkyPalette.setColor(QPalette::Link, link);
cobaltSkyPalette.setColor(QPalette::Highlight, highlight);
cobaltSkyPalette.setColor(QPalette::Link, blue);
cobaltSkyPalette.setColor(QPalette::Highlight, abyssBlue.lighter());
cobaltSkyPalette.setColor(QPalette::HighlightedText, Qt::white);
cobaltSkyPalette.setColor(QPalette::PlaceholderText, gray);
cobaltSkyPalette.setColor(QPalette::Active, QPalette::Button, lighterBlue);
cobaltSkyPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
@@ -475,9 +475,9 @@ void QtHost::SetStyleFromSettings()
// OLED screens.
qApp->setStyle(QStyleFactory::create("Fusion"));
const QColor black(0, 0, 0);
const QColor gray(25, 25, 25);
const QColor lighterGray(75, 75, 75);
const QColor black(5, 5, 5);
const QColor gray(22, 22, 29);
const QColor lighterGray(65, 79, 98);
const QColor blue(198, 238, 255);
QPalette AMOLEDPalette;
@@ -519,7 +519,7 @@ void QtHost::SetStyleFromSettings()
rubyPalette.setColor(QPalette::Window, slate);
rubyPalette.setColor(QPalette::WindowText, Qt::white);
rubyPalette.setColor(QPalette::Base, slate.lighter());
rubyPalette.setColor(QPalette::AlternateBase, slate.lighter());
rubyPalette.setColor(QPalette::AlternateBase, slate.darker());
rubyPalette.setColor(QPalette::ToolTipBase, slate);
rubyPalette.setColor(QPalette::ToolTipText, Qt::white);
rubyPalette.setColor(QPalette::Text, Qt::white);
@@ -553,7 +553,7 @@ void QtHost::SetStyleFromSettings()
sapphirePalette.setColor(QPalette::Window, slate);
sapphirePalette.setColor(QPalette::WindowText, Qt::white);
sapphirePalette.setColor(QPalette::Base, slate.lighter());
sapphirePalette.setColor(QPalette::AlternateBase, slate.lighter());
sapphirePalette.setColor(QPalette::AlternateBase, slate.darker());
sapphirePalette.setColor(QPalette::ToolTipBase, slate);
sapphirePalette.setColor(QPalette::ToolTipText, Qt::white);
sapphirePalette.setColor(QPalette::Text, Qt::white);
@@ -587,7 +587,7 @@ void QtHost::SetStyleFromSettings()
emeraldPalette.setColor(QPalette::Window, slate);
emeraldPalette.setColor(QPalette::WindowText, Qt::white);
emeraldPalette.setColor(QPalette::Base, slate.lighter());
emeraldPalette.setColor(QPalette::AlternateBase, slate.lighter());
emeraldPalette.setColor(QPalette::AlternateBase, slate.darker());
emeraldPalette.setColor(QPalette::ToolTipBase, slate);
emeraldPalette.setColor(QPalette::ToolTipText, Qt::white);
emeraldPalette.setColor(QPalette::Text, Qt::white);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,7 @@
#include "common/MD5Digest.h"
#include "common/Path.h"
#include "common/ScopedGuard.h"
#include "common/SettingsInterface.h"
#include "common/SmallString.h"
#include "common/StringUtil.h"
#include "common/Timer.h"
@@ -439,7 +440,25 @@ bool Achievements::Initialize()
IdentifyGame(VMManager::GetDiscCRC(), VMManager::GetCurrentCRC());
const std::string username = Host::GetBaseStringSettingValue("Achievements", "Username");
const std::string api_token = Host::GetBaseStringSettingValue("Achievements", "Token");
// Check the base settings file to see if the token is defined inside. Move if found.
std::string oldToken = Host::GetBaseStringSettingValue("Achievements", "Token");
if (!oldToken.empty())
{
auto secretsLock = Host::GetSecretsSettingsLock();
SettingsInterface* secretsInterface = Host::Internal::GetSecretsSettingsLayer();
secretsInterface->SetStringValue("Achievements", "Token", oldToken.c_str());
secretsInterface->Save();
oldToken.clear();
auto baseLock = Host::GetSettingsLock();
SettingsInterface* baseInterface = Host::Internal::GetBaseSettingsLayer();
baseInterface->DeleteValue("Achievements", "Token");
baseInterface->Save();
}
const std::string api_token = Host::GetStringSettingValue("Achievements", "Token");
if (!username.empty() && !api_token.empty())
{
Console.WriteLn("Achievements: Attempting login with user '%s'...", username.c_str());
@@ -1024,21 +1043,11 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
s_has_leaderboards = has_leaderboards;
s_has_rich_presence = rc_client_has_rich_presence(client);
s_game_icon = {};
s_game_icon_url = {};
s_game_icon_url = info->badge_url;
// ensure fullscreen UI is ready for notifications
MTGS::RunOnGSThread(&ImGuiManager::InitializeFullscreenUI);
char url_buffer[URL_BUFFER_SIZE];
if (int err = rc_client_game_get_image_url(info, url_buffer, std::size(url_buffer)); err == RC_OK)
{
s_game_icon_url = url_buffer;
}
else
{
ReportRCError(err, "rc_client_game_get_image_url() failed: ");
}
if (const std::string_view badge_name = info->badge_name; !badge_name.empty())
{
s_game_icon = Path::Combine(s_image_directory, fmt::format("game_{}.png", badge_name));
@@ -1785,9 +1794,12 @@ void Achievements::ClientLoginWithPasswordCallback(int result, const char* error
// Store configuration.
Host::SetBaseStringSettingValue("Achievements", "Username", params->username);
Host::SetBaseStringSettingValue("Achievements", "Token", user->token);
Host::SetBaseStringSettingValue("Achievements", "LoginTimestamp", fmt::format("{}", std::time(nullptr)).c_str());
Host::CommitBaseSettingChanges();
SettingsInterface* secretsInterface = Host::Internal::GetSecretsSettingsLayer();
secretsInterface->SetStringValue("Achievements", "Token", user->token);
secretsInterface->Save();
ShowLoginSuccess(client);
}
@@ -1887,9 +1899,13 @@ void Achievements::Logout()
Console.WriteLn("Achievements: Clearing credentials...");
Host::RemoveBaseSettingValue("Achievements", "Username");
Host::RemoveBaseSettingValue("Achievements", "Token");
Host::RemoveBaseSettingValue("Achievements", "LoginTimestamp");
Host::CommitBaseSettingChanges();
auto secretsLock = Host::GetSecretsSettingsLock();
SettingsInterface* secretsInterface = Host::Internal::GetSecretsSettingsLayer();
secretsInterface->DeleteValue("Achievements", "Token");
secretsInterface->Save();
}

View File

@@ -6,7 +6,7 @@
#include "CDVD/IsoFileFormats.h"
#include "Config.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "common/Assertions.h"
#include "common/Console.h"

View File

@@ -432,6 +432,13 @@ enum class GSTextureInRtMode : u8
MergeTargets,
};
enum class GSLimit24BitDepth : u8
{
Disabled,
PrioritizeUpper,
PrioritizeLower,
};
enum class GSBilinearDirtyMode : u8
{
Automatic,
@@ -844,6 +851,7 @@ struct Pcsx2Config
u8 UserHacks_CPUCLUTRender = 0;
GSGPUTargetCLUTMode UserHacks_GPUTargetCLUTMode = GSGPUTargetCLUTMode::Disabled;
GSTextureInRtMode UserHacks_TextureInsideRt = GSTextureInRtMode::Disabled;
GSLimit24BitDepth UserHacks_Limit24BitDepth = GSLimit24BitDepth::Disabled;
GSBilinearDirtyMode UserHacks_BilinearHack = GSBilinearDirtyMode::Automatic;
TriFiltering TriFilter = TriFiltering::Automatic;
s8 OverrideTextureBarriers = -1;

View File

@@ -10,9 +10,9 @@
std::vector<BreakPoint> CBreakPoints::breakPoints_;
u32 CBreakPoints::breakSkipFirstAtEE_ = 0;
u64 CBreakPoints::breakSkipFirstTicksEE_ = 0;
u32 CBreakPoints::breakSkipFirstAtIop_ = 0;
u64 CBreakPoints::breakSkipFirstTicksIop_ = 0;
bool CBreakPoints::pendingClearSkipFirstAtEE_ = false;
bool CBreakPoints::pendingClearSkipFirstAtIop_ = false;
std::vector<MemCheck> CBreakPoints::memChecks_;
std::vector<MemCheck*> CBreakPoints::cleanupMemChecks_;
bool CBreakPoints::breakpointTriggered_ = false;
@@ -393,30 +393,47 @@ void CBreakPoints::SetSkipFirst(BreakPointCpu cpu, u32 pc)
if (cpu == BREAKPOINT_EE)
{
breakSkipFirstAtEE_ = standardizeBreakpointAddress(pc);
breakSkipFirstTicksEE_ = r5900Debug.getCycles();
pendingClearSkipFirstAtEE_ = false;
}
else if (cpu == BREAKPOINT_IOP)
{
breakSkipFirstAtIop_ = pc;
breakSkipFirstTicksIop_ = r3000Debug.getCycles();
pendingClearSkipFirstAtIop_ = false;
}
}
u32 CBreakPoints::CheckSkipFirst(BreakPointCpu cpu, u32 cmpPc)
{
if (cpu == BREAKPOINT_EE && breakSkipFirstTicksEE_ == r5900Debug.getCycles())
if (cpu == BREAKPOINT_EE && breakSkipFirstAtEE_ == r5900Debug.getPC())
return breakSkipFirstAtEE_;
else if (cpu == BREAKPOINT_IOP && breakSkipFirstTicksIop_ == r3000Debug.getCycles())
else if (cpu == BREAKPOINT_IOP && breakSkipFirstAtIop_ == r3000Debug.getPC())
return breakSkipFirstAtIop_;
return 0;
}
void CBreakPoints::ClearSkipFirst()
void CBreakPoints::ClearSkipFirst(BreakPointCpu cpu)
{
breakSkipFirstAtEE_ = 0;
breakSkipFirstTicksEE_ = 0;
breakSkipFirstAtIop_ = 0;
breakSkipFirstTicksIop_ = 0;
if((cpu & BREAKPOINT_EE) != 0)
pendingClearSkipFirstAtEE_ = true;
else if ((cpu & BREAKPOINT_IOP) != 0)
pendingClearSkipFirstAtIop_ = true;
if(cpu == BREAKPOINT_IOP_AND_EE)
CommitClearSkipFirst(BREAKPOINT_IOP_AND_EE);
}
void CBreakPoints::CommitClearSkipFirst(BreakPointCpu cpu)
{
if((cpu & BREAKPOINT_EE) != 0 && pendingClearSkipFirstAtEE_)
{
pendingClearSkipFirstAtEE_ = false;
breakSkipFirstAtEE_ = 0;
}
else if ((cpu & BREAKPOINT_IOP) != 0 && pendingClearSkipFirstAtIop_)
{
pendingClearSkipFirstAtIop_ = true;
breakSkipFirstAtIop_ = 0;
}
}
const std::vector<MemCheck> CBreakPoints::GetMemCheckRanges()

View File

@@ -135,7 +135,8 @@ public:
static void SetSkipFirst(BreakPointCpu cpu, u32 pc);
static u32 CheckSkipFirst(BreakPointCpu cpu, u32 pc);
static void ClearSkipFirst();
static void ClearSkipFirst(BreakPointCpu cpu = BREAKPOINT_IOP_AND_EE);
static void CommitClearSkipFirst(BreakPointCpu cpu);
// Includes uncached addresses.
static const std::vector<MemCheck> GetMemCheckRanges();
@@ -169,9 +170,9 @@ private:
static std::vector<BreakPoint> breakPoints_;
static u32 breakSkipFirstAtEE_;
static u64 breakSkipFirstTicksEE_;
static bool pendingClearSkipFirstAtEE_;
static u32 breakSkipFirstAtIop_;
static u64 breakSkipFirstTicksIop_;
static bool pendingClearSkipFirstAtIop_;
static bool breakpointTriggered_;
static BreakPointCpu breakpointTriggeredCpu_;

View File

@@ -48,7 +48,7 @@
#include "common/SmallString.h"
#include "common/StringUtil.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "fmt/format.h"
@@ -533,7 +533,7 @@ bool GSHasDisplayWindow()
return (g_gs_device->GetWindowInfo().type != WindowInfo::Type::Surfaceless);
}
void GSResizeDisplayWindow(int width, int height, float scale)
void GSResizeDisplayWindow(u32 width, u32 height, float scale)
{
g_gs_device->ResizeWindow(width, height, scale);
ImGuiManager::WindowResized();

View File

@@ -83,7 +83,7 @@ void GSThrottlePresentation();
void GSGameChanged();
void GSSetDisplayAlignment(GSDisplayAlignment alignment);
bool GSHasDisplayWindow();
void GSResizeDisplayWindow(int width, int height, float scale);
void GSResizeDisplayWindow(u32 width, u32 height, float scale);
void GSUpdateDisplayWindow();
void GSSetVSyncMode(GSVSyncMode mode, bool allow_present_throttle);

View File

@@ -10,7 +10,7 @@
#include "SPU2/spu2.h"
#include "Host.h"
#include "Host/AudioStream.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/BitUtils.h"

View File

@@ -806,12 +806,12 @@ void GSState::DumpTransferList(const std::string& filename)
(*file) << std::endl;
// clear, EE->GS, or GS->GS
(*file) << LIST_ITEM << "type: " << (transfer.zero_clear ? "clear" : (transfer.ee_to_gs ? "EE_to_GS" : "GS_to_GS")) << std::endl;
(*file) << LIST_ITEM << "type: " << (transfer.zero_clear ? "clear" : ((transfer.transfer_type == EEGS_TransferType::EE_to_GS) ? "EE_to_GS" : "GS_to_GS")) << std::endl;
// Dump BITBLTBUF
(*file) << INDENT << "BITBLTBUF: " << OPEN_MAP;
const bool gs_to_gs = !transfer.ee_to_gs && !transfer.zero_clear;
const bool gs_to_gs = (transfer.transfer_type == EEGS_TransferType::GS_to_GS) && !transfer.zero_clear;
if (gs_to_gs)
{
@@ -857,7 +857,7 @@ void GSState::DumpTransferImages()
const GSUploadQueue& transfer = m_draw_transfers[i];
std::string filename;
if (transfer.ee_to_gs || transfer.zero_clear)
if ((transfer.transfer_type == EEGS_TransferType::EE_to_GS) || transfer.zero_clear)
{
// clear or EE->GS: only the destination info is relevant.
filename = GetDrawDumpPath("%05d_transfer%02d_%s_%04x_%d_%s_%d_%d_%d_%d.png",
@@ -2365,7 +2365,7 @@ void GSState::Write(const u8* mem, int len)
s_last_transfer_draw_n = s_n;
// Store the transfer for preloading new RT's.
if ((m_draw_transfers.size() > 0 && blit.DBP == m_draw_transfers.back().blit.DBP))
if ((m_draw_transfers.size() > 0 && blit.DBP == m_draw_transfers.back().blit.DBP && m_draw_transfers.back().transfer_type == EEGS_TransferType::EE_to_GS))
{
// Same BP, let's update the rect.
GSUploadQueue transfer = m_draw_transfers.back();
@@ -2377,7 +2377,7 @@ void GSState::Write(const u8* mem, int len)
}
else
{
const GSUploadQueue new_transfer = { blit, r, s_n, false, true };
const GSUploadQueue new_transfer = {blit, r, s_n, false, EEGS_TransferType::EE_to_GS};
m_draw_transfers.push_back(new_transfer);
}
@@ -2519,21 +2519,31 @@ void GSState::Move()
InvalidateLocalMem(m_env.BITBLTBUF, GSVector4i(sx, sy, sx + w, sy + h));
InvalidateVideoMem(m_env.BITBLTBUF, GSVector4i(dx, dy, dx + w, dy + h));
const bool overlaps = m_env.BITBLTBUF.SBP == m_env.BITBLTBUF.DBP;
const bool intersect = overlaps && !(GSVector4i(sx, sy, sx + w, sy + h).rintersect(GSVector4i(dx, dy, dx + w, dy + h)).rempty());
int xinc = 1;
int yinc = 1;
if (m_env.TRXPOS.DIRX)
{
sx += w - 1;
dx += w - 1;
xinc = -1;
// Only allow it to reverse if the destination is behind the source.
if (!intersect || (sx <= dx && (sx == dx || ((!m_env.TRXPOS.DIRY && sy >= dy) || (m_env.TRXPOS.DIRY && sy < dy)))))
{
sx += w - 1;
dx += w - 1;
xinc = -1;
}
}
if (m_env.TRXPOS.DIRY)
{
sy += h - 1;
dy += h - 1;
yinc = -1;
// Only allow it to reverse if the destination is behind the source.
if (!intersect || (sy <= dy && (sy == dy || ((!m_env.TRXPOS.DIRX && sx >= dx) || (m_env.TRXPOS.DIRX && sx < dx)))))
{
sy += h - 1;
dy += h - 1;
yinc = -1;
}
}
const GSLocalMemory::psm_t& spsm = GSLocalMemory::m_psm[m_env.BITBLTBUF.SPSM];
@@ -2556,7 +2566,7 @@ void GSState::Move()
s_last_transfer_draw_n = s_n;
// Store the transfer for preloading new RT's.
if ((m_draw_transfers.size() > 0 && m_env.BITBLTBUF.DBP == m_draw_transfers.back().blit.DBP))
if ((m_draw_transfers.size() > 0 && m_env.BITBLTBUF.DBP == m_draw_transfers.back().blit.DBP && m_draw_transfers.back().transfer_type == EEGS_TransferType::GS_to_GS))
{
// Same BP, let's update the rect.
GSUploadQueue transfer = m_draw_transfers.back();
@@ -2568,11 +2578,11 @@ void GSState::Move()
}
else
{
const GSUploadQueue new_transfer = { m_env.BITBLTBUF, r, s_n, false, false };
const GSUploadQueue new_transfer = {m_env.BITBLTBUF, r, s_n, false, EEGS_TransferType::GS_to_GS};
m_draw_transfers.push_back(new_transfer);
}
auto copy = [this, sbp, dbp, sx, sy, dx, dy, w, h, yinc, xinc](const GSOffset& dpo, const GSOffset& spo, auto&& pxCopyFn)
auto copy = [this, sbp, dbp, sx, sy, dx, dy, w, h, yinc, xinc, intersect](const GSOffset& dpo, const GSOffset& spo, auto&& pxCopyFn)
{
int _sy = sy, _dy = dy; // Faster with local copied variables, compiler optimizations are dumb
if (xinc > 0)
@@ -2584,8 +2594,6 @@ void GSState::Move()
// Copying from itself to itself (rotating textures) used in Gitaroo Man stage 8
// What probably happens is because the copy is buffered, the source stays just ahead of the destination.
// No need to do all this if the copy source/destination don't intersect, however.
const bool intersect = !(GSVector4i(sx, sy, sx + w, sy + h).rintersect(GSVector4i(dx, dy, dx + w, dy + h)).rempty());
if (intersect && sbp == dbp && (((_sy < _dy) && ((ypage + page_height) > _dy)) || ((sx < dx) && ((xpage + page_width) > dx))))
{
int starty = (yinc > 0) ? 0 : h-1;
@@ -4657,6 +4665,14 @@ __forceinline void GSState::VertexKick(u32 skip)
u32 next = m_vertex.next;
u32 xy_tail = m_vertex.xy_tail;
if (GSIsHardwareRenderer() && GSLocalMemory::m_psm[m_context->ZBUF.PSM].bpp == 32)
{
if (GSConfig.UserHacks_Limit24BitDepth == GSLimit24BitDepth::PrioritizeUpper)
m_v.XYZ.Z = ((m_v.XYZ.Z >> 8) & ~0xFF) | (m_v.XYZ.Z & 0xFF);
else if (GSConfig.UserHacks_Limit24BitDepth == GSLimit24BitDepth::PrioritizeLower)
m_v.XYZ.Z &= 0x00FFFFFF;
}
// callers should write XYZUVF to m_v.m[1] in one piece to have this load store-forwarded, either by the cpu or the compiler when this function is inlined
const GSVector4i new_v0(m_v.m[0]);

View File

@@ -211,13 +211,20 @@ protected:
void CorrectATEAlphaMinMax(const u32 atst, const int aref);
public:
enum EEGS_TransferType
{
EE_to_GS,
GS_to_GS,
GS_to_EE
};
struct GSUploadQueue
{
GIFRegBITBLTBUF blit;
GSVector4i rect;
int draw;
bool zero_clear;
bool ee_to_gs;
EEGS_TransferType transfer_type;
};
enum NoGapsType

View File

@@ -918,10 +918,15 @@ void GSDevice::Resize(int width, int height)
GSVector2i s = m_current->GetSize();
int multiplier = 1;
while (width > s.x || height > s.y)
if ((width > s.x || height > s.y))
{
s = m_current->GetSize() * GSVector2i(++multiplier);
while (width > s.x || height > s.y)
{
s = m_current->GetSize() * GSVector2i(++multiplier);
}
}
else
s = GSVector2i(width, height);
if (ResizeRenderTarget(&dTex, s.x, s.y, false, false))
{

View File

@@ -401,6 +401,7 @@ struct alignas(16) GSHWDrawConfig
// Depth clamp
u32 zclamp : 1;
u32 zfloor : 1;
// Hack
u32 tcoffsethack : 1;
@@ -1019,7 +1020,7 @@ public:
virtual bool UpdateWindow() = 0;
/// Call when the window size changes externally to recreate any resources.
virtual void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) = 0;
virtual void ResizeWindow(u32 new_window_width, u32 new_window_height, float new_window_scale) = 0;
/// Returns true if exclusive fullscreen is supported.
virtual bool SupportsExclusiveFullscreen() const = 0;

View File

@@ -22,7 +22,7 @@
#include "common/Timer.h"
#include "fmt/format.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include <algorithm>
#include <array>
@@ -714,6 +714,15 @@ void GSRenderer::VSync(u32 field, bool registers_written, bool idle_frame)
u32 screenshot_width, screenshot_height;
std::vector<u32> screenshot_pixels;
if (GSConfig.LinearPresent == GSPostBilinearMode::BilinearSharp)
{
const GSTexture* current = g_gs_device->GetCurrent();
const GSVector2i internal_res = GetInternalResolution();
if (current->GetWidth() > internal_res.x || current->GetHeight() > internal_res.y)
g_gs_device->Resize(internal_res.x, internal_res.y);
}
if (!m_dump && m_dump_frames > 0)
{
if (GSConfig.UserHacks_ReadTCOnClose)

View File

@@ -15,7 +15,7 @@
#include "common/StringUtil.h"
#include "common/Path.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include <appmodel.h>
#include <array>
@@ -439,7 +439,9 @@ GSRendererType D3D::GetPreferredRenderer()
if (!feature_level.has_value())
return GSRendererType::DX11;
else if (feature_level == D3D_FEATURE_LEVEL_12_0)
return check_vulkan_supported() ? GSRendererType::VK : GSRendererType::DX11;
return check_vulkan_supported() ? GSRendererType::VK : GSRendererType::DX12;
else if (feature_level == D3D_FEATURE_LEVEL_11_1)
return GSRendererType::DX12;
else
return GSRendererType::DX11;
}

View File

@@ -16,7 +16,7 @@
#include "common/StringUtil.h"
#include "imgui.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include <bit>
#include <fstream>
@@ -278,7 +278,7 @@ bool GSDevice11::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
for (size_t i = 0; i < std::size(m_merge.ps); i++)
{
const std::string entry_point(StringUtil::StdStringFromFormat("ps_main%d", i));
const std::string entry_point(StringUtil::StdStringFromFormat("ps_main%zu", i));
m_merge.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *shader, nullptr, entry_point.c_str());
if (!m_merge.ps[i])
return false;
@@ -312,7 +312,7 @@ bool GSDevice11::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
return false;
for (size_t i = 0; i < std::size(m_interlace.ps); i++)
{
const std::string entry_point(StringUtil::StdStringFromFormat("ps_main%d", i));
const std::string entry_point(StringUtil::StdStringFromFormat("ps_main%zu", i));
m_interlace.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *shader, nullptr, entry_point.c_str());
if (!m_interlace.ps[i])
return false;
@@ -498,7 +498,7 @@ bool GSDevice11::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
for (size_t i = 0; i < std::size(m_date.primid_init_ps); i++)
{
const std::string entry_point(StringUtil::StdStringFromFormat("ps_stencil_image_init_%d", i));
const std::string entry_point(StringUtil::StdStringFromFormat("ps_stencil_image_init_%zu", i));
m_date.primid_init_ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *convert_hlsl, nullptr, entry_point.c_str());
if (!m_date.primid_init_ps[i])
return false;
@@ -893,7 +893,7 @@ std::string GSDevice11::GetDriverInfo() const
return ret;
}
void GSDevice11::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
void GSDevice11::ResizeWindow(u32 new_window_width, u32 new_window_height, float new_window_scale)
{
if (!m_swap_chain || m_is_exclusive_fullscreen)
return;
@@ -1760,6 +1760,7 @@ void GSDevice11::SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstant
sm.AddMacro("PS_DITHER", sel.dither);
sm.AddMacro("PS_DITHER_ADJUST", sel.dither_adjust);
sm.AddMacro("PS_ZCLAMP", sel.zclamp);
sm.AddMacro("PS_ZFLOOR", sel.zfloor);
sm.AddMacro("PS_SCANMSK", sel.scanmsk);
sm.AddMacro("PS_AUTOMATIC_LOD", sel.automatic_lod);
sm.AddMacro("PS_MANUAL_LOD", sel.manual_lod);

View File

@@ -273,7 +273,7 @@ public:
RenderAPI GetRenderAPI() const override;
bool UpdateWindow() override;
void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
void ResizeWindow(u32 new_window_width, u32 new_window_height, float new_window_scale) override;
bool SupportsExclusiveFullscreen() const override;
bool HasSurface() const override;
void DestroySurface() override;

View File

@@ -750,6 +750,8 @@ bool GSDevice12::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
InitializeState();
InitializeSamplers();
// Reference stencil isn't tied to pipeline, so we can set it once and leave it.
SetStencilRef(1);
return true;
}
@@ -1054,7 +1056,7 @@ std::string GSDevice12::GetDriverInfo() const
return ret;
}
void GSDevice12::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
void GSDevice12::ResizeWindow(u32 new_window_width, u32 new_window_height, float new_window_scale)
{
if (!m_swap_chain)
return;
@@ -2920,6 +2922,7 @@ const ID3DBlob* GSDevice12::GetTFXPixelShader(const GSHWDrawConfig::PSSelector&
sm.AddMacro("PS_DITHER", sel.dither);
sm.AddMacro("PS_DITHER_ADJUST", sel.dither_adjust);
sm.AddMacro("PS_ZCLAMP", sel.zclamp);
sm.AddMacro("PS_ZFLOOR", sel.zfloor);
sm.AddMacro("PS_SCANMSK", sel.scanmsk);
sm.AddMacro("PS_AUTOMATIC_LOD", sel.automatic_lod);
sm.AddMacro("PS_MANUAL_LOD", sel.manual_lod);
@@ -3740,7 +3743,7 @@ void GSDevice12::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSV
IASetVertexBuffer(vertices, sizeof(vertices[0]), 4);
SetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
SetPipeline(m_convert[SetDATMShader(datm)].get());
SetStencilRef(1);
// Reference stencil value set on Create()
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
@@ -3828,26 +3831,6 @@ GSTexture12* GSDevice12::SetupPrimitiveTrackingDATE(GSHWDrawConfig& config, Pipe
void GSDevice12::RenderHW(GSHWDrawConfig& config)
{
// Destination Alpha Setup
const bool stencil_DATE_One = config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne;
const bool stencil_DATE = (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil || stencil_DATE_One);
// TODO: Backport from vk.
if (stencil_DATE_One)
{
config.ps.date = 0;
config.alpha_second_pass.ps.date = 0;
if (!config.ps.IsFeedbackLoop())
{
config.require_one_barrier = false;
config.require_full_barrier = false;
}
if (!config.alpha_second_pass.ps.IsFeedbackLoop())
{
config.alpha_second_pass.require_one_barrier = false;
config.alpha_second_pass.require_full_barrier = false;
}
}
GSTexture12* colclip_rt = static_cast<GSTexture12*>(g_gs_device->GetColorClipTexture());
GSTexture12* draw_rt = static_cast<GSTexture12*>(config.rt);
@@ -3910,8 +3893,29 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
}
}
if (stencil_DATE)
SetupDATE(draw_rt, config.ds, config.datm, config.drawarea);
// Destination Alpha Setup
const bool need_barrier = m_features.texture_barrier && (config.require_one_barrier || config.require_full_barrier);
switch (config.destination_alpha)
{
case GSHWDrawConfig::DestinationAlphaMode::Off: // No setup
case GSHWDrawConfig::DestinationAlphaMode::Full: // No setup
case GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking: // Setup is done below
break;
case GSHWDrawConfig::DestinationAlphaMode::StencilOne: // setup is done below
{
// we only need to do the setup here if we don't have barriers, in which case do full DATE.
if (!need_barrier)
{
SetupDATE(draw_rt, config.ds, config.datm, config.drawarea);
config.destination_alpha = GSHWDrawConfig::DestinationAlphaMode::Stencil;
}
}
break;
case GSHWDrawConfig::DestinationAlphaMode::Stencil:
SetupDATE(draw_rt, config.ds, config.datm, config.drawarea);
break;
}
// stream buffer in first, in case we need to exec
SetVSConstantBuffer(config.cb_vs);
@@ -4033,6 +4037,17 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
// For depth testing and sampling, use a read only dsv, otherwise use a write dsv
OMSetRenderTargets(draw_rt, draw_ds, config.scissor, config.tex && config.tex == config.ds);
// DX12 equivalent of vkCmdClearAttachments for StencilOne
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne)
{
EndRenderPass();
// Make sure the DSV is in writeable state
draw_ds->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
D3D12_RECT rect = {config.drawarea.left, config.drawarea.top, config.drawarea.left + config.drawarea.width(), config.drawarea.top + config.drawarea.height()};
GetCommandList()->ClearDepthStencilView(draw_ds->GetWriteDescriptor(), D3D12_CLEAR_FLAG_STENCIL, 0.0f, 1, 1, &rect);
}
// Begin render pass if new target or out of the area.
if (!m_in_render_pass)
{
@@ -4042,14 +4057,18 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
// Denormalize clear color for hw colclip.
clear_color *= GSVector4::cxpr(255.0f / 65535.0f, 255.0f / 65535.0f, 255.0f / 65535.0f, 1.0f);
}
const bool stencil_DATE = config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne;
BeginRenderPass(GetLoadOpForTexture(draw_rt),
draw_rt ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
GetLoadOpForTexture(draw_ds),
draw_ds ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
stencil_DATE ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE :
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
stencil_DATE ? (feedback ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE :
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD) :
stencil_DATE ? (need_barrier ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE :
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD) :
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
clear_color, draw_ds ? draw_ds->GetClearDepth() : 0.0f, 1);
}

View File

@@ -407,7 +407,7 @@ public:
void Destroy() override;
bool UpdateWindow() override;
void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
void ResizeWindow(u32 new_window_width, u32 new_window_height, float new_window_scale) override;
bool SupportsExclusiveFullscreen() const override;
void DestroySurface() override;
std::string GetDriverInfo() const override;

View File

@@ -738,7 +738,7 @@ void GSTexture12::TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RE
{D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE,
{{m_resource.get(), 1, m_resource_state, D3D12_RESOURCE_STATE_DEPTH_WRITE}}},
};
GSDevice12::GetInstance()->GetCommandList()->ResourceBarrier(m_resource_state == D3D12_RESOURCE_STATE_DEPTH_WRITE ? 1 : 2, barriers);
cmdlist->ResourceBarrier(m_resource_state == D3D12_RESOURCE_STATE_DEPTH_WRITE ? 1 : 2, barriers);
}
else if (m_resource_state == (D3D12_RESOURCE_STATE_DEPTH_READ | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE))
{
@@ -749,7 +749,7 @@ void GSTexture12::TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RE
{D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE,
{{m_resource.get(), 1, D3D12_RESOURCE_STATE_DEPTH_WRITE, state}}},
};
GSDevice12::GetInstance()->GetCommandList()->ResourceBarrier(state == D3D12_RESOURCE_STATE_DEPTH_WRITE ? 1 : 2, barriers);
cmdlist->ResourceBarrier(state == D3D12_RESOURCE_STATE_DEPTH_WRITE ? 1 : 2, barriers);
}
else
{

View File

@@ -3056,8 +3056,10 @@ void GSRendererHW::Draw()
const int second_u = (PRIM->FST ? v[i + 1].U : static_cast<int>(v[i + 1].ST.S / v[i + 1].RGBAQ.Q)) >> 4;
const int vector_width = std::abs(v[i + 1].XYZ.X - v[i].XYZ.X) / 16;
const int tex_width = std::abs(second_u - first_u);
const int first_vector = (static_cast<int>(v[i].XYZ.X + 8) - static_cast<int>(m_context->XYOFFSET.OFX)) / 16;
// & 7 just a quicker way of doing % 8
if ((vector_width & 7) != 0 || (tex_width & 7) != 0 || tex_width != vector_width)
// If the first vector is the same position as the first_u, then it's not shuffling, it's just copying.
if ((vector_width & 7) != 0 || (tex_width & 7) != 0 || tex_width != vector_width || first_vector == first_u)
{
shuffle_channel_reads = false;
break;
@@ -3194,6 +3196,7 @@ void GSRendererHW::Draw()
float target_scale = GetTextureScaleFactor();
bool scaled_copy = false;
int scale_draw = IsScalingDraw(src, m_primitive_covers_without_gaps != NoGapsType::GapsFound);
if (GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off)
{
if (target_scale > 1.0f && scale_draw > 0)
@@ -3202,9 +3205,15 @@ void GSRendererHW::Draw()
// 2 == Upscale, so likely putting it over the top of the render target.
if (scale_draw == 1)
{
if (!PRIM->ABE || GSConfig.UserHacks_NativeScaling < GSNativeScaling::NormalUpscaled)
target_scale = 1.0f;
m_downscale_source = src->m_from_target ? src->m_from_target->GetScale() > 1.0f : false;
const bool highlights_only = m_cached_ctx.TEST.ATE || (PRIM->ABE && m_context->ALPHA.C == 2 && m_context->ALPHA.FIX == 255);
// If it's alpha tested/stenciling for the bloom, we don't want to using the Upscaled versions. Also if the source is already native scale, may as well keep it so.
// Overlap check is for games such as Tomb Raider, where it recursively downsamples.
// Also make sure this isn't a blend, just draw (possibly with modulation).
if (GSConfig.UserHacks_NativeScaling < GSNativeScaling::NormalUpscaled || highlights_only || !PRIM->ABE || (src->m_from_target && src->m_from_target->Overlaps(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, m_r)))
{
target_scale = 1.0f;
}
}
else
m_downscale_source = ((GSConfig.UserHacks_NativeScaling != GSNativeScaling::Aggressive && GSConfig.UserHacks_NativeScaling != GSNativeScaling::AggressiveUpscaled) || !src->m_from_target) ? false : src->m_from_target->GetScale() > 1.0f; // Bad for GTA + Full Spectrum Warrior, good for Sacred Blaze + Parappa.
@@ -3232,7 +3241,7 @@ void GSRendererHW::Draw()
// This upscaling hack is for games which construct P8 textures by drawing a bunch of small sprites in C32,
// then reinterpreting it as P8. We need to keep the off-screen intermediate textures at native resolution,
// but not propagate that through to the normal render targets. Test Case: Crash Wrath of Cortex.
if (no_ds && src && !m_channel_shuffle && src->m_from_target && (GSConfig.UserHacks_NativePaletteDraw || (src->m_target_direct && src->m_from_target->m_downscaled && scale_draw <= 1)) &&
if (no_ds && src && !m_channel_shuffle && src->m_from_target && (GSConfig.UserHacks_NativePaletteDraw || (src->m_target_direct && src->m_from_target->m_downscaled && scale_draw <= 1)) &&
src->m_scale == 1.0f && (src->m_TEX0.PSM == PSMT8 || src->m_TEX0.TBP0 == m_cached_ctx.FRAME.Block()))
{
GL_CACHE("HW: Using native resolution for target based on texture source");
@@ -3525,7 +3534,7 @@ void GSRendererHW::Draw()
// Preserve downscaled target when copying directly from a downscaled target, or it's a normal draw using a downscaled target. Clears that are drawing to the target can also preserve size.
// Of course if this size is different (in width) or this is a shuffle happening, this will be bypassed.
const bool preserve_downscale_draw = (GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && (std::abs(scale_draw) == 1 || (scale_draw == 0 && src && src->m_from_target && src->m_from_target->m_downscaled))) || is_possible_mem_clear == ClearType::ClearWithDraw;
const bool preserve_downscale_draw = (GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && ((std::abs(scale_draw) == 1 && !scaled_copy) || (scale_draw == 0 && src && src->m_from_target && src->m_from_target->m_downscaled))) || is_possible_mem_clear == ClearType::ClearWithDraw;
rt = g_texture_cache->LookupTarget(FRAME_TEX0, t_size, ((src && src->m_scale != 1) && (GSConfig.UserHacks_NativeScaling == GSNativeScaling::Normal || GSConfig.UserHacks_NativeScaling == GSNativeScaling::NormalUpscaled) && !possible_shuffle) ? GetTextureScaleFactor() : target_scale, GSTextureCache::RenderTarget, true,
fm, false, force_preload, preserve_rt_rgb, preserve_rt_alpha, lookup_rect, possible_shuffle, is_possible_mem_clear && FRAME_TEX0.TBP0 != m_cached_ctx.ZBUF.Block(),
@@ -5138,6 +5147,7 @@ void GSRendererHW::EmulateZbuffer(const GSTextureCache::Target* ds)
m_conf.cb_vs.max_depth = GSVector2i(0xFFFFFFFF);
//ps_cb.MaxDepth = GSVector4(0.0f, 0.0f, 0.0f, 1.0f);
m_conf.ps.zclamp = 0;
m_conf.ps.zfloor = !m_cached_ctx.ZBUF.ZMSK;
if (clamp_z)
{
@@ -7024,7 +7034,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
// When using native HPO, the top-left column/row of pixels are often not drawn. Clamp these away to avoid sampling black,
// causing bleeding into the edges of the downsampled texture.
const u32 downsample_factor = static_cast<u32>(src_target->GetScale());
const GSVector2i clamp_min = (GSConfig.UserHacks_HalfPixelOffset < GSHalfPixelOffset::Native) ?
const GSVector2i clamp_min = (GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native) ?
GSVector2i(0, 0) :
GSVector2i(downsample_factor, downsample_factor);
GSVector4i copy_rect = tmm.coverage;
@@ -9222,7 +9232,7 @@ int GSRendererHW::IsScalingDraw(GSTextureCache::Source* src, bool no_gaps)
const bool no_resize = (std::abs(draw_size.x - tex_size.x) <= 1 && std::abs(draw_size.y - tex_size.y) <= 1);
const bool can_maintain = no_resize || (!is_target_src && m_index.tail == 2);
if (!src || ((!is_target_src || src->m_from_target->m_downscaled) && can_maintain))
if (!src || ((!is_target_src || (src->m_from_target->m_downscaled || GSConfig.UserHacks_NativeScaling > GSNativeScaling::Aggressive)) && can_maintain))
return -1;
const GSDrawingContext& next_ctx = m_env.CTXT[m_env.PRIM.CTXT];
@@ -9237,7 +9247,7 @@ int GSRendererHW::IsScalingDraw(GSTextureCache::Source* src, bool no_gaps)
// Only allow non-bilineared downscales if it's most of the target (misdetections of shadows in Naruto, Transformers etc), otherwise it's fine.
const GSVector4i src_valid = src->m_from_target ? src->m_from_target->m_valid : src->m_valid_rect;
const GSVector2i tex_size_half = GSVector2i((src->GetRegion().HasX() ? src->GetRegionSize().x : src_valid.width()) / 2, (src->GetRegion().HasY() ? src->GetRegionSize().y : src_valid.height()) / 2);
const bool possible_downscale = m_context->TEX1.MMIN == 1 || !src->m_from_target || src->m_from_target->m_downscaled || tex_size.x >= tex_size_half.x || tex_size.y >= tex_size_half.y;
const bool possible_downscale = m_context->TEX1.MMIN == 1 || !src->m_from_target || src->m_from_target->m_downscaled || GSConfig.UserHacks_NativeScaling > GSNativeScaling::Aggressive || tex_size.x >= tex_size_half.x || tex_size.y >= tex_size_half.y;
if (is_downscale && (draw_size.x >= PCRTCDisplays.GetResolution().x || !possible_downscale))
return 0;

View File

@@ -2756,7 +2756,22 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
if (!tex)
return nullptr;
g_gs_device->StretchRect(dst->m_texture, sRect, tex, dRect, (type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY, dst->m_scale < scale);
if (scale == 1.0f)
{
// When using native HPO, the top-left column/row of pixels are often not drawn. Clamp these away to avoid sampling black,
// causing bleeding into the edges of the downsampled texture.
const u32 downsample_factor = static_cast<u32>(dst->GetScale());
const GSVector2i clamp_min = (GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native) ?
GSVector2i(0, 0) :
GSVector2i(downsample_factor, downsample_factor);
const GSVector4 dRect = GSVector4(dst->GetUnscaledRect());
g_gs_device->FilteredDownsampleTexture(dst->m_texture, tex, downsample_factor, clamp_min, dRect);
}
else
g_gs_device->StretchRect(dst->m_texture, sRect, tex, dRect, (type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY, dst->m_scale < scale);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
m_target_memory_usage = (m_target_memory_usage - dst->m_texture->GetMemUsage()) + tex->GetMemUsage();

View File

@@ -12,7 +12,7 @@
#include "Config.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "GS/GSExtra.h"
#include "GS/GSLocalMemory.h"
#include "GS/Renderers/HW/GSTextureReplacements.h"

View File

@@ -385,7 +385,7 @@ public:
bool SupportsExclusiveFullscreen() const override;
std::string GetDriverInfo() const override;
void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
void ResizeWindow(u32 new_window_width, u32 new_window_height, float new_window_scale) override;
void UpdateTexture(id<MTLTexture> texture, u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_stride);

View File

@@ -1267,11 +1267,11 @@ std::string GSDeviceMTL::GetDriverInfo() const
return desc;
}}
void GSDeviceMTL::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
void GSDeviceMTL::ResizeWindow(u32 new_window_width, u32 new_window_height, float new_window_scale)
{
m_window_info.surface_scale = new_window_scale;
if (!m_layer ||
(m_window_info.surface_width == static_cast<u32>(new_window_width) && m_window_info.surface_height == static_cast<u32>(new_window_height)))
(m_window_info.surface_width == new_window_width && m_window_info.surface_height == new_window_height))
{
return;
}
@@ -1878,6 +1878,7 @@ void GSDeviceMTL::MRESetHWPipelineState(GSHWDrawConfig::VSSelector vssel, GSHWDr
setFnConstantI(m_fn_constants, pssel.dither, GSMTLConstantIndex_PS_DITHER);
setFnConstantI(m_fn_constants, pssel.dither_adjust, GSMTLConstantIndex_PS_DITHER_ADJUST);
setFnConstantB(m_fn_constants, pssel.zclamp, GSMTLConstantIndex_PS_ZCLAMP);
setFnConstantB(m_fn_constants, pssel.zfloor, GSMTLConstantIndex_PS_ZFLOOR);
setFnConstantB(m_fn_constants, pssel.tcoffsethack, GSMTLConstantIndex_PS_TCOFFSETHACK);
setFnConstantB(m_fn_constants, pssel.urban_chaos_hle, GSMTLConstantIndex_PS_URBAN_CHAOS_HLE);
setFnConstantB(m_fn_constants, pssel.tales_of_abyss_hle, GSMTLConstantIndex_PS_TALES_OF_ABYSS_HLE);

Some files were not shown because too many files have changed in this diff Show More