Compare commits

...

46 Commits

Author SHA1 Message Date
KamFretoZ
4f561aa9e9 Qt/Cheats: Add tooltip to cheat descriptions 2025-04-08 12:26:29 +02:00
PCSX2 Bot
8c1c4df10d [ci skip] PAD: Update to latest controller database. 2025-04-08 12:25:48 +02:00
PCSX2 Bot
a9e963e84b [ci skip] Qt: Update Base Translation. 2025-04-06 20:06:38 -04:00
JordanTheToaster
4a509610fe GameListWidget: Enable mouse tracking 2025-04-06 22:07:23 +02:00
JordanTheToaster
7de5066c87 VMManager: Add warning for debug device 2025-04-06 19:07:53 +02:00
JordanTheToaster
24b1be1dd2 OSD: Append debug device so Kam doesn't forget 2025-04-06 19:07:53 +02:00
JordanTheToaster
ee00213961 PerformanceMetrics: Revert increased update rate
It seems our OSD does not like updating at 0.25 per tick so let's just go back for now.
2025-04-06 19:07:53 +02:00
JordanTheToaster
b51b32c758 UI: Move Skip Presenting Duplicate Frames to Emulation Tab 2025-04-06 19:07:53 +02:00
JordanTheToaster
d16e669538 GameListWidget: Bodge broken icon styling in native theme
Still a bodge but this will fix the styling being missing on every other line on the type column.
2025-04-06 19:05:43 +02:00
JordanTheToaster
50d258fae9 Deps: Update Windows and Linux to Qt 6.9.0 2025-04-06 19:05:43 +02:00
chaoticgd
494cceff73 Deps: Update KDDockWidgets to 2.2.3 2025-04-05 20:50:54 +02:00
PCSX2 Bot
9885e61962 [ci skip] Qt: Update Base Translation. 2025-04-05 20:48:45 +02:00
chaoticgd
4b88a290c4 Qt: Destroy settings save timer before quitting 2025-04-05 00:48:54 +02:00
chaoticgd
ee8335e5f1 Debugger: Prevent blinking animation when stepping 2025-04-05 00:47:56 +02:00
JimScript
fcde7fdb80 GameDB: R&C Size Matters HPO Native with Texture Offset 2025-04-04 10:57:32 -04:00
JimScript
3d42da3e97 GameDB: R&C Size Matters HPO Native with Texture Offset 2025-04-04 10:57:32 -04:00
Berylskid
c81a37b740 GameDB: HPO update for Armored Core games 2025-04-04 02:31:08 +02:00
ElTioRata
4fa005ade0 GameDB: resident evil 4 - HPO Native w/ Texture Offset
Added 'Align to Native w/ Texture Offset'
2025-04-04 02:29:53 +02:00
PCSX2 Bot
bf656e892f [ci skip] Qt: Update Base Translation. 2025-04-04 02:29:37 +02:00
chaoticgd
abf074eaf4 Debugger: Fix some theming issues 2025-04-03 16:13:50 +02:00
chaoticgd
47657b51ab Debugger: Extract custom menu bar as its own class 2025-04-03 16:13:50 +02:00
PCSX2 Bot
76f8ffeb90 [ci skip] Qt: Update Base Translation. 2025-04-03 02:12:13 +02:00
TellowKrinkle
e68ae91b59 MacOS: Mark our help menu as the macOS help menu
This gives it a nice search box for searching other menus
2025-04-02 18:48:34 -04:00
JordanTheToaster
9222c21b4a Deps: Move Mac Qt download link to archive 2025-04-02 16:11:22 -04:00
chaoticgd
c837d9c91c Qt: Fix custom scan range settings and make sure to save symbol sources 2025-04-02 20:34:17 +02:00
JordanTheToaster
cdf7bef150 Deps: Update SDL to 3.2.10 2025-04-02 20:32:56 +02:00
PCSX2 Bot
eb52da9702 [ci skip] PAD: Update to latest controller database. 2025-04-02 20:31:11 +02:00
chaoticgd
8a1f2a151d Qt: Add GammaRay build scripts 2025-03-29 09:43:11 -04:00
lightningterror
1b4ced3e55 GS/HW: Don't use coverage when doing Af or Ad blend. 2025-03-27 21:27:06 +01:00
refractionpcsx2
29cd068dbd GS/HW: Fix typo on Tekken 5 CRC 2025-03-27 20:13:21 +00:00
TellowKrinkle
6681614f1a Core:Rec: Adjust bounds check asserts to not erroneously trip 2025-03-26 22:57:21 -04:00
PCSX2 Bot
1030db87d4 [ci skip] Qt: Update Base Translation. 2025-03-27 01:03:25 +01:00
JordanTheToaster
356ab30e89 3rdparty: Update CPUInfo to commit 5e3d2445e6a84d9599bee2bf78edbb4d80865e1d 2025-03-26 16:37:49 -04:00
KamFretoZ
0f09b8df77 BPM: GPU CLUT to FSUI 2025-03-26 10:54:55 -04:00
PCSX2 Bot
23c495b939 [ci skip] Qt: Update Base Translation. 2025-03-25 18:14:23 +01:00
PCSX2 Bot
2ac0420903 [ci skip] PAD: Update to latest controller database. 2025-03-25 18:14:06 +01:00
TellowKrinkle
aae070f826 GS:MTL: Avoid WC memory on Ryzen hackintoshes 2025-03-25 11:38:24 -04:00
chaoticgd
6ad825d1e0 Debugger: Fix Visual Studio filters 2025-03-24 20:00:35 -05:00
TellowKrinkle
7910506b3c GS:HW: Avoid using blend + fbfetch for AFAIL RGB_ONLY 2025-03-22 15:47:37 -05:00
chaoticgd
5393d724c5 Debugger: Fix crash during breakpoint deletion 2025-03-22 13:53:48 -04:00
JordanTheToaster
c8b1e4c4e6 3rdparty: Update ImGui to v1.91.9b 2025-03-22 12:13:20 -04:00
Ziemas
d373cb602d IOP Debug: allow reading ROM 2025-03-22 11:42:26 -04:00
lightningterror
58f195fc04 GS/HW: Adjust AA1 draw behavior.
Make sure we use coverage alpha on aa1 draw when there's no blending.

Make sure we set coverage alpha to 128 in vertex trace alpha min max.

Some const and cast cleanup.
2025-03-20 20:44:31 +01:00
refractionpcsx2
f6675808fc GS/Runner: Set the screenshot compression low to stop slow dump times 2025-03-20 14:19:47 +00:00
PCSX2 Bot
aa64712354 [ci skip] Qt: Update Base Translation. 2025-03-20 11:14:07 +01:00
chaoticgd
f6e2185c9c Debugger: Don't jump to PC if the breakpoint code paused the core 2025-03-18 22:04:41 -04:00
75 changed files with 6572 additions and 5475 deletions

View File

@@ -19,10 +19,10 @@ LIBJPEGTURBO=3.1.0
LIBPNG=1.6.45
LIBWEBP=1.5.0
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
SDL=SDL3-3.2.8
QT=6.8.2
SDL=SDL3-3.2.10
QT=6.9.0
ZSTD=1.5.7
KDDOCKWIDGETS=2.2.1
KDDOCKWIDGETS=2.2.3
SHADERC=2024.1
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
@@ -38,19 +38,19 @@ fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03 $SDL.tar.gz
f87be7b4dec66db4098e9c167b2aa34e2ca10aeb5443bdde95ae03185ed513e0 $SDL.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
012043ce6d411e6e8a91fdc4e05e6bedcfa10fcb1347d3c33908f7fdd10dfe05 qtbase-everywhere-src-$QT.tar.xz
d2a1bbb84707b8a0aec29227b170be00f04383fbf2361943596d09e7e443c8e1 qtimageformats-everywhere-src-$QT.tar.xz
aa2579f21ca66d19cbcf31d87e9067e07932635d36869c8239d4decd0a9dc1fa qtsvg-everywhere-src-$QT.tar.xz
326381b7d43f07913612f291abc298ae79bd95382e2233abce982cff2b53d2c0 qttools-everywhere-src-$QT.tar.xz
d2106e8a580bfd77702c4c1840299288d344902b0e2c758ca813ea04c6d6a3d1 qttranslations-everywhere-src-$QT.tar.xz
5e46157908295f2bf924462d8c0855b0508ba338ced9e810891fefa295dc9647 qtwayland-everywhere-src-$QT.tar.xz
c1800c2ea835801af04a05d4a32321d79a93954ee3ae2172bbeacf13d1f0598c qtbase-everywhere-src-$QT.tar.xz
2047c6242a57bf97cf40079fa9f91752c137cd9ae84760faa9a2e5e8a440606f qtimageformats-everywhere-src-$QT.tar.xz
ec359d930c95935ea48af58b100c2f5d0d275968ec8ca1e0e76629b7159215fc qtsvg-everywhere-src-$QT.tar.xz
fa645589cc3f939022401a926825972a44277dead8ec8607d9f2662e6529c9a4 qttools-everywhere-src-$QT.tar.xz
1d5581ef5fc7c7bc556f2403017983683993bbebfcdf977ef8f180f604668c3f qttranslations-everywhere-src-$QT.tar.xz
503416fcb04db503bd130e6a49c45e3e546f091e83406f774a0c703130c91805 qtwayland-everywhere-src-$QT.tar.xz
eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADERC.tar.gz
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
8693e06abee0c88517d8480b22647702a51a0708f3c876ed5385d9a4e356e1a5 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
b8529755b2d54205341766ae168e83177c6120660539f9afba71af6bca4b81ec KDDockWidgets-$KDDOCKWIDGETS.tar.gz
EOF
curl -L \
@@ -193,32 +193,9 @@ echo "Installing Qt Tools..."
rm -fr "qttools-everywhere-src-$QT"
tar xf "qttools-everywhere-src-$QT.tar.xz"
cd "qttools-everywhere-src-$QT"
# Force disable clang scanning, it gets very confused.
patch -u configure.cmake <<EOF
--- configure.cmake
+++ configure.cmake
@@ -14,12 +14,12 @@
# Presumably because 6.0 ClangConfig.cmake files are not good enough?
# In any case explicitly request a minimum version of 8.x for now, otherwise
# building with CMake will fail at compilation time.
-qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang)
+#qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang)
# special case end
-if(TARGET WrapLibClang::WrapLibClang)
- set(TEST_libclang "ON" CACHE BOOL "Required libclang version found." FORCE)
-endif()
+#if(TARGET WrapLibClang::WrapLibClang)
+# set(TEST_libclang "ON" CACHE BOOL "Required libclang version found." FORCE)
+#endif()
EOF
mkdir build
cd build
"$INSTALLDIR/bin/qt-configure-module" .. -- -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=ON -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
"$INSTALLDIR/bin/qt-configure-module" .. -- -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
cmake --build . --parallel
ninja install
cd ../../

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env bash
set -e
if [ "$#" -ne 2 ]; then
echo "Syntax: $0 <deps directory> <output directory>"
exit 1
fi
DEPSDIR=$(realpath "$1")
INSTALLDIR=$(realpath "$2")
if [ ! -d "$DEPSDIR/include/QtCore" ]; then
echo "Error: The build-dependencies-qt.sh script must be run on the deps directory first."
exit 1
fi
GAMMARAY=master
mkdir -p gammaray-build
cd gammaray-build
echo "Downloading..."
curl -L -o "GammaRay-$GAMMARAY.tar.gz" https://github.com/KDAB/GammaRay/archive/$GAMMARAY.tar.gz
rm -fr "GammaRay-$GAMMARAY"
echo "Extracting..."
tar xf "GammaRay-$GAMMARAY.tar.gz"
cd "GammaRay-$GAMMARAY"
mkdir build
cd build
echo "Configuring..."
cmake -DCMAKE_PREFIX_PATH="$DEPSDIR" -G Ninja -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DGAMMARAY_BUILD_DOCS=false ..
echo "Building..."
cmake --build . --parallel
echo "Installing..."
cmake --build . --target install
cd ../..
echo "Cleaning up..."
cd ..
rm -r gammaray-build

View File

