mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
13 Commits
v2.5.142
...
misc_auto_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b0a83c1ab | ||
|
|
9864cd97de | ||
|
|
6d7deb57a0 | ||
|
|
21876ff590 | ||
|
|
c543c05968 | ||
|
|
a5537da4df | ||
|
|
edaddeecc4 | ||
|
|
6b30a199da | ||
|
|
23c637e3e5 | ||
|
|
313b0fe3b5 | ||
|
|
90818c3627 | ||
|
|
89877aba58 | ||
|
|
80cb381b35 |
@@ -21,7 +21,7 @@ LIBJPEGTURBO=3.1.1
|
||||
LIBPNG=1.6.50
|
||||
LIBWEBP=1.6.0
|
||||
SDL=SDL3-3.2.20
|
||||
QT=6.9.1
|
||||
QT=6.9.2
|
||||
LZ4=1.10.0
|
||||
ZSTD=1.5.7
|
||||
KDDOCKWIDGETS=2.2.3
|
||||
@@ -46,12 +46,12 @@ e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWE
|
||||
467600ae090dd28616fa37369faf4e3143198ff1da37729b552137e47f751a67 $SDL.tar.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
40caedbf83cc9a1959610830563565889878bc95f115868bbf545d1914acf28e qtbase-everywhere-src-$QT.tar.xz
|
||||
ebe9f238daaf9bb752c7233edadf4af33fc4fa30d914936812b6410d3af1577c qtimageformats-everywhere-src-$QT.tar.xz
|
||||
2dfc5de5fd891ff2afd9861e519bf1a26e6deb729b3133f68a28ba763c9abbd5 qtsvg-everywhere-src-$QT.tar.xz
|
||||
90c4a562f4ccfd043fd99f34c600853e0b5ba9babc6ec616c0f306f2ce3f4b4c qttools-everywhere-src-$QT.tar.xz
|
||||
9761a1a555f447cdeba79fdec6a705dee8a7882ac10c12e85f49467ddd01a741 qttranslations-everywhere-src-$QT.tar.xz
|
||||
7d21ea0e687180ebb19b9a1f86ae9cfa7a25b4f02d5db05ec834164409932e3e qtwayland-everywhere-src-$QT.tar.xz
|
||||
44be9c9ecfe04129c4dea0a7e1b36ad476c9cc07c292016ac98e7b41514f2440 qtbase-everywhere-src-$QT.tar.xz
|
||||
8a023f7e2f57dedc02e2ab10c975f7cb3cccac9b8f0823c12fd6824834549139 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
d984cab8f26334aa1c15e5b8f0cd9f1b7c0c1289fe0b68c1c84ab469b75605a5 qtsvg-everywhere-src-$QT.tar.xz
|
||||
d8b7f7e8e970cc0b975205fd6d5832ea917ef3e751df69b97439c1cddd67a489 qttools-everywhere-src-$QT.tar.xz
|
||||
c73bb6281ed365c0f954f4b1b6e1b13e1b3fefd94854f46fcd9a412f641f7ed6 qttranslations-everywhere-src-$QT.tar.xz
|
||||
cad79806565568f12f9983fed69219416abcee9d5deef4abdfcf94aa2eef7781 qtwayland-everywhere-src-$QT.tar.xz
|
||||
a8e4a25e5c2686fd36981e527ed05e451fcfc226bddf350f4e76181371190937 shaderc-$SHADERC.tar.gz
|
||||
9427deccbdf4bde6a269938df38c6bd75247493786a310d8d733a2c82065ef47 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c2225a49c3d7efa5c4f4ce4a6b42081e6ea3daca376f3353d9d7c2722d77a28a shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
|
||||
@@ -47,7 +47,7 @@ set HARFBUZZ=11.2.0
|
||||
set LIBJPEGTURBO=3.1.1
|
||||
set LIBPNG=1650
|
||||
set SDL=SDL3-3.2.20
|
||||
set QT=6.9.1
|
||||
set QT=6.9.2
|
||||
set QTMINOR=6.9
|
||||
set LZ4=1.10.0
|
||||
set WEBP=1.6.0
|
||||
@@ -69,11 +69,11 @@ call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lp
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" aadc97ea91f6ef078b0ae3a62bba69e008d9a7db19b34e4ac973b19b71b4217c || 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" d76454913ea6f5f38856fbf00578d8e39daf842887f3396c95608414680250f7 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" efa6d8ef9f7ae0fd9f7d280fbff574d71882b60a357ae639e516dc173cf26986 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 8439d3394bc380fd17a920ee96df1d2272bf8d3490871d948ef750f95e0ded06 || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" a8f90c768b54e28d61e02c1229b74a2b834e9852af523e5c70bcd2ae4c34a772 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 38db91c4a8044c395eac89e325ecc25edbda12606fc28812491ef5e5b6b53dd6 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" fd2e776164751fb486495efeee336d26d85fe1ca1f6a7b9eb6aafca2e3d333aa || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 97d59c78e40b4ddd018738d285a12afc320b57f8265a3f760353739a3619ccdb || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" f2fc6ff382c6f3af79493d0709dbd64847d0356313518f094f9096315f2fdb30 || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" af80bb671ea0f66c0036ce7041a56b0e550fc94fb88d2c77b5b6a3e33e42139b || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" d2f4c7a4a12630e879702353f944f96a5d8e764771b5a5f04163334ad61b39db || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 3e168d1b081ee3a2175fe1bd97ad03bb40fe7ce38a37e99923a19f0e7ec4d81c || 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
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
|
||||
@@ -45,7 +45,7 @@ set HARFBUZZ=11.2.0
|
||||
set LIBJPEGTURBO=3.1.1
|
||||
set LIBPNG=1650
|
||||
set SDL=SDL3-3.2.20
|
||||
set QT=6.9.1
|
||||
set QT=6.9.2
|
||||
set QTMINOR=6.9
|
||||
set LZ4=1.10.0
|
||||
set WEBP=1.6.0
|
||||
@@ -67,11 +67,11 @@ call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lp
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" aadc97ea91f6ef078b0ae3a62bba69e008d9a7db19b34e4ac973b19b71b4217c || 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" d76454913ea6f5f38856fbf00578d8e39daf842887f3396c95608414680250f7 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" efa6d8ef9f7ae0fd9f7d280fbff574d71882b60a357ae639e516dc173cf26986 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 8439d3394bc380fd17a920ee96df1d2272bf8d3490871d948ef750f95e0ded06 || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" a8f90c768b54e28d61e02c1229b74a2b834e9852af523e5c70bcd2ae4c34a772 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 38db91c4a8044c395eac89e325ecc25edbda12606fc28812491ef5e5b6b53dd6 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" fd2e776164751fb486495efeee336d26d85fe1ca1f6a7b9eb6aafca2e3d333aa || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 97d59c78e40b4ddd018738d285a12afc320b57f8265a3f760353739a3619ccdb || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" f2fc6ff382c6f3af79493d0709dbd64847d0356313518f094f9096315f2fdb30 || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" af80bb671ea0f66c0036ce7041a56b0e550fc94fb88d2c77b5b6a3e33e42139b || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" d2f4c7a4a12630e879702353f944f96a5d8e764771b5a5f04163334ad61b39db || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 3e168d1b081ee3a2175fe1bd97ad03bb40fe7ce38a37e99923a19f0e7ec4d81c || 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
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
03000000c82d00000260000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||
03000000c82d00000261000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||
03000000c82d00001230000000000000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000c82d00001260000000000000,8BitDo Ultimate 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b17,paddle2:b16,paddle3:b2,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000c82d00001b30000000000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000c82d00001d30000000000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000c82d00001530000000000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
|
||||
@@ -173,10 +173,10 @@ cbuffer cb1
|
||||
float RcpScaleFactor;
|
||||
};
|
||||
|
||||
float4 sample_c(float2 uv, float uv_w)
|
||||
float4 sample_c(float2 uv, float uv_w, int2 xy)
|
||||
{
|
||||
#if PS_TEX_IS_FB == 1
|
||||
return RtTexture.Load(int3(int2(uv * WH.zw), 0));
|
||||
return RtTexture.Load(int3(int2(xy), 0));
|
||||
#elif PS_REGION_RECT == 1
|
||||
return Texture.Load(int3(int2(uv), 0));
|
||||
#else
|
||||
@@ -315,26 +315,26 @@ float4 clamp_wrap_uv(float4 uv)
|
||||
return uv;
|
||||
}
|
||||
|
||||
float4x4 sample_4c(float4 uv, float uv_w)
|
||||
float4x4 sample_4c(float4 uv, float uv_w, int2 xy)
|
||||
{
|
||||
float4x4 c;
|
||||
|
||||
c[0] = sample_c(uv.xy, uv_w);
|
||||
c[1] = sample_c(uv.zy, uv_w);
|
||||
c[2] = sample_c(uv.xw, uv_w);
|
||||
c[3] = sample_c(uv.zw, uv_w);
|
||||
c[0] = sample_c(uv.xy, uv_w, xy);
|
||||
c[1] = sample_c(uv.zy, uv_w, xy);
|
||||
c[2] = sample_c(uv.xw, uv_w, xy);
|
||||
c[3] = sample_c(uv.zw, uv_w, xy);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
uint4 sample_4_index(float4 uv, float uv_w)
|
||||
uint4 sample_4_index(float4 uv, float uv_w, int2 xy)
|
||||
{
|
||||
float4 c;
|
||||
|
||||
c.x = sample_c(uv.xy, uv_w).a;
|
||||
c.y = sample_c(uv.zy, uv_w).a;
|
||||
c.z = sample_c(uv.xw, uv_w).a;
|
||||
c.w = sample_c(uv.zw, uv_w).a;
|
||||
c.x = sample_c(uv.xy, uv_w, xy).a;
|
||||
c.y = sample_c(uv.zy, uv_w, xy).a;
|
||||
c.z = sample_c(uv.xw, uv_w, xy).a;
|
||||
c.w = sample_c(uv.zw, uv_w, xy).a;
|
||||
|
||||
// Denormalize value
|
||||
uint4 i;
|
||||
@@ -606,7 +606,7 @@ float4 fetch_gXbY(int2 xy)
|
||||
}
|
||||
}
|
||||
|
||||
float4 sample_color(float2 st, float uv_w)
|
||||
float4 sample_color(float2 st, float uv_w, int2 xy)
|
||||
{
|
||||
#if PS_TCOFFSETHACK
|
||||
st += TC_OffsetHack.xy;
|
||||
@@ -618,7 +618,7 @@ float4 sample_color(float2 st, float uv_w)
|
||||
|
||||
if (PS_LTF == 0 && PS_AEM_FMT == FMT_32 && PS_PAL_FMT == 0 && PS_REGION_RECT == 0 && PS_WMS < 2 && PS_WMT < 2)
|
||||
{
|
||||
c[0] = sample_c(st, uv_w);
|
||||
c[0] = sample_c(st, uv_w, xy);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -642,9 +642,9 @@ float4 sample_color(float2 st, float uv_w)
|
||||
uv = clamp_wrap_uv(uv);
|
||||
|
||||
#if PS_PAL_FMT != 0
|
||||
c = sample_4p(sample_4_index(uv, uv_w));
|
||||
c = sample_4p(sample_4_index(uv, uv_w, xy));
|
||||
#else
|
||||
c = sample_4c(uv, uv_w);
|
||||
c = sample_4c(uv, uv_w, xy);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -769,7 +769,7 @@ float4 ps_color(PS_INPUT input)
|
||||
#elif PS_DEPTH_FMT > 0
|
||||
float4 T = sample_depth(st_int, input.p.xy);
|
||||
#else
|
||||
float4 T = sample_color(st, input.t.w);
|
||||
float4 T = sample_color(st, input.t.w, int2(input.p.xy));
|
||||
#endif
|
||||
|
||||
if (PS_SHUFFLE && !PS_SHUFFLE_SAME && !PS_READ16_SRC && !(PS_PROCESS_BA == SHUFFLE_READWRITE && PS_PROCESS_RG == SHUFFLE_READWRITE))
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
#include "SymbolTreeDelegates.h"
|
||||
|
||||
#include "Debugger/SymbolTree/SymbolTreeModel.h"
|
||||
#include "Debugger/SymbolTree/TypeString.h"
|
||||
|
||||
#include <QtWidgets/QCheckBox>
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
#include <QtWidgets/QLineEdit>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include "Debugger/SymbolTree/SymbolTreeModel.h"
|
||||
#include "Debugger/SymbolTree/TypeString.h"
|
||||
|
||||
SymbolTreeValueDelegate::SymbolTreeValueDelegate(
|
||||
DebugInterface& cpu,
|
||||
@@ -28,6 +29,8 @@ QWidget* SymbolTreeValueDelegate::createEditor(QWidget* parent, const QStyleOpti
|
||||
if (!tree_model)
|
||||
return nullptr;
|
||||
|
||||
const SymbolTreeDisplayOptions& display_options = tree_model->displayOptions();
|
||||
|
||||
SymbolTreeNode* node = tree_model->nodeFromIndex(index);
|
||||
if (!node || !node->type.valid())
|
||||
return nullptr;
|
||||
@@ -46,9 +49,9 @@ QWidget* SymbolTreeValueDelegate::createEditor(QWidget* parent, const QStyleOpti
|
||||
{
|
||||
case ccc::ast::BUILTIN:
|
||||
{
|
||||
const ccc::ast::BuiltIn& builtIn = type.as<ccc::ast::BuiltIn>();
|
||||
const ccc::ast::BuiltIn& builtin = type.as<ccc::ast::BuiltIn>();
|
||||
|
||||
switch (builtIn.bclass)
|
||||
switch (builtin.bclass)
|
||||
{
|
||||
case ccc::ast::BuiltInClass::UNSIGNED_8:
|
||||
case ccc::ast::BuiltInClass::UNQUALIFIED_8:
|
||||
@@ -56,8 +59,9 @@ QWidget* SymbolTreeValueDelegate::createEditor(QWidget* parent, const QStyleOpti
|
||||
case ccc::ast::BuiltInClass::UNSIGNED_32:
|
||||
case ccc::ast::BuiltInClass::UNSIGNED_64:
|
||||
{
|
||||
QLineEdit* editor = new QLineEdit(parent);
|
||||
editor->setText(QString::number(value.toULongLong()));
|
||||
SymbolTreeIntegerLineEdit* editor = new SymbolTreeIntegerLineEdit(
|
||||
display_options, ccc::ast::builtin_class_size(builtin.bclass) * 8, parent);
|
||||
editor->setUnsignedValue(value.toULongLong());
|
||||
result = editor;
|
||||
|
||||
break;
|
||||
@@ -67,8 +71,9 @@ QWidget* SymbolTreeValueDelegate::createEditor(QWidget* parent, const QStyleOpti
|
||||
case ccc::ast::BuiltInClass::SIGNED_32:
|
||||
case ccc::ast::BuiltInClass::SIGNED_64:
|
||||
{
|
||||
QLineEdit* editor = new QLineEdit(parent);
|
||||
editor->setText(QString::number(value.toLongLong()));
|
||||
SymbolTreeIntegerLineEdit* editor = new SymbolTreeIntegerLineEdit(
|
||||
display_options, ccc::ast::builtin_class_size(builtin.bclass) * 8, parent);
|
||||
editor->setSignedValue(value.toLongLong());
|
||||
result = editor;
|
||||
|
||||
break;
|
||||
@@ -168,9 +173,9 @@ void SymbolTreeValueDelegate::setModelData(QWidget* editor, QAbstractItemModel*
|
||||
{
|
||||
case ccc::ast::BUILTIN:
|
||||
{
|
||||
const ccc::ast::BuiltIn& builtIn = type.as<ccc::ast::BuiltIn>();
|
||||
const ccc::ast::BuiltIn& builtin = type.as<ccc::ast::BuiltIn>();
|
||||
|
||||
switch (builtIn.bclass)
|
||||
switch (builtin.bclass)
|
||||
{
|
||||
case ccc::ast::BuiltInClass::UNSIGNED_8:
|
||||
case ccc::ast::BuiltInClass::UNQUALIFIED_8:
|
||||
@@ -178,13 +183,12 @@ void SymbolTreeValueDelegate::setModelData(QWidget* editor, QAbstractItemModel*
|
||||
case ccc::ast::BuiltInClass::UNSIGNED_32:
|
||||
case ccc::ast::BuiltInClass::UNSIGNED_64:
|
||||
{
|
||||
QLineEdit* line_edit = qobject_cast<QLineEdit*>(editor);
|
||||
auto line_edit = qobject_cast<SymbolTreeIntegerLineEdit*>(editor);
|
||||
Q_ASSERT(line_edit);
|
||||
|
||||
bool ok;
|
||||
qulonglong i = line_edit->text().toULongLong(&ok);
|
||||
if (ok)
|
||||
value = i;
|
||||
std::optional<u64> i = line_edit->unsignedValue();
|
||||
if (i.has_value())
|
||||
value = static_cast<quint64>(*i);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -193,13 +197,12 @@ void SymbolTreeValueDelegate::setModelData(QWidget* editor, QAbstractItemModel*
|
||||
case ccc::ast::BuiltInClass::SIGNED_32:
|
||||
case ccc::ast::BuiltInClass::SIGNED_64:
|
||||
{
|
||||
QLineEdit* line_edit = qobject_cast<QLineEdit*>(editor);
|
||||
auto line_edit = qobject_cast<SymbolTreeIntegerLineEdit*>(editor);
|
||||
Q_ASSERT(line_edit);
|
||||
|
||||
bool ok;
|
||||
qlonglong i = line_edit->text().toLongLong(&ok);
|
||||
if (ok)
|
||||
value = i;
|
||||
std::optional<s64> i = line_edit->signedValue();
|
||||
if (i.has_value())
|
||||
value = static_cast<qint64>(*i);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -481,3 +484,33 @@ void SymbolTreeTypeDelegate::setModelData(QWidget* editor, QAbstractItemModel* m
|
||||
else
|
||||
QMessageBox::warning(editor, tr("Cannot Change Type"), error_message);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
|
||||
SymbolTreeIntegerLineEdit::SymbolTreeIntegerLineEdit(
|
||||
SymbolTreeDisplayOptions display_options, s32 size_bits, QWidget* parent)
|
||||
: QLineEdit(parent)
|
||||
, m_display_options(display_options)
|
||||
, m_size_bits(size_bits)
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<u64> SymbolTreeIntegerLineEdit::unsignedValue()
|
||||
{
|
||||
return m_display_options.stringToUnsignedInteger(text());
|
||||
}
|
||||
|
||||
void SymbolTreeIntegerLineEdit::setUnsignedValue(u64 value)
|
||||
{
|
||||
setText(m_display_options.unsignedIntegerToString(value, m_size_bits));
|
||||
}
|
||||
|
||||
std::optional<s64> SymbolTreeIntegerLineEdit::signedValue()
|
||||
{
|
||||
return m_display_options.stringToSignedInteger(text());
|
||||
}
|
||||
|
||||
void SymbolTreeIntegerLineEdit::setSignedValue(s64 value)
|
||||
{
|
||||
setText(m_display_options.signedIntegerToString(value, m_size_bits));
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QStyledItemDelegate>
|
||||
#include "Debugger/SymbolTree/SymbolTreeNode.h"
|
||||
|
||||
#include "DebugTools/DebugInterface.h"
|
||||
#include "DebugTools/SymbolGuardian.h"
|
||||
|
||||
#include <QtWidgets/QStyledItemDelegate>
|
||||
#include <QtWidgets/QLineEdit>
|
||||
|
||||
class SymbolTreeValueDelegate : public QStyledItemDelegate
|
||||
{
|
||||
@@ -21,7 +23,7 @@ public:
|
||||
void setEditorData(QWidget* editor, const QModelIndex& index) const override;
|
||||
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
|
||||
|
||||
protected:
|
||||
private:
|
||||
// These make it so the values inputted are written back to memory
|
||||
// immediately when the widgets are interacted with rather than when they
|
||||
// are deselected.
|
||||
@@ -45,7 +47,7 @@ public:
|
||||
void setEditorData(QWidget* editor, const QModelIndex& index) const override;
|
||||
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
|
||||
|
||||
protected:
|
||||
private:
|
||||
DebugInterface& m_cpu;
|
||||
u32 m_alignment;
|
||||
};
|
||||
@@ -63,6 +65,24 @@ public:
|
||||
void setEditorData(QWidget* editor, const QModelIndex& index) const override;
|
||||
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
|
||||
|
||||
protected:
|
||||
private:
|
||||
DebugInterface& m_cpu;
|
||||
};
|
||||
|
||||
class SymbolTreeIntegerLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SymbolTreeIntegerLineEdit(SymbolTreeDisplayOptions display_options, s32 size_bits, QWidget* parent);
|
||||
|
||||
std::optional<u64> unsignedValue();
|
||||
void setUnsignedValue(u64 value);
|
||||
|
||||
std::optional<s64> signedValue();
|
||||
void setSignedValue(s64 value);
|
||||
|
||||
private:
|
||||
SymbolTreeDisplayOptions m_display_options;
|
||||
s32 m_size_bits;
|
||||
};
|
||||
|
||||
@@ -183,10 +183,10 @@ bool SymbolTreeModel::setData(const QModelIndex& index, const QVariant& value, i
|
||||
switch (role)
|
||||
{
|
||||
case EDIT_ROLE:
|
||||
data_changed = node->writeToVM(value, m_cpu, database);
|
||||
data_changed = node->writeToVM(value, m_cpu, database, m_display_options);
|
||||
break;
|
||||
case UPDATE_FROM_MEMORY_ROLE:
|
||||
data_changed = node->readFromVM(m_cpu, database);
|
||||
data_changed = node->readFromVM(m_cpu, database, m_display_options);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -216,7 +216,13 @@ void SymbolTreeModel::fetchMore(const QModelIndex& parent)
|
||||
return;
|
||||
|
||||
children = populateChildren(
|
||||
parent_node->name, parent_node->location, *logical_parent_type, parent_node->type, m_cpu, database);
|
||||
parent_node->name,
|
||||
parent_node->location,
|
||||
*logical_parent_type,
|
||||
parent_node->type,
|
||||
m_cpu,
|
||||
database,
|
||||
m_display_options);
|
||||
});
|
||||
|
||||
bool insert_children = !children.empty();
|
||||
@@ -403,7 +409,8 @@ std::vector<std::unique_ptr<SymbolTreeNode>> SymbolTreeModel::populateChildren(
|
||||
const ccc::ast::Node& logical_type,
|
||||
ccc::NodeHandle parent_handle,
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database)
|
||||
const ccc::SymbolDatabase& database,
|
||||
const SymbolTreeDisplayOptions& display_options)
|
||||
{
|
||||
auto [physical_type, symbol] = logical_type.physical_type(database);
|
||||
|
||||
@@ -485,7 +492,7 @@ std::vector<std::unique_ptr<SymbolTreeNode>> SymbolTreeModel::populateChildren(
|
||||
}
|
||||
|
||||
for (std::unique_ptr<SymbolTreeNode>& child : children)
|
||||
child->readFromVM(cpu, database);
|
||||
child->readFromVM(cpu, database, display_options);
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,9 @@ public:
|
||||
std::optional<QString> changeTypeTemporarily(QModelIndex index, std::string_view type_string);
|
||||
std::optional<QString> typeFromModelIndexToString(QModelIndex index);
|
||||
|
||||
const SymbolTreeDisplayOptions& displayOptions() const { return m_display_options; }
|
||||
void setDisplayOptions(const SymbolTreeDisplayOptions& options) { m_display_options = options; }
|
||||
|
||||
protected:
|
||||
static std::vector<std::unique_ptr<SymbolTreeNode>> populateChildren(
|
||||
const QString& name,
|
||||
@@ -72,11 +75,13 @@ protected:
|
||||
const ccc::ast::Node& logical_type,
|
||||
ccc::NodeHandle parent_handle,
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database);
|
||||
const ccc::SymbolDatabase& database,
|
||||
const SymbolTreeDisplayOptions& display_options);
|
||||
|
||||
static bool nodeHasChildren(const ccc::ast::Node& logical_type, const ccc::SymbolDatabase& database);
|
||||
|
||||
std::unique_ptr<SymbolTreeNode> m_root;
|
||||
QString m_filter;
|
||||
DebugInterface& m_cpu;
|
||||
SymbolTreeDisplayOptions m_display_options;
|
||||
};
|
||||
|
||||
@@ -20,7 +20,10 @@ std::optional<bool> SymbolTreeNode::liveness()
|
||||
return m_liveness;
|
||||
}
|
||||
|
||||
bool SymbolTreeNode::readFromVM(DebugInterface& cpu, const ccc::SymbolDatabase& database)
|
||||
bool SymbolTreeNode::readFromVM(
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database,
|
||||
const SymbolTreeDisplayOptions& display_options)
|
||||
{
|
||||
QVariant new_value;
|
||||
|
||||
@@ -39,14 +42,18 @@ bool SymbolTreeNode::readFromVM(DebugInterface& cpu, const ccc::SymbolDatabase&
|
||||
data_changed = true;
|
||||
}
|
||||
|
||||
data_changed |= updateDisplayString(cpu, database);
|
||||
data_changed |= updateDisplayString(cpu, database, display_options);
|
||||
data_changed |= updateLiveness(cpu);
|
||||
data_changed |= updateMatchesMemory(cpu, database);
|
||||
|
||||
return data_changed;
|
||||
}
|
||||
|
||||
bool SymbolTreeNode::writeToVM(QVariant value, DebugInterface& cpu, const ccc::SymbolDatabase& database)
|
||||
bool SymbolTreeNode::writeToVM(
|
||||
QVariant value,
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database,
|
||||
const SymbolTreeDisplayOptions& display_options)
|
||||
{
|
||||
bool data_changed = false;
|
||||
|
||||
@@ -63,7 +70,7 @@ bool SymbolTreeNode::writeToVM(QVariant value, DebugInterface& cpu, const ccc::S
|
||||
writeValueFromVariant(m_value, physical_type, cpu);
|
||||
}
|
||||
|
||||
data_changed |= updateDisplayString(cpu, database);
|
||||
data_changed |= updateDisplayString(cpu, database, display_options);
|
||||
data_changed |= updateLiveness(cpu);
|
||||
|
||||
return data_changed;
|
||||
@@ -202,7 +209,8 @@ bool SymbolTreeNode::writeValueFromVariant(QVariant value, const ccc::ast::Node&
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SymbolTreeNode::updateDisplayString(DebugInterface& cpu, const ccc::SymbolDatabase& database)
|
||||
bool SymbolTreeNode::updateDisplayString(
|
||||
DebugInterface& cpu, const ccc::SymbolDatabase& database, const SymbolTreeDisplayOptions& display)
|
||||
{
|
||||
QString result;
|
||||
|
||||
@@ -210,7 +218,7 @@ bool SymbolTreeNode::updateDisplayString(DebugInterface& cpu, const ccc::SymbolD
|
||||
if (logical_type)
|
||||
{
|
||||
const ccc::ast::Node& physical_type = *logical_type->physical_type(database).first;
|
||||
result = generateDisplayString(physical_type, cpu, database, 0);
|
||||
result = generateDisplayString(physical_type, cpu, database, display, 0);
|
||||
}
|
||||
|
||||
if (result.isEmpty())
|
||||
@@ -219,10 +227,10 @@ bool SymbolTreeNode::updateDisplayString(DebugInterface& cpu, const ccc::SymbolD
|
||||
// first 4 bytes of it as a hex dump.
|
||||
u32 value = location.read32(cpu);
|
||||
result = QString("%1 %2 %3 %4")
|
||||
.arg(value & 0xff, 2, 16, QChar('0'))
|
||||
.arg((value >> 8) & 0xff, 2, 16, QChar('0'))
|
||||
.arg((value >> 16) & 0xff, 2, 16, QChar('0'))
|
||||
.arg((value >> 24) & 0xff, 2, 16, QChar('0'));
|
||||
.arg(value & 0xff, 2, 16, QChar('0'))
|
||||
.arg((value >> 8) & 0xff, 2, 16, QChar('0'))
|
||||
.arg((value >> 16) & 0xff, 2, 16, QChar('0'))
|
||||
.arg((value >> 24) & 0xff, 2, 16, QChar('0'));
|
||||
}
|
||||
|
||||
if (result == m_display_value)
|
||||
@@ -234,7 +242,11 @@ bool SymbolTreeNode::updateDisplayString(DebugInterface& cpu, const ccc::SymbolD
|
||||
}
|
||||
|
||||
QString SymbolTreeNode::generateDisplayString(
|
||||
const ccc::ast::Node& physical_type, DebugInterface& cpu, const ccc::SymbolDatabase& database, s32 depth) const
|
||||
const ccc::ast::Node& physical_type,
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database,
|
||||
const SymbolTreeDisplayOptions& display_options,
|
||||
s32 depth) const
|
||||
{
|
||||
s32 max_elements_to_display = 0;
|
||||
switch (depth)
|
||||
@@ -270,7 +282,7 @@ QString SymbolTreeNode::generateDisplayString(
|
||||
SymbolTreeNode node;
|
||||
node.location = location.addOffset(i * array.element_type->size_bytes);
|
||||
|
||||
QString element = node.generateDisplayString(element_type, cpu, database, depth + 1);
|
||||
QString element = node.generateDisplayString(element_type, cpu, database, display_options, depth + 1);
|
||||
if (element.isEmpty())
|
||||
element = QString("(%1)").arg(ccc::ast::node_type_to_string(element_type));
|
||||
result += element;
|
||||
@@ -293,28 +305,28 @@ QString SymbolTreeNode::generateDisplayString(
|
||||
switch (builtIn.bclass)
|
||||
{
|
||||
case ccc::ast::BuiltInClass::UNSIGNED_8:
|
||||
result = QString::number(location.read8(cpu));
|
||||
result = display_options.unsignedIntegerToString(location.read8(cpu), 8);
|
||||
break;
|
||||
case ccc::ast::BuiltInClass::SIGNED_8:
|
||||
result = QString::number((s8)location.read8(cpu));
|
||||
result = display_options.signedIntegerToString(static_cast<s8>(location.read8(cpu)), 8);
|
||||
break;
|
||||
case ccc::ast::BuiltInClass::UNQUALIFIED_8:
|
||||
result = QString::number(location.read8(cpu));
|
||||
result = display_options.unsignedIntegerToString(location.read8(cpu), 8);
|
||||
break;
|
||||
case ccc::ast::BuiltInClass::BOOL_8:
|
||||
result = location.read8(cpu) ? "true" : "false";
|
||||
break;
|
||||
case ccc::ast::BuiltInClass::UNSIGNED_16:
|
||||
result = QString::number(location.read16(cpu));
|
||||
result = display_options.unsignedIntegerToString(location.read16(cpu), 16);
|
||||
break;
|
||||
case ccc::ast::BuiltInClass::SIGNED_16:
|
||||
result = QString::number((s16)location.read16(cpu));
|
||||
result = display_options.signedIntegerToString(static_cast<s16>(location.read16(cpu)), 16);
|
||||
break;
|
||||
case ccc::ast::BuiltInClass::UNSIGNED_32:
|
||||
result = QString::number(location.read32(cpu));
|
||||
result = display_options.unsignedIntegerToString(location.read32(cpu), 32);
|
||||
break;
|
||||
case ccc::ast::BuiltInClass::SIGNED_32:
|
||||
result = QString::number((s32)location.read32(cpu));
|
||||
result = display_options.signedIntegerToString(static_cast<s32>(location.read32(cpu)), 32);
|
||||
break;
|
||||
case ccc::ast::BuiltInClass::FLOAT_32:
|
||||
{
|
||||
@@ -323,10 +335,10 @@ QString SymbolTreeNode::generateDisplayString(
|
||||
break;
|
||||
}
|
||||
case ccc::ast::BuiltInClass::UNSIGNED_64:
|
||||
result = QString::number(location.read64(cpu));
|
||||
result = display_options.unsignedIntegerToString(location.read64(cpu), 64);
|
||||
break;
|
||||
case ccc::ast::BuiltInClass::SIGNED_64:
|
||||
result = QString::number((s64)location.read64(cpu));
|
||||
result = display_options.signedIntegerToString(static_cast<s64>(location.read64(cpu)), 64);
|
||||
break;
|
||||
case ccc::ast::BuiltInClass::FLOAT_64:
|
||||
{
|
||||
@@ -408,7 +420,7 @@ QString SymbolTreeNode::generateDisplayString(
|
||||
}
|
||||
else if (depth == 0)
|
||||
{
|
||||
QString pointee = generateDisplayString(value_type, cpu, database, depth + 1);
|
||||
QString pointee = generateDisplayString(value_type, cpu, database, display_options, depth + 1);
|
||||
if (!pointee.isEmpty())
|
||||
result += QString(" -> %1").arg(pointee);
|
||||
}
|
||||
@@ -437,7 +449,7 @@ QString SymbolTreeNode::generateDisplayString(
|
||||
node.location = location.addOffset(field.base_offset + field.node->offset_bytes);
|
||||
|
||||
const ccc::ast::Node& field_type = *field.node->physical_type(database).first;
|
||||
QString field_value = node.generateDisplayString(field_type, cpu, database, depth + 1);
|
||||
QString field_value = node.generateDisplayString(field_type, cpu, database, display_options, depth + 1);
|
||||
if (field_value.isEmpty())
|
||||
field_value = QString("(%1)").arg(ccc::ast::node_type_to_string(field_type));
|
||||
|
||||
@@ -709,3 +721,99 @@ void SymbolTreeNode::sortChildrenRecursively(bool sort_by_if_type_is_known)
|
||||
for (std::unique_ptr<SymbolTreeNode>& child : m_children)
|
||||
child->sortChildrenRecursively(sort_by_if_type_is_known);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
|
||||
int SymbolTreeDisplayOptions::integerBase() const
|
||||
{
|
||||
return m_integer_base;
|
||||
}
|
||||
|
||||
bool SymbolTreeDisplayOptions::setIntegerBase(int base)
|
||||
{
|
||||
if (base == m_integer_base || (base != 2 && base != 8 && base != 10 && base != 16))
|
||||
return false;
|
||||
|
||||
m_integer_base = base;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SymbolTreeDisplayOptions::showLeadingZeroes() const
|
||||
{
|
||||
return m_show_leading_zeroes;
|
||||
}
|
||||
|
||||
bool SymbolTreeDisplayOptions::setShowLeadingZeroes(bool show)
|
||||
{
|
||||
if (show == m_show_leading_zeroes)
|
||||
return false;
|
||||
|
||||
m_show_leading_zeroes = show;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<u64> SymbolTreeDisplayOptions::stringToUnsignedInteger(QString string) const
|
||||
{
|
||||
bool ok;
|
||||
u64 value = string.toULongLong(&ok, m_integer_base);
|
||||
if (!ok)
|
||||
{
|
||||
// Try parsing it as a signed integer too, just in case the user tried
|
||||
// to use a minus sign.
|
||||
value = static_cast<u64>(string.toLongLong(&ok, m_integer_base));
|
||||
if (!ok)
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
QString SymbolTreeDisplayOptions::unsignedIntegerToString(u64 value, s32 size_bits) const
|
||||
{
|
||||
int field_width = 0;
|
||||
if (m_show_leading_zeroes)
|
||||
field_width = static_cast<int>(ceilf(size_bits / log2f(m_integer_base)));
|
||||
|
||||
return QStringLiteral("%1").arg(value, field_width, m_integer_base, QLatin1Char('0'));
|
||||
}
|
||||
|
||||
std::optional<s64> SymbolTreeDisplayOptions::stringToSignedInteger(QString string) const
|
||||
{
|
||||
bool ok;
|
||||
s64 value = string.toLongLong(&ok, m_integer_base);
|
||||
if (!ok)
|
||||
{
|
||||
// Try to parse it as an unsigned integer too to handle bases other than
|
||||
// decimal (see below), and to handle the case that the user entered a
|
||||
// value that was too big for a signed integer.
|
||||
value = static_cast<s64>(string.toULongLong(&ok, m_integer_base));
|
||||
if (!ok)
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
QString SymbolTreeDisplayOptions::signedIntegerToString(s64 value, s32 size_bits) const
|
||||
{
|
||||
// For bases other than decimal, the user most likely just wants to view the
|
||||
// underlying representation, so we want to display it as unsigned.
|
||||
if (m_integer_base != 10)
|
||||
{
|
||||
// Truncate sign extended bits.
|
||||
u64 mask = (static_cast<u64>(1) << size_bits) - 1;
|
||||
return unsignedIntegerToString(static_cast<u64>(value) & mask, size_bits);
|
||||
}
|
||||
|
||||
int field_width = 0;
|
||||
if (m_show_leading_zeroes)
|
||||
{
|
||||
field_width = static_cast<int>(ceilf(size_bits / log2f(m_integer_base)));
|
||||
|
||||
// An extra character is needed for the minus sign.
|
||||
if (value < 0)
|
||||
field_width++;
|
||||
}
|
||||
|
||||
return QStringLiteral("%1").arg(value, field_width, m_integer_base, QLatin1Char('0'));
|
||||
}
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
#include "SymbolTreeLocation.h"
|
||||
|
||||
class DebugInterface;
|
||||
class SymbolTreeDisplayOptions;
|
||||
|
||||
// A node in a symbol tree model.
|
||||
struct SymbolTreeNode
|
||||
class SymbolTreeNode
|
||||
{
|
||||
public:
|
||||
enum Tag
|
||||
@@ -49,16 +50,29 @@ public:
|
||||
|
||||
// Read the value from the VM memory, update liveness information, and
|
||||
// generate a display string. Returns true if the data changed.
|
||||
bool readFromVM(DebugInterface& cpu, const ccc::SymbolDatabase& database);
|
||||
bool readFromVM(
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database,
|
||||
const SymbolTreeDisplayOptions& display_options);
|
||||
|
||||
// Write the value back to the VM memory. Returns true on success.
|
||||
bool writeToVM(QVariant value, DebugInterface& cpu, const ccc::SymbolDatabase& database);
|
||||
bool writeToVM(
|
||||
QVariant value,
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database,
|
||||
const SymbolTreeDisplayOptions& display_options);
|
||||
|
||||
QVariant readValueAsVariant(const ccc::ast::Node& physical_type, DebugInterface& cpu, const ccc::SymbolDatabase& database) const;
|
||||
bool writeValueFromVariant(QVariant value, const ccc::ast::Node& physical_type, DebugInterface& cpu) const;
|
||||
|
||||
bool updateDisplayString(DebugInterface& cpu, const ccc::SymbolDatabase& database);
|
||||
QString generateDisplayString(const ccc::ast::Node& physical_type, DebugInterface& cpu, const ccc::SymbolDatabase& database, s32 depth) const;
|
||||
bool updateDisplayString(
|
||||
DebugInterface& cpu, const ccc::SymbolDatabase& database, const SymbolTreeDisplayOptions& display);
|
||||
QString generateDisplayString(
|
||||
const ccc::ast::Node& physical_type,
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database,
|
||||
const SymbolTreeDisplayOptions& display_options,
|
||||
s32 depth) const;
|
||||
|
||||
bool updateLiveness(DebugInterface& cpu);
|
||||
|
||||
@@ -80,7 +94,7 @@ public:
|
||||
|
||||
void sortChildrenRecursively(bool sort_by_if_type_is_known);
|
||||
|
||||
protected:
|
||||
private:
|
||||
QVariant m_value;
|
||||
QString m_display_value;
|
||||
std::optional<bool> m_liveness;
|
||||
@@ -90,3 +104,25 @@ protected:
|
||||
std::vector<std::unique_ptr<SymbolTreeNode>> m_children;
|
||||
bool m_children_fetched = false;
|
||||
};
|
||||
|
||||
// Settings that control how text in the value column is displayed, including
|
||||
// for the editor widgets.
|
||||
class SymbolTreeDisplayOptions
|
||||
{
|
||||
public:
|
||||
int integerBase() const;
|
||||
bool setIntegerBase(int base);
|
||||
|
||||
bool showLeadingZeroes() const;
|
||||
bool setShowLeadingZeroes(bool show);
|
||||
|
||||
std::optional<u64> stringToUnsignedInteger(QString string) const;
|
||||
QString unsignedIntegerToString(u64 value, s32 size_bits) const;
|
||||
|
||||
std::optional<s64> stringToSignedInteger(QString string) const;
|
||||
QString signedIntegerToString(s64 value, s32 size_bits) const;
|
||||
|
||||
private:
|
||||
int m_integer_base = 10;
|
||||
bool m_show_leading_zeroes = false;
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Debugger/SymbolTree/NewSymbolDialogs.h"
|
||||
#include "Debugger/SymbolTree/SymbolTreeDelegates.h"
|
||||
|
||||
#include <QtGui/QActionGroup>
|
||||
#include <QtGui/QClipboard>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMenu>
|
||||
@@ -81,6 +82,12 @@ void SymbolTreeView::toJson(JsonValueWrapper& json)
|
||||
{
|
||||
json.value().AddMember("sortByIfTypeIsKnown", m_sort_by_if_type_is_known, json.allocator());
|
||||
}
|
||||
|
||||
if (m_flags & ALLOW_TYPE_ACTIONS)
|
||||
{
|
||||
json.value().AddMember("integerBase", m_display_options.integerBase(), json.allocator());
|
||||
json.value().AddMember("showLeadingZeroes", m_display_options.showLeadingZeroes(), json.allocator());
|
||||
}
|
||||
}
|
||||
|
||||
bool SymbolTreeView::fromJson(const JsonValueWrapper& json)
|
||||
@@ -89,6 +96,7 @@ bool SymbolTreeView::fromJson(const JsonValueWrapper& json)
|
||||
return false;
|
||||
|
||||
bool needs_reset = false;
|
||||
bool needs_update = false;
|
||||
|
||||
auto show_size_column = json.value().FindMember("showSizeColumn");
|
||||
if (show_size_column != json.value().MemberEnd() && show_size_column->value.IsBool())
|
||||
@@ -131,8 +139,26 @@ bool SymbolTreeView::fromJson(const JsonValueWrapper& json)
|
||||
}
|
||||
}
|
||||
|
||||
if (m_flags & ALLOW_TYPE_ACTIONS)
|
||||
{
|
||||
auto integer_base = json.value().FindMember("integerBase");
|
||||
if (integer_base != json.value().MemberEnd() && integer_base->value.IsInt())
|
||||
needs_update |= m_display_options.setIntegerBase(integer_base->value.GetInt());
|
||||
|
||||
auto show_leading_zeroes = json.value().FindMember("showLeadingZeroes");
|
||||
if (show_leading_zeroes != json.value().MemberEnd() && show_leading_zeroes->value.IsBool())
|
||||
needs_update |= m_display_options.setShowLeadingZeroes(show_leading_zeroes->value.GetBool());
|
||||
}
|
||||
|
||||
if (needs_reset)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
else if (needs_update && m_model)
|
||||
{
|
||||
m_model->setDisplayOptions(m_display_options);
|
||||
updateVisibleNodes(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -221,6 +247,7 @@ void SymbolTreeView::expandGroups(QModelIndex index)
|
||||
void SymbolTreeView::setupTree()
|
||||
{
|
||||
m_model = new SymbolTreeModel(cpu(), this);
|
||||
m_model->setDisplayOptions(m_display_options);
|
||||
m_ui.treeView->setModel(m_model);
|
||||
|
||||
auto location_delegate = new SymbolTreeLocationDelegate(cpu(), m_symbol_address_alignment, this);
|
||||
@@ -556,6 +583,47 @@ void SymbolTreeView::openContextMenu(QPoint pos)
|
||||
QAction* change_type_temporarily = menu->addAction(tr("Change Type Temporarily"));
|
||||
change_type_temporarily->setEnabled(node_is_object);
|
||||
connect(change_type_temporarily, &QAction::triggered, this, &SymbolTreeView::onChangeTypeTemporarily);
|
||||
|
||||
struct IntegerDisplayBase
|
||||
{
|
||||
int base;
|
||||
QString name;
|
||||
};
|
||||
|
||||
const std::array<IntegerDisplayBase, 4> bases = {{
|
||||
{2, tr("Binary")},
|
||||
{8, tr("Octal")},
|
||||
{10, tr("Decimal")},
|
||||
{16, tr("Hexadecimal")},
|
||||
}};
|
||||
|
||||
QMenu* integer_base_menu = menu->addMenu(tr("Integer Base"));
|
||||
QActionGroup* base_actions = new QActionGroup(integer_base_menu);
|
||||
|
||||
for (const auto& [base, name] : bases)
|
||||
{
|
||||
QAction* base_action = integer_base_menu->addAction(name);
|
||||
base_action->setCheckable(true);
|
||||
base_action->setChecked(m_model->displayOptions().integerBase() == base);
|
||||
connect(base_action, &QAction::toggled, this, [this, base](bool checked) {
|
||||
m_display_options.setIntegerBase(base);
|
||||
m_model->setDisplayOptions(m_display_options);
|
||||
|
||||
updateVisibleNodes(false);
|
||||
});
|
||||
|
||||
base_actions->addAction(base_action);
|
||||
}
|
||||
|
||||
QAction* show_leading_zeroes = menu->addAction(tr("Show Leading Zeroes"));
|
||||
show_leading_zeroes->setCheckable(true);
|
||||
show_leading_zeroes->setChecked(m_model->displayOptions().showLeadingZeroes());
|
||||
connect(show_leading_zeroes, &QAction::toggled, this, [this](bool checked) {
|
||||
m_display_options.setShowLeadingZeroes(checked);
|
||||
m_model->setDisplayOptions(m_display_options);
|
||||
|
||||
updateVisibleNodes(false);
|
||||
});
|
||||
}
|
||||
|
||||
menu->popup(m_ui.treeView->viewport()->mapToGlobal(pos));
|
||||
@@ -855,8 +923,8 @@ std::vector<SymbolTreeView::SymbolWork> GlobalVariableTreeView::getSymbols(
|
||||
function_name = tr("unknown function");
|
||||
|
||||
QString name = QString("%1 (%2)")
|
||||
.arg(QString::fromStdString(local_variable.name()))
|
||||
.arg(function_name);
|
||||
.arg(QString::fromStdString(local_variable.name()))
|
||||
.arg(function_name);
|
||||
if (!testName(name, filter))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "Debugger/DebuggerView.h"
|
||||
#include "Debugger/SymbolTree/SymbolTreeModel.h"
|
||||
|
||||
class SymbolTreeValueDelegate;
|
||||
|
||||
// A symbol tree view with its associated refresh button, filter box and
|
||||
// right-click menu. Supports grouping, sorting and various other settings.
|
||||
class SymbolTreeView : public DebuggerView
|
||||
@@ -112,6 +114,8 @@ protected:
|
||||
bool m_group_by_section = false;
|
||||
bool m_group_by_source_file = false;
|
||||
bool m_sort_by_if_type_is_known = false;
|
||||
|
||||
SymbolTreeDisplayOptions m_display_options;
|
||||
};
|
||||
|
||||
class FunctionTreeView : public SymbolTreeView
|
||||
|
||||
@@ -116,6 +116,11 @@
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="blending">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Minimum</string>
|
||||
@@ -123,7 +128,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Basic (Recommended)</string>
|
||||
<string>Basic</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -121,7 +121,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_hw.dithering, "EmuCore/GS", "dithering_ps2", 2);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_hw.mipmapping, "EmuCore/GS", "hw_mipmap", true);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(
|
||||
sif, m_hw.blending, "EmuCore/GS", "accurate_blending_unit", static_cast<int>(AccBlendLevel::Basic));
|
||||
sif, m_hw.blending, "EmuCore/GS", "accurate_blending_unit", static_cast<int>(AccBlendLevel::Automatic), -1);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_hw.enableHWFixes, "EmuCore/GS", "UserHacks", false);
|
||||
connect(m_hw.upscaleMultiplier, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&GraphicsSettingsWidget::onUpscaleMultiplierChanged);
|
||||
|
||||
@@ -44,8 +44,8 @@ const char* InterfaceSettingsWidget::THEME_NAMES[] = {
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Sapphire (Black/Blue) [Dark]"),
|
||||
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Emerald (Black/Green) [Dark]"),
|
||||
//: "Custom.qss" must be kept as-is.
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Custom.qss [Drop in PCSX2 Folder]"),
|
||||
//: "custom.qss" must be kept as-is.
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "custom.qss [Drop in PCSX2 Folder]"),
|
||||
nullptr};
|
||||
|
||||
const char* InterfaceSettingsWidget::THEME_VALUES[] = {
|
||||
|
||||
@@ -12779,7 +12779,7 @@ Scanning recursively takes more time, but will identify files in subdirectories.
|
||||
<context>
|
||||
<name>GlobalVariableTreeView</name>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="855"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="923"/>
|
||||
<source>unknown function</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -16213,148 +16213,148 @@ Swap chain: see Microsoft's Terminology Portal.</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="233"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="238"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="243"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="248"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="253"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="258"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="266"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="234"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="239"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="244"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="249"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="254"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="259"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="267"/>
|
||||
<source>Save States</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="234"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="235"/>
|
||||
<source>Select Previous Save Slot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="239"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="240"/>
|
||||
<source>Select Next Save Slot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="244"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="245"/>
|
||||
<source>Save State To Selected Slot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="249"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="250"/>
|
||||
<source>Load State From Selected Slot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="254"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="255"/>
|
||||
<source>Load Backup State From Selected Slot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="259"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="260"/>
|
||||
<source>Save State and Select Next Slot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="267"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="268"/>
|
||||
<source>Select Next Slot and Save State</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="285"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="286"/>
|
||||
<source>Save State To Slot 1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="286"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="287"/>
|
||||
<source>Load State From Slot 1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="287"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="288"/>
|
||||
<source>Save State To Slot 2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="288"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="289"/>
|
||||
<source>Load State From Slot 2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="289"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="290"/>
|
||||
<source>Save State To Slot 3</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="290"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="291"/>
|
||||
<source>Load State From Slot 3</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="291"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="292"/>
|
||||
<source>Save State To Slot 4</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="292"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="293"/>
|
||||
<source>Load State From Slot 4</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="293"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="294"/>
|
||||
<source>Save State To Slot 5</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="294"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="295"/>
|
||||
<source>Load State From Slot 5</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="295"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="296"/>
|
||||
<source>Save State To Slot 6</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="296"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="297"/>
|
||||
<source>Load State From Slot 6</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="297"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="298"/>
|
||||
<source>Save State To Slot 7</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="298"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="299"/>
|
||||
<source>Load State From Slot 7</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="299"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="300"/>
|
||||
<source>Save State To Slot 8</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="300"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="301"/>
|
||||
<source>Load State From Slot 8</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="301"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="302"/>
|
||||
<source>Save State To Slot 9</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="302"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="303"/>
|
||||
<source>Load State From Slot 9</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="303"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="304"/>
|
||||
<source>Save State To Slot 10</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="304"/>
|
||||
<location filename="../../pcsx2/Hotkeys.cpp" line="305"/>
|
||||
<source>Load State From Slot 10</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -17000,12 +17000,6 @@ Right click to clear binding</source>
|
||||
<extracomment>Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="48"/>
|
||||
<source>Custom.qss [Drop in PCSX2 Folder]</source>
|
||||
<extracomment>"Custom.qss" must be kept as-is.</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="121"/>
|
||||
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="150"/>
|
||||
@@ -17095,6 +17089,12 @@ Right click to clear binding</source>
|
||||
<source>Fusion [Light/Dark]</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="48"/>
|
||||
<source>custom.qss [Drop in PCSX2 Folder]</source>
|
||||
<extracomment>"custom.qss" must be kept as-is.</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="157"/>
|
||||
<source>Pauses the emulator when a game is started.</source>
|
||||
@@ -21323,32 +21323,32 @@ Scanning recursively takes more time, but will identify files in subdirectories.
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="272"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="278"/>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="274"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="280"/>
|
||||
<source>Value</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="276"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="282"/>
|
||||
<source>Location</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="278"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="284"/>
|
||||
<source>Size</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="280"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="286"/>
|
||||
<source>Type</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="282"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeModel.cpp" line="288"/>
|
||||
<source>Liveness</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -21356,12 +21356,12 @@ Scanning recursively takes more time, but will identify files in subdirectories.
|
||||
<context>
|
||||
<name>SymbolTreeTypeDelegate</name>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeDelegates.cpp" line="464"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeDelegates.cpp" line="467"/>
|
||||
<source>Symbol no longer exists.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeDelegates.cpp" line="482"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeDelegates.cpp" line="485"/>
|
||||
<source>Cannot Change Type</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -21394,109 +21394,139 @@ Scanning recursively takes more time, but will identify files in subdirectories.
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="355"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="382"/>
|
||||
<source>(unknown source file)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="394"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="421"/>
|
||||
<source>(unknown section)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="439"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="466"/>
|
||||
<source>(unknown module)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="464"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="491"/>
|
||||
<source>Copy Name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="469"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="496"/>
|
||||
<source>Copy Mangled Name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="473"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="500"/>
|
||||
<source>Copy Location</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="478"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="624"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="505"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="692"/>
|
||||
<source>Rename Symbol</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="498"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="525"/>
|
||||
<source>Show Size Column</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="510"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="537"/>
|
||||
<source>Group by Module</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="518"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="545"/>
|
||||
<source>Group by Section</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="526"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="553"/>
|
||||
<source>Group by Source File</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="539"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="566"/>
|
||||
<source>Sort by if type is known</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="552"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="579"/>
|
||||
<source>Reset Children</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="556"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="583"/>
|
||||
<source>Change Type Temporarily</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="578"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="594"/>
|
||||
<source>Binary</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="595"/>
|
||||
<source>Octal</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="596"/>
|
||||
<source>Decimal</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="597"/>
|
||||
<source>Hexadecimal</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="600"/>
|
||||
<source>Integer Base</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="618"/>
|
||||
<source>Show Leading Zeroes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="646"/>
|
||||
<source>Confirm Deletion</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="578"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="646"/>
|
||||
<source>Delete '%1'?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="625"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="693"/>
|
||||
<source>Name:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="667"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="735"/>
|
||||
<source>Change Type To</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="668"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="736"/>
|
||||
<source>Type:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="672"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="683"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="740"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="751"/>
|
||||
<source>Cannot Change Type</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="672"/>
|
||||
<location filename="../Debugger/SymbolTree/SymbolTreeViews.cpp" line="740"/>
|
||||
<source>That node cannot have a type.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
||||
@@ -75,7 +75,7 @@ void InputIsoFile::BeginRead2(uint lsn)
|
||||
{
|
||||
// While this usually indicates that the ISO is corrupted, some games do attempt
|
||||
// to read past the end of the disc, so don't error here.
|
||||
ERROR_LOG("isoFile error: Block index is past the end of file! (%u >= %u).", lsn, m_blocks);
|
||||
ERROR_LOG("isoFile error: Block index is past the end of file! ({} >= {}).", lsn, m_blocks);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -327,8 +327,9 @@ enum class TriFiltering : s8
|
||||
Forced,
|
||||
};
|
||||
|
||||
enum class AccBlendLevel : u8
|
||||
enum class AccBlendLevel : s8
|
||||
{
|
||||
Automatic = -1,
|
||||
Minimum,
|
||||
Basic,
|
||||
Medium,
|
||||
@@ -811,7 +812,7 @@ struct Pcsx2Config
|
||||
GSRendererType Renderer = GSRendererType::Auto;
|
||||
float UpscaleMultiplier = 1.0f;
|
||||
|
||||
AccBlendLevel AccurateBlendingUnit = AccBlendLevel::Basic;
|
||||
AccBlendLevel AccurateBlendingUnit = AccBlendLevel::Automatic;
|
||||
BiFiltering TextureFiltering = BiFiltering::PS2;
|
||||
TexturePreloadingLevel TexturePreloading = TexturePreloadingLevel::Full;
|
||||
GSDumpCompressionMethod GSDumpCompression = GSDumpCompressionMethod::Zstandard;
|
||||
|
||||
@@ -2741,12 +2741,6 @@ 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 (draw_ds && config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne &&
|
||||
m_features.multidraw_fb_copy && (config.require_one_barrier || config.require_full_barrier))
|
||||
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)
|
||||
|
||||
@@ -5180,6 +5180,8 @@ void GSRendererHW::EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt, GS
|
||||
enable_fbmask_emulation = true;
|
||||
break;
|
||||
case AccBlendLevel::Basic:
|
||||
case AccBlendLevel::Automatic:
|
||||
default:
|
||||
// Enable Fbmask emulation excluding triangle class because it is quite slow.
|
||||
enable_fbmask_emulation = (m_vt.m_primclass != GS_TRIANGLE_CLASS);
|
||||
break;
|
||||
@@ -5204,7 +5206,7 @@ void GSRendererHW::EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt, GS
|
||||
|
||||
// If date is enabled you need to test the green channel instead of the alpha channel.
|
||||
// Only enable this code in DATE mode to reduce the number of shaders.
|
||||
m_conf.ps.write_rg = (process_rg & SHUFFLE_WRITE) && m_cached_ctx.TEST.DATE;
|
||||
m_conf.ps.write_rg = (process_rg & SHUFFLE_WRITE) && (features.texture_barrier || features.multidraw_fb_copy) && m_cached_ctx.TEST.DATE;
|
||||
m_conf.ps.real16src = m_copy_16bit_to_target_shuffle;
|
||||
m_conf.ps.shuffle_same = m_same_group_texture_shuffle;
|
||||
// Please bang my head against the wall!
|
||||
@@ -5784,7 +5786,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||
const bool blend_ad = m_conf.ps.blend_c == 1;
|
||||
const bool alpha_mask = (m_cached_ctx.FRAME.FBMSK & 0xFF000000) == 0xFF000000;
|
||||
bool blend_ad_alpha_masked = blend_ad && alpha_mask;
|
||||
const bool is_basic_blend = GSConfig.AccurateBlendingUnit >= AccBlendLevel::Basic;
|
||||
const bool is_basic_blend = GSConfig.AccurateBlendingUnit != AccBlendLevel::Minimum;
|
||||
if (blend_ad_alpha_masked && (((is_basic_blend || (COLCLAMP.CLAMP == 0)) && (features.texture_barrier || features.multidraw_fb_copy))
|
||||
|| ((GSConfig.AccurateBlendingUnit >= AccBlendLevel::Medium) || m_conf.require_one_barrier)))
|
||||
{
|
||||
@@ -5894,6 +5896,8 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||
sw_blending |= m_vt.m_primclass == GS_SPRITE_CLASS && m_drawlist.size() < 100;
|
||||
[[fallthrough]];
|
||||
case AccBlendLevel::Basic:
|
||||
case AccBlendLevel::Automatic:
|
||||
default:
|
||||
// Prefer sw blend if possible.
|
||||
color_dest_blend &= !prefer_sw_blend;
|
||||
color_dest_blend2 &= !prefer_sw_blend;
|
||||
@@ -5935,6 +5939,8 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||
sw_blending |= !(blend_ad_alpha_masked || ad_second_pass) && (alpha_c1_high_max_one || alpha_c1_high_no_rta_correct) && no_prim_overlap;
|
||||
[[fallthrough]];
|
||||
case AccBlendLevel::Basic:
|
||||
case AccBlendLevel::Automatic:
|
||||
default:
|
||||
// Prefer sw blend if possible.
|
||||
color_dest_blend &= !prefer_sw_blend;
|
||||
color_dest_blend2 &= !prefer_sw_blend;
|
||||
@@ -6441,7 +6447,8 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||
// Switch DATE_PRIMID with DATE_BARRIER in such cases to ensure accuracy.
|
||||
// No mix of COLCLIP + sw blend + DATE_PRIMID, neither sw fbmask + DATE_PRIMID.
|
||||
// Note: Do the swap in the end, saves the expensive draw splitting/barriers when mixed software blending is used.
|
||||
if (sw_blending && DATE_PRIMID && m_conf.require_full_barrier)
|
||||
if (sw_blending && DATE_PRIMID && m_conf.require_full_barrier &&
|
||||
(features.texture_barrier || (features.multidraw_fb_copy && !no_prim_overlap)))
|
||||
{
|
||||
GL_PERF("DATE: Swap DATE_PRIMID with DATE_BARRIER");
|
||||
DATE_PRIMID = false;
|
||||
@@ -6869,7 +6876,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
|
||||
{
|
||||
m_conf.tex = nullptr;
|
||||
m_conf.ps.tex_is_fb = true;
|
||||
if (m_prim_overlap == PRIM_OVERLAP_NO || !g_gs_device->Features().texture_barrier)
|
||||
if (m_prim_overlap == PRIM_OVERLAP_NO || !(g_gs_device->Features().texture_barrier || g_gs_device->Features().multidraw_fb_copy))
|
||||
m_conf.require_one_barrier = true;
|
||||
else
|
||||
m_conf.require_full_barrier = true;
|
||||
@@ -7129,21 +7136,14 @@ bool GSRendererHW::CanUseTexIsFB(const GSTextureCache::Target* rt, const GSTextu
|
||||
return false;
|
||||
}
|
||||
|
||||
// If it's a channel shuffle, tex-is-fb should be fine, even on DX.
|
||||
// If it's a channel shuffle, tex-is-fb should be fine.
|
||||
if (m_channel_shuffle)
|
||||
{
|
||||
GL_CACHE("HW: Enabling tex-is-fb for channel shuffle.");
|
||||
return true;
|
||||
}
|
||||
|
||||
// No barriers -> we can't use tex-is-fb.
|
||||
if (!g_gs_device->Features().texture_barrier)
|
||||
{
|
||||
GL_CACHE("HW: Disabling tex-is-fb due to no barriers.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If it's a channel shuffle, tex-is-fb is always fine, except on DX.
|
||||
// If it's a channel shuffle, tex-is-fb is always fine.
|
||||
if (m_texture_shuffle)
|
||||
{
|
||||
// We can't do tex is FB if the source and destination aren't pointing to the same bit of texture.
|
||||
@@ -7154,6 +7154,13 @@ bool GSRendererHW::CanUseTexIsFB(const GSTextureCache::Target* rt, const GSTextu
|
||||
return true;
|
||||
}
|
||||
|
||||
// No barriers -> we can't use tex-is-fb when there's overlap.
|
||||
if (!(g_gs_device->Features().texture_barrier || g_gs_device->Features().multidraw_fb_copy) && m_prim_overlap != PRIM_OVERLAP_NO)
|
||||
{
|
||||
GL_CACHE("HW: Disabling tex-is-fb due to no barriers.");
|
||||
return false;
|
||||
}
|
||||
|
||||
static constexpr auto check_clamp = [](u32 clamp, u32 min, u32 max, s32 tmin, s32 tmax) {
|
||||
if (clamp == CLAMP_REGION_CLAMP)
|
||||
{
|
||||
@@ -7969,8 +7976,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
||||
}
|
||||
else if (DATE_one)
|
||||
{
|
||||
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)
|
||||
if (features.texture_barrier)
|
||||
{
|
||||
m_conf.require_one_barrier = true;
|
||||
m_conf.ps.date = 5 + m_cached_ctx.TEST.DATM;
|
||||
@@ -9544,7 +9550,7 @@ void GSRendererHW::EndHLEHardwareDraw(bool force_copy_on_hazard /* = false */)
|
||||
{
|
||||
const GSDevice::FeatureSupport features = g_gs_device->Features();
|
||||
|
||||
if (!force_copy_on_hazard && config.tex == config.rt && features.texture_barrier)
|
||||
if (!force_copy_on_hazard && config.tex == config.rt)
|
||||
{
|
||||
// Sample RT 1:1.
|
||||
config.require_one_barrier = !features.framebuffer_fetch;
|
||||
|
||||
@@ -664,10 +664,10 @@ bool GameDatabaseSchema::GameEntry::configMatchesHWFix(const Pcsx2Config::GSOpti
|
||||
return (config.GPUPaletteConversion == ((value > 1) ? (config.TexturePreloading == TexturePreloadingLevel::Full) : (value != 0)));
|
||||
|
||||
case GSHWFixId::MinimumBlendingLevel:
|
||||
return (static_cast<int>(config.AccurateBlendingUnit) >= value);
|
||||
return (config.AccurateBlendingUnit == AccBlendLevel::Automatic || static_cast<int>(config.AccurateBlendingUnit) >= value);
|
||||
|
||||
case GSHWFixId::MaximumBlendingLevel:
|
||||
return (static_cast<int>(config.AccurateBlendingUnit) <= value);
|
||||
return (config.AccurateBlendingUnit == AccBlendLevel::Automatic || static_cast<int>(config.AccurateBlendingUnit) <= value);
|
||||
|
||||
case GSHWFixId::RecommendedBlendingLevel:
|
||||
return true;
|
||||
@@ -868,21 +868,23 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
|
||||
|
||||
case GSHWFixId::MinimumBlendingLevel:
|
||||
{
|
||||
if (value >= 0 && value <= static_cast<int>(AccBlendLevel::Maximum))
|
||||
config.AccurateBlendingUnit = std::max(config.AccurateBlendingUnit, static_cast<AccBlendLevel>(value));
|
||||
if (value >= 0 && value <= static_cast<int>(AccBlendLevel::Maximum) && config.AccurateBlendingUnit == AccBlendLevel::Automatic)
|
||||
config.AccurateBlendingUnit = static_cast<AccBlendLevel>(value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSHWFixId::MaximumBlendingLevel:
|
||||
{
|
||||
if (value >= 0 && value <= static_cast<int>(AccBlendLevel::Maximum))
|
||||
config.AccurateBlendingUnit = std::min(config.AccurateBlendingUnit, static_cast<AccBlendLevel>(value));
|
||||
if (value >= 0 && value <= static_cast<int>(AccBlendLevel::Maximum) && config.AccurateBlendingUnit == AccBlendLevel::Automatic)
|
||||
config.AccurateBlendingUnit = static_cast<AccBlendLevel>(value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSHWFixId::RecommendedBlendingLevel:
|
||||
{
|
||||
if (!is_sw_renderer && value >= 0 && value <= static_cast<int>(AccBlendLevel::Maximum) && static_cast<int>(EmuConfig.GS.AccurateBlendingUnit) < value)
|
||||
// Need to increment by 1 because Automatic is -1.
|
||||
const int blend_level = static_cast<int>(config.AccurateBlendingUnit) + 1;
|
||||
if (!is_sw_renderer && value >= static_cast<int>(AccBlendLevel::Automatic) && value <= static_cast<int>(AccBlendLevel::Maximum) && blend_level < value)
|
||||
{
|
||||
Host::AddKeyedOSDMessage("HWBlendingWarning",
|
||||
fmt::format(TRANSLATE_FS("GameDatabase",
|
||||
@@ -891,8 +893,7 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
|
||||
"You can adjust the blending level in Game Properties to improve\n"
|
||||
"graphical quality, but this will increase system requirements."),
|
||||
ICON_FA_PAINTBRUSH,
|
||||
Pcsx2Config::GSOptions::BlendingLevelNames[static_cast<int>(
|
||||
EmuConfig.GS.AccurateBlendingUnit)],
|
||||
Pcsx2Config::GSOptions::BlendingLevelNames[blend_level],
|
||||
Pcsx2Config::GSOptions::BlendingLevelNames[value]),
|
||||
Host::OSD_WARNING_DURATION);
|
||||
}
|
||||
|
||||
@@ -4066,8 +4066,9 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
|
||||
FSUI_NSTR("Force 32bit"),
|
||||
};
|
||||
static constexpr const char* s_blending_options[] = {
|
||||
FSUI_NSTR("Automatic (Default)"),
|
||||
FSUI_NSTR("Minimum"),
|
||||
FSUI_NSTR("Basic (Recommended)"),
|
||||
FSUI_NSTR("Basic"),
|
||||
FSUI_NSTR("Medium"),
|
||||
FSUI_NSTR("High"),
|
||||
FSUI_NSTR("Full (Slow)"),
|
||||
@@ -4199,7 +4200,7 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
|
||||
"EmuCore/GS", "dithering_ps2", 2, s_dithering_options, std::size(s_dithering_options), true);
|
||||
DrawIntListSetting(bsi, FSUI_ICONSTR(ICON_FA_SPLOTCH, "Blending Accuracy"),
|
||||
FSUI_CSTR("Determines the level of accuracy when emulating blend modes not supported by the host graphics API."), "EmuCore/GS",
|
||||
"accurate_blending_unit", static_cast<int>(AccBlendLevel::Basic), s_blending_options, std::size(s_blending_options), true);
|
||||
"accurate_blending_unit", static_cast<int>(AccBlendLevel::Automatic), s_blending_options, std::size(s_blending_options), true);
|
||||
DrawToggleSetting(
|
||||
bsi, FSUI_ICONSTR(ICON_FA_BULLSEYE, "Mipmapping"), FSUI_CSTR("Enables emulation of the GS's texture mipmapping."), "EmuCore/GS", "hw_mipmap", true);
|
||||
}
|
||||
|
||||
@@ -653,6 +653,7 @@ const char* Pcsx2Config::GSOptions::FMVAspectRatioSwitchNames[(size_t)FMVAspectR
|
||||
nullptr};
|
||||
|
||||
const char* Pcsx2Config::GSOptions::BlendingLevelNames[] = {
|
||||
"Automatic",
|
||||
"Minimum",
|
||||
"Basic",
|
||||
"Medium",
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
/// Version number for GS and other shaders. Increment whenever any of the contents of the
|
||||
/// shaders change, to invalidate the cache.
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 71;
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 72;
|
||||
|
||||
@@ -3150,12 +3150,12 @@ void VMManager::WarnAboutUnsafeSettings()
|
||||
if (EmuConfig.GS.TriFilter != TriFiltering::Automatic)
|
||||
{
|
||||
append(ICON_FA_PAGER,
|
||||
TRANSLATE_SV("VMManager", "Trilinear filtering is not set to automatic. This may break rendering in some games."));
|
||||
TRANSLATE_SV("VMManager", "Trilinear filtering is not set to Automatic. This may break rendering in some games."));
|
||||
}
|
||||
if (EmuConfig.GS.AccurateBlendingUnit <= AccBlendLevel::Minimum)
|
||||
if (EmuConfig.GS.AccurateBlendingUnit == AccBlendLevel::Minimum)
|
||||
{
|
||||
append(ICON_FA_PAINTBRUSH,
|
||||
TRANSLATE_SV("VMManager", "Blending Accuracy is below Basic, this may break effects in some games."));
|
||||
TRANSLATE_SV("VMManager", "Blending Accuracy is set to Minimum. This may break rendering in some games."));
|
||||
}
|
||||
if (EmuConfig.GS.HWDownloadMode != GSHardwareDownloadMode::Enabled)
|
||||
{
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include "GS/GSVector.h"
|
||||
|
||||
#include <bit>
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
@@ -109,16 +111,6 @@ vtlb_private::VTLBVirtual::VTLBVirtual(VTLBPhysical phys, u32 paddr, u32 vaddr)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_M_X86)
|
||||
#include <immintrin.h>
|
||||
#elif defined(_M_ARM64)
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#include <arm64_neon.h>
|
||||
#else
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__inline int CheckCache(u32 addr)
|
||||
{
|
||||
// Check if the cache is enabled
|
||||
@@ -130,83 +122,28 @@ __inline int CheckCache(u32 addr)
|
||||
size_t i = 0;
|
||||
const size_t size = cachedTlbs.count;
|
||||
|
||||
#if defined(_M_X86)
|
||||
const int stride = 4;
|
||||
|
||||
const __m128i addr_vec = _mm_set1_epi32(addr);
|
||||
const GSVector4i addr_vec = GSVector4i::load(addr);
|
||||
|
||||
for (; i + stride <= size; i += stride)
|
||||
{
|
||||
const __m128i pfn1_vec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&cachedTlbs.PFN1s[i]));
|
||||
const __m128i pfn0_vec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&cachedTlbs.PFN0s[i]));
|
||||
const __m128i mask_vec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&cachedTlbs.PageMasks[i]));
|
||||
const GSVector4i pfn1_vec = GSVector4i::load<true>(&cachedTlbs.PFN1s[i]);
|
||||
const GSVector4i pfn0_vec = GSVector4i::load<true>(&cachedTlbs.PFN0s[i]);
|
||||
const GSVector4i mask_vec = GSVector4i::load<true>(&cachedTlbs.PageMasks[i]);
|
||||
|
||||
const __m128i cached1_vec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&cachedTlbs.CacheEnabled1[i]));
|
||||
const __m128i cached0_vec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&cachedTlbs.CacheEnabled0[i]));
|
||||
const GSVector4i cached1_enable_vec = GSVector4i::load<true>(&cachedTlbs.CacheEnabled1[i]);
|
||||
const GSVector4i cached0_enable_vec = GSVector4i::load<true>(&cachedTlbs.CacheEnabled0[i]);
|
||||
|
||||
const __m128i pfn1_end_vec = _mm_add_epi32(pfn1_vec, mask_vec);
|
||||
const __m128i pfn0_end_vec = _mm_add_epi32(pfn0_vec, mask_vec);
|
||||
const GSVector4i cmp1 = addr_vec.ge32(pfn1_vec) & addr_vec.le32(pfn1_vec + mask_vec);
|
||||
const GSVector4i cmp0 = addr_vec.ge32(pfn0_vec) & addr_vec.le32(pfn1_vec + mask_vec);
|
||||
|
||||
// pfn0 <= addr
|
||||
const __m128i gteLowerBound0 = _mm_or_si128(
|
||||
_mm_cmpgt_epi32(addr_vec, pfn0_vec),
|
||||
_mm_cmpeq_epi32(addr_vec, pfn0_vec));
|
||||
// pfn0 + mask >= addr
|
||||
const __m128i gteUpperBound0 = _mm_or_si128(
|
||||
_mm_cmpgt_epi32(pfn0_end_vec, addr_vec),
|
||||
_mm_cmpeq_epi32(pfn0_end_vec, addr_vec));
|
||||
const GSVector4i lanes_enabled = (cmp1 & cached1_enable_vec) | (cmp0 & cached0_enable_vec);
|
||||
|
||||
// pfn1 <= addr
|
||||
const __m128i gteUpperBound1 = _mm_or_si128(
|
||||
_mm_cmpgt_epi32(pfn1_end_vec, addr_vec),
|
||||
_mm_cmpeq_epi32(pfn1_end_vec, addr_vec));
|
||||
// pfn1 + mask >= addr
|
||||
const __m128i gteLowerBound1 = _mm_or_si128(
|
||||
_mm_cmpgt_epi32(addr_vec, pfn1_vec),
|
||||
_mm_cmpeq_epi32(addr_vec, pfn1_vec));
|
||||
|
||||
// pfn0 <= addr <= pfn0 + mask
|
||||
__m128i cmp0 = _mm_and_si128(gteLowerBound0, gteUpperBound0);
|
||||
// pfn1 <= addr <= pfn1 + mask
|
||||
__m128i cmp1 = _mm_and_si128(gteLowerBound1, gteUpperBound1);
|
||||
|
||||
cmp1 = _mm_and_si128(cmp1, cached1_vec);
|
||||
cmp0 = _mm_and_si128(cmp0, cached0_vec);
|
||||
|
||||
const __m128i cmp = _mm_or_si128(cmp1, cmp0);
|
||||
|
||||
if (!_mm_testz_si128(cmp, cmp))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#elif defined(_M_ARM64)
|
||||
const int stride = 4;
|
||||
|
||||
const uint32x4_t addr_vec = vld1q_dup_u32(&addr);
|
||||
|
||||
for (; i + stride <= size; i += stride)
|
||||
{
|
||||
const uint32x4_t pfn1_vec = vld1q_u32(&cachedTlbs.PFN1s[i]);
|
||||
const uint32x4_t pfn0_vec = vld1q_u32(&cachedTlbs.PFN0s[i]);
|
||||
const uint32x4_t mask_vec = vld1q_u32(&cachedTlbs.PageMasks[i]);
|
||||
|
||||
const uint32x4_t cached1_vec = vld1q_u32(&cachedTlbs.CacheEnabled1[i]);
|
||||
const uint32x4_t cached0_vec = vld1q_u32(&cachedTlbs.CacheEnabled0[i]);
|
||||
|
||||
const uint32x4_t pfn1_end_vec = vaddq_u32(pfn1_vec, mask_vec);
|
||||
const uint32x4_t pfn0_end_vec = vaddq_u32(pfn0_vec, mask_vec);
|
||||
|
||||
const uint32x4_t cmp1 = vandq_u32(vcgeq_u32(addr_vec, pfn1_vec), vcleq_u32(addr_vec, pfn1_end_vec));
|
||||
const uint32x4_t cmp0 = vandq_u32(vcgeq_u32(addr_vec, pfn0_vec), vcleq_u32(addr_vec, pfn0_end_vec));
|
||||
|
||||
const uint32x4_t lanes_enabled = vorrq_u32(vandq_u32(cached1_vec, cmp1), vandq_u32(cached0_vec, cmp0));
|
||||
|
||||
const uint32x2_t tmp = vorr_u32(vget_low_u32(lanes_enabled), vget_high_u32(lanes_enabled));
|
||||
if (vget_lane_u32(vpmax_u32(tmp, tmp), 0))
|
||||
if (!lanes_enabled.allfalse())
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; i < size; i++)
|
||||
{
|
||||
const u32 mask = cachedTlbs.PageMasks[i];
|
||||
@@ -637,7 +574,7 @@ static void TAKES_R128 vtlbUnmappedVWriteLg(u32 addr, r128 data) { vtlb_Miss(add
|
||||
template <typename OperandType>
|
||||
static OperandType vtlbUnmappedPReadSm(u32 addr) {
|
||||
vtlb_BusError(addr, 0);
|
||||
if(!CHECK_EEREC && CHECK_CACHE && CheckCache(addr)){
|
||||
if (!CHECK_EEREC && CHECK_CACHE && CheckCache(addr)){
|
||||
switch (sizeof(OperandType)) {
|
||||
case 1: return readCache8(addr, false);
|
||||
case 2: return readCache16(addr, false);
|
||||
|
||||
Reference in New Issue
Block a user