Compare commits

...

39 Commits

Author SHA1 Message Date
chaoticgd
e3063d6cd6 VMManager: Fix LoadStateFromSlot error messages 2025-11-28 13:58:51 -05:00
chaoticgd
8d30e8cee8 FullscreenUI: Fix save state loading 2025-11-28 10:50:41 -05:00
chaoticgd
ff2f1998ad Debugger: Pick out some new icons 2025-11-27 18:59:25 -05:00
TheTechnician27
7942ee438a GameListWidget: Fix header width bug 2025-11-27 17:18:29 +01:00
TJnotJT
f322dfb1d4 GS/SW: Use non-saturating ARM instructions for color gradient setup.
This is more efficient on ARM, though the equivalent instructions are not currently used in the x64 JIT and C++ versions of GSVector.

Co-authored-by: TellowKrinkle
2025-11-26 20:25:10 +01:00
TJnotJT
a7f5ddfe0d GS/SW: Mask color gradients to prevent incorrect clamping.
Co-authored-by: TellowKrinkle
2025-11-26 20:25:10 +01:00
PCSX2 Bot
0cdfb75fd0 [ci skip] Qt: Update Base Translation. 2025-11-25 19:03:17 -05:00
TJnotJT
35624a12d9 GS/HW: Refactor StretchRect() to have single entry to renderer/reduce duplication. 2025-11-25 18:38:52 +01:00
JordanTheToaster
9b147cc57c GameDB: FFX-2 FMV FIxes 2025-11-25 17:50:06 +01:00
JordanTheToaster
10e13cfece GS/HW: Test double buffer offset from target base address on lookup 2025-11-25 17:50:06 +01:00
lightningterror
7b2eb7bc47 GS/DX11: Do Stencil date_one in a single pass if there's a barrier.
We currently have a barrier so let's do date_one in a single pass, plus this avoids any issues with copies and stencil issues.
On dx copies are slower so we can only use the optimization if we have barriers already present.
2025-11-25 16:58:27 +01:00
PCSX2 Bot
ab1cb802d8 [ci skip] Qt: Update Base Translation. 2025-11-25 01:01:42 +01:00
TheLastRar
366cdd8df0 Qt: Remove incorrect check in shouldMouseLock() 2025-11-24 18:34:43 -05:00
TheLastRar
bc3cfb1373 Qt: Improve mouse lock DPI handling 2025-11-24 18:34:43 -05:00
SternXD
db6792af2e Achievements/Qt: Show success feedback on RetroAchievements login 2025-11-24 18:19:08 -05:00
SternXD
a1485fb7cd FullscreenUI: Allow pause menu to wrap around 2025-11-24 18:14:44 -05:00
Ty
c72c309218 InputRecording: Use u32 for frames since that's what the core uses (warning fixes) 2025-11-24 18:07:25 -05:00
Ty
58899a9ed3 MTVU: uptr to u32 implicit cast fix 2025-11-24 18:07:25 -05:00
Ty
0823c70460 VTLB: uptr to u32 implicit cast warning fix 2025-11-24 18:07:25 -05:00
Ty
e5c29a3975 BiosTools: s64 to to u32 implicit cast warning fix 2025-11-24 18:07:25 -05:00
Ty
1174ae99c9 GS SW: size_t to int implicit cast warning fixes 2025-11-24 18:07:25 -05:00
Ty
e2d3680038 GSPerfMon: Use int rather than u64 for a frame count to match the rest of the core 2025-11-24 18:07:25 -05:00
Ty
8630893cb1 GIF: implicit cast to u32 warning fix 2025-11-24 18:07:25 -05:00
Ty
53598b970d IopBios: Use typedefs and explicit casting 2025-11-24 18:07:25 -05:00
Ty
89de00ac36 DEV9: Implicit size_t to int conversion warning fix 2025-11-24 18:07:25 -05:00
Ty
d5ddf07958 Counters: u32 implicit cast warning fix 2025-11-24 18:07:25 -05:00
PCSX2 Bot
30dcf4a14a [ci skip] PAD: Update to latest controller database. 2025-11-24 19:11:46 +01:00
JordanTheToaster
a87710e4bc GameDB: Simple 91/ All Star Fighters fixes 2025-11-24 19:11:33 +01:00
JordanTheToaster
a12f87fec2 Github: Use pip install yamllint 2025-11-24 16:57:40 +01:00
JordanTheToaster
8ba9bba094 ImGuiOverlays: Various text changes 2025-11-24 16:57:40 +01:00
JordanTheToaster
1363571c14 GameDB: Fixes of various kinds 2025-11-24 16:57:40 +01:00
chaoticgd
80de666fcc Debugger: Fix crash in getEEThreads 2025-11-24 16:52:15 +01:00
chaoticgd
ff0a2f84fa Config: Initialize AchievementsOptions bitset to zero 2025-11-24 16:12:27 +01:00
JordanTheToaster
0676f145bc Deps: Add additional fixes for Mac OS 11 compat
cheeseus
2025-11-24 16:11:40 +01:00
JordanTheToaster
e19ae2bf60 Deps: Update Qt to 6.10.1 2025-11-24 16:11:40 +01:00
lightningterror
7782d930d5 GS/HW: Always swap DATE with DATE_BARRIER if we have barriers on when alpha write is masked.
This is always enabled on vk/gl but not on dx11/12 as copies are
slow so we can selectively enable it like now.
2025-11-24 16:09:46 +01:00
lightningterror
d1a53fe29b GS/DX11/GL: Move vertices for stencil date in SetupDATE.
The vertices are used only in SetupDATE so let's move them there.
VK/DX12 already do this.
2025-11-24 16:09:46 +01:00
lightningterror
c484cf286c GS/DX11: Don't unbind shader resource if depth stencil view is read only.
We don't need to unbind conflicting srv with dsv if the dsv itself is read only, it is used for depth testing and both can be bind at the same time.

Avoids re binding srv using a read only dsv.
2025-11-24 16:08:50 +01:00
PCSX2 Bot
f8882c4da6 [ci skip] Qt: Update Base Translation. 2025-11-22 06:31:36 +01:00
75 changed files with 2137 additions and 1849 deletions

View File

@@ -23,7 +23,7 @@ jobs:
- name: Install Packages
run: |
npm install -g ajv-cli prettier
sudo apt-get -y install yamllint
pip install yamllint
- name: Validate YAML
run: |

View File

@@ -21,7 +21,7 @@ LIBJPEGTURBO=3.1.2
LIBPNG=1.6.50
LIBWEBP=1.6.0
SDL=SDL3-3.2.26
QT=6.10.0
QT=6.10.1
QTAPNG=1.3.0
LZ4=1.10.0
ZSTD=1.5.7
@@ -48,12 +48,12 @@ dad488474a51a0b01d547cd2834893d6299328d2e30f479a3564088b5476bae2 $SDL.tar.gz
687ddc0c7cb128a3ea58e159b5129252537c27ede0c32a93f11f03127f0c0165 libpng-$LIBPNG-apng.patch.gz
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
ead4623bcb54a32257c5b3e3a5aec6d16ec96f4cda58d2e003f5a0c16f72046d qtbase-everywhere-src-$QT.tar.xz
64450a52507c540de53616ed5e516df0e0905a99d3035ddfaa690f2b3f7c0cea qtimageformats-everywhere-src-$QT.tar.xz
5ed2c0e04d5e73ff75c2a2ed92db5dc1788ba70f704fc2b71bc21644beda2533 qtsvg-everywhere-src-$QT.tar.xz
d86d5098cf3e3e599f37e18df477e65908fc8f036e10ea731b3469ec4fdbd02a qttools-everywhere-src-$QT.tar.xz
326e8253cfd0cb5745238117f297da80e30ce8f4c1db81990497bd388b026cde qttranslations-everywhere-src-$QT.tar.xz
603f2b0a259b24bd0fb14f880d7761b1d248118a42a6870cdbe8fdda4173761f qtwayland-everywhere-src-$QT.tar.xz
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
49bf6db800227a6b2c971f4c5d03dd1e81297e7ffb296ce4a96437304f27cb13 qtwayland-everywhere-src-$QT.tar.xz
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
a8e4a25e5c2686fd36981e527ed05e451fcfc226bddf350f4e76181371190937 shaderc-$SHADERC.tar.gz
9427deccbdf4bde6a269938df38c6bd75247493786a310d8d733a2c82065ef47 shaderc-glslang-$SHADERC_GLSLANG.tar.gz

View File

@@ -48,7 +48,7 @@ LIBJPEGTURBO=3.1.2
LIBWEBP=1.6.0
FFMPEG=8.0
MOLTENVK=1.2.9
QT=6.10.0
QT=6.10.1
QTAPNG=1.3.0
KDDOCKWIDGETS=2.4.0
PLUTOVG=1.3.1
@@ -89,11 +89,11 @@ e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWE
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
ead4623bcb54a32257c5b3e3a5aec6d16ec96f4cda58d2e003f5a0c16f72046d qtbase-everywhere-src-$QT.tar.xz
64450a52507c540de53616ed5e516df0e0905a99d3035ddfaa690f2b3f7c0cea qtimageformats-everywhere-src-$QT.tar.xz
5ed2c0e04d5e73ff75c2a2ed92db5dc1788ba70f704fc2b71bc21644beda2533 qtsvg-everywhere-src-$QT.tar.xz
d86d5098cf3e3e599f37e18df477e65908fc8f036e10ea731b3469ec4fdbd02a qttools-everywhere-src-$QT.tar.xz
326e8253cfd0cb5745238117f297da80e30ce8f4c1db81990497bd388b026cde qttranslations-everywhere-src-$QT.tar.xz
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
a8e4a25e5c2686fd36981e527ed05e451fcfc226bddf350f4e76181371190937 shaderc-$SHADERC.tar.gz
9427deccbdf4bde6a269938df38c6bd75247493786a310d8d733a2c82065ef47 shaderc-glslang-$SHADERC_GLSLANG.tar.gz

View File

@@ -30,7 +30,7 @@ LIBJPEGTURBO=3.1.2
LIBWEBP=1.6.0
FFMPEG=8.0
MOLTENVK=1.2.9
QT=6.10.0
QT=6.10.1
QTAPNG=1.3.0
KDDOCKWIDGETS=2.4.0
PLUTOVG=1.3.1
@@ -70,11 +70,11 @@ e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWE
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
ead4623bcb54a32257c5b3e3a5aec6d16ec96f4cda58d2e003f5a0c16f72046d qtbase-everywhere-src-$QT.tar.xz
64450a52507c540de53616ed5e516df0e0905a99d3035ddfaa690f2b3f7c0cea qtimageformats-everywhere-src-$QT.tar.xz
5ed2c0e04d5e73ff75c2a2ed92db5dc1788ba70f704fc2b71bc21644beda2533 qtsvg-everywhere-src-$QT.tar.xz
d86d5098cf3e3e599f37e18df477e65908fc8f036e10ea731b3469ec4fdbd02a qttools-everywhere-src-$QT.tar.xz
326e8253cfd0cb5745238117f297da80e30ce8f4c1db81990497bd388b026cde qttranslations-everywhere-src-$QT.tar.xz
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
a8e4a25e5c2686fd36981e527ed05e451fcfc226bddf350f4e76181371190937 shaderc-$SHADERC.tar.gz
9427deccbdf4bde6a269938df38c6bd75247493786a310d8d733a2c82065ef47 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
@@ -237,9 +237,6 @@ cd "qtbase-everywhere-src-$QT"
# Patch Qt to support macOS 11
patch -p1 < "$SCRIPTDIR/qt-macos11compat.patch"
# Patch Qt to fix a bug with message boxes on Tahoe
patch -p1 < "$SCRIPTDIR/clickbutton.patch"
# since we don't have a direct reference to QtSvg, it doesn't deployed directly from the main binary
# (only indirectly from iconengines), and the libqsvg.dylib imageformat plugin does not get deployed.
# We could run macdeployqt twice, but that's even more janky than patching it.

View File

@@ -1,16 +0,0 @@
--- a/src/plugins/platforms/cocoa/qcocoamessagedialog.mm
+++ b/src/plugins/platforms/cocoa/qcocoamessagedialog.mm
@@ -88,6 +88,11 @@ bool QCocoaMessageDialog::show(Qt::WindowModality windowModality)
qCWarning(lcQpaDialogs, "Cannot run window modal dialog without parent window");
return false;
}
+
+ // Tahoe has issues with window-modal alert buttons not responding to mouse
+ if (windowModality == Qt::WindowModal
+ && QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSTahoe)
+ return false;
// And without options we don't know what to show
if (!options())
# Source https://codereview.qt-project.org/c/qt/qtbase/+/689796

View File

@@ -1,5 +1,4 @@
diff --git a/.cmake.conf b/.cmake.conf
index 9a21ff42a74..d6707ba7dff 100644
--- a/.cmake.conf
+++ b/.cmake.conf
@@ -51,7 +51,7 @@ set(QT_MAX_NEW_POLICY_CMAKE_VERSION_QT_APPLE "3.21")
@@ -12,7 +11,6 @@ index 9a21ff42a74..d6707ba7dff 100644
set(QT_SUPPORTED_MIN_IOS_SDK_VERSION "17")
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d3a14fc67eb..1553b956fe3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,6 +12,10 @@ cmake_minimum_required(VERSION 3.16)
@@ -27,7 +25,6 @@ index d3a14fc67eb..1553b956fe3 100644
qt_internal_check_if_path_has_symlinks("${CMAKE_BINARY_DIR}")
diff --git a/src/corelib/global/qsysinfo.cpp b/src/corelib/global/qsysinfo.cpp
index ae762c0cc6d..9171a5736b4 100644
--- a/src/corelib/global/qsysinfo.cpp
+++ b/src/corelib/global/qsysinfo.cpp
@@ -1027,7 +1027,7 @@ QByteArray QSysInfo::machineUniqueId()
@@ -40,10 +37,9 @@ index ae762c0cc6d..9171a5736b4 100644
CFStringGetCString(stringRef, uuid, sizeof(uuid), kCFStringEncodingMacRoman);
return QByteArray(uuid);
diff --git a/src/corelib/kernel/qcore_mac.mm b/src/corelib/kernel/qcore_mac.mm
index 9f27dbe694e..c023a48cad3 100644
--- a/src/corelib/kernel/qcore_mac.mm
+++ b/src/corelib/kernel/qcore_mac.mm
@@ -372,7 +372,7 @@ bool qt_apple_runningWithLiquidGlass()
@@ -367,7 +367,7 @@ bool qt_apple_runningWithLiquidGlass()
return config;
#endif
@@ -52,8 +48,50 @@ index 9f27dbe694e..c023a48cad3 100644
if (!nvram) {
qWarning("Failed to locate NVRAM entry in IO registry");
return {};
diff --git a/src/gui/platform/darwin/qappleiconengine.mm b/src/gui/platform/darwin/qappleiconengine.mm
--- a/src/gui/platform/darwin/qappleiconengine.mm
+++ b/src/gui/platform/darwin/qappleiconengine.mm
@@ -366,12 +366,16 @@
weight:NSFontWeightRegular
scale:NSImageSymbolScaleLarge];
+ auto *primaryColor = [NSColor colorWithSRGBRed:color.redF()
+ green:color.greenF()
+ blue:color.blueF()
+ alpha:color.alphaF()];
+
+ if (@available(macOS 13, *)) {
+
// Apply tint color first, which switches the configuration to palette mode
config = [config configurationByApplyingConfiguration:
- [NSImageSymbolConfiguration configurationWithPaletteColors:@[
- [NSColor colorWithSRGBRed:color.redF() green:color.greenF()
- blue:color.blueF() alpha:color.alphaF()]
- ]]];
+ [NSImageSymbolConfiguration configurationWithPaletteColors:@[primaryColor]]];
// Then switch back to monochrome, as palette mode gives a different look
// than monochrome, even with a single color.
@@ -379,6 +383,18 @@
[NSImageSymbolConfiguration configurationPreferringMonochrome]];
return [image imageWithSymbolConfiguration:config];
+
+ } else {
+ NSImage *configuredImage = [image imageWithSymbolConfiguration:config];
+ return [NSImage imageWithSize:configuredImage.size flipped:NO
+ drawingHandler:^BOOL(NSRect) {
+ [primaryColor set];
+ NSRect imageRect = {NSZeroPoint, configuredImage.size};
+ [configuredImage drawInRect:imageRect];
+ NSRectFillUsingOperation(imageRect, NSCompositingOperationSourceIn);
+ return YES;
+ }];
+ }
}
#elif defined(QT_PLATFORM_UIKIT)
auto *configuredImage(const UIImage *image, const QColor &color)
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 6b33d94d58c..867389e4c93 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -323,6 +323,8 @@ a normal (not maximized or full screen) top-level window.

View File