@@ -14,8 +14,8 @@
"sources": [
{
"type": "archive",
"url": "https://libsdl.org/release/SDL3-3.2.8.tar.gz",
"sha256": "13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03"
"url": "https://libsdl.org/release/SDL3-3.2.10.tar.gz",
"sha256": "f87be7b4dec66db4098e9c167b2aa34e2ca10aeb5443bdde95ae03185ed513e0"
}
],
"cleanup": [

View File

@@ -14,8 +14,8 @@
{
"type": "git",
"url": "https://github.com/KDAB/KDDockWidgets.git",
"tag": "v2.2.1",
"commit": "3aaccddc00a11a643e0959a24677838993de15ac",
"tag": "v2.2.3",
"commit": "28d16d0431d7cdc9f36cb619d22621146fdfab44",
"disable-submodules": true
},
{

View File

@@ -40,7 +40,7 @@ fi
FREETYPE=2.13.3
HARFBUZZ=10.0.1
SDL=SDL3-3.2.8
SDL=SDL3-3.2.10
ZSTD=1.5.7
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
LIBPNG=1.6.45
@@ -49,7 +49,7 @@ LIBWEBP=1.5.0
FFMPEG=6.0
MOLTENVK=1.2.9
QT=6.7.3
KDDOCKWIDGETS=2.2.1
KDDOCKWIDGETS=2.2.3
SHADERC=2024.1
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
@@ -77,7 +77,7 @@ CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
cat > SHASUMS <<EOF
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03 $SDL.tar.gz
f87be7b4dec66db4098e9c167b2aa34e2ca10aeb5443bdde95ae03185ed513e0 $SDL.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
@@ -94,7 +94,7 @@ eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADE
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
8693e06abee0c88517d8480b22647702a51a0708f3c876ed5385d9a4e356e1a5 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
b8529755b2d54205341766ae168e83177c6120660539f9afba71af6bca4b81ec KDDockWidgets-$KDDOCKWIDGETS.tar.gz
EOF
curl -C - -L \

View File

@@ -22,7 +22,7 @@ fi
FREETYPE=2.13.3
HARFBUZZ=10.0.1
SDL=SDL3-3.2.8
SDL=SDL3-3.2.10
ZSTD=1.5.7
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
LIBPNG=1.6.45
@@ -31,7 +31,7 @@ LIBWEBP=1.5.0
FFMPEG=6.0
MOLTENVK=1.2.9
QT=6.7.3
KDDOCKWIDGETS=2.2.1
KDDOCKWIDGETS=2.2.3
SHADERC=2024.1
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
@@ -57,7 +57,7 @@ CMAKE_COMMON=(
cat > SHASUMS <<EOF
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03 $SDL.tar.gz
f87be7b4dec66db4098e9c167b2aa34e2ca10aeb5443bdde95ae03185ed513e0 $SDL.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
@@ -74,7 +74,7 @@ eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADE
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
8693e06abee0c88517d8480b22647702a51a0708f3c876ed5385d9a4e356e1a5 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
b8529755b2d54205341766ae168e83177c6120660539f9afba71af6bca4b81ec KDDockWidgets-$KDDOCKWIDGETS.tar.gz
EOF
curl -L \
@@ -88,11 +88,11 @@ curl -L \
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
-O "https://github.com/KhronosGroup/MoltenVK/archive/refs/tags/v$MOLTENVK.tar.gz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \

View File

@@ -47,14 +47,14 @@ set HARFBUZZ=10.0.1
set LIBJPEGTURBO=3.1.0
set LIBPNG=1645
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
set QT=6.8.2
set QTMINOR=6.8
set SDL=SDL3-3.2.8
set SDL=SDL3-3.2.10
set QT=6.9.0
set QTMINOR=6.9
set WEBP=1.5.0
set ZLIB=1.3.1
set ZLIBSHORT=131
set ZSTD=1.5.7
set KDDOCKWIDGETS=2.2.1
set KDDOCKWIDGETS=2.2.3
set SHADERC=2024.1
set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
@@ -67,15 +67,15 @@ 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" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 7f8ff5c8246db4145301bc122601a5f8cef25ee2c326eddb3e88668849c61ddf || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 01d9ab20fc071b076be91df5396b464b4ef159e93b2b2addda1cc36750fc1f29 || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 513df15a6365a40f6230ec9463ad8c71b824e181d4b661dac9707e103b24ae0c || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" d428fd17a0d3f92c48a30f1d23806bf20352fbce2e80e5bbee27fa80576480ee || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 54bf06afeb67035f1c6afcd00beec755c0d776626b4cce9ab56992a55215ba69 || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 5f8a94a161bd2e71a82f478dc19f4ec77ac95a50709f5a68d5951001ed6bb856 || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 5885ce1a114615cc5fa69e459f069d3fe2bcb1320fd9cc162821f3920ef44735 || 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
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v2.2.1.zip" 78b5e242bf47476e150175b7de934ab84069459e151beb2d5ce84fd067138aa5 || goto error
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v%KDDOCKWIDGETS%.zip" 1ba8e5b48f3b4d47d2de7121529d448532200fa36d9ed21f93909f6eb03f61cb || goto error
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error

View File

@@ -45,14 +45,14 @@ set HARFBUZZ=10.0.1
set LIBJPEGTURBO=3.1.0
set LIBPNG=1645
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
set QT=6.8.2
set QTMINOR=6.8
set SDL=SDL3-3.2.8
set SDL=SDL3-3.2.10
set QT=6.9.0
set QTMINOR=6.9
set WEBP=1.5.0
set ZLIB=1.3.1
set ZLIBSHORT=131
set ZSTD=1.5.7
set KDDOCKWIDGETS=2.2.1
set KDDOCKWIDGETS=2.2.3
set SHADERC=2024.1
set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
@@ -65,15 +65,15 @@ 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" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 7f8ff5c8246db4145301bc122601a5f8cef25ee2c326eddb3e88668849c61ddf || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 01d9ab20fc071b076be91df5396b464b4ef159e93b2b2addda1cc36750fc1f29 || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 513df15a6365a40f6230ec9463ad8c71b824e181d4b661dac9707e103b24ae0c || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" d428fd17a0d3f92c48a30f1d23806bf20352fbce2e80e5bbee27fa80576480ee || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 54bf06afeb67035f1c6afcd00beec755c0d776626b4cce9ab56992a55215ba69 || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 5f8a94a161bd2e71a82f478dc19f4ec77ac95a50709f5a68d5951001ed6bb856 || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 5885ce1a114615cc5fa69e459f069d3fe2bcb1320fd9cc162821f3920ef44735 || 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
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v2.2.1.zip" 78b5e242bf47476e150175b7de934ab84069459e151beb2d5ce84fd067138aa5 || goto error
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v%KDDOCKWIDGETS%.zip" 1ba8e5b48f3b4d47d2de7121529d448532200fa36d9ed21f93909f6eb03f61cb || goto error
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error

View File

@@ -0,0 +1,68 @@
@echo off
setlocal enabledelayedexpansion
echo Setting environment...
if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" (
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
) else if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" (
call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
) else (
echo Visual Studio 2022 not found.
goto error
)
pushd %~dp0
cd ..\..\..\..
cd deps || goto error
set "DEPSDIR=%CD%"
cd ..
mkdir gammaray
cd gammaray || goto error
set "INSTALLDIR=%CD%"
cd ..
mkdir gammaray-build
cd gammaray-build || goto error
set "BUILDDIR=%CD%"
echo DEPSDIR=%DEPSDIR%
echo BUILDDIR=%BUILDDIR%
echo INSTALLDIR=%INSTALLDIR%
set GAMMARAY="master"
echo Downloading...
curl -L -o "GammaRay-%GAMMARAY%.tar.gz" "https://github.com/KDAB/GammaRay/archive/%GAMMARAY%.tar.gz" || goto error
rmdir /s /q "GammaRay-%GAMMARAY%"
echo Extracting...
tar -xf "GammaRay-%GAMMARAY%.tar.gz" || goto error
echo Configuring...
cmake "GammaRay-%GAMMARAY%" -B build -DCMAKE_PREFIX_PATH="%DEPSDIR%" -G Ninja -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DGAMMARAY_BUILD_DOCS=false || goto error
echo Building...
cmake --build build --parallel || goto error
echo Installing...
cmake --build build --target install || goto errorlevel
echo Copying DLLs...
xcopy /y "%DEPSDIR%\bin\*.dll" "%INSTALLDIR%\bin\"
xcopy /y /e /s "%DEPSDIR%\plugins" "%INSTALLDIR%\bin\"
echo Cleaning up...
cd ..
rd /s /q gammaray-build
echo Exiting with success.
popd
pause
exit 0
:error
echo Failed with error #%errorlevel%.
popd
pause
exit %errorlevel%

2
.gitignore vendored
View File

@@ -109,6 +109,8 @@ oprofile_data/
/deps-build
/deps
/deps-arm64
/gammaray-build
/gammaray
/ipch
!/3rdparty/libjpeg/change.log

View File

@@ -522,6 +522,8 @@ enum cpuinfo_uarch {
cpuinfo_uarch_falkor = 0x00400103,
/** Qualcomm Saphira. */
cpuinfo_uarch_saphira = 0x00400104,
/** Qualcomm Oryon. */
cpuinfo_uarch_oryon = 0x00400105,
/** Nvidia Denver. */
cpuinfo_uarch_denver = 0x00500100,
@@ -821,6 +823,7 @@ struct cpuinfo_x86_isa {
bool avx512_4vnniw;
bool avx512_4fmaps;
bool avx10_1;
bool avx10_2;
bool amx_bf16;
bool amx_tile;
bool amx_int8;
@@ -1444,6 +1447,14 @@ static inline bool cpuinfo_has_x86_avx10_1(void) {
#endif
}
static inline bool cpuinfo_has_x86_avx10_2(void) {
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
return cpuinfo_isa.avx10_2;
#else
return false;
#endif
}
static inline bool cpuinfo_has_x86_hle(void) {
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
return cpuinfo_isa.hle;

View File

@@ -1,5 +1,11 @@
#pragma once
#ifdef _MSC_VER
#define RESTRICT_STATIC /* nothing for MSVC */
#else
#define RESTRICT_STATIC restrict static
#endif
#include <stdbool.h>
#include <stdint.h>
@@ -82,11 +88,11 @@ struct cpuinfo_arm_chipset {
#ifndef __cplusplus
CPUINFO_INTERNAL void cpuinfo_arm_chipset_to_string(
const struct cpuinfo_arm_chipset chipset[restrict static 1],
char name[restrict static CPUINFO_ARM_CHIPSET_NAME_MAX]);
const struct cpuinfo_arm_chipset chipset[RESTRICT_STATIC 1],
char name[RESTRICT_STATIC CPUINFO_ARM_CHIPSET_NAME_MAX]);
CPUINFO_INTERNAL void cpuinfo_arm_fixup_chipset(
struct cpuinfo_arm_chipset chipset[restrict static 1],
struct cpuinfo_arm_chipset chipset[RESTRICT_STATIC 1],
uint32_t cores,
uint32_t max_cpu_freq_max);
@@ -95,23 +101,23 @@ CPUINFO_INTERNAL void cpuinfo_arm_decode_vendor_uarch(
#if CPUINFO_ARCH_ARM
bool has_vfpv4,
#endif
enum cpuinfo_vendor vendor[restrict static 1],
enum cpuinfo_uarch uarch[restrict static 1]);
enum cpuinfo_vendor vendor[RESTRICT_STATIC 1],
enum cpuinfo_uarch uarch[RESTRICT_STATIC 1]);
CPUINFO_INTERNAL void cpuinfo_arm_decode_cache(
enum cpuinfo_uarch uarch,
uint32_t cluster_cores,
uint32_t midr,
const struct cpuinfo_arm_chipset chipset[restrict static 1],
const struct cpuinfo_arm_chipset chipset[RESTRICT_STATIC 1],
uint32_t cluster_id,
uint32_t arch_version,
struct cpuinfo_cache l1i[restrict static 1],
struct cpuinfo_cache l1d[restrict static 1],
struct cpuinfo_cache l2[restrict static 1],
struct cpuinfo_cache l3[restrict static 1]);
struct cpuinfo_cache l1i[RESTRICT_STATIC 1],
struct cpuinfo_cache l1d[RESTRICT_STATIC 1],
struct cpuinfo_cache l2[RESTRICT_STATIC 1],
struct cpuinfo_cache l3[RESTRICT_STATIC 1]);
CPUINFO_INTERNAL uint32_t
cpuinfo_arm_compute_max_cache_size(const struct cpuinfo_processor processor[restrict static 1]);
cpuinfo_arm_compute_max_cache_size(const struct cpuinfo_processor processor[RESTRICT_STATIC 1]);
#else /* defined(__cplusplus) */
CPUINFO_INTERNAL void cpuinfo_arm_decode_cache(
enum cpuinfo_uarch uarch,

View File

@@ -101,7 +101,6 @@ static enum cpuinfo_uarch decode_uarch(uint32_t cpu_family, uint32_t core_index,
return cpuinfo_uarch_unknown;
}
/* Small bodge until cpuinfo merges PR #246 */
static int read_package_name_from_brand_string(char* package_name) {
size_t size;
if (sysctlbyname("machdep.cpu.brand_string", NULL, &size, NULL, 0) != 0) {

View File

@@ -9,8 +9,8 @@ void cpuinfo_arm_decode_vendor_uarch(
#if CPUINFO_ARCH_ARM
bool has_vfpv4,
#endif /* CPUINFO_ARCH_ARM */
enum cpuinfo_vendor vendor[restrict static 1],
enum cpuinfo_uarch uarch[restrict static 1]) {
enum cpuinfo_vendor vendor[RESTRICT_STATIC 1],
enum cpuinfo_uarch uarch[RESTRICT_STATIC 1]) {
switch (midr_get_implementer(midr)) {
case 'A':
*vendor = cpuinfo_vendor_arm;
@@ -332,6 +332,9 @@ void cpuinfo_arm_decode_vendor_uarch(
*uarch = cpuinfo_uarch_cortex_a55;
break;
#if CPUINFO_ARCH_ARM64
case 0x001:
*uarch = cpuinfo_uarch_oryon;
break;
case 0xC00:
*uarch = cpuinfo_uarch_falkor;
break;

View File

@@ -750,11 +750,14 @@ void store_core_info_per_processor(
if (cores) {
processors[processor_global_index].core = cores + core_id;
cores[core_id].core_id = core_id;
get_core_uarch_for_efficiency(
chip_info->chip_name,
core_info->Processor.EfficiencyClass,
&(cores[core_id].uarch),
&(cores[core_id].frequency));
if (chip_info->uarchs == NULL) {
cpuinfo_log_error("uarch is NULL for core %d", core_id);
return;
}
cores[core_id].uarch = chip_info->uarchs[0].uarch;
cores[core_id].frequency = chip_info->uarchs[0].frequency;
/* We don't have cluster information, so we handle it as
* fixed 1 to (cluster / cores).

View File

@@ -7,6 +7,9 @@
#include <cpuinfo/internal-api.h>
#include <cpuinfo/log.h>
#include <arm/api.h>
#include <arm/midr.h>
#include "windows-arm-init.h"
struct cpuinfo_arm_isa cpuinfo_isa;
@@ -14,62 +17,7 @@ struct cpuinfo_arm_isa cpuinfo_isa;
static void set_cpuinfo_isa_fields(void);
static struct woa_chip_info* get_system_info_from_registry(void);
static struct woa_chip_info woa_chip_unknown = {
L"Unknown",
woa_chip_name_unknown,
{{cpuinfo_vendor_unknown, cpuinfo_uarch_unknown, 0}}};
/* Please add new SoC/chip info here! */
static struct woa_chip_info woa_chips[woa_chip_name_last] = {
/* Microsoft SQ1 Kryo 495 4 + 4 cores (3 GHz + 1.80 GHz) */
[woa_chip_name_microsoft_sq_1] =
{L"Microsoft SQ1",
woa_chip_name_microsoft_sq_1,
{{
cpuinfo_vendor_arm,
cpuinfo_uarch_cortex_a55,
1800000000,
},
{
cpuinfo_vendor_arm,
cpuinfo_uarch_cortex_a76,
3000000000,
}}},
/* Microsoft SQ2 Kryo 495 4 + 4 cores (3.15 GHz + 2.42 GHz) */
[woa_chip_name_microsoft_sq_2] =
{L"Microsoft SQ2",
woa_chip_name_microsoft_sq_2,
{{
cpuinfo_vendor_arm,
cpuinfo_uarch_cortex_a55,
2420000000,
},
{cpuinfo_vendor_arm, cpuinfo_uarch_cortex_a76, 3150000000}}},
/* Snapdragon (TM) 8cx Gen 3 @ 3.0 GHz */
[woa_chip_name_microsoft_sq_3] =
{L"Snapdragon (TM) 8cx Gen 3",
woa_chip_name_microsoft_sq_3,
{{
cpuinfo_vendor_arm,
cpuinfo_uarch_cortex_a78,
2420000000,
},
{cpuinfo_vendor_arm, cpuinfo_uarch_cortex_x1, 3000000000}}},
/* Microsoft Windows Dev Kit 2023 */
[woa_chip_name_microsoft_sq_3_devkit] =
{L"Snapdragon Compute Platform",
woa_chip_name_microsoft_sq_3_devkit,
{{
cpuinfo_vendor_arm,
cpuinfo_uarch_cortex_a78,
2420000000,
},
{cpuinfo_vendor_arm, cpuinfo_uarch_cortex_x1, 3000000000}}},
/* Ampere Altra */
[woa_chip_name_ampere_altra] = {
L"Ampere(R) Altra(R) Processor",
woa_chip_name_ampere_altra,
{{cpuinfo_vendor_arm, cpuinfo_uarch_neoverse_n1, 3000000000}}}};
static struct woa_chip_info woa_chip_unknown = {L"Unknown", {{cpuinfo_vendor_unknown, cpuinfo_uarch_unknown, 0}}};
BOOL CALLBACK cpuinfo_arm_windows_init(PINIT_ONCE init_once, PVOID parameter, PVOID* context) {
struct woa_chip_info* chip_info = NULL;
@@ -87,23 +35,6 @@ BOOL CALLBACK cpuinfo_arm_windows_init(PINIT_ONCE init_once, PVOID parameter, PV
return true;
}
bool get_core_uarch_for_efficiency(
enum woa_chip_name chip,
BYTE EfficiencyClass,
enum cpuinfo_uarch* uarch,
uint64_t* frequency) {
/* For currently supported WoA chips, the Efficiency class selects
* the pre-defined little and big core.
* Any further supported SoC's logic should be implemented here.
*/
if (uarch && frequency && chip < woa_chip_name_last && EfficiencyClass < MAX_WOA_VALID_EFFICIENCY_CLASSES) {
*uarch = woa_chips[chip].uarchs[EfficiencyClass].uarch;
*frequency = woa_chips[chip].uarchs[EfficiencyClass].frequency;
return true;
}
return false;
}
/* Static helper functions */
static wchar_t* read_registry(LPCWSTR subkey, LPCWSTR value) {
@@ -149,40 +80,112 @@ static wchar_t* read_registry(LPCWSTR subkey, LPCWSTR value) {
return text_buffer;
}
static uint64_t read_registry_qword(LPCWSTR subkey, LPCWSTR value) {
DWORD key_type = 0;
DWORD data_size = sizeof(uint64_t);
const DWORD flags = RRF_RT_REG_QWORD; /* Only read QWORD (REG_QWORD) values */
uint64_t qword_value = 0;
LSTATUS result = RegGetValueW(HKEY_LOCAL_MACHINE, subkey, value, flags, &key_type, &qword_value, &data_size);
if (result != ERROR_SUCCESS || data_size != sizeof(uint64_t)) {
cpuinfo_log_error("Registry QWORD read error");
return 0;
}
return qword_value;
}
static uint64_t read_registry_dword(LPCWSTR subkey, LPCWSTR value) {
DWORD key_type = 0;
DWORD data_size = sizeof(DWORD);
DWORD dword_value = 0;
LSTATUS result =
RegGetValueW(HKEY_LOCAL_MACHINE, subkey, value, RRF_RT_REG_DWORD, &key_type, &dword_value, &data_size);
if (result != ERROR_SUCCESS || data_size != sizeof(DWORD)) {
cpuinfo_log_error("Registry DWORD read error");
return 0;
}
return (uint64_t)dword_value;
}
static wchar_t* wcsndup(const wchar_t* src, size_t n) {
size_t len = wcsnlen(src, n);
wchar_t* dup = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (len + 1) * sizeof(wchar_t));
if (dup) {
wcsncpy_s(dup, len + 1, src, len);
dup[len] = L'\0';
}
return dup;
}
static struct core_info_by_chip_name get_core_info_from_midr(uint32_t midr, uint64_t frequency) {
struct core_info_by_chip_name info;
enum cpuinfo_vendor vendor;
enum cpuinfo_uarch uarch;
#if CPUINFO_ARCH_ARM
bool has_vfpv4 = false;
cpuinfo_arm_decode_vendor_uarch(midr, has_vfpv4, &vendor, &uarch);
#else
cpuinfo_arm_decode_vendor_uarch(midr, &vendor, &uarch);
#endif
info.vendor = vendor;
info.uarch = uarch;
info.frequency = frequency;
return info;
}
static struct woa_chip_info* get_system_info_from_registry(void) {
wchar_t* text_buffer = NULL;
LPCWSTR cpu0_subkey = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
LPCWSTR chip_name_value = L"ProcessorNameString";
LPCWSTR chip_midr_value = L"CP 4000";
LPCWSTR chip_mhz_value = L"~MHz";
struct woa_chip_info* chip_info = NULL;
HANDLE heap = GetProcessHeap();
/* Read processor model name from registry and find in the hard-coded
* list. */
text_buffer = read_registry(cpu0_subkey, chip_name_value);
if (text_buffer == NULL) {
cpuinfo_log_error("Registry read error");
cpuinfo_log_error("Registry read error for processor name");
return NULL;
}
for (uint32_t i = 0; i < (uint32_t)woa_chip_name_last; i++) {
size_t compare_length = wcsnlen(woa_chips[i].chip_name_string, CPUINFO_PACKAGE_NAME_MAX);
int compare_result = wcsncmp(text_buffer, woa_chips[i].chip_name_string, compare_length);
if (compare_result == 0) {
chip_info = woa_chips + i;
break;
}
/*
* https://developer.arm.com/documentation/100442/0100/register-descriptions/aarch32-system-registers/midr--main-id-register
* Regedit for MIDR :
*HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0\CP 4000
*/
uint64_t midr_qword = (uint32_t)read_registry_qword(cpu0_subkey, chip_midr_value);
if (midr_qword == 0) {
cpuinfo_log_error("Registry read error for MIDR value");
return NULL;
}
// MIDR is only 32 bits, so we need to cast it to uint32_t
uint32_t midr_value = (uint32_t)midr_qword;
/* Read the frequency from the registry
* The value is in MHz, so we need to convert it to Hz */
uint64_t frequency_mhz = read_registry_dword(cpu0_subkey, chip_mhz_value);
if (frequency_mhz == 0) {
cpuinfo_log_error("Registry read error for frequency value");
return NULL;
}
// Convert MHz to Hz
uint64_t frequency_hz = frequency_mhz * 1000000;
// Allocate chip_info before using it.
chip_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct woa_chip_info));
if (chip_info == NULL) {
/* No match was found, so print a warning and assign the unknown
* case. */
cpuinfo_log_error(
"Unknown chip model name '%ls'.\nPlease add new Windows on Arm SoC/chip support to arm/windows/init.c!",
text_buffer);
} else {
cpuinfo_log_debug("detected chip model name: %s", chip_info->chip_name_string);
cpuinfo_log_error("Heap allocation error for chip_info");
return NULL;
}
HeapFree(heap, 0, text_buffer);
// set chip_info fields
chip_info->chip_name_string = wcsndup(text_buffer, CPUINFO_PACKAGE_NAME_MAX - 1);
chip_info->uarchs[0] = get_core_info_from_midr(midr_value, frequency_hz);
cpuinfo_log_debug("detected chip model name: %ls", chip_info->chip_name_string);
return chip_info;
}
@@ -216,4 +219,4 @@ static void set_cpuinfo_isa_fields(void) {
cpuinfo_isa.pmull = crypto;
cpuinfo_isa.crc32 = IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) != 0;
}
}

View File

@@ -3,17 +3,6 @@
/* Efficiency class = 0 means little core, while 1 means big core for now. */
#define MAX_WOA_VALID_EFFICIENCY_CLASSES 2
/* List of known and supported Windows on Arm SoCs/chips. */
enum woa_chip_name {
woa_chip_name_microsoft_sq_1 = 0,
woa_chip_name_microsoft_sq_2 = 1,
woa_chip_name_microsoft_sq_3 = 2,
woa_chip_name_microsoft_sq_3_devkit = 3,
woa_chip_name_ampere_altra = 4,
woa_chip_name_unknown = 5,
woa_chip_name_last = woa_chip_name_unknown
};
/* Topology information hard-coded by SoC/chip name */
struct core_info_by_chip_name {
enum cpuinfo_vendor vendor;
@@ -26,14 +15,7 @@ struct core_info_by_chip_name {
*/
struct woa_chip_info {
wchar_t* chip_name_string;
enum woa_chip_name chip_name;
struct core_info_by_chip_name uarchs[MAX_WOA_VALID_EFFICIENCY_CLASSES];
};
bool get_core_uarch_for_efficiency(
enum woa_chip_name chip,
BYTE EfficiencyClass,
enum cpuinfo_uarch* uarch,
uint64_t* frequency);
bool cpu_info_init_by_logical_sys_info(const struct woa_chip_info* chip_info, enum cpuinfo_vendor vendor);

View File

@@ -46,6 +46,8 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
(max_base_index >= 7) ? cpuidex(7, 0) : (struct cpuid_regs){0, 0, 0, 0};
const struct cpuid_regs structured_feature_info1 =
(max_base_index >= 7) ? cpuidex(7, 1) : (struct cpuid_regs){0, 0, 0, 0};
const struct cpuid_regs structured_feature_info2 =
(max_base_index >= 7) ? cpuidex(0x24, 0) : (struct cpuid_regs){0, 0, 0, 0};
const uint32_t processor_capacity_info_index = UINT32_C(0x80000008);
const struct cpuid_regs processor_capacity_info = (max_extended_index >= processor_capacity_info_index)
@@ -430,10 +432,17 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
isa.avx512f = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00010000));
/*
* AVX 10.1 instructions:
* AVX 10.1 instructions: avx 10 isa supported.
* - Intel: edx[bit 19] in structured feature info (ecx = 1).
*/
isa.avx10_1 = avx512_regs && !!(structured_feature_info1.edx & UINT32_C(0x00080000));
/*
* AVX 10.2 instructions: avx 10 version information.
* - Intel: ebx[bits 0-7] in structured features info (eax = 24 ecx = 0).
*/
isa.avx10_2 = ((structured_feature_info2.ebx & UINT32_C(0x000000FF)) >= 2) && isa.avx10_1;
/*
* AVX512PF instructions:
* - Intel: ebx[bit 26] in structured feature info (ecx = 0).

View File

@@ -83,8 +83,9 @@ struct proc_cpuinfo_parser_state {
static bool parse_line(
const char* line_start,
const char* line_end,
struct proc_cpuinfo_parser_state state[restrict static 1],
void* context,
uint64_t line_number) {
struct proc_cpuinfo_parser_state* restrict state = context;
/* Empty line. Skip. */
if (line_start == line_end) {
return true;
@@ -215,5 +216,5 @@ bool cpuinfo_x86_linux_parse_proc_cpuinfo(
.processors = processors,
};
return cpuinfo_linux_parse_multiline_file(
"/proc/cpuinfo", BUFFER_SIZE, (cpuinfo_line_callback)parse_line, &state);
"/proc/cpuinfo", BUFFER_SIZE, parse_line, &state);
}

View File

@@ -88,8 +88,7 @@
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
// Only works in combination with IMGUI_ENABLE_FREETYPE.
// - lunasvg is currently easier to acquire/install, as e.g. it is part of vcpkg.
// - plutosvg will support more fonts and may load them faster. It currently requires to be built manually but it is fairly easy. See misc/freetype/README for instructions.
// - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It will support more fonts and may load them faster. See misc/freetype/README for instructions.
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.8
// dear imgui, v1.91.9b
// (headers)
// Help:
@@ -28,8 +28,8 @@
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.91.8"
#define IMGUI_VERSION_NUM 19180
#define IMGUI_VERSION "1.91.9b"
#define IMGUI_VERSION_NUM 19191
#define IMGUI_HAS_TABLE
/*
@@ -37,6 +37,7 @@
Index of this file:
// [SECTION] Header mess
// [SECTION] Forward declarations and basic types
// [SECTION] Texture identifier (ImTextureID)
// [SECTION] Dear ImGui end-user API functions
// [SECTION] Flags & Enumerations
// [SECTION] Tables API flags and structures (ImGuiTableFlags, ImGuiTableColumnFlags, ImGuiTableRowFlags, ImGuiTableBgTarget, ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs)
@@ -250,22 +251,6 @@ typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: f
typedef int ImGuiViewportFlags; // -> enum ImGuiViewportFlags_ // Flags: for ImGuiViewport
typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild()
// ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type]
// - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file.
// - This can be whatever to you want it to be! read the FAQ about ImTextureID for details.
// - You can make this a structure with various constructors if you need. You will have to implement ==/!= operators.
// - (note: before v1.91.4 (2024/10/08) the default type for ImTextureID was void*. Use intermediary intptr_t cast and read FAQ if you have casting warnings)
#ifndef ImTextureID
typedef ImU64 ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that)
#endif
// ImDrawIdx: vertex index. [Compile-time configurable type]
// - To use 16-bit indices + allow large meshes: backend need to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset (recommended).
// - To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in your imconfig.h file.
#ifndef ImDrawIdx
typedef unsigned short ImDrawIdx; // Default: 16-bit (for maximum compatibility with renderer backends)
#endif
// Character types
// (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display)
typedef unsigned int ImWchar32; // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings.
@@ -315,6 +300,19 @@ struct ImVec4
};
IM_MSVC_RUNTIME_CHECKS_RESTORE
//-----------------------------------------------------------------------------
// [SECTION] Texture identifier (ImTextureID)
//-----------------------------------------------------------------------------
// ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type]
// - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file.
// - This can be whatever to you want it to be! read the FAQ about ImTextureID for details.
// - You can make this a structure with various constructors if you need. You will have to implement ==/!= operators.
// - (note: before v1.91.4 (2024/10/08) the default type for ImTextureID was void*. Use intermediary intptr_t cast and read FAQ if you have casting warnings)
#ifndef ImTextureID
typedef ImU64 ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that)
#endif
//-----------------------------------------------------------------------------
// [SECTION] Dear ImGui end-user API functions
// (Note that ImGui:: being a namespace, you can add extra ImGui:: functions in your own separate file. Please don't modify imgui source files!)
@@ -544,7 +542,7 @@ namespace ImGui
IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args) IM_FMTLIST(2);
IMGUI_API void BulletText(const char* fmt, ...) IM_FMTARGS(1); // shortcut for Bullet()+Text()
IMGUI_API void BulletTextV(const char* fmt, va_list args) IM_FMTLIST(1);
IMGUI_API void SeparatorText(const char* label); // currently: formatted text with an horizontal line
IMGUI_API void SeparatorText(const char* label); // currently: formatted text with a horizontal line
// Widgets: Main
// - Most widgets return true when the value has been changed or when pressed/selected
@@ -566,9 +564,10 @@ namespace ImGui
// Widgets: Images
// - Read about ImTextureID here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
// - 'uv0' and 'uv1' are texture coordinates. Read about them from the same link above.
// - Note that Image() may add +2.0f to provided size if a border is visible, ImageButton() adds style.FramePadding*2.0f to provided size.
// - Image() pads adds style.ImageBorderSize on each side, ImageButton() adds style.FramePadding on each side.
// - ImageButton() draws a background based on regular Button() color + optionally an inner background if specified.
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec4& border_col = ImVec4(0, 0, 0, 0));
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1));
IMGUI_API void ImageWithBg(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
IMGUI_API bool ImageButton(const char* str_id, ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
// Widgets: Combo Box (Dropdown)
@@ -906,7 +905,7 @@ namespace ImGui
IMGUI_API void PopClipRect();
// Focus, Activation
IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of of a newly appearing window.
IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a newly appearing window.
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget.
// Keyboard/Gamepad Navigation
@@ -974,7 +973,7 @@ namespace ImGui
IMGUI_API bool IsKeyReleased(ImGuiKey key); // was key released (went from Down to !Down)?
IMGUI_API bool IsKeyChordPressed(ImGuiKeyChord key_chord); // was key chord (mods + key) pressed, e.g. you can pass 'ImGuiMod_Ctrl | ImGuiKey_S' as a key-chord. This doesn't do any routing or focus check, please consider using Shortcut() function instead.
IMGUI_API int GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate
IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names a provided for debugging purpose and are not meant to be saved persistently not compared.
IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names are provided for debugging purpose and are not meant to be saved persistently nor compared.
IMGUI_API void SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard); // Override io.WantCaptureKeyboard flag next frame (said flag is left for your application to handle, typically when true it instructs your app to ignore inputs). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting "io.WantCaptureKeyboard = want_capture_keyboard"; after the next NewFrame() call.
// Inputs Utilities: Shortcut Testing & Routing [BETA]
@@ -1177,7 +1176,7 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID().
// Elide display / Alignment
ImGuiInputTextFlags_ElideLeft = 1 << 17, // When text doesn't fit, elide left side to ensure right side stays visible. Useful for path/filenames. Single-line only!
ImGuiInputTextFlags_ElideLeft = 1 << 17, // When text doesn't fit, elide left side to ensure right side stays visible. Useful for path/filenames. Single-line only!
// Callback features
ImGuiInputTextFlags_CallbackCompletion = 1 << 18, // Callback on pressing TAB (for completion handling)
@@ -1492,6 +1491,7 @@ enum ImGuiKey : int
ImGuiKey_KeypadEqual,
ImGuiKey_AppBack, // Available on some keyboard/mouses. Often referred as "Browser Back"
ImGuiKey_AppForward,
ImGuiKey_Oem102, // Non-US backslash.
// Gamepad (some of those are analog values, 0.0f to 1.0f) // NAVIGATION ACTION
// (download controller mapping PNG/PSD at http://dearimgui.com/controls_sheets)
@@ -1714,6 +1714,7 @@ enum ImGuiStyleVar_
ImGuiStyleVar_ScrollbarRounding, // float ScrollbarRounding
ImGuiStyleVar_GrabMinSize, // float GrabMinSize
ImGuiStyleVar_GrabRounding, // float GrabRounding
ImGuiStyleVar_ImageBorderSize, // float ImageBorderSize
ImGuiStyleVar_TabRounding, // float TabRounding
ImGuiStyleVar_TabBorderSize, // float TabBorderSize
ImGuiStyleVar_TabBarBorderSize, // float TabBarBorderSize
@@ -1833,6 +1834,8 @@ enum ImGuiMouseCursor_
ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window
ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window
ImGuiMouseCursor_Hand, // (Unused by Dear ImGui functions. Use for e.g. hyperlinks)
ImGuiMouseCursor_Wait, // When waiting for something to process/load.
ImGuiMouseCursor_Progress, // When waiting for something to process/load, but application is still interactive.
ImGuiMouseCursor_NotAllowed, // When hovering something with disallowed interaction. Usually a crossed circle.
ImGuiMouseCursor_COUNT
};
@@ -2146,6 +2149,7 @@ struct ImGuiStyle
ImVec2 WindowPadding; // Padding within a window.
float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended.
float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly).
float WindowBorderHoverPadding; // Hit-testing extent outside/inside resizing border. Also extend determination of hovered window. Generally meaningfully larger than WindowBorderSize to make it easy to reach borders.
ImVec2 WindowMinSize; // Minimum window size. This is a global setting. If you want to constrain individual windows, use SetNextWindowSizeConstraints().
ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered.
ImGuiDir WindowMenuButtonPosition; // Side of the collapsing/docking button in the title bar (None/Left/Right). Defaults to ImGuiDir_Left.
@@ -2167,9 +2171,11 @@ struct ImGuiStyle
float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar.
float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
float LogSliderDeadzone; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
float ImageBorderSize; // Thickness of border around Image() calls.
float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
float TabBorderSize; // Thickness of border around tabs.
float TabMinWidthForCloseButton; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected.
float TabCloseButtonMinWidthSelected; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width.
float TabCloseButtonMinWidthUnselected; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width. FLT_MAX: never show close button when unselected.
float TabBarBorderSize; // Thickness of tab-bar separator, which takes on the tab active color to denote focus.
float TabBarOverlineSize; // Thickness of tab-bar overline, which highlights the selected tab-bar.
float TableAngledHeadersAngle; // Angle of angled headers (supported values range from -50.0f degrees to +50.0f degrees).
@@ -2188,6 +2194,8 @@ struct ImGuiStyle
bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
// Colors
ImVec4 Colors[ImGuiCol_COUNT];
// Behaviors
@@ -2200,6 +2208,11 @@ struct ImGuiStyle
IMGUI_API ImGuiStyle();
IMGUI_API void ScaleAllSizes(float scale_factor);
// Obsolete names
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// TabMinWidthForCloseButton = TabCloseButtonMinWidthUnselected // Renamed in 1.91.9.
#endif
};
//-----------------------------------------------------------------------------
@@ -2310,7 +2323,8 @@ struct ImGuiIO
// - Code should use PushID()/PopID() in loops, or append "##xx" to same-label identifiers.
// - Empty label e.g. Button("") == same ID as parent widget/node. Use Button("##xx") instead!
// - See FAQ https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#q-about-the-id-stack-system
bool ConfigDebugHighlightIdConflicts;// = true // Highlight and show an error message when multiple items have conflicting identifiers.
bool ConfigDebugHighlightIdConflicts;// = true // Highlight and show an error message popup when multiple items have conflicting identifiers.
bool ConfigDebugHighlightIdConflictsShowItemPicker;//=true // Show "Item Picker" button in aforementioned popup.
// Tools to test correct Begin/End and BeginChild/EndChild behaviors.
// - Presently Begin()/End() and BeginChild()/EndChild() needs to ALWAYS be called in tandem, regardless of return value of BeginXXX()
@@ -2420,7 +2434,7 @@ struct ImGuiIO
bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds.
bool MouseDownOwnedUnlessPopupClose[5]; // Track if button was clicked inside a dear imgui window.
bool MouseWheelRequestAxisSwap; // On a non-Mac system, holding SHIFT requests WheelY to perform the equivalent of a WheelX event. On a Mac system this is already enforced by the system.
bool MouseCtrlLeftAsRightClick; // (OSX) Set to true when the current click was a ctrl-click that spawned a simulated right click
bool MouseCtrlLeftAsRightClick; // (OSX) Set to true when the current click was a Ctrl+click that spawned a simulated right click
float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked)
float MouseDownDurationPrev[5]; // Previous time the mouse button has been down
float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point (used for moving thresholds)
@@ -2585,10 +2599,11 @@ struct ImGuiTextBuffer
ImGuiTextBuffer() { }
inline char operator[](int i) const { IM_ASSERT(Buf.Data != NULL); return Buf.Data[i]; }
const char* begin() const { return Buf.Data ? &Buf.front() : EmptyString; }
const char* end() const { return Buf.Data ? &Buf.back() : EmptyString; } // Buf is zero-terminated, so end() will point on the zero-terminator
const char* end() const { return Buf.Data ? &Buf.back() : EmptyString; } // Buf is zero-terminated, so end() will point on the zero-terminator
int size() const { return Buf.Size ? Buf.Size - 1 : 0; }
bool empty() const { return Buf.Size <= 1; }
void clear() { Buf.clear(); }
void resize(int size) { if (Buf.Size > size) Buf.Data[size] = 0; Buf.resize(size ? size + 1 : 0, 0); } // Similar to resize(0) on ImVector: empty string but don't free buffer.
void reserve(int capacity) { Buf.reserve(capacity); }
const char* c_str() const { return Buf.Data ? Buf.Data : EmptyString; }
IMGUI_API void append(const char* str, const char* str_end = NULL);
@@ -2940,6 +2955,13 @@ struct ImGuiSelectionExternalStorage
#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (32)
#endif
// ImDrawIdx: vertex index. [Compile-time configurable type]
// - To use 16-bit indices + allow large meshes: backend need to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset (recommended).
// - To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in your imconfig.h file.
#ifndef ImDrawIdx
typedef unsigned short ImDrawIdx; // Default: 16-bit (for maximum compatibility with renderer backends)
#endif
// ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h]
// NB: You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering,
// you can poke into the draw list for that! Draw callback may be useful for example to:
@@ -3131,7 +3153,7 @@ struct ImDrawList
// General polygon
// - Only simple polygons are supported by filling functions (no self-intersections, no holes).
// - Concave polygon fill is more expensive than convex one: it has O(N^2) complexity. Provided as a convenience fo user but not used by main library.
// - Concave polygon fill is more expensive than convex one: it has O(N^2) complexity. Provided as a convenience for the user but not used by the main library.
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness);
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col);
IMGUI_API void AddConcavePolyFilled(const ImVec2* points, int num_points, ImU32 col);
@@ -3257,11 +3279,12 @@ struct ImFontConfig
int OversampleH; // 0 (2) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1 or 2 depending on size. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
int OversampleV; // 0 (1) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1. This is not really useful as we don't use sub-pixel positions on the Y axis.
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs when rendered: essentially add to glyph->AdvanceX. Only X axis is supported for now.
//ImVec2 GlyphExtraSpacing; // 0, 0 // (REMOVED IN 1.91.9: use GlyphExtraAdvanceX)
ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input.
const ImWchar* GlyphRanges; // NULL // THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list).
float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs
float GlyphExtraAdvanceX; // 0 // Extra spacing (in pixels) between glyphs. Please contact us if you are using this.
unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future.
float RasterizerDensity; // 1.0f // DPI scale for rasterization, not altering other font metrics: make it easy to swap between e.g. a 100% and a 400% fonts for a zooming display. IMPORTANT: If you increase this it is expected that you increase font scale accordingly, otherwise quality may look lowered.
@@ -3281,7 +3304,7 @@ struct ImFontGlyph
unsigned int Colored : 1; // Flag to indicate glyph is colored and should generally ignore tinting (make it usable with no shift on little-endian as this is used in loops)
unsigned int Visible : 1; // Flag to indicate glyph has no visible pixels (e.g. space). Allow early out when rendering.
unsigned int Codepoint : 30; // 0x0000..0x10FFFF
float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in)
float AdvanceX; // Horizontal distance to advance layout with
float X0, Y0, X1, Y1; // Glyph corners
float U0, V0, U1, V1; // Texture coordinates
};
@@ -3405,12 +3428,12 @@ struct ImFontAtlas
// [Internal]
IMGUI_API void CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) const;
IMGUI_API bool GetMouseCursorTexData(ImGuiMouseCursor cursor, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]);
//-------------------------------------------
// Members
//-------------------------------------------
// Input
ImFontAtlasFlags Flags; // Build flags (see ImFontAtlasFlags_)
ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure.
int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
@@ -3430,7 +3453,7 @@ struct ImFontAtlas
ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel
ImVector<ImFont*> Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font.
ImVector<ImFontAtlasCustomRect> CustomRects; // Rectangles for packing custom texture data into the atlas.
ImVector<ImFontConfig> ConfigData; // Configuration data
ImVector<ImFontConfig> Sources; // Source/configuration data
ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1]; // UVs for baked anti-aliased lines
// [Internal] Font builder
@@ -3442,8 +3465,8 @@ struct ImFontAtlas
int PackIdLines; // Custom texture rectangle ID for baked anti-aliased lines
// [Obsolete]
//typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+
//typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+
//typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+
//typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+
};
// Font runtime data and rendering
@@ -3458,13 +3481,13 @@ struct ImFont
// [Internal] Members: Hot ~28/40 bytes (for RenderText loop)
ImVector<ImU16> IndexLookup; // 12-16 // out // Sparse. Index glyphs by Unicode code-point.
ImVector<ImFontGlyph> Glyphs; // 12-16 // out // All glyphs.
const ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar)
ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar)
// [Internal] Members: Cold ~32/40 bytes
// Conceptually ConfigData[] is the list of font sources merged to create this font.
// Conceptually Sources[] is the list of font sources merged to create this font.
ImFontAtlas* ContainerAtlas; // 4-8 // out // What we has been loaded into
const ImFontConfig* ConfigData; // 4-8 // in // Pointer within ContainerAtlas->ConfigData to ConfigDataCount instances
short ConfigDataCount; // 2 // in // Number of ImFontConfig involved in creating this font. Usually 1, or >1 when merging multiple font sources into one ImFont.
ImFontConfig* Sources; // 4-8 // in // Pointer within ContainerAtlas->Sources[], to SourcesCount instances
short SourcesCount; // 2 // in // Number of ImFontConfig involved in creating this font. Usually 1, or >1 when merging multiple font sources into one ImFont.
short EllipsisCharCount; // 1 // out // 1 or 3
ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...').
ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?')
@@ -3479,12 +3502,13 @@ struct ImFont
// Methods
IMGUI_API ImFont();
IMGUI_API ~ImFont();
IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c);
IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c);
IMGUI_API ImFontGlyph* FindGlyph(ImWchar c);
IMGUI_API ImFontGlyph* FindGlyphNoFallback(ImWchar c);
float GetCharAdvance(ImWchar c) { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; }
bool IsLoaded() const { return ContainerAtlas != NULL; }
const char* GetDebugName() const { return ConfigData ? ConfigData->Name : "<unknown>"; }
const char* GetDebugName() const { return Sources ? Sources->Name : "<unknown>"; }
// [Internal] Don't use!
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL); // utf8
@@ -3498,7 +3522,6 @@ struct ImFont
IMGUI_API void GrowIndex(int new_size);
IMGUI_API void AddGlyph(const ImFontConfig* src_cfg, ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x);
IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built.
IMGUI_API void SetGlyphVisible(ImWchar c, bool visible);
IMGUI_API bool IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last);
};
@@ -3552,7 +3575,7 @@ struct ImGuiPlatformIO
IMGUI_API ImGuiPlatformIO();
//------------------------------------------------------------------
// Interface with OS and Platform backend
// Input - Interface with OS and Platform backend (most common stuff)
//------------------------------------------------------------------
// Optional: Access OS clipboard
@@ -3562,7 +3585,7 @@ struct ImGuiPlatformIO
void* Platform_ClipboardUserData;
// Optional: Open link/folder/file in OS Shell
// (default to use ShellExecuteA() on Windows, system() on Linux/Mac)
// (default to use ShellExecuteW() on Windows, system() on Linux/Mac)
bool (*Platform_OpenInShellFn)(ImGuiContext* ctx, const char* path);
void* Platform_OpenInShellUserData;
@@ -3577,7 +3600,7 @@ struct ImGuiPlatformIO
ImWchar Platform_LocaleDecimalPoint; // '.'
//------------------------------------------------------------------
// Interface with Renderer Backend
// Input - Interface with Renderer Backend
//------------------------------------------------------------------
// Written by some backends during ImGui_ImplXXXX_RenderDrawData() call to point backend_specific ImGui_ImplXXXX_RenderState* structure.
@@ -3603,6 +3626,8 @@ struct ImGuiPlatformImeData
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
namespace ImGui
{
// OBSOLETED in 1.91.9 (from February 2025)
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); // <-- border_col was removed in favor of ImGuiCol_ImageBorder.
// OBSOLETED in 1.91.0 (from July 2024)
static inline void PushButtonRepeat(bool repeat) { PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); }
static inline void PopButtonRepeat() { PopItemFlag(); }

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.8
// dear imgui, v1.91.9b
// (internal structures/api)
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
@@ -14,6 +14,7 @@ Index of this file:
// [SECTION] Macros
// [SECTION] Generic helpers
// [SECTION] ImDrawList support
// [SECTION] Style support
// [SECTION] Data types support
// [SECTION] Widgets support: flags, enums, data structures
// [SECTION] Popup support
@@ -145,7 +146,6 @@ struct ImGuiBoxSelectState; // Box-selection state (currently used by mu
struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it
struct ImGuiContext; // Main Dear ImGui context
struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine
struct ImGuiDataVarInfo; // Variable information (e.g. to access style variables from an enum)
struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum
struct ImGuiDeactivatedItemData; // Data for IsItemDeactivated()/IsItemDeactivatedAfterEdit() function.
struct ImGuiErrorRecoveryState; // Storage of stack sizes for error handling and recovery
@@ -166,6 +166,7 @@ struct ImGuiOldColumns; // Storage data for a columns set for legacy
struct ImGuiPopupData; // Storage for current popup stack
struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file
struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it
struct ImGuiStyleVarInfo; // Style variable information (e.g. to access style variables from an enum)
struct ImGuiTabBar; // Storage for a tab bar
struct ImGuiTabItem; // Storage for a tab item (within a tab bar)
struct ImGuiTable; // Storage for a table
@@ -366,11 +367,14 @@ static inline void ImQsort(void* base, size_t count, size_t size_of_element
IMGUI_API ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b);
// Helpers: Bit manipulation
static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; }
static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; }
static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
static inline unsigned int ImCountSetBits(unsigned int v) { unsigned int count = 0; while (v > 0) { v = v & (v - 1); count++; } return count; }
// Helpers: String
#define ImStrlen strlen
#define ImMemchr memchr
IMGUI_API int ImStricmp(const char* str1, const char* str2); // Case insensitive compare.
IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); // Case insensitive compare to a certain count.
IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); // Copy to a certain count and always zero terminate (strncpy doesn't).
@@ -786,8 +790,9 @@ struct IMGUI_API ImDrawListSharedData
float FontScale; // Current/default font scale (== FontSize / Font->FontSize)
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo()
float CircleSegmentMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc
ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
float InitialFringeScale; // Initial scale to apply to AA fringe
ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards)
ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
ImVector<ImVec2> TempBuffer; // Temporary write buffer
// Lookup tables
@@ -808,17 +813,38 @@ struct ImDrawDataBuilder
};
//-----------------------------------------------------------------------------
// [SECTION] Data types support
// [SECTION] Style support
//-----------------------------------------------------------------------------
struct ImGuiDataVarInfo
struct ImGuiStyleVarInfo
{
ImGuiDataType Type;
ImU32 Count; // 1+
ImU32 Offset; // Offset in parent structure
ImU32 Count : 8; // 1+
ImGuiDataType DataType : 8;
ImU32 Offset : 16; // Offset in parent structure
void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); }
};
// Stacked color modifier, backup of modified data so we can restore it
struct ImGuiColorMod
{
ImGuiCol Col;
ImVec4 BackupValue;
};
// Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable.
struct ImGuiStyleMod
{
ImGuiStyleVar VarIdx;
union { int BackupInt[2]; float BackupFloat[2]; };
ImGuiStyleMod(ImGuiStyleVar idx, int v) { VarIdx = idx; BackupInt[0] = v; }
ImGuiStyleMod(ImGuiStyleVar idx, float v) { VarIdx = idx; BackupFloat[0] = v; }
ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v) { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; }
};
//-----------------------------------------------------------------------------
// [SECTION] Data types support
//-----------------------------------------------------------------------------
struct ImGuiDataTypeStorage
{
ImU8 Data[8]; // Opaque storage to fit any data up to ImGuiDataType_COUNT
@@ -836,7 +862,7 @@ struct ImGuiDataTypeInfo
// Extend ImGuiDataType_
enum ImGuiDataTypePrivate_
{
ImGuiDataType_Pointer = ImGuiDataType_COUNT + 1,
ImGuiDataType_Pointer = ImGuiDataType_COUNT,
ImGuiDataType_ID,
};
@@ -1037,23 +1063,6 @@ enum ImGuiPlotType
ImGuiPlotType_Histogram,
};
// Stacked color modifier, backup of modified data so we can restore it
struct ImGuiColorMod
{
ImGuiCol Col;
ImVec4 BackupValue;
};
// Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable.
struct ImGuiStyleMod
{
ImGuiStyleVar VarIdx;
union { int BackupInt[2]; float BackupFloat[2]; };
ImGuiStyleMod(ImGuiStyleVar idx, int v) { VarIdx = idx; BackupInt[0] = v; }
ImGuiStyleMod(ImGuiStyleVar idx, float v) { VarIdx = idx; BackupFloat[0] = v; }
ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v) { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; }
};
// Storage data for BeginComboPreview()/EndComboPreview()
struct IMGUI_API ImGuiComboPreviewData
{
@@ -1194,14 +1203,17 @@ enum ImGuiNextWindowDataFlags_
ImGuiNextWindowDataFlags_HasFocus = 1 << 5,
ImGuiNextWindowDataFlags_HasBgAlpha = 1 << 6,
ImGuiNextWindowDataFlags_HasScroll = 1 << 7,
ImGuiNextWindowDataFlags_HasChildFlags = 1 << 8,
ImGuiNextWindowDataFlags_HasRefreshPolicy = 1 << 9,
ImGuiNextWindowDataFlags_HasWindowFlags = 1 << 8,
ImGuiNextWindowDataFlags_HasChildFlags = 1 << 9,
ImGuiNextWindowDataFlags_HasRefreshPolicy = 1 << 10,
};
// Storage for SetNexWindow** functions
struct ImGuiNextWindowData
{
ImGuiNextWindowDataFlags Flags;
ImGuiNextWindowDataFlags HasFlags;
// Members below are NOT cleared. Always rely on HasFlags.
ImGuiCond PosCond;
ImGuiCond SizeCond;
ImGuiCond CollapsedCond;
@@ -1210,6 +1222,7 @@ struct ImGuiNextWindowData
ImVec2 SizeVal;
ImVec2 ContentSizeVal;
ImVec2 ScrollVal;
ImGuiWindowFlags WindowFlags; // Only honored by BeginTable()
ImGuiChildFlags ChildFlags;
bool CollapsedVal;
ImRect SizeConstraintRect;
@@ -1220,7 +1233,7 @@ struct ImGuiNextWindowData
ImGuiWindowRefreshFlags RefreshFlagsVal;
ImGuiNextWindowData() { memset(this, 0, sizeof(*this)); }
inline void ClearFlags() { Flags = ImGuiNextWindowDataFlags_None; }
inline void ClearFlags() { HasFlags = ImGuiNextWindowDataFlags_None; }
};
enum ImGuiNextItemDataFlags_
@@ -1237,7 +1250,8 @@ struct ImGuiNextItemData
{
ImGuiNextItemDataFlags HasFlags; // Called HasFlags instead of Flags to avoid mistaking this
ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemFlags_AllowOverlap and ImGuiItemFlags_HasSelectionUserData.
// Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem()
// Members below are NOT cleared by ItemAdd() meaning they are still valid during e.g. NavProcessItem(). Always rely on HasFlags.
ImGuiID FocusScopeId; // Set by SetNextItemSelectionUserData()
ImGuiSelectionUserData SelectionUserData; // Set by SetNextItemSelectionUserData() (note that NULL/0 is a valid value, we use -1 == ImGuiSelectionUserData_Invalid to mark invalid values)
float Width; // Set by SetNextItemWidth()
@@ -1305,6 +1319,7 @@ struct ImGuiWindowStackData
ImGuiLastItemData ParentLastItemDataBackup;
ImGuiErrorRecoveryState StackSizesInBegin; // Store size of various stacks for asserting
bool DisabledOverrideReenable; // Non-child window override disabled flag
float DisabledOverrideReenableAlphaBackup;
};
struct ImGuiShrinkWidthItem
@@ -1992,7 +2007,6 @@ struct ImGuiMetricsConfig
bool ShowDrawCmdMesh = true;
bool ShowDrawCmdBoundingBoxes = true;
bool ShowTextEncodingViewer = false;
bool ShowAtlasTintedWithTextColor = false;
int ShowWindowsRectsType = -1;
int ShowTablesRectsType = -1;
int HighlightMonitorIdx = -1;
@@ -2019,6 +2033,7 @@ struct ImGuiIDStackTool
ImVector<ImGuiStackLevelInfo> Results;
bool CopyToClipboardOnCtrlC;
float CopyToClipboardLastTime;
ImGuiTextBuffer ResultPathBuf;
ImGuiIDStackTool() { memset(this, 0, sizeof(*this)); CopyToClipboardLastTime = -FLT_MAX; }
};
@@ -2083,7 +2098,7 @@ struct ImGuiContext
ImVector<ImGuiWindowStackData> CurrentWindowStack;
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
int WindowsActiveCount; // Number of unique windows submitted by frame
ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING).
float WindowsBorderHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, style.WindowBorderHoverPadding). This isn't so multi-dpi friendly.
ImGuiID DebugBreakInWindow; // Set to break in Begin() call.
ImGuiWindow* CurrentWindow; // Window being drawn into
ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs.
@@ -2500,6 +2515,8 @@ struct IMGUI_API ImGuiWindow
ImVec2 ScrollTargetEdgeSnapDist; // 0.0f = no snapping, >0.0f snapping threshold
ImVec2 ScrollbarSizes; // Size taken by each scrollbars on their smaller axis. Pay attention! ScrollbarSizes.x == width of the vertical scrollbar, ScrollbarSizes.y = height of the horizontal scrollbar.
bool ScrollbarX, ScrollbarY; // Are scrollbars visible?
bool ScrollbarXStabilizeEnabled; // Was ScrollbarX previously auto-stabilized?
ImU8 ScrollbarXStabilizeToggledHistory; // Used to stabilize scrollbar visibility in case of feedback loops
bool Active; // Set to true on Begin(), unless Collapsed
bool WasActive;
bool WriteAccessed; // Set to true when any widget access the current window
@@ -2787,7 +2804,7 @@ struct IMGUI_API ImGuiTable
{
ImGuiID ID;
ImGuiTableFlags Flags;
void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[] and RowCellData[]
void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[], and RowCellData[]
ImGuiTableTempData* TempData; // Transient data while table is active. Point within g.CurrentTableStack[]
ImSpan<ImGuiTableColumn> Columns; // Point within RawData[]
ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
@@ -2801,7 +2818,7 @@ struct IMGUI_API ImGuiTable
int ColumnsCount; // Number of columns declared in BeginTable()
int CurrentRow;
int CurrentColumn;
ImS16 InstanceCurrent; // Count of BeginTable() calls with same ID in the same frame (generally 0). This is a little bit similar to BeginCount for a window, but multiple table with same ID look are multiple tables, they are just synched.
ImS16 InstanceCurrent; // Count of BeginTable() calls with same ID in the same frame (generally 0). This is a little bit similar to BeginCount for a window, but multiple tables with the same ID are multiple tables, they are just synced.
ImS16 InstanceInteracted; // Mark which instance (generally 0) of the same ID is being interacted with
float RowPosY1;
float RowPosY2;
@@ -2833,7 +2850,7 @@ struct IMGUI_API ImGuiTable
float AngledHeadersHeight; // Set by TableAngledHeadersRow(), used in TableUpdateLayout()
float AngledHeadersSlope; // Set by TableAngledHeadersRow(), used in TableUpdateLayout()
ImRect OuterRect; // Note: for non-scrolling table, OuterRect.Max.y is often FLT_MAX until EndTable(), unless a height has been specified in BeginTable().
ImRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is
ImRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is "
ImRect WorkRect;
ImRect InnerClipRect;
ImRect BgClipRect; // We use this to cpu-clip cell background color fill, evolve during the frame as we cross frozen rows boundaries
@@ -2930,7 +2947,7 @@ struct IMGUI_API ImGuiTableTempData
ImGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; }
};
// sizeof() ~ 12
// sizeof() ~ 16
struct ImGuiTableColumnSettings
{
float WidthOrWeight;
@@ -2939,7 +2956,7 @@ struct ImGuiTableColumnSettings
ImGuiTableColumnIdx DisplayOrder;
ImGuiTableColumnIdx SortOrder;
ImU8 SortDirection : 2;
ImU8 IsEnabled : 1; // "Visible" in ini file
ImS8 IsEnabled : 2; // "Visible" in ini file
ImU8 IsStretch : 1;
ImGuiTableColumnSettings()
@@ -2949,7 +2966,7 @@ struct ImGuiTableColumnSettings
Index = -1;
DisplayOrder = SortOrder = -1;
SortDirection = ImGuiSortDirection_None;
IsEnabled = 1;
IsEnabled = -1;
IsStretch = 0;
}
};
@@ -2980,7 +2997,8 @@ namespace ImGui
// If this ever crashes because g.CurrentWindow is NULL, it means that either:
// - ImGui::NewFrame() has never been called, which is illegal.
// - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
IMGUI_API ImGuiIO& GetIOEx(ImGuiContext* ctx);
IMGUI_API ImGuiIO& GetIO(ImGuiContext* ctx);
IMGUI_API ImGuiPlatformIO& GetPlatformIO(ImGuiContext* ctx);
inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; }
inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; }
IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id);
@@ -3108,7 +3126,7 @@ namespace ImGui
IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess);
// Parameter stacks (shared)
IMGUI_API const ImGuiDataVarInfo* GetStyleVarInfo(ImGuiStyleVar idx);
IMGUI_API const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx);
IMGUI_API void BeginDisabledOverrideReenable();
IMGUI_API void EndDisabledOverrideReenable();
@@ -3123,6 +3141,7 @@ namespace ImGui
// Popups, Modals
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags);
IMGUI_API bool BeginPopupMenuEx(ImGuiID id, const char* label, ImGuiWindowFlags extra_window_flags);
IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None);
IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
@@ -3474,6 +3493,7 @@ namespace ImGui
inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); }
inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active
IMGUI_API void SetNextItemRefVal(ImGuiDataType data_type, void* p_data);
inline bool IsItemActiveAsInputText() { ImGuiContext& g = *GImGui; return g.ActiveId != 0 && g.ActiveId == g.LastItemData.ID && g.InputTextState.ID == g.LastItemData.ID; } // This may be useful to apply workaround that a based on distinguish whenever an item is active as a text input field.
// Color
IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags);
@@ -3569,16 +3589,18 @@ struct ImFontBuilderIO
#ifdef IMGUI_ENABLE_STB_TRUETYPE
IMGUI_API const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype();
#endif
IMGUI_API void ImFontAtlasUpdateConfigDataPointers(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasUpdateSourcesPointers(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src, float ascent, float descent);
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque);
IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value);
IMGUI_API void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value);
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
IMGUI_API void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* cfg, int* out_oversample_h, int* out_oversample_v);
IMGUI_API void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* src, int* out_oversample_h, int* out_oversample_v);
IMGUI_API bool ImFontAtlasGetMouseCursorTexData(ImFontAtlas* atlas, ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]);
//-----------------------------------------------------------------------------
// [SECTION] Test Engine specific hooks (imgui_test_engine)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.8
// dear imgui, v1.91.9b
// (drawing and font code)
/*
@@ -68,6 +68,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
#pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier
#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
@@ -143,6 +144,7 @@ namespace IMGUI_STB_NAMESPACE
#define STBTT_fabs(x) ImFabs(x)
#define STBTT_ifloor(x) ((int)ImFloor(x))
#define STBTT_iceil(x) ((int)ImCeil(x))
#define STBTT_strlen(x) ImStrlen(x)
#define STBTT_STATIC
#define STB_TRUETYPE_IMPLEMENTATION
#else
@@ -374,6 +376,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
ImDrawListSharedData::ImDrawListSharedData()
{
memset(this, 0, sizeof(*this));
InitialFringeScale = 1.0f;
for (int i = 0; i < IM_ARRAYSIZE(ArcFastVtx); i++)
{
const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(ArcFastVtx);
@@ -433,7 +436,7 @@ void ImDrawList::_ResetForNewFrame()
_Path.resize(0);
_Splitter.Clear();
CmdBuffer.push_back(ImDrawCmd());
_FringeScale = 1.0f;
_FringeScale = _Data->InitialFringeScale;
}
void ImDrawList::_ClearFreeMemory()
@@ -2401,13 +2404,13 @@ ImFontConfig::ImFontConfig()
// - ImFontAtlas::AddCustomRectRegular()
// - ImFontAtlas::AddCustomRectFontGlyph()
// - ImFontAtlas::CalcCustomRectUV()
// - ImFontAtlas::GetMouseCursorTexData()
// - ImFontAtlasGetMouseCursorTexData()
// - ImFontAtlas::Build()
// - ImFontAtlasBuildMultiplyCalcLookupTable()
// - ImFontAtlasBuildMultiplyRectAlpha8()
// - ImFontAtlasBuildWithStbTruetype()
// - ImFontAtlasGetBuilderForStbTruetype()
// - ImFontAtlasUpdateConfigDataPointers()
// - ImFontAtlasUpdateSourcesPointers()
// - ImFontAtlasBuildSetupFont()
// - ImFontAtlasBuildPackCustomRects()
// - ImFontAtlasBuildRender8bppRectFromString()
@@ -2465,6 +2468,8 @@ static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3
{ ImVec2(73,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNESW
{ ImVec2(55,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNWSE
{ ImVec2(91,0), ImVec2(17,22), ImVec2( 5, 0) }, // ImGuiMouseCursor_Hand
{ ImVec2(0,3), ImVec2(12,19), ImVec2(0, 0) }, // ImGuiMouseCursor_Wait // Arrow + custom code in ImGui::RenderMouseCursor()
{ ImVec2(0,3), ImVec2(12,19), ImVec2(0, 0) }, // ImGuiMouseCursor_Progress // Arrow + custom code in ImGui::RenderMouseCursor()
{ ImVec2(109,0),ImVec2(13,15), ImVec2( 6, 7) }, // ImGuiMouseCursor_NotAllowed
};
@@ -2484,7 +2489,7 @@ ImFontAtlas::~ImFontAtlas()
void ImFontAtlas::ClearInputData()
{
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
for (ImFontConfig& font_cfg : ConfigData)
for (ImFontConfig& font_cfg : Sources)
if (font_cfg.FontData && font_cfg.FontDataOwnedByAtlas)
{
IM_FREE(font_cfg.FontData);
@@ -2493,12 +2498,12 @@ void ImFontAtlas::ClearInputData()
// When clearing this we lose access to the font name and other information used to build the font.
for (ImFont* font : Fonts)
if (font->ConfigData >= ConfigData.Data && font->ConfigData < ConfigData.Data + ConfigData.Size)
if (font->Sources >= Sources.Data && font->Sources < Sources.Data + Sources.Size)
{
font->ConfigData = NULL;
font->ConfigDataCount = 0;
font->Sources = NULL;
font->SourcesCount = 0;
}
ConfigData.clear();
Sources.clear();
CustomRects.clear();
PackIdMouseCursors = PackIdLines = -1;
// Important: we leave TexReady untouched
@@ -2581,8 +2586,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
else
IM_ASSERT(Fonts.Size > 0 && "Cannot use MergeMode for the first font"); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font.
ConfigData.push_back(*font_cfg);
ImFontConfig& new_font_cfg = ConfigData.back();
Sources.push_back(*font_cfg);
ImFontConfig& new_font_cfg = Sources.back();
if (new_font_cfg.DstFont == NULL)
new_font_cfg.DstFont = Fonts.back();
if (!new_font_cfg.FontDataOwnedByAtlas)
@@ -2598,8 +2603,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
// - We may support it better later and remove this rounding.
new_font_cfg.SizePixels = ImTrunc(new_font_cfg.SizePixels);
// Pointers to ConfigData and BuilderData are otherwise dangling
ImFontAtlasUpdateConfigDataPointers(this);
// Pointers to Sources data are otherwise dangling
ImFontAtlasUpdateSourcesPointers(this);
// Invalidate texture
TexReady = false;
@@ -2669,7 +2674,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels,
{
// Store a short copy of filename into into the font name for convenience
const char* p;
for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
for (p = filename + ImStrlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels);
}
return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges);
@@ -2704,7 +2709,7 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_d
ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges)
{
int compressed_ttf_size = (((int)strlen(compressed_ttf_data_base85) + 4) / 5) * 4;
int compressed_ttf_size = (((int)ImStrlen(compressed_ttf_data_base85) + 4) / 5) * 4;
void* compressed_ttf = IM_ALLOC((size_t)compressed_ttf_size);
Decode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf);
ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges);
@@ -2751,24 +2756,24 @@ void ImFontAtlas::CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* ou
*out_uv_max = ImVec2((float)(rect->X + rect->Width) * TexUvScale.x, (float)(rect->Y + rect->Height) * TexUvScale.y);
}
bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2])
bool ImFontAtlasGetMouseCursorTexData(ImFontAtlas* atlas, ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2])
{
if (cursor_type <= ImGuiMouseCursor_None || cursor_type >= ImGuiMouseCursor_COUNT)
return false;
if (Flags & ImFontAtlasFlags_NoMouseCursors)
if (atlas->Flags & ImFontAtlasFlags_NoMouseCursors)
return false;
IM_ASSERT(PackIdMouseCursors != -1);
ImFontAtlasCustomRect* r = GetCustomRectByIndex(PackIdMouseCursors);
IM_ASSERT(atlas->PackIdMouseCursors != -1);
ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdMouseCursors);
ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r->X, (float)r->Y);
ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1];
*out_size = size;
*out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2];
out_uv_border[0] = (pos) * TexUvScale;
out_uv_border[1] = (pos + size) * TexUvScale;
out_uv_border[0] = (pos) * atlas->TexUvScale;
out_uv_border[1] = (pos + size) * atlas->TexUvScale;
pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W + 1;
out_uv_fill[0] = (pos) * TexUvScale;
out_uv_fill[1] = (pos + size) * TexUvScale;
out_uv_fill[0] = (pos) * atlas->TexUvScale;
out_uv_fill[1] = (pos + size) * atlas->TexUvScale;
return true;
}
@@ -2777,7 +2782,7 @@ bool ImFontAtlas::Build()
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
// Default font is none are specified
if (ConfigData.Size == 0)
if (Sources.Size == 0)
AddFontDefault();
// Select builder
@@ -2819,11 +2824,11 @@ void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsig
*data = table[*data];
}
void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* cfg, int* out_oversample_h, int* out_oversample_v)
void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* src, int* out_oversample_h, int* out_oversample_v)
{
// Automatically disable horizontal oversampling over size 36
*out_oversample_h = (cfg->OversampleH != 0) ? cfg->OversampleH : (cfg->SizePixels * cfg->RasterizerDensity > 36.0f || cfg->PixelSnapH) ? 1 : 2;
*out_oversample_v = (cfg->OversampleV != 0) ? cfg->OversampleV : 1;
*out_oversample_h = (src->OversampleH != 0) ? src->OversampleH : (src->SizePixels * src->RasterizerDensity > 36.0f || src->PixelSnapH) ? 1 : 2;
*out_oversample_v = (src->OversampleV != 0) ? src->OversampleV : 1;
}
#ifdef IMGUI_ENABLE_STB_TRUETYPE
@@ -2866,7 +2871,7 @@ static void UnpackBitVectorToFlatIndexList(const ImBitVector* in, ImVector<int>*
static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
{
IM_ASSERT(atlas->ConfigData.Size > 0);
IM_ASSERT(atlas->Sources.Size > 0);
ImFontAtlasBuildInit(atlas);
@@ -2880,32 +2885,32 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
// Temporary storage for building
ImVector<ImFontBuildSrcData> src_tmp_array;
ImVector<ImFontBuildDstData> dst_tmp_array;
src_tmp_array.resize(atlas->ConfigData.Size);
src_tmp_array.resize(atlas->Sources.Size);
dst_tmp_array.resize(atlas->Fonts.Size);
memset(src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes());
memset(dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes());
// 1. Initialize font loading structure, check font data validity
for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++)
for (int src_i = 0; src_i < atlas->Sources.Size; src_i++)
{
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
ImFontConfig& cfg = atlas->ConfigData[src_i];
IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas));
ImFontConfig& src = atlas->Sources[src_i];
IM_ASSERT(src.DstFont && (!src.DstFont->IsLoaded() || src.DstFont->ContainerAtlas == atlas));
// Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
// Find index from src.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
src_tmp.DstIndex = -1;
for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
if (cfg.DstFont == atlas->Fonts[output_i])
if (src.DstFont == atlas->Fonts[output_i])
src_tmp.DstIndex = output_i;
if (src_tmp.DstIndex == -1)
{
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
IM_ASSERT(src_tmp.DstIndex != -1); // src.DstFont not pointing within atlas->Fonts[] array?
return false;
}
// Initialize helper structure for font loading and verify that the TTF/OTF data is correct
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo);
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)src.FontData, src.FontNo);
IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found.");
if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset))
if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)src.FontData, font_offset))
{
IM_ASSERT(0 && "stbtt_InitFont(): failed to parse FontData. It is correct and complete? Check FontDataSize.");
return false;
@@ -2913,7 +2918,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
// Measure highest codepoints
ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
src_tmp.SrcRanges = src.GlyphRanges ? src.GlyphRanges : atlas->GetGlyphRangesDefault();
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
{
// Check for valid range. This may also help detect *some* dangling pointers, because a common
@@ -2992,12 +2997,12 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
buf_packedchars_out_n += src_tmp.GlyphsCount;
// Automatic selection of oversampling parameters
ImFontConfig& cfg = atlas->ConfigData[src_i];
ImFontConfig& src = atlas->Sources[src_i];
int oversample_h, oversample_v;
ImFontAtlasBuildGetOversampleFactors(&cfg, &oversample_h, &oversample_v);
ImFontAtlasBuildGetOversampleFactors(&src, &oversample_h, &oversample_v);
// Convert our ranges in the format stb_truetype wants
src_tmp.PackRange.font_size = cfg.SizePixels * cfg.RasterizerDensity;
src_tmp.PackRange.font_size = src.SizePixels * src.RasterizerDensity;
src_tmp.PackRange.first_unicode_codepoint_in_range = 0;
src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data;
src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size;
@@ -3006,7 +3011,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
src_tmp.PackRange.v_oversample = (unsigned char)oversample_v;
// Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects)
const float scale = (cfg.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels * cfg.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels * cfg.RasterizerDensity);
const float scale = (src.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, src.SizePixels * src.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -src.SizePixels * src.RasterizerDensity);
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
{
int x0, y0, x1, y1;
@@ -3066,7 +3071,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
// 8. Render/rasterize font characters into the texture
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
ImFontConfig& cfg = atlas->ConfigData[src_i];
ImFontConfig& src = atlas->Sources[src_i];
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
if (src_tmp.GlyphsCount == 0)
continue;
@@ -3074,10 +3079,10 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
stbtt_PackFontRangesRenderIntoRects(&spc, &src_tmp.FontInfo, &src_tmp.PackRange, 1, src_tmp.Rects);
// Apply multiply operator
if (cfg.RasterizerMultiply != 1.0f)
if (src.RasterizerMultiply != 1.0f)
{
unsigned char multiply_table[256];
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, src.RasterizerMultiply);
stbrp_rect* r = &src_tmp.Rects[0];
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++, r++)
if (r->was_packed)
@@ -3095,22 +3100,22 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
{
// When merging fonts with MergeMode=true:
// - We can have multiple input fonts writing into a same destination font.
// - dst_font->ConfigData is != from cfg which is our source configuration.
// - dst_font->Sources is != from src which is our source configuration.
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
ImFontConfig& cfg = atlas->ConfigData[src_i];
ImFont* dst_font = cfg.DstFont;
ImFontConfig& src = atlas->Sources[src_i];
ImFont* dst_font = src.DstFont;
const float font_scale = stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels);
const float font_scale = stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, src.SizePixels);
int unscaled_ascent, unscaled_descent, unscaled_line_gap;
stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
const float ascent = ImCeil(unscaled_ascent * font_scale);
const float descent = ImFloor(unscaled_descent * font_scale);
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
const float font_off_x = cfg.GlyphOffset.x;
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
ImFontAtlasBuildSetupFont(atlas, dst_font, &src, ascent, descent);
const float font_off_x = src.GlyphOffset.x;
const float font_off_y = src.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
const float inv_rasterization_scale = 1.0f / cfg.RasterizerDensity;
const float inv_rasterization_scale = 1.0f / src.RasterizerDensity;
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
{
@@ -3124,7 +3129,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
float y0 = q.y0 * inv_rasterization_scale + font_off_y;
float x1 = q.x1 * inv_rasterization_scale + font_off_x;
float y1 = q.y1 * inv_rasterization_scale + font_off_y;
dst_font->AddGlyph(&cfg, (ImWchar)codepoint, x0, y0, x1, y1, q.s0, q.t0, q.s1, q.t1, pc.xadvance * inv_rasterization_scale);
dst_font->AddGlyph(&src, (ImWchar)codepoint, x0, y0, x1, y1, q.s0, q.t0, q.s1, q.t1, pc.xadvance * inv_rasterization_scale);
}
}
@@ -3144,17 +3149,17 @@ const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype()
#endif // IMGUI_ENABLE_STB_TRUETYPE
void ImFontAtlasUpdateConfigDataPointers(ImFontAtlas* atlas)
void ImFontAtlasUpdateSourcesPointers(ImFontAtlas* atlas)
{
for (ImFontConfig& font_cfg : atlas->ConfigData)
for (ImFontConfig& src : atlas->Sources)
{
ImFont* font = font_cfg.DstFont;
if (!font_cfg.MergeMode)
ImFont* font = src.DstFont;
if (!src.MergeMode)
{
font->ConfigData = &font_cfg;
font->ConfigDataCount = 0;
font->Sources = &src;
font->SourcesCount = 0;
}
font->ConfigDataCount++;
font->SourcesCount++;
}
}
@@ -3164,7 +3169,7 @@ void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* f
{
font->ClearOutputData();
font->FontSize = font_config->SizePixels;
IM_ASSERT(font->ConfigData == font_config);
IM_ASSERT(font->Sources == font_config);
font->ContainerAtlas = atlas;
font->Ascent = ascent;
font->Descent = descent;
@@ -3349,7 +3354,7 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
if (r->Font == NULL || r->GlyphID == 0)
continue;
// Will ignore ImFontConfig settings: GlyphMinAdvanceX, GlyphMinAdvanceY, GlyphExtraSpacing, PixelSnapH
// Will ignore ImFontConfig settings: GlyphMinAdvanceX, GlyphMinAdvanceY, PixelSnapH
IM_ASSERT(r->Font->ContainerAtlas == atlas);
ImVec2 uv0, uv1;
atlas->CalcCustomRectUV(r, &uv0, &uv1);
@@ -3685,21 +3690,8 @@ void ImFontGlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges)
ImFont::ImFont()
{
FontSize = 0.0f;
FallbackAdvanceX = 0.0f;
FallbackChar = 0;
EllipsisChar = 0;
EllipsisWidth = EllipsisCharStep = 0.0f;
EllipsisCharCount = 0;
FallbackGlyph = NULL;
ContainerAtlas = NULL;
ConfigData = NULL;
ConfigDataCount = 0;
DirtyLookupTables = false;
memset(this, 0, sizeof(*this));
Scale = 1.0f;
Ascent = Descent = 0.0f;
MetricsTotalSurface = 0;
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
}
ImFont::~ImFont()
@@ -3770,8 +3762,10 @@ void ImFont::BuildLookupTable()
}
// Mark special glyphs as not visible (note that AddGlyph already mark as non-visible glyphs with zero-size polygons)
SetGlyphVisible((ImWchar)' ', false);
SetGlyphVisible((ImWchar)'\t', false);
if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)' '))
glyph->Visible = false;
if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)'\t'))
glyph->Visible = false;
// Setup Fallback character
const ImWchar fallback_chars[] = { (ImWchar)IM_UNICODE_CODEPOINT_INVALID, (ImWchar)'?', (ImWchar)' ' };
@@ -3794,7 +3788,7 @@ void ImFont::BuildLookupTable()
// Setup Ellipsis character. It is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis).
// However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character.
// FIXME: Note that 0x2026 is rarely included in our font ranges. Because of this we are more likely to use three individual dots.
const ImWchar ellipsis_chars[] = { ConfigData->EllipsisChar, (ImWchar)0x2026, (ImWchar)0x0085 };
const ImWchar ellipsis_chars[] = { Sources->EllipsisChar, (ImWchar)0x2026, (ImWchar)0x0085 };
const ImWchar dots_chars[] = { (ImWchar)'.', (ImWchar)0xFF0E };
if (EllipsisChar == 0)
EllipsisChar = FindFirstExistingGlyph(this, ellipsis_chars, IM_ARRAYSIZE(ellipsis_chars));
@@ -3827,12 +3821,6 @@ bool ImFont::IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last)
return true;
}
void ImFont::SetGlyphVisible(ImWchar c, bool visible)
{
if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)c))
glyph->Visible = visible ? 1 : 0;
}
void ImFont::GrowIndex(int new_size)
{
IM_ASSERT(IndexAdvanceX.Size == IndexLookup.Size);
@@ -3844,27 +3832,27 @@ void ImFont::GrowIndex(int new_size)
// x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero.
// Not to be mistaken with texture coordinates, which are held by u0/v0/u1/v1 in normalized format (0.0..1.0 on each texture axis).
// 'cfg' is not necessarily == 'this->ConfigData' because multiple source fonts+configs can be used to build one target font.
void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x)
// 'src' is not necessarily == 'this->Sources' because multiple source fonts+configs can be used to build one target font.
void ImFont::AddGlyph(const ImFontConfig* src, ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x)
{
if (cfg != NULL)
if (src != NULL)
{
// Clamp & recenter if needed
const float advance_x_original = advance_x;
advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX);
advance_x = ImClamp(advance_x, src->GlyphMinAdvanceX, src->GlyphMaxAdvanceX);
if (advance_x != advance_x_original)
{
float char_off_x = cfg->PixelSnapH ? ImTrunc((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f;
float char_off_x = src->PixelSnapH ? ImTrunc((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f;
x0 += char_off_x;
x1 += char_off_x;
}
// Snap to pixel
if (cfg->PixelSnapH)
if (src->PixelSnapH)
advance_x = IM_ROUND(advance_x);
// Bake spacing
advance_x += cfg->GlyphExtraSpacing.x;
// Bake extra spacing
advance_x += src->GlyphExtraAdvanceX;
}
int glyph_idx = Glyphs.Size;
@@ -3907,7 +3895,7 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
}
// Find glyph, return fallback if missing
const ImFontGlyph* ImFont::FindGlyph(ImWchar c)
ImFontGlyph* ImFont::FindGlyph(ImWchar c)
{
if (c >= (size_t)IndexLookup.Size)
return FallbackGlyph;
@@ -3917,7 +3905,7 @@ const ImFontGlyph* ImFont::FindGlyph(ImWchar c)
return &Glyphs.Data[i];
}
const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c)
ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c)
{
if (c >= (size_t)IndexLookup.Size)
return NULL;
@@ -4043,7 +4031,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining)
{
if (!text_end)
text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this.
text_end = text_begin + ImStrlen(text_begin); // FIXME-OPT: Need to avoid this.
const float line_height = size;
const float scale = size / FontSize;
@@ -4143,7 +4131,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
return;
if (!text_end)
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
text_end = text_begin + ImStrlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
const float scale = size / FontSize;
const float line_height = FontSize * scale;
@@ -4155,7 +4143,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
if (y + line_height < clip_rect.y)
while (y + line_height < clip_rect.y && s < text_end)
{
const char* line_end = (const char*)memchr(s, '\n', text_end - s);
const char* line_end = (const char*)ImMemchr(s, '\n', text_end - s);
if (word_wrap_enabled)
{
// FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPositionA().
@@ -4179,7 +4167,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
float y_end = y;
while (y_end < clip_rect.w && s_end < text_end)
{
s_end = (const char*)memchr(s_end, '\n', text_end - s_end);
s_end = (const char*)ImMemchr(s_end, '\n', text_end - s_end);
s_end = s_end ? s_end + 1 : text_end;
y_end += line_height;
}

View File

@@ -166,7 +166,7 @@ namespace
// NB: No ctor/dtor, explicitly call Init()/Shutdown()
struct FreeTypeFont
{
bool InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime.
bool InitFont(FT_Library ft_library, const ImFontConfig& src, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime.
void CloseFont();
void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
@@ -185,9 +185,9 @@ namespace
float InvRasterizationDensity;
};
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags)
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& src, unsigned int extra_font_builder_flags)
{
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)src.FontData, (uint32_t)src.FontDataSize, (uint32_t)src.FontNo, &Face);
if (error != 0)
return false;
error = FT_Select_Charmap(Face, FT_ENCODING_UNICODE);
@@ -195,7 +195,7 @@ namespace
return false;
// Convert to FreeType flags (NB: Bold and Oblique are processed separately)
UserFlags = cfg.FontBuilderFlags | extra_font_builder_flags;
UserFlags = src.FontBuilderFlags | extra_font_builder_flags;
LoadFlags = 0;
if ((UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) == 0)
@@ -222,11 +222,11 @@ namespace
if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor)
LoadFlags |= FT_LOAD_COLOR;
RasterizationDensity = cfg.RasterizerDensity;
RasterizationDensity = src.RasterizerDensity;
InvRasterizationDensity = 1.0f / RasterizationDensity;
memset(&Info, 0, sizeof(Info));
SetPixelHeight((uint32_t)cfg.SizePixels);
SetPixelHeight((uint32_t)src.SizePixels);
return true;
}
@@ -269,11 +269,11 @@ namespace
if (glyph_index == 0)
return nullptr;
// If this crash for you: FreeType 2.11.0 has a crash bug on some bitmap/colored fonts.
// - https://gitlab.freedesktop.org/freetype/freetype/-/issues/1076
// - https://github.com/ocornut/imgui/issues/4567
// - https://github.com/ocornut/imgui/issues/4566
// You can use FreeType 2.10, or the patched version of 2.11.0 in VcPkg, or probably any upcoming FreeType version.
// If this crash for you: FreeType 2.11.0 has a crash bug on some bitmap/colored fonts.
// - https://gitlab.freedesktop.org/freetype/freetype/-/issues/1076
// - https://github.com/ocornut/imgui/issues/4567
// - https://github.com/ocornut/imgui/issues/4566
// You can use FreeType 2.10, or the patched version of 2.11.0 in VcPkg, or probably any upcoming FreeType version.
FT_Error error = FT_Load_Glyph(Face, glyph_index, LoadFlags);
if (error)
return nullptr;
@@ -443,7 +443,7 @@ struct ImFontBuildDstDataFT
bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
{
IM_ASSERT(atlas->ConfigData.Size > 0);
IM_ASSERT(atlas->Sources.Size > 0);
ImFontAtlasBuildInit(atlas);
@@ -458,36 +458,36 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
bool src_load_color = false;
ImVector<ImFontBuildSrcDataFT> src_tmp_array;
ImVector<ImFontBuildDstDataFT> dst_tmp_array;
src_tmp_array.resize(atlas->ConfigData.Size);
src_tmp_array.resize(atlas->Sources.Size);
dst_tmp_array.resize(atlas->Fonts.Size);
memset((void*)src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes());
memset((void*)dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes());
// 1. Initialize font loading structure, check font data validity
for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++)
for (int src_i = 0; src_i < atlas->Sources.Size; src_i++)
{
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
ImFontConfig& cfg = atlas->ConfigData[src_i];
ImFontConfig& src = atlas->Sources[src_i];
FreeTypeFont& font_face = src_tmp.Font;
IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas));
IM_ASSERT(src.DstFont && (!src.DstFont->IsLoaded() || src.DstFont->ContainerAtlas == atlas));
// Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
// Find index from src.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
src_tmp.DstIndex = -1;
for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
if (cfg.DstFont == atlas->Fonts[output_i])
if (src.DstFont == atlas->Fonts[output_i])
src_tmp.DstIndex = output_i;
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
IM_ASSERT(src_tmp.DstIndex != -1); // src.DstFont not pointing within atlas->Fonts[] array?
if (src_tmp.DstIndex == -1)
return false;
// Load font
if (!font_face.InitFont(ft_library, cfg, extra_flags))
if (!font_face.InitFont(ft_library, src, extra_flags))
return false;
// Measure highest codepoints
src_load_color |= (cfg.FontBuilderFlags & ImGuiFreeTypeBuilderFlags_LoadColor) != 0;
src_load_color |= (src.FontBuilderFlags & ImGuiFreeTypeBuilderFlags_LoadColor) != 0;
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
src_tmp.SrcRanges = src.GlyphRanges ? src.GlyphRanges : atlas->GetGlyphRangesDefault();
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
{
// Check for valid range. This may also help detect *some* dangling pointers, because a common
@@ -577,7 +577,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
ImFontConfig& cfg = atlas->ConfigData[src_i];
ImFontConfig& src = atlas->Sources[src_i];
if (src_tmp.GlyphsCount == 0)
continue;
@@ -585,10 +585,10 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
buf_rects_out_n += src_tmp.GlyphsCount;
// Compute multiply table if requested
const bool multiply_enabled = (cfg.RasterizerMultiply != 1.0f);
const bool multiply_enabled = (src.RasterizerMultiply != 1.0f);
unsigned char multiply_table[256];
if (multiply_enabled)
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, src.RasterizerMultiply);
// Gather the sizes of all rectangles we will need to pack
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
@@ -687,18 +687,18 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
// When merging fonts with MergeMode=true:
// - We can have multiple input fonts writing into a same destination font.
// - dst_font->ConfigData is != from cfg which is our source configuration.
ImFontConfig& cfg = atlas->ConfigData[src_i];
ImFont* dst_font = cfg.DstFont;
// - dst_font->Sources is != from src which is our source configuration.
ImFontConfig& src = atlas->Sources[src_i];
ImFont* dst_font = src.DstFont;
const float ascent = src_tmp.Font.Info.Ascender;
const float descent = src_tmp.Font.Info.Descender;
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
ImFontAtlasBuildSetupFont(atlas, dst_font, &src, ascent, descent);
if (src_tmp.GlyphsCount == 0)
continue;
const float font_off_x = cfg.GlyphOffset.x;
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
const float font_off_x = src.GlyphOffset.x;
const float font_off_y = src.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
const int padding = atlas->TexGlyphPadding;
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
@@ -724,7 +724,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
float v0 = (ty) / (float)atlas->TexHeight;
float u1 = (tx + info.Width) / (float)atlas->TexWidth;
float v1 = (ty + info.Height) / (float)atlas->TexHeight;
dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX * src_tmp.Font.InvRasterizationDensity);
dst_font->AddGlyph(&src, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX * src_tmp.Font.InvRasterizationDensity);
ImFontGlyph* dst_glyph = &dst_font->Glyphs.back();
IM_ASSERT(dst_glyph->Codepoint == src_glyph.Codepoint);

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.8
// dear imgui, v1.91b
// (tables and columns code)
/*
@@ -221,6 +221,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
#pragma clang diagnostic ignored "-Wformat" // warning: format specifies type 'int' but the argument has type 'unsigned int'
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
@@ -230,6 +231,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
@@ -340,6 +342,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
{
ItemSize(outer_rect);
ItemAdd(outer_rect, id);
g.NextWindowData.ClearFlags();
return false;
}
@@ -415,12 +418,15 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// Reset scroll if we are reactivating it
if ((previous_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasScroll) == 0)
if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasScroll) == 0)
SetNextWindowScroll(ImVec2(0.0f, 0.0f));
// Create scrolling region (without border and zero window padding)
ImGuiWindowFlags child_window_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
BeginChildEx(name, instance_id, outer_rect.GetSize(), ImGuiChildFlags_None, child_window_flags);
ImGuiChildFlags child_child_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) ? g.NextWindowData.ChildFlags : ImGuiChildFlags_None;
ImGuiWindowFlags child_window_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasWindowFlags) ? g.NextWindowData.WindowFlags : ImGuiWindowFlags_None;
if (flags & ImGuiTableFlags_ScrollX)
child_window_flags |= ImGuiWindowFlags_HorizontalScrollbar;
BeginChildEx(name, instance_id, outer_rect.GetSize(), child_child_flags, child_window_flags);
table->InnerWindow = g.CurrentWindow;
table->WorkRect = table->InnerWindow->WorkRect;
table->OuterRect = table->InnerWindow->Rect();
@@ -573,6 +579,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// Initialize
table->SettingsOffset = -1;
table->IsSortSpecsDirty = true;
table->IsSettingsDirty = true; // Records itself into .ini file even when in default state (#7934)
table->InstanceInteracted = -1;
table->ContextPopupColumn = -1;
table->ReorderColumn = table->ResizedColumn = table->LastResizedColumn = -1;
@@ -972,7 +979,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// [Part 4] Apply final widths based on requested widths
const ImRect work_rect = table->WorkRect;
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synched tables with mismatching scrollbar state (#5920)
const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synced tables with mismatching scrollbar state (#5920)
const float width_avail = ImMax(1.0f, (((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth()) - width_removed);
const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests;
float width_remaining_for_stretched_columns = width_avail_for_stretched_columns;
@@ -1385,7 +1392,7 @@ void ImGui::EndTable()
// Setup inner scrolling range
// FIXME: This ideally should be done earlier, in BeginTable() SetNextWindowContentSize call, just like writing to inner_window->DC.CursorMaxPos.y,
// but since the later is likely to be impossible to do we'd rather update both axises together.
// but since the later is likely to be impossible to do we'd rather update both axes together.
if (table->Flags & ImGuiTableFlags_ScrollX)
{
const float outer_padding_for_border = (table->Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f;
@@ -1560,6 +1567,31 @@ void ImGui::EndTable()
NavUpdateCurrentWindowIsScrollPushableX();
}
// Called in TableSetupColumn() when initializing and in TableLoadSettings() for defaults before applying stored settings.
// 'init_mask' specify which fields to initialize.
static void TableInitColumnDefaults(ImGuiTable* table, ImGuiTableColumn* column, ImGuiTableColumnFlags init_mask)
{
ImGuiTableColumnFlags flags = column->Flags;
if (init_mask & ImGuiTableFlags_Resizable)
{
float init_width_or_weight = column->InitStretchWeightOrWidth;
column->WidthRequest = ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f;
column->StretchWeight = (init_width_or_weight > 0.0f && (flags & ImGuiTableColumnFlags_WidthStretch)) ? init_width_or_weight : -1.0f;
if (init_width_or_weight > 0.0f) // Disable auto-fit if an explicit width/weight has been specified
column->AutoFitQueue = 0x00;
}
if (init_mask & ImGuiTableFlags_Reorderable)
column->DisplayOrder = (ImGuiTableColumnIdx)table->Columns.index_from_ptr(column);
if (init_mask & ImGuiTableFlags_Hideable)
column->IsUserEnabled = column->IsUserEnabledNextFrame = (flags & ImGuiTableColumnFlags_DefaultHide) ? 0 : 1;
if (init_mask & ImGuiTableFlags_Sortable)
{
// Multiple columns using _DefaultSort will be reassigned unique SortOrder values when building the sort specs.
column->SortOrder = (flags & ImGuiTableColumnFlags_DefaultSort) ? 0 : -1;
column->SortDirection = (flags & ImGuiTableColumnFlags_DefaultSort) ? ((flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending)) : (ImS8)ImGuiSortDirection_None;
}
}
// See "COLUMNS SIZING POLICIES" comments at the top of this file
// If (init_width_or_weight <= 0.0f) it is ignored
void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
@@ -1588,7 +1620,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitly in either Table or Column.");
// When passing a width automatically enforce WidthFixed policy
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not Resizable)
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not resizable)
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f)
if ((table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedFit || (table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame)
flags |= ImGuiTableColumnFlags_WidthFixed;
@@ -1606,27 +1638,10 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
column->InitStretchWeightOrWidth = init_width_or_weight;
if (table->IsInitializing)
{
// Init width or weight
ImGuiTableFlags init_flags = ~table->SettingsLoadedFlags;
if (column->WidthRequest < 0.0f && column->StretchWeight < 0.0f)
{
if ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f)
column->WidthRequest = init_width_or_weight;
if (flags & ImGuiTableColumnFlags_WidthStretch)
column->StretchWeight = (init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f;
// Disable auto-fit if an explicit width/weight has been specified
if (init_width_or_weight > 0.0f)
column->AutoFitQueue = 0x00;
}
// Init default visibility/sort state
if ((flags & ImGuiTableColumnFlags_DefaultHide) && (table->SettingsLoadedFlags & ImGuiTableFlags_Hideable) == 0)
column->IsUserEnabled = column->IsUserEnabledNextFrame = false;
if (flags & ImGuiTableColumnFlags_DefaultSort && (table->SettingsLoadedFlags & ImGuiTableFlags_Sortable) == 0)
{
column->SortOrder = 0; // Multiple columns using _DefaultSort will be reassigned unique SortOrder values when building the sort specs.
column->SortDirection = (column->Flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending);
}
init_flags |= ImGuiTableFlags_Resizable;
TableInitColumnDefaults(table, column, init_flags);
}
// Store name (append with zero-terminator in contiguous buffer)
@@ -1635,7 +1650,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
if (label != NULL && label[0] != 0)
{
column->NameOffset = (ImS16)table->ColumnsNames.size();
table->ColumnsNames.append(label, label + strlen(label) + 1);
table->ColumnsNames.append(label, label + ImStrlen(label) + 1);
}
}
@@ -2101,7 +2116,11 @@ bool ImGui::TableSetColumnIndex(int column_n)
{
if (table->CurrentColumn != -1)
TableEndCell(table);
IM_ASSERT(column_n >= 0 && table->ColumnsCount);
if ((column_n >= 0 && column_n < table->ColumnsCount) == false)
{
IM_ASSERT_USER_ERROR(column_n >= 0 && column_n < table->ColumnsCount, "TableSetColumnIndex() invalid column index!");
return false;
}
TableBeginCell(table, column_n);
}
@@ -3714,6 +3733,14 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
table->SettingsLoadedFlags = settings->SaveFlags;
table->RefScale = settings->RefScale;
// Initialize default columns settings
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
{
ImGuiTableColumn* column = &table->Columns[column_n];
TableInitColumnDefaults(table, column, ~0);
column->AutoFitQueue = 0x00;
}
// Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn
ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
ImU64 display_order_mask = 0;
@@ -3730,14 +3757,12 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
column->StretchWeight = column_settings->WidthOrWeight;
else
column->WidthRequest = column_settings->WidthOrWeight;
column->AutoFitQueue = 0x00;
}
if (settings->SaveFlags & ImGuiTableFlags_Reorderable)
column->DisplayOrder = column_settings->DisplayOrder;
else
column->DisplayOrder = (ImGuiTableColumnIdx)column_n;
display_order_mask |= (ImU64)1 << column->DisplayOrder;
column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled;
if ((settings->SaveFlags & ImGuiTableFlags_Hideable) && column_settings->IsEnabled != -1)
column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled == 1;
column->SortOrder = column_settings->SortOrder;
column->SortDirection = column_settings->SortDirection;
}
@@ -3833,8 +3858,7 @@ static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandle
const bool save_visible = (settings->SaveFlags & ImGuiTableFlags_Hideable) != 0;
const bool save_order = (settings->SaveFlags & ImGuiTableFlags_Reorderable) != 0;
const bool save_sort = (settings->SaveFlags & ImGuiTableFlags_Sortable) != 0;
if (!save_size && !save_visible && !save_order && !save_sort)
continue;
// We need to save the [Table] entry even if all the bools are false, since this records a table with "default settings".
buf->reserve(buf->size() + 30 + settings->ColumnsCount * 50); // ballpark reserve
buf->appendf("[%s][0x%08X,%d]\n", handler->TypeName, settings->ID, settings->ColumnsCount);

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.8
// dear imgui, v1.91b
// (widgets code)
/*
@@ -70,6 +70,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
#pragma clang diagnostic ignored "-Wformat" // warning: format specifies type 'int' but the argument has type 'unsigned int'
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used.
@@ -80,6 +81,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
@@ -169,7 +171,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
// Calculate length
const char* text_begin = text;
if (text_end == NULL)
text_end = text + strlen(text); // FIXME-OPT
text_end = text + ImStrlen(text); // FIXME-OPT
const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
const float wrap_pos_x = window->DC.TextWrapPos;
@@ -209,7 +211,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
int lines_skipped = 0;
while (line < text_end && lines_skipped < lines_skippable)
{
const char* line_end = (const char*)memchr(line, '\n', text_end - line);
const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line);
if (!line_end)
line_end = text_end;
if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0)
@@ -230,7 +232,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
if (IsClippedEx(line_rect, 0))
break;
const char* line_end = (const char*)memchr(line, '\n', text_end - line);
const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line);
if (!line_end)
line_end = text_end;
text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x);
@@ -245,7 +247,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
int lines_skipped = 0;
while (line < text_end)
{
const char* line_end = (const char*)memchr(line, '\n', text_end - line);
const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line);
if (!line_end)
line_end = text_end;
if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0)
@@ -913,7 +915,7 @@ ImRect ImGui::GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis)
const ImRect outer_rect = window->Rect();
const ImRect inner_rect = window->InnerRect;
const float scrollbar_size = window->ScrollbarSizes[axis ^ 1]; // (ScrollbarSizes.x = width of Y scrollbar; ScrollbarSizes.y = height of X scrollbar)
IM_ASSERT(scrollbar_size > 0.0f);
IM_ASSERT(scrollbar_size >= 0.0f);
const float border_size = IM_ROUND(window->WindowBorderSize * 0.5f);
const float border_top = (window->Flags & ImGuiWindowFlags_MenuBar) ? IM_ROUND(g.Style.FrameBorderSize * 0.5f) : 0.0f;
if (axis == ImGuiAxis_X)
@@ -971,8 +973,8 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
// When we are too small, start hiding and disabling the grab (this reduce visual noise on very small window and facilitate using the window resize grab)
float alpha = 1.0f;
if ((axis == ImGuiAxis_Y) && bb_frame_height < g.FontSize + g.Style.FramePadding.y * 2.0f)
alpha = ImSaturate((bb_frame_height - g.FontSize) / (g.Style.FramePadding.y * 2.0f));
if ((axis == ImGuiAxis_Y) && bb_frame_height < bb_frame_width)
alpha = ImSaturate(bb_frame_height / ImMax(bb_frame_width * 2.0f, 1.0f));
if (alpha <= 0.0f)
return false;
@@ -989,7 +991,8 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
// But we maintain a minimum size in pixel to allow for the user to still aim inside.
IM_ASSERT(ImMax(size_contents_v, size_visible_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers.
const ImS64 win_size_v = ImMax(ImMax(size_contents_v, size_visible_v), (ImS64)1);
const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_visible_v / (float)win_size_v), style.GrabMinSize, scrollbar_size_v);
const float grab_h_minsize = ImMin(bb.GetSize()[axis], style.GrabMinSize);
const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_visible_v / (float)win_size_v), grab_h_minsize, scrollbar_size_v);
const float grab_h_norm = grab_h_pixels / scrollbar_size_v;
// Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
@@ -1061,25 +1064,45 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
// - Read about ImTextureID here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
// - 'uv0' and 'uv1' are texture coordinates. Read about them from the same link above.
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
void ImGui::ImageWithBg(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return;
const float border_size = (border_col.w > 0.0f) ? 1.0f : 0.0f;
const ImVec2 padding(border_size, border_size);
const ImVec2 padding(g.Style.ImageBorderSize, g.Style.ImageBorderSize);
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + image_size + padding * 2.0f);
ItemSize(bb);
if (!ItemAdd(bb, 0))
return;
// Render
if (border_size > 0.0f)
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(border_col), 0.0f, ImDrawFlags_None, border_size);
if (g.Style.ImageBorderSize > 0.0f)
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border), 0.0f, ImDrawFlags_None, g.Style.ImageBorderSize);
if (bg_col.w > 0.0f)
window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col));
window->DrawList->AddImage(user_texture_id, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
}
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1)
{
ImageWithBg(user_texture_id, image_size, uv0, uv1);
}
// 1.91.9 (February 2025) removed 'tint_col' and 'border_col' parameters, made border size not depend on color value. (#8131, #8238)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
{
ImGuiContext& g = *GImGui;
PushStyleVar(ImGuiStyleVar_ImageBorderSize, (border_col.w > 0.0f) ? ImMax(1.0f, g.Style.ImageBorderSize) : 0.0f); // Preserve legacy behavior where border is always visible when border_col's Alpha is >0.0f
PushStyleColor(ImGuiCol_Border, border_col);
ImageWithBg(user_texture_id, image_size, uv0, uv1, ImVec4(0, 0, 0, 0), tint_col);
PopStyleColor();
PopStyleVar();
}
#endif
bool ImGui::ImageButtonEx(ImGuiID id, ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags)
{
ImGuiContext& g = *GImGui;
@@ -1423,7 +1446,7 @@ bool ImGui::TextLink(const char* label)
const ImGuiID id = window->GetID(label);
const char* label_end = FindRenderedTextEnd(label);
ImVec2 pos = window->DC.CursorPos;
ImVec2 pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
ImVec2 size = CalcTextSize(label, label_end, true);
ImRect bb(pos, pos + size);
ItemSize(size, 0.0f);
@@ -1828,7 +1851,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
ImGuiNextWindowDataFlags backup_next_window_data_flags = g.NextWindowData.Flags;
ImGuiNextWindowDataFlags backup_next_window_data_flags = g.NextWindowData.HasFlags;
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
if (window->SkipItems)
return false;
@@ -1897,7 +1920,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
if (!popup_open)
return false;
g.NextWindowData.Flags = backup_next_window_data_flags;
g.NextWindowData.HasFlags = backup_next_window_data_flags;
return BeginComboPopup(popup_id, bb, flags);
}
@@ -1912,7 +1935,7 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
// Set popup size
float w = bb.GetWidth();
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint)
if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSizeConstraint)
{
g.NextWindowData.SizeConstraintRect.Min.x = ImMax(g.NextWindowData.SizeConstraintRect.Min.x, w);
}
@@ -1926,9 +1949,9 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
else if (flags & ImGuiComboFlags_HeightSmall) popup_max_height_in_items = 4;
else if (flags & ImGuiComboFlags_HeightLarge) popup_max_height_in_items = 20;
ImVec2 constraint_min(0.0f, 0.0f), constraint_max(FLT_MAX, FLT_MAX);
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.x <= 0.0f) // Don't apply constraints if user specified a size
if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.x <= 0.0f) // Don't apply constraints if user specified a size
constraint_min.x = w;
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.y <= 0.0f)
if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.y <= 0.0f)
constraint_max.y = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items);
SetNextWindowSizeConstraints(constraint_min, constraint_max);
}
@@ -2043,7 +2066,7 @@ static const char* Items_SingleStringGetter(void* data, int idx)
{
if (idx == items_count)
break;
p += strlen(p) + 1;
p += ImStrlen(p) + 1;
items_count++;
}
return *p ? p : NULL;
@@ -2060,7 +2083,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* (*getter)(vo
preview_value = getter(user_data, *current_item);
// The old Combo() API exposed "popup_max_height_in_items". The new more general BeginCombo() API doesn't have/need it, but we emulate it here.
if (popup_max_height_in_items != -1 && !(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint))
if (popup_max_height_in_items != -1 && !(g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSizeConstraint))
SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items)));
if (!BeginCombo(label, preview_value, ImGuiComboFlags_None))
@@ -2111,7 +2134,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa
const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open
while (*p)
{
p += strlen(p) + 1;
p += ImStrlen(p) + 1;
items_count++;
}
bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items);
@@ -2621,7 +2644,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
if (!temp_input_is_active)
{
// Tabbing or CTRL-clicking on Drag turns it into an InputText
// Tabbing or CTRL+click on Drag turns it into an InputText
const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id);
const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2 && TestKeyOwner(ImGuiKey_MouseLeft, id));
const bool make_active = (clicked || double_clicked || g.NavActivateId == id);
@@ -3225,7 +3248,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
if (!temp_input_is_active)
{
// Tabbing or CTRL-clicking on Slider turns it into an input box
// Tabbing or CTRL+click on Slider turns it into an input box
const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id);
const bool make_active = (clicked || g.NavActivateId == id);
if (make_active && clicked)
@@ -3878,7 +3901,7 @@ static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char**
line_count++;
if (s_eol == NULL)
{
s = s + strlen(s);
s = s + ImStrlen(s);
break;
}
s = s_eol + 1;
@@ -4166,7 +4189,7 @@ void ImGuiInputTextState::OnCharPressed(unsigned int c)
// The changes we had to make to stb_textedit_key made it very much UTF-8 specific which is not too great.
char utf8[5];
ImTextCharToUtf8(utf8, c);
stb_textedit_text(this, Stb, utf8, (int)strlen(utf8));
stb_textedit_text(this, Stb, utf8, (int)ImStrlen(utf8));
CursorFollow = true;
CursorAnimReset();
}
@@ -4217,7 +4240,7 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
// Grow internal buffer if needed
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text);
const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)ImStrlen(new_text);
if (new_text_len + BufTextLen >= BufSize)
{
if (!is_resizable)
@@ -4251,7 +4274,7 @@ void ImGui::PushPasswordFont()
ImGuiContext& g = *GImGui;
ImFont* in_font = g.Font;
ImFont* out_font = &g.InputTextPasswordFont;
const ImFontGlyph* glyph = in_font->FindGlyph('*');
ImFontGlyph* glyph = in_font->FindGlyph('*');
out_font->FontSize = in_font->FontSize;
out_font->Scale = in_font->Scale;
out_font->Ascent = in_font->Ascent;
@@ -4273,7 +4296,13 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im
if (c < 0x20)
{
bool pass = false;
pass |= (c == '\n') && (flags & ImGuiInputTextFlags_Multiline) != 0; // Note that an Enter KEY will emit \r and be ignored (we poll for KEY in InputText() code)
pass |= (c == '\n') && (flags & ImGuiInputTextFlags_Multiline) != 0; // Note that an Enter KEY will emit \r and be ignored (we poll for KEY in InputText() code)
if (c == '\n' && input_source_is_clipboard && (flags & ImGuiInputTextFlags_Multiline) == 0) // In single line mode, replace \n with a space
{
c = *p_char = ' ';
pass = true;
}
pass |= (c == '\n') && (flags & ImGuiInputTextFlags_Multiline) != 0;
pass |= (c == '\t') && (flags & ImGuiInputTextFlags_AllowTabInput) != 0;
if (!pass)
return false;
@@ -4539,7 +4568,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const bool init_state = (init_make_active || user_scroll_active);
if (init_reload_from_user_buf)
{
int new_len = (int)strlen(buf);
int new_len = (int)ImStrlen(buf);
IM_ASSERT(new_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
state->WantReloadUserBuf = false;
InputTextReconcileUndoState(state, state->TextA.Data, state->TextLen, buf, new_len);
@@ -4561,7 +4590,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Take a copy of the initial buffer value.
// From the moment we focused we are normally ignoring the content of 'buf' (unless we are in read-only mode)
const int buf_len = (int)strlen(buf);
const int buf_len = (int)ImStrlen(buf);
IM_ASSERT(buf_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
memcpy(state->TextToRevertTo.Data, buf, buf_len + 1);
@@ -4646,7 +4675,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Read-only mode always ever read from source buffer. Refresh TextLen when active.
if (is_readonly && state != NULL)
state->TextLen = (int)strlen(buf);
state->TextLen = (int)ImStrlen(buf);
//if (is_readonly && state != NULL)
// state->TextA.clear(); // Uncomment to facilitate debugging, but we otherwise prefer to keep/amortize th allocation.
}
@@ -4669,7 +4698,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Select the buffer to render.
const bool buf_display_from_state = (render_cursor || render_selection || g.ActiveId == id) && !is_readonly && state;
const bool is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
bool is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
// Password pushes a temporary font with only a fallback glyph
if (is_password && !is_displaying_hint)
@@ -4803,14 +4832,14 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl
const bool is_startend_key_down = is_osx && io.KeyCtrl && !io.KeySuper && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End
// Using Shortcut() with ImGuiInputFlags_RouteFocused (default policy) to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: formet would be handled by InputText)
// Using Shortcut() with ImGuiInputFlags_RouteFocused (default policy) to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: former would be handled by InputText)
// Otherwise we could simply assume that we own the keys as we are active.
const ImGuiInputFlags f_repeat = ImGuiInputFlags_Repeat;
const bool is_cut = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_X, f_repeat, id) || Shortcut(ImGuiMod_Shift | ImGuiKey_Delete, f_repeat, id)) && !is_readonly && !is_password && (!is_multiline || state->HasSelection());
const bool is_copy = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_C, 0, id) || Shortcut(ImGuiMod_Ctrl | ImGuiKey_Insert, 0, id)) && !is_password && (!is_multiline || state->HasSelection());
const bool is_paste = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_V, f_repeat, id) || Shortcut(ImGuiMod_Shift | ImGuiKey_Insert, f_repeat, id)) && !is_readonly;
const bool is_undo = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_Z, f_repeat, id)) && !is_readonly && is_undoable;
const bool is_redo = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_Y, f_repeat, id) || (is_osx && Shortcut(ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Z, f_repeat, id))) && !is_readonly && is_undoable;
const bool is_redo = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_Y, f_repeat, id) || Shortcut(ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Z, f_repeat, id)) && !is_readonly && is_undoable;
const bool is_select_all = Shortcut(ImGuiMod_Ctrl | ImGuiKey_A, 0, id);
// We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful.
@@ -4925,7 +4954,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (const char* clipboard = GetClipboardText())
{
// Filter pasted buffer
const int clipboard_len = (int)strlen(clipboard);
const int clipboard_len = (int)ImStrlen(clipboard);
ImVector<char> clipboard_filtered;
clipboard_filtered.reserve(clipboard_len + 1);
for (const char* s = clipboard; *s != 0; )
@@ -4937,7 +4966,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
continue;
char c_utf8[5];
ImTextCharToUtf8(c_utf8, c);
int out_len = (int)strlen(c_utf8);
int out_len = (int)ImStrlen(c_utf8);
clipboard_filtered.resize(clipboard_filtered.Size + out_len);
memcpy(clipboard_filtered.Data + clipboard_filtered.Size - out_len, c_utf8, out_len);
}
@@ -5067,7 +5096,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (buf_dirty)
{
// Callback may update buffer and thus set buf_dirty even in read-only mode.
IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
IM_ASSERT(callback_data.BufTextLen == (int)ImStrlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
InputTextReconcileUndoState(state, state->CallbackTextBackup.Data, state->CallbackTextBackup.Size - 1, callback_data.Buf, callback_data.BufTextLen);
state->TextLen = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen()
state->CursorAnimReset();
@@ -5151,10 +5180,22 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const int buf_display_max_length = 2 * 1024 * 1024;
const char* buf_display = buf_display_from_state ? state->TextA.Data : buf; //-V595
const char* buf_display_end = NULL; // We have specialized paths below for setting the length
// Display hint when contents is empty
// At this point we need to handle the possibility that a callback could have modified the underlying buffer (#8368)
const bool new_is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
if (new_is_displaying_hint != is_displaying_hint)
{
if (is_password && !is_displaying_hint)
PopFont();
is_displaying_hint = new_is_displaying_hint;
if (is_password && !is_displaying_hint)
PushPasswordFont();
}
if (is_displaying_hint)
{
buf_display = hint;
buf_display_end = hint + strlen(hint);
buf_display_end = hint + ImStrlen(hint);
}
// Render text. We currently only render selection when the widget is active or while scrolling.
@@ -5187,7 +5228,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
int line_count = 1;
if (is_multiline)
{
for (const char* s = text_begin; (s = (const char*)memchr(s, '\n', (size_t)(text_end - s))) != NULL; s++)
for (const char* s = text_begin; (s = (const char*)ImMemchr(s, '\n', (size_t)(text_end - s))) != NULL; s++)
{
if (cursor_line_no == -1 && s >= cursor_ptr) { cursor_line_no = line_count; }
if (selmin_line_no == -1 && s >= selmin_ptr) { selmin_line_no = line_count; }
@@ -5265,7 +5306,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
break;
if (rect_pos.y < clip_rect.y)
{
p = (const char*)memchr((void*)p, '\n', text_selected_end - p);
p = (const char*)ImMemchr((void*)p, '\n', text_selected_end - p);
p = p ? p + 1 : text_selected_end;
}
else
@@ -5317,7 +5358,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
else if (!is_displaying_hint && g.ActiveId == id)
buf_display_end = buf_display + state->TextLen;
else if (!is_displaying_hint)
buf_display_end = buf_display + strlen(buf_display);
buf_display_end = buf_display + ImStrlen(buf_display);
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
{
@@ -5462,7 +5503,7 @@ static void ColorEditRestoreHS(const float* col, float* H, float* S, float* V)
// Edit colors components (each component in 0.0f..1.0f range).
// See enum ImGuiColorEditFlags_ for available options. e.g. Only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set.
// With typical options: Left-click on color square to open color picker. Right-click to open option menu. CTRL-Click over input fields to edit them and TAB to go to next item.
// With typical options: Left-click on color square to open color picker. Right-click to open option menu. CTRL+Click over input fields to edit them and TAB to go to next item.
bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags)
{
ImGuiWindow* window = GetCurrentWindow();
@@ -6166,7 +6207,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
if (g.Style.FrameBorderSize > 0.0f)
RenderFrameBorder(bb.Min, bb.Max, rounding);
else
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color buttons are often in need of some sort of border
}
// Drag and Drop Source
@@ -7088,7 +7129,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
// Text stays at the submission position. Alignment/clipping extents ignore SpanAllColumns.
if (is_visible)
RenderTextClipped(pos, ImVec2(window->WorkRect.Max.x, pos.y + size.y), label, NULL, &label_size, style.SelectableTextAlign, &bb);
RenderTextClipped(pos, ImVec2(ImMin(pos.x + size.x, window->WorkRect.Max.x), pos.y + size.y), label, NULL, &label_size, style.SelectableTextAlign, &bb);
// Automatically close popups
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_NoAutoClosePopups) && (g.LastItemData.ItemFlags & ImGuiItemFlags_AutoClosePopups))
@@ -7151,7 +7192,7 @@ ImGuiTypingSelectRequest* ImGui::GetTypingSelectRequest(ImGuiTypingSelectFlags f
// Append to buffer
const int buffer_max_len = IM_ARRAYSIZE(data->SearchBuffer) - 1;
int buffer_len = (int)strlen(data->SearchBuffer);
int buffer_len = (int)ImStrlen(data->SearchBuffer);
bool select_request = false;
for (ImWchar w : g.IO.InputQueueCharacters)
{
@@ -8834,7 +8875,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
if (g.MenusIdSubmittedThisFrame.contains(id))
{
if (menu_is_open)
menu_is_open = BeginPopupEx(id, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
menu_is_open = BeginPopupMenuEx(id, label, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
else
g.NextWindowData.ClearFlags(); // we behave like Begin() and need to consume those values
return menu_is_open;
@@ -8865,7 +8906,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_NoAutoClosePopups;
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
{
// Menu inside an horizontal menu bar
// Menu inside a horizontal menu bar
// Selectable extend their highlight by half ItemSpacing in each direction.
// For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin()
popup_pos = ImVec2(pos.x - 1.0f - IM_TRUNC(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight);
@@ -8996,7 +9037,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
ImGuiLastItemData last_item_in_parent = g.LastItemData;
SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: misleading: the value will serve as reference for FindBestWindowPosForPopup(), not actual pos.
PushStyleVar(ImGuiStyleVar_ChildRounding, style.PopupRounding); // First level will use _PopupRounding, subsequent will use _ChildRounding
menu_is_open = BeginPopupEx(id, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
menu_is_open = BeginPopupMenuEx(id, label, window_flags); // menu_is_open may be 'false' when the popup is completely clipped (e.g. zero size display)
PopStyleVar();
if (menu_is_open)
{
@@ -10078,7 +10119,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
else
{
tab->NameOffset = (ImS32)tab_bar->TabsNames.size();
tab_bar->TabsNames.append(label, label + strlen(label) + 1);
tab_bar->TabsNames.append(label, label + ImStrlen(label) + 1);
}
// Update selected tab
@@ -10355,13 +10396,24 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
// 'g.ActiveId==close_button_id' will be true when we are holding on the close button, in which case both hovered booleans are false
bool close_button_pressed = false;
bool close_button_visible = false;
if (close_button_id != 0)
if (is_contents_visible || bb.GetWidth() >= ImMax(button_sz, g.Style.TabMinWidthForCloseButton))
if (g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == tab_id || g.ActiveId == close_button_id)
close_button_visible = true;
bool unsaved_marker_visible = (flags & ImGuiTabItemFlags_UnsavedDocument) != 0 && (button_pos.x + button_sz <= bb.Max.x);
bool is_hovered = g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == tab_id || g.ActiveId == close_button_id; // Any interaction account for this too.
if (close_button_visible)
if (close_button_id != 0)
{
if (is_contents_visible)
close_button_visible = (g.Style.TabCloseButtonMinWidthSelected < 0.0f) ? true : (is_hovered && bb.GetWidth() >= ImMax(button_sz, g.Style.TabCloseButtonMinWidthSelected));
else
close_button_visible = (g.Style.TabCloseButtonMinWidthUnselected < 0.0f) ? true : (is_hovered && bb.GetWidth() >= ImMax(button_sz, g.Style.TabCloseButtonMinWidthUnselected));
}
// When tabs/document is unsaved, the unsaved marker takes priority over the close button.
const bool unsaved_marker_visible = (flags & ImGuiTabItemFlags_UnsavedDocument) != 0 && (button_pos.x + button_sz <= bb.Max.x) && (!close_button_visible || !is_hovered);
if (unsaved_marker_visible)
{
const ImRect bullet_bb(button_pos, button_pos + ImVec2(button_sz, button_sz));
RenderBullet(draw_list, bullet_bb.GetCenter(), GetColorU32(ImGuiCol_Text));
}
else if (close_button_visible)
{
ImGuiLastItemData last_item_backup = g.LastItemData;
if (CloseButton(close_button_id, button_pos))
@@ -10369,14 +10421,9 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
g.LastItemData = last_item_backup;
// Close with middle mouse button
if (!(flags & ImGuiTabItemFlags_NoCloseWithMiddleMouseButton) && IsMouseClicked(2))
if (is_hovered && !(flags & ImGuiTabItemFlags_NoCloseWithMiddleMouseButton) && IsMouseClicked(2))
close_button_pressed = true;
}
else if (unsaved_marker_visible)
{
const ImRect bullet_bb(button_pos, button_pos + ImVec2(button_sz, button_sz));
RenderBullet(draw_list, bullet_bb.GetCenter(), GetColorU32(ImGuiCol_Text));
}
// This is all rather complicated
// (the main idea is that because the close button only appears on hover, we don't want it to alter the ellipsis position)

View File

@@ -1654,7 +1654,7 @@ SCAJ-20076:
name: "Armored Core - Nexus [Disc 1]"
region: "NTSC-Unk"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SCAJ-20076"
@@ -1667,7 +1667,7 @@ SCAJ-20077:
name: "Armored Core - Nexus [Disc 2]"
region: "NTSC-Unk"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SCAJ-20076"
@@ -1826,7 +1826,7 @@ SCAJ-20105:
name: "Armored Core - Nine Breaker"
region: "NTSC-Unk"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
cpuSpriteRenderLevel: 2 # Needed for above.
@@ -1941,9 +1941,7 @@ SCAJ-20121:
name: "Armored Core - Formula Front"
region: "NTSC-Unk"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
cpuSpriteRenderBW: 1 # Fixes broken shadow caused by HPO 1.
cpuSpriteRenderLevel: 2 # Needed for above.
halfPixelOffset: 5 # Fixes misaligned blur.
SCAJ-20122:
name: "Swords of Destiny"
region: "NTSC-Unk"
@@ -6514,7 +6512,12 @@ SCES-54941:
region: "PAL-E"
SCES-55019:
name: "Ratchet & Clank - Size Matters"
region: "PAL-M5"
region: "PAL-M13"
gsHWFixes:
recommendedBlendingLevel: 4 # Fixes vendor and other bloom.
autoFlush: 2 # Fixes missing bloom and shadow definition.
halfPixelOffset: 5 # Fixes misaligned bloom.
nativeScaling: 2 # Fixes pixelated bloom.
SCES-55038:
name: "EyeToy Play - Hero"
region: "PAL-M15"
@@ -7203,7 +7206,7 @@ SCKA-20047:
name: "Armored Core - Nine Breaker"
region: "NTSC-K"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
cpuSpriteRenderLevel: 2 # Needed for above.
@@ -7653,6 +7656,8 @@ SCKA-20120:
gsHWFixes:
recommendedBlendingLevel: 4 # Fixes vendor and other bloom.
autoFlush: 2 # Fixes missing bloom and shadow definition.
halfPixelOffset: 5 # Fixes misaligned bloom.
nativeScaling: 2 # Fixes pixelated bloom.
SCKA-20124:
name: "Piposarugetchu 3" # Ape Escape 3
region: "NTSC-K"
@@ -12436,6 +12441,8 @@ SCUS-97615:
gsHWFixes:
recommendedBlendingLevel: 4 # Fixes vendor and other bloom.
autoFlush: 2 # Fixes missing bloom and shadow definition.
halfPixelOffset: 5 # Fixes misaligned bloom.
nativeScaling: 2 # Fixes pixelated bloom.
SCUS-97616:
name: "SingStar '80s"
region: "NTSC-U"
@@ -23409,7 +23416,7 @@ SLES-53702:
region: "PAL-M5"
compat: 5
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
halfPixelOffset: 5 # Fixes blurriness.
SLES-53703:
name: "Peter Jackson's King Kong - The Official Game of the Movie"
name-sort: "King Kong, Peter Jackson's - The Official Game of the Movie"
@@ -23643,7 +23650,7 @@ SLES-53756:
name: "Resident Evil 4"
region: "PAL-M5"
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
halfPixelOffset: 5 # Fixes blurriness.
SLES-53758:
name: "Sniper Elite [Pre-Production]"
region: "PAL-E"
@@ -23809,7 +23816,7 @@ SLES-53819:
name: "Armored Core - Nine Breaker"
region: "PAL-E"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
cpuSpriteRenderLevel: 2 # Needed for above.
@@ -27630,6 +27637,8 @@ SLES-55019:
gsHWFixes:
recommendedBlendingLevel: 4 # Fixes vendor and other bloom.
autoFlush: 2 # Fixes missing bloom and shadow definition.
halfPixelOffset: 5 # Fixes misaligned bloom.
nativeScaling: 2 # Fixes pixelated bloom.
SLES-55020:
name: "Die Simpsons - Das Spiel"
region: "PAL-G"
@@ -29509,7 +29518,7 @@ SLES-82036:
name: "Armored Core - Nexus [Disc 1]"
region: "PAL-M5"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SLES-82036"
@@ -29518,7 +29527,7 @@ SLES-82037:
name: "Armored Core - Nexus [Disc 2]"
region: "PAL-M5"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SLES-82036"
@@ -30598,7 +30607,7 @@ SLKA-25201:
name: "Armored Core - Nexus [Disc 1]"
region: "NTSC-K"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SLKA-25201"
@@ -30607,7 +30616,7 @@ SLKA-25202:
name: "Armored Core - Nexus [Disc 2]"
region: "NTSC-K"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SLKA-25201"
@@ -30925,9 +30934,7 @@ SLKA-25270:
name: "Armored Core - Formula Front"
region: "NTSC-K"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
cpuSpriteRenderBW: 1 # Fixes broken shadow caused by HPO 1.
cpuSpriteRenderLevel: 2 # Needed for above.
halfPixelOffset: 5 # Fixes misaligned blur.
SLKA-25271:
name: "Harry Potter and the Order of the Phoenix"
region: "NTSC-K"
@@ -31588,7 +31595,7 @@ SLKA-25410:
gameFixes:
- BlitInternalFPSHack # Fixes internal FPS detection.
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
halfPixelOffset: 5 # Fixes blurriness.
SLKA-25411:
name: "Need for Speed - ProStreet"
region: "NTSC-K"
@@ -56797,7 +56804,7 @@ SLPS-25338:
name-en: "Armored Core - Nexus [Disc 1]"
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SCAJ-20076"
@@ -56812,7 +56819,7 @@ SLPS-25339:
name-en: "Armored Core - Nexus [Disc 2]"
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SCAJ-20076"
@@ -57265,7 +57272,7 @@ SLPS-25408:
name-en: "Armored Core - Nine Breaker"
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
cpuSpriteRenderLevel: 2 # Needed for above.
@@ -57590,9 +57597,7 @@ SLPS-25461:
name-en: "Armored Core - Formula Front"
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
cpuSpriteRenderBW: 1 # Fixes broken shadow caused by HPO 1.
cpuSpriteRenderLevel: 2 # Needed for above.
halfPixelOffset: 5 # Fixes misaligned blur.
SLPS-25462:
name: "アーマード・コア ラストレイヴン"
name-sort: "あーまーどこあ らすとれいゔん"
@@ -60857,7 +60862,7 @@ SLPS-73202:
name-en: "Armored Core - Nexus [Disc 1] [PlayStation2 the Best]"
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SCAJ-20076"
@@ -60872,7 +60877,7 @@ SLPS-73203:
name-en: "Armored Core - Nexus [Disc 2] [PlayStation2 the Best]"
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SCAJ-20076"
@@ -66576,7 +66581,7 @@ SLUS-20986:
region: "NTSC-U"
compat: 5
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SLUS-20986"
@@ -67150,7 +67155,7 @@ SLUS-21079:
name: "Armored Core - Nexus [Disc 2]"
region: "NTSC-U"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
memcardFilters:
- "SLUS-20986"
@@ -67457,7 +67462,7 @@ SLUS-21134:
gameFixes:
- BlitInternalFPSHack # Fixes internal FPS detection.
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
halfPixelOffset: 5 # Fixes blurriness.
SLUS-21135:
name: "MVP Baseball 2005"
region: "NTSC-U"
@@ -67828,7 +67833,7 @@ SLUS-21200:
region: "NTSC-U"
compat: 5
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned blur.
halfPixelOffset: 5 # Fixes misaligned blur.
recommendedBlendingLevel: 3 # Fixes level brightness.
cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
cpuSpriteRenderLevel: 2 # Needed for above.
@@ -73016,7 +73021,7 @@ SLUS-29169:
gameFixes:
- BlitInternalFPSHack # Fixes internal FPS detection.
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
halfPixelOffset: 5 # Fixes blurriness.
SLUS-29170:
name: "Total Overdose - A Gunslinger's Tale in Mexico [Demo]"
region: "NTSC-U"

View File

@@ -193,6 +193,7 @@
030000007d0400000640000000000000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Windows,
03000000120c0000f61c000000000000,Elite,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000430b00000300000000000000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,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:Windows,
03000000062000001801000000000000,EMS TrioLinker Plus II,a:b0,b:b1,x:b2,y:b3,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,platform:Windows,
03000000242f000000b7000000000000,ESM 9110,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Windows,
03000000101c0000181c000000000000,Essential,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b4,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
030000008f0e00000f31000000000000,EXEQ,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:b3,y:b2,platform:Windows,
@@ -610,6 +611,7 @@
03000000921200004547000000000000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b6,x:b3,y:b4,platform:Windows,
03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
03000000830500006020000000000000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
03000000632500007805000000000000,Retro Fighters Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
0300000003040000c197000000000000,Retrode Adapter,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
03000000bd12000013d0000000000000,Retrolink Sega Saturn Classic Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,
03000000bd12000015d0000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
@@ -757,8 +759,8 @@
03000000ff1100004133000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
03000000632500002305000000000000,USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000882800000305000000000000,V5 Game Pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,x:b2,y:b3,platform:Windows,
03000000790000001a18000000000000,Venom,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000790000001a18000000000000,Venom PS4 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000790000001b18000000000000,Venom PS4 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00000302000000000000,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:Windows,
030000006f0e00000702000000000000,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:Windows,
0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:a3,righty:a4,start:b4,x:b2,y:b3,platform:Windows,
@@ -1288,7 +1290,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
190000004b4800000010000000010000,GO-Advance Controller,a:b1,b:b0,back:b10,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,leftshoulder:b4,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b13,start:b15,x:b2,y:b3,platform:Linux,
190000004b4800000010000001010000,GO-Advance Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b13,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b16,righttrigger:b15,start:b17,x:b2,y:b3,platform:Linux,
190000004b4800000011000000010000,GO-Super Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b2,y:b3,platform:Linux,
190000004b4800000011000000010000,GO-Super Gamepad,a:b0,b:b1,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b3,y:b2,platform:Linux,
03000000f0250000c183000010010000,Goodbetterbest Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000d11800000094000011010000,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
05000000d11800000094000000010000,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
@@ -1425,6 +1427,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000d102000003020000,Microsoft Xbox One,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,
030000005e040000dd02000003020000,Microsoft Xbox One,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,
030000005e040000ea02000008040000,Microsoft Xbox One,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,
030000005e040000ea0200000f050000,Microsoft Xbox One,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,
060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000e302000003020000,Microsoft Xbox One Elite,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,
030000005e040000000b000007040000,Microsoft Xbox One Elite 2,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,paddle1:b12,paddle2:b14,paddle3:b13,paddle4:b15,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -1432,7 +1435,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e0400008e02000030110000,Microsoft Xbox One Elite 2,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,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b00000b050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000120b000001050000,Microsoft Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000016050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000017050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000120b000001050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
03000000790000001c18000010010000,Mobapad Chitu HD,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
@@ -1450,6 +1455,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006b140000010c000010010000,Nacon GC 400ES,a:b0,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:b2,y:b3,platform:Linux,
03000000853200000706000012010000,Nacon GC-100,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,
05000000853200000503000000010000,Nacon MG-X Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
0300000085320000170d000011010000,Nacon Revolution 5 Pro,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
0300000085320000190d000011010000,Nacon Revolution 5 Pro,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -1494,7 +1500,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e0000b802000001010000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000b802000013020000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00006401000001010000,PDP Battlefield One,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,
030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,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,
030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,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,
030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00008501000011010000,PDP Fightpad Pro Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -1509,7 +1515,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e0000ef02000007640000,PDP Xbox Series Kinetic Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c62400000053000000010000,PowerA,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,
03000000c62400003a54000001010000,PowerA 1428124-01,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,
03000000d62000000540000001010000,PowerA Advantage Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000000540000001010000,PowerA Advantage Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d620000011a7000011010000,PowerA Core Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000dd62000015a7000011010000,PowerA Fusion Nintendo Switch Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000d620000012a7000011010000,PowerA Fusion Nintendo Switch Fight Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -1524,9 +1530,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000d62000000228000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c62400001a54000001010000,PowerA Xbox One Mini Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
03000000d62000000520000050010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000000b20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000000f20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,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,
03000000d62000000520000050010000,PowerA Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000000b20000001010000,PowerA Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000250900000017000010010000,PS/SS/N64 Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b5,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2~,righty:a3,start:b8,platform:Linux,
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
@@ -1718,6 +1724,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
03000000790000001100000000010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,
03000000790000001a18000011010000,Venom PS4 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000790000001b18000011010000,Venom PS4 Arcade Joystick,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00000302000011010000,Victrix Pro Fightstick PS4,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:Linux,
030000006f0e00000702000011010000,Victrix Pro Fightstick PS4,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:Linux,
05000000ac0500003232000001000000,VR Box Controller,a:b0,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:b2,y:b3,platform:Linux,
@@ -1759,6 +1767,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000120b000009050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000011050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000014050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000015050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
@@ -1768,13 +1778,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000005e040000130b000011050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000130b000015050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000130b000017050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
060000005e040000120b000007050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000014050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000005e040000130b000017050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
060000005e040000120b00000d050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000200b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000220b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,

View File

@@ -25,7 +25,8 @@
#define SW_AD_TO_HW (PS_BLEND_C == 1 && PS_A_MASKED)
#define PS_PRIMID_INIT (PS_DATE == 1 || PS_DATE == 2)
#define NEEDS_RT_EARLY (PS_TEX_IS_FB == 1 || PS_DATE >= 5)
#define NEEDS_RT (NEEDS_RT_EARLY || (!PS_PRIMID_INIT && (PS_FBMASK || SW_BLEND_NEEDS_RT || SW_AD_TO_HW)))
#define NEEDS_RT_FOR_AFAIL (PS_AFAIL == 3 && PS_NO_COLOR1)
#define NEEDS_RT (NEEDS_RT_EARLY || NEEDS_RT_FOR_AFAIL || (!PS_PRIMID_INIT && (PS_FBMASK || SW_BLEND_NEEDS_RT || SW_AD_TO_HW)))
#define NEEDS_TEX (PS_TFX != 4)
layout(std140, binding = 0) uniform cb21
@@ -1114,7 +1115,7 @@ void ps_main()
ps_fbmask(C);
#if PS_AFAIL == 3 // RGB_ONLY
#if PS_AFAIL == 3 && !PS_NO_COLOR1 // RGB_ONLY
// Use alpha blend factor to determine whether to update A.
alpha_blend.a = float(atst_pass);
#endif
@@ -1130,6 +1131,10 @@ void ps_main()
#else
SV_Target0.rgb = C.rgb / 255.0f;
#endif
#if PS_AFAIL == 3 && !PS_NO_COLOR1 // RGB_ONLY, no dual src blend
if (!atst_pass)
SV_Target0.a = sample_from_rt().a;
#endif
#if !PS_NO_COLOR1
SV_Target1 = alpha_blend;
#endif

View File

@@ -299,8 +299,9 @@ void main()
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
#define SW_BLEND_NEEDS_RT (SW_BLEND && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1))
#define SW_AD_TO_HW (PS_BLEND_C == 1 && PS_A_MASKED)
#define AFAIL_NEEDS_RT (PS_AFAIL == 3 && PS_NO_COLOR1)
#define PS_FEEDBACK_LOOP_IS_NEEDED (PS_TEX_IS_FB == 1 || PS_FBMASK || SW_BLEND_NEEDS_RT || SW_AD_TO_HW || (PS_DATE >= 5))
#define PS_FEEDBACK_LOOP_IS_NEEDED (PS_TEX_IS_FB == 1 || AFAIL_NEEDS_RT || PS_FBMASK || SW_BLEND_NEEDS_RT || SW_AD_TO_HW || (PS_DATE >= 5))
#define NEEDS_TEX (PS_TFX != 4)
@@ -1381,7 +1382,7 @@ void main()
ps_fbmask(C);
#if PS_AFAIL == 3 // RGB_ONLY
#if PS_AFAIL == 3 && !PS_NO_COLOR1 // RGB_ONLY
// Use alpha blend factor to determine whether to update A.
alpha_blend.a = float(atst_pass);
#endif
@@ -1400,6 +1401,10 @@ void main()
#if !PS_NO_COLOR1
o_col1 = alpha_blend;
#endif
#if PS_AFAIL == 3 && PS_NO_COLOR1 // RGB_ONLY, no dual src blend
if (!atst_pass)
o_col0.a = sample_from_rt().a;
#endif
#endif
#if PS_ZCLAMP

View File

@@ -19,6 +19,8 @@ namespace CocoaTools
void AddThemeChangeHandler(void* ctx, void(handler)(void* ctx));
/// Remove a handler previously added using AddThemeChangeHandler with the given context
void RemoveThemeChangeHandler(void* ctx);
/// Mark an NSMenu as the help menu
void MarkHelpMenu(void* menu);
/// Returns the bundle path.
std::optional<std::string> GetBundlePath();
/// Get the bundle path to the actual application without any translocation fun

View File

@@ -143,6 +143,11 @@ void CocoaTools::RemoveThemeChangeHandler(void* ctx)
[s_themeChangeHandler removeCallback:ctx];
}
void CocoaTools::MarkHelpMenu(void* menu)
{
[NSApp setHelpMenu:(__bridge NSMenu*)menu];
}
// MARK: - Sound playback
bool Common::PlaySoundAsync(const char* path)

View File

@@ -113,6 +113,10 @@ bool GSRunner::InitializeConfig()
si.SetBoolValue("EmuCore/GS", "FrameLimitEnable", false);
si.SetIntValue("EmuCore/GS", "VsyncEnable", false);
// Force screenshot quality settings to something more performant, overriding any defaults good for users.
si.SetIntValue("EmuCore/GS", "ScreenshotFormat", static_cast<int>(GSScreenshotFormat::PNG));
si.SetIntValue("EmuCore/GS", "ScreenshotQuality", 10);
// ensure all input sources are disabled, we're not using them
si.SetBoolValue("InputSources", "SDL", false);
si.SetBoolValue("InputSources", "XInput", false);

View File

@@ -196,6 +196,8 @@ target_sources(pcsx2-qt PRIVATE
Debugger/Docking/DockLayout.h
Debugger/Docking/DockManager.cpp
Debugger/Docking/DockManager.h
Debugger/Docking/DockMenuBar.cpp
Debugger/Docking/DockMenuBar.h
Debugger/Docking/DockTables.cpp
Debugger/Docking/DockTables.h
Debugger/Docking/DockUtils.cpp

View File

@@ -59,7 +59,7 @@ int BreakpointModel::columnCount(const QModelIndex&) const
QVariant BreakpointModel::data(const QModelIndex& index, int role) const
{
size_t row = static_cast<size_t>(index.row());
const size_t row = static_cast<size_t>(index.row());
if (!index.isValid() || row >= m_breakpoints.size())
return QVariant();
@@ -298,7 +298,7 @@ Qt::ItemFlags BreakpointModel::flags(const QModelIndex& index) const
bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
size_t row = static_cast<size_t>(index.row());
const size_t row = static_cast<size_t>(index.row());
if (!index.isValid() || row >= m_breakpoints.size())
return false;
@@ -401,9 +401,14 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i
bool BreakpointModel::removeRows(int row, int count, const QModelIndex& index)
{
const size_t begin_index = static_cast<size_t>(row);
const size_t end_index = static_cast<size_t>(row + count);
if (end_index > m_breakpoints.size())
return false;
beginRemoveRows(index, row, row + count - 1);
for (int i = row; i < row + count; i++)
for (size_t i = begin_index; i < end_index; i++)
{
auto bp_mc = m_breakpoints.at(i);
@@ -420,6 +425,7 @@ bool BreakpointModel::removeRows(int row, int count, const QModelIndex& index)
});
}
}
const auto begin = m_breakpoints.begin() + row;
const auto end = begin + count;
m_breakpoints.erase(begin, end);

View File

@@ -111,16 +111,14 @@ void BreakpointWidget::contextDelete()
if (!selModel->hasSelection())
return;
QModelIndexList rows = selModel->selectedIndexes();
QModelIndexList indices = selModel->selectedIndexes();
std::sort(rows.begin(), rows.end(), [](const QModelIndex& a, const QModelIndex& b) {
return a.row() > b.row();
});
std::set<int> rows;
for (QModelIndex index : indices)
rows.emplace(index.row());
for (const QModelIndex& index : rows)
{
m_model->removeRows(index.row(), 1);
}
for (auto row = rows.rbegin(); row != rows.rend(); row++)
m_model->removeRows(*row, 1);
}
void BreakpointWidget::contextNew()

View File

@@ -112,7 +112,9 @@ DebuggerWindow::DebuggerWindow(QWidget* parent)
QMenuBar* menu_bar = menuBar();
setMenuWidget(m_dock_manager->createLayoutSwitcher(menu_bar));
setMenuWidget(m_dock_manager->createMenuBar(menu_bar));
updateTheme();
Host::RunOnCPUThread([]() {
R5900SymbolImporter.OnDebuggerOpened();
@@ -193,7 +195,7 @@ void DebuggerWindow::setupFonts()
m_font_size++;
updateFontActions();
updateStyleSheets();
updateTheme();
saveFontSize();
});
@@ -205,7 +207,7 @@ void DebuggerWindow::setupFonts()
m_font_size--;
updateFontActions();
updateStyleSheets();
updateTheme();
saveFontSize();
});
@@ -213,12 +215,11 @@ void DebuggerWindow::setupFonts()
m_font_size = DEFAULT_FONT_SIZE;
updateFontActions();
updateStyleSheets();
updateTheme();
saveFontSize();
});
updateFontActions();
updateStyleSheets();
}
void DebuggerWindow::updateFontActions()
@@ -239,7 +240,7 @@ int DebuggerWindow::fontSize()
return m_font_size;
}
void DebuggerWindow::updateStyleSheets()
void DebuggerWindow::updateTheme()
{
// TODO: Migrate away from stylesheets to improve performance.
if (m_font_size != DEFAULT_FONT_SIZE)
@@ -252,7 +253,7 @@ void DebuggerWindow::updateStyleSheets()
setStyleSheet(QString());
}
dockManager().updateStyleSheets();
dockManager().updateTheme();
}
void DebuggerWindow::saveWindowGeometry()
@@ -306,12 +307,18 @@ void DebuggerWindow::onVMPaused()
m_ui.actionStepOver->setEnabled(true);
m_ui.actionStepOut->setEnabled(true);
// Switch to the CPU tab that triggered the breakpoint.
// Also blink the tab text to indicate that a breakpoint was triggered.
if (CBreakPoints::GetBreakpointTriggered())
{
const BreakPointCpu triggeredCpu = CBreakPoints::GetBreakpointTriggeredCpu();
m_dock_manager->switchToLayoutWithCPU(triggeredCpu, true);
// Select a layout tab corresponding to the CPU that triggered the
// breakpoint and make it start blinking unless said breakpoint was
// generated as a result of stepping.
const BreakPointCpu cpu_type = CBreakPoints::GetBreakpointTriggeredCpu();
if (cpu_type == BREAKPOINT_EE || cpu_type == BREAKPOINT_IOP)
{
DebugInterface& cpu = DebugInterface::get(cpu_type);
bool blink_tab = !CBreakPoints::IsSteppingBreakPoint(cpu_type, cpu.getPC());
m_dock_manager->switchToLayoutWithCPU(cpu_type, blink_tab);
}
Host::RunOnCPUThread([] {
CBreakPoints::ClearTemporaryBreakPoints();
@@ -323,6 +330,13 @@ void DebuggerWindow::onVMPaused()
CBreakPoints::SetSkipFirst(BREAKPOINT_IOP, r3000Debug.getPC());
});
}
// Stops us from telling the disassembly widget to jump somwhere because
// breakpoint code paused the core.
if (!CBreakPoints::GetCorePaused())
emit onVMActuallyPaused();
else
CBreakPoints::SetCorePaused(false);
}
void DebuggerWindow::onVMResumed()
@@ -410,7 +424,7 @@ void DebuggerWindow::onStepInto()
bpAddr = info.branchTarget; // Syscalls are always taken
Host::RunOnCPUThread([cpu, bpAddr] {
CBreakPoints::AddBreakPoint(cpu->getCpuType(), bpAddr, true);
CBreakPoints::AddBreakPoint(cpu->getCpuType(), bpAddr, true, true, true);
cpu->resumeCpu();
});
@@ -460,7 +474,7 @@ void DebuggerWindow::onStepOver()
}
Host::RunOnCPUThread([cpu, bpAddr] {
CBreakPoints::AddBreakPoint(cpu->getCpuType(), bpAddr, true);
CBreakPoints::AddBreakPoint(cpu->getCpuType(), bpAddr, true, true, true);
cpu->resumeCpu();
});
@@ -501,7 +515,7 @@ void DebuggerWindow::onStepOut()
u32 breakpoint_pc = stack_frames.at(1).pc;
Host::RunOnCPUThread([cpu, breakpoint_pc] {
CBreakPoints::AddBreakPoint(cpu->getCpuType(), breakpoint_pc, true);
CBreakPoints::AddBreakPoint(cpu->getCpuType(), breakpoint_pc, true, true, true);
cpu->resumeCpu();
});

View File

@@ -31,7 +31,7 @@ public:
void updateFontActions();
void saveFontSize();
int fontSize();
void updateStyleSheets();
void updateTheme();
void saveWindowGeometry();
void restoreWindowGeometry();
@@ -51,6 +51,11 @@ public slots:
void onStepOver();
void onStepOut();
Q_SIGNALS:
// Only emitted if the pause wasn't a temporary one triggered by the
// breakpoint code.
void onVMActuallyPaused();
protected:
void closeEvent(QCloseEvent* event);

View File

@@ -3,8 +3,9 @@
#include "DisassemblyWidget.h"
#include "Debugger/Breakpoints/BreakpointModel.h"
#include "Debugger/DebuggerWindow.h"
#include "Debugger/JsonValueWrapper.h"
#include "Debugger/Breakpoints/BreakpointModel.h"
#include "DebugTools/DebugInterface.h"
#include "DebugTools/DisassemblyManager.h"
@@ -35,7 +36,8 @@ DisassemblyWidget::DisassemblyWidget(const DebuggerWidgetParameters& parameters)
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &DisassemblyWidget::customContextMenuRequested, this, &DisassemblyWidget::openContextMenu);
connect(g_emu_thread, &EmuThread::onVMPaused, this, &DisassemblyWidget::gotoProgramCounterOnPause);
connect(g_debugger_window, &DebuggerWindow::onVMActuallyPaused,
this, &DisassemblyWidget::gotoProgramCounterOnPause);
receiveEvent<DebuggerEvents::Refresh>([this](const DebuggerEvents::Refresh& event) -> bool {
update();

View File

@@ -25,7 +25,8 @@
#include <QtCore/QTimer>
#include <QtCore/QtTranslation>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QProxyStyle>
#include <QtWidgets/QStyleFactory>
DockManager::DockManager(QObject* parent)
: QObject(parent)
@@ -33,9 +34,6 @@ DockManager::DockManager(QObject* parent)
QTimer* autosave_timer = new QTimer(this);
connect(autosave_timer, &QTimer::timeout, this, &DockManager::saveCurrentLayout);
autosave_timer->start(60 * 1000);
m_blink_timer = new QTimer(this);
connect(m_blink_timer, &QTimer::timeout, this, &DockManager::layoutSwitcherUpdateBlink);
}
void DockManager::configureDockingSystem()
@@ -144,17 +142,13 @@ void DockManager::switchToLayout(DockLayout::Index layout_index, bool blink_tab)
layout.thaw();
int tab_index = static_cast<int>(layout_index);
if (m_switcher && tab_index >= 0 && tab_index < m_plus_tab_index)
{
m_ignore_current_tab_changed = true;
m_switcher->setCurrentIndex(tab_index);
m_ignore_current_tab_changed = false;
}
if (m_menu_bar && tab_index >= 0)
m_menu_bar->onCurrentLayoutChanged(layout_index);
}
}
if (blink_tab)
layoutSwitcherStartBlink();
m_menu_bar->startBlink(m_current_layout);
}
bool DockManager::switchToLayoutWithCPU(BreakPointCpu cpu, bool blink_tab)
@@ -476,168 +470,195 @@ void DockManager::createWindowsMenu(QMenu* menu)
menu->addAction(toggle.action);
}
QWidget* DockManager::createLayoutSwitcher(QWidget* menu_bar)
QWidget* DockManager::createMenuBar(QWidget* original_menu_bar)
{
QWidget* container = new QWidget;
pxAssert(!m_menu_bar);
QHBoxLayout* layout = new QHBoxLayout;
layout->setContentsMargins(0, 2, 2, 0);
container->setLayout(layout);
m_menu_bar = new DockMenuBar(original_menu_bar);
QWidget* menu_wrapper = new QWidget;
menu_wrapper->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
layout->addWidget(menu_wrapper);
connect(m_menu_bar, &DockMenuBar::currentLayoutChanged, this, [this](DockLayout::Index layout_index) {
if (layout_index >= m_layouts.size())
return;
QHBoxLayout* menu_layout = new QHBoxLayout;
menu_layout->setContentsMargins(0, 4, 0, 4);
menu_wrapper->setLayout(menu_layout);
menu_layout->addWidget(menu_bar);
m_switcher = new QTabBar;
m_switcher->setContentsMargins(0, 0, 0, 0);
m_switcher->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
m_switcher->setContextMenuPolicy(Qt::CustomContextMenu);
m_switcher->setMovable(true);
layout->addWidget(m_switcher);
switchToLayout(layout_index);
});
connect(m_menu_bar, &DockMenuBar::newButtonClicked, this, &DockManager::newLayoutClicked);
connect(m_menu_bar, &DockMenuBar::layoutMoved, this, &DockManager::layoutSwitcherTabMoved);
connect(m_menu_bar, &DockMenuBar::lockButtonToggled, this, &DockManager::setLayoutLockedAndSaveSetting);
connect(m_menu_bar, &DockMenuBar::layoutSwitcherContextMenuRequested,
this, &DockManager::openLayoutSwitcherContextMenu);
updateLayoutSwitcher();
connect(m_switcher, &QTabBar::tabMoved, this, &DockManager::layoutSwitcherTabMoved);
connect(m_switcher, &QTabBar::customContextMenuRequested, this, &DockManager::layoutSwitcherContextMenu);
QWidget* spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
layout->addWidget(spacer);
bool layout_locked = Host::GetBaseBoolSettingValue("Debugger/UserInterface", "LayoutLocked", true);
setLayoutLocked(layout_locked, false);
QPushButton* lock_layout_toggle = new QPushButton;
lock_layout_toggle->setCheckable(true);
lock_layout_toggle->setChecked(layout_locked);
lock_layout_toggle->setFlat(true);
connect(lock_layout_toggle, &QPushButton::toggled, this, [this, lock_layout_toggle](bool checked) {
setLayoutLocked(checked, lock_layout_toggle, true);
});
layout->addWidget(lock_layout_toggle);
setLayoutLocked(layout_locked, lock_layout_toggle, false);
return container;
return m_menu_bar;
}
void DockManager::updateLayoutSwitcher()
{
if (!m_switcher)
return;
disconnect(m_tab_connection);
for (int i = m_switcher->count(); i > 0; i--)
m_switcher->removeTab(i - 1);
for (DockLayout& layout : m_layouts)
{
const char* cpu_name = DebugInterface::cpuName(layout.cpu());
QString tab_name = QString("%1 (%2)").arg(layout.name()).arg(cpu_name);
m_switcher->addTab(tab_name);
}
m_plus_tab_index = m_switcher->addTab("+");
m_current_tab_index = m_current_layout;
if (m_current_layout != DockLayout::INVALID_INDEX)
m_switcher->setCurrentIndex(m_current_layout);
// If we don't have any layouts, the currently selected tab will never be
// changed, so we respond to all clicks instead.
if (!m_layouts.empty())
m_tab_connection = connect(m_switcher, &QTabBar::currentChanged, this, &DockManager::layoutSwitcherTabChanged);
else
m_tab_connection = connect(m_switcher, &QTabBar::tabBarClicked, this, &DockManager::layoutSwitcherTabChanged);
layoutSwitcherStopBlink();
if (m_menu_bar)
m_menu_bar->updateLayoutSwitcher(m_current_layout, m_layouts);
}
void DockManager::layoutSwitcherTabChanged(int index)
void DockManager::newLayoutClicked()
{
// Prevent recursion.
if (m_ignore_current_tab_changed)
return;
// The plus button has just been made the current tab, so set it back to the
// one corresponding to the current layout again.
m_menu_bar->onCurrentLayoutChanged(m_current_layout);
if (index == m_plus_tab_index)
auto name_validator = [this](const QString& name) {
return !hasNameConflict(name, DockLayout::INVALID_INDEX);
};
bool can_clone_current_layout = m_current_layout != DockLayout::INVALID_INDEX;
QPointer<LayoutEditorDialog> dialog = new LayoutEditorDialog(
name_validator, can_clone_current_layout, g_debugger_window);
if (dialog->exec() == QDialog::Accepted && name_validator(dialog->name()))
{
if (m_current_tab_index >= 0 && m_current_tab_index < m_plus_tab_index)
DockLayout::Index new_layout = DockLayout::INVALID_INDEX;
const auto [mode, index] = dialog->initialState();
switch (mode)
{
m_ignore_current_tab_changed = true;
m_switcher->setCurrentIndex(m_current_tab_index);
m_ignore_current_tab_changed = false;
case LayoutEditorDialog::DEFAULT_LAYOUT:
{
const DockTables::DefaultDockLayout& default_layout = DockTables::DEFAULT_DOCK_LAYOUTS.at(index);
new_layout = createLayout(dialog->name(), dialog->cpu(), false, default_layout.name);
break;
}
case LayoutEditorDialog::BLANK_LAYOUT:
{
new_layout = createLayout(dialog->name(), dialog->cpu(), false);
break;
}
case LayoutEditorDialog::CLONE_LAYOUT:
{
if (m_current_layout == DockLayout::INVALID_INDEX)
break;
DockLayout::Index old_layout = m_current_layout;
// Freeze the current layout so we can copy the geometry.
switchToLayout(DockLayout::INVALID_INDEX);
new_layout = createLayout(dialog->name(), dialog->cpu(), false, m_layouts.at(old_layout));
break;
}
}
auto name_validator = [this](const QString& name) {
return !hasNameConflict(name, DockLayout::INVALID_INDEX);
};
bool can_clone_current_layout = m_current_layout != DockLayout::INVALID_INDEX;
QPointer<LayoutEditorDialog> dialog = new LayoutEditorDialog(
name_validator, can_clone_current_layout, g_debugger_window);
if (dialog->exec() == QDialog::Accepted && name_validator(dialog->name()))
if (new_layout != DockLayout::INVALID_INDEX)
{
DockLayout::Index new_layout = DockLayout::INVALID_INDEX;
const auto [mode, index] = dialog->initialState();
switch (mode)
{
case LayoutEditorDialog::DEFAULT_LAYOUT:
{
const DockTables::DefaultDockLayout& default_layout = DockTables::DEFAULT_DOCK_LAYOUTS.at(index);
new_layout = createLayout(dialog->name(), dialog->cpu(), false, default_layout.name);
break;
}
case LayoutEditorDialog::BLANK_LAYOUT:
{
new_layout = createLayout(dialog->name(), dialog->cpu(), false);
break;
}
case LayoutEditorDialog::CLONE_LAYOUT:
{
if (m_current_layout == DockLayout::INVALID_INDEX)
return;
DockLayout::Index old_layout = m_current_layout;
// Freeze the current layout so we can copy the geometry.
switchToLayout(DockLayout::INVALID_INDEX);
new_layout = createLayout(dialog->name(), dialog->cpu(), false, m_layouts.at(old_layout));
break;
}
}
updateLayoutSwitcher();
switchToLayout(new_layout);
}
delete dialog.get();
}
else
{
DockLayout::Index layout_index = static_cast<DockLayout::Index>(index);
if (layout_index < 0 || layout_index >= m_layouts.size())
return;
switchToLayout(layout_index);
m_current_tab_index = index;
}
delete dialog.get();
}
void DockManager::layoutSwitcherTabMoved(int from, int to)
void DockManager::openLayoutSwitcherContextMenu(const QPoint& pos, QTabBar* layout_switcher)
{
DockLayout::Index from_index = static_cast<DockLayout::Index>(from);
DockLayout::Index to_index = static_cast<DockLayout::Index>(to);
DockLayout::Index layout_index = static_cast<DockLayout::Index>(layout_switcher->tabAt(pos));
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
QMenu* menu = new QMenu(layout_switcher);
menu->setAttribute(Qt::WA_DeleteOnClose);
QAction* edit_action = menu->addAction(tr("Edit Layout"));
connect(edit_action, &QAction::triggered, [this, layout_index]() {
editLayoutClicked(layout_index);
});
QAction* reset_action = menu->addAction(tr("Reset Layout"));
reset_action->setEnabled(layout.canReset());
reset_action->connect(reset_action, &QAction::triggered, [this, layout_index]() {
resetLayoutClicked(layout_index);
});
QAction* delete_action = menu->addAction(tr("Delete Layout"));
connect(delete_action, &QAction::triggered, [this, layout_index]() {
deleteLayoutClicked(layout_index);
});
menu->popup(layout_switcher->mapToGlobal(pos));
}
void DockManager::editLayoutClicked(DockLayout::Index layout_index)
{
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
auto name_validator = [this, layout_index](const QString& name) {
return !hasNameConflict(name, layout_index);
};
QPointer<LayoutEditorDialog> dialog = new LayoutEditorDialog(
layout.name(), layout.cpu(), name_validator, g_debugger_window);
if (dialog->exec() != QDialog::Accepted || !name_validator(dialog->name()))
return;
layout.setName(dialog->name());
layout.setCpu(dialog->cpu());
layout.save(layout_index);
delete dialog.get();
updateLayoutSwitcher();
}
void DockManager::resetLayoutClicked(DockLayout::Index layout_index)
{
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
if (!layout.canReset())
return;
QString text = tr("Are you sure you want to reset layout '%1'?").arg(layout.name());
if (QMessageBox::question(g_debugger_window, tr("Confirmation"), text) != QMessageBox::Yes)
return;
bool current_layout = layout_index == m_current_layout;
if (current_layout)
switchToLayout(DockLayout::INVALID_INDEX);
layout.reset();
layout.save(layout_index);
if (current_layout)
switchToLayout(layout_index);
}
void DockManager::deleteLayoutClicked(DockLayout::Index layout_index)
{
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
QString text = tr("Are you sure you want to delete layout '%1'?").arg(layout.name());
if (QMessageBox::question(g_debugger_window, tr("Confirmation"), text) != QMessageBox::Yes)
return;
deleteLayout(layout_index);
updateLayoutSwitcher();
}
void DockManager::layoutSwitcherTabMoved(DockLayout::Index from_index, DockLayout::Index to_index)
{
if (from_index >= m_layouts.size() || to_index >= m_layouts.size())
{
// This happens when the user tries to move a layout to the right of the
@@ -660,135 +681,6 @@ void DockManager::layoutSwitcherTabMoved(int from, int to)
m_current_layout = from_index;
}
void DockManager::layoutSwitcherContextMenu(QPoint pos)
{
DockLayout::Index layout_index = static_cast<DockLayout::Index>(m_switcher->tabAt(pos));
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
QMenu* menu = new QMenu(m_switcher);
menu->setAttribute(Qt::WA_DeleteOnClose);
QAction* edit_action = menu->addAction(tr("Edit Layout"));
connect(edit_action, &QAction::triggered, [this, layout_index]() {
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
auto name_validator = [this, layout_index](const QString& name) {
return !hasNameConflict(name, layout_index);
};
QPointer<LayoutEditorDialog> dialog = new LayoutEditorDialog(
layout.name(), layout.cpu(), name_validator, g_debugger_window);
if (dialog->exec() != QDialog::Accepted || !name_validator(dialog->name()))
return;
layout.setName(dialog->name());
layout.setCpu(dialog->cpu());
layout.save(layout_index);
delete dialog.get();
updateLayoutSwitcher();
});
QAction* reset_action = menu->addAction(tr("Reset Layout"));
reset_action->setEnabled(layout.canReset());
reset_action->connect(reset_action, &QAction::triggered, [this, layout_index]() {
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
if (!layout.canReset())
return;
QString text = tr("Are you sure you want to reset layout '%1'?").arg(layout.name());
if (QMessageBox::question(g_debugger_window, tr("Confirmation"), text) != QMessageBox::Yes)
return;
bool current_layout = layout_index == m_current_layout;
if (current_layout)
switchToLayout(DockLayout::INVALID_INDEX);
layout.reset();
layout.save(layout_index);
if (current_layout)
switchToLayout(layout_index);
});
QAction* delete_action = menu->addAction(tr("Delete Layout"));
connect(delete_action, &QAction::triggered, [this, layout_index]() {
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
QString text = tr("Are you sure you want to delete layout '%1'?").arg(layout.name());
if (QMessageBox::question(g_debugger_window, tr("Confirmation"), text) != QMessageBox::Yes)
return;
deleteLayout(layout_index);
updateLayoutSwitcher();
});
menu->popup(m_switcher->mapToGlobal(pos));
}
void DockManager::layoutSwitcherStartBlink()
{
if (!m_switcher)
return;
layoutSwitcherStopBlink();
if (m_current_layout == DockLayout::INVALID_INDEX)
return;
m_blink_tab = m_current_layout;
m_blink_stage = 0;
m_blink_timer->start(500);
layoutSwitcherUpdateBlink();
}
void DockManager::layoutSwitcherUpdateBlink()
{
if (!m_switcher)
return;
if (m_blink_tab < m_switcher->count())
{
if (m_blink_stage % 2 == 0)
m_switcher->setTabTextColor(m_blink_tab, Qt::red);
else
m_switcher->setTabTextColor(m_blink_tab, m_switcher->palette().text().color());
}
m_blink_stage++;
if (m_blink_stage > 7)
m_blink_timer->stop();
}
void DockManager::layoutSwitcherStopBlink()
{
if (m_blink_timer->isActive())
{
if (m_blink_tab < m_switcher->count())
m_switcher->setTabTextColor(m_blink_tab, m_switcher->palette().text().color());
m_blink_timer->stop();
}
}
bool DockManager::hasNameConflict(const QString& name, DockLayout::Index layout_index)
{
std::string safe_name = Path::SanitizeFileName(name.toStdString());
@@ -867,11 +759,23 @@ void DockManager::switchToDebuggerWidget(DebuggerWidget* widget)
}
}
void DockManager::updateStyleSheets()
void DockManager::updateTheme()
{
if (m_menu_bar)
m_menu_bar->updateTheme();
for (DockLayout& layout : m_layouts)
for (const auto& [unique_name, widget] : layout.debuggerWidgets())
widget->updateStyleSheet();
// KDDockWidgets::QtWidgets::TabBar sets its own style to a subclass of
// QProxyStyle in its constructor, so we need to update that here.
for (KDDockWidgets::Core::Group* group : KDDockWidgets::DockRegistry::self()->groups())
{
auto tab_bar = static_cast<KDDockWidgets::QtWidgets::TabBar*>(group->tabBar()->view());
if (QProxyStyle* style = qobject_cast<QProxyStyle*>(tab_bar->style()))
style->setBaseStyle(QStyleFactory::create(qApp->style()->name()));
}
}
bool DockManager::isLayoutLocked()
@@ -879,23 +783,17 @@ bool DockManager::isLayoutLocked()
return m_layout_locked;
}
void DockManager::setLayoutLocked(bool locked, QPushButton* lock_layout_toggle, bool write_back)
void DockManager::setLayoutLockedAndSaveSetting(bool locked)
{
setLayoutLocked(locked, true);
}
void DockManager::setLayoutLocked(bool locked, bool save_setting)
{
m_layout_locked = locked;
if (lock_layout_toggle)
{
if (m_layout_locked)
{
lock_layout_toggle->setText(tr("Layout Locked"));
lock_layout_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("padlock-lock")));
}
else
{
lock_layout_toggle->setText(tr("Layout Unlocked"));
lock_layout_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("padlock-unlock")));
}
}
if (m_menu_bar)
m_menu_bar->onLockStateChanged(locked);
updateToolBarLockState();
@@ -909,7 +807,7 @@ void DockManager::setLayoutLocked(bool locked, QPushButton* lock_layout_toggle,
stack->tabBar()->setTabText(0, stack->tabBar()->tabText(0));
}
if (write_back)
if (save_setting)
{
Host::SetBaseBoolSettingValue("Debugger/UserInterface", "LayoutLocked", m_layout_locked);
Host::CommitBaseSettingChanges();

View File

@@ -4,6 +4,7 @@
#pragma once
#include "Debugger/Docking/DockLayout.h"
#include "Debugger/Docking/DockMenuBar.h"
#include <kddockwidgets/MainWindow.h>
#include <kddockwidgets/DockWidget.h>
@@ -68,14 +69,14 @@ public:
void createToolsMenu(QMenu* menu);
void createWindowsMenu(QMenu* menu);
QWidget* createLayoutSwitcher(QWidget* menu_bar);
QWidget* createMenuBar(QWidget* original_menu_bar);
void updateLayoutSwitcher();
void layoutSwitcherTabChanged(int index);
void layoutSwitcherTabMoved(int from, int to);
void layoutSwitcherContextMenu(QPoint pos);
void layoutSwitcherStartBlink();
void layoutSwitcherUpdateBlink();
void layoutSwitcherStopBlink();
void newLayoutClicked();
void openLayoutSwitcherContextMenu(const QPoint& pos, QTabBar* layout_switcher);
void editLayoutClicked(DockLayout::Index layout_index);
void resetLayoutClicked(DockLayout::Index layout_index);
void deleteLayoutClicked(DockLayout::Index layout_index);
void layoutSwitcherTabMoved(DockLayout::Index from_index, DockLayout::Index to_index);
bool hasNameConflict(const QString& name, DockLayout::Index layout_index);
@@ -88,10 +89,11 @@ public:
void setPrimaryDebuggerWidget(DebuggerWidget* widget, bool is_primary);
void switchToDebuggerWidget(DebuggerWidget* widget);
void updateStyleSheets();
void updateTheme();
bool isLayoutLocked();
void setLayoutLocked(bool locked, QPushButton* lock_layout_toggle, bool write_back);
void setLayoutLockedAndSaveSetting(bool locked);
void setLayoutLocked(bool locked, bool save_setting);
void updateToolBarLockState();
std::optional<BreakPointCpu> cpu();
@@ -103,16 +105,7 @@ private:
std::vector<DockLayout> m_layouts;
DockLayout::Index m_current_layout = DockLayout::INVALID_INDEX;
QTabBar* m_switcher = nullptr;
int m_plus_tab_index = -1;
int m_current_tab_index = -1;
bool m_ignore_current_tab_changed = false;
QMetaObject::Connection m_tab_connection;
DockMenuBar* m_menu_bar = nullptr;
bool m_layout_locked = true;
QTimer* m_blink_timer = nullptr;
int m_blink_tab = 0;
int m_blink_stage = 0;
};

View File

@@ -0,0 +1,342 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "DockMenuBar.h"
#include <QtCore/QTimer>
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
#include <QtWidgets/QBoxLayout>
#include <QtWidgets/QStyleFactory>
#include <QtWidgets/QStyleOption>
static const int OUTER_MENU_MARGIN = 2;
static const int INNER_MENU_MARGIN = 4;
DockMenuBar::DockMenuBar(QWidget* original_menu_bar, QWidget* parent)
: QWidget(parent)
, m_original_menu_bar(original_menu_bar)
{
QHBoxLayout* layout = new QHBoxLayout;
layout->setContentsMargins(0, OUTER_MENU_MARGIN, OUTER_MENU_MARGIN, 0);
setLayout(layout);
QWidget* menu_wrapper = new QWidget;
menu_wrapper->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
layout->addWidget(menu_wrapper);
QHBoxLayout* menu_layout = new QHBoxLayout;
menu_layout->setContentsMargins(0, INNER_MENU_MARGIN, 0, INNER_MENU_MARGIN);
menu_wrapper->setLayout(menu_layout);
menu_layout->addWidget(original_menu_bar);
m_layout_switcher = new QTabBar;
m_layout_switcher->setContentsMargins(0, 0, 0, 0);
m_layout_switcher->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
m_layout_switcher->setContextMenuPolicy(Qt::CustomContextMenu);
m_layout_switcher->setDrawBase(false);
m_layout_switcher->setExpanding(false);
m_layout_switcher->setMovable(true);
layout->addWidget(m_layout_switcher);
connect(m_layout_switcher, &QTabBar::tabMoved, this, [this](int from, int to) {
DockLayout::Index from_index = static_cast<DockLayout::Index>(from);
DockLayout::Index to_index = static_cast<DockLayout::Index>(to);
emit layoutMoved(from_index, to_index);
});
connect(m_layout_switcher, &QTabBar::customContextMenuRequested, this, [this](const QPoint& pos) {
emit layoutSwitcherContextMenuRequested(pos, m_layout_switcher);
});
m_blink_timer = new QTimer(this);
connect(m_blink_timer, &QTimer::timeout, this, &DockMenuBar::updateBlink);
m_layout_locked_toggle = new QPushButton;
m_layout_locked_toggle->setCheckable(true);
connect(m_layout_locked_toggle, &QPushButton::clicked, this, [this](bool checked) {
if (m_ignore_lock_state_changed)
return;
emit lockButtonToggled(checked);
});
layout->addWidget(m_layout_locked_toggle);
updateTheme();
}
void DockMenuBar::updateTheme()
{
DockMenuBarStyle* style = new DockMenuBarStyle(m_layout_switcher);
m_original_menu_bar->setStyle(style);
m_layout_switcher->setStyle(style);
m_layout_locked_toggle->setStyle(style);
delete m_style;
m_style = style;
}
void DockMenuBar::updateLayoutSwitcher(DockLayout::Index current_index, const std::vector<DockLayout>& layouts)
{
disconnect(m_tab_connection);
for (int i = m_layout_switcher->count(); i > 0; i--)
m_layout_switcher->removeTab(i - 1);
for (const DockLayout& layout : layouts)
{
const char* cpu_name = DebugInterface::cpuName(layout.cpu());
QString tab_name = QString("%1 (%2)").arg(layout.name()).arg(cpu_name);
m_layout_switcher->addTab(tab_name);
}
m_plus_tab_index = m_layout_switcher->addTab("+");
m_current_tab_index = current_index;
if (current_index != DockLayout::INVALID_INDEX)
m_layout_switcher->setCurrentIndex(current_index);
else
m_layout_switcher->setCurrentIndex(m_plus_tab_index);
// If we don't have any layouts, the currently selected tab will never be
// changed, so we respond to all clicks instead.
if (m_plus_tab_index > 0)
m_tab_connection = connect(m_layout_switcher, &QTabBar::currentChanged, this, &DockMenuBar::tabChanged);
else
m_tab_connection = connect(m_layout_switcher, &QTabBar::tabBarClicked, this, &DockMenuBar::tabChanged);
stopBlink();
}
void DockMenuBar::onCurrentLayoutChanged(DockLayout::Index current_index)
{
m_ignore_current_tab_changed = true;
if (current_index != DockLayout::INVALID_INDEX)
m_layout_switcher->setCurrentIndex(current_index);
else
m_layout_switcher->setCurrentIndex(m_plus_tab_index);
m_ignore_current_tab_changed = false;
}
void DockMenuBar::onLockStateChanged(bool layout_locked)
{
m_ignore_lock_state_changed = true;
m_layout_locked_toggle->setChecked(layout_locked);
if (layout_locked)
{
m_layout_locked_toggle->setText(tr("Layout Locked"));
m_layout_locked_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("padlock-lock")));
}
else
{
m_layout_locked_toggle->setText(tr("Layout Unlocked"));
m_layout_locked_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("padlock-unlock")));
}
m_ignore_lock_state_changed = false;
}
void DockMenuBar::startBlink(DockLayout::Index layout_index)
{
stopBlink();
if (layout_index == DockLayout::INVALID_INDEX)
return;
m_blink_tab = static_cast<int>(layout_index);
m_blink_stage = 0;
m_blink_timer->start(500);
updateBlink();
}
void DockMenuBar::updateBlink()
{
if (m_blink_tab < m_layout_switcher->count())
{
if (m_blink_stage % 2 == 0)
m_layout_switcher->setTabTextColor(m_blink_tab, Qt::red);
else
m_layout_switcher->setTabTextColor(m_blink_tab, m_layout_switcher->palette().text().color());
}
m_blink_stage++;
if (m_blink_stage > 7)
m_blink_timer->stop();
}
void DockMenuBar::stopBlink()
{
if (m_blink_timer->isActive())
{
if (m_blink_tab < m_layout_switcher->count())
m_layout_switcher->setTabTextColor(m_blink_tab, m_layout_switcher->palette().text().color());
m_blink_timer->stop();
}
}
int DockMenuBar::innerHeight() const
{
return m_original_menu_bar->sizeHint().height() + INNER_MENU_MARGIN * 2;
}
void DockMenuBar::paintEvent(QPaintEvent* event)
{
QPainter painter(this);
// This fixes the background colour of the menu bar when using the Windows
// Vista style.
QStyleOptionMenuItem menu_option;
menu_option.palette = palette();
menu_option.state = QStyle::State_None;
menu_option.menuItemType = QStyleOptionMenuItem::EmptyArea;
menu_option.checkType = QStyleOptionMenuItem::NotCheckable;
menu_option.rect = rect();
menu_option.menuRect = rect();
style()->drawControl(QStyle::CE_MenuBarEmptyArea, &menu_option, &painter, this);
}
void DockMenuBar::tabChanged(int index)
{
// Prevent recursion.
if (m_ignore_current_tab_changed)
return;
if (index < m_plus_tab_index)
{
DockLayout::Index layout_index = static_cast<DockLayout::Index>(index);
emit currentLayoutChanged(layout_index);
}
else if (index == m_plus_tab_index)
{
emit newButtonClicked();
}
}
// *****************************************************************************
DockMenuBarStyle::DockMenuBarStyle(QObject* parent)
: QProxyStyle(QStyleFactory::create(qApp->style()->name()))
{
setParent(parent);
}
void DockMenuBarStyle::drawControl(
ControlElement element,
const QStyleOption* option,
QPainter* painter,
const QWidget* widget) const
{
switch (element)
{
case CE_MenuBarItem:
{
const QStyleOptionMenuItem* opt = qstyleoption_cast<const QStyleOptionMenuItem*>(option);
if (!opt)
break;
QWidget* menu_wrapper = widget->parentWidget();
if (!menu_wrapper)
break;
const DockMenuBar* menu_bar = qobject_cast<const DockMenuBar*>(menu_wrapper->parentWidget());
if (!menu_bar)
break;
if (baseStyle()->name() != "fusion")
break;
// This mirrors a check in QFusionStyle::drawControl. If act is
// false, QFusionStyle will try to draw a border along the bottom.
bool act = opt->state & State_Selected && opt->state & State_Sunken;
if (act)
break;
// Extend the menu item to the bottom of the menu bar to fix the
// position in which it draws its bottom border. We also need to
// extend it up by the same amount so that the text isn't moved.
QStyleOptionMenuItem menu_opt = *opt;
int difference = (menu_bar->innerHeight() - option->rect.top()) - menu_opt.rect.height();
menu_opt.rect.adjust(0, -difference, 0, difference);
QProxyStyle::drawControl(element, &menu_opt, painter, widget);
return;
}
case CE_TabBarTab:
{
QProxyStyle::drawControl(element, option, painter, widget);
// Draw a slick-looking highlight under the currently selected tab.
if (baseStyle()->name() == "fusion")
{
const QStyleOptionTab* tab = qstyleoption_cast<const QStyleOptionTab*>(option);
if (tab && (tab->state & State_Selected))
{
painter->setPen(tab->palette.highlight().color());
painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight());
}
}
return;
}
case CE_MenuBarEmptyArea:
{
// Prevent it from drawing a border in the wrong position.
return;
}
default:
{
break;
}
}
QProxyStyle::drawControl(element, option, painter, widget);
}
QSize DockMenuBarStyle::sizeFromContents(
QStyle::ContentsType type, const QStyleOption* option, const QSize& contents_size, const QWidget* widget) const
{
QSize size = QProxyStyle::sizeFromContents(type, option, contents_size, widget);
#ifdef Q_OS_WIN32
// Adjust the sizes of the layout switcher tabs depending on the theme.
if (type == CT_TabBarTab)
{
const QStyleOptionTab* opt = qstyleoption_cast<const QStyleOptionTab*>(option);
if (!opt)
return size;
const QTabBar* tab_bar = qobject_cast<const QTabBar*>(widget);
if (!tab_bar)
return size;
const DockMenuBar* menu_bar = qobject_cast<const DockMenuBar*>(tab_bar->parentWidget());
if (!menu_bar)
return size;
if (baseStyle()->name() == "fusion" || baseStyle()->name() == "windowsvista")
{
// Make sure the tab extends to the bottom of the widget.
size.setHeight(menu_bar->innerHeight() - opt->rect.top());
}
else if (baseStyle()->name() == "windows11")
{
// Adjust the size of the tab such that it is vertically centred.
size.setHeight(menu_bar->innerHeight() - opt->rect.top() * 2 - OUTER_MENU_MARGIN);
// Make the plus button square.
if (opt->tabIndex + 1 == tab_bar->count())
size.setWidth(size.height());
}
}
#endif
return size;
}

View File

@@ -0,0 +1,93 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#pragma once
#include "Debugger/Docking/DockLayout.h"
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QProxyStyle>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QTabBar>
#include <QtWidgets/QWidget>
class DockMenuBarStyle;
// The widget that replaces the normal menu bar. This contains the original menu
// bar, the layout switcher and the layout locked/unlocked toggle button.
class DockMenuBar : public QWidget
{
Q_OBJECT
public:
DockMenuBar(QWidget* original_menu_bar, QWidget* parent = nullptr);
void updateLayoutSwitcher(DockLayout::Index current_index, const std::vector<DockLayout>& layouts);
void updateTheme();
// Notify the menu bar that a new layout has been selected.
void onCurrentLayoutChanged(DockLayout::Index current_index);
// Notify the menu bar that the layout has been locked/unlocked.
void onLockStateChanged(bool layout_locked);
void startBlink(DockLayout::Index layout_index);
void updateBlink();
void stopBlink();
int innerHeight() const;
Q_SIGNALS:
void currentLayoutChanged(DockLayout::Index layout_index);
void newButtonClicked();
void layoutMoved(DockLayout::Index from_index, DockLayout::Index to_index);
void lockButtonToggled(bool locked);
void layoutSwitcherContextMenuRequested(const QPoint& pos, QTabBar* layout_switcher);
protected:
void paintEvent(QPaintEvent* event) override;
private:
void tabChanged(int index);
QWidget* m_original_menu_bar;
QTabBar* m_layout_switcher;
QMetaObject::Connection m_tab_connection;
int m_plus_tab_index = -1;
int m_current_tab_index = -1;
bool m_ignore_current_tab_changed = false;
QTimer* m_blink_timer = nullptr;
int m_blink_tab = 0;
int m_blink_stage = 0;
QPushButton* m_layout_locked_toggle;
bool m_ignore_lock_state_changed = false;
DockMenuBarStyle* m_style = nullptr;
};
// Fixes some theming issues relating to the menu bar, the layout switcher and
// the layout locked/unlocked toggle button.
class DockMenuBarStyle : public QProxyStyle
{
Q_OBJECT
public:
DockMenuBarStyle(QObject* parent = nullptr);
void drawControl(
ControlElement element,
const QStyleOption* option,
QPainter* painter,
const QWidget* widget = nullptr) const override;
QSize sizeFromContents(
QStyle::ContentsType type,
const QStyleOption* option,
const QSize& contents_size,
const QWidget* widget = nullptr) const override;
};

View File

@@ -20,6 +20,7 @@
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QMenu>
#include <QtWidgets/QStyleFactory>
KDDockWidgets::Core::View* DockViewFactory::createDockWidget(
const QString& unique_name,
@@ -143,6 +144,14 @@ DockTabBar::DockTabBar(KDDockWidgets::Core::TabBar* controller, QWidget* parent)
{
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &DockTabBar::customContextMenuRequested, this, &DockTabBar::openContextMenu);
// The constructor of KDDockWidgets::QtWidgets::TabBar makes a QProxyStyle
// that ends up taking ownerhsip of the style for the entire application!
if (QProxyStyle* proxy_style = qobject_cast<QProxyStyle*>(style()))
{
proxy_style->baseStyle()->setParent(qApp);
proxy_style->setBaseStyle(QStyleFactory::create(qApp->style()->name()));
}
}
void DockTabBar::openContextMenu(QPoint pos)

View File

@@ -116,7 +116,7 @@ namespace
// draw default item
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
opt.icon = QIcon();
opt.type = QStyleOption::SO_Default;
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0);
const QRect r = option.rect;
@@ -181,6 +181,7 @@ void GameListWidget::initialize()
m_table_view->setSelectionBehavior(QAbstractItemView::SelectRows);
m_table_view->setContextMenuPolicy(Qt::CustomContextMenu);
m_table_view->setAlternatingRowColors(true);
m_table_view->setMouseTracking(true);
m_table_view->setShowGrid(false);
m_table_view->setCurrentIndex({});
m_table_view->horizontalHeader()->setHighlightSections(false);

View File

@@ -151,6 +151,10 @@ void MainWindow::initialize()
ctx->updateTheme(); // Qt won't notice the style change without us touching the palette in some way
});
});
// The cocoa backing isn't initialized yet, delay this until stuff is set up with a `RunOnUIThread` call
QtHost::RunOnUIThread([this]{
CocoaTools::MarkHelpMenu(m_ui.menuHelp->toNSMenu());
});
#endif
m_ui.setupUi(this);
setupAdditionalUi();
@@ -1781,7 +1785,7 @@ void MainWindow::updateTheme()
reloadThemeSpecificImages();
if (g_debugger_window)
g_debugger_window->updateStyleSheets();
g_debugger_window->updateTheme();
}
void MainWindow::reloadThemeSpecificImages()

View File

@@ -84,7 +84,7 @@ namespace QtHost
//////////////////////////////////////////////////////////////////////////
// Local variable declarations
//////////////////////////////////////////////////////////////////////////
static std::unique_ptr<QTimer> s_settings_save_timer;
static QTimer* s_settings_save_timer = nullptr;
static std::unique_ptr<INISettingsInterface> s_base_settings_interface;
static bool s_batch_mode = false;
static bool s_nogui_mode = false;
@@ -1404,7 +1404,7 @@ void QtHost::SaveSettings()
if (s_settings_save_timer)
{
s_settings_save_timer->deleteLater();
s_settings_save_timer.release();
s_settings_save_timer = nullptr;
}
}
@@ -1420,10 +1420,21 @@ void Host::CommitBaseSettingChanges()
if (s_settings_save_timer)
return;
s_settings_save_timer = std::make_unique<QTimer>();
s_settings_save_timer->connect(s_settings_save_timer.get(), &QTimer::timeout, &QtHost::SaveSettings);
s_settings_save_timer = new QTimer;
s_settings_save_timer->connect(s_settings_save_timer, &QTimer::timeout, &QtHost::SaveSettings);
s_settings_save_timer->setSingleShot(true);
s_settings_save_timer->start(SETTINGS_SAVE_DELAY);
static bool connected = false;
if (!connected)
{
QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, []() {
delete s_settings_save_timer;
s_settings_save_timer = nullptr;
});
connected = true;
}
}
bool QtHost::InBatchMode()

View File

@@ -19,10 +19,14 @@ DebugAnalysisSettingsWidget::DebugAnalysisSettingsWidget(QWidget* parent)
setupSymbolSourceGrid();
m_ui.importFromElf->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "ImportSymbolsFromELF", true));
m_ui.importSymFileFromDefaultLocation->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "ImportSymFileFromDefaultLocation", true));
m_ui.demangleSymbols->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "DemangleSymbols", true));
m_ui.demangleParameters->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "DemangleParameters", true));
m_ui.importFromElf->setChecked(
Host::GetBoolSettingValue("Debugger/Analysis", "ImportSymbolsFromELF", true));
m_ui.importSymFileFromDefaultLocation->setChecked(
Host::GetBoolSettingValue("Debugger/Analysis", "ImportSymFileFromDefaultLocation", true));
m_ui.demangleSymbols->setChecked(
Host::GetBoolSettingValue("Debugger/Analysis", "DemangleSymbols", true));
m_ui.demangleParameters->setChecked(
Host::GetBoolSettingValue("Debugger/Analysis", "DemangleParameters", true));
setupSymbolFileList();
@@ -36,15 +40,22 @@ DebugAnalysisSettingsWidget::DebugAnalysisSettingsWidget(QWidget* parent)
m_ui.functionScanMode->setCurrentIndex(i);
}
m_ui.customAddressRange->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "CustomFunctionScanRange", false));
m_ui.addressRangeStart->setText(QString::fromStdString(Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanStartAddress", "")));
m_ui.addressRangeEnd->setText(QString::fromStdString(Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanEndAddress", "")));
m_ui.customAddressRange->setChecked(
Host::GetBoolSettingValue("Debugger/Analysis", "CustomFunctionScanRange", false));
m_ui.addressRangeStart->setText(QString::fromStdString(
Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanStartAddress", "")));
m_ui.addressRangeEnd->setText(QString::fromStdString(
Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanEndAddress", "")));
m_ui.grayOutOverwrittenFunctions->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "GenerateFunctionHashes", true));
m_ui.grayOutOverwrittenFunctions->setChecked(
Host::GetBoolSettingValue("Debugger/Analysis", "GenerateFunctionHashes", true));
connect(m_ui.automaticallyClearSymbols, &QCheckBox::checkStateChanged, this, &DebugAnalysisSettingsWidget::updateEnabledStates);
connect(m_ui.demangleSymbols, &QCheckBox::checkStateChanged, this, &DebugAnalysisSettingsWidget::updateEnabledStates);
connect(m_ui.customAddressRange, &QCheckBox::checkStateChanged, this, &DebugAnalysisSettingsWidget::updateEnabledStates);
connect(m_ui.automaticallyClearSymbols, &QCheckBox::checkStateChanged,
this, &DebugAnalysisSettingsWidget::updateEnabledStates);
connect(m_ui.demangleSymbols, &QCheckBox::checkStateChanged,
this, &DebugAnalysisSettingsWidget::updateEnabledStates);
connect(m_ui.customAddressRange, &QCheckBox::checkStateChanged,
this, &DebugAnalysisSettingsWidget::updateEnabledStates);
updateEnabledStates();
}
@@ -122,8 +133,16 @@ DebugAnalysisSettingsWidget::DebugAnalysisSettingsWidget(SettingsWindow* dialog,
{
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.customAddressRange, "Debugger/Analysis", "CustomFunctionScanRange", false);
connect(m_ui.addressRangeStart, &QLineEdit::textChanged, this, &DebugAnalysisSettingsWidget::functionScanRangeChanged);
connect(m_ui.addressRangeEnd, &QLineEdit::textChanged, this, &DebugAnalysisSettingsWidget::functionScanRangeChanged);
m_ui.addressRangeStart->setText(QString::fromStdString(
getStringSettingValue("Debugger/Analysis", "FunctionScanStartAddress", "")));
m_ui.addressRangeEnd->setText(QString::fromStdString(
getStringSettingValue("Debugger/Analysis", "FunctionScanEndAddress", "")));
connect(m_ui.addressRangeStart, &QLineEdit::textChanged,
this, &DebugAnalysisSettingsWidget::saveFunctionScanRange);
connect(m_ui.addressRangeEnd, &QLineEdit::textChanged,
this, &DebugAnalysisSettingsWidget::saveFunctionScanRange);
m_dialog->registerWidgetHelp(m_ui.customAddressRange, tr("Custom Address Range"), tr("Unchecked"),
tr("Whether to look for functions from the address range specified (Checked), or from the ELF segment "
@@ -302,6 +321,9 @@ void DebugAnalysisSettingsWidget::saveSymbolSources()
i++;
}
QtHost::SaveGameSettings(sif, true);
g_emu_thread->reloadGameSettings();
}
void DebugAnalysisSettingsWidget::setupSymbolFileList()
@@ -445,7 +467,7 @@ void DebugAnalysisSettingsWidget::saveSymbolFiles()
g_emu_thread->reloadGameSettings();
}
void DebugAnalysisSettingsWidget::functionScanRangeChanged()
void DebugAnalysisSettingsWidget::saveFunctionScanRange()
{
if (!m_dialog)
return;
@@ -457,13 +479,11 @@ void DebugAnalysisSettingsWidget::functionScanRangeChanged()
QString start_address = m_ui.addressRangeStart->text();
QString end_address = m_ui.addressRangeEnd->text();
bool ok;
sif->SetStringValue("Debugger/Analysis", "FunctionScanStartAddress", start_address.toStdString().c_str());
sif->SetStringValue("Debugger/Analysis", "FunctionScanEndAddress", end_address.toStdString().c_str());
if (start_address.toUInt(&ok, 16), ok)
sif->SetStringValue("Debugger/Analysis", "FunctionScanStartAddress", start_address.toStdString().c_str());
if (end_address.toUInt(&ok, 16), ok)
sif->SetStringValue("Debugger/Analysis", "FunctionScanEndAddress", end_address.toStdString().c_str());
QtHost::SaveGameSettings(sif, true);
g_emu_thread->reloadGameSettings();
}
void DebugAnalysisSettingsWidget::updateEnabledStates()

View File

@@ -38,7 +38,7 @@ protected:
void removeSymbolFile();
void saveSymbolFiles();
void functionScanRangeChanged();
void saveFunctionScanRange();
void updateEnabledStates();

View File

@@ -34,6 +34,7 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsWindow* dialog, QWidget
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vsync, "EmuCore/GS", "VsyncEnable", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.syncToHostRefreshRate, "EmuCore/GS", "SyncToHostRefreshRate", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useVSyncForTiming, "EmuCore/GS", "UseVSyncForTiming", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.skipPresentingDuplicateFrames, "EmuCore/GS", "SkipDuplicateFrames", false);
connect(m_ui.optimalFramePacing, &QCheckBox::checkStateChanged, this, &EmulationSettingsWidget::onOptimalFramePacingChanged);
connect(m_ui.vsync, &QCheckBox::checkStateChanged, this, &EmulationSettingsWidget::updateUseVSyncForTimingEnabled);
connect(m_ui.syncToHostRefreshRate, &QCheckBox::checkStateChanged, this, &EmulationSettingsWidget::updateUseVSyncForTimingEnabled);
@@ -154,6 +155,11 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsWindow* dialog, QWidget
dialog->registerWidgetHelp(m_ui.useVSyncForTiming, tr("Use Host VSync Timing"), tr("Unchecked"),
tr("When synchronizing with the host refresh rate, this option disable's PCSX2's internal frame timing, and uses the host instead. "
"Can result in smoother frame pacing, <strong>but at the cost of increased input latency</strong>."));
dialog->registerWidgetHelp(m_ui.skipPresentingDuplicateFrames, tr("Skip Presenting Duplicate Frames"), tr("Checked"),
tr("Detects when idle frames are being presented in 25/30fps games, and skips presenting those frames. The frame is still "
"rendered, it just means the GPU has more time to complete it (this is NOT frame skipping). Can smooth out frame time "
"fluctuations when the CPU/GPU are near maximum utilization, but makes frame pacing more inconsistent and can increase "
"input lag. Helps when using frame generation on 25/30fps games."));
dialog->registerWidgetHelp(m_ui.manuallySetRealTimeClock, tr("Manually Set Real-Time Clock"), tr("Unchecked"),
tr("Manually set a real-time clock to use for the virtual PlayStation 2 instead of using your OS' system clock."));
dialog->registerWidgetHelp(m_ui.rtcDateTime, tr("Real-Time Clock"), tr("Current date and time"),

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>672</width>
<height>438</height>
<height>500</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -222,13 +222,6 @@
</item>
<item row="3" column="0" colspan="2">
<layout class="QGridLayout" name="basicCheckboxGridLayout">
<item row="1" column="1">
<widget class="QCheckBox" name="useVSyncForTiming">
<property name="text">
<string>Use Host VSync Timing</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="syncToHostRefreshRate">
<property name="text">
@@ -236,6 +229,13 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="vsync">
<property name="text">
<string>Vertical Sync (VSync)</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="optimalFramePacing">
<property name="text">
@@ -243,10 +243,17 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="vsync">
<item row="1" column="1">
<widget class="QCheckBox" name="useVSyncForTiming">
<property name="text">
<string>Vertical Sync (VSync)</string>
<string>Use Host VSync Timing</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="skipPresentingDuplicateFrames">
<property name="text">
<string>Skip Presenting Duplicate Frames</string>
</property>
</widget>
</item>
@@ -282,8 +289,7 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QDateTimeEdit" name="rtcDateTime">
</widget>
<widget class="QDateTimeEdit" name="rtcDateTime"/>
</item>
</layout>
</widget>

View File

@@ -283,6 +283,7 @@ QList<QStandardItem*> GameCheatSettingsWidget::populateTreeViewRow(const Patch::
QStandardItem* authorItem = new QStandardItem(QString::fromStdString(pi.author));
QStandardItem* descriptionItem = new QStandardItem(QString::fromStdString(pi.description));
descriptionItem->setToolTip(QString::fromStdString(pi.description));
items.push_back(nameItem);
items.push_back(authorItem);

View File

@@ -244,7 +244,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useBlitSwapChain, "EmuCore/GS", "UseBlitSwapChain", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useDebugDevice, "EmuCore/GS", "UseDebugDevice", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.skipPresentingDuplicateFrames, "EmuCore/GS", "SkipDuplicateFrames", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableMailboxPresentation, "EmuCore/GS", "DisableMailboxPresentation", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.extendedUpscales, "EmuCore/GS", "ExtendedUpscalingMultipliers", false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.exclusiveFullscreenControl, "EmuCore/GS", "ExclusiveFullscreenControl", -1, -1);
@@ -395,7 +394,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
m_ui.extendedUpscales = nullptr;
m_ui.spinCPUDuringReadbacks = nullptr;
m_ui.spinGPUDuringReadbacks = nullptr;
m_ui.skipPresentingDuplicateFrames = nullptr;
m_ui.overrideTextureBarriers = nullptr;
m_ui.disableFramebufferFetch = nullptr;
m_ui.disableShaderCache = nullptr;
@@ -861,12 +859,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
tr("Overrides the driver's heuristics for enabling exclusive fullscreen, or direct flip/scanout.<br>"
"Disallowing exclusive fullscreen may enable smoother task switching and overlays, but increase input latency."));
dialog->registerWidgetHelp(m_ui.skipPresentingDuplicateFrames, tr("Skip Presenting Duplicate Frames"), tr("Unchecked"),
tr("Detects when idle frames are being presented in 25/30fps games, and skips presenting those frames. The frame is still "
"rendered, it just means the GPU has more time to complete it (this is NOT frame skipping). Can smooth out frame time "
"fluctuations when the CPU/GPU are near maximum utilization, but makes frame pacing more inconsistent and can increase "
"input lag."));
dialog->registerWidgetHelp(m_ui.disableMailboxPresentation, tr("Disable Mailbox Presentation"), tr("Unchecked"),
tr("Forces the use of FIFO over Mailbox presentation, i.e. double buffering instead of triple buffering. "
"Usually results in worse frame pacing."));

View File

@@ -2131,6 +2131,13 @@
</item>
<item row="10" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_9">
<item row="1" column="1">
<widget class="QCheckBox" name="extendedUpscales">
<property name="text">
<string>Extended Upscaling Multipliers</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="disableMailboxPresentation">
<property name="text">
@@ -2145,31 +2152,17 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="skipPresentingDuplicateFrames">
<property name="text">
<string>Skip Presenting Duplicate Frames</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="extendedUpscales">
<widget class="QCheckBox" name="spinCPUDuringReadbacks">
<property name="text">
<string>Extended Upscaling Multipliers</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="spinGPUDuringReadbacks">
<property name="text">
<string>Spin GPU During Readbacks</string>
<string>Spin CPU During Readbacks</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="spinCPUDuringReadbacks">
<widget class="QCheckBox" name="spinGPUDuringReadbacks">
<property name="text">
<string>Spin CPU During Readbacks</string>
<string>Spin GPU During Readbacks</string>
</property>
</widget>
</item>

File diff suppressed because it is too large Load Diff

View File

@@ -126,6 +126,7 @@
<ClCompile Include="Debugger\Breakpoints\BreakpointWidget.cpp" />
<ClCompile Include="Debugger\Docking\DockLayout.cpp" />
<ClCompile Include="Debugger\Docking\DockManager.cpp" />
<ClCompile Include="Debugger\Docking\DockMenuBar.cpp" />
<ClCompile Include="Debugger\Docking\DockTables.cpp" />
<ClCompile Include="Debugger\Docking\DockUtils.cpp" />
<ClCompile Include="Debugger\Docking\DockViews.cpp" />
@@ -242,6 +243,7 @@
<QtMoc Include="Debugger\Breakpoints\BreakpointWidget.h" />
<QtMoc Include="Debugger\Docking\DockLayout.h" />
<QtMoc Include="Debugger\Docking\DockManager.h" />
<QtMoc Include="Debugger\Docking\DockMenuBar.h" />
<QtMoc Include="Debugger\Docking\DockTables.h" />
<QtMoc Include="Debugger\Docking\DockUtils.h" />
<QtMoc Include="Debugger\Docking\DockViews.h" />
@@ -313,6 +315,7 @@
<ClCompile Include="$(IntDir)Debugger\Breakpoints\moc_BreakpointModel.cpp" />
<ClCompile Include="$(IntDir)Debugger\Breakpoints\moc_BreakpointWidget.cpp" />
<ClCompile Include="$(IntDir)Debugger\Docking\moc_DockManager.cpp" />
<ClCompile Include="$(IntDir)Debugger\Docking\moc_DockMenuBar.cpp" />
<ClCompile Include="$(IntDir)Debugger\Docking\moc_DockViews.cpp" />
<ClCompile Include="$(IntDir)Debugger\Docking\moc_DropIndicators.cpp" />
<ClCompile Include="$(IntDir)Debugger\Docking\moc_LayoutEditorDialog.cpp" />

View File

@@ -22,15 +22,21 @@
<Filter Include="Debugger">
<UniqueIdentifier>{ddb40cc4-9996-4ade-b647-eb549063553c}</UniqueIdentifier>
</Filter>
<Filter Include="Debugger\Models">
<UniqueIdentifier>{f4084ca0-d9d5-4584-b9d2-063db9f67de2}</UniqueIdentifier>
</Filter>
<Filter Include="Translations">
<UniqueIdentifier>{ad04f939-64a0-4039-97aa-a38b8aa46855}</UniqueIdentifier>
</Filter>
<Filter Include="Debugger\SymbolTree">
<UniqueIdentifier>{a622b871-62ae-4b70-b9b2-6ee30ce7fa7a}</UniqueIdentifier>
</Filter>
<Filter Include="Debugger\Breakpoints">
<UniqueIdentifier>{694f359a-dd3c-4e05-b000-684acb0fe0b0}</UniqueIdentifier>
</Filter>
<Filter Include="Debugger\Docking">
<UniqueIdentifier>{669ad4fe-0b5a-4722-946c-9e0742cebbca}</UniqueIdentifier>
</Filter>
<Filter Include="Debugger\Memory">
<UniqueIdentifier>{63790c94-0680-417d-926c-a8b74118f80f}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\pcsx2\windows\PCSX2.rc" />
@@ -302,51 +308,6 @@
<ClCompile Include="Debugger\ThreadWidget.cpp">
<Filter>Debugger</Filter>
</ClCompile>
<ClCompile Include="Debugger\Breakpoints\BreakpointDialog.cpp">
<Filter>Debugger\Breakpoints</Filter>
</ClCompile>
<ClCompile Include="Debugger\Breakpoints\BreakpointModel.cpp">
<Filter>Debugger\Breakpoints</Filter>
</ClCompile>
<ClCompile Include="Debugger\Breakpoints\BreakpointWidget.cpp">
<Filter>Debugger\Breakpoints</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockLayout.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockManager.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockTables.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockUtils.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockViews.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DropIndicators.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\LayoutEditorDialog.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\NoLayoutsWidget.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Memory\MemorySearchWidget.cpp">
<Filter>Debugger\Memory</Filter>
</ClCompile>
<ClCompile Include="Debugger\Memory\MemoryViewWidget.cpp">
<Filter>Debugger\Memory</Filter>
</ClCompile>
<ClCompile Include="Debugger\Memory\SavedAddressesModel.cpp">
<Filter>Debugger\Memory</Filter>
</ClCompile>
<ClCompile Include="Debugger\Memory\SavedAddressesWidget.cpp">
<Filter>Debugger\Memory</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\moc_AnalysisOptionsDialog.cpp">
<Filter>moc</Filter>
</ClCompile>
@@ -461,6 +422,78 @@
<Filter>Debugger\SymbolTree</Filter>
</ClCompile>
<ClCompile Include="VCRuntimeChecker.cpp" />
<ClCompile Include="Debugger\Breakpoints\BreakpointDialog.cpp">
<Filter>Debugger\Breakpoints</Filter>
</ClCompile>
<ClCompile Include="Debugger\Breakpoints\BreakpointModel.cpp">
<Filter>Debugger\Breakpoints</Filter>
</ClCompile>
<ClCompile Include="Debugger\Breakpoints\BreakpointWidget.cpp">
<Filter>Debugger\Breakpoints</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockLayout.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockManager.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockTables.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockUtils.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockViews.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DropIndicators.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Memory\SavedAddressesModel.cpp">
<Filter>Debugger\Memory</Filter>
</ClCompile>
<ClCompile Include="Debugger\Memory\SavedAddressesWidget.cpp">
<Filter>Debugger\Memory</Filter>
</ClCompile>
<ClCompile Include="Debugger\Memory\MemorySearchWidget.cpp">
<Filter>Debugger\Memory</Filter>
</ClCompile>
<ClCompile Include="Debugger\Memory\MemoryViewWidget.cpp">
<Filter>Debugger\Memory</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\LayoutEditorDialog.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\NoLayoutsWidget.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\SymbolTree\moc_NewSymbolDialogs.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\SymbolTree\moc_SymbolTreeDelegates.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\SymbolTree\moc_SymbolTreeLocation.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\SymbolTree\moc_SymbolTreeModel.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\SymbolTree\moc_SymbolTreeNode.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\SymbolTree\moc_SymbolTreeWidgets.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\SymbolTree\moc_TypeString.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\Docking\moc_DockMenuBar.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockMenuBar.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Manifest Include="..\pcsx2\windows\PCSX2.manifest">
@@ -483,27 +516,6 @@
<ClInclude Include="Debugger\DebuggerSettingsManager.h">
<Filter>Debugger</Filter>
</ClInclude>
<ClInclude Include="Debugger\SymbolTree\NewSymbolDialogs.h">
<Filter>Debugger\SymbolTree</Filter>
</ClInclude>
<ClInclude Include="Debugger\SymbolTree\SymbolTreeDelegates.h">
<Filter>Debugger\SymbolTree</Filter>
</ClInclude>
<ClInclude Include="Debugger\SymbolTree\SymbolTreeLocation.h">
<Filter>Debugger\SymbolTree</Filter>
</ClInclude>
<ClInclude Include="Debugger\SymbolTree\SymbolTreeModel.h">
<Filter>Debugger\SymbolTree</Filter>
</ClInclude>
<ClInclude Include="Debugger\SymbolTree\SymbolTreeNode.h">
<Filter>Debugger\SymbolTree</Filter>
</ClInclude>
<ClInclude Include="Debugger\SymbolTree\SymbolTreeWidgets.h">
<Filter>Debugger\SymbolTree</Filter>
</ClInclude>
<ClInclude Include="Debugger\SymbolTree\TypeString.h">
<Filter>Debugger\SymbolTree</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtMoc Include="MainWindow.h" />
@@ -640,6 +652,16 @@
<QtMoc Include="Debugger\ThreadWidget.h">
<Filter>Debugger</Filter>
</QtMoc>
<QtMoc Include="ColorPickerButton.h" />
<QtMoc Include="SetupWizardDialog.h" />
<QtMoc Include="Settings\GameCheatSettingsWidget.h">
<Filter>Settings</Filter>
</QtMoc>
<QtMoc Include="Settings\GamePatchSettingsWidget.h">
<Filter>Settings</Filter>
</QtMoc>
<QtMoc Include="LogWindow.h" />
<QtMoc Include="Debugger\SymbolTree\TypeString.h" />
<QtMoc Include="Debugger\Breakpoints\BreakpointDialog.h">
<Filter>Debugger\Breakpoints</Filter>
</QtMoc>
@@ -667,17 +689,20 @@
<QtMoc Include="Debugger\Docking\DropIndicators.h">
<Filter>Debugger\Docking</Filter>
</QtMoc>
<QtMoc Include="Debugger\Docking\LayoutEditorDialog.h">
<Filter>Debugger\Docking</Filter>
<QtMoc Include="Debugger\SymbolTree\SymbolTreeWidgets.h">
<Filter>Debugger\SymbolTree</Filter>
</QtMoc>
<QtMoc Include="Debugger\Docking\NoLayoutsWidget.h">
<Filter>Debugger\Docking</Filter>
<QtMoc Include="Debugger\SymbolTree\SymbolTreeDelegates.h">
<Filter>Debugger\SymbolTree</Filter>
</QtMoc>
<QtMoc Include="Debugger\Memory\MemorySearchWidget.h">
<Filter>Debugger\Memory</Filter>
<QtMoc Include="Debugger\SymbolTree\SymbolTreeLocation.h">
<Filter>Debugger\SymbolTree</Filter>
</QtMoc>
<QtMoc Include="Debugger\Memory\MemoryViewWidget.h">
<Filter>Debugger\Memory</Filter>
<QtMoc Include="Debugger\SymbolTree\SymbolTreeModel.h">
<Filter>Debugger\SymbolTree</Filter>
</QtMoc>
<QtMoc Include="Debugger\SymbolTree\SymbolTreeNode.h">
<Filter>Debugger\SymbolTree</Filter>
</QtMoc>
<QtMoc Include="Debugger\Memory\SavedAddressesModel.h">
<Filter>Debugger\Memory</Filter>
@@ -685,15 +710,24 @@
<QtMoc Include="Debugger\Memory\SavedAddressesWidget.h">
<Filter>Debugger\Memory</Filter>
</QtMoc>
<QtMoc Include="ColorPickerButton.h" />
<QtMoc Include="SetupWizardDialog.h" />
<QtMoc Include="Settings\GameCheatSettingsWidget.h">
<Filter>Settings</Filter>
<QtMoc Include="Debugger\Memory\MemorySearchWidget.h">
<Filter>Debugger\Memory</Filter>
</QtMoc>
<QtMoc Include="Settings\GamePatchSettingsWidget.h">
<Filter>Settings</Filter>
<QtMoc Include="Debugger\Memory\MemoryViewWidget.h">
<Filter>Debugger\Memory</Filter>
</QtMoc>
<QtMoc Include="Debugger\Docking\LayoutEditorDialog.h">
<Filter>Debugger\Docking</Filter>
</QtMoc>
<QtMoc Include="Debugger\Docking\NoLayoutsWidget.h">
<Filter>Debugger\Docking</Filter>
</QtMoc>
<QtMoc Include="Debugger\SymbolTree\NewSymbolDialogs.h">
<Filter>Debugger\SymbolTree</Filter>
</QtMoc>
<QtMoc Include="Debugger\Docking\DockMenuBar.h">
<Filter>Debugger\Docking</Filter>
</QtMoc>
<QtMoc Include="LogWindow.h" />
</ItemGroup>
<ItemGroup>
<QtResource Include="resources\resources.qrc">
@@ -815,27 +849,6 @@
<QtUi Include="Debugger\RegisterWidget.ui">
<Filter>Debugger</Filter>
</QtUi>
<QtUi Include="Debugger\Breakpoints\BreakpointDialog.ui">
<Filter>Debugger\Breakpoints</Filter>
</QtUi>
<QtUi Include="Debugger\Breakpoints\BreakpointWidget.ui">
<Filter>Debugger\Breakpoints</Filter>
</QtUi>
<QtUi Include="Debugger\Docking\LayoutEditorDialog.ui">
<Filter>Debugger\Docking</Filter>
</QtUi>
<QtUi Include="Debugger\Docking\NoLayoutsWidget.ui">
<Filter>Debugger\Docking</Filter>
</QtUi>
<QtUi Include="Debugger\Memory\MemorySearchWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Debugger\Memory\MemoryViewWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Debugger\Memory\SavedAddressesWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Settings\ControllerLEDSettingsDialog.ui">
<Filter>Settings</Filter>
</QtUi>
@@ -885,6 +898,27 @@
<QtUi Include="Settings\AudioStretchSettingsDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Debugger\Breakpoints\BreakpointDialog.ui">
<Filter>Debugger\Breakpoints</Filter>
</QtUi>
<QtUi Include="Debugger\Breakpoints\BreakpointWidget.ui">
<Filter>Debugger\Breakpoints</Filter>
</QtUi>
<QtUi Include="Debugger\Memory\SavedAddressesWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Debugger\Memory\MemoryViewWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Debugger\Memory\MemorySearchWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Debugger\Docking\LayoutEditorDialog.ui">
<Filter>Debugger\Docking</Filter>
</QtUi>
<QtUi Include="Debugger\Docking\NoLayoutsWidget.ui">
<Filter>Debugger\Docking</Filter>
</QtUi>
</ItemGroup>
<ItemGroup>
<None Include="Settings\FolderSettingsWidget.ui">
@@ -908,4 +942,4 @@
<Filter>Translations</Filter>
</QtTs>
</ItemGroup>
</Project>
</Project>

View File

@@ -172,7 +172,13 @@ bool CBreakPoints::IsTempBreakPoint(BreakPointCpu cpu, u32 addr)
return bp != INVALID_BREAKPOINT;
}
void CBreakPoints::AddBreakPoint(BreakPointCpu cpu, u32 addr, bool temp, bool enabled)
bool CBreakPoints::IsSteppingBreakPoint(BreakPointCpu cpu, u32 addr)
{
const size_t bp = FindBreakpoint(cpu, addr, true, true);
return bp != INVALID_BREAKPOINT && breakPoints_[bp].stepping;
}
void CBreakPoints::AddBreakPoint(BreakPointCpu cpu, u32 addr, bool temp, bool enabled, bool stepping)
{
const size_t bp = FindBreakpoint(cpu, addr, true, temp);
if (bp == INVALID_BREAKPOINT)
@@ -180,6 +186,7 @@ void CBreakPoints::AddBreakPoint(BreakPointCpu cpu, u32 addr, bool temp, bool en
BreakPoint pt;
pt.enabled = enabled;
pt.temporary = temp;
pt.stepping = stepping;
pt.addr = addr;
pt.cpu = cpu;

View File

@@ -12,15 +12,10 @@
struct BreakPointCond
{
DebugInterface* debug;
DebugInterface* debug = nullptr;
PostfixExpression expression;
std::string expressionString;
BreakPointCond()
: debug(NULL)
{
}
u32 Evaluate()
{
u64 result;
@@ -33,17 +28,10 @@ struct BreakPointCond
struct BreakPoint
{
BreakPoint()
: addr(0)
, enabled(false)
, temporary(false)
, hasCond(false)
{
}
u32 addr;
bool enabled;
bool temporary;
u32 addr = 0;
bool enabled = false;
bool temporary = false;
bool stepping = false;
bool hasCond;
BreakPointCond cond;
@@ -120,7 +108,8 @@ public:
static bool IsAddressBreakPoint(BreakPointCpu cpu, u32 addr);
static bool IsAddressBreakPoint(BreakPointCpu cpu, u32 addr, bool* enabled);
static bool IsTempBreakPoint(BreakPointCpu cpu, u32 addr);
static void AddBreakPoint(BreakPointCpu cpu, u32 addr, bool temp = false, bool enabled = true);
static bool IsSteppingBreakPoint(BreakPointCpu cpu, u32 addr);
static void AddBreakPoint(BreakPointCpu cpu, u32 addr, bool temp = false, bool enabled = true, bool stepping = false);
static void RemoveBreakPoint(BreakPointCpu cpu, u32 addr);
static void ChangeBreakPoint(BreakPointCpu cpu, u32 addr, bool enable);
static void ClearAllBreakPoints();

View File

@@ -1029,6 +1029,11 @@ bool R3000DebugInterface::isValidAddress(u32 addr)
return true;
}
if (addr >= 0x1FC00000 && addr < 0x20000000)
{
return true;
}
if (addr < 0x200000)
{
return true;

View File

@@ -20,10 +20,10 @@ void GSVertexTrace::Update(const void* vertex, const u16* index, int v_count, in
m_primclass = primclass;
u32 iip = m_state->PRIM->IIP;
u32 tme = m_state->PRIM->TME;
u32 fst = m_state->PRIM->FST;
u32 color = !(m_state->PRIM->TME && m_state->m_context->TEX0.TFX == TFX_DECAL && m_state->m_context->TEX0.TCC);
const u32 iip = m_state->PRIM->IIP;
const u32 tme = m_state->PRIM->TME;
const u32 fst = m_state->PRIM->FST;
const u32 color = !(m_state->PRIM->TME && m_state->m_context->TEX0.TFX == TFX_DECAL && m_state->m_context->TEX0.TCC);
m_fmm[color][fst][tme][iip][primclass](*this, vertex, index, i_count);
@@ -36,6 +36,13 @@ void GSVertexTrace::Update(const void* vertex, const u16* index, int v_count, in
m_accurate_stq = true;
}
// AA1: Set alpha min max to coverage 128 when there is no alpha blending.
if (!m_state->PRIM->ABE && m_state->PRIM->AA1 && (m_primclass == GS_LINE_CLASS || m_primclass == GS_TRIANGLE_CLASS))
{
m_min.c.a = 128;
m_max.c.a = 128;
}
m_eq.value = (m_min.c == m_max.c).mask() | ((m_min.p == m_max.p).mask() << 16) | ((m_min.t == m_max.t).mask() << 20);
m_alpha.valid = false;
@@ -46,7 +53,7 @@ void GSVertexTrace::Update(const void* vertex, const u16* index, int v_count, in
CorrectDepthTrace(vertex, v_count);
}
if (m_state->PRIM->TME)
if (tme)
{
const GIFRegTEX1& TEX1 = m_state->m_context->TEX1;
@@ -59,17 +66,17 @@ void GSVertexTrace::Update(const void* vertex, const u16* index, int v_count, in
}
else
{
float K = (float)TEX1.K / 16;
const float K = static_cast<float>(TEX1.K) / 16;
if (TEX1.LCM == 0 && m_state->PRIM->FST == 0) // FST == 1 => Q is not interpolated
{
// LOD = log2(1/|Q|) * (1 << L) + K
GSVector4::storel(&m_lod, m_max.t.uph(m_min.t).log2(3).neg() * (float)(1 << TEX1.L) + K);
GSVector4::storel(&m_lod, m_max.t.uph(m_min.t).log2(3).neg() * static_cast<float>(1 << TEX1.L) + K);
if (m_lod.x > m_lod.y)
{
float tmp = m_lod.x;
const float tmp = m_lod.x;
m_lod.x = m_lod.y;
m_lod.y = tmp;
}

View File

@@ -212,7 +212,7 @@ bool GSHwHack::GSC_Tekken5(GSRendererHW& r, int& skip)
{
if (skip == 0)
{
if (r.IsPossibleChannelShuffle() && (RTBP0 & 31))
if (r.IsPossibleChannelShuffle() && !(RTBP0 & 31))
{
GSVertex* v = &r.m_vertex.buff[0];

View File

@@ -4259,14 +4259,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
m_conf.ps.blend_d = 2;
}
}
// When AA1 is enabled and Alpha Blending is disabled, alpha blending done with coverage instead of alpha.
// We use a COV value of 128 (full coverage) in triangles (except the edge geometry, which we can't do easily).
if (IsCoverageAlpha())
{
m_conf.ps.fixed_one_a = 1;
m_conf.ps.blend_c = 0;
}
else if (m_conf.ps.blend_c == 1)
if (m_conf.ps.blend_c == 1)
{
// When both rt alpha min and max are equal replace Ad with Af, easier to manage.
if (rt_alpha_min == rt_alpha_max)
@@ -6169,6 +6162,9 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
new_scale_rt_alpha = rt->m_rt_alpha_scale;
}
// AA1: Set alpha source to coverage 128 when there is no alpha blending.
m_conf.ps.fixed_one_a = IsCoverageAlpha();
if ((!IsOpaque() || m_context->ALPHA.IsBlack()) && rt && ((m_conf.colormask.wrgba & 0x7) || (m_texture_shuffle && !m_copy_16bit_to_target_shuffle && !m_same_group_texture_shuffle)))
{
EmulateBlending(blend_alpha_min, blend_alpha_max, DATE, DATE_PRIMID, DATE_BARRIER, rt, can_scale_rt_alpha, new_scale_rt_alpha);
@@ -6239,23 +6235,32 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
// Blending might be off, ensure it's enabled.
// We write the alpha pass/fail to SRC1_ALPHA, which is used to update A.
m_conf.ps.afail = AFAIL_RGB_ONLY;
m_conf.ps.no_color1 = false;
if (!m_conf.blend.enable)
if ((features.framebuffer_fetch && m_conf.require_one_barrier) || m_conf.require_full_barrier)
{
m_conf.blend = GSHWDrawConfig::BlendState(true, GSDevice::CONST_ONE, GSDevice::CONST_ZERO,
GSDevice::OP_ADD, GSDevice::SRC1_ALPHA, GSDevice::INV_SRC1_ALPHA, false, 0);
// We're reading the rt anyways, use it for AFAIL
// This ensures we don't attempt to use fbfetch + blend, which breaks Intel GPUs on Metal
// Setting afail to RGB_ONLY without enabling color1 will enable this mode in the shader, so nothing more to do here.
}
else
{
if (m_conf.blend_multi_pass.enable)
m_conf.ps.no_color1 = false;
if (!m_conf.blend.enable)
{
m_conf.blend_multi_pass.blend.src_factor_alpha = GSDevice::SRC1_ALPHA;
m_conf.blend_multi_pass.blend.dst_factor_alpha = GSDevice::INV_SRC1_ALPHA;
m_conf.blend = GSHWDrawConfig::BlendState(true, GSDevice::CONST_ONE, GSDevice::CONST_ZERO,
GSDevice::OP_ADD, GSDevice::SRC1_ALPHA, GSDevice::INV_SRC1_ALPHA, false, 0);
}
else
{
m_conf.blend.src_factor_alpha = GSDevice::SRC1_ALPHA;
m_conf.blend.dst_factor_alpha = GSDevice::INV_SRC1_ALPHA;
if (m_conf.blend_multi_pass.enable)
{
m_conf.blend_multi_pass.blend.src_factor_alpha = GSDevice::SRC1_ALPHA;
m_conf.blend_multi_pass.blend.dst_factor_alpha = GSDevice::INV_SRC1_ALPHA;
}
else
{
m_conf.blend.src_factor_alpha = GSDevice::SRC1_ALPHA;
m_conf.blend.dst_factor_alpha = GSDevice::INV_SRC1_ALPHA;
}
}
}

View File

@@ -219,6 +219,7 @@ public:
MRCOwned<id<MTLFence>> m_draw_sync_fence;
MRCOwned<MTLFunctionConstantValues*> m_fn_constants;
MRCOwned<MTLVertexDescriptor*> m_hw_vertex;
MTLResourceOptions m_resource_options_shared_wc;
// Previously in MetalHostDisplay.
MRCOwned<NSView*> m_view;

View File

@@ -10,6 +10,7 @@
#include "common/Console.h"
#include "common/HostSys.h"
#include "cpuinfo.h"
#include "imgui.h"
#ifdef __APPLE__
@@ -90,6 +91,12 @@ GSDeviceMTL::GSDeviceMTL()
, m_dev(nil)
{
m_backref->second = this;
m_resource_options_shared_wc = MTLResourceStorageModeShared | MTLResourceCPUCacheModeWriteCombined;
#ifdef _M_X86
// WC memory doesn't work properly on AMD hackintoshes, and ends up being horribly slow even when only writing
if (cpuinfo_get_core(0)->vendor == cpuinfo_vendor_amd)
m_resource_options_shared_wc = MTLResourceStorageModeShared;
#endif
}
GSDeviceMTL::~GSDeviceMTL()
@@ -107,7 +114,7 @@ GSDeviceMTL::Map GSDeviceMTL::Allocate(UploadBuffer& buffer, size_t amt)
size_t newsize = std::max<size_t>(buffer.usage.Size() * 2, 4096);
while (newsize < amt)
newsize *= 2;
MTLResourceOptions options = MTLResourceStorageModeShared | MTLResourceCPUCacheModeWriteCombined;
MTLResourceOptions options = m_resource_options_shared_wc;
buffer.mtlbuffer = MRCTransfer([m_dev.dev newBufferWithLength:newsize options:options]);
pxAssertRel(buffer.mtlbuffer, "Failed to allocate MTLBuffer (out of memory?)");
buffer.buffer = [buffer.mtlbuffer contents];
@@ -148,7 +155,7 @@ GSDeviceMTL::Map GSDeviceMTL::Allocate(BufferPair& buffer, size_t amt)
size_t newsize = std::max<size_t>(buffer.usage.Size() * 2, 4096);
while (newsize < amt)
newsize *= 2;
MTLResourceOptions options = MTLResourceStorageModeShared | MTLResourceCPUCacheModeWriteCombined;
MTLResourceOptions options = m_resource_options_shared_wc;
buffer.cpubuffer = MRCTransfer([m_dev.dev newBufferWithLength:newsize options:options]);
pxAssertRel(buffer.cpubuffer, "Failed to allocate MTLBuffer (out of memory?)");
buffer.buffer = [buffer.cpubuffer contents];
@@ -1277,7 +1284,7 @@ void GSDeviceMTL::UpdateTexture(id<MTLTexture> texture, u32 x, u32 y, u32 width,
id<MTLCommandBuffer> cmdbuf = [m_queue commandBuffer];
id<MTLBlitCommandEncoder> enc = [cmdbuf blitCommandEncoder];
size_t bytes = data_stride * height;
MRCOwned<id<MTLBuffer>> buf = MRCTransfer([m_dev.dev newBufferWithLength:bytes options:MTLResourceStorageModeShared | MTLResourceCPUCacheModeWriteCombined]);
MRCOwned<id<MTLBuffer>> buf = MRCTransfer([m_dev.dev newBufferWithLength:bytes options:m_resource_options_shared_wc]);
memcpy([buf contents], data, bytes);
[enc copyFromBuffer:buf
sourceOffset:0

View File

@@ -97,7 +97,8 @@ constant bool SW_BLEND = (PS_BLEND_A != PS_BLEND_B) || PS_BLEND_D;
constant bool SW_AD_TO_HW = (PS_BLEND_C == 1 && PS_A_MASKED);
constant bool NEEDS_RT_FOR_BLEND = (((PS_BLEND_A != PS_BLEND_B) && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1)) || PS_BLEND_D == 1 || SW_AD_TO_HW);
constant bool NEEDS_RT_EARLY = PS_TEX_IS_FB || PS_DATE >= 5;
constant bool NEEDS_RT = NEEDS_RT_EARLY || (!PS_PRIM_CHECKING_INIT && (PS_FBMASK || NEEDS_RT_FOR_BLEND));
constant bool NEEDS_RT_FOR_AFAIL = PS_AFAIL == 3 && PS_NO_COLOR1;
constant bool NEEDS_RT = NEEDS_RT_FOR_AFAIL || NEEDS_RT_EARLY || (!PS_PRIM_CHECKING_INIT && (PS_FBMASK || NEEDS_RT_FOR_BLEND));
constant bool PS_COLOR0 = !PS_NO_COLOR;
constant bool PS_COLOR1 = !PS_NO_COLOR1;
@@ -1202,8 +1203,12 @@ struct PSMain
alpha_blend.a = float(atst_pass);
if (PS_COLOR0)
{
out.c0.a = PS_RTA_CORRECTION ? C.a / 128.f : C.a / 255.f;
out.c0.rgb = PS_HDR ? float3(C.rgb / 65535.f) : C.rgb / 255.f;
if (PS_AFAIL == 3 && !PS_COLOR1 && !atst_pass) // Doing RGB_ONLY without COLOR1
out.c0.a = current_color.a;
}
if (PS_COLOR1)
out.c1 = alpha_blend;
if (PS_ZCLAMP)

View File

@@ -4091,6 +4091,12 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
FSUI_NSTR("Enabled (All Primitives)"),
};
static constexpr const char* s_gpu_clut_options[] = {
FSUI_NSTR("Disabled (Default)"),
FSUI_NSTR("Enabled (Exact Match)"),
FSUI_NSTR("Enabled (Check Inside Target)"),
};
DrawIntListSetting(bsi, FSUI_CSTR("CPU Sprite Render Size"),
FSUI_CSTR("Uses software renderer to draw texture decompression-like sprites."), "EmuCore/GS",
"UserHacks_CPUSpriteRenderBW", 0, s_cpu_sprite_render_bw_options, std::size(s_cpu_sprite_render_bw_options), true);
@@ -4100,6 +4106,9 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
DrawIntListSetting(bsi, FSUI_CSTR("Software CLUT Render"),
FSUI_CSTR("Uses software renderer to draw texture CLUT points/sprites."), "EmuCore/GS", "UserHacks_CPUCLUTRender", 0,
s_cpu_clut_render_options, std::size(s_cpu_clut_render_options), true);
DrawIntListSetting(bsi, FSUI_CSTR("GPU Target CLUT"),
FSUI_CSTR("Try to detect when a game is drawing its own color palette and then renders it on the GPU with special handling."), "EmuCore/GS", "UserHacks_GPUTargetCLUTMode",
0, s_gpu_clut_options, std::size(s_gpu_clut_options), true, 0, manual_hw_fixes);
DrawIntSpinBoxSetting(bsi, FSUI_CSTR("Skip Draw Start"), FSUI_CSTR("Object range to skip drawing."), "EmuCore/GS",
"UserHacks_SkipDraw_Start", 0, 0, 5000, 1);
DrawIntSpinBoxSetting(bsi, FSUI_CSTR("Skip Draw End"), FSUI_CSTR("Object range to skip drawing."), "EmuCore/GS",
@@ -7391,6 +7400,8 @@ TRANSLATE_NOOP("FullscreenUI", "CPU Sprite Render Level");
TRANSLATE_NOOP("FullscreenUI", "Determines filter level for CPU sprite render.");
TRANSLATE_NOOP("FullscreenUI", "Software CLUT Render");
TRANSLATE_NOOP("FullscreenUI", "Uses software renderer to draw texture CLUT points/sprites.");
TRANSLATE_NOOP("FullscreenUI", "GPU Target CLUT");
TRANSLATE_NOOP("FullscreenUI", "Try to detect when a game is drawing its own color palette and then renders it on the GPU with special handling.");
TRANSLATE_NOOP("FullscreenUI", "Skip Draw Start");
TRANSLATE_NOOP("FullscreenUI", "Object range to skip drawing.");
TRANSLATE_NOOP("FullscreenUI", "Skip Draw End");
@@ -7865,6 +7876,8 @@ TRANSLATE_NOOP("FullscreenUI", "Force Nearest");
TRANSLATE_NOOP("FullscreenUI", "Disabled (Default)");
TRANSLATE_NOOP("FullscreenUI", "Enabled (Sprites Only)");
TRANSLATE_NOOP("FullscreenUI", "Enabled (All Primitives)");
TRANSLATE_NOOP("FullscreenUI", "Enabled (Exact Match)");
TRANSLATE_NOOP("FullscreenUI", "Enabled (Check Inside Target)");
TRANSLATE_NOOP("FullscreenUI", "None (Default)");
TRANSLATE_NOOP("FullscreenUI", "Sharpen Only (Internal Resolution)");
TRANSLATE_NOOP("FullscreenUI", "Sharpen and Resize (Display Resolution)");

View File

@@ -230,7 +230,7 @@ __ri void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, f
// GPU
text.clear();
text.append_format("GPU: {}", g_gs_device->GetName());
text.append_format("GPU: {}{}", g_gs_device->GetName(), GSConfig.UseDebugDevice ? " (Debug)" : "");
DRAW_LINE(fixed_font, text.c_str(), IM_COL32(255, 255, 255, 255));
}

View File

@@ -15,7 +15,7 @@
#include "MTVU.h"
#include "VMManager.h"
static const float UPDATE_INTERVAL = 0.25f;
static const float UPDATE_INTERVAL = 0.5f;
static float s_fps = 0.0f;
static float s_internal_fps = 0.0f;

View File

@@ -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 = 59;
static constexpr u32 SHADER_CACHE_VERSION = 60;

View File

@@ -3173,6 +3173,11 @@ void VMManager::WarnAboutUnsafeSettings()
append(ICON_FA_IMAGES,
TRANSLATE_SV("VMManager", "Mipmapping is disabled. This may break rendering in some games."));
}
if (EmuConfig.GS.UseDebugDevice)
{
append(ICON_FA_BUG,
TRANSLATE_SV("VMManager", "Debug device is enabled. This will massively reduce performance."));
}
static bool render_change_warn = false;
if (EmuConfig.GS.Renderer != GSRendererType::Auto && EmuConfig.GS.Renderer != GSRendererType::SW && !render_change_warn)
{

View File

@@ -1736,7 +1736,7 @@ StartRecomp:
}
}
pxAssert(xGetPtr() < recPtrEnd);
pxAssert(xGetPtr() < SysMemory::GetIOPRecEnd());
pxAssert(xGetPtr() - recPtr < _64kb);
s_pCurBlockEx->x86size = xGetPtr() - recPtr;

View File

@@ -900,7 +900,7 @@ u8* recEndThunk()
{
u8* block_end = x86Ptr;
pxAssert(block_end < recPtrEnd);
pxAssert(block_end < SysMemory::GetEERecEnd());
recPtr = block_end;
return block_end;
}
@@ -2698,7 +2698,7 @@ StartRecomp:
}
}
pxAssert(xGetPtr() < recPtrEnd);
pxAssert(xGetPtr() < SysMemory::GetEERecEnd());
s_pCurBlockEx->x86size = static_cast<u32>(xGetPtr() - recPtr);