@@ -48,7 +48,7 @@ set LIBJPEGTURBO=3.1.2
set LIBPNG=1650
set LIBPNGLONG=1.6.50
set SDL=SDL3-3.2.26
set QT=6.10.0
set QT=6.10.1
set QTMINOR=6.10
set QTAPNG=1.3.0
set LZ4=1.10.0
@@ -72,11 +72,11 @@ call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net
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 "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" d3b5379edcace266273d789249b6d68ae9495ec1b0b562ba6d039034cd315d8e || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" ac2fe34a9f1c1451b6785474e9b1b64eb59edef6553be3d630240f16a730456d || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" c12f8bfb617e4a03da104be36f6966ba7f64bee331f0095da1a649a1149796d2 || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" c6d0f0a512304ad87b20f5ff604442dd8d55769d659576ecfe5462fcd7bb9b7d || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" e6cc1ebf62cf37d81f3b86990086108518037bb383e75da327f297cc4fc1ae36 || 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
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" db8e49ed50912c3c064a4f9ada7791c09eccec5a8d53463a19608eaab17679f0 || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 868eb651e395d48ade5932ef2c386e606e054eb5888ebe5284fbd8cb63ed935a || goto error
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error

View File

@@ -46,7 +46,7 @@ set LIBJPEGTURBO=3.1.2
set LIBPNG=1650
set SDL=SDL3-3.2.26
set LIBPNGLONG=1.6.50
set QT=6.10.0
set QT=6.10.1
set QTMINOR=6.10
set QTAPNG=1.3.0
set LZ4=1.10.0
@@ -70,11 +70,11 @@ call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net
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 "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" d3b5379edcace266273d789249b6d68ae9495ec1b0b562ba6d039034cd315d8e || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" ac2fe34a9f1c1451b6785474e9b1b64eb59edef6553be3d630240f16a730456d || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" c12f8bfb617e4a03da104be36f6966ba7f64bee331f0095da1a649a1149796d2 || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" c6d0f0a512304ad87b20f5ff604442dd8d55769d659576ecfe5462fcd7bb9b7d || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" e6cc1ebf62cf37d81f3b86990086108518037bb383e75da327f297cc4fc1ae36 || 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
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" db8e49ed50912c3c064a4f9ada7791c09eccec5a8d53463a19608eaab17679f0 || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 868eb651e395d48ade5932ef2c386e606e054eb5888ebe5284fbd8cb63ed935a || goto error
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error

File diff suppressed because it is too large Load Diff

View File

@@ -175,7 +175,6 @@
030000001a1c00000001000000000000,Datel Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000451300000830000000000000,Defender Game Racer X7,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,
03000000791d00000103000000000000,Dual Box Wii,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000c0160000e105000000000000,Dual Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
030000004f040000070f000000000000,Dual Power,a:b8,b:b9,back:b4,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,leftshoulder:b13,leftstick:b6,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b12,rightstick:b7,righttrigger:b15,start:b5,x:b10,y:b11,platform:Windows,
030000004f04000012b3000000000000,Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
030000004f04000020b3000000000000,Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
@@ -839,6 +838,7 @@
03000000172700004431000000000000,Xiaomi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000172700003350000000000000,Xiaomi XMGP01YM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000bc2000005060000000000000,Xiaomi XMGP01YM,+lefty:+a2,+righty:+a5,-lefty:-a1,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,
03000000c0160000e105000000000000,XinMo Dual Arcade,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000007d0400000340000000000000,Xterminator Digital Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:-a4,lefttrigger:+a4,leftx:a0,lefty:a1,paddle1:b7,paddle2:b6,rightshoulder:b5,rightstick:b9,righttrigger:b2,rightx:a3,righty:a5,start:b8,x:b3,y:b4,platform:Windows,
030000002c3600000100000000000000,Yawman Arrow,+rightx:h0.2,+righty:h0.4,-rightx:h0.8,-righty:h0.1,a:b4,b:b5,back:b6,dpdown:b15,dpleft:b14,dpright:b16,dpup:b13,leftshoulder:b10,leftstick:b0,lefttrigger:-a4,leftx:a0,lefty:a1,paddle1:b11,paddle2:b12,rightshoulder:b8,rightstick:b9,righttrigger:+a4,start:b3,x:b1,y:b2,platform:Windows,
@@ -1119,6 +1119,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005f140000c501000000020000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,
03000000632500002605000000010000,Uberwith Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000c0160000e105000000040000,Ultimate Atari Fight Stick,a:b2,b:b4,back:b18,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,rightshoulder:b8,righttrigger:b10,start:b16,x:b0,y:b6,platform:Mac OS X,
03000000151900005678000010010000,Uniplay U6,a:b3,b:b6,back:b25,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b17,leftstick:b31,lefttrigger:b21,leftx:a1,lefty:a3,rightshoulder:b19,rightstick:b33,righttrigger:b23,rightx:a4,righty:a5,start:b27,x:b11,y:b13,platform:Mac OS X,
030000006f0e00000302000025040000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
030000006f0e00000702000003060000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
@@ -1774,6 +1775,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
06000000f51000000870000003010000,Turtle Beach Recon,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000100800000100000010010000,Twin PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000c0160000e105000010010000,Ultimate Atari Fight Stick,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,platform:Linux,
03000000151900005678000010010000,Uniplay U6,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000790000000600000007010000,USB gamepad,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:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,

View File

@@ -208,7 +208,7 @@
</action>
<action name="actionAnalyse">
<property name="icon">
<iconset theme="magnifier-line"/>
<iconset theme="search-line"/>
</property>
<property name="text">
<string>Analyze</string>

View File

@@ -144,12 +144,12 @@ void DockMenuBar::onLockStateChanged(bool layout_locked)
if (layout_locked)
{
m_layout_locked_toggle->setText(tr("Layout Locked"));
m_layout_locked_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("padlock-lock")));
m_layout_locked_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("lock-fill")));
}
else
{
m_layout_locked_toggle->setText(tr("Layout Unlocked"));
m_layout_locked_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("padlock-unlock")));
m_layout_locked_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("lock-unlock-fill")));
}
m_ignore_lock_state_changed = false;

View File

@@ -13,7 +13,7 @@ ThreadModel::ThreadModel(DebugInterface& cpu, QObject* parent)
int ThreadModel::rowCount(const QModelIndex&) const
{
return m_cpu.GetThreadList().size();
return static_cast<int>(m_threads.size());
}
int ThreadModel::columnCount(const QModelIndex&) const

View File

@@ -256,8 +256,6 @@ void GameListWidget::initialize()
m_table_view = new QTableView(m_ui.stack);
m_table_view->setModel(m_sort_model);
m_table_view->setSortingEnabled(true);
m_table_view->horizontalHeader()->setSectionsMovable(true);
m_table_view->setSelectionMode(QAbstractItemView::SingleSelection);
m_table_view->setSelectionBehavior(QAbstractItemView::SelectRows);
m_table_view->setContextMenuPolicy(Qt::CustomContextMenu);
@@ -265,8 +263,9 @@ void GameListWidget::initialize()
m_table_view->setMouseTracking(true);
m_table_view->setShowGrid(false);
m_table_view->setCurrentIndex(QModelIndex());
m_table_view->horizontalHeader()->setHighlightSections(false);
m_table_view->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
m_table_view->horizontalHeader()->setHighlightSections(false);
m_table_view->horizontalHeader()->setSectionsMovable(true);
m_table_view->verticalHeader()->hide();
m_table_view->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
@@ -738,8 +737,8 @@ void GameListWidget::resizeTableViewColumnsToFit()
QtUtils::ResizeColumnsForTableView(m_table_view, {
DEFAULT_COLUMN_WIDTHS[GameListModel::Column_Type],
DEFAULT_COLUMN_WIDTHS[GameListModel::Column_Serial],
DEFAULT_COLUMN_WIDTHS[GameListModel::Column_Title],
DEFAULT_COLUMN_WIDTHS[GameListModel::Column_FileTitle],
DEFAULT_COLUMN_WIDTHS[GameListModel::Column_Type],
DEFAULT_COLUMN_WIDTHS[GameListModel::Column_CRC],
DEFAULT_COLUMN_WIDTHS[GameListModel::Column_TimePlayed],
DEFAULT_COLUMN_WIDTHS[GameListModel::Column_LastPlayed],

View File

@@ -1099,7 +1099,7 @@ bool MainWindow::shouldMouseLock() const
if (!Host::GetBoolSettingValue("EmuCore", "EnableMouseLock", false))
return false;
if (m_display_created == false || m_display_surface == nullptr && !isRenderingToMain())
if (m_display_created == false || m_display_surface == nullptr)
return false;
bool windowsHidden = (!g_debugger_window || g_debugger_window->isHidden()) &&
@@ -2570,11 +2570,21 @@ void MainWindow::checkMousePosition(int x, int y)
const QSize logicalSize = displayWindow->size();
const QPoint logicalPosition = displayWindow->position() + displayWindow->parent()->position();
// The offset to the origin of the current screen is in device-independent pixels while the origin itself is native!
// The logicalPosition is the sum of these two values, so we need to separate them and only scale the offset
const QScreen* screen = displayWindow->screen();
// If we fail to get the screen associated with the window, avoid mouse locking as it's probably in an unexpected position.
if (!screen)
return;
const QPoint screenPosition = screen->geometry().topLeft();
// physical frame rect
const qreal scale = displayWindow->devicePixelRatio();
const QRectF physicalBounds(
logicalPosition.x() * scale,
logicalPosition.y() * scale,
screenPosition.x() + (logicalPosition.x() - screenPosition.x()) * scale,
screenPosition.y() + (logicalPosition.y() - screenPosition.y()) * scale,
logicalSize.width() * scale,
logicalSize.height() * scale);

View File

@@ -855,7 +855,7 @@
</action>
<action name="actionDebugger">
<property name="icon">
<iconset theme="heart-circle-line"/>
<iconset theme="bug-line"/>
</property>
<property name="text">
<string>&amp;Open Debugger</string>

View File

@@ -318,7 +318,9 @@ void EmuThread::loadState(const QString& filename)
if (!VMManager::HasValidVM())
return;
VMManager::LoadState(filename.toUtf8().constData());
Error error;
if (!VMManager::LoadState(filename.toUtf8().constData(), &error))
Host::ReportErrorAsync(TRANSLATE_SV("QtHost", "Failed to Load State"), error.GetDescription());
}
void EmuThread::loadStateFromSlot(qint32 slot, bool load_backup)
@@ -332,7 +334,9 @@ void EmuThread::loadStateFromSlot(qint32 slot, bool load_backup)
if (!VMManager::HasValidVM())
return;
VMManager::LoadStateFromSlot(slot, load_backup);
Error error;
if (!VMManager::LoadStateFromSlot(slot, load_backup, &error))
Host::ReportErrorAsync(TRANSLATE_SV("QtHost", "Failed to Load State"), error.GetDescription());
}
void EmuThread::saveState(const QString& filename)

View File

@@ -127,7 +127,25 @@ void AchievementLoginDialog::processLoginResult(bool result, const QString& mess
}
}
done(0);
// Show success messagebox
const std::string username = Host::GetBaseStringSettingValue("Achievements", "Username");
QMessageBox::information(
this, tr("Login Successful"),
tr("Successfully logged in to RetroAchievements as %1.").arg(QString::fromStdString(username)));
m_ui.status->setText(tr("Successfully logged in as %1.").arg(QString::fromStdString(username)));
m_ui.status->setStyleSheet("color: green; font-weight: bold;");
disconnect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, &AchievementLoginDialog::loginClicked);
m_login->setVisible(false);
QPushButton* dismissButton = m_ui.buttonBox->addButton(tr("&Dismiss"), QDialogButtonBox::AcceptRole);
dismissButton->setDefault(true);
dismissButton->setFocus();
connect(dismissButton, &QPushButton::clicked, this, [this]() { done(0); });
enableUI(false);
}
void AchievementLoginDialog::connectUi()

View File

@@ -209,7 +209,7 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* settings_dialog
tr("Shows the game you are currently playing as part of your profile in Discord."));
dialog()->registerWidgetHelp(
m_ui.mouseLock, tr("Enable Mouse Lock"), tr("Unchecked"),
tr("Locks the mouse cursor to the windows when PCSX2 is in focus and all other windows are closed.<br><b>Unavailable on Linux Wayland.</b><br><b>Requires accessibility permissions on macOS.</b><br><b>Limited support for mixed-resolution with non-100% DPI configurations.</b>"));
tr("Locks the mouse cursor to the windows when PCSX2 is in focus and all other windows are closed.<br><b>Unavailable on Linux Wayland.</b><br><b>Requires accessibility permissions on macOS.</b>"));
dialog()->registerWidgetHelp(
m_ui.doubleClickTogglesFullscreen, tr("Double-Click Toggles Fullscreen"), tr("Checked"),
tr("Allows switching in and out of fullscreen mode by double-clicking the game window."));

View File

@@ -204,7 +204,7 @@ void SettingsWindow::setupUi(const GameList::Entry* game)
tr("<strong>Advanced Settings</strong><hr>These are advanced options to determine the configuration of the simulated "
"console.<br><br>Mouse over an option for additional information, and Shift+Wheel to scroll this panel."));
addWidget(m_debug_settings = new DebugSettingsWidget(this, m_ui.settingsContainer), tr("Debug"),
QStringLiteral("debugger-line"),
QStringLiteral("bug-line"),
tr("<strong>Debug Settings</strong><hr>These are options which can be used to log internal information about the application. "
"<strong>Do not modify unless you know what you are doing</strong>, it will cause significant slowdown, and can waste large "
"amounts of disk space."));

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24"><path d="M13 19.9C15.2822 19.4367 17 17.419 17 15V12C17 11.299 16.8564 10.6219 16.5846 10H7.41538C7.14358 10.6219 7 11.299 7 12V15C7 17.419 8.71776 19.4367 11 19.9V14H13V19.9ZM5.5358 17.6907C5.19061 16.8623 5 15.9534 5 15H2V13H5V12C5 11.3573 5.08661 10.7348 5.2488 10.1436L3.0359 8.86602L4.0359 7.13397L6.05636 8.30049C6.11995 8.19854 6.18609 8.09835 6.25469 8H17.7453C17.8139 8.09835 17.88 8.19854 17.9436 8.30049L19.9641 7.13397L20.9641 8.86602L18.7512 10.1436C18.9134 10.7348 19 11.3573 19 12V13H22V15H19C19 15.9534 18.8094 16.8623 18.4642 17.6907L20.9641 19.134L19.9641 20.866L17.4383 19.4077C16.1549 20.9893 14.1955 22 12 22C9.80453 22 7.84512 20.9893 6.56171 19.4077L4.0359 20.866L3.0359 19.134L5.5358 17.6907ZM8 6C8 3.79086 9.79086 2 12 2C14.2091 2 16 3.79086 16 6H8Z"></path></svg>

After

Width:  |  Height:  |  Size: 815 B

View File

@@ -1,28 +0,0 @@
<svg viewBox="0 0 150 150">
<defs>
<style>
.cls-1 {
stroke: #000;
stroke-miterlimit: 10;
stroke-width: 2px;
}
</style>
</defs>
<g id="Camada_3">
<g id="By_Maxihplay">
<g id="baixo">
<path class="cls-1" d="m20.57,127.29v-7.95h12.21v-30.79l-10.63,5.87-2.93-7.29,15.21-8.03h7.51v40.25h10.52v7.95h-31.89Z"/>
<path class="cls-1" d="m95.6,103.13c0,3.94-.43,7.45-1.28,10.56-.86,3.1-2.11,5.73-3.76,7.86-1.65,2.14-3.66,3.77-6.03,4.89-2.37,1.12-5.08,1.69-8.14,1.69-2.64,0-5.07-.47-7.3-1.39-2.22-.93-4.14-2.39-5.76-4.38-1.61-1.99-2.87-4.54-3.78-7.64-.9-3.1-1.36-6.82-1.36-11.14,0-3.93.43-7.45,1.3-10.56.87-3.1,2.12-5.72,3.76-7.86,1.64-2.14,3.65-3.77,6.05-4.89,2.4-1.12,5.11-1.69,8.14-1.69,2.64,0,5.07.47,7.3,1.39,2.22.93,4.14,2.38,5.74,4.36,1.6,1.98,2.85,4.52,3.76,7.62.9,3.1,1.36,6.83,1.36,11.18Zm-28.37.15v1.37c0,.43.02.86.07,1.3l17.96-12.98c-.86-2.42-1.98-4.21-3.39-5.37s-3.06-1.74-4.97-1.74c-1.37,0-2.64.35-3.81,1.05s-2.19,1.77-3.06,3.21c-.87,1.44-1.55,3.25-2.05,5.43-.5,2.18-.75,4.75-.75,7.74Zm19.36.15c0-.42-.01-.84-.04-1.26-.02-.43-.04-.84-.04-1.23l-17.85,12.9c.78,2.37,1.88,4.13,3.3,5.28,1.42,1.15,3.07,1.72,4.95,1.72,1.37,0,2.64-.35,3.83-1.06s2.21-1.78,3.08-3.21c.87-1.43,1.55-3.24,2.03-5.43.49-2.19.73-4.76.73-7.72Z"/>
<path class="cls-1" d="m103.12,127.29v-7.95h12.21v-30.79l-10.63,5.87-2.93-7.29,15.21-8.03h7.51v40.25h10.52v7.95h-31.89Z"/>
</g>
<g id="cima">
<path class="cls-1" d="m52.38,46.43c0,3.94-.43,7.45-1.28,10.56-.86,3.1-2.11,5.73-3.76,7.86-1.65,2.14-3.66,3.77-6.03,4.89-2.37,1.12-5.08,1.69-8.14,1.69-2.64,0-5.07-.47-7.3-1.39-2.22-.93-4.14-2.39-5.76-4.38-1.61-1.99-2.87-4.54-3.78-7.64-.9-3.1-1.36-6.82-1.36-11.14,0-3.93.43-7.45,1.3-10.56.87-3.1,2.12-5.72,3.76-7.86,1.64-2.14,3.65-3.77,6.05-4.89,2.4-1.12,5.11-1.69,8.14-1.69,2.64,0,5.07.47,7.3,1.39,2.22.93,4.14,2.38,5.74,4.36,1.6,1.98,2.85,4.52,3.76,7.62.9,3.1,1.36,6.83,1.36,11.18Zm-28.37.15v1.37c0,.43.02.86.07,1.3l17.96-12.98c-.86-2.42-1.98-4.21-3.39-5.37s-3.06-1.74-4.97-1.74c-1.37,0-2.64.35-3.81,1.05s-2.19,1.77-3.06,3.21c-.87,1.44-1.55,3.25-2.05,5.43-.5,2.18-.75,4.75-.75,7.74Zm19.36.15c0-.42-.01-.84-.04-1.26-.02-.43-.04-.84-.04-1.23l-17.85,12.9c.78,2.37,1.88,4.13,3.3,5.28,1.42,1.15,3.07,1.72,4.95,1.72,1.37,0,2.64-.35,3.83-1.06s2.21-1.78,3.08-3.21c.87-1.43,1.55-3.24,2.03-5.43.49-2.19.73-4.76.73-7.72Z"/>
<path class="cls-1" d="m59.89,70.58v-7.95h12.21v-30.79l-10.63,5.87-2.93-7.29,15.21-8.03h7.51v40.25h10.52v7.95h-31.89Z"/>
<path class="cls-1" d="m134.93,46.43c0,3.94-.43,7.45-1.28,10.56-.86,3.1-2.11,5.73-3.76,7.86-1.65,2.14-3.66,3.77-6.03,4.89-2.37,1.12-5.08,1.69-8.14,1.69-2.64,0-5.07-.47-7.3-1.39-2.22-.93-4.14-2.39-5.76-4.38-1.61-1.99-2.87-4.54-3.78-7.64-.9-3.1-1.36-6.82-1.36-11.14,0-3.93.43-7.45,1.3-10.56.87-3.1,2.12-5.72,3.76-7.86,1.64-2.14,3.65-3.77,6.05-4.89,2.4-1.12,5.11-1.69,8.14-1.69,2.64,0,5.07.47,7.3,1.39,2.22.93,4.14,2.38,5.74,4.36,1.6,1.98,2.85,4.52,3.76,7.62.9,3.1,1.36,6.83,1.36,11.18Zm-28.37.15v1.37c0,.43.02.86.07,1.3l17.96-12.98c-.86-2.42-1.98-4.21-3.39-5.37-1.41-1.16-3.06-1.74-4.97-1.74-1.37,0-2.64.35-3.81,1.05s-2.19,1.77-3.06,3.21c-.87,1.44-1.55,3.25-2.05,5.43-.5,2.18-.75,4.75-.75,7.74Zm19.36.15c0-.42-.01-.84-.04-1.26-.02-.43-.04-.84-.04-1.23l-17.85,12.9c.78,2.37,1.88,4.13,3.3,5.28,1.42,1.15,3.07,1.72,4.95,1.72,1.37,0,2.64-.35,3.83-1.06s2.21-1.78,3.08-3.21c.87-1.43,1.55-3.24,2.03-5.43.49-2.19.73-4.76.73-7.72Z"/>
</g>
</g>
</g>
<g id="Camada_2">
<path class="cls-2" d="m-3.8-.03h154.06v152.06H-3.8V-.03Z" fill="none"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -1,10 +0,0 @@
<svg viewBox="0 0 512 512">
<circle
style="fill:none;stroke:#000000;stroke-width:39.1094;stroke-linecap:round;stroke-dasharray:none"
cx="255.99998"
cy="255.99998"
r="236.44533"/>
<path
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:round"
d="M 14.169739,256 H 138.21901 L 210.20476,131.31702 277.76735,383.464 358.15788,244.22352 h 139.38547"/>
</svg>

Before

Width:  |  Height:  |  Size: 396 B

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24"><path d="M19 10H20C20.5523 10 21 10.4477 21 11V21C21 21.5523 20.5523 22 20 22H4C3.44772 22 3 21.5523 3 21V11C3 10.4477 3.44772 10 4 10H5V9C5 5.13401 8.13401 2 12 2C15.866 2 19 5.13401 19 9V10ZM17 10V9C17 6.23858 14.7614 4 12 4C9.23858 4 7 6.23858 7 9V10H17ZM11 14V18H13V14H11Z"></path></svg>

After

Width:  |  Height:  |  Size: 317 B

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24"><path d="M7 10H20C20.5523 10 21 10.4477 21 11V21C21 21.5523 20.5523 22 20 22H4C3.44772 22 3 21.5523 3 21V11C3 10.4477 3.44772 10 4 10H5V9C5 5.13401 8.13401 2 12 2C14.7405 2 17.1131 3.5748 18.2624 5.86882L16.4731 6.76344C15.6522 5.12486 13.9575 4 12 4C9.23858 4 7 6.23858 7 9V10ZM10 15V17H14V15H10Z"></path></svg>

After

Width:  |  Height:  |  Size: 338 B

View File

@@ -1 +0,0 @@
<svg viewBox="0 0 512 512"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg>

Before

Width:  |  Height:  |  Size: 391 B

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="800px" height="800px" fill="none" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m8.1816 10.703s4e-5 -2.5676 0-4.1081c-4e-5 -1.8489 1.527-3.5946 3.8182-3.5946 2.2912 0 3.8181 1.7457 3.8181 3.5946v4.1081" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path d="m4.5 11.393c-4e-5 1.7387-1e-4 5.3708 2e-5 7.8056 1.3e-4 2.6923 4.1637 3.3012 7.5 3.3012 3.3363 0 7.4999-0.6089 7.4999-3.3012v-7.8056c0-0.5523-0.4477-0.9975-1-0.9975h-13c-0.55227 0-0.99998 0.4452-0.99999 0.9975zm6 4.6096c0 0.476 0.2069 0.9037 0.5357 1.198v1.5521c0 0.5522 0.4477 1 1 1h0.1429c0.5523 0 1-0.4478 1-1v-1.5521c0.3288-0.2943 0.5357-0.722 0.5357-1.198 0-0.8876-0.7195-1.6071-1.6071-1.6071-0.8877 0-1.6072 0.7195-1.6072 1.6071z" clip-rule="evenodd" fill="#000" fill-rule="evenodd"/>
</svg>

Before

Width:  |  Height:  |  Size: 876 B

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="800px" height="800px" fill="none" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m4.5 11.393c-4e-5 1.7387-1e-4 5.3708 2e-5 7.8056 1.3e-4 2.6923 4.1637 3.3012 7.5 3.3012 3.3363 0 7.4999-0.6089 7.4999-3.3012v-7.8056c0-0.5523-0.4477-0.9975-1-0.9975h-13c-0.55227 0-0.99998 0.4452-0.99999 0.9975zm6 4.6096c0 0.476 0.2069 0.9037 0.5357 1.198v1.5521c0 0.5522 0.4477 1 1 1h0.1429c0.5523 0 1-0.4478 1-1v-1.5521c0.3288-0.2943 0.5357-0.722 0.5357-1.198 0-0.8876-0.7195-1.6071-1.6071-1.6071-0.8877 0-1.6072 0.7195-1.6072 1.6071z" clip-rule="evenodd" fill="#000" fill-rule="evenodd"/>
<path d="m8.1816 10.703s4e-5 -2.5676 0-4.1081c-4e-5 -1.8489 1.527-3.5946 3.8182-3.5946 2.2912 0 3.8181 1.7457 3.8181 3.5946" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</svg>

Before

Width:  |  Height:  |  Size: 869 B

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24"><path d="M18.031 16.6168L22.3137 20.8995L20.8995 22.3137L16.6168 18.031C15.0769 19.263 13.124 20 11 20C6.032 20 2 15.968 2 11C2 6.032 6.032 2 11 2C15.968 2 20 6.032 20 11C20 13.124 19.263 15.0769 18.031 16.6168ZM16.0247 15.8748C17.2475 14.6146 18 12.8956 18 11C18 7.1325 14.8675 4 11 4C7.1325 4 4 7.1325 4 11C4 14.8675 7.1325 18 11 18C12.8956 18 14.6146 17.2475 15.8748 16.0247L16.0247 15.8748Z"></path></svg>

After

Width:  |  Height:  |  Size: 435 B

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="#fff"><path d="M13 19.9C15.2822 19.4367 17 17.419 17 15V12C17 11.299 16.8564 10.6219 16.5846 10H7.41538C7.14358 10.6219 7 11.299 7 12V15C7 17.419 8.71776 19.4367 11 19.9V14H13V19.9ZM5.5358 17.6907C5.19061 16.8623 5 15.9534 5 15H2V13H5V12C5 11.3573 5.08661 10.7348 5.2488 10.1436L3.0359 8.86602L4.0359 7.13397L6.05636 8.30049C6.11995 8.19854 6.18609 8.09835 6.25469 8H17.7453C17.8139 8.09835 17.88 8.19854 17.9436 8.30049L19.9641 7.13397L20.9641 8.86602L18.7512 10.1436C18.9134 10.7348 19 11.3573 19 12V13H22V15H19C19 15.9534 18.8094 16.8623 18.4642 17.6907L20.9641 19.134L19.9641 20.866L17.4383 19.4077C16.1549 20.9893 14.1955 22 12 22C9.80453 22 7.84512 20.9893 6.56171 19.4077L4.0359 20.866L3.0359 19.134L5.5358 17.6907ZM8 6C8 3.79086 9.79086 2 12 2C14.2091 2 16 3.79086 16 6H8Z"></path></svg>

After

Width:  |  Height:  |  Size: 827 B

View File

@@ -1,31 +0,0 @@
<svg viewBox="0 0 150 150">
<defs>
<style>
.cls-1 {
fill: #fff;
stroke: #fff;
stroke-miterlimit: 10;
stroke-width: 2px;
}
</style>
</defs>
<g id="Camada_3">
<g id="codigos">
<g id="By_Maxihplay">
<g id="baixo">
<path class="cls-1" d="m20.57,127.29v-7.95h12.21v-30.79l-10.63,5.87-2.93-7.29,15.21-8.03h7.51v40.25h10.52v7.95h-31.89Z"/>
<path class="cls-1" d="m95.6,103.13c0,3.94-.43,7.45-1.28,10.56-.86,3.1-2.11,5.73-3.76,7.86-1.65,2.14-3.66,3.77-6.03,4.89-2.37,1.12-5.08,1.69-8.14,1.69-2.64,0-5.07-.47-7.3-1.39-2.22-.93-4.14-2.39-5.76-4.38-1.61-1.99-2.87-4.54-3.78-7.64-.9-3.1-1.36-6.82-1.36-11.14,0-3.93.43-7.45,1.3-10.56.87-3.1,2.12-5.72,3.76-7.86,1.64-2.14,3.65-3.77,6.05-4.89,2.4-1.12,5.11-1.69,8.14-1.69,2.64,0,5.07.47,7.3,1.39,2.22.93,4.14,2.38,5.74,4.36,1.6,1.98,2.85,4.52,3.76,7.62.9,3.1,1.36,6.83,1.36,11.18Zm-28.37.15v1.37c0,.43.02.86.07,1.3l17.96-12.98c-.86-2.42-1.98-4.21-3.39-5.37s-3.06-1.74-4.97-1.74c-1.37,0-2.64.35-3.81,1.05s-2.19,1.77-3.06,3.21c-.87,1.44-1.55,3.25-2.05,5.43-.5,2.18-.75,4.75-.75,7.74Zm19.36.15c0-.42-.01-.84-.04-1.26-.02-.43-.04-.84-.04-1.23l-17.85,12.9c.78,2.37,1.88,4.13,3.3,5.28,1.42,1.15,3.07,1.72,4.95,1.72,1.37,0,2.64-.35,3.83-1.06s2.21-1.78,3.08-3.21c.87-1.43,1.55-3.24,2.03-5.43.49-2.19.73-4.76.73-7.72Z"/>
<path class="cls-1" d="m103.12,127.29v-7.95h12.21v-30.79l-10.63,5.87-2.93-7.29,15.21-8.03h7.51v40.25h10.52v7.95h-31.89Z"/>
</g>
<g id="cima">
<path class="cls-1" d="m52.38,46.43c0,3.94-.43,7.45-1.28,10.56-.86,3.1-2.11,5.73-3.76,7.86-1.65,2.14-3.66,3.77-6.03,4.89-2.37,1.12-5.08,1.69-8.14,1.69-2.64,0-5.07-.47-7.3-1.39-2.22-.93-4.14-2.39-5.76-4.38-1.61-1.99-2.87-4.54-3.78-7.64-.9-3.1-1.36-6.82-1.36-11.14,0-3.93.43-7.45,1.3-10.56.87-3.1,2.12-5.72,3.76-7.86,1.64-2.14,3.65-3.77,6.05-4.89,2.4-1.12,5.11-1.69,8.14-1.69,2.64,0,5.07.47,7.3,1.39,2.22.93,4.14,2.38,5.74,4.36,1.6,1.98,2.85,4.52,3.76,7.62.9,3.1,1.36,6.83,1.36,11.18Zm-28.37.15v1.37c0,.43.02.86.07,1.3l17.96-12.98c-.86-2.42-1.98-4.21-3.39-5.37s-3.06-1.74-4.97-1.74c-1.37,0-2.64.35-3.81,1.05s-2.19,1.77-3.06,3.21c-.87,1.44-1.55,3.25-2.05,5.43-.5,2.18-.75,4.75-.75,7.74Zm19.36.15c0-.42-.01-.84-.04-1.26-.02-.43-.04-.84-.04-1.23l-17.85,12.9c.78,2.37,1.88,4.13,3.3,5.28,1.42,1.15,3.07,1.72,4.95,1.72,1.37,0,2.64-.35,3.83-1.06s2.21-1.78,3.08-3.21c.87-1.43,1.55-3.24,2.03-5.43.49-2.19.73-4.76.73-7.72Z"/>
<path class="cls-1" d="m59.89,70.58v-7.95h12.21v-30.79l-10.63,5.87-2.93-7.29,15.21-8.03h7.51v40.25h10.52v7.95h-31.89Z"/>
<path class="cls-1" d="m134.93,46.43c0,3.94-.43,7.45-1.28,10.56-.86,3.1-2.11,5.73-3.76,7.86-1.65,2.14-3.66,3.77-6.03,4.89-2.37,1.12-5.08,1.69-8.14,1.69-2.64,0-5.07-.47-7.3-1.39-2.22-.93-4.14-2.39-5.76-4.38-1.61-1.99-2.87-4.54-3.78-7.64-.9-3.1-1.36-6.82-1.36-11.14,0-3.93.43-7.45,1.3-10.56.87-3.1,2.12-5.72,3.76-7.86,1.64-2.14,3.65-3.77,6.05-4.89,2.4-1.12,5.11-1.69,8.14-1.69,2.64,0,5.07.47,7.3,1.39,2.22.93,4.14,2.38,5.74,4.36,1.6,1.98,2.85,4.52,3.76,7.62.9,3.1,1.36,6.83,1.36,11.18Zm-28.37.15v1.37c0,.43.02.86.07,1.3l17.96-12.98c-.86-2.42-1.98-4.21-3.39-5.37-1.41-1.16-3.06-1.74-4.97-1.74-1.37,0-2.64.35-3.81,1.05s-2.19,1.77-3.06,3.21c-.87,1.44-1.55,3.25-2.05,5.43-.5,2.18-.75,4.75-.75,7.74Zm19.36.15c0-.42-.01-.84-.04-1.26-.02-.43-.04-.84-.04-1.23l-17.85,12.9c.78,2.37,1.88,4.13,3.3,5.28,1.42,1.15,3.07,1.72,4.95,1.72,1.37,0,2.64-.35,3.83-1.06,1.19-.71,2.21-1.78,3.08-3.21.87-1.43,1.55-3.24,2.03-5.43.49-2.19.73-4.76.73-7.72Z"/>
</g>
</g>
</g>
</g>
<g id="Camada_2">
<path class="cls-2" d="m-3.8-.03h154.06v152.06H-3.8V-.03Z" fill="none"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -1,10 +0,0 @@
<svg viewBox="0 0 512 512">
<circle
style="fill:none;stroke:#ffffff;stroke-width:39.1094;stroke-linecap:round;stroke-dasharray:none"
cx="255.99998"
cy="255.99998"
r="236.44533" />
<path
style="fill:none;stroke:#ffffff;stroke-width:30;stroke-linecap:round"
d="M 14.169739,256 H 138.21901 L 210.20476,131.31702 277.76735,383.464 358.15788,244.22352 h 139.38547"/>
</svg>

Before

Width:  |  Height:  |  Size: 397 B

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="#fff"><path d="M19 10H20C20.5523 10 21 10.4477 21 11V21C21 21.5523 20.5523 22 20 22H4C3.44772 22 3 21.5523 3 21V11C3 10.4477 3.44772 10 4 10H5V9C5 5.13401 8.13401 2 12 2C15.866 2 19 5.13401 19 9V10ZM17 10V9C17 6.23858 14.7614 4 12 4C9.23858 4 7 6.23858 7 9V10H17ZM11 14V18H13V14H11Z"></path></svg>

After

Width:  |  Height:  |  Size: 329 B

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="#fff"><path d="M7 10H20C20.5523 10 21 10.4477 21 11V21C21 21.5523 20.5523 22 20 22H4C3.44772 22 3 21.5523 3 21V11C3 10.4477 3.44772 10 4 10H5V9C5 5.13401 8.13401 2 12 2C14.7405 2 17.1131 3.5748 18.2624 5.86882L16.4731 6.76344C15.6522 5.12486 13.9575 4 12 4C9.23858 4 7 6.23858 7 9V10ZM10 15V17H14V15H10Z"></path></svg>

After

Width:  |  Height:  |  Size: 350 B

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="#fff"><path d="M18.031 16.6168L22.3137 20.8995L20.8995 22.3137L16.6168 18.031C15.0769 19.263 13.124 20 11 20C6.032 20 2 15.968 2 11C2 6.032 6.032 2 11 2C15.968 2 20 6.032 20 11C20 13.124 19.263 15.0769 18.031 16.6168ZM16.0247 15.8748C17.2475 14.6146 18 12.8956 18 11C18 7.1325 14.8675 4 11 4C7.1325 4 4 7.1325 4 11C4 14.8675 7.1325 18 11 18C12.8956 18 14.6146 17.2475 15.8748 16.0247L16.0247 15.8748Z"></path></svg>

After

Width:  |  Height:  |  Size: 447 B

View File

@@ -9,6 +9,7 @@
<file>icons/black/svg/booklet.svg</file>
<file>icons/black/svg/book.svg</file>
<file>icons/black/svg/brush-line.svg</file>
<file>icons/black/svg/bug-line.svg</file>
<file>icons/black/svg/buzz-controller-line.svg</file>
<file>icons/black/svg/camera-video.svg</file>
<file>icons/black/svg/cheats-line.svg</file>
@@ -17,7 +18,6 @@
<file>icons/black/svg/close-line.svg</file>
<file>icons/black/svg/controller-line.svg</file>
<file>icons/black/svg/controller-strike-line.svg</file>
<file>icons/black/svg/debugger-line.svg</file>
<file>icons/black/svg/debug-step-into-line.svg</file>
<file>icons/black/svg/debug-step-out-line.svg</file>
<file>icons/black/svg/debug-step-over-line.svg</file>
@@ -54,7 +54,6 @@
<file>icons/black/svg/guitar-line.svg</file>
<file>icons/black/svg/guncon2-line.svg</file>
<file>icons/black/svg/headset-line.svg</file>
<file>icons/black/svg/heart-circle-line.svg</file>
<file>icons/black/svg/image-fill.svg</file>
<file>icons/black/svg/interface-line.svg</file>
<file>icons/black/svg/jogcon-line.svg</file>
@@ -63,16 +62,15 @@
<file>icons/black/svg/keyboardmania-line.svg</file>
<file>icons/black/svg/lightbulb-line.svg</file>
<file>icons/black/svg/list-check.svg</file>
<file>icons/black/svg/lock-fill.svg</file>
<file>icons/black/svg/lock-unlock-fill.svg</file>
<file>icons/black/svg/login-box-line.svg</file>
<file>icons/black/svg/magnifier-line.svg</file>
<file>icons/black/svg/memcard-line.svg</file>
<file>icons/black/svg/mic-line.svg</file>
<file>icons/black/svg/minus-line.svg</file>
<file>icons/black/svg/mouse-line.svg</file>
<file>icons/black/svg/msd-line.svg</file>
<file>icons/black/svg/negcon-line.svg</file>
<file>icons/black/svg/padlock-lock.svg</file>
<file>icons/black/svg/padlock-unlock.svg</file>
<file>icons/black/svg/pause-line.svg</file>
<file>icons/black/svg/pencil-line.svg</file>
<file>icons/black/svg/pin-filled.svg</file>
@@ -87,6 +85,7 @@
<file>icons/black/svg/save-3-line.svg</file>
<file>icons/black/svg/screenshot-2-line.svg</file>
<file>icons/black/svg/seamic-line.svg</file>
<file>icons/black/svg/search-line.svg</file>
<file>icons/black/svg/settings-3-line.svg</file>
<file>icons/black/svg/shut-down-line.svg</file>
<file>icons/black/svg/singstar-line.svg</file>
@@ -114,6 +113,7 @@
<file>icons/white/svg/booklet.svg</file>
<file>icons/white/svg/book.svg</file>
<file>icons/white/svg/brush-line.svg</file>
<file>icons/white/svg/bug-line.svg</file>
<file>icons/white/svg/buzz-controller-line.svg</file>
<file>icons/white/svg/camera-video.svg</file>
<file>icons/white/svg/cheats-line.svg</file>
@@ -122,7 +122,6 @@
<file>icons/white/svg/close-line.svg</file>
<file>icons/white/svg/controller-line.svg</file>
<file>icons/white/svg/controller-strike-line.svg</file>
<file>icons/white/svg/debugger-line.svg</file>
<file>icons/white/svg/debug-step-into-line.svg</file>
<file>icons/white/svg/debug-step-out-line.svg</file>
<file>icons/white/svg/debug-step-over-line.svg</file>
@@ -159,7 +158,6 @@
<file>icons/white/svg/guitar-line.svg</file>
<file>icons/white/svg/guncon2-line.svg</file>
<file>icons/white/svg/headset-line.svg</file>
<file>icons/white/svg/heart-circle-line.svg</file>
<file>icons/white/svg/image-fill.svg</file>
<file>icons/white/svg/interface-line.svg</file>
<file>icons/white/svg/jogcon-line.svg</file>
@@ -168,6 +166,8 @@
<file>icons/white/svg/keyboardmania-line.svg</file>
<file>icons/white/svg/lightbulb-line.svg</file>
<file>icons/white/svg/list-check.svg</file>
<file>icons/white/svg/lock-fill.svg</file>
<file>icons/white/svg/lock-unlock-fill.svg</file>
<file>icons/white/svg/login-box-line.svg</file>
<file>icons/white/svg/magnifier-line.svg</file>
<file>icons/white/svg/memcard-line.svg</file>
@@ -192,6 +192,7 @@
<file>icons/white/svg/save-3-line.svg</file>
<file>icons/white/svg/screenshot-2-line.svg</file>
<file>icons/white/svg/seamic-line.svg</file>
<file>icons/white/svg/search-line.svg</file>
<file>icons/white/svg/settings-3-line.svg</file>
<file>icons/white/svg/shut-down-line.svg</file>
<file>icons/white/svg/singstar-line.svg</file>

View File

@@ -252,7 +252,7 @@ static void vSyncInfoCalc(vSyncTimingInfo* info, double framesPerSecond, u32 sca
const u64 accumilatedHRenderError = (hRender % 10000) + (hBlank % 10000);
const u64 accumilatedHFractional = accumilatedHRenderError % 10000;
info->hRender += (u32)(accumilatedHRenderError / 10000);
info->hSyncError = (accumilatedHFractional * (scansPerFrame / (IsInterlacedVideoMode() ? 2 : 1))) / 10000;
info->hSyncError = (u32)((accumilatedHFractional * (scansPerFrame / (IsInterlacedVideoMode() ? 2 : 1))) / 10000);
// Note: In NTSC modes there is some small rounding error in the vsync too,
// however it would take thousands of frames for it to amount to anything and

View File

@@ -160,7 +160,7 @@ namespace InternalServers
//Counts
ret->questions = dns.questions;
DNS_State* state = new DNS_State(reqs.size(), reqs, ret, payload->sourcePort);
DNS_State* state = new DNS_State(static_cast<int>(reqs.size()), reqs, ret, payload->sourcePort);
outstandingQueries++;
for (size_t i = 0; i < reqs.size(); i++)

View File

@@ -8,22 +8,19 @@
std::vector<std::unique_ptr<BiosThread>> getEEThreads()
{
std::vector<std::unique_ptr<BiosThread>> threads;
if (CurrentBiosInformation.eeThreadListAddr <= 0)
return threads;
if (!VMManager::HasValidVM() || CurrentBiosInformation.eeThreadListAddr == 0)
return {};
const u32 start = CurrentBiosInformation.eeThreadListAddr & 0x3fffff;
std::vector<std::unique_ptr<BiosThread>> threads;
for (int tid = 0; tid < 256; tid++)
{
EEInternalThread* internal = static_cast<EEInternalThread*>(
PSM(start + tid * sizeof(EEInternalThread)));
EEInternalThread* internal = static_cast<EEInternalThread*>(PSM(start + tid * sizeof(EEInternalThread)));
if (internal->status != (int)ThreadStatus::THS_BAD)
{
auto thread = std::make_unique<EEThread>(tid, *internal);
threads.push_back(std::move(thread));
}
if (internal && internal->status != (int)ThreadStatus::THS_BAD)
threads.emplace_back(std::make_unique<EEThread>(tid, *internal));
}
return threads;
@@ -63,8 +60,7 @@ std::vector<std::unique_ptr<BiosThread>> getIOPThreads()
data.PC = iopMemRead32(data.SavedSP + 0x8c);
auto thread = std::make_unique<IOPThread>(data);
threads.push_back(std::move(thread));
threads.emplace_back(std::make_unique<IOPThread>(data));
item = iopMemRead32(item + 0x24);
}
@@ -93,7 +89,7 @@ std::vector<IopMod> getIOPModules()
if (i > 1000)
return {};
IopMod mod;
IopMod& mod = modlist.emplace_back();
u32 nstr = iopMemRead32(maddr + 4);
if (nstr)
@@ -113,8 +109,6 @@ std::vector<IopMod> getIOPModules()
mod.data_size = iopMemRead32(maddr + 0x20);
mod.bss_size = iopMemRead32(maddr + 0x24);
modlist.push_back(mod);
maddr = iopMemRead32(maddr);
}

View File

@@ -674,11 +674,11 @@ void GSgetStats(SmallStringBase& info)
}
else if (pps >= _1kb)
{
pps /= _1kb; // Kpps
prefix = 'K';
pps /= _1kb; // kpps
prefix = 'k';
}
info.format("{} SW | {} SP | {} P | {} D | {:.2f} S | {:.2f} U | {:.2f} {}pps",
info.format("{} SW | {} SYNP | {} PRIM | {} DRW | {:.2f} SWIZ | {:.2f} UNSWIZ | {:.2f} {}pps",
api_name,
(int)pm.Get(GSPerfMon::SyncPoint),
(int)pm.Get(GSPerfMon::Prim),
@@ -693,7 +693,7 @@ void GSgetStats(SmallStringBase& info)
}
else
{
info.format("{} HW | {} P | {} D | {} DC | {} B | {} RP | {} RB | {} TC | {} TU",
info.format("{} HW | {} PRIM | {} DRW | {} DRWC | {} BAR | {} RP | {} RB | {} TC | {} TU",
api_name,
(int)pm.Get(GSPerfMon::Prim),
(int)pm.Get(GSPerfMon::Draw),
@@ -733,7 +733,7 @@ void GSgetMemoryStats(SmallStringBase& info)
{
const double hashcache_MB = get_MB(static_cast<double>(g_texture_cache->GetHashCacheMemoryUsage()));
const double total_MB = targets_MB + sources_MB + hashcache_MB + pool_MB;
info.format("VRAM: {} MB | T: {} MB | S: {} MB | H: {} MB | P: {} MB",
info.format("VRAM: {} MB | TGT: {} MB | SRC: {} MB | HC: {} MB | PL: {} MB",
format_precision(total_MB),
format_precision(targets_MB),
format_precision(sources_MB),
@@ -743,7 +743,7 @@ void GSgetMemoryStats(SmallStringBase& info)
else
{
const double total_MB = targets_MB + sources_MB + pool_MB;
info.format("VRAM: {} MB | T: {} MB | S: {} MB | P: {} MB",
info.format("VRAM: {} MB | TGT: {} MB | SRC: {} MB | PL: {} MB",
format_precision(total_MB),
format_precision(targets_MB),
format_precision(sources_MB),

View File

@@ -36,7 +36,7 @@ public:
protected:
double m_counters[CounterLast] = {};
double m_stats[CounterLast] = {};
u64 m_frame = 0;
int m_frame = 0;
clock_t m_lastframe = 0;
int m_count = 0;
int m_disp_fb_sprite_blits = 0;
@@ -46,8 +46,8 @@ public:
void Reset();
void SetFrame(u64 frame) { m_frame = frame; }
u64 GetFrame() { return m_frame; }
void SetFrame(int frame) { m_frame = frame; }
int GetFrame() { return m_frame; }
void EndFrame(bool frame_only);
void Put(counter_t c, double val) { m_counters[c] += val; }
@@ -68,4 +68,4 @@ public:
void Dump(const std::string& filename, bool hw);
};
extern GSPerfMon g_perfmon;
extern GSPerfMon g_perfmon;

View File

@@ -723,6 +723,39 @@ GSTexture* GSDevice::CreateTexture(int w, int h, int mipmap_levels, GSTexture::F
return FetchSurface(GSTexture::Type::Texture, w, h, levels, format, false, m_features.prefer_new_textures && !prefer_reuse);
}
void GSDevice::DoStretchRectWithAssertions(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear)
{
pxAssert((dTex && dTex->IsDepthStencil()) == HasDepthOutput(shader));
pxAssert(linear ? SupportsBilinear(shader) : SupportsNearest(shader));
GL_INS("StretchRect(%d) {%d,%d} %dx%d -> {%d,%d) %dx%d", shader, int(sRect.left), int(sRect.top),
int(sRect.right - sRect.left), int(sRect.bottom - sRect.top), int(dRect.left), int(dRect.top),
int(dRect.right - dRect.left), int(dRect.bottom - dRect.top));
DoStretchRect(sTex, sRect, dTex, dRect, cms, shader, linear);
}
void GSDevice::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
bool red, bool green, bool blue, bool alpha, ShaderConvert shader)
{
GSHWDrawConfig::ColorMaskSelector cms;
cms.wr = red;
cms.wg = green;
cms.wb = blue;
cms.wa = alpha;
pxAssert(HasVariableWriteMask(shader));
GL_INS("ColorCopy Red:%d Green:%d Blue:%d Alpha:%d", cms.wr, cms.wg, cms.wb, cms.wa);
DoStretchRectWithAssertions(sTex, sRect, dTex, dRect, cms, shader, false);
}
void GSDevice::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
ShaderConvert shader, bool linear)
{
DoStretchRectWithAssertions(sTex, sRect, dTex, dRect, GSHWDrawConfig::ColorMaskSelector(ShaderConvertWriteMask(shader)), shader, linear);
}
void GSDevice::StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
{
StretchRect(sTex, GSVector4(0, 0, 1, 1), dTex, dRect, shader, linear);
@@ -734,11 +767,11 @@ void GSDevice::DrawMultiStretchRects(
for (u32 i = 0; i < num_rects; i++)
{
const MultiStretchRect& sr = rects[i];
pxAssert(shader == ShaderConvert::COPY || shader == ShaderConvert::RTA_CORRECTION || rects[0].wmask.wrgba == 0xf);
pxAssert(HasVariableWriteMask(shader) || rects[0].wmask.wrgba == 0xf);
if (rects[0].wmask.wrgba != 0xf)
{
g_gs_device->StretchRect(sr.src, sr.src_rect, dTex, sr.dst_rect, rects[0].wmask.wr,
rects[0].wmask.wg, rects[0].wmask.wb, rects[0].wmask.wa);
rects[0].wmask.wg, rects[0].wmask.wb, rects[0].wmask.wa, shader);
}
else
{

View File

@@ -69,6 +69,27 @@ enum class ShaderInterlace
Count
};
static inline bool HasVariableWriteMask(ShaderConvert shader)
{
switch (shader)
{
case ShaderConvert::COPY:
case ShaderConvert::RTA_CORRECTION:
return true;
default:
return false;
}
}
static inline int GetShaderIndexForMask(ShaderConvert shader, int mask)
{
pxAssert(HasVariableWriteMask(shader));
int index = mask;
if (shader == ShaderConvert::RTA_CORRECTION)
index |= 1 << 4;
return index;
}
static inline bool HasDepthOutput(ShaderConvert shader)
{
switch (shader)
@@ -549,6 +570,7 @@ struct alignas(16) GSHWDrawConfig
constexpr ColorMaskSelector(): key(0xF) {}
constexpr ColorMaskSelector(u8 c): key(0) { wrgba = c; }
};
#pragma pack(pop)
struct alignas(16) VSConstantBuffer
{
@@ -922,6 +944,12 @@ protected:
/// Perform texture operations for ImGui
void UpdateImGuiTextures();
protected:
// Entry point to the renderer-specific StretchRect code.
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) = 0;
void DoStretchRectWithAssertions(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear);
public:
GSDevice();
virtual ~GSDevice();
@@ -1037,9 +1065,9 @@ public:
virtual std::unique_ptr<GSDownloadTexture> CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format) = 0;
virtual void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) = 0;
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) = 0;
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) = 0;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true);
void StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true);
/// Performs a screen blit for display. If dTex is null, it assumes you are writing to the system framebuffer/swap chain.

View File

@@ -1274,28 +1274,18 @@ void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
dTex->SetState(GSTexture::State::Dirty);
}
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
void GSDevice11::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear)
{
pxAssert(dTex->IsDepthStencil() == HasDepthOutput(shader));
pxAssert(linear ? SupportsBilinear(shader) : SupportsNearest(shader));
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), nullptr,
m_convert.bs[ShaderConvertWriteMask(shader)].get(), linear);
DoStretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), nullptr, m_convert.bs[cms.wrgba].get(), linear);
}
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear)
void GSDevice11::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear)
{
StretchRect(sTex, sRect, dTex, dRect, ps, ps_cb, m_convert.bs[D3D11_COLOR_WRITE_ENABLE_ALL].get(), linear);
DoStretchRect(sTex, sRect, dTex, dRect, ps, ps_cb, m_convert.bs[D3D11_COLOR_WRITE_ENABLE_ALL].get(), linear);
}
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader)
{
const u8 index = static_cast<u8>(red) | (static_cast<u8>(green) << 1) | (static_cast<u8>(blue) << 2) |
(static_cast<u8>(alpha) << 3);
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), nullptr,
m_convert.bs[index].get(), false);
}
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear)
void GSDevice11::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear)
{
CommitClear(sTex);
@@ -1439,7 +1429,7 @@ void GSDevice11::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u
const GSVector4 dRect(0, 0, dSize, 1);
const ShaderConvert shader = (dSize == 16) ? ShaderConvert::CLUT_4 : ShaderConvert::CLUT_8;
StretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
DoStretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
}
void GSDevice11::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM)
@@ -1457,7 +1447,7 @@ void GSDevice11::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offs
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
StretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
DoStretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
}
void GSDevice11::FilteredDownsampleTexture(GSTexture* sTex, GSTexture* dTex, u32 downsample_factor, const GSVector2i& clamp_min, const GSVector4& dRect)
@@ -1477,7 +1467,7 @@ void GSDevice11::FilteredDownsampleTexture(GSTexture* sTex, GSTexture* dTex, u32
m_ctx->UpdateSubresource(m_merge.cb.get(), 0, nullptr, &cb, 0, 0);
const ShaderConvert shader = ShaderConvert::DOWNSAMPLE_COPY;
StretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
DoStretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
}
void GSDevice11::DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvert shader)
@@ -1596,7 +1586,7 @@ void GSDevice11::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
// Save 2nd output
if (feedback_write_2)
{
StretchRect(dTex, full_r, sTex[2], dRect[2], m_convert.ps[static_cast<int>(ShaderConvert::YUV)].get(),
DoStretchRect(dTex, full_r, sTex[2], dRect[2], m_convert.ps[static_cast<int>(ShaderConvert::YUV)].get(),
m_merge.cb.get(), nullptr, linear);
}
@@ -1607,12 +1597,12 @@ void GSDevice11::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
if (sTex[0])
{
// 1st output is enabled. It must be blended
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge.ps[PMODE.MMOD].get(), m_merge.cb.get(), m_merge.bs.get(), linear);
DoStretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge.ps[PMODE.MMOD].get(), m_merge.cb.get(), m_merge.bs.get(), linear);
}
if (feedback_write_1)
{
StretchRect(dTex, full_r, sTex[2], dRect[2], m_convert.ps[static_cast<int>(ShaderConvert::YUV)].get(),
DoStretchRect(dTex, full_r, sTex[2], dRect[2], m_convert.ps[static_cast<int>(ShaderConvert::YUV)].get(),
m_merge.cb.get(), nullptr, linear);
}
}
@@ -1621,7 +1611,7 @@ void GSDevice11::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture*
{
m_ctx->UpdateSubresource(m_interlace.cb.get(), 0, nullptr, &cb, 0, 0);
StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[static_cast<int>(shader)].get(), m_interlace.cb.get(), linear);
DoStretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[static_cast<int>(shader)].get(), m_interlace.cb.get(), linear);
}
void GSDevice11::DoFXAA(GSTexture* sTex, GSTexture* dTex)
@@ -1647,7 +1637,7 @@ void GSDevice11::DoFXAA(GSTexture* sTex, GSTexture* dTex)
return;
}
StretchRect(sTex, sRect, dTex, dRect, m_fxaa_ps.get(), nullptr, true);
DoStretchRect(sTex, sRect, dTex, dRect, m_fxaa_ps.get(), nullptr, true);
}
void GSDevice11::DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4])
@@ -1659,7 +1649,7 @@ void GSDevice11::DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float para
m_ctx->UpdateSubresource(m_shadeboost.cb.get(), 0, nullptr, params, 0, 0);
StretchRect(sTex, sRect, dTex, dRect, m_shadeboost.ps.get(), m_shadeboost.cb.get(), false);
DoStretchRect(sTex, sRect, dTex, dRect, m_shadeboost.ps.get(), m_shadeboost.cb.get(), false);
}
void GSDevice11::SetupVS(VSSelector sel, const GSHWDrawConfig::VSConstantBuffer* cb)
@@ -2158,7 +2148,7 @@ void GSDevice11::RenderImGui()
m_ctx->IASetVertexBuffers(0, 1, m_vb.addressof(), &m_state.vb_stride, &vb_offset);
}
void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, SetDATM datm)
void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSVector4i& bbox)
{
// sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
@@ -2179,6 +2169,17 @@ void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vert
// ia
const GSVector4 src = GSVector4(bbox) / GSVector4(ds->GetSize()).xyxy();
const GSVector4 dst = src * 2.0f - 1.0f;
const GSVertexPT1 vertices[] =
{
{GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)},
{GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)},
{GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)},
{GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)},
};
IASetVertexBuffer(vertices, sizeof(vertices[0]), 4);
IASetInputLayout(m_convert.il.get());
IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
@@ -2447,7 +2448,7 @@ void GSDevice11::PSUnbindConflictingSRVs(GSTexture* tex1, GSTexture* tex2)
bool changed = false;
for (size_t i = 0; i < m_state.ps_sr_views.size(); i++)
{
if ((tex1 && m_state.ps_sr_views[i] == *(GSTexture11*)tex1) || (tex2 && m_state.ps_sr_views[i] == *(GSTexture11*)tex2))
if ((tex1 && m_state.ps_sr_views[i] == *static_cast<GSTexture11*>(tex1)) || (tex2 && m_state.ps_sr_views[i] == *static_cast<GSTexture11*>(tex2)))
{
m_state.ps_sr_views[i] = nullptr;
changed = true;
@@ -2624,6 +2625,8 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
}
}
// Destination Alpha Setup
const bool multidraw_fb_copy = m_features.multidraw_fb_copy && (config.require_one_barrier || config.require_full_barrier);
GSTexture* primid_texture = nullptr;
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking)
{
@@ -2634,25 +2637,12 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
return;
}
StretchRect(colclip_rt ? colclip_rt : config.rt, GSVector4(config.drawarea) / GSVector4(rtsize).xyxy(),
DoStretchRect(colclip_rt ? colclip_rt : config.rt, GSVector4(config.drawarea) / GSVector4(rtsize).xyxy(),
primid_texture, GSVector4(config.drawarea), m_date.primid_init_ps[static_cast<u8>(config.datm)].get(), nullptr, false);
}
else if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne)
{
const GSVector4 src = GSVector4(config.drawarea) / GSVector4(config.ds->GetSize()).xyxy();
const GSVector4 dst = src * 2.0f - 1.0f;
GSVertexPT1 vertices[] =
{
{GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)},
{GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)},
{GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)},
{GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)},
};
SetupDATE(colclip_rt ? colclip_rt : config.rt, config.ds, vertices, config.datm);
}
(config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne && !multidraw_fb_copy))
SetupDATE(colclip_rt ? colclip_rt : config.rt, config.ds, config.datm, config.drawarea);
if (config.vs.expand != GSHWDrawConfig::VSExpand::None)
{
@@ -2697,8 +2687,13 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
}
IASetPrimitiveTopology(topology);
// Depth testing and sampling, bind resource as dsv read only and srv at the same time without the need of a copy.
ID3D11DepthStencilView* read_only_dsv = nullptr;
if (config.tex && config.tex == config.ds)
read_only_dsv = static_cast<GSTexture11*>(config.ds)->ReadOnlyDepthStencilView();
// Should be called before changing local srv state.
PSUnbindConflictingSRVs(colclip_rt ? colclip_rt : config.rt, config.ds);
PSUnbindConflictingSRVs(colclip_rt ? colclip_rt : config.rt, read_only_dsv ? nullptr : config.ds);
if (config.tex)
{
@@ -2714,11 +2709,6 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
SetupVS(config.vs, &config.cb_vs);
SetupPS(config.ps, &config.cb_ps, config.sampler);
// Depth testing and sampling, bind resource as dsv read only and srv at the same time without the need of a copy.
ID3D11DepthStencilView* read_only_dsv = nullptr;
if (config.tex && config.tex == config.ds)
read_only_dsv = static_cast<GSTexture11*>(config.ds)->ReadOnlyDepthStencilView();
if (primid_texture)
{
OMDepthStencilSelector dss = config.depth;
@@ -2766,6 +2756,11 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
OMSetRenderTargets(draw_rt, draw_ds, &config.scissor, read_only_dsv);
SetupOM(config.depth, OMBlendSelector(config.colormask, config.blend), config.blend.constant);
// Clear stencil as close as possible to the RT bind, to avoid framebuffer swaps.
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne && multidraw_fb_copy)
m_ctx->ClearDepthStencilView(*static_cast<GSTexture11*>(draw_ds), D3D11_CLEAR_STENCIL, 0.0f, 1);
SendHWDraw(config, draw_rt_clone, draw_rt, config.require_one_barrier, config.require_full_barrier, false);
if (config.blend_multi_pass.enable)

View File

@@ -253,6 +253,10 @@ private:
D3D11ShaderCache m_shader_cache;
std::string m_tfx_source;
protected:
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) override;
public:
GSDevice11();
~GSDevice11() override;
@@ -298,10 +302,8 @@ public:
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear = true);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) override;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear = true);
void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear);
void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear);
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, PresentShader shader, float shaderTime, bool linear) override;
void UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) override;
void ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM) override;
@@ -309,7 +311,7 @@ public:
void DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvert shader) override;
void DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, const GSVector2& ds);
void SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, SetDATM datm);
void SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSVector4i& bbox);
void* IAMapVertexBuffer(u32 stride, u32 count);
void IAUnmapVertexBuffer(u32 stride, u32 count);

View File

@@ -1425,30 +1425,17 @@ void GSDevice12::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
dTex12->SetState(GSTexture::State::Dirty);
}
void GSDevice12::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
ShaderConvert shader /* = ShaderConvert::COPY */, bool linear /* = true */)
void GSDevice12::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear)
{
pxAssert(HasDepthOutput(shader) == (dTex && dTex->GetType() == GSTexture::Type::DepthStencil));
GL_INS("StretchRect(%d) {%d,%d} %dx%d -> {%d,%d) %dx%d", shader, int(sRect.left), int(sRect.top),
int(sRect.right - sRect.left), int(sRect.bottom - sRect.top), int(dRect.left), int(dRect.top),
int(dRect.right - dRect.left), int(dRect.bottom - dRect.top));
const bool allow_discard = (cms.wrgba == 0xf);
const ID3D12PipelineState* state;
if (HasVariableWriteMask(shader))
state = m_color_copy[GetShaderIndexForMask(shader, cms.wrgba)].get();
else
state = dTex ? m_convert[static_cast<int>(shader)].get() : m_present[static_cast<int>(shader)].get();
DoStretchRect(static_cast<GSTexture12*>(sTex), sRect, static_cast<GSTexture12*>(dTex), dRect,
dTex ? m_convert[static_cast<int>(shader)].get() : m_present[static_cast<int>(shader)].get(), linear,
ShaderConvertWriteMask(shader) == 0xf);
}
void GSDevice12::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red,
bool green, bool blue, bool alpha, ShaderConvert shader)
{
GL_PUSH("ColorCopy Red:%d Green:%d Blue:%d Alpha:%d", red, green, blue, alpha);
const u32 index = (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0);
int rta_offset = (shader == ShaderConvert::RTA_CORRECTION) ? 16 : 0;
const bool allow_discard = (index == 0xf);
DoStretchRect(static_cast<GSTexture12*>(sTex), sRect, static_cast<GSTexture12*>(dTex), dRect,
m_color_copy[index + rta_offset].get(), false, allow_discard);
state, linear, allow_discard);
}
void GSDevice12::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
@@ -1639,10 +1626,10 @@ void GSDevice12::DoMultiStretchRects(
SetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
SetUtilityTexture(rects[0].src, rects[0].linear ? m_linear_sampler_cpu : m_point_sampler_cpu);
pxAssert(shader == ShaderConvert::COPY || shader == ShaderConvert::RTA_CORRECTION || rects[0].wmask.wrgba == 0xf);
int rta_bit = (shader == ShaderConvert::RTA_CORRECTION) ? 16 : 0;
SetPipeline((rects[0].wmask.wrgba != 0xf) ? m_color_copy[rects[0].wmask.wrgba | rta_bit].get() :
m_convert[static_cast<int>(shader)].get());
pxAssert(HasVariableWriteMask(shader) || rects[0].wmask.wrgba == 0xf);
SetPipeline((rects[0].wmask.wrgba != 0xf) ?
m_color_copy[GetShaderIndexForMask(shader, rects[0].wmask.wrgba)].get() :
m_convert[static_cast<int>(shader)].get());
if (ApplyUtilityState())
DrawIndexedPrimitive();
@@ -3831,8 +3818,12 @@ GSTexture12* GSDevice12::SetupPrimitiveTrackingDATE(GSHWDrawConfig& config, Pipe
void GSDevice12::RenderHW(GSHWDrawConfig& config)
{
// Destination Alpha Setup
const bool stencil_DATE = (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne);
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;
GSTexture12* colclip_rt = static_cast<GSTexture12*>(g_gs_device->GetColorClipTexture());
GSTexture12* draw_rt = static_cast<GSTexture12*>(config.rt);

View File

@@ -390,6 +390,10 @@ private:
void DestroyResources();
protected:
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) override;
public:
GSDevice12();
~GSDevice12() override;
@@ -428,10 +432,6 @@ public:
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red,
bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) override;
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
PresentShader shader, float shaderTime, bool linear) override;
void UpdateCLUTTexture(

View File

@@ -5769,9 +5769,6 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
m_conf.ps.a_masked = 1;
m_conf.ps.blend_c = 0;
m_conf.require_one_barrier |= true;
// Alpha write is masked, by default this is enabled on vk/gl but not on dx11/12 as copies are slow so we can enable it now since rt alpha is read.
DATE_BARRIER = DATE;
}
else
blend_ad_alpha_masked = false;
@@ -7698,6 +7695,11 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
}
}
// Always swap DATE with DATE_BARRIER if we have barriers on when alpha write is masked.
// This is always enabled on vk/gl but not on dx11/12 as copies are slow so we can selectively enable it like now.
if (DATE && !m_conf.colormask.wa && (m_conf.require_one_barrier || m_conf.require_full_barrier))
DATE_BARRIER = true;
if ((m_conf.ps.tex_is_fb && rt && rt->m_rt_alpha_scale) || (tex && tex->m_from_target && tex->m_target_direct && tex->m_from_target->m_rt_alpha_scale))
m_conf.ps.rta_source_correction = 1;
@@ -7937,7 +7939,8 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
}
else if (DATE_one)
{
if (features.texture_barrier)
const bool multidraw_fb_copy = features.multidraw_fb_copy && (m_conf.require_one_barrier || m_conf.require_full_barrier);
if (features.texture_barrier || multidraw_fb_copy)
{
m_conf.require_one_barrier = true;
m_conf.ps.date = 5 + m_cached_ctx.TEST.DATM;

View File

@@ -2663,8 +2663,10 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
for (auto i = list.begin(); i != list.end(); ++i)
{
Target* t = *i;
const bool half_buffer_match = GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::InsideTargets && TEX0.TBW == t->m_TEX0.TBW && TEX0.PSM == t->m_TEX0.PSM &&
bp == GSLocalMemory::GetStartBlockAddress(t->m_TEX0.TBP0, t->m_TEX0.TBW, t->m_TEX0.PSM, GSVector4i(0, size.y, size.x, size.y + 1));
// Make sure the target is inside the texture
if (t->m_TEX0.TBP0 <= bp && bp <= t->m_end_block && t->Inside(bp, TEX0.TBW, TEX0.PSM, GSVector4i::loadh(size)))
if (t->m_TEX0.TBP0 <= bp && bp <= t->m_end_block && (half_buffer_match || t->Inside(bp, TEX0.TBW, TEX0.PSM, GSVector4i::loadh(size))))
{
if (dst && (GSState::s_n - dst->m_last_draw) < (GSState::s_n - t->m_last_draw))
continue;

View File

@@ -407,8 +407,6 @@ public:
void DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2& ds);
/// Copy from a position in sTex to the same position in the currently active render encoder using the given fs pipeline and rect
void RenderCopy(GSTexture* sTex, id<MTLRenderPipelineState> pipeline, const GSVector4i& rect);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) override;
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, PresentShader shader, float shaderTime, bool linear) override;
void DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvert shader) override;
void UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) override;
@@ -452,6 +450,10 @@ public:
void RenderImGui(ImDrawData* data);
u32 FrameNo() const { return m_frame; }
protected:
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) override;
};
static constexpr bool IsCommandBufferCompleted(MTLCommandBufferStatus status)

View File

@@ -1600,33 +1600,21 @@ void GSDeviceMTL::RenderCopy(GSTexture* sTex, id<MTLRenderPipelineState> pipelin
g_perfmon.Put(GSPerfMon::DrawCalls, 1);
}
void GSDeviceMTL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
void GSDeviceMTL::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear)
{ @autoreleasepool {
pxAssert(linear ? SupportsBilinear(shader) : SupportsNearest(shader));
id<MTLRenderPipelineState> pipeline = m_convert_pipeline[static_cast<int>(shader)];
const LoadAction load_action = (cms.wrgba == 0xf) ? LoadAction::DontCareIfFull : LoadAction::Load;
id<MTLRenderPipelineState> pipeline;
if (HasVariableWriteMask(shader))
pipeline = m_convert_pipeline_copy_mask[GetShaderIndexForMask(shader, cms.wrgba)];
else
pipeline = m_convert_pipeline[static_cast<int>(shader)];
pxAssertRel(pipeline, fmt::format("No pipeline for {}", shaderName(shader)).c_str());
const LoadAction load_action = (ShaderConvertWriteMask(shader) == 0xf) ? LoadAction::DontCareIfFull : LoadAction::Load;
DoStretchRect(sTex, sRect, dTex, dRect, pipeline, linear, load_action, nullptr, 0);
}}
void GSDeviceMTL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader)
{ @autoreleasepool {
int sel = 0;
if (red) sel |= 1;
if (green) sel |= 2;
if (blue) sel |= 4;
if (alpha) sel |= 8;
if (shader == ShaderConvert::RTA_CORRECTION) sel |= 16;
const int color_sel = sel & 15;
id<MTLRenderPipelineState> pipeline = m_convert_pipeline_copy_mask[sel];
DoStretchRect(sTex, sRect, dTex, dRect, pipeline, false, color_sel == 15 ? LoadAction::DontCareIfFull : LoadAction::Load, nullptr, 0);
}}
static_assert(sizeof(DisplayConstantBuffer) == sizeof(GSMTLPresentPSUniform));
static_assert(offsetof(DisplayConstantBuffer, SourceRect) == offsetof(GSMTLPresentPSUniform, source_rect));
static_assert(offsetof(DisplayConstantBuffer, TargetRect) == offsetof(GSMTLPresentPSUniform, target_rect));
@@ -1683,9 +1671,9 @@ void GSDeviceMTL::DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_r
const u32 end = i * 4;
const u32 vertex_count = end - start;
const u32 index_count = vertex_count + (vertex_count >> 1); // 6 indices per 4 vertices
const int rta_bit = shader == ShaderConvert::RTA_CORRECTION ? 16 : 0;
pxAssert(HasVariableWriteMask(shader) || wmask == 0xf);
id<MTLRenderPipelineState> new_pipeline = wmask == 0xf ? m_convert_pipeline[static_cast<int>(shader)]
: m_convert_pipeline_copy_mask[wmask | rta_bit];
: m_convert_pipeline_copy_mask[GetShaderIndexForMask(shader, wmask)];
if (new_pipeline != pipeline)
{
pipeline = new_pipeline;

View File

@@ -1253,7 +1253,7 @@ GSTexture* GSDeviceOGL::InitPrimDateTexture(GSTexture* rt, const GSVector4i& are
return nullptr;
GL_PUSH("PrimID Destination Alpha Clear");
StretchRect(rt, GSVector4(area) / GSVector4(rtsize).xyxy(), tex, GSVector4(area), m_date.primid_ps[static_cast<u8>(datm)], false);
DoStretchRect(rt, GSVector4(area) / GSVector4(rtsize).xyxy(), tex, GSVector4(area), m_date.primid_ps[static_cast<u8>(datm)], false);
return tex;
}
@@ -1472,31 +1472,20 @@ void GSDeviceOGL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r
dTex->SetState(GSTexture::State::Dirty);
}
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
void GSDeviceOGL::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
OMColorMaskSelector cms, ShaderConvert shader, bool linear)
{
pxAssert(dTex->IsDepthStencil() == HasDepthOutput(shader));
pxAssert(linear ? SupportsBilinear(shader) : SupportsNearest(shader));
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[(int)shader], false, OMColorMaskSelector(ShaderConvertWriteMask(shader)), linear);
DoStretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(shader)], false, cms, linear);
}
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool linear)
void GSDeviceOGL::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
const GLProgram& ps, bool linear)
{
StretchRect(sTex, sRect, dTex, dRect, ps, false, OMColorMaskSelector(), linear);
DoStretchRect(sTex, sRect, dTex, dRect, ps, false, OMColorMaskSelector(), linear);
}
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader)
{
OMColorMaskSelector cms;
cms.wr = red;
cms.wg = green;
cms.wb = blue;
cms.wa = alpha;
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[(int)shader], false, cms, false);
}
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool alpha_blend, OMColorMaskSelector cms, bool linear)
void GSDeviceOGL::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
const GLProgram& ps, bool alpha_blend, OMColorMaskSelector cms, bool linear)
{
CommitClear(sTex, true);
@@ -1816,12 +1805,12 @@ void GSDeviceOGL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
// Blend with a constant alpha
m_merge_obj.ps[1].Bind();
m_merge_obj.ps[1].Uniform4fv(0, GSVector4::unorm8(c).v);
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[1], true, OMColorMaskSelector(), linear);
DoStretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[1], true, OMColorMaskSelector(), linear);
}
else
{
// Blend with 2 * input alpha
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[0], true, OMColorMaskSelector(), linear);
DoStretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[0], true, OMColorMaskSelector(), linear);
}
}
@@ -1836,7 +1825,7 @@ void GSDeviceOGL::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture
m_interlace.ps[static_cast<int>(shader)].Bind();
m_interlace.ps[static_cast<int>(shader)].Uniform4fv(0, cb.ZrH.F32);
StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[static_cast<int>(shader)], linear);
DoStretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[static_cast<int>(shader)], linear);
}
bool GSDeviceOGL::CompileFXAAProgram()
@@ -1875,7 +1864,7 @@ void GSDeviceOGL::DoFXAA(GSTexture* sTex, GSTexture* dTex)
const GSVector4 sRect(0, 0, 1, 1);
const GSVector4 dRect(0, 0, s.x, s.y);
StretchRect(sTex, sRect, dTex, dRect, m_fxaa.ps, true);
DoStretchRect(sTex, sRect, dTex, dRect, m_fxaa.ps, true);
}
bool GSDeviceOGL::CompileShadeBoostProgram()
@@ -1909,10 +1898,10 @@ void GSDeviceOGL::DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float par
const GSVector4 sRect(0, 0, 1, 1);
const GSVector4 dRect(0, 0, s.x, s.y);
StretchRect(sTex, sRect, dTex, dRect, m_shadeboost.ps, false);
DoStretchRect(sTex, sRect, dTex, dRect, m_shadeboost.ps, false);
}
void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, SetDATM datm)
void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSVector4i& bbox)
{
GL_PUSH("DATE First Pass");
@@ -1933,6 +1922,17 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
// ia
const GSVector4 src = GSVector4(bbox) / GSVector4(ds->GetSize()).xyxy();
const GSVector4 dst = src * 2.f - 1.f;
const GSVertexPT1 vertices[] =
{
{GSVector4(dst.x, dst.y, 0.0f, 0.0f), GSVector2(src.x, src.y)},
{GSVector4(dst.z, dst.y, 0.0f, 0.0f), GSVector2(src.z, src.y)},
{GSVector4(dst.x, dst.w, 0.0f, 0.0f), GSVector2(src.x, src.w)},
{GSVector4(dst.z, dst.w, 0.0f, 0.0f), GSVector2(src.z, src.w)},
};
IASetVAO(m_vao);
IASetVertexBuffer(vertices, 4);
IASetPrimitiveTopology(GL_TRIANGLE_STRIP);
@@ -2490,18 +2490,8 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
}
[[fallthrough]];
case GSHWDrawConfig::DestinationAlphaMode::Stencil:
{
const GSVector4 src = GSVector4(config.drawarea) / GSVector4(config.ds->GetSize()).xyxy();
const GSVector4 dst = src * 2.f - 1.f;
GSVertexPT1 vertices[] =
{
{GSVector4(dst.x, dst.y, 0.0f, 0.0f), GSVector2(src.x, src.y)},
{GSVector4(dst.z, dst.y, 0.0f, 0.0f), GSVector2(src.z, src.y)},
{GSVector4(dst.x, dst.w, 0.0f, 0.0f), GSVector2(src.x, src.w)},
{GSVector4(dst.z, dst.w, 0.0f, 0.0f), GSVector2(src.z, src.w)},
};
SetupDATE(colclip_rt ? colclip_rt : config.rt, config.ds, vertices, config.datm);
}
SetupDATE(colclip_rt ? colclip_rt : config.rt, config.ds, config.datm, config.drawarea);
break;
}
GSTexture* draw_rt_clone = nullptr;

View File

@@ -265,6 +265,10 @@ private:
void DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds);
protected:
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) override;
public:
GSDeviceOGL();
virtual ~GSDeviceOGL();
@@ -317,10 +321,8 @@ public:
// BlitRect *does* mess with GL state, be sure to re-bind.
void BlitRect(GSTexture* sTex, const GSVector4i& r, const GSVector2i& dsize, bool at_origin, bool linear);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool linear = true);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) override;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool alpha_blend, OMColorMaskSelector cms, bool linear = true);
void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool linear);
void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool alpha_blend, OMColorMaskSelector cms, bool linear);
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, PresentShader shader, float shaderTime, bool linear) override;
void UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) override;
void ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM) override;
@@ -332,7 +334,7 @@ public:
void RenderHW(GSHWDrawConfig& config) override;
void SendHWDraw(const GSHWDrawConfig& config, bool one_barrier, bool full_barrier);
void SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, SetDATM datm);
void SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSVector4i& bbox);
void IASetVAO(GLuint vao);
void IASetPrimitiveTopology(GLenum topology);

View File

@@ -323,10 +323,11 @@ void GSDrawScanline::CSetupPrim(const GSVertexSW* vertex, const u16* index, cons
{
if (sel.iip)
{
constexpr VectorI mask16 = VectorI::cxpr(0xFFFF);
#if _M_SSE >= 0x501
GSVector4i::storel(&local.d8.c, GSVector4i(dscan.c * step_shift).xzyw().ps32());
GSVector4i::storel(&local.d8.c, (GSVector4i(dscan.c * step_shift) & GSVector4i::cast(mask16)).xzyw().pu32());
#else
local.d4.c = GSVector4i(dscan.c * step_shift).xzyw().ps32();
local.d4.c = (GSVector4i(dscan.c * step_shift) & mask16).xzyw().pu32();
#endif
VectorF dc(dscan.c);
@@ -335,8 +336,8 @@ void GSDrawScanline::CSetupPrim(const GSVertexSW* vertex, const u16* index, cons
for (int i = 0; i < vlen; i++)
{
VectorI r = VectorI(dr * shift[1 + i]).ps32();
VectorI b = VectorI(db * shift[1 + i]).ps32();
VectorI r = (VectorI(dr * shift[1 + i]) & mask16).pu32();
VectorI b = (VectorI(db * shift[1 + i]) & mask16).pu32();
local.d[i].rb = r.upl16(b);
}
@@ -346,8 +347,8 @@ void GSDrawScanline::CSetupPrim(const GSVertexSW* vertex, const u16* index, cons
for (int i = 0; i < vlen; i++)
{
VectorI g = VectorI(dg * shift[1 + i]).ps32();
VectorI a = VectorI(da * shift[1 + i]).ps32();
VectorI g = (VectorI(dg * shift[1 + i]) & mask16).pu32();
VectorI a = (VectorI(da * shift[1 + i]) & mask16).pu32();
local.d[i].ga = g.upl16(a);
}

View File

@@ -1549,7 +1549,7 @@ void GSRasterizerList::Queue(const GSRingHeap::SharedPtr<GSRasterizerData>& data
pxAssert(r.top >= 0 && r.top < 2048 && r.bottom >= 0 && r.bottom < 2048);
int top = r.top >> m_thread_height;
int bottom = std::min<int>((r.bottom + (1 << m_thread_height) - 1) >> m_thread_height, top + m_workers.size());
int bottom = std::min<int>((r.bottom + (1 << m_thread_height) - 1) >> m_thread_height, top + (int)m_workers.size());
while (top < bottom)
{

View File

@@ -1652,7 +1652,7 @@ void GSRendererSW::SharedData::UpdateSource()
std::string s;
for (size_t i = 0; m_tex[i].t; i++)
for (u32 i = 0; m_tex[i].t; i++)
{
const GIFRegTEX0& TEX0 = g_gs_renderer->GetTex0Layer(i);

View File

@@ -89,7 +89,7 @@ void GSSetupPrimCodeGenerator::Generate()
many_regs = isYmm && !m_sel.notest && needs_shift;
#ifdef _WIN64
int needs_saving = many_regs ? 6 : m_sel.notest ? 0 : 2;
int needs_saving = many_regs ? 7 : m_sel.notest ? 1 : 3;
if (needs_saving)
{
sub(rsp, 8 + 16 * needs_saving);
@@ -398,12 +398,17 @@ void GSSetupPrimCodeGenerator::Color()
broadcastf128(xym0, ptr[_dscan + offsetof(GSVertexSW, c)]);
// m_local.d4.c = GSVector4i(c * 4.0f).xzyw().ps32();
// constexpr VectorI mask16 = VectorI::cxpr(0xFFFF);
XYm mask16 = XYm(many_regs ? 12 : m_sel.notest ? 6 : 8);
pcmpeqd(mask16, mask16);
psrld(mask16, 16);
// local.d4.c = (GSVector4i(dscan.c * step_shift) & mask16).xzyw().pu32();
THREEARG(mulps, xmm1, xmm0, xmm3);
cvttps2dq(xmm1, xmm1);
pshufd(xmm1, xmm1, _MM_SHUFFLE(3, 1, 2, 0));
packssdw(xmm1, xmm1);
pand(xym1, mask16);
packusdw(xmm1, xmm1);
if (isXmm)
movdqa(_rip_local_d(c), xmm1);
else
@@ -419,23 +424,25 @@ void GSSetupPrimCodeGenerator::Color()
for (int i = 0; i < (m_sel.notest ? 1 : dsize); i++)
{
// GSVector4i r = GSVector4i(dr * m_shift[i]).ps32();
// VectorI r = (VectorI(dr * shift[1 + i]) & mask16).pu32();
if (i < 4 || many_regs)
THREEARG(mulps, xym0, XYm(4 + i), xym2);
else
vmulps(ymm0, ymm2, ptr[g_const.m_shift_256b[i + 1]]);
cvttps2dq(xym0, xym0);
packssdw(xym0, xym0);
pand(xym0, mask16);
packusdw(xym0, xym0);
// GSVector4i b = GSVector4i(db * m_shift[i]).ps32();
// VectorI b = (VectorI(db * shift[1 + i]) & mask16).pu32();
if (i < 4 || many_regs)
THREEARG(mulps, xym1, XYm(4 + i), xym3);
else
vmulps(ymm1, ymm3, ptr[g_const.m_shift_256b[i + 1]]);
cvttps2dq(xym1, xym1);
packssdw(xym1, xym1);
pand(xym1, mask16);
packusdw(xym1, xym1);
// m_local.d[i].rb = r.upl16(b);
@@ -455,23 +462,25 @@ void GSSetupPrimCodeGenerator::Color()
for (int i = 0; i < (m_sel.notest ? 1 : dsize); i++)
{
// GSVector4i g = GSVector4i(dg * m_shift[i]).ps32();
// VectorI g = (VectorI(dg * shift[1 + i]) & mask16).pu32();
if (i < 4 || many_regs)
THREEARG(mulps, xym0, XYm(4 + i), xym2);
else
vmulps(ymm0, ymm2, ptr[g_const.m_shift_256b[i + 1]]);
cvttps2dq(xym0, xym0);
packssdw(xym0, xym0);
pand(xym0, mask16);
packusdw(xym0, xym1);
// GSVector4i a = GSVector4i(da * m_shift[i]).ps32();
// VectorI a = (VectorI(da * shift[1 + i]) & mask16).pu32();
if (i < 4 || many_regs)
THREEARG(mulps, xym1, XYm(4 + i), xym3);
else
vmulps(ymm1, ymm3, ptr[g_const.m_shift_256b[i + 1]]);
cvttps2dq(xym1, xym1);
packssdw(xym1, xym1);
pand(xym1, mask16);
packusdw(xym1, xym1);
// m_local.d[i].ga = g.upl16(a);

View File

@@ -225,14 +225,13 @@ void GSSetupPrimCodeGenerator::Color()
// GSVector4 c = dscan.c;
armAsm->Ldr(v16, MemOperand(_dscan, offsetof(GSVertexSW, c)));
// m_local.d4.c = GSVector4i(c * 4.0f).xzyw().ps32();
// GSVector4i tmp = GSVector4i(dscan.c * step_shift).xzyw();
// local.d4.c = tmp.uzp1_16(tmp); // Not currently in GSVector since that's mainly targeting x86 for now
armAsm->Fmul(v2.V4S(), v16.V4S(), v3.V4S());
armAsm->Fcvtzs(v2.V4S(), v2.V4S());
armAsm->Rev64(_vscratch.V4S(), v2.V4S());
armAsm->Uzp1(v2.V4S(), v2.V4S(), _vscratch.V4S());
armAsm->Sqxtn(v2.V4H(), v2.V4S());
armAsm->Dup(v2.V2D(), v2.V2D(), 0);
armAsm->Uzp1(v2.V8H(), v2.V8H(), v2.V8H());
armAsm->Str(v2, MemOperand(_locals, offsetof(GSScanlineLocalData, d4.c)));
// GSVector4 dr = c.xxxx();
@@ -243,23 +242,18 @@ void GSSetupPrimCodeGenerator::Color()
for (int i = 0; i < (m_sel.notest ? 1 : 4); i++)
{
// GSVector4i r = GSVector4i(dr * m_shift[i]).ps32();
// VectorI r = VectorI(dr * shift[1 + i]);
armAsm->Fmul(v2.V4S(), v0.V4S(), VRegister(4 + i, kFormat4S));
armAsm->Fcvtzs(v2.V4S(), v2.V4S());
armAsm->Sqxtn(v2.V4H(), v2.V4S());
armAsm->Dup(v2.V2D(), v2.V2D(), 0);
// GSVector4i b = GSVector4i(db * m_shift[i]).ps32();
// VectorI b = VectorI(db * shift[1 + i]);
armAsm->Fmul(v3.V4S(), v1.V4S(), VRegister(4 + i, kFormat4S));
armAsm->Fcvtzs(v3.V4S(), v3.V4S());
armAsm->Sqxtn(v3.V4H(), v3.V4S());
armAsm->Dup(v3.V2D(), v3.V2D(), 0);
// m_local.d[i].rb = r.upl16(b);
armAsm->Zip1(v2.V8H(), v2.V8H(), v3.V8H());
// m_local.d[i].rb = r.trn1_16(b); // Not currently in GSVector since that's mainly targeting x86 for now
armAsm->Trn1(v2.V8H(), v2.V8H(), v3.V8H());
armAsm->Str(v2, _local(d[i].rb));
}
@@ -273,23 +267,19 @@ void GSSetupPrimCodeGenerator::Color()
for (int i = 0; i < (m_sel.notest ? 1 : 4); i++)
{
// GSVector4i g = GSVector4i(dg * m_shift[i]).ps32();
// VectorI g = VectorI(dg * shift[1 + i]);
armAsm->Fmul(v2.V4S(), v0.V4S(), VRegister(4 + i, kFormat4S));
armAsm->Fcvtzs(v2.V4S(), v2.V4S());
armAsm->Sqxtn(v2.V4H(), v2.V4S());
armAsm->Dup(v2.V2D(), v2.V2D(), 0);
// GSVector4i a = GSVector4i(da * m_shift[i]).ps32();
// VectorI a = VectorI(da * shift[1 + i]);
armAsm->Fmul(v3.V4S(), v1.V4S(), VRegister(4 + i, kFormat4S));
armAsm->Fcvtzs(v3.V4S(), v3.V4S());
armAsm->Sqxtn(v3.V4H(), v3.V4S());
armAsm->Dup(v3.V2D(), v3.V2D(), 0);
// m_local.d[i].ga = g.upl16(a);
// m_local.d[i].ga = g.trn1_16(a); // Not currently in GSVector since that's mainly targeting x86 for now
armAsm->Zip1(v2.V8H(), v2.V8H(), v3.V8H());
armAsm->Trn1(v2.V8H(), v2.V8H(), v3.V8H());
armAsm->Str(v2, _local(d[i].ga));
}
}

View File

@@ -2821,31 +2821,16 @@ void GSDeviceVK::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
dTexVK->SetState(GSTexture::State::Dirty);
}
void GSDeviceVK::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
ShaderConvert shader /* = ShaderConvert::COPY */, bool linear /* = true */)
void GSDeviceVK::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear)
{
pxAssert(HasDepthOutput(shader) == (dTex && dTex->GetType() == GSTexture::Type::DepthStencil));
pxAssert(linear ? SupportsBilinear(shader) : SupportsNearest(shader));
GL_INS("StretchRect(%d) {%d,%d} %dx%d -> {%d,%d) %dx%d", shader, int(sRect.left), int(sRect.top),
int(sRect.right - sRect.left), int(sRect.bottom - sRect.top), int(dRect.left), int(dRect.top),
int(dRect.right - dRect.left), int(dRect.bottom - dRect.top));
DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect,
dTex ? m_convert[static_cast<int>(shader)] : m_present[static_cast<int>(shader)], linear,
ShaderConvertWriteMask(shader) == 0xf);
}
void GSDeviceVK::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red,
bool green, bool blue, bool alpha, ShaderConvert shader)
{
GL_PUSH("ColorCopy Red:%d Green:%d Blue:%d Alpha:%d", red, green, blue, alpha);
const u32 index = (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0);
const bool allow_discard = (index == 0xf);
int rta_offset = (shader == ShaderConvert::RTA_CORRECTION) ? 16 : 0;
DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect, m_color_copy[index + rta_offset],
false, allow_discard);
const bool allow_discard = (cms.wrgba == 0xf);
VkPipeline state;
if (HasVariableWriteMask(shader))
state = m_color_copy[GetShaderIndexForMask(shader, cms.wrgba)];
else
state = dTex ? m_convert[static_cast<int>(shader)] : m_present[static_cast<int>(shader)];
DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect, state, linear, allow_discard);
}
void GSDeviceVK::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
@@ -2967,10 +2952,10 @@ void GSDeviceVK::DoMultiStretchRects(
BeginRenderPassForStretchRect(dTex, rc, rc, false);
SetUtilityTexture(rects[0].src, rects[0].linear ? m_linear_sampler : m_point_sampler);
pxAssert(shader == ShaderConvert::COPY || shader == ShaderConvert::RTA_CORRECTION || rects[0].wmask.wrgba == 0xf);
int rta_bit = (shader == ShaderConvert::RTA_CORRECTION) ? 16 : 0;
SetPipeline(
(rects[0].wmask.wrgba != 0xf) ? m_color_copy[rects[0].wmask.wrgba | rta_bit] : m_convert[static_cast<int>(shader)]);
pxAssert(HasVariableWriteMask(shader) || rects[0].wmask.wrgba == 0xf);
SetPipeline((rects[0].wmask.wrgba != 0xf) ?
m_color_copy[GetShaderIndexForMask(shader, rects[0].wmask.wrgba)] :
m_convert[static_cast<int>(shader)]);
if (ApplyUtilityState())
DrawIndexedPrimitive();

View File

@@ -470,6 +470,10 @@ private:
void DestroyResources();
protected:
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) override;
public:
GSDeviceVK();
~GSDeviceVK() override;
@@ -525,10 +529,6 @@ public:
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red,
bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) override;
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
PresentShader shader, float shaderTime, bool linear) override;
void DrawMultiStretchRects(

View File

@@ -521,7 +521,7 @@ struct Gif_Path
// GS Packets that MTGS hasn't yet processed
u32 GetPendingGSPackets()
{
return mtvu.gsPackQueue.size();
return (u32)mtvu.gsPackQueue.size();
}
};

View File

@@ -14,6 +14,7 @@
#include "SIO/Memcard/MemoryCardFile.h"
#include "common/Assertions.h"
#include "common/Error.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/Timer.h"
@@ -103,7 +104,10 @@ static void HotkeyLoadStateSlot(s32 slot)
return;
}
VMManager::LoadStateFromSlot(slot);
Error error;
if (!VMManager::LoadStateFromSlot(slot, false, &error))
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_TRIANGLE_EXCLAMATION,
error.GetDescription(), Host::OSD_INFO_DURATION);
});
}

View File

@@ -6866,6 +6866,46 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
BeginMenuButtons(submenu_item_count[static_cast<u32>(s_current_pause_submenu)], 1.0f, ImGuiFullscreen::LAYOUT_MENU_BUTTON_X_PADDING,
ImGuiFullscreen::LAYOUT_MENU_BUTTON_Y_PADDING, ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY);
if (!ImGui::IsPopupOpen(0u, ImGuiPopupFlags_AnyPopup))
{
const bool up_pressed = ImGui::IsKeyPressed(ImGuiKey_GamepadDpadUp, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner) ||
ImGui::IsKeyPressed(ImGuiKey_UpArrow, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner);
const bool down_pressed = ImGui::IsKeyPressed(ImGuiKey_GamepadDpadDown, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner) ||
ImGui::IsKeyPressed(ImGuiKey_DownArrow, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner);
if (up_pressed || down_pressed)
{
const ImGuiID current_focus_id = ImGui::GetFocusID();
ImGuiWindow* window = ImGui::GetCurrentWindow();
ImGuiID first_id = 0;
ImGuiID last_id = 0;
switch (s_current_pause_submenu)
{
case PauseSubMenu::None:
first_id = ImGui::GetID(FSUI_ICONSTR(ICON_FA_PLAY, "Resume Game"));
last_id = ImGui::GetID(FSUI_ICONSTR(ICON_FA_POWER_OFF, "Close Game"));
break;
case PauseSubMenu::Exit:
first_id = ImGui::GetID(FSUI_ICONSTR(ICON_PF_BACKWARD, "Back To Pause Menu"));
last_id = ImGui::GetID(FSUI_ICONSTR(ICON_FA_POWER_OFF, "Exit Without Saving"));
break;
case PauseSubMenu::Achievements:
first_id = ImGui::GetID(FSUI_ICONSTR(ICON_PF_BACKWARD, "Back To Pause Menu"));
last_id = ImGui::GetID(FSUI_ICONSTR(ICON_FA_STOPWATCH, "Leaderboards"));
break;
}
if (first_id != 0 && last_id != 0)
{
if (up_pressed && current_focus_id == first_id)
ImGui::SetFocusID(last_id, window);
else if (down_pressed && current_focus_id == last_id)
ImGui::SetFocusID(first_id, window);
}
}
}
switch (s_current_pause_submenu)
{
case PauseSubMenu::None:
@@ -7562,65 +7602,17 @@ void FullscreenUI::DrawResumeStateSelector()
void FullscreenUI::DoLoadState(std::string path)
{
// Check for hardcore mode before loading state
if (Achievements::IsHardcoreModeActive())
{
Achievements::ConfirmHardcoreModeDisableAsync(TRANSLATE("VMManager", "Loading state"),
[path = std::move(path)](bool approved) {
if (approved)
DoLoadState(std::move(path));
});
return;
}
const std::string filename = std::string(Path::GetFileName(path));
s32 slot = -1;
bool is_backup = false;
std::string base_filename = filename;
if (filename.length() > 7 && filename.substr(filename.length() - 7) == ".backup")
{
is_backup = true;
base_filename = filename.substr(0, filename.length() - 7);
}
// Get slot number from filename (format: serial.crc.slot.p2s)
const size_t last_dot = base_filename.rfind('.');
const size_t second_last_dot = base_filename.rfind('.', last_dot - 1);
if (last_dot != std::string::npos && second_last_dot != std::string::npos)
{
const std::string slot_str = base_filename.substr(second_last_dot + 1, last_dot - second_last_dot - 1);
if (!slot_str.empty())
slot = std::atoi(slot_str.c_str());
}
const std::string message = (slot >= 0) ?
fmt::format(TRANSLATE_FS("VMManager", "Loading {} from slot {}..."), is_backup ? TRANSLATE("VMManager", "backup state") : TRANSLATE("VMManager", "state"), slot) :
TRANSLATE_STR("VMManager", "Loading save state...");
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_FOLDER_OPEN, message, Host::OSD_QUICK_DURATION);
Host::RunOnCPUThread([path = std::move(path)]()
{
const std::string boot_path = s_save_state_selector_game_path;
Host::RunOnCPUThread([boot_path = s_save_state_selector_game_path, path = std::move(path)]() {
if (VMManager::HasValidVM())
{
Error error;
if (!SaveState_UnzipFromDisk(path, &error))
if (!VMManager::LoadState(path.c_str(), &error))
{
if (error.GetDescription().find("outdated") != std::string::npos)
{
Host::RunOnCPUThread([error_desc = error.GetDescription()]()
{
ImGuiFullscreen::OpenInfoMessageDialog(
FSUI_ICONSTR(ICON_FA_TRIANGLE_EXCLAMATION, "Incompatible Save State"),
error_desc);
});
}
else
{
Host::ReportErrorAsync(TRANSLATE_SV("VMManager", "Failed to load save state"), error.GetDescription());
}
MTGS::RunOnGSThread([error = std::move(error)]() {
ImGuiFullscreen::OpenInfoMessageDialog(
FSUI_ICONSTR(ICON_FA_TRIANGLE_EXCLAMATION, "Failed to Load State"),
error.GetDescription());
});
return;
}
@@ -10113,6 +10105,10 @@ TRANSLATE_NOOP("FullscreenUI", "Compression Method");
TRANSLATE_NOOP("FullscreenUI", "Compression Level");
TRANSLATE_NOOP("FullscreenUI", "Use Debug Device");
TRANSLATE_NOOP("FullscreenUI", "Resume Game");
TRANSLATE_NOOP("FullscreenUI", "Close Game");
TRANSLATE_NOOP("FullscreenUI", "Back To Pause Menu");
TRANSLATE_NOOP("FullscreenUI", "Exit Without Saving");
TRANSLATE_NOOP("FullscreenUI", "Leaderboards");
TRANSLATE_NOOP("FullscreenUI", "Toggle Frame Limit");
TRANSLATE_NOOP("FullscreenUI", "Game Properties");
TRANSLATE_NOOP("FullscreenUI", "Achievements");
@@ -10120,11 +10116,7 @@ TRANSLATE_NOOP("FullscreenUI", "Save Screenshot");
TRANSLATE_NOOP("FullscreenUI", "Switch To Software Renderer");
TRANSLATE_NOOP("FullscreenUI", "Switch To Hardware Renderer");
TRANSLATE_NOOP("FullscreenUI", "Change Disc");
TRANSLATE_NOOP("FullscreenUI", "Close Game");
TRANSLATE_NOOP("FullscreenUI", "Exit Without Saving");
TRANSLATE_NOOP("FullscreenUI", "Back To Pause Menu");
TRANSLATE_NOOP("FullscreenUI", "Exit And Save State");
TRANSLATE_NOOP("FullscreenUI", "Leaderboards");
TRANSLATE_NOOP("FullscreenUI", "Delete Save");
TRANSLATE_NOOP("FullscreenUI", "Close Menu");
TRANSLATE_NOOP("FullscreenUI", "Default Boot");

View File

@@ -28,6 +28,7 @@
#include "VMManager.h"
#include "common/BitUtils.h"
#include "common/Error.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
@@ -622,7 +623,7 @@ __ri void ImGuiManager::DrawSettingsOverlay(float scale, float margin, float spa
else
APPEND("IR={} ", static_cast<unsigned>(GSConfig.UpscaleMultiplier));
APPEND("B={} PL={} ", static_cast<unsigned>(GSConfig.AccurateBlendingUnit), static_cast<unsigned>(GSConfig.TexturePreloading));
APPEND("BL={} TPL={} ", static_cast<unsigned>(GSConfig.AccurateBlendingUnit), static_cast<unsigned>(GSConfig.TexturePreloading));
if (GSConfig.GPUPaletteConversion)
APPEND("PLTX ");
@@ -1325,7 +1326,10 @@ s32 SaveStateSelectorUI::GetCurrentSlot()
void SaveStateSelectorUI::LoadCurrentSlot()
{
Host::RunOnCPUThread([slot = GetCurrentSlot()]() {
VMManager::LoadStateFromSlot(slot);
Error error;
if (!VMManager::LoadStateFromSlot(slot, false, &error))
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_TRIANGLE_EXCLAMATION,
error.GetDescription(), Host::OSD_INFO_DURATION);
});
Close();
}
@@ -1333,7 +1337,10 @@ void SaveStateSelectorUI::LoadCurrentSlot()
void SaveStateSelectorUI::LoadCurrentBackupSlot()
{
Host::RunOnCPUThread([slot = GetCurrentSlot()]() {
VMManager::LoadStateFromSlot(slot, true);
Error error;
if (!VMManager::LoadStateFromSlot(slot, true, &error))
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_TRIANGLE_EXCLAMATION,
error.GetDescription(), Host::OSD_INFO_DURATION);
});
Close();
}

View File

@@ -44,39 +44,39 @@
typedef struct
{
unsigned int mode;
unsigned int attr;
unsigned int size;
unsigned char ctime[8];
unsigned char atime[8];
unsigned char mtime[8];
unsigned int hisize;
u32 mode;
u32 attr;
u32 size;
u8 ctime[8];
u8 atime[8];
u8 mtime[8];
u32 hisize;
} fio_stat_t;
typedef struct
{
fio_stat_t _fioStat;
/** Number of subs (main) / subpart number (sub) */
unsigned int private_0;
unsigned int private_1;
unsigned int private_2;
unsigned int private_3;
unsigned int private_4;
u32 private_0;
u32 private_1;
u32 private_2;
u32 private_3;
u32 private_4;
/** Sector start. */
unsigned int private_5;
u32 private_5;
} fxio_stat_t;
typedef struct
{
fio_stat_t stat;
char name[256];
unsigned int unknown;
u32 unknown;
} fio_dirent_t;
typedef struct
{
fxio_stat_t stat;
char name[256];
unsigned int unknown;
u32 unknown;
} fxio_dirent_t;
static std::string hostRoot;
@@ -171,7 +171,7 @@ namespace R3000A
if (!FileSystem::StatFile(file_path.c_str(), &file_stats))
return -IOP_ENOENT;
host_stats->size = file_stats.st_size;
host_stats->size = (u32)file_stats.st_size;
host_stats->hisize = 0;
// Convert the mode.
@@ -315,13 +315,13 @@ namespace R3000A
switch (whence)
{
case IOP_SEEK_SET:
err = ::lseek(fd, offset, SEEK_SET);
err = static_cast<int>(::lseek(fd, offset, SEEK_SET));
break;
case IOP_SEEK_CUR:
err = ::lseek(fd, offset, SEEK_CUR);
err = static_cast<int>(::lseek(fd, offset, SEEK_CUR));
break;
case IOP_SEEK_END:
err = ::lseek(fd, offset, SEEK_END);
err = static_cast<int>(::lseek(fd, offset, SEEK_END));
break;
default:
return -IOP_EIO;
@@ -332,12 +332,12 @@ namespace R3000A
virtual int read(void* buf, u32 count) /* Flawfinder: ignore */
{
return translate_error(::read(fd, buf, count));
return translate_error(static_cast<int>(::read(fd, buf, count)));
}
virtual int write(void* buf, u32 count)
{
return translate_error(::write(fd, buf, count));
return translate_error(static_cast<int>(::write(fd, buf, count)));
}
};
@@ -762,7 +762,7 @@ namespace R3000A
v0 = host_stat(full_path, (fxio_stat_t*)&buf);
for (size_t i = 0; i < sizeof(fxio_stat_t); i++)
iopMemWrite8(data + i, buf[i]);
iopMemWrite8(static_cast<u32>(data + i), buf[i]);
}
else
{
@@ -770,7 +770,7 @@ namespace R3000A
v0 = host_stat(full_path, (fio_stat_t*)&buf);
for (size_t i = 0; i < sizeof(fio_stat_t); i++)
iopMemWrite8(data + i, buf[i]);
iopMemWrite8(static_cast<u32>(data + i), buf[i]);
}
pc = ra;
return 1;

View File

@@ -186,7 +186,7 @@ void VU_Thread::ExecuteRingBuffer()
break;
case MTVU_VIF_UNPACK:
{
u32 vif_copy_size = (uptr)&vif.StructEnd - (uptr)&vif.tag;
u32 vif_copy_size = static_cast<u32>((uptr)&vif.StructEnd - (uptr)&vif.tag);
Read(&vif.tag, vif_copy_size);
ReadRegs(&vifRegs);
u32 size = Read();
@@ -467,7 +467,7 @@ void VU_Thread::ExecuteVU(u32 vu_addr, u32 vif_top, u32 vif_itop, u32 fbrst)
void VU_Thread::VifUnpack(vifStruct& _vif, VIFregisters& _vifRegs, const u8* data, u32 size)
{
MTVU_LOG("MTVU - VifUnpack!");
u32 vif_copy_size = (uptr)&_vif.StructEnd - (uptr)&_vif.tag;
u32 vif_copy_size = (u32)((uptr)&_vif.StructEnd - (uptr)&_vif.tag);
ReserveSpace(1 + size_u32(vif_copy_size) + size_u32(sizeof(VIFregistersMTVU)) + 1 + size_u32(size));
Write(MTVU_VIF_UNPACK);
Write(&_vif.tag, vif_copy_size);

View File

@@ -8,6 +8,7 @@
#include "Elfheader.h"
#include "PINE.h"
#include "VMManager.h"
#include "common/Error.h"
#include "common/Threading.h"
#include <atomic>
@@ -18,6 +19,7 @@
#include <thread>
#include "fmt/format.h"
#include "IconsFontAwesome6.h"
#if defined(_WIN32)
#define read_portable(a, b, c) (recv(a, (char*)b, c, 0))
@@ -654,7 +656,12 @@ PINEServer::IPCBuffer PINEServer::ParseCommand(std::span<u8> buf, std::vector<u8
goto error;
if (!SafetyChecks(buf_cnt, 1, ret_cnt, 0, buf_size)) [[unlikely]]
goto error;
Host::RunOnCPUThread([slot = FromSpan<u8>(buf, buf_cnt)] { VMManager::LoadStateFromSlot(slot); });
Host::RunOnCPUThread([slot = FromSpan<u8>(buf, buf_cnt)] {
Error state_error;
if (!VMManager::LoadStateFromSlot(slot, false, &state_error))
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_TRIANGLE_EXCLAMATION,
state_error.GetDescription(), Host::OSD_INFO_DURATION);
});
buf_cnt += 1;
break;
}

View File

@@ -1844,6 +1844,7 @@ bool Pcsx2Config::PadOptions::Port::operator!=(const PadOptions::Port& right) co
Pcsx2Config::AchievementsOptions::AchievementsOptions()
{
bitset = 0;
Enabled = false;
HardcoreMode = false;
EncoreMode = false;

View File

@@ -66,12 +66,12 @@ const std::string& InputRecordingFile::getFilename() const noexcept
return m_filename;
}
unsigned long InputRecordingFile::getTotalFrames() const noexcept
u32 InputRecordingFile::getTotalFrames() const noexcept
{
return m_totalFrames;
}
unsigned long InputRecordingFile::getUndoCount() const noexcept
u32 InputRecordingFile::getUndoCount() const noexcept
{
return m_undoCount;
}
@@ -237,7 +237,7 @@ std::vector<PadData> InputRecordingFile::bulkReadPadData(u32 frameStart, u32 fra
}
// TODO - no multi-tap support
for (uint64_t currFrame = frameStart; currFrame < frameEnd; currFrame++)
for (u32 currFrame = frameStart; currFrame < frameEnd; currFrame++)
{
const auto padData = readPadData(currFrame, port, 0);
if (padData)

View File

@@ -68,8 +68,8 @@ public:
// Retrieve the input recording's filename (not the path)
const std::string& getFilename() const noexcept;
unsigned long getTotalFrames() const noexcept;
unsigned long getUndoCount() const noexcept;
u32 getTotalFrames() const noexcept;
u32 getUndoCount() const noexcept;
void logRecordingMetadata();
std::vector<PadData> bulkReadPadData(u32 frameStart, u32 frameEnd, const uint port);
@@ -92,8 +92,8 @@ private:
bool m_savestate = false;
// An signed 32-bit frame limit is equivalent to 1.13 years of continuous 60fps footage
unsigned long m_totalFrames = 0;
unsigned long m_undoCount = 0;
u32 m_totalFrames = 0;
u32 m_undoCount = 0;
// Calculates the position of the current frame in the input recording
size_t getRecordingBlockSeekPoint(const u32 frame) const noexcept;

View File

@@ -114,7 +114,7 @@ namespace VMManager
static void PrecacheCDVDFile();
static std::string GetCurrentSaveStateFileName(s32 slot, bool backup = false);
static bool DoLoadState(const char* filename);
static bool DoLoadState(const char* filename, Error* error = nullptr);
static bool DoSaveState(const char* filename, s32 slot_for_message, bool zip_on_thread, bool backup_old_state);
static void ZipSaveState(std::unique_ptr<ArchiveEntryList> elist,
std::unique_ptr<SaveStateScreenshotData> screenshot, std::string osd_key, const char* filename,
@@ -1589,8 +1589,10 @@ bool VMManager::Initialize(VMBootParameters boot_params)
// do we want to load state?
if (!GSDumpReplayer::IsReplayingDump() && !state_to_load.empty())
{
if (!DoLoadState(state_to_load.c_str()))
Error state_error;
if (!DoLoadState(state_to_load.c_str(), &state_error))
{
Host::ReportErrorAsync(TRANSLATE_SV("VMManager", "Failed to load save state."), state_error.GetDescription());
Shutdown(false);
return false;
}
@@ -1824,19 +1826,18 @@ std::string VMManager::GetCurrentSaveStateFileName(s32 slot, bool backup)
return GetSaveStateFileName(s_disc_serial.c_str(), s_disc_crc, slot, backup);
}
bool VMManager::DoLoadState(const char* filename)
bool VMManager::DoLoadState(const char* filename, Error* error)
{
if (GSDumpReplayer::IsReplayingDump())
{
Error::SetString(error, TRANSLATE_STR("VMManager", "Cannot load save state while replaying GS dump."));
return false;
}
Host::OnSaveStateLoading(filename);
Error error;
if (!SaveState_UnzipFromDisk(filename, &error))
{
Host::ReportErrorAsync(TRANSLATE_SV("VMManager", "Failed to load save state"), error.GetDescription());
if (!SaveState_UnzipFromDisk(filename, error))
return false;
}
Host::OnSaveStateLoaded(filename, true);
if (g_InputRecording.isActive())
@@ -1980,62 +1981,70 @@ u32 VMManager::DeleteSaveStates(const char* game_serial, u32 game_crc, bool also
return deleted;
}
bool VMManager::LoadState(const char* filename)
bool VMManager::LoadState(const char* filename, Error* error)
{
if (Achievements::IsHardcoreModeActive())
{
Host::AddIconOSDMessage("LoadStateHardcoreBlocked", ICON_FA_TRIANGLE_EXCLAMATION,
TRANSLATE_SV("VMManager", "Cannot load save state while RetroAchievements Hardcore Mode is active."),
Host::OSD_WARNING_DURATION);
Error::SetString(error,
TRANSLATE_STR("VMManager", "Cannot load save state while RetroAchievements Hardcore Mode is active."));
return false;
}
if (MemcardBusy::IsBusy())
{
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_TRIANGLE_EXCLAMATION,
fmt::format(TRANSLATE_FS("VMManager", "Failed to load state (Memory card is busy)")),
Host::OSD_QUICK_DURATION);
Error::SetString(error,
TRANSLATE_STR("VMManager", "Memory card is busy."));
return false;
}
// TODO: Save the current state so we don't need to reset.
if (DoLoadState(filename))
if (DoLoadState(filename, error))
return true;
Reset();
return false;
}
bool VMManager::LoadStateFromSlot(s32 slot, bool backup)
bool VMManager::LoadStateFromSlot(s32 slot, bool backup, Error* error)
{
const std::string filename = GetCurrentSaveStateFileName(slot, backup);
if (filename.empty() || !FileSystem::FileExists(filename.c_str()))
{
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_TRIANGLE_EXCLAMATION,
fmt::format(TRANSLATE_FS("VMManager", "There is no saved {} in slot {}."), backup ? TRANSLATE("VMManager", "backup state") : "state", slot),
Host::OSD_QUICK_DURATION);
if (backup)
Error::SetStringFmt(error,
TRANSLATE_FS("VMManager", "There is no save state in backup slot {}."), slot);
else
Error::SetStringFmt(error,
TRANSLATE_FS("VMManager", "There is no save state in slot {}."), slot);
return false;
}
if (Achievements::IsHardcoreModeActive())
{
Host::AddIconOSDMessage("LoadStateHardcoreBlocked", ICON_FA_TRIANGLE_EXCLAMATION,
fmt::format(TRANSLATE_FS("VMManager", "Cannot load save {} from slot {} while RetroAchievements Hardcore Mode is active."), backup ? TRANSLATE("VMManager", "backup state") : TRANSLATE("VMManager", "state"), slot),
Host::OSD_WARNING_DURATION);
if (backup)
Error::SetStringFmt(error,
TRANSLATE_FS("VMManager", "Cannot load save state from backup slot {} while RetroAchievements Hardcore Mode is active."), slot);
else
Error::SetStringFmt(error,
TRANSLATE_FS("VMManager", "Cannot load save state from slot {} while RetroAchievements Hardcore Mode is active."), slot);
return false;
}
if (MemcardBusy::IsBusy())
{
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_TRIANGLE_EXCLAMATION,
fmt::format(TRANSLATE_FS("VMManager", "Failed to load {} from slot {} (Memory card is busy)"), backup ? TRANSLATE("VMManager", "backup state") : TRANSLATE("VMManager", "state"), slot),
Host::OSD_QUICK_DURATION);
if (backup)
Error::SetStringFmt(error,
TRANSLATE_FS("VMManager", "Failed to load save state from backup slot {} (memory card is busy)."), slot);
else
Error::SetStringFmt(error,
TRANSLATE_FS("VMManager", "Failed to load save state from slot {} (memory card is busy)."), slot);
return false;
}
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_FOLDER_OPEN,
fmt::format(TRANSLATE_FS("VMManager", "Loading {} from slot {}..."), backup ? TRANSLATE("VMManager", "backup state") : TRANSLATE("VMManager", "state"), slot), Host::OSD_QUICK_DURATION);
return DoLoadState(filename.c_str());
return DoLoadState(filename.c_str(), error);
}
bool VMManager::SaveState(const char* filename, bool zip_on_thread, bool backup_old_state)

View File

@@ -127,10 +127,10 @@ namespace VMManager
bool HasSaveStateInSlot(const char* game_serial, u32 game_crc, s32 slot);
/// Loads state from the specified file.
bool LoadState(const char* filename);
bool LoadState(const char* filename, Error* error = nullptr);
/// Loads state from the specified slot.
bool LoadStateFromSlot(s32 slot, bool backup = false);
bool LoadStateFromSlot(s32 slot, bool backup = false, Error* error = nullptr);
/// Saves state to the specified filename.
bool SaveState(const char* filename, bool zip_on_thread = true, bool backup_old_state = false);

View File

@@ -177,7 +177,7 @@ static bool LoadBiosVersion(std::FILE* fp, u32& version, std::string& descriptio
"",
serial.c_str());
version = strtol(vermaj, (char**)NULL, 0) << 8;
version = static_cast<u32>(strtol(vermaj, (char**)NULL, 0) << 8);
version |= strtol(vermin, (char**)NULL, 0);
Console.WriteLn("BIOS Found: %s", description.c_str());

View File

@@ -174,7 +174,7 @@ namespace vtlb_private
/// Assumes the entry is a handler, and gets the raw handler ID
u8 assumeHandlerGetID() const { return value; }
/// Assumes the entry is a handler, and gets the physical address
u32 assumeHandlerGetPAddr(u32 vaddr) const { return (value + vaddr - assumeHandlerGetID()) & ~POINTER_SIGN_BIT; }
u32 assumeHandlerGetPAddr(u32 vaddr) const { return static_cast<u32>((value + vaddr - assumeHandlerGetID()) & ~POINTER_SIGN_BIT); }
/// Assumes the entry is a handler, returning it as a void*
void *assumeHandlerGetRaw(int index, bool write) const;
/// Assumes the entry is a handler, returning it