mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-07-11 09:44:17 +02:00
Compare commits
91 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0a49e52fce | |||
| 76a0cf525c | |||
| b7fa45ee76 | |||
| b8ab8b69bd | |||
| 647b2b1cbd | |||
| b97f652e3f | |||
| 3eb2a2693f | |||
| 18fecfbd07 | |||
| e8ba3653ee | |||
| 848a9fd551 | |||
| 0cb16dee70 | |||
| 24090772cd | |||
| 62c40f1f01 | |||
| e5c580a1d4 | |||
| ad4bab8f68 | |||
| c16c1b76ed | |||
| 763d005f06 | |||
| b26b0996e3 | |||
| 23b931c5c6 | |||
| 31f621681d | |||
| 581e21a5f7 | |||
| aa04e57df5 | |||
| 99a8afac8d | |||
| 16fde28c39 | |||
| ed515782f9 | |||
| fa85ef3f92 | |||
| 12136217c4 | |||
| 0e5445d2a7 | |||
| e83a343bab | |||
| d5aeb9e20a | |||
| d9128872fd | |||
| 6e129a69d2 | |||
| 6e2d17073a | |||
| f622726bb1 | |||
| a39a0fd268 | |||
| f14e061438 | |||
| 0356b8a73e | |||
| 1d9b7c0387 | |||
| 2164078b2d | |||
| aeb1d500df | |||
| e44a388455 | |||
| 74044cdbce | |||
| 3f6ec596f0 | |||
| 1831d11671 | |||
| 362e89d668 | |||
| 936836e096 | |||
| 0e9de44c72 | |||
| d3841591a5 | |||
| 7f13863bb8 | |||
| dab29f8443 | |||
| 73d11a88da | |||
| 21320c750b | |||
| 35ce3c483f | |||
| fdd360f919 | |||
| fcb1d4ff4e | |||
| 815a59b6ed | |||
| 2097ff232c | |||
| 53d98a53e8 | |||
| f81a95f3a9 | |||
| 74e190511b | |||
| a86f441ac8 | |||
| 2557c2e887 | |||
| 6accade0d5 | |||
| 9437e1ac41 | |||
| b2b87f9e87 | |||
| f2ab17ff94 | |||
| a1514e2c6c | |||
| 329c6d42be | |||
| 800da09b1d | |||
| fb8c1b901d | |||
| df817924e0 | |||
| c227686d46 | |||
| 683ced4fe2 | |||
| ad6a8a5cf3 | |||
| 20e3896714 | |||
| 084df36598 | |||
| 28abbc6bf5 | |||
| 3a125a2d7a | |||
| 8415a4b0d6 | |||
| 209e676e3a | |||
| a64431c7b5 | |||
| 665eb3d6b3 | |||
| fe7935ce0e | |||
| 2fba420339 | |||
| e35c84c2c6 | |||
| 4b79645774 | |||
| df4be2c170 | |||
| ede25a5ecc | |||
| 76977da05a | |||
| aca37d14a1 | |||
| eee315718f |
@@ -17,7 +17,7 @@ jobs:
|
||||
run: ./.github/workflows/scripts/common/update_base_translation.sh
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0
|
||||
with:
|
||||
title: "Qt: Update Base Translation"
|
||||
commit-message: "[ci skip] Qt: Update Base Translation."
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
mv ./game_controller_db.txt ${{github.workspace}}/bin/resources/game_controller_db.txt
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0
|
||||
with:
|
||||
title: "PAD: Update to latest controller database"
|
||||
commit-message: "[ci skip] PAD: Update to latest controller database."
|
||||
|
||||
@@ -18,6 +18,9 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
|
||||
INSTALLDIR="$PWD/$INSTALLDIR"
|
||||
fi
|
||||
|
||||
QT=6.10.2
|
||||
QTAPNG=1.3.0
|
||||
|
||||
FFMPEG=8.0
|
||||
FREETYPE=2.14.1
|
||||
HARFBUZZ=12.2.0
|
||||
@@ -27,8 +30,6 @@ LIBPNG=1.6.53
|
||||
LIBWEBP=1.6.0
|
||||
NVENC=13.0.19.0
|
||||
SDL=SDL3-3.4.0
|
||||
QT=6.10.1
|
||||
QTAPNG=1.3.0
|
||||
LZ4=1.10.0
|
||||
VULKAN=1.4.328.1
|
||||
ZSTD=1.5.7
|
||||
@@ -47,6 +48,14 @@ cd deps-build
|
||||
export PKG_CONFIG_PATH="$INSTALLDIR/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
aeb78d29291a2b5fd53cb55950f8f5065b4978c25fb1d77f627d695ab9adf21e qtbase-everywhere-src-$QT.tar.xz
|
||||
8b8f9c718638081e7b3c000e7f31910140b1202a98e98df5d1b496fe6f639d67 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
f07ff80f38caf235187200345392ca7479445ddf49a36c3694cd52a735dad6e1 qtsvg-everywhere-src-$QT.tar.xz
|
||||
1e3d2c07c1fd76d2425c6eaeeaa62ffaff5f79210c4e1a5bc2a6a9db668d5b24 qttools-everywhere-src-$QT.tar.xz
|
||||
b3b3813bc9d76b545716dc8b6e659fa71b6e2bc14569e9fab6dab8b30650a644 qttranslations-everywhere-src-$QT.tar.xz
|
||||
391998eb432719df26a6a67d8efdc67f8bf2afdd76c1ee3381ebff4fe7527ee2 qtwayland-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
|
||||
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
|
||||
@@ -60,20 +69,14 @@ e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWE
|
||||
13da39edb3a40ed9713ae390ca89faa2f1202c9dda869ef306a8d4383e242bee nv-codec-headers-$NVENC.tar.gz
|
||||
c465aa56757e7746ac707f582b6e2d51546569a4a2488c1172fb543aa5fdfc2c vulkan-sdk-$VULKAN.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
|
||||
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
|
||||
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
|
||||
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
|
||||
49bf6db800227a6b2c971f4c5d03dd1e81297e7ffb296ce4a96437304f27cb13 qtwayland-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
|
||||
8a89fb6612ace8954470aae004623374a8fc8b7a34a4277bee5527173b064faf shaderc-$SHADERC.tar.gz
|
||||
272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
EOF
|
||||
|
||||
curl -L \
|
||||
@@ -213,7 +216,7 @@ tar xf "harfbuzz-$HARFBUZZ.tar.gz"
|
||||
cd "harfbuzz-$HARFBUZZ"
|
||||
# Add an SOVERSION to match system harfbuzz
|
||||
sed -i 's/PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)/PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE SOVERSION 0)/g' CMakeLists.txt
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DHB_BUILD_UTILS=OFF -DHB_HAVE_FREETYPE=ON -DHB_HAVE_GOBJECT=ON -B build -G Ninja
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DHB_BUILD_UTILS=OFF -DHB_HAVE_FREETYPE=ON -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
@@ -247,7 +250,7 @@ tar xf "qtbase-everywhere-src-$QT.tar.xz"
|
||||
cd "qtbase-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
../configure -prefix "$INSTALLDIR" -release -dbus-linked -gui -widgets -fontconfig -qt-doubleconversion -ssl -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -xcb -gtk -- --log-level=STATUS -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DFEATURE_dbus=ON -DFEATURE_icu=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON
|
||||
../configure -prefix "$INSTALLDIR" -release -dbus-linked -gui -widgets -fontconfig -qt-doubleconversion -ssl -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -xcb -- --log-level=STATUS -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DFEATURE_dbus=ON -DFEATURE_icu=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON -DFEATURE_gtk3=OFF
|
||||
cmake --build . --parallel
|
||||
ninja install
|
||||
cd ../../
|
||||
|
||||
@@ -38,6 +38,9 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
|
||||
INSTALLDIR="$PWD/$INSTALLDIR"
|
||||
fi
|
||||
|
||||
QT=6.10.1
|
||||
QTAPNG=1.3.0
|
||||
|
||||
FREETYPE=2.14.1
|
||||
HARFBUZZ=12.2.0
|
||||
SDL=SDL3-3.4.0
|
||||
@@ -48,8 +51,6 @@ LIBJPEGTURBO=3.1.2
|
||||
LIBWEBP=1.6.0
|
||||
FFMPEG=8.0
|
||||
MOLTENVK=1.4.1
|
||||
QT=6.10.1
|
||||
QTAPNG=1.3.0
|
||||
KDDOCKWIDGETS=2.4.0
|
||||
PLUTOVG=1.3.2
|
||||
PLUTOSVG=0.0.7
|
||||
@@ -78,6 +79,13 @@ CMAKE_ARCH_ARM64=-DCMAKE_OSX_ARCHITECTURES="arm64"
|
||||
CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
aeb78d29291a2b5fd53cb55950f8f5065b4978c25fb1d77f627d695ab9adf21e qtbase-everywhere-src-$QT.tar.xz
|
||||
8b8f9c718638081e7b3c000e7f31910140b1202a98e98df5d1b496fe6f639d67 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
f07ff80f38caf235187200345392ca7479445ddf49a36c3694cd52a735dad6e1 qtsvg-everywhere-src-$QT.tar.xz
|
||||
1e3d2c07c1fd76d2425c6eaeeaa62ffaff5f79210c4e1a5bc2a6a9db668d5b24 qttools-everywhere-src-$QT.tar.xz
|
||||
b3b3813bc9d76b545716dc8b6e659fa71b6e2bc14569e9fab6dab8b30650a644 qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
|
||||
082cbf5f429e0d80820f68dc2b507a94d4cc1b4e70817b119bbb8ec6a69584b8 $SDL.tar.gz
|
||||
@@ -89,19 +97,14 @@ e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWE
|
||||
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
|
||||
9985f141902a17de818e264d17c1ce334b748e499ee02fcb4703e4dc0038f89c v$MOLTENVK.tar.gz
|
||||
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
|
||||
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
|
||||
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
|
||||
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
|
||||
8a89fb6612ace8954470aae004623374a8fc8b7a34a4277bee5527173b064faf shaderc-$SHADERC.tar.gz
|
||||
272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
EOF
|
||||
|
||||
curl -C - -L \
|
||||
|
||||
@@ -20,6 +20,9 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
|
||||
INSTALLDIR="$PWD/$INSTALLDIR"
|
||||
fi
|
||||
|
||||
QT=6.10.2
|
||||
QTAPNG=1.3.0
|
||||
|
||||
FREETYPE=2.14.1
|
||||
HARFBUZZ=12.2.0
|
||||
SDL=SDL3-3.4.0
|
||||
@@ -30,8 +33,6 @@ LIBJPEGTURBO=3.1.2
|
||||
LIBWEBP=1.6.0
|
||||
FFMPEG=8.0
|
||||
MOLTENVK=1.4.1
|
||||
QT=6.10.1
|
||||
QTAPNG=1.3.0
|
||||
KDDOCKWIDGETS=2.4.0
|
||||
PLUTOVG=1.3.2
|
||||
PLUTOSVG=0.0.7
|
||||
@@ -59,6 +60,13 @@ CMAKE_COMMON=(
|
||||
)
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
aeb78d29291a2b5fd53cb55950f8f5065b4978c25fb1d77f627d695ab9adf21e qtbase-everywhere-src-$QT.tar.xz
|
||||
8b8f9c718638081e7b3c000e7f31910140b1202a98e98df5d1b496fe6f639d67 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
f07ff80f38caf235187200345392ca7479445ddf49a36c3694cd52a735dad6e1 qtsvg-everywhere-src-$QT.tar.xz
|
||||
1e3d2c07c1fd76d2425c6eaeeaa62ffaff5f79210c4e1a5bc2a6a9db668d5b24 qttools-everywhere-src-$QT.tar.xz
|
||||
b3b3813bc9d76b545716dc8b6e659fa71b6e2bc14569e9fab6dab8b30650a644 qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
|
||||
082cbf5f429e0d80820f68dc2b507a94d4cc1b4e70817b119bbb8ec6a69584b8 $SDL.tar.gz
|
||||
@@ -70,19 +78,14 @@ e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWE
|
||||
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
|
||||
9985f141902a17de818e264d17c1ce334b748e499ee02fcb4703e4dc0038f89c v$MOLTENVK.tar.gz
|
||||
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
|
||||
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
|
||||
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
|
||||
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
|
||||
8a89fb6612ace8954470aae004623374a8fc8b7a34a4277bee5527173b064faf shaderc-$SHADERC.tar.gz
|
||||
272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
EOF
|
||||
|
||||
curl -L \
|
||||
|
||||
@@ -2,10 +2,15 @@
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
echo Setting environment...
|
||||
if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsamd64_arm64.bat" (
|
||||
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsamd64_arm64.bat"
|
||||
) else if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsamd64_arm64.bat" (
|
||||
call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsamd64_arm64.bat"
|
||||
if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" (
|
||||
for /f "usebackq tokens=*" %%i in (`call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -version "[17, 18)" -latest -property installationPath`) do set "VSINSTPATH=%%i"
|
||||
if defined VSINSTPATH (
|
||||
echo VSINSTPATH=!VSINSTPATH!
|
||||
call "!VSINSTPATH!\VC\Auxiliary\Build\vcvarsamd64_arm64.bat" || goto error
|
||||
) else (
|
||||
echo Visual Studio 2022 not found.
|
||||
goto error
|
||||
)
|
||||
) else (
|
||||
echo Visual Studio 2022 not found.
|
||||
goto error
|
||||
@@ -42,15 +47,16 @@ echo INSTALLDIR=%INSTALLDIR%
|
||||
|
||||
cd "%BUILDDIR%"
|
||||
|
||||
set QT=6.10.2
|
||||
set QTMINOR=6.10
|
||||
set QTAPNG=1.3.0
|
||||
|
||||
set FREETYPE=2.14.1
|
||||
set HARFBUZZ=12.2.0
|
||||
set LIBJPEGTURBO=3.1.2
|
||||
set LIBPNG=1653
|
||||
set LIBPNGLONG=1.6.53
|
||||
set SDL=SDL3-3.4.0
|
||||
set QT=6.10.1
|
||||
set QTMINOR=6.10
|
||||
set QTAPNG=1.3.0
|
||||
set LZ4=1.10.0
|
||||
set WEBP=1.6.0
|
||||
set ZLIB=1.3.1
|
||||
@@ -67,6 +73,13 @@ set SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
|
||||
set AGILITYSDK=1.618.5
|
||||
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 690e08ce807041150d388b5351de2e591febf0a0bc973b56e1197e2df9a2d96f || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" a407e489ca8d68639530e881aea797f58754e355ca06024a73358bd9cc5fca17 || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" fd9f4f6e983a55f6b0ba4c49ce13f8b014cd30d12e75a49a478a640462f9bf64 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" a498357aed659c66aa87ceb556eacab55e3e7d7c9b9599049066de70eb7efa59 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" cf5e04a2048c02369f579c1251f61af965f241cde2d69de3db90e6c9f0ee2bf3 || goto error
|
||||
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
|
||||
|
||||
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 174d9e53402e1bf9ec7277e22ec199ba3e55a6be2c0740cb18c0ee9850fc8c34 || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 31490c781bacd2ce56862555b11c51c964977c39f14f51b817dfaecf0be089fe || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1653.zip 140566abc64bb2320cb35f1d154d1cb3eb7174a12234d33bfdffb446bdc0a1d2 || goto error
|
||||
@@ -74,12 +87,6 @@ call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 9ac2debb493e0d3e13dbd2729fb91f4bfeb00a0f4dff5e04b73cc9bac276b38d || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" c43f471a808b07fc541528410e94ce89c6745bdc1d744492e19911d35fbf7d33 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 2d828d8c999fdd18167937c071781c22321c643b04a106c714411c2356cdb26d || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" ddd74a417d2397eb085d047a9b6ba52b76e748055817f728fe691f8456035d23 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" db8e49ed50912c3c064a4f9ada7791c09eccec5a8d53463a19608eaab17679f0 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 868eb651e395d48ade5932ef2c386e606e054eb5888ebe5284fbd8cb63ed935a || goto error
|
||||
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://github.com/madler/zlib/releases/download/v%ZLIB%/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
|
||||
|
||||
@@ -2,10 +2,15 @@
|
||||
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"
|
||||
if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" (
|
||||
for /f "usebackq tokens=*" %%i in (`call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -version "[17, 18)" -latest -property installationPath`) do set "VSINSTPATH=%%i"
|
||||
if defined VSINSTPATH (
|
||||
echo VSINSTPATH=!VSINSTPATH!
|
||||
call "!VSINSTPATH!\VC\Auxiliary\Build\vcvars64.bat" || goto error
|
||||
) else (
|
||||
echo Visual Studio 2022 not found.
|
||||
goto error
|
||||
)
|
||||
) else (
|
||||
echo Visual Studio 2022 not found.
|
||||
goto error
|
||||
@@ -40,15 +45,16 @@ set "PATH=%PATH%;%INSTALLDIR%\bin"
|
||||
|
||||
cd "%BUILDDIR%"
|
||||
|
||||
set QT=6.10.2
|
||||
set QTMINOR=6.10
|
||||
set QTAPNG=1.3.0
|
||||
|
||||
set FREETYPE=2.14.1
|
||||
set HARFBUZZ=12.2.0
|
||||
set LIBJPEGTURBO=3.1.2
|
||||
set LIBPNG=1653
|
||||
set LIBPNGLONG=1.6.53
|
||||
set SDL=SDL3-3.4.0
|
||||
set QT=6.10.1
|
||||
set QTMINOR=6.10
|
||||
set QTAPNG=1.3.0
|
||||
set LZ4=1.10.0
|
||||
set WEBP=1.6.0
|
||||
set ZLIB=1.3.1
|
||||
@@ -65,6 +71,13 @@ set SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
|
||||
set AGILITYSDK=1.618.5
|
||||
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 690e08ce807041150d388b5351de2e591febf0a0bc973b56e1197e2df9a2d96f || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" a407e489ca8d68639530e881aea797f58754e355ca06024a73358bd9cc5fca17 || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" fd9f4f6e983a55f6b0ba4c49ce13f8b014cd30d12e75a49a478a640462f9bf64 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" a498357aed659c66aa87ceb556eacab55e3e7d7c9b9599049066de70eb7efa59 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" cf5e04a2048c02369f579c1251f61af965f241cde2d69de3db90e6c9f0ee2bf3 || goto error
|
||||
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
|
||||
|
||||
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 174d9e53402e1bf9ec7277e22ec199ba3e55a6be2c0740cb18c0ee9850fc8c34 || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 31490c781bacd2ce56862555b11c51c964977c39f14f51b817dfaecf0be089fe || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1653.zip 140566abc64bb2320cb35f1d154d1cb3eb7174a12234d33bfdffb446bdc0a1d2 || goto error
|
||||
@@ -72,12 +85,6 @@ call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 9ac2debb493e0d3e13dbd2729fb91f4bfeb00a0f4dff5e04b73cc9bac276b38d || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" c43f471a808b07fc541528410e94ce89c6745bdc1d744492e19911d35fbf7d33 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 2d828d8c999fdd18167937c071781c22321c643b04a106c714411c2356cdb26d || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" ddd74a417d2397eb085d047a9b6ba52b76e748055817f728fe691f8456035d23 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" db8e49ed50912c3c064a4f9ada7791c09eccec5a8d53463a19608eaab17679f0 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 868eb651e395d48ade5932ef2c386e606e054eb5888ebe5284fbd8cb63ed935a || goto error
|
||||
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://github.com/madler/zlib/releases/download/v%ZLIB%/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
|
||||
|
||||
Vendored
+247
-2
@@ -35,6 +35,248 @@ HOW TO UPDATE?
|
||||
and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users.
|
||||
- Please report any issue!
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.6 (2026-02-17)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.92.6
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Fonts:
|
||||
- `AddFontDefault()` now automatically selects an embedded font between:
|
||||
- `AddFontDefaultBitmap()`: classic pixel-clean font. Recommended at Size 13px with no scaling.
|
||||
- `AddFontDefaultVector()`: new scalable font. Recommended at any higher size.
|
||||
- The default selection is based on (style.FontSizeBase * FontScaleMain * FontScaleDpi)
|
||||
reaching a small threshold, but old codebases may not set any of them properly.
|
||||
As as a result, it is likely that old codebase may still default to AddFontDefaultBitmap().
|
||||
- Prefer explicitly calling either of them based on your own logic!
|
||||
You can call `AddFontDefaultBitmap()` to ensure legacy behavior.
|
||||
- Fixed handling of `ImFontConfig::FontDataOwnedByAtlas = false` which did
|
||||
erroneously make a copy of the font data, essentially defeating the purpose
|
||||
of this flag and wasting memory (undetected since July 2015 and now spotted
|
||||
by @TellowKrinkle, this is perhaps the oldest bug in Dear ImGui history,
|
||||
albeit for a rarely used feature!) (#9086, #8465)
|
||||
HOWEVER, fixing this bug is likely to surface bugs in user/app code:
|
||||
- Prior to 1.92, font data only needs to be available during the `atlas->AddFontXXX()` call.
|
||||
Since 1.92, font data needs to available until `atlas->RemoveFont()`, or more typically
|
||||
until a shutdown of the owning context or font atlas.
|
||||
- The fact that handling of `FontDataOwnedByAtlas = false` was broken bypassed
|
||||
the issue altogether.
|
||||
- Removed `ImFontConfig::PixelSnapV` added in 1.92 which turns out is unnecessary
|
||||
(and was mis-documented). Post-rescale `GlyphOffset` is always rounded.
|
||||
- Popups: changed compile-time `ImGuiPopupFlags popup_flags = 1` default value to be `= 0` for
|
||||
`BeginPopupContextItem()`, `BeginPopupContextWindow()`, `BeginPopupContextVoid()`, `OpenPopupOnItemClick()`.
|
||||
The default value has same meaning before and after. (#9157, #9146)
|
||||
- Before this version, those functions had a `ImGuiPopupFlags popup_flags = 1` default
|
||||
value in their function signature. This was introduced by a change on 2020/06/23 (1.77)
|
||||
while changing the signature from `int mouse_button` to `ImGuiPopupFlags popup_flags`
|
||||
and trying to preserve then-legacy behavior.
|
||||
- We have now changed this behavior to: cleanup a very old API quirk, facilitate use by
|
||||
bindings, and to remove the last and error-prone non-zero default value. Also because we
|
||||
deemed it extremely rare to use those helper functions with the Left mouse button!
|
||||
As using the LMB would generally be triggered via another widget,
|
||||
e.g. a Button() + a OpenPopup()/BeginPopup() call.
|
||||
- Before: The default = 1 means `ImGuiPopupFlags_MouseButtonRight`.
|
||||
Explicitly passing a literal 0 means `ImGuiPopupFlags_MouseButtonLeft`.
|
||||
- After: The default = 0 means `ImGuiPopupFlags_MouseButtonRight`.
|
||||
Explicitly passing a literal 1 also means `ImGuiPopupFlags_MouseButtonRight`.
|
||||
(if legacy behavior are enabled) or will assert (if legacy behavior are disabled).
|
||||
- TL;DR: if you don't want to use right mouse button for popups, always specify it
|
||||
explicitly using a named `ImGuiPopupFlags_MouseButtonXXXX` value.
|
||||
Recap:
|
||||
- BeginPopupContextItem("foo"); // Behavior unchanged (use Right button)
|
||||
- BeginPopupContextItem("foo", ImGuiPopupFlags_MouseButtonLeft); // Behavior unchanged (use Left button)
|
||||
- BeginPopupContextItem("foo", ImGuiPopupFlags_MouseButtonLeft | xxx); // Behavior unchanged (use Left button + flags)
|
||||
- BeginPopupContextItem("foo", ImGuiPopupFlags_MouseButtonRight | xxx); // Behavior unchanged (use Right button + flags)
|
||||
- BeginPopupContextItem("foo", 1); // Behavior unchanged (as a courtesy we legacy interpret 1 as ImGuiPopupFlags_MouseButtonRight, will assert if disabling legacy behaviors.
|
||||
- BeginPopupContextItem("foo", 0); // !! Behavior changed !! Was Left button. Now will defaults to Right button! --> Use ImGuiPopupFlags_MouseButtonLeft.
|
||||
- BeginPopupContextItem("foo", ImGuiPopupFlags_NoReopen); // !! Behavior changed !! Was Left button + flags. Now will defaults to Right button! --> Use ImGuiPopupFlags_MouseButtonLeft | xxx.
|
||||
- Commented out legacy names obsoleted in 1.90 (Sept 2023):
|
||||
- `BeginChildFrame()` --> `BeginChild()` with `ImGuiChildFlags_FrameStyle` flag.
|
||||
- `EndChildFrame()` --> `EndChild()`.
|
||||
- `ShowStackToolWindow()` --> `ShowIDStackToolWindow()`.
|
||||
- `IM_OFFSETOF()` --> `offsetof()`.
|
||||
- `IM_FLOOR()` --> `IM_TRUNC()` [internal, for positive values only]
|
||||
- Hashing: handling of "###" operator to reset to seed within a string identifier
|
||||
doesn't include the "###" characters in the output hash anymore:
|
||||
Before: `GetID("Hello###World") == GetID("###World") != GetID("World")`
|
||||
After: `GetID("Hello###World") == GetID("###World") == GetID("World")`
|
||||
- This has the property of facilitating concatenating and manipulating
|
||||
identifiers using "###", and will allow fixing other dangling issues.
|
||||
- This will invalidate hashes (stored in .ini data) for Tables and Windows
|
||||
that are using the "###" operators. (#713, #1698)
|
||||
- Renamed helper macro `IM_ARRAYSIZE()` -> `IM_COUNTOF()`. Kept redirection/legacy name.
|
||||
- Backends:
|
||||
- Vulkan: optional `ImGui_ImplVulkanH_DestroyWindow()` helper used by our example
|
||||
code does not call `vkDestroySurfaceKHR()`: because surface is created by caller
|
||||
of `ImGui_ImplVulkanH_CreateOrResizeWindow()`, it is more consistent. (#9163)
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Fonts:
|
||||
- Added `AddFontDefaultVector()`: a new embedded monospace scalable font: ProggyForever!
|
||||
From https://github.com/ocornut/proggyforever:
|
||||
"ProggyForever is an MIT-licensed partial reimplementation of the ProggyVector
|
||||
font (originally by Tristan Grimmer), which itself is a vector-based
|
||||
reinterpretation of the ProggyClean bitmap font that happily served as
|
||||
Dear ImGui default font for over 10 years." [...]
|
||||
"I commissioned Thiebault Courot to recreate this, applied various minor tweaks
|
||||
and fixes, and reworked his editing pipeline toward shipping FontForge source
|
||||
files so we can allow and track future changes."
|
||||
- TL;DR; there was no strictly MIT-licensed matching font. We made it!
|
||||
- The font data was carefully subsetted, trimmed and compressed so the embedded
|
||||
data is ~14 KB. Embedding a scalable default font ensures that Dear ImGui can
|
||||
be easily and readily used in all contexts, even without file system access.
|
||||
- Expect minor fixes/improvements in following releases.
|
||||
- As always you can opt-out of the embedded font data if desired.
|
||||
- `AddFontDefault()` now automatically selects an embedded font between
|
||||
the classic pixel-looking one and the new scalable one.
|
||||
Prefer calling `AddFontDefaultVector()` or `AddFontDefaultBitmap()` explicitly.
|
||||
- Fixed a crash when trying to use `AddFont()` with `MergeMode==true` on a font that
|
||||
has already been rendered. (#9162) [@ocornut, @cyfewlp]
|
||||
- Fixed an issue where using `PushFont()` from the implicit/fallback "Debug" window
|
||||
when its recorded state is collapsed would incorrectly early out. This would break
|
||||
e.g. using direct draw-list calls such as `GetForegroundDrawList()` with current font.
|
||||
(#9210, #8865)
|
||||
- Fixed an issue related to `EllipsisChar` handling, while changing
|
||||
font loader or font loader flags dynamically in Style->Fonts menus.
|
||||
- imgui_freetype: fixed overwriting `ImFontConfig::PixelSnapH` when hinting
|
||||
is enabled, creating side-effects when later disabling hinting or
|
||||
dynamically switching to stb_truetype rasterizer.
|
||||
- Adding new fonts after removing all fonts mid-frame properly updates current state.
|
||||
- Textures:
|
||||
- Fixed a building issue when `ImTextureID` is defined as a struct.
|
||||
- Fixed displaying texture # in Metrics/Debugger window.
|
||||
- Menus:
|
||||
- Fixed `MenuItem()` label position and `BeginMenu()` arrow/icon/popup positions,
|
||||
when used inside a line with a baseline offset.
|
||||
- Made navigation into menu-bar auto wrap on X axis. (#9178)
|
||||
- TreeNode:
|
||||
- Fixed highlight position when used inside a line with a large text baseline offset.
|
||||
(it never quite worked in this situation; but then most of the time the text
|
||||
baseline offset ends up being zero or `FramePadding.y` for a given line).
|
||||
- Tables:
|
||||
- Fixed an issue where a very thin scrolling table would advance parent layout
|
||||
slightly differently depending on its visibility (caused by a mismatch
|
||||
between hard minimum window size and table minimum size).
|
||||
- Fixed an issue where submitting non-integer row heights would eventually
|
||||
advance table parent layout by +0/+1 depending on its visibility.
|
||||
- Fixed losing stored display order when reducing column count or when .ini
|
||||
data has missing or duplicate values. (#9108, #4046)
|
||||
- ColorEdit:
|
||||
- Added R/G/B/A color markers next to each component (enabled by default).
|
||||
- Added `ImGuiColorEditFlags_NoColorMarkers` to disable them.
|
||||
- Added `style.ColorMarkerSize` to configure width of color component markers.
|
||||
- Sliders, Drags:
|
||||
- Added `ImGuiSliderFlags_ColorMarkers` to opt-in adding R/G/B/A color markers
|
||||
next to each components, in multi-components functions.
|
||||
- Added a way to select a specific marker color.
|
||||
- InputText:
|
||||
- InputTextMultiline(): fixed a minor bug where Shift+Wheel would allow a small
|
||||
horizontal scroll offset when there should be none. (#9249)
|
||||
- ImGuiInputTextCallbackData: `SelectAll()` also sets `CursorPos` to `SelectionEnd`.
|
||||
- ImGuiInputTextCallbackData: Added `SetSelection()` helper.
|
||||
- ImGuiInputTextCallbackData: Added `ID` and `EventActivated` members. (#9174)
|
||||
- Text, InputText:
|
||||
- Reworked word-wrapping logic:
|
||||
- Try to not wrap in the middle of contiguous punctuation. (#8139, #8439, #9094)
|
||||
- Try to not wrap between a punctuation and a digit. (#8503)
|
||||
- Inside `InputTextMultiline()` with WordWrap enabled: prefer keeping blanks at
|
||||
the end of a line rather than at the beginning of next line. (#8990, #3237)
|
||||
- Fixed low-level word-wrapping function reading from `*text_end` when passed
|
||||
a string range. (#9107) [@achabense]
|
||||
- Changed `RenderTextEllipsis()` logic to not trim trailing blanks before
|
||||
the ellipsis, making ellipsis position more consistent and not arbitrary
|
||||
hiding the possibility of multiple blanks. (#9229)
|
||||
- Nav:
|
||||
- Fixed remote/shortcut InputText() not teleporting mouse cursor when
|
||||
nav cursor is visible and `io.ConfigNavMoveSetMousePos` is enabled.
|
||||
- Fixed a looping/wrapping issue when used in menu layer. (#9178)
|
||||
- Fixed speed scale for resizing/moving with keyboard/gamepad. We incorrectly
|
||||
used `io.DisplayFramebufferScale` as a scaling factor (very old code),
|
||||
effectively making those actions faster on macOS/iOS retina screens.
|
||||
(changed this to use a style scale factor that's not fully formalized yet)
|
||||
- Fixed an UBSan warning when using in a `ImGuiListClipper` region . (#9160)
|
||||
- Scrollbar: fixed a code-path leading to a divide-by-zero (which would not be
|
||||
noticeable by user but detected by sanitizers). (#9089) [@judicaelclair]
|
||||
- InvisibleButton: allow calling with size (0,0) to fit to available content
|
||||
size. (#9166, #7623)
|
||||
- Tooltips, Disabled: fixed `EndDisabledOverrideReenable()` assertion when
|
||||
nesting a tooltip in a disabled block. (#9180, #7640) [@RegimantasSimkus]
|
||||
- Added `GetItemFlags()` in public API for consistency and to expose generic
|
||||
flags of last submitted item. (#9127)
|
||||
- Misc: fixed build on ARM64/ARM64EC targets trying to use SSE/immintrin.h.
|
||||
(#9209, #5943, #4091) [@navvyswethgraphics]
|
||||
- Log/Capture:
|
||||
- Fixed erroneously injecting extra carriage returns in output text buffer
|
||||
when `ItemSpacing.y` > `FramePadding.y + 1` while emitting items.
|
||||
- Images:
|
||||
- Added `style.ImageRounding`, `ImGuiStyleVar_ImageRounding `to configure
|
||||
rounding of `Image()` widgets. (#2942, #845)
|
||||
- `ImageButton()` doesn't use a clamped `style.FrameRounding` value but instead
|
||||
adjust inner image rounding when `FramePadding > `FrameRounding`. (#2942, #845)
|
||||
- Shortcuts:
|
||||
- IsItemHovered() without `ImGuiHoveredFlags_AllowWhenBlockedByActiveItem`
|
||||
doesn't filter out the signal when activated item is a shortcut remote activation;
|
||||
(which mimics what's done internally in the `ItemHoverable()` function). (#9138)
|
||||
- Fixed tooltip placement being affected for a frame when located over an item
|
||||
activated by `SetNextItemShortcut()`. (#9138)
|
||||
- Error Handling:
|
||||
- Improved error handling and recovery for `EndMenu()`/`EndCombo()`. (#1651, #9165, #8499)
|
||||
- Improved error handling and recovery for `TableSetupColumn()`.
|
||||
- Debug Tools:
|
||||
- Debug Log: fixed incorrectly printing characters in IO log when submitting
|
||||
non-ASCII values to `io.AddInputCharacter()`. (#9099)
|
||||
- Debug Log: can output to debugger on Windows via Win32 `OutputDebugString()` (#5855)
|
||||
- Demo:
|
||||
- Slightly improve `Selectable()` demos. (#9193)
|
||||
- Backends:
|
||||
- DirectX10: added `SamplerNearest` in `ImGui_ImplDX10_RenderState`.
|
||||
(+renamed `SamplerDefault` to `SamplerLinear`, which was tagged as beta API)
|
||||
- DirectX11: added `SamplerNearest` in ImGui_ImplDX11_RenderState.
|
||||
(+renamed `SamplerDefault` to `SamplerLinear`, which was tagged as beta API)
|
||||
- GLFW: Avoid repeated `glfwSetCursor()` / `glfwSetInputMode()` unnecessary calls.
|
||||
Lowers overhead for very high framerates (e.g. 10k+ FPS). [@maxliani]
|
||||
- GLFW: Added `IMGUI_IMPL_GLFW_DISABLE_X11` / `IMGUI_IMPL_GLFW_DISABLE_WAYLAND` to
|
||||
forcefully disable either. (#9109, #9116)
|
||||
Try to set them automatically if headers are not accessible. (#9225)
|
||||
- OpenGL3: Fixed embedded loader multiple init/shutdown cycles broken on some
|
||||
platforms. (#8792, #9112)
|
||||
- SDL2, SDL3: changed `GetClipboardText()` handler to return NULL on error aka
|
||||
clipboard contents is not text. Consistent with other backends. (#9168)
|
||||
- SDL2, SDL3: systems other than X11 are back to starting mouse capture on mouse down
|
||||
(reverts 1.91.9 change). Only X11 requires waiting for a drag by default (not ideal,
|
||||
but a better default for X11 users). Waiting for a drag to start mouse capture leads to
|
||||
input drops when dragging after clicking on the edge of a window.
|
||||
(#3650, #6410, #9235, #3956, #3835)
|
||||
- SDL2, SDL3: added `ImGui_ImplSDL2_SetMouseCaptureMode()`/`ImGui_ImplSDL3_SetMouseCaptureMode()`
|
||||
function for X11 users to disable mouse capturing/grabbing. (#3650, #6410, #9235, #3956, #3835)
|
||||
- When attached to a debugger may want to call:
|
||||
- `ImGui_ImplSDL3_SetMouseCaptureMode(ImGui_ImplSDL3_MouseCaptureMode_Disabled);`
|
||||
- But you can also configure your system or debugger to automatically release
|
||||
mouse grab when crashing/breaking in debugger, e.g.
|
||||
- console: `setxkbmap -option grab:break_actions && xdotool key XF86Ungrab`
|
||||
- or use a GDB script to call `SDL_CaptureMouse(false)`. See #3650.
|
||||
- On platforms other than X11 this is unnecessary.
|
||||
- SDL_GPU3: added `SamplerNearest` in `ImGui_ImplSDLGPU3_RenderState`.
|
||||
- SDL_GPU3: macOS version can use MSL shaders in order to support macOS 10.14+
|
||||
(vs Metallib shaders requiring macOS 14+). Requires application calling
|
||||
`SDL_CreateGPUDevice()` with `SDL_GPU_SHADERFORMAT_MSL`. (#9076) [@Niminem]
|
||||
- Vulkan: helper for creating a swapchain (used by examples and multi-viewports)
|
||||
selects `VkSwapchainCreateInfoKHR`'s `compositeAlpha` value based on
|
||||
`cap.supportedCompositeAlpha`, which seems to be required on some Android
|
||||
devices. (#8784) [@FelixStach]
|
||||
- WebGPU: fixes for Emscripten 5.0.0 (note: current examples do not build with 5.0.1).
|
||||
- Win32: handle `WM_IME_CHAR`/`WM_IME_COMPOSITION` to support Unicode inputs on
|
||||
MBCS (non-Unicode) Windows. (#9099, #3653, #5961) [@ulhc, @ocornut, @Othereum]
|
||||
- Win32: minor optimization not submitting gamepad input if packet number has not
|
||||
changed (reworked previous 1.92.4). (#9202, #8556) [@AhmedSamyMousa, @MidTerm-CN]
|
||||
- Examples:
|
||||
- Win32+DirectX12: ignore seemingly incorrect `D3D12_MESSAGE_ID_FENCE_ZERO_WAIT`
|
||||
warning on startups on some setups. (#9084, #9093) [@RT2Code, @LeoGautheron]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.5 (Released 2025-11-20)
|
||||
-----------------------------------------------------------------------
|
||||
@@ -141,7 +383,7 @@ Other Changes:
|
||||
debug/metrics window is not in the same viewport as the table.
|
||||
- Backends:
|
||||
- NULL: added imgui_impl_null platform/renderer backend.
|
||||
This is designed if you need to run e.g. context with no input or no ouput.
|
||||
This is designed if you need to run e.g. context with no input or no output.
|
||||
- GLFW: fixed building on Linux platforms where Wayland headers
|
||||
are not available. (#9024, #8969, #8921, #8920) [@jagot]
|
||||
- GLFW: lower minimum requirement from GLFW 3.1 to GLFW 3.0. Though
|
||||
@@ -219,6 +461,8 @@ Other Changes:
|
||||
using ImGuiWindowFlags_UnsavedDocument/ImGuiTabItemFlags_UnsavedDocument. (#8983)
|
||||
- IO: added ImGuiPlatformIO::ClearPlatformHandlers(), ClearRendererHandlers()
|
||||
helpers to null all handlers. (#8945, #2769)
|
||||
- Tables: changed ImGuiTableFlags_NoBordersInBody behavior to not draw border in
|
||||
body even when resizing. (#8893)
|
||||
- Inputs:
|
||||
- Shortcuts: added support for combining ImGuiInputFlags_RouteFocused
|
||||
(which is the default route) with ImGuiInputFlags_RouteOverActive, allowing
|
||||
@@ -621,7 +865,7 @@ Breaking changes:
|
||||
which font input is providing which glyph.
|
||||
- Fonts: **IMPORTANT** on Thread Safety:
|
||||
- A few functions such as font->CalcTextSizeA() were by sheer luck (== accidentally)
|
||||
thread-safe even thou we had never provided that guarantee before. They are
|
||||
thread-safe even though we had never provided that guarantee before. They are
|
||||
definitively not thread-safe anymore as new glyphs may be loaded.
|
||||
|
||||
- Textures:
|
||||
@@ -1374,6 +1618,7 @@ Breaking changes:
|
||||
- Commented out pre-1.87 IO system (equivalent to using IMGUI_DISABLE_OBSOLETE_KEYIO or IMGUI_DISABLE_OBSOLETE_FUNCTIONS before).
|
||||
- io.KeyMap[] and io.KeysDown[] are removed (obsoleted February 2022). Use IsKeyDown() instead.
|
||||
- io.NavInputs[] and ImGuiNavInput are removed (obsoleted July 2022).
|
||||
- GetKeyIndex() is removed (obsoleted March 2022). The indirection is now unnecessary.
|
||||
- Pre-1.87 backends are not supported:
|
||||
- backends need to call io.AddKeyEvent(), io.AddMouseEvent() instead of writing to io.KeysDown[], io.MouseDown[] fields.
|
||||
- backends need to call io.AddKeyAnalogEvent() for gamepad values instead of writing to io.NavInputs[] fields.
|
||||
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2026 Omar Cornut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Vendored
+1
-1
@@ -49,7 +49,7 @@
|
||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert.
|
||||
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded fonts (ProggyClean/ProggyForever), remove ~9 KB + ~14 KB from output binary. AddFontDefaultXXX() functions will assert.
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Enable Test Engine / Automation features.
|
||||
|
||||
Vendored
+104
-79
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.5
|
||||
// dear imgui, v1.92.6
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@@ -29,8 +29,8 @@
|
||||
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.92.5"
|
||||
#define IMGUI_VERSION_NUM 19250
|
||||
#define IMGUI_VERSION "1.92.6"
|
||||
#define IMGUI_VERSION_NUM 19261
|
||||
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
||||
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
||||
|
||||
@@ -95,7 +95,7 @@ Index of this file:
|
||||
#include <assert.h>
|
||||
#define IM_ASSERT(_EXPR) assert(_EXPR) // You can override the default assert handler by editing imconfig.h
|
||||
#endif
|
||||
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers!
|
||||
#define IM_COUNTOF(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers!
|
||||
#define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds.
|
||||
#define IM_STRINGIFY_HELPER(_EXPR) #_EXPR
|
||||
#define IM_STRINGIFY(_EXPR) IM_STRINGIFY_HELPER(_EXPR) // Preprocessor idiom to stringify e.g. an integer or a macro.
|
||||
@@ -349,7 +349,7 @@ typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or
|
||||
// The identifier is valid even before the texture has been uploaded to the GPU/graphics system.
|
||||
// This is what gets passed to functions such as `ImGui::Image()`, `ImDrawList::AddImage()`.
|
||||
// This is what gets stored in draw commands (`ImDrawCmd`) to identify a texture during rendering.
|
||||
// - When a texture is created by user code (e.g. custom images), we directly stores the low-level ImTextureID.
|
||||
// - When a texture is created by user code (e.g. custom images), we directly store the low-level ImTextureID.
|
||||
// Because of this, when displaying your own texture you are likely to ever only manage ImTextureID values on your side.
|
||||
// - When a texture is created by the backend, we stores a ImTextureData* which becomes an indirection
|
||||
// to extract the ImTextureID value during rendering, after texture upload has happened.
|
||||
@@ -853,20 +853,23 @@ namespace ImGui
|
||||
// - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options).
|
||||
// - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup().
|
||||
// - Use IsWindowAppearing() after BeginPopup() to tell if a window just opened.
|
||||
// - IMPORTANT: Notice that for OpenPopupOnItemClick() we exceptionally default flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter
|
||||
IMGUI_API void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!).
|
||||
IMGUI_API void OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags = 0); // id overload to facilitate calling from nested stacks
|
||||
IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // helper to open popup when clicked on last item. Default to ImGuiPopupFlags_MouseButtonRight == 1. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)
|
||||
IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 0); // helper to open popup when clicked on last item. Default to ImGuiPopupFlags_MouseButtonRight == 1. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)
|
||||
IMGUI_API void CloseCurrentPopup(); // manually close the popup we have begin-ed into.
|
||||
|
||||
// Popups: open+begin combined functions helpers
|
||||
// Popups: Open+Begin popup combined functions helpers to create context menus.
|
||||
// - Helpers to do OpenPopup+BeginPopup where the Open action is triggered by e.g. hovering an item and right-clicking.
|
||||
// - They are convenient to easily create context menus, hence the name.
|
||||
// - IMPORTANT: Notice that BeginPopupContextXXX takes ImGuiPopupFlags just like OpenPopup() and unlike BeginPopup(). For full consistency, we may add ImGuiWindowFlags to the BeginPopupContextXXX functions in the future.
|
||||
// - IMPORTANT: Notice that we exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter, so if you add other flags remember to re-add the ImGuiPopupFlags_MouseButtonRight.
|
||||
IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked on last item. Use str_id==NULL to associate the popup to previous item. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp!
|
||||
IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1);// open+begin popup when clicked on current window.
|
||||
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked in void (where there are no windows).
|
||||
// - IMPORTANT: If you ever used the left mouse button with BeginPopupContextXXX() helpers before 1.92.6:
|
||||
// - Before this version, OpenPopupOnItemClick(), BeginPopupContextItem(), BeginPopupContextWindow(), BeginPopupContextVoid() had 'a ImGuiPopupFlags popup_flags = 1' default value in their function signature.
|
||||
// - Before: Explicitly passing a literal 0 meant ImGuiPopupFlags_MouseButtonLeft. The default = 1 meant ImGuiPopupFlags_MouseButtonRight.
|
||||
// - After: The default = 0 means ImGuiPopupFlags_MouseButtonRight. Explicitly passing a literal 1 also means ImGuiPopupFlags_MouseButtonRight (if legacy behavior are enabled) or will assert (if legacy behavior are disabled).
|
||||
// - TL;DR: if you don't want to use right mouse button for popups, always specify it explicitly using a named ImGuiPopupFlags_MouseButtonXXXX value.
|
||||
// - Read "API BREAKING CHANGES" 2026/01/07 (1.92.6) entry in imgui.cpp or GitHub topic #9157 for all details.
|
||||
IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 0); // open+begin popup when clicked on last item. Use str_id==NULL to associate the popup to previous item. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp!
|
||||
IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 0);// open+begin popup when clicked on current window.
|
||||
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 0); // open+begin popup when clicked in void (where there are no windows).
|
||||
|
||||
// Popups: query functions
|
||||
// - IsPopupOpen(): return true if the popup is open at the current BeginPopup() level of the popup stack.
|
||||
@@ -897,7 +900,7 @@ namespace ImGui
|
||||
// - 5. Call EndTable()
|
||||
IMGUI_API bool BeginTable(const char* str_id, int columns, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f);
|
||||
IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true!
|
||||
IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row.
|
||||
IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row. 'min_row_height' include the minimum top and bottom padding aka CellPadding.y * 2.0f.
|
||||
IMGUI_API bool TableNextColumn(); // append into the next column (or first column of next row if currently in last column). Return true when column is visible.
|
||||
IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return true when column is visible.
|
||||
|
||||
@@ -977,7 +980,7 @@ namespace ImGui
|
||||
// Disabling [BETA API]
|
||||
// - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors)
|
||||
// - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled)
|
||||
// - Tooltips windows are automatically opted out of disabling. Note that IsItemHovered() by default returns false on disabled items, unless using ImGuiHoveredFlags_AllowWhenDisabled.
|
||||
// - Tooltips windows are automatically opted out of disabling. Note that IsItemHovered() by default returns false on disabled items, unless using ImGuiHoveredFlags_AllowWhenDisabled.
|
||||
// - BeginDisabled(false)/EndDisabled() essentially does nothing but is provided to facilitate use of boolean expressions (as a micro-optimization: if you have tens of thousands of BeginDisabled(false)/EndDisabled() pairs, you might want to reformulate your code to avoid making those calls)
|
||||
IMGUI_API void BeginDisabled(bool disabled = true);
|
||||
IMGUI_API void EndDisabled();
|
||||
@@ -1017,6 +1020,7 @@ namespace ImGui
|
||||
IMGUI_API ImVec2 GetItemRectMin(); // get upper-left bounding rectangle of the last item (screen space)
|
||||
IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space)
|
||||
IMGUI_API ImVec2 GetItemRectSize(); // get size of last item
|
||||
IMGUI_API ImGuiItemFlags GetItemFlags(); // get generic flags of last item
|
||||
|
||||
// Viewports
|
||||
// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.
|
||||
@@ -1047,19 +1051,22 @@ namespace ImGui
|
||||
IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v);
|
||||
IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b);
|
||||
|
||||
// Inputs Utilities: Keyboard/Mouse/Gamepad
|
||||
// Inputs Utilities: Raw Keyboard/Mouse/Gamepad Access
|
||||
// - Consider using the Shortcut() function instead of IsKeyPressed()/IsKeyChordPressed()! Shortcut() is easier to use and better featured (can do focus routing check).
|
||||
// - the ImGuiKey enum contains all possible keyboard, mouse and gamepad inputs (e.g. ImGuiKey_A, ImGuiKey_MouseLeft, ImGuiKey_GamepadDpadUp...).
|
||||
// - (legacy: before v1.87, we used ImGuiKey to carry native/user indices as defined by each backends. This was obsoleted in 1.87 (2022-02) and completely removed in 1.91.5 (2024-11). See https://github.com/ocornut/imgui/issues/4921)
|
||||
// - (legacy: any use of ImGuiKey will assert when key < 512 to detect passing legacy native/user indices)
|
||||
// - (legacy: before v1.87 (2022-02), we used ImGuiKey < 512 values to carry native/user indices as defined by each backends. This was obsoleted in 1.87 (2022-02) and completely removed in 1.91.5 (2024-11). See https://github.com/ocornut/imgui/issues/4921)
|
||||
IMGUI_API bool IsKeyDown(ImGuiKey key); // is key being held.
|
||||
IMGUI_API bool IsKeyPressed(ImGuiKey key, bool repeat = true); // was key pressed (went from !Down to Down)? if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate
|
||||
IMGUI_API bool IsKeyPressed(ImGuiKey key, bool repeat = true); // was key pressed (went from !Down to Down)? Repeat rate uses io.KeyRepeatDelay / KeyRepeatRate.
|
||||
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 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]
|
||||
// Inputs Utilities: Shortcut Testing & Routing
|
||||
// - Typical use is e.g.: 'if (ImGui::Shortcut(ImGuiMod_Ctrl | ImGuiKey_S)) { ... }'.
|
||||
// - Flags: Default route use ImGuiInputFlags_RouteFocused, but see ImGuiInputFlags_RouteGlobal and other options in ImGuiInputFlags_!
|
||||
// - Flags: Use ImGuiInputFlags_Repeat to support repeat.
|
||||
// - ImGuiKeyChord = a ImGuiKey + optional ImGuiMod_Alt/ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Super.
|
||||
// ImGuiKey_C // Accepted by functions taking ImGuiKey or ImGuiKeyChord arguments
|
||||
// ImGuiMod_Ctrl | ImGuiKey_C // Accepted by functions taking ImGuiKeyChord arguments
|
||||
@@ -1071,8 +1078,10 @@ namespace ImGui
|
||||
// The whole system is order independent, so if Child1 makes its calls before Parent, results will be identical.
|
||||
// This is an important property as it facilitate working with foreign code or larger codebase.
|
||||
// - To understand the difference:
|
||||
// - IsKeyChordPressed() compares mods and call IsKeyPressed() -> function has no side-effect.
|
||||
// - Shortcut() submits a route, routes are resolved, if it currently can be routed it calls IsKeyChordPressed() -> function has (desirable) side-effects as it can prevents another call from getting the route.
|
||||
// - IsKeyChordPressed() compares mods and call IsKeyPressed()
|
||||
// -> the function has no side-effect.
|
||||
// - Shortcut() submits a route, routes are resolved, if it currently can be routed it calls IsKeyChordPressed()
|
||||
// -> the function has (desirable) side-effects as it can prevents another call from getting the route.
|
||||
// - Visualize registered routes in 'Metrics/Debugger->Inputs'.
|
||||
IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0);
|
||||
IMGUI_API void SetNextItemShortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0);
|
||||
@@ -1122,7 +1131,9 @@ namespace ImGui
|
||||
IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings.
|
||||
|
||||
// Debug Utilities
|
||||
// - Your main debugging friend is the ShowMetricsWindow() function, which is also accessible from Demo->Tools->Metrics Debugger
|
||||
// - Your main debugging friend is the ShowMetricsWindow() function.
|
||||
// - Interactive tools are all accessible from the 'Dear ImGui Demo->Tools' menu.
|
||||
// - Read https://github.com/ocornut/imgui/wiki/Debug-Tools for a description of all available debug tools.
|
||||
IMGUI_API void DebugTextEncoding(const char* text);
|
||||
IMGUI_API void DebugFlashStyleColor(ImGuiCol idx);
|
||||
IMGUI_API void DebugStartItemPicker();
|
||||
@@ -1218,7 +1229,7 @@ enum ImGuiChildFlags_
|
||||
};
|
||||
|
||||
// Flags for ImGui::PushItemFlag()
|
||||
// (Those are shared by all items)
|
||||
// (Those are shared by all submitted items)
|
||||
enum ImGuiItemFlags_
|
||||
{
|
||||
ImGuiItemFlags_None = 0, // (Default)
|
||||
@@ -1228,6 +1239,7 @@ enum ImGuiItemFlags_
|
||||
ImGuiItemFlags_ButtonRepeat = 1 << 3, // false // Any button-like behavior will have repeat mode enabled (based on io.KeyRepeatDelay and io.KeyRepeatRate values). Note that you can also call IsItemActive() after any button to tell if it is being held.
|
||||
ImGuiItemFlags_AutoClosePopups = 1 << 4, // true // MenuItem()/Selectable() automatically close their parent popup window.
|
||||
ImGuiItemFlags_AllowDuplicateId = 1 << 5, // false // Allow submitting an item with the same identifier as an item already submitted this frame without triggering a warning tooltip if io.ConfigDebugHighlightIdConflicts is set.
|
||||
ImGuiItemFlags_Disabled = 1 << 6, // false // [Internal] Disable interactions. DOES NOT affect visuals. This is used by BeginDisabled()/EndDisabled() and only provided here so you can read back via GetItemFlags().
|
||||
};
|
||||
|
||||
// Flags for ImGui::InputText()
|
||||
@@ -1320,21 +1332,14 @@ enum ImGuiTreeNodeFlags_
|
||||
};
|
||||
|
||||
// Flags for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() functions.
|
||||
// - To be backward compatible with older API which took an 'int mouse_button = 1' argument instead of 'ImGuiPopupFlags flags',
|
||||
// we need to treat small flags values as a mouse button index, so we encode the mouse button in the first few bits of the flags.
|
||||
// It is therefore guaranteed to be legal to pass a mouse button index in ImGuiPopupFlags.
|
||||
// - For the same reason, we exceptionally default the ImGuiPopupFlags argument of BeginPopupContextXXX functions to 1 instead of 0.
|
||||
// IMPORTANT: because the default parameter is 1 (==ImGuiPopupFlags_MouseButtonRight), if you rely on the default parameter
|
||||
// and want to use another flag, you need to pass in the ImGuiPopupFlags_MouseButtonRight flag explicitly.
|
||||
// - IMPORTANT: If you ever used the left mouse button with BeginPopupContextXXX() helpers before 1.92.6: Read "API BREAKING CHANGES" 2026/01/07 (1.92.6) entry in imgui.cpp or GitHub topic #9157.
|
||||
// - Multiple buttons currently cannot be combined/or-ed in those functions (we could allow it later).
|
||||
enum ImGuiPopupFlags_
|
||||
{
|
||||
ImGuiPopupFlags_None = 0,
|
||||
ImGuiPopupFlags_MouseButtonLeft = 0, // For BeginPopupContext*(): open on Left Mouse release. Guaranteed to always be == 0 (same as ImGuiMouseButton_Left)
|
||||
ImGuiPopupFlags_MouseButtonRight = 1, // For BeginPopupContext*(): open on Right Mouse release. Guaranteed to always be == 1 (same as ImGuiMouseButton_Right)
|
||||
ImGuiPopupFlags_MouseButtonMiddle = 2, // For BeginPopupContext*(): open on Middle Mouse release. Guaranteed to always be == 2 (same as ImGuiMouseButton_Middle)
|
||||
ImGuiPopupFlags_MouseButtonMask_ = 0x1F,
|
||||
ImGuiPopupFlags_MouseButtonDefault_ = 1,
|
||||
ImGuiPopupFlags_MouseButtonLeft = 1 << 2, // For BeginPopupContext*(): open on Left Mouse release. Only one button allowed!
|
||||
ImGuiPopupFlags_MouseButtonRight = 2 << 2, // For BeginPopupContext*(): open on Right Mouse release. Only one button allowed! (default)
|
||||
ImGuiPopupFlags_MouseButtonMiddle = 3 << 2, // For BeginPopupContext*(): open on Middle Mouse release. Only one button allowed!
|
||||
ImGuiPopupFlags_NoReopen = 1 << 5, // For OpenPopup*(), BeginPopupContext*(): don't reopen same popup if already open (won't reposition, won't reinitialize navigation)
|
||||
//ImGuiPopupFlags_NoReopenAlwaysNavInit = 1 << 6, // For OpenPopup*(), BeginPopupContext*(): focus and initialize navigation even when not reopening.
|
||||
ImGuiPopupFlags_NoOpenOverExistingPopup = 1 << 7, // For OpenPopup*(), BeginPopupContext*(): don't open if there's already a popup at the same level of the popup stack
|
||||
@@ -1342,6 +1347,9 @@ enum ImGuiPopupFlags_
|
||||
ImGuiPopupFlags_AnyPopupId = 1 << 10, // For IsPopupOpen(): ignore the ImGuiID parameter and test for any popup.
|
||||
ImGuiPopupFlags_AnyPopupLevel = 1 << 11, // For IsPopupOpen(): search/test at any level of the popup stack (default test in the current level)
|
||||
ImGuiPopupFlags_AnyPopup = ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel,
|
||||
ImGuiPopupFlags_MouseButtonShift_ = 2, // [Internal]
|
||||
ImGuiPopupFlags_MouseButtonMask_ = 0x0C, // [Internal]
|
||||
ImGuiPopupFlags_InvalidMask_ = 0x03, // [Internal] Reserve legacy bits 0-1 to detect incorrectly passing 1 or 2 to the function.
|
||||
};
|
||||
|
||||
// Flags for ImGui::Selectable()
|
||||
@@ -1538,7 +1546,7 @@ enum ImGuiSortDirection : ImU8
|
||||
// All our named keys are >= 512. Keys value 0 to 511 are left unused and were legacy native/opaque key values (< 1.87).
|
||||
// Support for legacy keys was completely removed in 1.91.5.
|
||||
// Read details about the 1.87+ transition : https://github.com/ocornut/imgui/issues/4921
|
||||
// Note that "Keys" related to physical keys and are not the same concept as input "Characters", the later are submitted via io.AddInputCharacter().
|
||||
// Note that "Keys" related to physical keys and are not the same concept as input "Characters", the latter are submitted via io.AddInputCharacter().
|
||||
// The keyboard key enum values are named after the keys on a standard US keyboard, and on other keyboard types the keys reported may not match the keycaps.
|
||||
enum ImGuiKey : int
|
||||
{
|
||||
@@ -1695,7 +1703,7 @@ enum ImGuiInputFlags_
|
||||
enum ImGuiConfigFlags_
|
||||
{
|
||||
ImGuiConfigFlags_None = 0,
|
||||
ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. Enable full Tabbing + directional arrows + space/enter to activate.
|
||||
ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. Enable full Tabbing + directional arrows + Space/Enter to activate. Note: some features such as basic Tabbing and CtrL+Tab are enabled by regardless of this flag (and may be disabled via other means, see #4828, #9218).
|
||||
ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. Backend also needs to set ImGuiBackendFlags_HasGamepad.
|
||||
ImGuiConfigFlags_NoMouse = 1 << 4, // Instruct dear imgui to disable mouse inputs and interactions.
|
||||
ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, // Instruct backend to not alter mouse cursor shape and visibility. Use if the backend cursor changes are interfering with yours and you don't want to use SetMouseCursor() to change mouse cursor. You may want to honor requests from imgui by reading GetMouseCursor() yourself instead.
|
||||
@@ -1829,6 +1837,7 @@ enum ImGuiStyleVar_
|
||||
ImGuiStyleVar_ScrollbarPadding, // float ScrollbarPadding
|
||||
ImGuiStyleVar_GrabMinSize, // float GrabMinSize
|
||||
ImGuiStyleVar_GrabRounding, // float GrabRounding
|
||||
ImGuiStyleVar_ImageRounding, // float ImageRounding
|
||||
ImGuiStyleVar_ImageBorderSize, // float ImageBorderSize
|
||||
ImGuiStyleVar_TabRounding, // float TabRounding
|
||||
ImGuiStyleVar_TabBorderSize, // float TabBorderSize
|
||||
@@ -1871,19 +1880,20 @@ enum ImGuiColorEditFlags_
|
||||
ImGuiColorEditFlags_NoTooltip = 1 << 6, // // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview.
|
||||
ImGuiColorEditFlags_NoLabel = 1 << 7, // // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker).
|
||||
ImGuiColorEditFlags_NoSidePreview = 1 << 8, // // ColorPicker: disable bigger color preview on right side of the picker, use small color square preview instead.
|
||||
ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.
|
||||
ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target/source. ColorButton: disable drag and drop source.
|
||||
ImGuiColorEditFlags_NoBorder = 1 << 10, // // ColorButton: disable border (which is enforced by default)
|
||||
ImGuiColorEditFlags_NoColorMarkers = 1 << 11, // // ColorEdit: disable rendering R/G/B/A color marker. May also be disabled globally by setting style.ColorMarkerSize = 0.
|
||||
|
||||
// Alpha preview
|
||||
// - Prior to 1.91.8 (2025/01/21): alpha was made opaque in the preview by default using old name ImGuiColorEditFlags_AlphaPreview.
|
||||
// - We now display the preview as transparent by default. You can use ImGuiColorEditFlags_AlphaOpaque to use old behavior.
|
||||
// - The new flags may be combined better and allow finer controls.
|
||||
ImGuiColorEditFlags_AlphaOpaque = 1 << 11, // // ColorEdit, ColorPicker, ColorButton: disable alpha in the preview,. Contrary to _NoAlpha it may still be edited when calling ColorEdit4()/ColorPicker4(). For ColorButton() this does the same as _NoAlpha.
|
||||
ImGuiColorEditFlags_AlphaNoBg = 1 << 12, // // ColorEdit, ColorPicker, ColorButton: disable rendering a checkerboard background behind transparent color.
|
||||
ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 13, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half transparent preview.
|
||||
ImGuiColorEditFlags_AlphaOpaque = 1 << 12, // // ColorEdit, ColorPicker, ColorButton: disable alpha in the preview,. Contrary to _NoAlpha it may still be edited when calling ColorEdit4()/ColorPicker4(). For ColorButton() this does the same as _NoAlpha.
|
||||
ImGuiColorEditFlags_AlphaNoBg = 1 << 13, // // ColorEdit, ColorPicker, ColorButton: disable rendering a checkerboard background behind transparent color.
|
||||
ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 14, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half transparent preview.
|
||||
|
||||
// User Options (right-click on widget to change some of them).
|
||||
ImGuiColorEditFlags_AlphaBar = 1 << 16, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
|
||||
ImGuiColorEditFlags_AlphaBar = 1 << 18, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
|
||||
ImGuiColorEditFlags_HDR = 1 << 19, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well).
|
||||
ImGuiColorEditFlags_DisplayRGB = 1 << 20, // [Display] // ColorEdit: override _display_ type among RGB/HSV/Hex. ColorPicker: select any combination using one or more of RGB/HSV/Hex.
|
||||
ImGuiColorEditFlags_DisplayHSV = 1 << 21, // [Display] // "
|
||||
@@ -1926,8 +1936,9 @@ enum ImGuiSliderFlags_
|
||||
ImGuiSliderFlags_ClampOnInput = 1 << 9, // Clamp value to min/max bounds when input manually with Ctrl+Click. By default Ctrl+Click allows going out of bounds.
|
||||
ImGuiSliderFlags_ClampZeroRange = 1 << 10, // Clamp even if min==max==0.0f. Otherwise due to legacy reason DragXXX functions don't clamp with those values. When your clamping limits are dynamic you almost always want to use it.
|
||||
ImGuiSliderFlags_NoSpeedTweaks = 1 << 11, // Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic.
|
||||
ImGuiSliderFlags_ColorMarkers = 1 << 12, // DragScalarN(), SliderScalarN(): Draw R/G/B/A color markers on each component.
|
||||
ImGuiSliderFlags_AlwaysClamp = ImGuiSliderFlags_ClampOnInput | ImGuiSliderFlags_ClampZeroRange,
|
||||
ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed.
|
||||
ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from legacy API (obsoleted 2020-08) that has got miscast to this enum, and will trigger an assert if needed.
|
||||
};
|
||||
|
||||
// Identify a mouse button.
|
||||
@@ -2017,7 +2028,7 @@ enum ImGuiTableFlags_
|
||||
ImGuiTableFlags_Reorderable = 1 << 1, // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
|
||||
ImGuiTableFlags_Hideable = 1 << 2, // Enable hiding/disabling columns in context menu.
|
||||
ImGuiTableFlags_Sortable = 1 << 3, // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see ImGuiTableFlags_SortMulti and ImGuiTableFlags_SortTristate.
|
||||
ImGuiTableFlags_NoSavedSettings = 1 << 4, // Disable persisting columns order, width and sort settings in the .ini file.
|
||||
ImGuiTableFlags_NoSavedSettings = 1 << 4, // Disable persisting columns order, width, visibility and sort settings in the .ini file.
|
||||
ImGuiTableFlags_ContextMenuInBody = 1 << 5, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().
|
||||
// Decorations
|
||||
ImGuiTableFlags_RowBg = 1 << 6, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent of calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually)
|
||||
@@ -2133,7 +2144,7 @@ struct ImGuiTableSortSpecs
|
||||
int SpecsCount; // Sort spec count. Most often 1. May be > 1 when ImGuiTableFlags_SortMulti is enabled. May be == 0 when ImGuiTableFlags_SortTristate is enabled.
|
||||
bool SpecsDirty; // Set to true when specs have changed since last time! Use this to sort again, then clear the flag.
|
||||
|
||||
ImGuiTableSortSpecs() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiTableSortSpecs() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Sorting specification for one column of a table (sizeof == 12 bytes)
|
||||
@@ -2144,7 +2155,7 @@ struct ImGuiTableColumnSortSpecs
|
||||
ImS16 SortOrder; // Index within parent ImGuiTableSortSpecs (always stored in order starting from 0, tables sorted on a single criteria will always have a 0 here)
|
||||
ImGuiSortDirection SortDirection; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
|
||||
|
||||
ImGuiTableColumnSortSpecs() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiTableColumnSortSpecs() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2267,7 +2278,7 @@ struct ImGuiStyle
|
||||
// - recap: ImGui::GetFontSize() == FontSizeBase * (FontScaleMain * FontScaleDpi * other_scaling_factors)
|
||||
float FontSizeBase; // Current base font size before external global factors are applied. Use PushFont(NULL, size) to modify. Use ImGui::GetFontSize() to obtain scaled value.
|
||||
float FontScaleMain; // Main global scale factor. May be set by application once, or exposed to end-user.
|
||||
float FontScaleDpi; // Additional global scale factor from viewport/monitor contents scale. When io.ConfigDpiScaleFonts is enabled, this is automatically overwritten when changing monitor DPI.
|
||||
float FontScaleDpi; // Additional global scale factor from viewport/monitor contents scale. In docking branch: when io.ConfigDpiScaleFonts is enabled, this is automatically overwritten when changing monitor DPI.
|
||||
|
||||
float Alpha; // Global alpha applies to everything in Dear ImGui.
|
||||
float DisabledAlpha; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha.
|
||||
@@ -2297,6 +2308,7 @@ 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 ImageRounding; // Rounding of Image() calls.
|
||||
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.
|
||||
@@ -2314,6 +2326,7 @@ struct ImGuiStyle
|
||||
float DragDropTargetRounding; // Radius of the drag and drop target frame.
|
||||
float DragDropTargetBorderSize; // Thickness of the drag and drop target border.
|
||||
float DragDropTargetPadding; // Size to expand the drag and drop target from actual target item size.
|
||||
float ColorMarkerSize; // Size of R/G/B/A color markers for ColorEdit4() and for Drags/Sliders when using ImGuiSliderFlags_ColorMarkers.
|
||||
ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
|
||||
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered).
|
||||
ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.
|
||||
@@ -2434,7 +2447,7 @@ struct ImGuiIO
|
||||
|
||||
// Options to configure Error Handling and how we handle recoverable errors [EXPERIMENTAL]
|
||||
// - Error recovery is provided as a way to facilitate:
|
||||
// - Recovery after a programming error (native code or scripting language - the later tends to facilitate iterating on code while running).
|
||||
// - Recovery after a programming error (native code or scripting language - the latter tends to facilitate iterating on code while running).
|
||||
// - Recovery after running an exception handler or any error processing which may skip code after an error has been detected.
|
||||
// - Error recovery is not perfect nor guaranteed! It is a feature to ease development.
|
||||
// You not are not supposed to rely on it in the course of a normal application run.
|
||||
@@ -2623,18 +2636,20 @@ struct ImGuiInputTextCallbackData
|
||||
ImGuiInputTextFlags EventFlag; // One ImGuiInputTextFlags_Callback* // Read-only
|
||||
ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only
|
||||
void* UserData; // What user passed to InputText() // Read-only
|
||||
ImGuiID ID; // Widget ID // Read-only
|
||||
|
||||
// Arguments for the different callback events
|
||||
// - During Resize callback, Buf will be same as your input buffer.
|
||||
// - However, during Completion/History/Always callback, Buf always points to our own internal data (it is not the same as your buffer)! Changes to it will be reflected into your own buffer shortly after the callback.
|
||||
// - To modify the text buffer in a callback, prefer using the InsertChars() / DeleteChars() function. InsertChars() will take care of calling the resize callback if necessary.
|
||||
// - If you know your edits are not going to resize the underlying buffer allocation, you may modify the contents of 'Buf[]' directly. You need to update 'BufTextLen' accordingly (0 <= BufTextLen < BufSize) and set 'BufDirty'' to true so InputText can update its internal state.
|
||||
ImWchar EventChar; // Character input // Read-write // [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0;
|
||||
ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only // [Completion,History]
|
||||
ImWchar EventChar; // Character input // Read-write // [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0;
|
||||
bool EventActivated; // Input field just got activated // Read-only // [Always]
|
||||
bool BufDirty; // Set if you modify Buf/BufTextLen! // Write // [Completion,History,Always]
|
||||
char* Buf; // Text buffer // Read-write // [Resize] Can replace pointer / [Completion,History,Always] Only write to pointed data, don't replace the actual pointer!
|
||||
int BufTextLen; // Text length (in bytes) // Read-write // [Resize,Completion,History,Always] Exclude zero-terminator storage. In C land: == strlen(some_text), in C++ land: string.length()
|
||||
int BufSize; // Buffer size (in bytes) = capacity+1 // Read-only // [Resize,Completion,History,Always] Include zero-terminator storage. In C land: == ARRAYSIZE(my_char_array), in C++ land: string.capacity()+1
|
||||
bool BufDirty; // Set if you modify Buf/BufTextLen! // Write // [Completion,History,Always]
|
||||
int CursorPos; // // Read-write // [Completion,History,Always]
|
||||
int SelectionStart; // // Read-write // [Completion,History,Always] == to SelectionEnd when no selection
|
||||
int SelectionEnd; // // Read-write // [Completion,History,Always]
|
||||
@@ -2644,9 +2659,10 @@ struct ImGuiInputTextCallbackData
|
||||
IMGUI_API ImGuiInputTextCallbackData();
|
||||
IMGUI_API void DeleteChars(int pos, int bytes_count);
|
||||
IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL);
|
||||
void SelectAll() { SelectionStart = 0; SelectionEnd = BufTextLen; }
|
||||
void ClearSelection() { SelectionStart = SelectionEnd = BufTextLen; }
|
||||
bool HasSelection() const { return SelectionStart != SelectionEnd; }
|
||||
void SelectAll() { SelectionStart = 0; CursorPos = SelectionEnd = BufTextLen; }
|
||||
void SetSelection(int s, int e) { IM_ASSERT(s >= 0 && s <= BufTextLen); IM_ASSERT(e >= 0 && e <= BufTextLen); SelectionStart = s; CursorPos = SelectionEnd = e; }
|
||||
void ClearSelection() { SelectionStart = SelectionEnd = BufTextLen; }
|
||||
bool HasSelection() const { return SelectionStart != SelectionEnd; }
|
||||
};
|
||||
|
||||
// Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin().
|
||||
@@ -2865,7 +2881,7 @@ struct ImGuiListClipper
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
//inline void IncludeRangeByIndices(int item_begin, int item_end) { IncludeItemsByIndex(item_begin, item_end); } // [renamed in 1.89.9]
|
||||
//inline void ForceDisplayRangeByIndices(int item_begin, int item_end) { IncludeItemsByIndex(item_begin, item_end); } // [renamed in 1.89.6]
|
||||
//inline ImGuiListClipper(int items_count, float items_height = -1.0f) { memset(this, 0, sizeof(*this)); ItemsCount = -1; Begin(items_count, items_height); } // [removed in 1.79]
|
||||
//inline ImGuiListClipper(int items_count, float items_height = -1.0f) { memset((void*)this, 0, sizeof(*this)); ItemsCount = -1; Begin(items_count, items_height); } // [removed in 1.79]
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -3150,7 +3166,7 @@ struct ImDrawCmd
|
||||
int UserCallbackDataSize; // 4 // Size of callback user data when using storage, otherwise 0.
|
||||
int UserCallbackDataOffset;// 4 // [Internal] Offset of callback user data when using storage, otherwise -1.
|
||||
|
||||
ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed
|
||||
ImDrawCmd() { memset((void*)this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed
|
||||
|
||||
// Since 1.83: returns ImTextureID associated with this draw call. Warning: DO NOT assume this is always same as 'TextureId' (we will change this function for an upcoming feature)
|
||||
// Since 1.92: removed ImDrawCmd::TextureId field, the getter function must be used!
|
||||
@@ -3196,7 +3212,7 @@ struct ImDrawListSplitter
|
||||
int _Count; // Number of active channels (1+)
|
||||
ImVector<ImDrawChannel> _Channels; // Draw channels (not resized down so _Count might be < Channels.Size)
|
||||
|
||||
inline ImDrawListSplitter() { memset(this, 0, sizeof(*this)); }
|
||||
inline ImDrawListSplitter() { memset((void*)this, 0, sizeof(*this)); }
|
||||
inline ~ImDrawListSplitter() { ClearFreeMemory(); }
|
||||
inline void Clear() { _Current = 0; _Count = 1; } // Do not clear Channels[] so our allocations are reused next frame
|
||||
IMGUI_API void ClearFreeMemory();
|
||||
@@ -3489,7 +3505,7 @@ struct ImTextureData
|
||||
bool WantDestroyNextFrame; // rw - // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame.
|
||||
|
||||
// Functions
|
||||
ImTextureData() { memset(this, 0, sizeof(*this)); Status = ImTextureStatus_Destroyed; TexID = ImTextureID_Invalid; }
|
||||
ImTextureData() { memset((void*)this, 0, sizeof(*this)); Status = ImTextureStatus_Destroyed; TexID = ImTextureID_Invalid; }
|
||||
~ImTextureData() { DestroyPixels(); }
|
||||
IMGUI_API void Create(ImTextureFormat format, int w, int h);
|
||||
IMGUI_API void DestroyPixels();
|
||||
@@ -3504,7 +3520,7 @@ struct ImTextureData
|
||||
// - Call SetTexID() and SetStatus() after honoring texture requests. Never modify TexID and Status directly!
|
||||
// - A backend may decide to destroy a texture that we did not request to destroy, which is fine (e.g. freeing resources), but we immediately set the texture back in _WantCreate mode.
|
||||
void SetTexID(ImTextureID tex_id) { TexID = tex_id; }
|
||||
void SetStatus(ImTextureStatus status) { Status = status; if (status == ImTextureStatus_Destroyed && !WantDestroyNextFrame) Status = ImTextureStatus_WantCreate; }
|
||||
void SetStatus(ImTextureStatus status) { Status = status; if (status == ImTextureStatus_Destroyed && !WantDestroyNextFrame && Pixels != nullptr) Status = ImTextureStatus_WantCreate; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -3518,16 +3534,15 @@ struct ImFontConfig
|
||||
char Name[40]; // <auto> // Name (strictly to ease debugging, hence limited size buffer)
|
||||
void* FontData; // // TTF/OTF data
|
||||
int FontDataSize; // // TTF/OTF data size
|
||||
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the owner ImFontAtlas (will delete memory itself).
|
||||
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the owner ImFontAtlas (will delete memory itself). SINCE 1.92, THE DATA NEEDS TO PERSIST FOR WHOLE DURATION OF ATLAS.
|
||||
|
||||
// Options
|
||||
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
|
||||
bool PixelSnapH; // false // Align every glyph AdvanceX to pixel boundaries. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
|
||||
bool PixelSnapV; // true // Align Scaled GlyphOffset.y to pixel boundaries.
|
||||
bool PixelSnapH; // false // Align every glyph AdvanceX to pixel boundaries. Prevents fractional font size from working correctly! Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, OversampleH/V will default to 1.
|
||||
ImS8 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.
|
||||
ImS8 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.
|
||||
ImWchar EllipsisChar; // 0 // Explicitly specify Unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
|
||||
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
|
||||
float SizePixels; // // Output size in pixels for rasterizer (more or less maps to the resulting font height).
|
||||
const ImWchar* GlyphRanges; // NULL // *LEGACY* 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).
|
||||
const ImWchar* GlyphExcludeRanges; // NULL // Pointer to a small user-provided list of Unicode ranges (2 value per range, values are inclusive, zero-terminated list). This is very close to GlyphRanges[] but designed to exclude ranges from a font source, when merging fonts with overlapping glyphs. Use "Input Glyphs Overlap Detection Tool" to find about your overlapping ranges.
|
||||
//ImVec2 GlyphExtraSpacing; // 0, 0 // (REMOVED AT IT SEEMS LARGELY OBSOLETE. PLEASE REPORT IF YOU WERE USING THIS). Extra spacing (in pixels) between glyphs when rendered: essentially add to glyph->AdvanceX. Only X axis is supported for now.
|
||||
@@ -3537,9 +3552,10 @@ struct ImFontConfig
|
||||
float GlyphExtraAdvanceX; // 0 // Extra spacing (in pixels) between glyphs. Please contact us if you are using this. // FIXME-NEWATLAS: Intentionally unscaled
|
||||
ImU32 FontNo; // 0 // Index of font within TTF/OTF file
|
||||
unsigned int FontLoaderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
|
||||
//unsigned int FontBuilderFlags; // -- // [Renamed in 1.92] Ue FontLoaderFlags.
|
||||
//unsigned int FontBuilderFlags; // -- // [Renamed in 1.92] Use FontLoaderFlags.
|
||||
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 // [LEGACY: this only makes sense when ImGuiBackendFlags_RendererHasTextures is not supported] DPI scale multiplier for rasterization. Not altering other font metrics: makes it easy to swap between e.g. a 100% and a 400% fonts for a zooming display, or handle Retina screen. IMPORTANT: If you change this it is expected that you increase/decrease font scale roughly to the inverse of this, otherwise quality may look lowered.
|
||||
float ExtraSizeScale; // 1.0f // Extra rasterizer scale over SizePixels.
|
||||
|
||||
// [Internal]
|
||||
ImFontFlags Flags; // Font flags (don't use just yet, will be exposed in upcoming 1.92.X updates)
|
||||
@@ -3547,6 +3563,9 @@ struct ImFontConfig
|
||||
const ImFontLoader* FontLoader; // Custom font backend for this source (default source is the one stored in ImFontAtlas)
|
||||
void* FontLoaderData; // Font loader opaque storage (per font config)
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
bool PixelSnapV; // true // [Obsoleted in 1.91.6] Align Scaled GlyphOffset.y to pixel boundaries.
|
||||
#endif
|
||||
IMGUI_API ImFontConfig();
|
||||
};
|
||||
|
||||
@@ -3563,7 +3582,7 @@ struct ImFontGlyph
|
||||
float U0, V0, U1, V1; // Texture coordinates for the current value of ImFontAtlas->TexRef. Cached equivalent of calling GetCustomRect() with PackId.
|
||||
int PackId; // [Internal] ImFontAtlasRectId value (FIXME: Cold data, could be moved elsewhere?)
|
||||
|
||||
ImFontGlyph() { memset(this, 0, sizeof(*this)); PackId = -1; }
|
||||
ImFontGlyph() { memset((void*)this, 0, sizeof(*this)); PackId = -1; }
|
||||
};
|
||||
|
||||
// Helper to build glyph ranges from text/string data. Feed your application strings/characters to it then call BuildRanges().
|
||||
@@ -3596,7 +3615,7 @@ struct ImFontAtlasRect
|
||||
unsigned short w, h; // Size
|
||||
ImVec2 uv0, uv1; // UV coordinates (in current texture)
|
||||
|
||||
ImFontAtlasRect() { memset(this, 0, sizeof(*this)); }
|
||||
ImFontAtlasRect() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Flags for ImFontAtlas build
|
||||
@@ -3632,7 +3651,9 @@ struct ImFontAtlas
|
||||
IMGUI_API ImFontAtlas();
|
||||
IMGUI_API ~ImFontAtlas();
|
||||
IMGUI_API ImFont* AddFont(const ImFontConfig* font_cfg);
|
||||
IMGUI_API ImFont* AddFontDefault(const ImFontConfig* font_cfg = NULL);
|
||||
IMGUI_API ImFont* AddFontDefault(const ImFontConfig* font_cfg = NULL); // Selects between AddFontDefaultVector() and AddFontDefaultBitmap().
|
||||
IMGUI_API ImFont* AddFontDefaultVector(const ImFontConfig* font_cfg = NULL); // Embedded scalable font. Recommended at any higher size.
|
||||
IMGUI_API ImFont* AddFontDefaultBitmap(const ImFontConfig* font_cfg = NULL); // Embedded classic pixel-clean font. Recommended at Size 13px with no scaling.
|
||||
IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels = 0.0f, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL);
|
||||
IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_data_size, float size_pixels = 0.0f, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Note: Transfer ownership of 'ttf_data' to ImFontAtlas! Will be deleted after destruction of the atlas. Set font_cfg->FontDataOwnedByAtlas=false to keep ownership of your data and it won't be freed.
|
||||
IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_data_size, float size_pixels = 0.0f, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp.
|
||||
@@ -3794,7 +3815,7 @@ struct ImFontBaked
|
||||
unsigned int MetricsTotalSurface:26;// 3 // out // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
|
||||
unsigned int WantDestroy:1; // 0 // // Queued for destroy
|
||||
unsigned int LoadNoFallback:1; // 0 // // Disable loading fallback in lower-level calls.
|
||||
unsigned int LoadNoRenderOnLayout:1;// 0 // // Enable a two-steps mode where CalcTextSize() calls will load AdvanceX *without* rendering/packing glyphs. Only advantagous if you know that the glyph is unlikely to actually be rendered, otherwise it is slower because we'd do one query on the first CalcTextSize and one query on the first Draw.
|
||||
unsigned int LoadNoRenderOnLayout:1;// 0 // // Enable a two-steps mode where CalcTextSize() calls will load AdvanceX *without* rendering/packing glyphs. Only advantageous if you know that the glyph is unlikely to actually be rendered, otherwise it is slower because we'd do one query on the first CalcTextSize and one query on the first Draw.
|
||||
int LastUsedFrame; // 4 // // Record of that time this was bounds
|
||||
ImGuiID BakedId; // 4 // // Unique ID for this baked storage
|
||||
ImFont* OwnerFont; // 4-8 // in // Parent font
|
||||
@@ -3837,10 +3858,10 @@ struct ImFont
|
||||
ImGuiID FontId; // Unique identifier for the font
|
||||
float LegacySize; // 4 // in // Font size passed to AddFont(). Use for old code calling PushFont() expecting to use that size. (use ImGui::GetFontBaked() to get font baked at current bound size).
|
||||
ImVector<ImFontConfig*> Sources; // 16 // in // List of sources. Pointers within OwnerAtlas->Sources[]
|
||||
ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...').
|
||||
ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...'). If you ever want to temporarily swap this for an alternative/dummy char, make sure to clear EllipsisAutoBake.
|
||||
ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?')
|
||||
ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/8192/8]; // 1 bytes if ImWchar=ImWchar16, 16 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
|
||||
bool EllipsisAutoBake; // 1 // // Mark when the "..." glyph needs to be generated.
|
||||
ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/8192/8]; // 1 bytes if ImWchar=ImWchar16, 17 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 8K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
|
||||
bool EllipsisAutoBake; // 1 // // Mark when the "..." glyph (== EllipsisChar) needs to be generated by combining multiple '.'.
|
||||
ImGuiStorage RemapPairs; // 16 // // Remapping pairs when using AddRemapChar(), otherwise empty.
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
float Scale; // 4 // in // Legacy base font scale (~1.0f), multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
|
||||
@@ -3923,7 +3944,7 @@ struct ImGuiViewport
|
||||
void* PlatformHandle; // void* to hold higher-level, platform window handle (e.g. HWND, GLFWWindow*, SDL_Window*)
|
||||
void* PlatformHandleRaw; // void* to hold lower-level, platform-native window handle (under Win32 this is expected to be a HWND, unused for other platforms)
|
||||
|
||||
ImGuiViewport() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiViewport() { memset((void*)this, 0, sizeof(*this)); }
|
||||
|
||||
// Helpers
|
||||
ImVec2 GetCenter() const { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); }
|
||||
@@ -3945,7 +3966,7 @@ struct ImGuiPlatformIO
|
||||
|
||||
// Optional: Access OS clipboard
|
||||
// (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures)
|
||||
const char* (*Platform_GetClipboardTextFn)(ImGuiContext* ctx);
|
||||
const char* (*Platform_GetClipboardTextFn)(ImGuiContext* ctx); // Should return NULL on failure (e.g. clipboard data is not text).
|
||||
void (*Platform_SetClipboardTextFn)(ImGuiContext* ctx, const char* text);
|
||||
void* Platform_ClipboardUserData;
|
||||
|
||||
@@ -4000,7 +4021,7 @@ struct ImGuiPlatformImeData
|
||||
float InputLineHeight; // Line height (for IME).
|
||||
ImGuiID ViewportId; // ID of platform window/viewport.
|
||||
|
||||
ImGuiPlatformImeData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiPlatformImeData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -4022,19 +4043,21 @@ namespace ImGui
|
||||
inline void PopButtonRepeat() { PopItemFlag(); }
|
||||
inline void PushTabStop(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); }
|
||||
inline void PopTabStop() { PopItemFlag(); }
|
||||
// You do not need those functions! See #7838 on GitHub for more info.
|
||||
IMGUI_API ImVec2 GetContentRegionMax(); // Content boundaries max (e.g. window boundaries including scrolling, or current column boundaries). You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
|
||||
IMGUI_API ImVec2 GetWindowContentRegionMin(); // Content boundaries min for the window (roughly (0,0)-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
|
||||
IMGUI_API ImVec2 GetWindowContentRegionMax(); // Content boundaries max for the window (roughly (0,0)+Size-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
|
||||
// OBSOLETED in 1.90.0 (from September 2023)
|
||||
inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags window_flags = 0) { return BeginChild(id, size, ImGuiChildFlags_FrameStyle, window_flags); }
|
||||
inline void EndChildFrame() { EndChild(); }
|
||||
//inline bool BeginChild(const char* str_id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags){ return BeginChild(str_id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
//inline bool BeginChild(ImGuiID id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags) { return BeginChild(id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
inline void ShowStackToolWindow(bool* p_open = NULL) { ShowIDStackToolWindow(p_open); }
|
||||
IMGUI_API bool Combo(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int popup_max_height_in_items = -1);
|
||||
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int height_in_items = -1);
|
||||
|
||||
// Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE)
|
||||
// OBSOLETED in 1.90.0 (from September 2023)
|
||||
//inline bool BeginChild(const char* str_id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags) { return BeginChild(str_id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
//inline bool BeginChild(ImGuiID id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags) { return BeginChild(id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
//inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0) { return BeginChild(id, size, ImGuiChildFlags_FrameStyle, flags); }
|
||||
//inline void EndChildFrame() { EndChild(); }
|
||||
//inline void ShowStackToolWindow(bool* p_open = NULL) { ShowIDStackToolWindow(p_open); }
|
||||
// OBSOLETED in 1.89.7 (from June 2023)
|
||||
//IMGUI_API void SetItemAllowOverlap(); // Use SetNextItemAllowOverlap() _before_ item.
|
||||
//-- OBSOLETED in 1.89.4 (from March 2023)
|
||||
@@ -4144,10 +4167,12 @@ typedef ImFontAtlasRect ImFontAtlasCustomRect;
|
||||
//typedef ImGuiKeyChord ImGuiKeyModFlags; // == int
|
||||
//enum ImGuiKeyModFlags_ { ImGuiKeyModFlags_None = 0, ImGuiKeyModFlags_Ctrl = ImGuiMod_Ctrl, ImGuiKeyModFlags_Shift = ImGuiMod_Shift, ImGuiKeyModFlags_Alt = ImGuiMod_Alt, ImGuiKeyModFlags_Super = ImGuiMod_Super };
|
||||
|
||||
#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // OBSOLETED IN 1.90 (now using C++11 standard version)
|
||||
//#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // OBSOLETED IN 1.90 (now using C++11 standard version)
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
#define IM_ARRAYSIZE IM_COUNTOF // RENAMED IN 1.92.6: IM_ARRAYSIZE -> IM_COUNTOF
|
||||
|
||||
// RENAMED IMGUI_DISABLE_METRICS_WINDOW > IMGUI_DISABLE_DEBUG_TOOLS in 1.88 (from June 2022)
|
||||
#ifdef IMGUI_DISABLE_METRICS_WINDOW
|
||||
#error IMGUI_DISABLE_METRICS_WINDOW was renamed to IMGUI_DISABLE_DEBUG_TOOLS, please use new name.
|
||||
|
||||
+112
-82
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.5
|
||||
// dear imgui, v1.92.6
|
||||
// (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.
|
||||
@@ -60,7 +60,7 @@ Index of this file:
|
||||
#include <limits.h> // INT_MIN, INT_MAX
|
||||
|
||||
// Enable SSE intrinsics if available
|
||||
#if (defined __SSE__ || defined __x86_64__ || defined _M_X64 || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))) && !defined(IMGUI_DISABLE_SSE)
|
||||
#if (defined __SSE__ || defined __x86_64__ || defined _M_X64 || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))) && !defined(IMGUI_DISABLE_SSE) && !defined(_M_ARM64) && !defined(_M_ARM64EC)
|
||||
#define IMGUI_ENABLE_SSE
|
||||
#include <immintrin.h>
|
||||
#if (defined __AVX__ || defined __SSE4_2__)
|
||||
@@ -106,6 +106,7 @@ Index of this file:
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion" // warning: conversion to 'xxxx' from 'xxxx' may change the sign of the result
|
||||
#endif
|
||||
|
||||
// In 1.89.4, we moved the implementation of "courtesy maths operators" from imgui_internal.h in imgui.h
|
||||
@@ -276,11 +277,9 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
||||
#define IM_MEMALIGN(_OFF,_ALIGN) (((_OFF) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align e.g. IM_ALIGN(0,4)=0, IM_ALIGN(1,4)=4, IM_ALIGN(4,4)=4, IM_ALIGN(5,4)=8
|
||||
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
|
||||
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
|
||||
#define IM_TRUNC(_VAL) ((float)(int)(_VAL)) // ImTrunc() is not inlined in MSVC debug builds
|
||||
#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) //
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
#define IM_FLOOR IM_TRUNC // [OBSOLETE] Renamed in 1.90.0 (Sept 2023)
|
||||
#endif
|
||||
#define IM_TRUNC(_VAL) ((float)(int)(_VAL)) // Positive values only! ImTrunc() is not inlined in MSVC debug builds
|
||||
#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) // Positive values only!
|
||||
//#define IM_FLOOR IM_TRUNC // [OBSOLETE] Renamed in 1.90.0 (Sept 2023)
|
||||
|
||||
// Hint for branch prediction
|
||||
#if (defined(__cplusplus) && (__cplusplus >= 202002L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 202002L))
|
||||
@@ -335,7 +334,6 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
||||
#define IM_PRIu64 "llu"
|
||||
#define IM_PRIX64 "llX"
|
||||
#endif
|
||||
#define IM_TEXTUREID_TO_U64(_TEXID) ((ImU64)(intptr_t)(_TEXID))
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Generic helpers
|
||||
@@ -442,6 +440,16 @@ IMGUI_API ImVec2 ImFontCalcTextSizeEx(ImFont* font, float size, float max
|
||||
IMGUI_API const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* text, const char* text_end, float wrap_width, ImDrawTextFlags flags = 0);
|
||||
IMGUI_API const char* ImTextCalcWordWrapNextLineStart(const char* text, const char* text_end, ImDrawTextFlags flags = 0); // trim trailing space and find beginning of next line
|
||||
|
||||
// Character classification for word-wrapping logic
|
||||
enum ImWcharClass
|
||||
{
|
||||
ImWcharClass_Blank, ImWcharClass_Punct, ImWcharClass_Other
|
||||
};
|
||||
IMGUI_API void ImTextInitClassifiers();
|
||||
IMGUI_API void ImTextClassifierClear(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class);
|
||||
IMGUI_API void ImTextClassifierSetCharClass(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class, unsigned int c);
|
||||
IMGUI_API void ImTextClassifierSetCharClassFromStr(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class, const char* s);
|
||||
|
||||
// Helpers: File System
|
||||
#ifdef IMGUI_DISABLE_FILE_FUNCTIONS
|
||||
#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
|
||||
@@ -518,7 +526,7 @@ inline ImVec2 ImTrunc(const ImVec2& v) { return
|
||||
inline float ImFloor(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
|
||||
inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); }
|
||||
inline float ImTrunc64(float f) { return (float)(ImS64)(f); }
|
||||
inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); }
|
||||
inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); } // FIXME: Positive values only.
|
||||
inline int ImModPositive(int a, int b) { return (a + b) % b; }
|
||||
inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
|
||||
inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
|
||||
@@ -602,7 +610,6 @@ struct IMGUI_API ImRect
|
||||
void TranslateY(float dy) { Min.y += dy; Max.y += dy; }
|
||||
void ClipWith(const ImRect& r) { Min = ImMax(Min, r.Min); Max = ImMin(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display.
|
||||
void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped.
|
||||
void Floor() { Min.x = IM_TRUNC(Min.x); Min.y = IM_TRUNC(Min.y); Max.x = IM_TRUNC(Max.x); Max.y = IM_TRUNC(Max.y); }
|
||||
bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
|
||||
ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); }
|
||||
const ImVec4& AsVec4() const { return *(const ImVec4*)&Min.x; }
|
||||
@@ -636,15 +643,15 @@ typedef ImU32* ImBitArrayPtr; // Name for use in structs
|
||||
template<int BITCOUNT, int OFFSET = 0>
|
||||
struct ImBitArray
|
||||
{
|
||||
ImU32 Storage[(BITCOUNT + 31) >> 5];
|
||||
ImU32 Data[(BITCOUNT + 31) >> 5];
|
||||
ImBitArray() { ClearAllBits(); }
|
||||
void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); }
|
||||
void SetAllBits() { memset(Storage, 255, sizeof(Storage)); }
|
||||
bool TestBit(int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Storage, n); }
|
||||
void SetBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Storage, n); }
|
||||
void ClearBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArrayClearBit(Storage, n); }
|
||||
void SetBitRange(int n, int n2) { n += OFFSET; n2 += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT && n2 > n && n2 <= BITCOUNT); ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2)
|
||||
bool operator[](int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Storage, n); }
|
||||
void ClearAllBits() { memset(Data, 0, sizeof(Data)); }
|
||||
void SetAllBits() { memset(Data, 255, sizeof(Data)); }
|
||||
bool TestBit(int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Data, n); }
|
||||
void SetBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Data, n); }
|
||||
void ClearBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArrayClearBit(Data, n); }
|
||||
void SetBitRange(int n, int n2) { n += OFFSET; n2 += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT && n2 > n && n2 <= BITCOUNT); ImBitArraySetBitRange(Data, n, n2); } // Works on range [n..n2)
|
||||
bool operator[](int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Data, n); }
|
||||
};
|
||||
|
||||
// Helper: ImBitVector
|
||||
@@ -701,7 +708,7 @@ struct ImSpanAllocator
|
||||
int Offsets[CHUNKS];
|
||||
int Sizes[CHUNKS];
|
||||
|
||||
ImSpanAllocator() { memset(this, 0, sizeof(*this)); }
|
||||
ImSpanAllocator() { memset((void*)this, 0, sizeof(*this)); }
|
||||
inline void Reserve(int n, size_t sz, int a=4) { IM_ASSERT(n == CurrIdx && n < CHUNKS); CurrOff = IM_MEMALIGN(CurrOff, a); Offsets[n] = CurrOff; Sizes[n] = (int)sz; CurrIdx++; CurrOff += (int)sz; }
|
||||
inline int GetArenaSizeInBytes() { return CurrOff; }
|
||||
inline void SetArenaBasePtr(void* base_ptr) { BasePtr = (char*)base_ptr; }
|
||||
@@ -712,10 +719,10 @@ struct ImSpanAllocator
|
||||
};
|
||||
|
||||
// Helper: ImStableVector<>
|
||||
// Allocating chunks of BLOCK_SIZE items. Objects pointers are never invalidated when growing, only by clear().
|
||||
// Allocating chunks of BLOCKSIZE items. Objects pointers are never invalidated when growing, only by clear().
|
||||
// Important: does not destruct anything!
|
||||
// Implemented only the minimum set of functions we need for it.
|
||||
template<typename T, int BLOCK_SIZE>
|
||||
template<typename T, int BLOCKSIZE>
|
||||
struct ImStableVector
|
||||
{
|
||||
int Size = 0;
|
||||
@@ -729,19 +736,19 @@ struct ImStableVector
|
||||
inline void resize(int new_size) { if (new_size > Capacity) reserve(new_size); Size = new_size; }
|
||||
inline void reserve(int new_cap)
|
||||
{
|
||||
new_cap = IM_MEMALIGN(new_cap, BLOCK_SIZE);
|
||||
int old_count = Capacity / BLOCK_SIZE;
|
||||
int new_count = new_cap / BLOCK_SIZE;
|
||||
new_cap = IM_MEMALIGN(new_cap, BLOCKSIZE);
|
||||
int old_count = Capacity / BLOCKSIZE;
|
||||
int new_count = new_cap / BLOCKSIZE;
|
||||
if (new_count <= old_count)
|
||||
return;
|
||||
Blocks.resize(new_count);
|
||||
for (int n = old_count; n < new_count; n++)
|
||||
Blocks[n] = (T*)IM_ALLOC(sizeof(T) * BLOCK_SIZE);
|
||||
Blocks[n] = (T*)IM_ALLOC(sizeof(T) * BLOCKSIZE);
|
||||
Capacity = new_cap;
|
||||
}
|
||||
inline T& operator[](int i) { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCK_SIZE][i % BLOCK_SIZE]; }
|
||||
inline const T& operator[](int i) const { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCK_SIZE][i % BLOCK_SIZE]; }
|
||||
inline T* push_back(const T& v) { int i = Size; IM_ASSERT(i >= 0); if (Size == Capacity) reserve(Capacity + BLOCK_SIZE); void* ptr = &Blocks[i / BLOCK_SIZE][i % BLOCK_SIZE]; memcpy(ptr, &v, sizeof(v)); Size++; return (T*)ptr; }
|
||||
inline T& operator[](int i) { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCKSIZE][i % BLOCKSIZE]; }
|
||||
inline const T& operator[](int i) const { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCKSIZE][i % BLOCKSIZE]; }
|
||||
inline T* push_back(const T& v) { int i = Size; IM_ASSERT(i >= 0); if (Size == Capacity) reserve(Capacity + BLOCKSIZE); void* ptr = &Blocks[i / BLOCKSIZE][i % BLOCKSIZE]; memcpy(ptr, &v, sizeof(v)); Size++; return (T*)ptr; }
|
||||
};
|
||||
|
||||
// Helper: ImPool<>
|
||||
@@ -882,7 +889,7 @@ struct ImDrawDataBuilder
|
||||
ImVector<ImDrawList*>* Layers[2]; // Pointers to global layers for: regular, tooltip. LayersP[0] is owned by DrawData.
|
||||
ImVector<ImDrawList*> LayerData1;
|
||||
|
||||
ImDrawDataBuilder() { memset(this, 0, sizeof(*this)); }
|
||||
ImDrawDataBuilder() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImFontStackData
|
||||
@@ -956,7 +963,6 @@ enum ImGuiDataTypePrivate_
|
||||
enum ImGuiItemFlagsPrivate_
|
||||
{
|
||||
// Controlled by user
|
||||
ImGuiItemFlags_Disabled = 1 << 10, // false // Disable interactions (DOES NOT affect visuals. DO NOT mix direct use of this with BeginDisabled(). See BeginDisabled()/EndDisabled() for full disable feature, and github #211).
|
||||
ImGuiItemFlags_ReadOnly = 1 << 11, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
|
||||
ImGuiItemFlags_MixedValue = 1 << 12, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets)
|
||||
ImGuiItemFlags_NoWindowHoverableCheck = 1 << 13, // false // Disable hoverable check in ItemHoverable()
|
||||
@@ -1158,7 +1164,7 @@ struct IMGUI_API ImGuiComboPreviewData
|
||||
float BackupPrevLineTextBaseOffset;
|
||||
ImGuiLayoutType BackupLayout;
|
||||
|
||||
ImGuiComboPreviewData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiComboPreviewData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Stacked storage data for BeginGroup()/EndGroup()
|
||||
@@ -1192,7 +1198,7 @@ struct IMGUI_API ImGuiMenuColumns
|
||||
ImU16 OffsetMark;
|
||||
ImU16 Widths[4]; // Width of: Icon, Label, Shortcut, Mark (accumulators for current frame)
|
||||
|
||||
ImGuiMenuColumns() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiMenuColumns() { memset((void*)this, 0, sizeof(*this)); }
|
||||
void Update(float spacing, bool window_reappearing);
|
||||
float DeclColumns(float w_icon, float w_label, float w_shortcut, float w_mark);
|
||||
void CalcNextTotalWidth(bool update_offsets);
|
||||
@@ -1204,7 +1210,7 @@ struct IMGUI_API ImGuiInputTextDeactivatedState
|
||||
ImGuiID ID; // widget id owning the text state (which just got deactivated)
|
||||
ImVector<char> TextA; // text buffer
|
||||
|
||||
ImGuiInputTextDeactivatedState() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiInputTextDeactivatedState() { memset((void*)this, 0, sizeof(*this)); }
|
||||
void ClearFreeMemory() { ID = 0; TextA.clear(); }
|
||||
};
|
||||
|
||||
@@ -1228,7 +1234,7 @@ struct IMGUI_API ImGuiInputTextState
|
||||
ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set.
|
||||
ImGuiID ID; // widget id owning the text state
|
||||
int TextLen; // UTF-8 length of the string in TextA (in bytes)
|
||||
const char* TextSrc; // == TextA.Data unless read-only, in which case == buf passed to InputText(). Field only set and valid _inside_ the call InputText() call.
|
||||
const char* TextSrc; // == TextA.Data unless read-only, in which case == buf passed to InputText(). For _ReadOnly fields, pointer will be null outside the InputText() call.
|
||||
ImVector<char> TextA; // main UTF8 buffer. TextA.Size is a buffer size! Should always be >= buf_size passed by user (and of course >= CurLenA + 1).
|
||||
ImVector<char> TextToRevertTo; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered)
|
||||
ImVector<char> CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack
|
||||
@@ -1262,6 +1268,7 @@ struct IMGUI_API ImGuiInputTextState
|
||||
int GetCursorPos() const;
|
||||
int GetSelectionStart() const;
|
||||
int GetSelectionEnd() const;
|
||||
void SetSelection(int start, int end);
|
||||
void SelectAll();
|
||||
|
||||
// Reload user buf (WIP #2890)
|
||||
@@ -1329,18 +1336,19 @@ struct ImGuiNextWindowData
|
||||
ImVec2 MenuBarOffsetMinVal; // (Always on) This is not exposed publicly, so we don't clear it and it doesn't have a corresponding flag (could we? for consistency?)
|
||||
ImGuiWindowRefreshFlags RefreshFlagsVal;
|
||||
|
||||
ImGuiNextWindowData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiNextWindowData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
inline void ClearFlags() { HasFlags = ImGuiNextWindowDataFlags_None; }
|
||||
};
|
||||
|
||||
enum ImGuiNextItemDataFlags_
|
||||
{
|
||||
ImGuiNextItemDataFlags_None = 0,
|
||||
ImGuiNextItemDataFlags_HasWidth = 1 << 0,
|
||||
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
|
||||
ImGuiNextItemDataFlags_HasShortcut = 1 << 2,
|
||||
ImGuiNextItemDataFlags_HasRefVal = 1 << 3,
|
||||
ImGuiNextItemDataFlags_HasStorageID = 1 << 4,
|
||||
ImGuiNextItemDataFlags_None = 0,
|
||||
ImGuiNextItemDataFlags_HasWidth = 1 << 0,
|
||||
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
|
||||
ImGuiNextItemDataFlags_HasShortcut = 1 << 2,
|
||||
ImGuiNextItemDataFlags_HasRefVal = 1 << 3,
|
||||
ImGuiNextItemDataFlags_HasStorageID = 1 << 4,
|
||||
ImGuiNextItemDataFlags_HasColorMarker = 1 << 5,
|
||||
};
|
||||
|
||||
struct ImGuiNextItemData
|
||||
@@ -1358,8 +1366,9 @@ struct ImGuiNextItemData
|
||||
ImU8 OpenCond; // Set by SetNextItemOpen()
|
||||
ImGuiDataTypeStorage RefVal; // Not exposed yet, for ImGuiInputTextFlags_ParseEmptyAsRefVal
|
||||
ImGuiID StorageId; // Set by SetNextItemStorageID()
|
||||
ImU32 ColorMarker; // Set by SetNextItemColorMarker(). Not exposed yet, supported by DragScalar,SliderScalar and for ImGuiSliderFlags_ColorMarkers.
|
||||
|
||||
ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; }
|
||||
ImGuiNextItemData() { memset((void*)this, 0, sizeof(*this)); SelectionUserData = -1; }
|
||||
inline void ClearFlags() { HasFlags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()!
|
||||
};
|
||||
|
||||
@@ -1376,7 +1385,7 @@ struct ImGuiLastItemData
|
||||
ImRect ClipRect; // Clip rectangle at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasClipRect) is set..
|
||||
ImGuiKeyChord Shortcut; // Shortcut at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasShortcut) is set..
|
||||
|
||||
ImGuiLastItemData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiLastItemData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Store data emitted by TreeNode() for usage by TreePop()
|
||||
@@ -1409,7 +1418,7 @@ struct IMGUI_API ImGuiErrorRecoveryState
|
||||
short SizeOfBeginPopupStack;
|
||||
short SizeOfDisabledStack;
|
||||
|
||||
ImGuiErrorRecoveryState() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiErrorRecoveryState() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Data saved for each window pushed into the stack
|
||||
@@ -1470,7 +1479,7 @@ struct ImGuiPopupData
|
||||
ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse)
|
||||
ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup
|
||||
|
||||
ImGuiPopupData() { memset(this, 0, sizeof(*this)); ParentNavLayer = OpenFrameCount = -1; }
|
||||
ImGuiPopupData() { memset((void*)this, 0, sizeof(*this)); ParentNavLayer = OpenFrameCount = -1; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1548,7 +1557,7 @@ struct ImGuiInputEvent
|
||||
};
|
||||
bool AddedByTestEngine;
|
||||
|
||||
ImGuiInputEvent() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiInputEvent() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Input function taking an 'ImGuiID owner_id' argument defaults to (ImGuiKeyOwner_Any == 0) aka don't test ownership, which matches legacy behavior.
|
||||
@@ -1580,7 +1589,7 @@ struct ImGuiKeyRoutingTable
|
||||
ImVector<ImGuiKeyRoutingData> EntriesNext; // Double-buffer to avoid reallocation (could use a shared buffer)
|
||||
|
||||
ImGuiKeyRoutingTable() { Clear(); }
|
||||
void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Index); n++) Index[n] = -1; Entries.clear(); EntriesNext.clear(); }
|
||||
void Clear() { for (int n = 0; n < IM_COUNTOF(Index); n++) Index[n] = -1; Entries.clear(); EntriesNext.clear(); }
|
||||
};
|
||||
|
||||
// This extends ImGuiKeyData but only for named keys (legacy keys don't support the new features)
|
||||
@@ -1663,7 +1672,7 @@ struct ImGuiListClipperData
|
||||
int ItemsFrozen;
|
||||
ImVector<ImGuiListClipperRange> Ranges;
|
||||
|
||||
ImGuiListClipperData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiListClipperData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
void Reset(ImGuiListClipper* clipper) { ListClipper = clipper; StepNo = ItemsFrozen = 0; Ranges.resize(0); }
|
||||
};
|
||||
|
||||
@@ -1798,7 +1807,7 @@ struct IMGUI_API ImGuiTypingSelectState
|
||||
float LastRequestTime = 0.0f;
|
||||
bool SingleCharModeLock = false; // After a certain single char repeat count we lock into SingleCharMode. Two benefits: 1) buffer never fill, 2) we can provide an immediate SingleChar mode without timer elapsing.
|
||||
|
||||
ImGuiTypingSelectState() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiTypingSelectState() { memset((void*)this, 0, sizeof(*this)); }
|
||||
void Clear() { SearchBuffer[0] = 0; SingleCharModeLock = false; } // We preserve remaining data for easier debugging
|
||||
};
|
||||
|
||||
@@ -1834,7 +1843,7 @@ struct ImGuiOldColumnData
|
||||
ImGuiOldColumnFlags Flags; // Not exposed
|
||||
ImRect ClipRect;
|
||||
|
||||
ImGuiOldColumnData() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiOldColumnData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGuiOldColumns
|
||||
@@ -1855,7 +1864,7 @@ struct ImGuiOldColumns
|
||||
ImVector<ImGuiOldColumnData> Columns;
|
||||
ImDrawListSplitter Splitter;
|
||||
|
||||
ImGuiOldColumns() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiOldColumns() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1883,7 +1892,7 @@ struct ImGuiBoxSelectState
|
||||
ImRect BoxSelectRectPrev; // Selection rectangle in absolute coordinates (derived every frame from BoxSelectStartPosRel and MousePos)
|
||||
ImRect BoxSelectRectCurr;
|
||||
|
||||
ImGuiBoxSelectState() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiBoxSelectState() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1994,7 +2003,7 @@ struct ImGuiWindowSettings
|
||||
bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
|
||||
bool WantDelete; // Set to invalidate/delete the settings entry
|
||||
|
||||
ImGuiWindowSettings() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiWindowSettings() { memset((void*)this, 0, sizeof(*this)); }
|
||||
char* GetName() { return (char*)(this + 1); }
|
||||
};
|
||||
|
||||
@@ -2010,7 +2019,7 @@ struct ImGuiSettingsHandler
|
||||
void (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf); // Write: Output every entries into 'out_buf'
|
||||
void* UserData;
|
||||
|
||||
ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiSettingsHandler() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2049,7 +2058,9 @@ struct ImGuiLocEntry
|
||||
// - See 'Demo->Configuration->Error Handling' and ImGuiIO definitions for details on error handling.
|
||||
// - Read https://github.com/ocornut/imgui/wiki/Error-Handling for details on error handling.
|
||||
#ifndef IM_ASSERT_USER_ERROR
|
||||
#define IM_ASSERT_USER_ERROR(_EXPR,_MSG) do { if (!(_EXPR) && ImGui::ErrorLog(_MSG)) { IM_ASSERT((_EXPR) && _MSG); } } while (0) // Recoverable User Error
|
||||
#define IM_ASSERT_USER_ERROR(_EXPR,_MSG) do { if (!(_EXPR)) { if (ImGui::ErrorLog(_MSG)) { IM_ASSERT((_EXPR) && _MSG); } } } while (0) // Recoverable User Error
|
||||
#define IM_ASSERT_USER_ERROR_RET(_EXPR,_MSG) do { if (!(_EXPR)) { if (ImGui::ErrorLog(_MSG)) { IM_ASSERT((_EXPR) && _MSG); } return; } } while (0) // Recoverable User Error
|
||||
#define IM_ASSERT_USER_ERROR_RETV(_EXPR,_RETV,_MSG) do { if (!(_EXPR)) { if (ImGui::ErrorLog(_MSG)) { IM_ASSERT((_EXPR) && _MSG); } return _RETV; } } while (0) // Recoverable User Error
|
||||
#endif
|
||||
|
||||
// The error callback is currently not public, as it is expected that only advanced users will rely on it.
|
||||
@@ -2079,7 +2090,8 @@ enum ImGuiDebugLogFlags_
|
||||
|
||||
ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventError | ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventFont | ImGuiDebugLogFlags_EventInputRouting | ImGuiDebugLogFlags_EventDocking | ImGuiDebugLogFlags_EventViewport,
|
||||
ImGuiDebugLogFlags_OutputToTTY = 1 << 20, // Also send output to TTY
|
||||
ImGuiDebugLogFlags_OutputToTestEngine = 1 << 21, // Also send output to Test Engine
|
||||
ImGuiDebugLogFlags_OutputToDebugger = 1 << 21, // Also send output to Debugger Console [Windows only]
|
||||
ImGuiDebugLogFlags_OutputToTestEngine = 1 << 22, // Also send output to Dear ImGui Test Engine
|
||||
};
|
||||
|
||||
struct ImGuiDebugAllocEntry
|
||||
@@ -2096,7 +2108,7 @@ struct ImGuiDebugAllocInfo
|
||||
ImS16 LastEntriesIdx; // Current index in buffer
|
||||
ImGuiDebugAllocEntry LastEntriesBuf[6]; // Track last 6 frames that had allocations
|
||||
|
||||
ImGuiDebugAllocInfo() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiDebugAllocInfo() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGuiMetricsConfig
|
||||
@@ -2125,7 +2137,7 @@ struct ImGuiStackLevelInfo
|
||||
ImS8 DataType; // ImGuiDataType
|
||||
int DescOffset; // -1 or offset into parent's ResultsPathsBuf
|
||||
|
||||
ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); DataType = -1; DescOffset = -1; }
|
||||
ImGuiStackLevelInfo() { memset((void*)this, 0, sizeof(*this)); DataType = -1; DescOffset = -1; }
|
||||
};
|
||||
|
||||
struct ImGuiDebugItemPathQuery
|
||||
@@ -2138,7 +2150,7 @@ struct ImGuiDebugItemPathQuery
|
||||
ImGuiTextBuffer ResultsDescBuf;
|
||||
ImGuiTextBuffer ResultPathBuf;
|
||||
|
||||
ImGuiDebugItemPathQuery() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiDebugItemPathQuery() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// State for ID Stack tool queries
|
||||
@@ -2149,7 +2161,7 @@ struct ImGuiIDStackTool
|
||||
int LastActiveFrame;
|
||||
float CopyToClipboardLastTime;
|
||||
|
||||
ImGuiIDStackTool() { memset(this, 0, sizeof(*this)); LastActiveFrame = -1; OptHexEncodeNonAsciiChars = true; CopyToClipboardLastTime = -FLT_MAX; }
|
||||
ImGuiIDStackTool() { memset((void*)this, 0, sizeof(*this)); LastActiveFrame = -1; OptHexEncodeNonAsciiChars = true; CopyToClipboardLastTime = -FLT_MAX; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2167,7 +2179,7 @@ struct ImGuiContextHook
|
||||
ImGuiContextHookCallback Callback;
|
||||
void* UserData;
|
||||
|
||||
ImGuiContextHook() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiContextHook() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2340,7 +2352,7 @@ struct ImGuiContext
|
||||
ImGuiDir NavMoveDirForDebug;
|
||||
ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename?
|
||||
ImRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring.
|
||||
ImRect NavScoringNoClipRect; // Some nav operations (such as PageUp/PageDown) enforce a region which clipper will attempt to always keep submitted
|
||||
ImRect NavScoringNoClipRect; // Some nav operations (such as PageUp/PageDown) enforce a region which clipper will attempt to always keep submitted. Unset/invalid if inverted.
|
||||
int NavScoringDebugCount; // Metrics for debugging
|
||||
int NavTabbingDir; // Generally -1 or +1, 0 when tabbing without a nav id
|
||||
int NavTabbingCounter; // >0 when counting items for tabbing
|
||||
@@ -2357,10 +2369,15 @@ struct ImGuiContext
|
||||
bool NavJustMovedToIsTabbing; // Copy of ImGuiNavMoveFlags_IsTabbing. Maybe we should store whole flags.
|
||||
bool NavJustMovedToHasSelectionData; // Copy of move result's ItemFlags & ImGuiItemFlags_HasSelectionUserData). Maybe we should just store ImGuiNavItemData.
|
||||
|
||||
// Navigation: Windowing (Ctrl+Tab for list, or Menu button + keys or directional pads to move/resize)
|
||||
// Navigation: extra config options (will be made public eventually)
|
||||
// - Tabbing (Tab, Shift+Tab) and Windowing (Ctrl+Tab, Ctrl+Shift+Tab) are enabled REGARDLESS of ImGuiConfigFlags_NavEnableKeyboard being set.
|
||||
// - Ctrl+Tab is reconfigurable because it is the only shortcut that may be polled when no window are focused. It also doesn't work e.g. Web platforms.
|
||||
bool ConfigNavEnableTabbing; // = true. Enable tabbing (Tab, Shift+Tab). PLEASE LET ME KNOW IF YOU USE THIS.
|
||||
bool ConfigNavWindowingWithGamepad; // = true. Enable Ctrl+Tab by holding ImGuiKey_GamepadFaceLeft (== ImGuiKey_NavGamepadMenu). When false, the button may still be used to toggle Menu layer.
|
||||
ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiKey_Tab on OS X). For reconfiguration (see #4828)
|
||||
ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiKey_Tab on OS X). Set to 0 to disable. For reconfiguration (see #4828)
|
||||
ImGuiKeyChord ConfigNavWindowingKeyPrev; // = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiMod_Shift | ImGuiKey_Tab on OS X)
|
||||
|
||||
// Navigation: Windowing (Ctrl+Tab for list, or Menu button + keys or directional pads to move/resize)
|
||||
ImGuiWindow* NavWindowingTarget; // Target window when doing Ctrl+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most!
|
||||
ImGuiWindow* NavWindowingTargetAnim; // Record of last valid NavWindowingTarget until DimBgRatio and NavWindowingHighlightAlpha becomes 0.0f, so the fade-out can stay on it.
|
||||
ImGuiWindow* NavWindowingListWindow; // Internal window actually listing the Ctrl+Tab contents
|
||||
@@ -2562,6 +2579,8 @@ struct ImGuiContext
|
||||
// [SECTION] ImGuiWindowTempData, ImGuiWindow
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define IMGUI_WINDOW_HARD_MIN_SIZE 4.0f
|
||||
|
||||
// Transient per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the DC variable name in ImGuiWindow.
|
||||
// (That's theory, in practice the delimitation between ImGuiWindow and ImGuiWindowTempData is quite tenuous and could be reconsidered..)
|
||||
// (This doesn't need a constructor because we zero-clear it as part of ImGuiWindow and all frame-temporary data are setup on Begin)
|
||||
@@ -2612,6 +2631,7 @@ struct IMGUI_API ImGuiWindowTempData
|
||||
// Local parameters stacks
|
||||
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
|
||||
float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window).
|
||||
float ItemWidthDefault;
|
||||
float TextWrapPos; // Current text wrap pos.
|
||||
ImVector<float> ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth)
|
||||
ImVector<float> TextWrapPosStack; // Store text wrap pos to restore (attention: .back() is not == TextWrapPos)
|
||||
@@ -2702,7 +2722,6 @@ struct IMGUI_API ImGuiWindow
|
||||
|
||||
int LastFrameActive; // Last frame number the window was Active.
|
||||
float LastTimeActive; // Last timestamp the window was Active (using float as we don't need high precision there)
|
||||
float ItemWidthDefault;
|
||||
ImGuiStorage StateStorage;
|
||||
ImVector<ImGuiOldColumns> ColumnsStorage;
|
||||
float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
|
||||
@@ -2778,7 +2797,7 @@ struct ImGuiTabItem
|
||||
ImGuiTabItemFlags Flags;
|
||||
int LastFrameVisible;
|
||||
int LastFrameSelected; // This allows us to infer an ordered list of the last activated tabs with little maintenance
|
||||
float Offset; // Position relative to beginning of tab
|
||||
float Offset; // Position relative to beginning of tab bar
|
||||
float Width; // Width currently displayed
|
||||
float ContentWidth; // Width of label + padding, stored during BeginTabItem() call (misnamed as "Content" would normally imply width of label only)
|
||||
float RequestedWidth; // Width optionally requested by caller, -1.0f is unused
|
||||
@@ -2787,7 +2806,7 @@ struct ImGuiTabItem
|
||||
ImS16 IndexDuringLayout; // Index only used during TabBarLayout(). Tabs gets reordered so 'Tabs[n].IndexDuringLayout == n' but may mismatch during additions.
|
||||
bool WantClose; // Marked as closed by SetTabItemClosed()
|
||||
|
||||
ImGuiTabItem() { memset(this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; RequestedWidth = -1.0f; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; }
|
||||
ImGuiTabItem() { memset((void*)this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; RequestedWidth = -1.0f; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; }
|
||||
};
|
||||
|
||||
// Storage for a tab bar (sizeof() 160 bytes)
|
||||
@@ -2799,6 +2818,7 @@ struct IMGUI_API ImGuiTabBar
|
||||
ImGuiID ID; // Zero for tab-bars used by docking
|
||||
ImGuiID SelectedTabId; // Selected tab/window
|
||||
ImGuiID NextSelectedTabId; // Next selected tab/window. Will also trigger a scrolling animation
|
||||
ImGuiID NextScrollToTabId;
|
||||
ImGuiID VisibleTabId; // Can occasionally be != SelectedTabId (e.g. when previewing contents for Ctrl+Tab preview)
|
||||
int CurrFrameVisible;
|
||||
int PrevFrameVisible;
|
||||
@@ -2891,7 +2911,7 @@ struct ImGuiTableColumn
|
||||
|
||||
ImGuiTableColumn()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
StretchWeight = WidthRequest = -1.0f;
|
||||
NameOffset = -1;
|
||||
DisplayOrder = IndexWithinEnabledSet = -1;
|
||||
@@ -3052,7 +3072,7 @@ struct IMGUI_API ImGuiTable
|
||||
bool MemoryCompacted;
|
||||
bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
|
||||
|
||||
ImGuiTable() { memset(this, 0, sizeof(*this)); LastFrameActive = -1; }
|
||||
ImGuiTable() { memset((void*)this, 0, sizeof(*this)); LastFrameActive = -1; }
|
||||
~ImGuiTable() { IM_FREE(RawData); }
|
||||
};
|
||||
|
||||
@@ -3081,7 +3101,7 @@ struct IMGUI_API ImGuiTableTempData
|
||||
float HostBackupItemWidth; // Backup of OuterWindow->DC.ItemWidth at the end of BeginTable()
|
||||
int HostBackupItemWidthStackSize;//Backup of OuterWindow->DC.ItemWidthStack.Size at the end of BeginTable()
|
||||
|
||||
ImGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; }
|
||||
ImGuiTableTempData() { memset((void*)this, 0, sizeof(*this)); LastTimeActive = -1.0f; }
|
||||
};
|
||||
|
||||
// sizeof() ~ 16
|
||||
@@ -3118,7 +3138,7 @@ struct ImGuiTableSettings
|
||||
ImGuiTableColumnIdx ColumnsCountMax; // Maximum number of columns this settings instance can store, we can recycle a settings instance with lower number of columns but not higher
|
||||
bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
|
||||
|
||||
ImGuiTableSettings() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiTableSettings() { memset((void*)this, 0, sizeof(*this)); }
|
||||
ImGuiTableColumnSettings* GetColumnSettings() { return (ImGuiTableColumnSettings*)(this + 1); }
|
||||
};
|
||||
|
||||
@@ -3136,6 +3156,7 @@ namespace ImGui
|
||||
// - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
|
||||
IMGUI_API ImGuiIO& GetIO(ImGuiContext* ctx);
|
||||
IMGUI_API ImGuiPlatformIO& GetPlatformIO(ImGuiContext* ctx);
|
||||
inline float GetScale() { ImGuiContext& g = *GImGui; return g.Style._MainScale; } // FIXME-DPI: I don't want to formalize this just yet. Because reasons. Please don't use.
|
||||
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);
|
||||
@@ -3194,6 +3215,12 @@ namespace ImGui
|
||||
IMGUI_API void Initialize();
|
||||
IMGUI_API void Shutdown(); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext().
|
||||
|
||||
// Context name & generic context hooks
|
||||
IMGUI_API void SetContextName(ImGuiContext* ctx, const char* name);
|
||||
IMGUI_API ImGuiID AddContextHook(ImGuiContext* ctx, const ImGuiContextHook* hook);
|
||||
IMGUI_API void RemoveContextHook(ImGuiContext* ctx, ImGuiID hook_to_remove);
|
||||
IMGUI_API void CallContextHooks(ImGuiContext* ctx, ImGuiContextHookType type);
|
||||
|
||||
// NewFrame
|
||||
IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs);
|
||||
IMGUI_API void UpdateHoveredWindowAndCaptureFlags(const ImVec2& mouse_pos);
|
||||
@@ -3203,12 +3230,8 @@ namespace ImGui
|
||||
IMGUI_API void UpdateMouseMovingWindowNewFrame();
|
||||
IMGUI_API void UpdateMouseMovingWindowEndFrame();
|
||||
|
||||
// Generic context hooks
|
||||
IMGUI_API ImGuiID AddContextHook(ImGuiContext* context, const ImGuiContextHook* hook);
|
||||
IMGUI_API void RemoveContextHook(ImGuiContext* context, ImGuiID hook_to_remove);
|
||||
IMGUI_API void CallContextHooks(ImGuiContext* context, ImGuiContextHookType type);
|
||||
|
||||
// Viewports
|
||||
inline ImGuiViewport* GetWindowViewport() { return GetMainViewport(); } // For code consistency. This is public API in docking branch.
|
||||
IMGUI_API void ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale);
|
||||
IMGUI_API void SetWindowViewport(ImGuiWindow* window, ImGuiViewportP* viewport);
|
||||
|
||||
@@ -3246,7 +3269,6 @@ namespace ImGui
|
||||
|
||||
// Basic Accessors
|
||||
inline ImGuiItemStatusFlags GetItemStatusFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; }
|
||||
inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.ItemFlags; }
|
||||
inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; }
|
||||
inline ImGuiID GetFocusID() { ImGuiContext& g = *GImGui; return g.NavId; }
|
||||
IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window);
|
||||
@@ -3302,6 +3324,7 @@ namespace ImGui
|
||||
IMGUI_API ImGuiWindow* FindBlockingModal(ImGuiWindow* window);
|
||||
IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window);
|
||||
IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy);
|
||||
IMGUI_API ImGuiMouseButton GetMouseButtonFromPopupFlags(ImGuiPopupFlags flags);
|
||||
|
||||
// Tooltips
|
||||
IMGUI_API bool BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags);
|
||||
@@ -3509,6 +3532,7 @@ namespace ImGui
|
||||
IMGUI_API void TableMergeDrawChannels(ImGuiTable* table);
|
||||
inline ImGuiTableInstanceData* TableGetInstanceData(ImGuiTable* table, int instance_no) { if (instance_no == 0) return &table->InstanceDataFirst; return &table->InstanceDataExtra[instance_no - 1]; }
|
||||
inline ImGuiID TableGetInstanceID(ImGuiTable* table, int instance_no) { return TableGetInstanceData(table, instance_no)->TableInstanceID; }
|
||||
IMGUI_API void TableFixDisplayOrder(ImGuiTable* table);
|
||||
IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table);
|
||||
IMGUI_API void TableSortSpecsBuild(ImGuiTable* table);
|
||||
IMGUI_API ImGuiSortDirection TableGetColumnNextSortDirection(ImGuiTableColumn* column);
|
||||
@@ -3524,6 +3548,7 @@ namespace ImGui
|
||||
IMGUI_API float TableCalcMaxColumnWidth(const ImGuiTable* table, int column_n);
|
||||
IMGUI_API void TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n);
|
||||
IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table);
|
||||
IMGUI_API void TableSetColumnDisplayOrder(ImGuiTable* table, int column_n, int dst_order);
|
||||
IMGUI_API void TableRemove(ImGuiTable* table);
|
||||
IMGUI_API void TableGcCompactTransientBuffers(ImGuiTable* table);
|
||||
IMGUI_API void TableGcCompactTransientBuffers(ImGuiTableTempData* table);
|
||||
@@ -3572,6 +3597,7 @@ namespace ImGui
|
||||
IMGUI_API void RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float ellipsis_max_x, const char* text, const char* text_end, const ImVec2* text_size_if_known);
|
||||
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool borders = true, float rounding = 0.0f);
|
||||
IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f);
|
||||
IMGUI_API void RenderColorComponentMarker(const ImRect& bb, ImU32 col, float rounding);
|
||||
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void RenderNavCursor(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFlags flags = ImGuiNavRenderCursorFlags_None); // Navigation highlight
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
@@ -3585,8 +3611,9 @@ namespace ImGui
|
||||
IMGUI_API void RenderBullet(ImDrawList* draw_list, ImVec2 pos, ImU32 col);
|
||||
IMGUI_API void RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz);
|
||||
IMGUI_API void RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col);
|
||||
IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding);
|
||||
IMGUI_API void RenderRectFilledInRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float fill_x0, float fill_x1, float rounding);
|
||||
IMGUI_API void RenderRectFilledWithHole(ImDrawList* draw_list, const ImRect& outer, const ImRect& inner, ImU32 col, float rounding);
|
||||
IMGUI_API ImDrawFlags CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRect& r_outer, float threshold);
|
||||
|
||||
// Widgets: Text
|
||||
IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0);
|
||||
@@ -3651,7 +3678,7 @@ namespace ImGui
|
||||
IMGUI_API void InputTextDeactivateHook(ImGuiID id);
|
||||
IMGUI_API bool TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, int buf_size, ImGuiInputTextFlags flags);
|
||||
IMGUI_API bool TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min = NULL, const void* p_clamp_max = NULL);
|
||||
inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); }
|
||||
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.
|
||||
@@ -3660,6 +3687,7 @@ namespace ImGui
|
||||
IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags);
|
||||
IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags);
|
||||
IMGUI_API void ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags flags);
|
||||
inline void SetNextItemColorMarker(ImU32 col) { ImGuiContext& g = *GImGui; g.NextItemData.HasFlags |= ImGuiNextItemDataFlags_HasColorMarker; g.NextItemData.ColorMarker = col; }
|
||||
|
||||
// Plot
|
||||
IMGUI_API int PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, const ImVec2& size_arg);
|
||||
@@ -3697,6 +3725,7 @@ namespace ImGui
|
||||
IMGUI_API bool DebugBreakButton(const char* label, const char* description_of_location);
|
||||
IMGUI_API void DebugBreakButtonTooltip(bool keyboard_only, const char* description_of_location);
|
||||
IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas);
|
||||
IMGUI_API ImU64 DebugTextureIDToU64(ImTextureID tex_id);
|
||||
IMGUI_API void DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* data_id, const void* data_id_end);
|
||||
IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns);
|
||||
IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label);
|
||||
@@ -3760,14 +3789,14 @@ struct ImFontLoader
|
||||
// FIXME: At this point the two other types of buffers may be managed by core to be consistent?
|
||||
size_t FontBakedSrcLoaderDataSize;
|
||||
|
||||
ImFontLoader() { memset(this, 0, sizeof(*this)); }
|
||||
ImFontLoader() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
#ifdef IMGUI_ENABLE_STB_TRUETYPE
|
||||
IMGUI_API const ImFontLoader* ImFontAtlasGetFontLoaderForStbTruetype();
|
||||
#endif
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
typedef ImFontLoader ImFontBuilderIO; // [renamed/changed in 1.92] The types are not actually compatible but we provide this as a compile-time error report helper.
|
||||
typedef ImFontLoader ImFontBuilderIO; // [renamed/changed in 1.92.0] The types are not actually compatible but we provide this as a compile-time error report helper.
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -3857,7 +3886,7 @@ struct ImFontAtlasBuilder
|
||||
ImFontAtlasRectId PackIdMouseCursors; // White pixel + mouse cursors. Also happen to be fallback in case of packing failure.
|
||||
ImFontAtlasRectId PackIdLinesTexData;
|
||||
|
||||
ImFontAtlasBuilder() { memset(this, 0, sizeof(*this)); FrameCount = -1; RectsIndexFreeListStart = -1; PackIdMouseCursors = PackIdLinesTexData = -1; }
|
||||
ImFontAtlasBuilder() { memset((void*)this, 0, sizeof(*this)); FrameCount = -1; RectsIndexFreeListStart = -1; PackIdMouseCursors = PackIdLinesTexData = -1; }
|
||||
};
|
||||
|
||||
IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
|
||||
@@ -3886,6 +3915,7 @@ IMGUI_API void ImFontAtlasFontSourceAddToFont(ImFontAtlas* atlas, I
|
||||
IMGUI_API void ImFontAtlasFontDestroySourceData(ImFontAtlas* atlas, ImFontConfig* src);
|
||||
IMGUI_API bool ImFontAtlasFontInitOutput(ImFontAtlas* atlas, ImFont* font); // Using FontDestroyOutput/FontInitOutput sequence useful notably if font loader params have changed
|
||||
IMGUI_API void ImFontAtlasFontDestroyOutput(ImFontAtlas* atlas, ImFont* font);
|
||||
IMGUI_API void ImFontAtlasFontRebuildOutput(ImFontAtlas* atlas, ImFont* font);
|
||||
IMGUI_API void ImFontAtlasFontDiscardBakes(ImFontAtlas* atlas, ImFont* font, int unused_frames);
|
||||
|
||||
IMGUI_API ImGuiID ImFontAtlasBakedGetId(ImGuiID font_id, float baked_size, float rasterizer_density);
|
||||
|
||||
Vendored
+315
-243
File diff suppressed because it is too large
Load Diff
Vendored
+208
-146
File diff suppressed because it is too large
Load Diff
Vendored
+493
-107
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.5
|
||||
// dear imgui, v1.92.6
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@@ -17,10 +17,11 @@ Index of this file:
|
||||
// [SECTION] ImFontAtlas: backend for stb_truetype
|
||||
// [SECTION] ImFontAtlas: glyph ranges helpers
|
||||
// [SECTION] ImFontGlyphRangesBuilder
|
||||
// [SECTION] ImFont
|
||||
// [SECTION] ImFontBaked, ImFont
|
||||
// [SECTION] ImGui Internal Render Helpers
|
||||
// [SECTION] Decompression code
|
||||
// [SECTION] Default font data (ProggyClean.ttf)
|
||||
// [SECTION] Default font data (ProggyForever.ttf)
|
||||
|
||||
*/
|
||||
|
||||
@@ -81,6 +82,7 @@ Index of this file:
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion" // warning: conversion to 'xxxx' from 'xxxx' may change the sign of the result
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -103,6 +105,7 @@ namespace IMGUI_STB_NAMESPACE
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4456) // declaration of 'xx' hides previous local declaration
|
||||
#pragma warning (disable: 6011) // (stb_rectpack) Dereferencing NULL pointer 'cur->next'.
|
||||
#pragma warning (disable: 5262) // (stb_truetype) implicit fall-through occurs here; are you missing a break statement?
|
||||
#pragma warning (disable: 6385) // (stb_truetype) Reading invalid data from 'buffer': the readable size is '_Old_3`kernel_width' bytes, but '3' bytes may be read.
|
||||
#pragma warning (disable: 28182) // (stb_rectpack) Dereferencing NULL pointer. 'cur' contains the same NULL value as 'cur->next' did.
|
||||
#endif
|
||||
@@ -389,11 +392,11 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
|
||||
ImDrawListSharedData::ImDrawListSharedData()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
InitialFringeScale = 1.0f;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(ArcFastVtx); i++)
|
||||
for (int i = 0; i < IM_COUNTOF(ArcFastVtx); i++)
|
||||
{
|
||||
const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(ArcFastVtx);
|
||||
const float a = ((float)i * 2 * IM_PI) / (float)IM_COUNTOF(ArcFastVtx);
|
||||
ArcFastVtx[i] = ImVec2(ImCos(a), ImSin(a));
|
||||
}
|
||||
ArcFastRadiusCutoff = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(IM_DRAWLIST_ARCFAST_SAMPLE_MAX, CircleSegmentMaxError);
|
||||
@@ -411,7 +414,7 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error)
|
||||
|
||||
IM_ASSERT(max_error > 0.0f);
|
||||
CircleSegmentMaxError = max_error;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(CircleSegmentCounts); i++)
|
||||
for (int i = 0; i < IM_COUNTOF(CircleSegmentCounts); i++)
|
||||
{
|
||||
const float radius = (float)i;
|
||||
CircleSegmentCounts[i] = (ImU8)((i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : IM_DRAWLIST_ARCFAST_SAMPLE_MAX);
|
||||
@@ -421,7 +424,7 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error)
|
||||
|
||||
ImDrawList::ImDrawList(ImDrawListSharedData* shared_data)
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
_SetDrawListSharedData(shared_data);
|
||||
}
|
||||
|
||||
@@ -444,10 +447,13 @@ void ImDrawList::_SetDrawListSharedData(ImDrawListSharedData* data)
|
||||
// In the majority of cases, you would want to call PushClipRect() and PushTexture() after this.
|
||||
void ImDrawList::_ResetForNewFrame()
|
||||
{
|
||||
// Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory.
|
||||
// Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory to match ImDrawCmdHeader.
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, ClipRect) == 0);
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, TexRef) == sizeof(ImVec4));
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureRef));
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, ClipRect) == offsetof(ImDrawCmdHeader, ClipRect));
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, TexRef) == offsetof(ImDrawCmdHeader, TexRef));
|
||||
IM_STATIC_ASSERT(offsetof(ImDrawCmd, VtxOffset) == offsetof(ImDrawCmdHeader, VtxOffset));
|
||||
if (_Splitter._Count > 1)
|
||||
_Splitter.Merge(this);
|
||||
|
||||
@@ -643,7 +649,7 @@ int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const
|
||||
{
|
||||
// Automatic segment count
|
||||
const int radius_idx = (int)(radius + 0.999999f); // ceil to never reduce accuracy
|
||||
if (radius_idx >= 0 && radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
|
||||
if (radius_idx >= 0 && radius_idx < IM_COUNTOF(_Data->CircleSegmentCounts))
|
||||
return _Data->CircleSegmentCounts[radius_idx]; // Use cached value
|
||||
else
|
||||
return IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError);
|
||||
@@ -2411,10 +2417,11 @@ void ImGui::ShadeVertsTransformPos(ImDrawList* draw_list, int vert_start_idx, in
|
||||
// FIXME-NEWATLAS: Oversample specification could be more dynamic. For now, favoring automatic selection.
|
||||
ImFontConfig::ImFontConfig()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
FontDataOwnedByAtlas = true;
|
||||
OversampleH = 0; // Auto == 1 or 2 depending on size
|
||||
OversampleV = 0; // Auto == 1
|
||||
ExtraSizeScale = 1.0f;
|
||||
GlyphMaxAdvanceX = FLT_MAX;
|
||||
RasterizerMultiply = 1.0f;
|
||||
RasterizerDensity = 1.0f;
|
||||
@@ -2513,6 +2520,8 @@ void ImTextureData::DestroyPixels()
|
||||
//-----------------------------------------------------------------------------
|
||||
// - ImFontAtlas::AddFont()
|
||||
// - ImFontAtlas::AddFontDefault()
|
||||
// - ImFontAtlas::AddFontDefaultBitmap()
|
||||
// - ImFontAtlas::AddFontDefaultVector()
|
||||
// - ImFontAtlas::AddFontFromFileTTF()
|
||||
// - ImFontAtlas::AddFontFromMemoryTTF()
|
||||
// - ImFontAtlas::AddFontFromMemoryCompressedTTF()
|
||||
@@ -2632,7 +2641,7 @@ static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3
|
||||
|
||||
ImFontAtlas::ImFontAtlas()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
TexDesiredFormat = ImTextureFormat_RGBA32;
|
||||
TexGlyphPadding = 1;
|
||||
TexMinWidth = 512;
|
||||
@@ -3028,6 +3037,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg_in)
|
||||
ImFontAtlasBuildInit(this);
|
||||
|
||||
// Create new font
|
||||
const bool is_first_font = (Fonts.Size == 0);
|
||||
ImFont* font;
|
||||
if (!font_cfg_in->MergeMode)
|
||||
{
|
||||
@@ -3040,8 +3050,9 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg_in)
|
||||
}
|
||||
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.
|
||||
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.
|
||||
font = font_cfg_in->DstFont ? font_cfg_in->DstFont : Fonts.back();
|
||||
ImFontAtlasFontDiscardBakes(this, font, 0); // Need to discard bakes if the font was already used, because baked->FontLoaderDatas[] will change size. (#9162)
|
||||
}
|
||||
|
||||
// Add to list
|
||||
@@ -3052,12 +3063,6 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg_in)
|
||||
font->Sources.push_back(font_cfg);
|
||||
ImFontAtlasBuildUpdatePointers(this); // Pointers to Sources are otherwise dangling after we called Sources.push_back().
|
||||
|
||||
if (font_cfg->FontDataOwnedByAtlas == false)
|
||||
{
|
||||
font_cfg->FontDataOwnedByAtlas = true;
|
||||
font_cfg->FontData = ImMemdup(font_cfg->FontData, (size_t)font_cfg->FontDataSize);
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
// We don't round cfg.SizePixels yet as relative size of merged fonts are used afterwards.
|
||||
if (font_cfg->GlyphExcludeRanges != NULL)
|
||||
@@ -3090,6 +3095,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg_in)
|
||||
}
|
||||
ImFontAtlasFontSourceAddToFont(this, font, font_cfg);
|
||||
|
||||
if (is_first_font)
|
||||
ImFontAtlasBuildNotifySetFont(this, NULL, font);
|
||||
return font;
|
||||
}
|
||||
|
||||
@@ -3108,32 +3115,72 @@ static void Decode85(const unsigned char* src, unsigned char* dst)
|
||||
}
|
||||
}
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
static const char* GetDefaultCompressedFontDataTTF(int* out_size);
|
||||
static const char* GetDefaultCompressedFontDataProggyClean(int* out_size);
|
||||
static const char* GetDefaultCompressedFontDataProggyForever(int* out_size);
|
||||
#endif
|
||||
|
||||
// Load embedded ProggyClean.ttf at size 13, disable oversampling
|
||||
// If you want a similar font which may be better scaled, consider using ProggyVector from the same author!
|
||||
ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
|
||||
// This duplicates some of the logic in UpdateFontsNewFrame() which is a bit chicken-and-eggy/tricky to extract due to variety of codepaths and possible initialization ordering.
|
||||
static float GetExpectedContextFontSize(ImGuiContext* ctx)
|
||||
{
|
||||
return ((ctx->Style.FontSizeBase > 0.0f) ? ctx->Style.FontSizeBase : 13.0f) * ctx->Style.FontScaleMain * ctx->Style.FontScaleDpi;
|
||||
}
|
||||
|
||||
// Legacy function with heuristic to select Pixel or Vector font.
|
||||
// The selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold at the time of adding the default font.
|
||||
// Prefer calling AddFontDefaultVector() or AddFontDefaultBitmap() based on your own logic.
|
||||
ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg)
|
||||
{
|
||||
if (OwnerContext == NULL || GetExpectedContextFontSize(OwnerContext) >= 15.0f)
|
||||
return AddFontDefaultVector(font_cfg);
|
||||
else
|
||||
return AddFontDefaultBitmap(font_cfg);
|
||||
}
|
||||
|
||||
// Load embedded ProggyClean.ttf. Default size 13, disable oversampling.
|
||||
// If you want a similar font which may be better scaled, consider using AddFontDefaultVector().
|
||||
ImFont* ImFontAtlas::AddFontDefaultBitmap(const ImFontConfig* font_cfg_template)
|
||||
{
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
|
||||
if (!font_cfg_template)
|
||||
{
|
||||
font_cfg.OversampleH = font_cfg.OversampleV = 1;
|
||||
font_cfg.PixelSnapH = true;
|
||||
}
|
||||
font_cfg.PixelSnapH = true; // Prevents sub-integer scaling factors at lower-level layers.
|
||||
if (font_cfg.SizePixels <= 0.0f)
|
||||
font_cfg.SizePixels = 13.0f * 1.0f;
|
||||
font_cfg.SizePixels = 13.0f; // This only serves (1) as a reference for GlyphOffset.y setting and (2) as a default for pre-1.92 backend.
|
||||
if (font_cfg.Name[0] == '\0')
|
||||
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf");
|
||||
ImFormatString(font_cfg.Name, IM_COUNTOF(font_cfg.Name), "ProggyClean.ttf");
|
||||
font_cfg.EllipsisChar = (ImWchar)0x0085;
|
||||
font_cfg.GlyphOffset.y += 1.0f * IM_TRUNC(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units
|
||||
font_cfg.GlyphOffset.y += 1.0f * (font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units
|
||||
|
||||
int ttf_compressed_size = 0;
|
||||
const char* ttf_compressed = GetDefaultCompressedFontDataTTF(&ttf_compressed_size);
|
||||
const char* ttf_compressed = GetDefaultCompressedFontDataProggyClean(&ttf_compressed_size);
|
||||
return AddFontFromMemoryCompressedTTF(ttf_compressed, ttf_compressed_size, font_cfg.SizePixels, &font_cfg);
|
||||
#else
|
||||
IM_ASSERT(0 && "AddFontDefault() disabled in this build.");
|
||||
IM_ASSERT(0 && "Function is disabled in this build.");
|
||||
IM_UNUSED(font_cfg_template);
|
||||
return NULL;
|
||||
#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
}
|
||||
|
||||
// Load a minimal version of ProggyForever, designed to match our good old ProggyClean, but nicely scalable.
|
||||
// (See build script in https://github.com/ocornut/proggyforever for details)
|
||||
ImFont* ImFontAtlas::AddFontDefaultVector(const ImFontConfig* font_cfg_template)
|
||||
{
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
|
||||
if (!font_cfg_template)
|
||||
font_cfg.PixelSnapH = true; // Precisely match ProggyClean, but prevents sub-integer scaling factors at lower-level layers.
|
||||
if (font_cfg.SizePixels <= 0.0f)
|
||||
font_cfg.SizePixels = 13.0f;
|
||||
if (font_cfg.Name[0] == '\0')
|
||||
ImFormatString(font_cfg.Name, IM_COUNTOF(font_cfg.Name), "ProggyForever.ttf");
|
||||
font_cfg.ExtraSizeScale *= 1.015f; // Match ProggyClean
|
||||
font_cfg.GlyphOffset.y += 0.5f * (font_cfg.SizePixels / 16.0f); // Closer match ProggyClean + avoid descenders going too high (with current code).
|
||||
|
||||
int ttf_compressed_size = 0;
|
||||
const char* ttf_compressed = GetDefaultCompressedFontDataProggyForever(&ttf_compressed_size);
|
||||
return AddFontFromMemoryCompressedTTF(ttf_compressed, ttf_compressed_size, font_cfg.SizePixels, &font_cfg);
|
||||
#else
|
||||
IM_ASSERT(0 && "Function is disabled in this build.");
|
||||
IM_UNUSED(font_cfg_template);
|
||||
return NULL;
|
||||
#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
@@ -3159,7 +3206,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 + ImStrlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
|
||||
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s", p);
|
||||
ImFormatString(font_cfg.Name, IM_COUNTOF(font_cfg.Name), "%s", p);
|
||||
}
|
||||
return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges);
|
||||
}
|
||||
@@ -3211,6 +3258,9 @@ void ImFontAtlasBuildNotifySetFont(ImFontAtlas* atlas, ImFont* old_font, ImFont*
|
||||
shared_data->Font = new_font;
|
||||
if (ImGuiContext* ctx = shared_data->Context)
|
||||
{
|
||||
if (ctx->FrameCount == 0 && old_font == NULL) // While this should work either way, we save ourselves the bother / debugging confusion of running ImGui code so early when it is not needed.
|
||||
continue;
|
||||
|
||||
if (ctx->IO.FontDefault == old_font)
|
||||
ctx->IO.FontDefault = new_font;
|
||||
if (ctx->Font == old_font)
|
||||
@@ -3233,7 +3283,6 @@ void ImFontAtlasBuildNotifySetFont(ImFontAtlas* atlas, ImFont* old_font, ImFont*
|
||||
void ImFontAtlas::RemoveFont(ImFont* font)
|
||||
{
|
||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
||||
font->ClearOutputData();
|
||||
|
||||
ImFontAtlasFontDestroyOutput(this, font);
|
||||
for (ImFontConfig* src : font->Sources)
|
||||
@@ -3396,6 +3445,7 @@ void ImFontAtlasBuildMain(ImFontAtlas* atlas)
|
||||
|
||||
void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, ImFontBaked* baked, int* out_oversample_h, int* out_oversample_v)
|
||||
{
|
||||
// (Only used by stb_truetype builder)
|
||||
// Automatically disable horizontal oversampling over size 36
|
||||
const float raster_size = baked->Size * baked->RasterizerDensity * src->RasterizerDensity;
|
||||
*out_oversample_h = (src->OversampleH != 0) ? src->OversampleH : (raster_size > 36.0f || src->PixelSnapH) ? 1 : 2;
|
||||
@@ -3610,6 +3660,12 @@ void ImFontAtlasFontDestroyOutput(ImFontAtlas* atlas, ImFont* font)
|
||||
}
|
||||
}
|
||||
|
||||
void ImFontAtlasFontRebuildOutput(ImFontAtlas* atlas, ImFont* font)
|
||||
{
|
||||
ImFontAtlasFontDestroyOutput(atlas, font);
|
||||
ImFontAtlasFontInitOutput(atlas, font);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ImFontAtlasFontSourceInit(ImFontAtlas* atlas, ImFontConfig* src)
|
||||
@@ -3638,7 +3694,7 @@ void ImFontAtlasFontDestroySourceData(ImFontAtlas* atlas, ImFontConfig* src)
|
||||
IM_UNUSED(atlas);
|
||||
// IF YOU GET A CRASH IN THE IM_FREE() CALL HERE AND USED AddFontFromMemoryTTF():
|
||||
// - DUE TO LEGACY REASON AddFontFromMemoryTTF() TRANSFERS MEMORY OWNERSHIP BY DEFAULT.
|
||||
// - IT WILL THEREFORE CRASH WHEN PASSED DATA WHICH MAY NOT BE FREEED BY IMGUI.
|
||||
// - IT WILL THEREFORE CRASH WHEN PASSED DATA WHICH MAY NOT BE FREED BY IMGUI.
|
||||
// - USE `ImFontConfig font_cfg; font_cfg.FontDataOwnedByAtlas = false; io.Fonts->AddFontFromMemoryTTF(....., &cfg);` to disable passing ownership/
|
||||
// WE WILL ADDRESS THIS IN A FUTURE REWORK OF THE API.
|
||||
if (src->FontDataOwnedByAtlas)
|
||||
@@ -4009,7 +4065,7 @@ static void ImFontAtlasDebugWriteTexToDisk(ImTextureData* tex, const char* descr
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
char buf[128];
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "[%05d] Texture #%03d - %s.png", g.FrameCount, tex->UniqueID, description);
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "[%05d] Texture #%03d - %s.png", g.FrameCount, tex->UniqueID, description);
|
||||
stbi_write_png(buf, tex->Width, tex->Height, tex->BytesPerPixel, tex->Pixels, tex->GetPitch()); // tex->BytesPerPixel is technically not component, but ok for the formats we support.
|
||||
}
|
||||
#endif
|
||||
@@ -4238,6 +4294,10 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
|
||||
ImFontAtlasUpdateDrawListsSharedData(atlas);
|
||||
|
||||
//atlas->TexIsBuilt = true;
|
||||
|
||||
// Lazily initialize char/text classifier
|
||||
// FIXME: This could be practically anywhere, and should eventually be parameters to CalcTextSize/word-wrapping code, but there's no obvious spot now.
|
||||
ImTextInitClassifiers();
|
||||
}
|
||||
|
||||
// Destroy builder and all cached glyphs. Do not destroy actual fonts.
|
||||
@@ -4544,16 +4604,16 @@ void ImFontAtlasDebugLogTextureRequests(ImFontAtlas* atlas)
|
||||
if (tex->Status == ImTextureStatus_WantCreate)
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: create %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: destroy %dx%d, texid=0x%" IM_PRIX64 ", backend_data=%p\n", tex->UniqueID, tex->Width, tex->Height, IM_TEXTUREID_TO_U64(tex->TexID), tex->BackendUserData);
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: destroy %dx%d, texid=0x%" IM_PRIX64 ", backend_data=%p\n", tex->UniqueID, tex->Width, tex->Height, ImGui::DebugTextureIDToU64(tex->TexID), tex->BackendUserData);
|
||||
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||
{
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update %d regions, texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, tex->Updates.Size, IM_TEXTUREID_TO_U64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData);
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update %d regions, texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, tex->Updates.Size, ImGui::DebugTextureIDToU64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData);
|
||||
for (const ImTextureRect& r : tex->Updates)
|
||||
{
|
||||
IM_UNUSED(r);
|
||||
IM_ASSERT(r.x >= 0 && r.y >= 0);
|
||||
IM_ASSERT(r.x + r.w <= tex->Width && r.y + r.h <= tex->Height); // In theory should subtract PackPadding but it's currently part of atlas and mid-frame change would wreck assert.
|
||||
//IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update (% 4d..%-4d)->(% 4d..%-4d), texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, r.x, r.y, r.x + r.w, r.y + r.h, IM_TEXTUREID_TO_U64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData);
|
||||
//IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update (% 4d..%-4d)->(% 4d..%-4d), texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, r.x, r.y, r.x + r.w, r.y + r.h, ImGui::DebugTextureIDToU64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4583,14 +4643,14 @@ static bool ImGui_ImplStbTrueType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig*
|
||||
IM_ASSERT(src->FontLoaderData == NULL);
|
||||
|
||||
// Initialize helper structure for font loading and verify that the TTF/OTF data is correct
|
||||
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)src->FontData, src->FontNo);
|
||||
const int font_offset = stbtt_GetFontOffsetForIndex((const unsigned char*)src->FontData, src->FontNo);
|
||||
if (font_offset < 0)
|
||||
{
|
||||
IM_DELETE(bd_font_data);
|
||||
IM_ASSERT_USER_ERROR(0, "stbtt_GetFontOffsetForIndex(): FontData is incorrect, or FontNo cannot be found.");
|
||||
return false;
|
||||
}
|
||||
if (!stbtt_InitFont(&bd_font_data->FontInfo, (unsigned char*)src->FontData, font_offset))
|
||||
if (!stbtt_InitFont(&bd_font_data->FontInfo, (const unsigned char*)src->FontData, font_offset))
|
||||
{
|
||||
IM_DELETE(bd_font_data);
|
||||
IM_ASSERT_USER_ERROR(0, "stbtt_InitFont(): failed to parse FontData. It is correct and complete? Check FontDataSize.");
|
||||
@@ -4602,12 +4662,10 @@ static bool ImGui_ImplStbTrueType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig*
|
||||
if (src->MergeMode && src->SizePixels == 0.0f)
|
||||
src->SizePixels = ref_size;
|
||||
|
||||
if (src->SizePixels >= 0.0f)
|
||||
bd_font_data->ScaleFactor = stbtt_ScaleForPixelHeight(&bd_font_data->FontInfo, 1.0f);
|
||||
else
|
||||
bd_font_data->ScaleFactor = stbtt_ScaleForMappingEmToPixels(&bd_font_data->FontInfo, 1.0f);
|
||||
bd_font_data->ScaleFactor = stbtt_ScaleForPixelHeight(&bd_font_data->FontInfo, 1.0f);
|
||||
if (src->MergeMode && src->SizePixels != 0.0f && ref_size != 0.0f)
|
||||
bd_font_data->ScaleFactor *= src->SizePixels / ref_size; // FIXME-NEWATLAS: Should tidy up that a bit
|
||||
bd_font_data->ScaleFactor *= src->ExtraSizeScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -4640,7 +4698,7 @@ static bool ImGui_ImplStbTrueType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig
|
||||
{
|
||||
// FIXME-NEWFONTS: reevaluate how to use sizing metrics
|
||||
// FIXME-NEWFONTS: make use of line gap value
|
||||
float scale_for_layout = bd_font_data->ScaleFactor * baked->Size;
|
||||
const float scale_for_layout = bd_font_data->ScaleFactor * baked->Size / src->ExtraSizeScale;
|
||||
int unscaled_ascent, unscaled_descent, unscaled_line_gap;
|
||||
stbtt_GetFontVMetrics(&bd_font_data->FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
|
||||
baked->Ascent = ImCeil(unscaled_ascent * scale_for_layout);
|
||||
@@ -4715,12 +4773,8 @@ static bool ImGui_ImplStbTrueType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontC
|
||||
|
||||
const float ref_size = baked->OwnerFont->Sources[0]->SizePixels;
|
||||
const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f;
|
||||
float font_off_x = (src->GlyphOffset.x * offsets_scale);
|
||||
float font_off_y = (src->GlyphOffset.y * offsets_scale);
|
||||
if (src->PixelSnapH) // Snap scaled offset. This is to mitigate backward compatibility issues for GlyphOffset, but a better design would be welcome.
|
||||
font_off_x = IM_ROUND(font_off_x);
|
||||
if (src->PixelSnapV)
|
||||
font_off_y = IM_ROUND(font_off_y);
|
||||
float font_off_x = ImFloor(src->GlyphOffset.x * offsets_scale + 0.5f); // Snap scaled offset.
|
||||
float font_off_y = ImFloor(src->GlyphOffset.y * offsets_scale + 0.5f);
|
||||
font_off_x += sub_x;
|
||||
font_off_y += sub_y + IM_ROUND(baked->Ascent);
|
||||
float recip_h = 1.0f / (oversample_h * rasterizer_density);
|
||||
@@ -4892,11 +4946,11 @@ const ImWchar* ImFontAtlas::GetGlyphRangesChineseSimplifiedCommon()
|
||||
0xFF00, 0xFFEF, // Half-width characters
|
||||
0xFFFD, 0xFFFD // Invalid
|
||||
};
|
||||
static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00) * 2 + 1] = { 0 };
|
||||
static ImWchar full_ranges[IM_COUNTOF(base_ranges) + IM_COUNTOF(accumulative_offsets_from_0x4E00) * 2 + 1] = { 0 };
|
||||
if (!full_ranges[0])
|
||||
{
|
||||
memcpy(full_ranges, base_ranges, sizeof(base_ranges));
|
||||
UnpackAccumulativeOffsetsIntoRanges(0x4E00, accumulative_offsets_from_0x4E00, IM_ARRAYSIZE(accumulative_offsets_from_0x4E00), full_ranges + IM_ARRAYSIZE(base_ranges));
|
||||
UnpackAccumulativeOffsetsIntoRanges(0x4E00, accumulative_offsets_from_0x4E00, IM_COUNTOF(accumulative_offsets_from_0x4E00), full_ranges + IM_COUNTOF(base_ranges));
|
||||
}
|
||||
return &full_ranges[0];
|
||||
}
|
||||
@@ -4982,11 +5036,11 @@ const ImWchar* ImFontAtlas::GetGlyphRangesJapanese()
|
||||
0xFF00, 0xFFEF, // Half-width characters
|
||||
0xFFFD, 0xFFFD // Invalid
|
||||
};
|
||||
static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00)*2 + 1] = { 0 };
|
||||
static ImWchar full_ranges[IM_COUNTOF(base_ranges) + IM_COUNTOF(accumulative_offsets_from_0x4E00)*2 + 1] = { 0 };
|
||||
if (!full_ranges[0])
|
||||
{
|
||||
memcpy(full_ranges, base_ranges, sizeof(base_ranges));
|
||||
UnpackAccumulativeOffsetsIntoRanges(0x4E00, accumulative_offsets_from_0x4E00, IM_ARRAYSIZE(accumulative_offsets_from_0x4E00), full_ranges + IM_ARRAYSIZE(base_ranges));
|
||||
UnpackAccumulativeOffsetsIntoRanges(0x4E00, accumulative_offsets_from_0x4E00, IM_COUNTOF(accumulative_offsets_from_0x4E00), full_ranges + IM_COUNTOF(base_ranges));
|
||||
}
|
||||
return &full_ranges[0];
|
||||
}
|
||||
@@ -5075,12 +5129,12 @@ void ImFontGlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ImFont
|
||||
// [SECTION] ImFontBaked, ImFont
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ImFontBaked::ImFontBaked()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
FallbackGlyphIndex = -1;
|
||||
}
|
||||
|
||||
@@ -5097,7 +5151,7 @@ void ImFontBaked::ClearOutputData()
|
||||
|
||||
ImFont::ImFont()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
Scale = 1.0f;
|
||||
#endif
|
||||
@@ -5112,7 +5166,7 @@ void ImFont::ClearOutputData()
|
||||
{
|
||||
if (ImFontAtlas* atlas = OwnerAtlas)
|
||||
ImFontAtlasFontDiscardBakes(atlas, this, 0);
|
||||
FallbackChar = EllipsisChar = 0;
|
||||
//FallbackChar = EllipsisChar = 0;
|
||||
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
|
||||
LastBaked = NULL;
|
||||
}
|
||||
@@ -5373,22 +5427,69 @@ const char* ImTextCalcWordWrapNextLineStart(const char* text, const char* text_e
|
||||
if ((flags & ImDrawTextFlags_WrapKeepBlanks) == 0)
|
||||
while (text < text_end && ImCharIsBlankA(*text))
|
||||
text++;
|
||||
if (*text == '\n')
|
||||
if (text < text_end && *text == '\n')
|
||||
text++;
|
||||
return text;
|
||||
}
|
||||
|
||||
void ImTextClassifierClear(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class)
|
||||
{
|
||||
for (unsigned int c = codepoint_min; c < codepoint_end; c++)
|
||||
ImTextClassifierSetCharClass(bits, codepoint_min, codepoint_end, char_class, c);
|
||||
}
|
||||
|
||||
void ImTextClassifierSetCharClass(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class, unsigned int c)
|
||||
{
|
||||
IM_ASSERT(c >= codepoint_min && c < codepoint_end);
|
||||
IM_UNUSED(codepoint_end);
|
||||
c -= codepoint_min;
|
||||
const ImU32 shift = (c & 15) << 1;
|
||||
bits[c >> 4] = (bits[c >> 4] & ~(0x03 << shift)) | (char_class << shift);
|
||||
}
|
||||
|
||||
void ImTextClassifierSetCharClassFromStr(ImU32* bits, unsigned int codepoint_min, unsigned int codepoint_end, ImWcharClass char_class, const char* s)
|
||||
{
|
||||
const char* s_end = s + strlen(s);
|
||||
while (*s)
|
||||
{
|
||||
unsigned int c;
|
||||
s += ImTextCharFromUtf8(&c, s, s_end);
|
||||
ImTextClassifierSetCharClass(bits, codepoint_min, codepoint_end, char_class, c);
|
||||
}
|
||||
}
|
||||
|
||||
#define ImTextClassifierGet(_BITS, _CHAR_OFFSET) ((_BITS[(_CHAR_OFFSET) >> 4] >> (((_CHAR_OFFSET) & 15) << 1)) & 0x03)
|
||||
|
||||
// 2-bit per character
|
||||
static ImU32 g_CharClassifierIsSeparator_0000_007f[128 / 16] = {};
|
||||
static ImU32 g_CharClassifierIsSeparator_3000_300f[ 16 / 16] = {};
|
||||
|
||||
void ImTextInitClassifiers()
|
||||
{
|
||||
if (ImTextClassifierGet(g_CharClassifierIsSeparator_0000_007f, ',') != 0)
|
||||
return;
|
||||
|
||||
// List of hardcoded separators: .,;!?'"
|
||||
// Making this dynamic given known ranges is trivial BUT requires us to standardize where you pass them as parameters. (#3002, #8503)
|
||||
ImTextClassifierClear(g_CharClassifierIsSeparator_0000_007f, 0, 128, ImWcharClass_Other);
|
||||
ImTextClassifierSetCharClassFromStr(g_CharClassifierIsSeparator_0000_007f, 0, 128, ImWcharClass_Blank, " \t");
|
||||
ImTextClassifierSetCharClassFromStr(g_CharClassifierIsSeparator_0000_007f, 0, 128, ImWcharClass_Punct, ".,;!?\"");
|
||||
|
||||
ImTextClassifierClear(g_CharClassifierIsSeparator_3000_300f, 0x3000, 0x300F, ImWcharClass_Other);
|
||||
ImTextClassifierSetCharClass(g_CharClassifierIsSeparator_3000_300f, 0x3000, 0x300F, ImWcharClass_Blank, 0x3000);
|
||||
ImTextClassifierSetCharClass(g_CharClassifierIsSeparator_3000_300f, 0x3000, 0x300F, ImWcharClass_Punct, 0x3001);
|
||||
ImTextClassifierSetCharClass(g_CharClassifierIsSeparator_3000_300f, 0x3000, 0x300F, ImWcharClass_Punct, 0x3002);
|
||||
}
|
||||
|
||||
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
|
||||
// This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end.
|
||||
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
|
||||
// Refer to imgui_test_suite's "drawlist_text_wordwrap_1" for tests.
|
||||
const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* text, const char* text_end, float wrap_width, ImDrawTextFlags flags)
|
||||
{
|
||||
// For references, possible wrap point marked with ^
|
||||
// "aaa bbb, ccc,ddd. eee fff. ggg!"
|
||||
// ^ ^ ^ ^ ^__ ^ ^
|
||||
|
||||
// List of hardcoded separators: .,;!?'"
|
||||
|
||||
// Skip extra blanks after a line returns (that includes not counting them in width computation)
|
||||
// e.g. "Hello world" --> "Hello" "World"
|
||||
|
||||
@@ -5399,16 +5500,20 @@ const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* t
|
||||
const float scale = size / baked->Size;
|
||||
|
||||
float line_width = 0.0f;
|
||||
float word_width = 0.0f;
|
||||
float blank_width = 0.0f;
|
||||
wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters
|
||||
|
||||
const char* word_end = text;
|
||||
const char* prev_word_end = NULL;
|
||||
bool inside_word = true;
|
||||
|
||||
const char* s = text;
|
||||
IM_ASSERT(text_end != NULL);
|
||||
|
||||
int prev_type = ImWcharClass_Other;
|
||||
const bool keep_blanks = (flags & ImDrawTextFlags_WrapKeepBlanks) != 0;
|
||||
|
||||
// Find next wrapping point
|
||||
//const char* span_begin = s;
|
||||
const char* span_end = s;
|
||||
float span_width = 0.0f;
|
||||
|
||||
while (s < text_end)
|
||||
{
|
||||
unsigned int c = (unsigned int)*s;
|
||||
@@ -5424,7 +5529,7 @@ const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* t
|
||||
return s; // Direct return, skip "Wrap_width is too small to fit anything" path.
|
||||
if (c == '\r')
|
||||
{
|
||||
s = next_s;
|
||||
s = next_s; // Fast-skip
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -5434,46 +5539,56 @@ const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* t
|
||||
if (char_width < 0.0f)
|
||||
char_width = BuildLoadGlyphGetAdvanceOrFallback(baked, c);
|
||||
|
||||
if (ImCharIsBlankW(c))
|
||||
// Classify current character
|
||||
int curr_type;
|
||||
if (c < 128)
|
||||
curr_type = ImTextClassifierGet(g_CharClassifierIsSeparator_0000_007f, c);
|
||||
else if (c >= 0x3000 && c < 0x3010)
|
||||
curr_type = ImTextClassifierGet(g_CharClassifierIsSeparator_3000_300f, c & 15); //-V578
|
||||
else
|
||||
curr_type = ImWcharClass_Other;
|
||||
|
||||
if (curr_type == ImWcharClass_Blank)
|
||||
{
|
||||
if (inside_word)
|
||||
// End span: 'A ' or '. '
|
||||
if (prev_type != ImWcharClass_Blank && !keep_blanks)
|
||||
{
|
||||
line_width += blank_width;
|
||||
blank_width = 0.0f;
|
||||
word_end = s;
|
||||
span_end = s;
|
||||
line_width += span_width;
|
||||
span_width = 0.0f;
|
||||
}
|
||||
blank_width += char_width;
|
||||
inside_word = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
word_width += char_width;
|
||||
if (inside_word)
|
||||
// End span: '.X' unless X is a digit
|
||||
if (prev_type == ImWcharClass_Punct && curr_type != ImWcharClass_Punct && !(c >= '0' && c <= '9')) // FIXME: Digit checks might be removed if allow custom separators (#8503)
|
||||
{
|
||||
word_end = next_s;
|
||||
span_end = s;
|
||||
line_width += span_width + blank_width;
|
||||
span_width = blank_width = 0.0f;
|
||||
}
|
||||
else
|
||||
// End span: 'A ' or '. '
|
||||
else if (prev_type == ImWcharClass_Blank && keep_blanks)
|
||||
{
|
||||
prev_word_end = word_end;
|
||||
line_width += word_width + blank_width;
|
||||
if ((flags & ImDrawTextFlags_WrapKeepBlanks) && line_width <= wrap_width)
|
||||
prev_word_end = s;
|
||||
word_width = blank_width = 0.0f;
|
||||
span_end = s;
|
||||
line_width += span_width + blank_width;
|
||||
span_width = blank_width = 0.0f;
|
||||
}
|
||||
|
||||
// Allow wrapping after punctuation.
|
||||
inside_word = (c != '.' && c != ',' && c != ';' && c != '!' && c != '?' && c != '\"' && c != 0x3001 && c != 0x3002);
|
||||
span_width += char_width;
|
||||
}
|
||||
|
||||
// We ignore blank width at the end of the line (they can be skipped)
|
||||
if (line_width + word_width > wrap_width)
|
||||
if (span_width + blank_width + line_width > wrap_width)
|
||||
{
|
||||
// Words that cannot possibly fit within an entire line will be cut anywhere.
|
||||
if (word_width < wrap_width)
|
||||
s = prev_word_end ? prev_word_end : word_end;
|
||||
break;
|
||||
if (span_width + blank_width > wrap_width)
|
||||
break;
|
||||
// FIXME: Narrow wrapping e.g. "A quick brown" -> "Quic|k br|own", would require knowing if span is going to be longer than wrap_width.
|
||||
//if (span_width > wrap_width && !is_blank && !was_blank)
|
||||
// return s;
|
||||
return span_end;
|
||||
}
|
||||
|
||||
prev_type = curr_type;
|
||||
s = next_s;
|
||||
}
|
||||
|
||||
@@ -5625,7 +5740,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||
}
|
||||
|
||||
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
||||
// DO NOT CALL DIRECTLY THIS WILL CHANGE WILDLY IN 2025-2025. Use ImDrawList::AddText().
|
||||
// DO NOT CALL DIRECTLY THIS WILL CHANGE WILDLY IN 2026. Use ImDrawList::AddText().
|
||||
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, ImDrawTextFlags flags)
|
||||
{
|
||||
// Align to be pixel perfect
|
||||
@@ -5839,7 +5954,7 @@ begin:
|
||||
// - RenderBullet()
|
||||
// - RenderCheckMark()
|
||||
// - RenderArrowPointingAt()
|
||||
// - RenderRectFilledRangeH()
|
||||
// - RenderRectFilledInRangeH()
|
||||
// - RenderRectFilledWithHole()
|
||||
//-----------------------------------------------------------------------------
|
||||
// Function in need of a redesign (legacy mess)
|
||||
@@ -5922,15 +6037,15 @@ static inline float ImAcos01(float x)
|
||||
}
|
||||
|
||||
// FIXME: Cleanup and move code to ImDrawList.
|
||||
void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding)
|
||||
// - Before 2025-12-04: RenderRectFilledRangeH() with 'float x_start_norm, float x_end_norm` <- normalized
|
||||
// - After 2025-12-04: RenderRectFilledInRangeH() with 'float x1, float x2' <- absolute coords!!
|
||||
void ImGui::RenderRectFilledInRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float fill_x0, float fill_x1, float rounding)
|
||||
{
|
||||
if (x_end_norm == x_start_norm)
|
||||
if (fill_x0 > fill_x1)
|
||||
return;
|
||||
if (x_start_norm > x_end_norm)
|
||||
ImSwap(x_start_norm, x_end_norm);
|
||||
|
||||
ImVec2 p0 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_start_norm), rect.Min.y);
|
||||
ImVec2 p1 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_end_norm), rect.Max.y);
|
||||
ImVec2 p0 = ImVec2(fill_x0, rect.Min.y);
|
||||
ImVec2 p1 = ImVec2(fill_x1, rect.Max.y);
|
||||
if (rounding == 0.0f)
|
||||
{
|
||||
draw_list->AddRectFilled(p0, p1, col, 0.0f);
|
||||
@@ -5998,6 +6113,17 @@ void ImGui::RenderRectFilledWithHole(ImDrawList* draw_list, const ImRect& outer,
|
||||
if (fill_R && fill_D) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Max.y), ImVec2(outer.Max.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersBottomRight);
|
||||
}
|
||||
|
||||
ImDrawFlags ImGui::CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRect& r_outer, float threshold)
|
||||
{
|
||||
bool round_l = r_in.Min.x <= r_outer.Min.x + threshold;
|
||||
bool round_r = r_in.Max.x >= r_outer.Max.x - threshold;
|
||||
bool round_t = r_in.Min.y <= r_outer.Min.y + threshold;
|
||||
bool round_b = r_in.Max.y >= r_outer.Max.y - threshold;
|
||||
return ImDrawFlags_RoundCornersNone
|
||||
| ((round_t && round_l) ? ImDrawFlags_RoundCornersTopLeft : 0) | ((round_t && round_r) ? ImDrawFlags_RoundCornersTopRight : 0)
|
||||
| ((round_b && round_l) ? ImDrawFlags_RoundCornersBottomLeft : 0) | ((round_b && round_r) ? ImDrawFlags_RoundCornersBottomRight : 0);
|
||||
}
|
||||
|
||||
// Helper for ColorPicker4()
|
||||
// NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that.
|
||||
// Spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding altogether.
|
||||
@@ -6161,11 +6287,8 @@ static unsigned int stb_decompress(unsigned char *output, const unsigned char *i
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Default font data (ProggyClean.ttf)
|
||||
//-----------------------------------------------------------------------------
|
||||
// ProggyClean.ttf
|
||||
// Copyright (c) 2004, 2005 Tristan Grimmer
|
||||
// MIT license (see License.txt in http://www.proggyfonts.net/index.php?menu=download)
|
||||
// Download and more information at http://www.proggyfonts.net or http://upperboundsinteractive.com/fonts.php
|
||||
// If you want a similar font which may be better scaled, consider using ProggyVector from the same author!
|
||||
// MIT License / Copyright (c) 2004, 2005 Tristan Grimmer
|
||||
// Download and more information at https://github.com/bluescan/proggyfonts
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
@@ -6343,11 +6466,274 @@ static const unsigned char proggy_clean_ttf_compressed_data[9583] =
|
||||
239,32,57,141,239,32,57,141,239,32,57,141,239,32,57,141,239,32,57,141,239,35,57,102,0,0,5,250,72,249,98,247,
|
||||
};
|
||||
|
||||
static const char* GetDefaultCompressedFontDataTTF(int* out_size)
|
||||
static const char* GetDefaultCompressedFontDataProggyClean(int* out_size)
|
||||
{
|
||||
*out_size = proggy_clean_ttf_compressed_size;
|
||||
return (const char*)proggy_clean_ttf_compressed_data;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Default font data (ProggyForever-Regular-minimal.ttf)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Based on ProggyForever: https://github.com/ocornut/proggyforever
|
||||
// MIT license / Copyright (c) 2026 Disco Hello, Copyright (c) 2019,2023 Tristan Grimmer
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// File: 'output/ProggyForever-Regular-minimal.ttf' (18556 bytes)
|
||||
// Exported using binary_to_compressed_c.exe -u8 "output/ProggyForever-Regular-minimal.ttf" proggy_forever_minimal_ttf
|
||||
static const unsigned int proggy_forever_minimal_ttf_compressed_size = 14562;
|
||||
static const unsigned char proggy_forever_minimal_ttf_compressed_data[14562] =
|
||||
{
|
||||
87,188,0,0,0,0,0,0,0,0,72,124,0,4,0,0,55,0,1,0,0,0,14,0,128,0,3,0,96,70,70,84,77,176,111,174,190,0,0,72,96,130,21,40,28,71,68,69,70,0,136,0,105,130,15,32,64,130,15,44,30,79,83,47,50,
|
||||
104,97,19,194,0,0,1,104,130,15,44,96,99,109,97,112,177,173,221,139,0,0,3,80,130,19,44,114,99,118,116,32,0,33,2,121,0,0,4,196,130,31,38,4,103,97,115,112,255,255,130,89,34,0,72,56,130,
|
||||
15,56,8,103,108,121,102,239,245,108,207,0,0,6,76,0,0,62,224,104,101,97,100,44,57,58,3,130,27,32,236,130,3,33,54,104,130,16,35,4,62,0,230,130,75,32,36,130,15,39,36,104,109,116,120,24,
|
||||
22,19,130,95,33,1,200,130,19,40,136,108,111,99,97,80,9,64,114,130,95,131,15,39,130,109,97,120,112,1,7,0,131,31,32,72,130,47,44,32,110,97,109,101,10,160,159,151,0,0,69,44,130,47,44,
|
||||
68,112,111,115,116,70,77,175,253,0,0,70,112,130,15,32,197,132,235,32,1,130,9,42,224,136,151,95,15,60,245,0,11,3,232,130,55,36,0,229,175,187,66,132,7,42,178,59,232,255,225,255,68,1,
|
||||
215,2,176,130,15,34,8,0,2,130,5,131,2,130,51,39,2,131,255,71,0,0,1,184,130,31,34,226,1,215,132,73,131,25,135,3,32,4,132,17,37,192,0,90,0,5,0,131,0,33,2,0,130,44,132,19,34,64,0,46,130,
|
||||
11,38,0,0,4,1,184,1,144,131,29,35,2,138,2,187,130,17,32,140,133,7,38,1,223,0,49,1,2,0,138,0,37,128,0,0,7,16,0,136,123,33,0,88,130,0,37,0,64,0,32,32,172,133,131,34,2,175,0,131,63,33,
|
||||
3,0,130,0,35,1,133,2,6,130,6,38,32,0,1,1,184,0,33,130,9,130,161,32,0,132,3,39,0,166,0,116,255,249,0,49,130,113,36,4,0,185,0,135,130,1,38,27,0,22,0,154,0,53,130,25,40,39,0,41,0,79,0,
|
||||
50,0,45,130,17,32,49,130,11,33,46,0,131,17,36,166,0,143,0,24,132,1,34,48,255,225,130,55,34,38,0,47,130,23,44,52,0,58,0,35,0,42,0,66,0,65,0,19,130,79,32,19,130,47,38,35,0,44,0,13,0,
|
||||
38,130,21,38,9,0,37,0,13,255,250,130,121,36,5,0,33,0,104,130,47,40,104,0,37,255,242,0,124,0,48,130,95,32,59,130,3,34,37,0,40,130,5,36,62,0,139,0,100,130,57,36,133,0,20,0,62,130,55,
|
||||
32,50,130,19,40,69,0,69,0,87,0,54,0,29,130,167,32,20,130,107,36,64,0,63,0,188,130,3,36,22,0,21,0,159,130,7,36,40,0,55,0,5,130,17,34,64,0,109,130,33,34,92,0,50,130,5,42,109,0,101,0,
|
||||
24,0,115,0,109,0,131,130,121,32,48,130,39,36,143,0,114,0,83,130,77,32,19,130,157,34,18,0,73,130,49,32,5,136,3,32,2,130,85,33,52,0,133,1,33,66,0,133,1,32,17,130,125,32,35,130,209,131,
|
||||
3,36,46,0,1,0,46,132,1,32,47,130,51,32,42,130,25,32,38,130,213,135,3,34,5,0,59,130,99,32,37,132,3,34,51,0,68,132,1,32,42,130,189,33,43,0,135,1,36,24,0,12,0,61,134,1,32,26,130,131,38,
|
||||
26,0,30,0,0,0,3,134,3,32,28,130,93,130,10,35,0,108,0,3,132,9,36,28,0,4,0,80,130,16,34,16,0,16,132,35,46,126,0,133,0,171,0,210,0,211,0,255,32,172,255,255,130,25,32,32,130,17,34,161,
|
||||
0,174,130,17,32,212,131,17,45,255,227,255,221,255,194,255,192,255,95,255,191,224,19,132,67,130,36,139,2,34,1,6,0,136,22,35,1,2,0,0,66,53,9,32,0,133,0,32,1,130,142,8,148,4,5,6,7,8,9,
|
||||
10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,
|
||||
70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,0,132,133,135,137,145,149,155,160,159,161,163,162,164,166,168,167,169,170,172,171,173,174,176,178,
|
||||
177,179,181,180,185,184,186,187,0,112,100,101,105,0,118,158,110,107,0,116,106,0,134,151,0,113,0,0,103,117,132,158,38,108,122,0,165,183,127,99,132,11,38,109,123,0,0,128,131,148,132,
|
||||
11,130,4,37,182,0,190,60,0,191,130,8,34,0,0,119,130,5,47,130,138,129,139,136,141,142,143,140,50,147,0,146,153,154,152,130,18,32,111,130,3,32,120,130,3,130,2,34,33,2,121,130,5,33,42,
|
||||
0,133,1,9,155,68,0,86,0,134,0,210,1,14,1,104,1,116,1,148,1,180,1,212,1,232,2,6,2,20,2,38,2,54,2,100,2,122,2,172,2,232,3,2,3,60,3,116,3,134,3,210,4,10,4,40,4,82,4,102,4,122,4,142,4,
|
||||
204,5,36,5,60,5,118,5,158,5,184,5,208,5,228,6,24,6,44,6,68,6,94,6,118,6,134,6,160,6,182,6,224,7,14,7,64,7,106,7,182,7,200,7,238,8,0,8,28,8,52,8,72,8,96,8,114,8,130,8,148,8,166,8,180,
|
||||
8,194,9,12,9,58,9,92,9,140,9,182,9,214,10,14,10,44,10,74,10,110,10,134,10,150,10,198,10,230,11,4,11,50,11,96,11,130,11,188,11,216,11,250,12,14,12,42,12,66,12,114,12,142,12,198,12,210,
|
||||
13,10,13,62,13,126,13,152,13,198,13,238,14,34,14,72,14,90,14,198,14,232,15,32,15,106,15,134,15,200,15,214,15,244,16,16,16,56,16,114,16,128,16,182,16,212,16,230,17,2,17,22,17,60,17,
|
||||
86,17,132,17,194,18,20,18,76,18,108,18,140,18,176,18,228,19,24,19,74,19,110,19,168,19,198,19,228,20,6,20,56,20,86,20,116,20,150,20,200,20,252,21,44,21,92,21,144,21,212,22,24,22,50,
|
||||
22,112,22,148,22,186,22,226,23,28,23,56,23,90,23,160,23,246,24,76,24,164,25,18,25,124,25,226,26,94,26,150,26,198,26,248,27,44,27,114,27,144,27,174,27,208,28,2,28,74,28,136,28,174,28,
|
||||
212,28,254,29,60,29,118,29,172,29,230,30,16,30,58,30,104,30,166,30,206,30,244,31,48,31,112,0,0,0,2,0,33,0,0,1,42,2,154,0,3,0,7,0,46,177,1,0,47,60,178,7,4,0,237,50,177,6,5,220,60,178,
|
||||
3,2,130,10,34,0,177,3,131,22,32,5,131,22,39,178,7,6,1,252,60,178,1,131,23,52,51,17,33,17,39,51,17,35,33,1,9,232,199,199,2,154,253,102,33,2,88,131,83,38,166,255,254,1,18,2,35,130,81,
|
||||
61,13,0,0,54,50,22,20,6,34,38,52,55,35,3,55,51,21,198,44,32,32,44,32,85,59,14,1,83,105,31,131,11,36,122,1,4,91,91,130,135,38,116,1,70,1,68,2,7,132,135,37,0,1,35,53,51,7,130,3,8,40,
|
||||
1,67,64,64,142,65,65,1,70,192,192,192,0,2,255,248,0,3,1,191,2,3,0,3,0,31,0,0,63,1,35,7,37,35,7,51,21,35,7,35,55,132,3,34,53,51,55,130,51,35,55,51,7,51,131,3,53,254,30,92,30,1,29,104,
|
||||
31,92,106,38,59,38,92,38,58,38,96,110,31,98,112,134,11,34,90,201,115,130,0,33,54,143,130,0,35,54,115,54,144,130,0,32,0,130,85,8,37,49,255,241,1,135,2,22,0,6,0,11,0,52,0,0,55,62,1,53,
|
||||
52,38,47,1,53,6,21,20,23,30,3,21,20,7,21,35,53,46,1,130,16,8,109,30,2,23,53,46,3,53,52,54,55,53,51,21,30,1,31,1,21,38,39,21,50,249,32,41,36,37,60,72,137,22,40,46,28,141,60,36,67,15,
|
||||
15,6,21,69,37,31,44,43,22,75,65,60,25,55,15,15,43,67,3,81,7,37,31,30,32,10,73,135,12,61,44,30,4,15,28,50,33,114,15,44,43,1,14,6,6,63,4,11,22,3,162,6,15,26,42,29,53,67,9,45,42,2,11,
|
||||
5,5,62,29,4,150,0,5,130,1,36,11,1,178,1,250,130,161,52,11,0,19,0,27,0,35,0,0,1,51,1,35,36,50,54,52,38,34,6,20,65,97,7,34,2,20,22,132,17,65,111,5,53,54,50,1,74,71,254,222,71,1,16,41,
|
||||
30,30,41,29,7,84,60,60,84,59,174,130,9,34,29,41,122,130,9,51,59,84,1,249,254,21,47,27,39,27,27,39,115,56,79,56,56,79,1,26,131,11,33,27,7,131,11,8,59,56,0,0,0,3,0,4,255,246,1,179,2,
|
||||
21,0,9,0,28,0,62,0,0,55,50,55,46,1,39,6,21,20,22,3,28,2,30,5,23,62,1,53,52,38,35,34,6,1,23,35,38,39,6,35,34,38,53,52,54,55,46,2,130,5,8,101,51,50,22,21,20,14,2,7,22,23,54,53,55,20,
|
||||
206,52,37,25,110,24,65,80,41,1,2,3,6,8,12,7,37,37,31,23,24,35,1,2,67,72,13,21,60,89,72,104,52,44,22,19,15,63,60,61,51,15,32,25,24,89,58,36,61,44,36,28,131,28,54,59,48,62,1,125,1,7,
|
||||
3,7,5,10,9,13,16,9,25,40,24,21,25,32,254,143,79,15,24,49,96,66,50,74,33,25,130,17,56,41,69,55,49,20,36,34,20,17,107,69,65,72,1,108,0,1,0,185,1,70,0,255,2,8,130,189,42,0,19,35,53,51,
|
||||
254,68,68,1,71,193,130,23,8,59,135,255,193,1,49,2,62,0,17,0,0,1,14,1,20,22,23,35,46,4,52,62,2,63,1,1,49,43,55,55,43,60,4,15,38,29,24,23,32,33,11,11,2,61,60,177,161,177,60,6,21,68,70,
|
||||
103,97,102,75,61,16,16,130,50,32,0,138,63,34,19,30,4,130,220,40,15,1,35,62,1,52,38,39,195,137,57,32,60,131,73,44,2,61,6,22,68,71,103,97,101,75,60,16,16,132,73,32,0,131,63,38,27,0,69,
|
||||
1,157,1,199,132,127,8,41,7,23,7,39,21,35,53,7,39,55,39,55,23,53,51,21,55,1,157,131,131,33,128,64,129,32,131,131,32,129,64,128,1,77,71,71,50,70,142,142,70,50,134,7,49,0,1,0,22,0,74,
|
||||
1,162,1,185,0,11,0,0,19,51,21,35,130,62,130,221,37,53,51,251,166,166,62,130,2,38,1,31,59,154,154,59,154,130,39,39,154,255,129,1,30,0,107,0,130,180,32,54,65,133,5,8,37,15,1,39,54,55,
|
||||
46,1,53,52,209,45,31,21,31,30,11,11,26,55,10,17,25,107,32,22,32,61,40,32,7,7,37,48,41,1,31,21,22,131,163,54,53,0,227,1,131,1,32,0,3,0,0,37,33,53,33,1,131,254,178,1,78,228,60,132,191,
|
||||
40,166,255,255,1,18,0,105,0,7,67,209,9,67,203,5,37,105,31,44,31,31,44,132,35,38,39,255,222,1,144,2,39,131,63,49,9,1,35,1,1,144,254,221,69,1,34,2,39,253,184,2,72,0,130,21,8,73,41,255,
|
||||
247,1,143,2,14,0,10,0,21,0,27,0,0,55,50,62,3,53,52,39,7,22,19,34,14,3,21,20,23,55,38,39,50,16,35,34,16,220,17,28,30,21,14,4,190,27,57,17,28,31,20,14,4,189,26,57,178,178,178,51,7,26,
|
||||
44,78,53,40,34,230,52,1,161,8,131,10,39,39,33,229,52,58,253,234,2,130,186,41,0,1,0,79,0,0,1,104,2,7,130,91,40,0,19,39,55,51,17,51,21,33,130,5,50,81,1,106,68,105,254,233,1,105,1,103,
|
||||
81,78,254,55,61,61,1,122,130,43,32,50,130,43,37,134,2,17,0,31,0,130,43,49,62,2,51,50,30,2,21,20,6,15,1,33,21,33,53,52,55,54,67,247,5,8,58,35,34,6,7,55,1,8,29,81,37,48,72,36,17,44,59,
|
||||
147,1,1,254,173,13,1,165,37,40,58,45,26,75,24,1,159,65,5,16,27,30,48,46,21,40,78,58,146,61,46,14,12,1,165,38,80,33,33,47,27,13,0,130,94,41,0,45,255,246,1,139,2,16,0,41,130,12,32,22,
|
||||
130,93,38,35,34,38,47,1,53,30,130,108,40,54,53,52,38,43,1,53,51,50,131,8,130,101,37,15,1,53,54,51,50,131,35,8,62,1,26,112,107,85,34,78,22,23,7,25,80,41,57,65,65,49,64,64,46,56,55,45,
|
||||
33,72,20,20,74,68,78,98,51,1,22,30,109,65,84,13,7,6,69,4,12,19,51,49,46,52,58,45,38,37,43,14,7,7,64,23,74,59,50,55,130,119,34,2,0,22,130,111,45,162,2,7,0,2,0,13,0,0,37,17,3,59,1,66,
|
||||
44,6,54,19,51,1,16,179,237,88,88,67,241,208,100,181,1,18,254,238,58,123,123,73,1,66,130,46,33,0,49,130,171,32,135,130,51,37,40,0,0,19,17,33,130,47,130,143,37,30,3,21,20,14,2,137,181,
|
||||
36,62,2,53,52,46,130,15,8,68,6,7,72,1,33,221,24,41,25,48,51,38,24,35,61,67,38,43,70,14,14,7,24,76,38,21,39,39,23,23,40,44,25,28,56,14,1,2,1,4,59,127,11,10,25,38,63,40,49,72,38,18,11,
|
||||
6,5,71,4,11,19,11,25,48,33,33,48,25,12,13,7,130,157,55,41,255,248,1,143,2,8,0,9,0,37,0,0,55,50,53,52,35,34,6,21,20,22,19,65,139,5,130,119,42,53,52,62,2,51,50,22,31,1,21,38,131,26,8,
|
||||
58,54,224,101,101,41,59,59,51,31,56,49,29,91,82,87,98,36,63,79,48,24,46,11,10,31,59,69,89,36,48,119,121,57,64,63,56,1,39,20,40,68,43,90,89,114,136,73,110,63,31,8,4,3,66,25,95,98,72,
|
||||
0,130,0,38,1,0,46,0,0,1,138,130,227,32,6,130,227,8,42,53,33,21,3,35,19,46,1,91,197,78,190,1,203,59,29,254,23,1,202,0,0,3,0,39,255,246,1,145,2,17,0,15,0,31,0,52,0,0,54,50,62,2,130,243,
|
||||
38,34,14,2,20,30,1,18,132,6,32,2,132,18,35,1,23,30,1,65,210,5,35,53,52,55,38,68,239,7,8,50,199,42,32,32,18,18,33,32,40,32,33,18,18,32,72,37,29,29,16,17,29,28,36,28,30,16,16,29,33,48,
|
||||
52,104,76,77,104,99,84,95,71,70,96,45,7,20,42,63,42,19,7,7,19,130,6,43,20,1,166,6,17,37,53,37,16,6,6,16,130,6,59,17,191,16,72,52,69,78,77,70,107,33,30,91,62,69,70,61,90,0,2,0,41,0,
|
||||
0,1,143,2,16,65,43,5,43,19,34,21,20,51,50,54,53,52,38,3,34,69,108,11,65,170,5,32,22,131,26,8,44,6,215,100,100,42,59,60,51,30,57,48,29,91,82,86,99,36,64,79,47,24,46,11,11,32,59,68,89,
|
||||
35,1,216,120,120,56,64,64,56,254,217,20,39,68,44,89,90,65,44,6,35,3,4,65,24,65,44,5,55,2,0,166,0,81,1,18,1,171,0,7,0,15,0,0,18,34,38,52,54,50,22,20,6,71,199,6,38,242,44,32,32,44,32,
|
||||
76,132,5,39,1,65,31,44,31,31,44,165,132,5,32,0,130,0,36,2,0,143,255,209,134,59,32,24,140,59,35,21,20,14,2,68,137,8,37,243,45,31,31,45,31,130,67,41,22,30,31,11,10,27,55,10,17,25,135,
|
||||
74,37,32,22,33,60,41,31,68,150,10,8,37,0,1,0,24,0,84,1,160,1,176,0,6,0,0,19,37,21,13,1,21,37,24,1,135,254,200,1,56,254,121,1,30,145,62,111,112,62,145,132,123,38,24,0,152,1,159,1,114,
|
||||
72,67,5,34,37,33,53,132,1,33,1,159,130,37,32,135,131,3,35,153,59,99,59,130,39,141,79,37,5,21,5,53,45,1,131,79,32,121,130,79,36,200,1,176,145,57,131,81,132,79,42,48,0,0,1,135,2,31,0,
|
||||
34,0,42,130,121,33,50,22,130,195,44,3,29,1,35,53,52,62,4,53,52,38,35,34,132,209,34,62,4,16,65,25,6,58,226,83,82,29,42,42,29,70,21,33,38,33,22,52,43,25,45,29,22,4,5,52,2,10,34,38,61,
|
||||
132,239,8,33,2,31,68,52,28,47,33,30,33,17,41,41,22,39,28,29,23,31,16,30,33,16,23,23,8,8,34,4,14,35,26,22,254,75,65,71,9,47,255,225,255,233,1,215,2,32,0,7,0,64,0,0,54,50,71,233,5,39,
|
||||
5,23,14,4,35,34,46,3,71,98,10,46,21,35,53,6,35,34,38,52,54,51,50,22,31,1,50,132,151,8,122,6,21,20,30,2,51,50,62,3,214,60,43,43,60,43,1,5,38,2,11,38,43,71,37,63,103,67,46,20,141,105,
|
||||
105,128,15,24,21,10,55,36,43,55,79,80,55,28,49,10,11,45,84,70,81,118,39,61,75,39,35,64,40,30,14,168,56,79,57,57,79,120,46,4,11,27,21,17,33,55,74,79,42,120,163,78,67,24,35,17,7,1,198,
|
||||
19,31,93,131,94,26,13,13,28,34,57,124,104,53,87,55,30,13,20,20,13,0,0,0,2,0,5,0,0,1,178,2,7,130,9,8,38,10,0,0,55,51,3,55,19,35,39,35,7,35,19,141,158,79,45,169,77,41,193,40,77,169,192,
|
||||
1,9,61,253,250,136,136,2,6,0,3,0,38,130,47,32,146,130,47,36,8,0,17,0,39,130,49,32,50,69,22,5,36,21,17,21,22,55,131,10,42,35,23,30,4,21,20,14,2,43,1,17,69,159,6,8,61,220,65,52,62,45,
|
||||
121,71,39,84,49,42,77,12,23,34,25,18,30,50,57,31,194,177,43,62,32,15,49,58,47,52,47,43,189,1,147,156,1,2,4,76,42,33,183,3,7,20,27,48,31,38,57,32,14,2,5,25,43,46,24,42,55,130,110,47,
|
||||
0,47,255,248,1,137,2,18,0,26,0,0,37,21,6,35,67,62,7,58,23,21,38,35,34,14,2,21,20,30,1,51,50,1,136,49,79,56,86,50,24,112,104,77,51,51,77,130,65,55,15,26,66,50,77,93,73,28,42,74,95,58,
|
||||
117,151,32,71,45,33,59,74,46,62,91,59,130,233,130,183,33,1,144,130,195,34,6,0,13,131,193,33,53,52,130,172,58,19,50,17,16,35,7,17,199,125,125,84,84,201,200,160,58,202,201,254,109,1,
|
||||
204,254,253,254,254,1,130,247,34,1,0,52,130,136,32,131,130,51,8,34,11,0,0,19,33,21,33,23,51,21,35,21,33,21,33,53,1,77,254,253,1,227,228,1,4,254,178,2,6,59,153,59,188,59,0,130,0,38,
|
||||
1,0,58,0,0,1,126,130,47,32,9,132,47,34,35,31,1,130,47,40,35,58,1,67,249,1,181,182,74,130,41,35,158,1,59,241,130,34,33,0,35,130,219,32,148,130,219,32,36,130,219,38,39,35,53,51,21,14,
|
||||
4,149,224,47,62,1,1,78,1,99,170,2,7,27,32,54,30,56,85,51,130,233,33,78,50,132,233,47,14,25,66,50,27,42,11,67,141,58,223,2,7,18,13,11,143,241,37,11,7,0,1,0,42,130,108,32,141,133,191,
|
||||
57,51,17,51,21,51,53,51,17,35,53,35,21,43,75,204,75,75,204,2,6,212,212,253,250,247,246,130,39,32,66,130,39,32,117,133,39,36,19,53,33,21,35,130,43,55,5,53,55,17,67,1,50,116,116,254,
|
||||
206,115,1,203,59,59,254,112,58,1,57,1,1,145,132,231,36,65,255,249,1,118,130,47,32,13,130,231,8,33,51,17,20,6,35,7,53,51,50,54,53,17,35,158,216,66,78,164,147,48,37,140,2,6,254,158,80,
|
||||
90,1,57,48,58,1,47,130,50,39,0,1,0,19,0,0,1,165,137,139,59,55,51,7,19,35,3,7,21,19,75,233,85,212,221,90,180,57,2,6,230,230,212,254,206,1,4,57,202,130,48,34,1,0,49,130,47,32,135,130,
|
||||
47,50,5,0,0,55,17,51,17,33,21,49,75,1,10,1,2,5,254,53,58,132,31,131,79,32,164,130,31,56,12,0,0,51,17,51,23,55,51,17,7,17,3,35,3,17,20,100,99,101,100,65,107,57,106,130,130,42,254,253,
|
||||
251,1,1,197,254,239,1,19,254,130,52,34,1,0,41,130,83,32,142,65,159,5,35,51,3,51,19,130,86,130,48,38,45,3,98,186,72,95,186,130,46,55,90,1,166,253,250,1,166,254,90,0,0,2,0,35,255,250,
|
||||
1,149,2,18,0,5,0,25,130,229,63,50,16,35,34,16,18,50,62,3,52,46,3,34,14,3,20,30,2,220,184,184,184,167,34,27,30,20,13,13,20,30,27,131,8,33,14,14,130,22,50,17,253,234,2,22,254,37,8,26,
|
||||
43,78,106,78,44,26,8,8,26,44,130,8,33,43,26,130,179,38,2,0,44,255,255,1,139,132,179,32,30,131,83,71,166,5,45,43,1,21,55,50,22,21,20,6,43,1,28,1,30,130,3,8,47,49,35,17,50,206,32,46,
|
||||
22,10,10,21,42,30,93,99,85,91,85,84,108,1,1,75,174,1,10,19,31,31,17,17,31,31,18,195,252,80,70,71,89,5,21,55,48,50,29,2,6,130,90,45,0,2,0,13,255,184,1,171,2,15,0,12,0,32,131,91,39,17,
|
||||
20,7,23,21,35,39,6,143,182,39,198,184,40,84,48,82,40,58,147,187,40,14,254,245,123,67,97,44,91,27,149,193,38,2,0,38,0,0,1,145,130,191,34,9,0,24,130,99,34,35,21,22,73,125,5,35,15,1,35,
|
||||
17,73,20,5,8,45,7,23,35,39,38,213,99,68,39,34,51,53,139,3,72,179,79,83,57,44,122,79,111,97,1,205,184,1,2,2,46,45,43,47,242,218,2,5,89,69,45,69,16,229,217,1,130,184,42,1,0,42,255,246,
|
||||
1,141,2,17,0,54,130,91,44,21,46,2,35,34,6,21,20,30,7,23,30,3,73,135,16,32,39,69,75,6,8,95,30,2,23,1,109,6,21,67,35,62,61,6,14,11,25,12,31,9,33,1,23,42,48,29,101,89,43,78,18,18,7,27,
|
||||
86,45,45,66,61,69,34,48,47,24,103,87,18,40,32,27,8,1,245,71,4,13,21,41,48,11,18,15,11,10,5,7,3,5,1,4,17,33,58,39,78,74,16,9,8,73,5,16,27,46,45,46,37,14,6,17,31,50,34,72,82,5,8,9,84,
|
||||
93,5,32,9,130,143,32,175,130,235,32,7,130,233,56,53,33,21,35,17,7,17,10,1,164,172,75,1,203,59,59,254,54,1,1,203,0,1,0,37,130,187,32,147,130,35,32,24,66,163,5,32,20,74,49,5,8,50,17,
|
||||
51,17,20,14,3,34,46,3,37,76,6,19,43,32,67,48,75,6,22,38,68,95,70,38,22,7,166,1,96,254,153,26,35,34,18,54,67,1,95,254,173,33,48,53,33,22,21,32,50,44,130,75,32,13,130,111,32,171,130,
|
||||
75,8,32,6,0,0,51,3,51,27,1,51,3,174,161,73,134,134,72,161,2,6,254,58,1,198,253,250,0,1,255,249,0,0,1,190,130,35,32,12,135,35,131,38,47,35,11,1,75,81,63,58,63,83,64,57,64,81,73,72,73,
|
||||
130,47,44,99,1,157,254,98,1,158,253,250,1,184,254,72,130,55,32,255,130,55,32,185,67,123,5,8,33,19,39,51,23,55,51,7,19,35,39,7,35,184,160,80,121,123,81,165,177,80,141,141,80,1,19,243,
|
||||
195,195,243,254,237,218,218,130,139,32,5,130,47,32,178,130,47,36,8,0,0,55,3,131,47,50,3,21,35,182,176,79,135,134,80,177,75,234,1,28,228,228,254,227,233,130,34,33,0,33,130,4,32,151,
|
||||
130,39,32,9,65,35,5,60,1,33,21,5,53,1,41,1,102,254,224,1,40,254,138,1,24,1,203,59,53,254,106,58,1,56,1,147,0,130,42,41,0,104,255,189,1,80,2,73,0,7,130,12,55,39,17,51,21,35,17,51,1,
|
||||
79,162,162,231,231,2,18,1,253,226,56,2,140,0,1,0,76,151,10,41,19,1,35,1,109,1,35,70,254,222,76,150,7,130,31,138,67,52,19,51,17,35,53,51,17,7,104,231,231,163,163,2,73,253,116,56,2,30,
|
||||
1,130,90,37,0,37,1,63,1,147,65,75,5,33,19,23,131,233,45,55,252,150,82,100,101,82,150,2,6,198,141,141,198,131,139,55,255,241,255,190,1,199,255,247,0,3,0,0,5,33,53,33,1,198,254,44,1,
|
||||
212,66,56,131,27,39,0,124,1,160,1,60,2,57,131,27,131,63,39,207,108,82,109,2,57,153,153,130,27,8,175,2,0,48,255,246,1,136,1,143,0,17,0,54,0,0,55,50,62,3,53,34,35,38,14,4,21,20,22,39,
|
||||
52,62,3,23,48,60,1,46,6,35,7,53,50,54,51,21,50,30,2,21,7,35,54,39,6,35,34,38,204,32,48,23,13,2,10,21,24,45,39,32,22,13,51,118,28,50,69,81,45,2,3,7,9,15,18,26,16,122,18,58,34,38,58,
|
||||
52,29,1,61,2,2,38,99,64,79,44,26,33,49,27,17,1,2,3,10,18,28,20,37,35,72,36,51,28,16,1,1,14,7,17,10,16,10,12,7,5,2,54,2,1,12,33,65,47,241,25,27,61,63,0,0,2,0,50,255,247,1,134,2,49,0,
|
||||
9,0,30,0,0,54,50,54,53,52,38,34,6,21,20,39,62,4,67,150,5,130,127,8,57,47,1,7,35,17,51,172,112,50,51,110,52,3,1,5,18,23,42,25,71,87,88,59,32,62,16,15,7,61,68,45,82,68,67,83,83,67,68,
|
||||
212,3,8,20,16,12,102,101,98,106,29,15,15,49,2,47,0,1,0,59,130,91,32,125,130,239,35,20,0,0,1,131,84,36,22,51,50,55,21,72,197,7,8,34,23,21,38,1,13,65,72,72,65,62,49,47,78,85,110,110,
|
||||
85,78,47,49,1,89,74,76,76,74,43,65,32,106,196,106,32,65,43,139,159,32,7,133,159,133,158,38,19,51,17,35,39,14,4,130,155,8,35,53,52,54,51,50,30,2,31,1,122,200,48,104,48,200,68,62,6,3,
|
||||
8,26,27,41,20,59,88,87,70,25,42,24,17,3,4,45,150,131,158,51,1,109,253,209,49,3,7,21,15,13,106,98,101,102,12,17,17,6,7,0,130,0,34,2,0,37,130,163,32,147,130,163,37,5,0,26,0,0,19,130,
|
||||
165,35,51,52,7,20,130,168,32,54,133,169,132,95,8,42,22,29,1,32,227,47,69,224,227,62,67,42,62,46,70,82,89,109,105,79,91,90,254,218,1,89,68,48,116,165,56,79,18,21,64,29,109,95,93,110,
|
||||
97,73,48,130,83,42,1,0,40,0,3,1,144,2,36,0,19,132,247,37,29,1,51,21,35,17,130,1,33,53,51,130,77,61,59,1,21,1,40,35,31,125,125,68,122,122,65,64,108,1,237,25,37,75,57,254,217,1,39,57,
|
||||
52,78,62,55,133,147,36,50,255,70,1,134,130,147,32,9,73,49,5,77,51,8,44,51,17,20,6,43,1,53,51,50,62,2,61,1,137,254,8,60,22,23,222,99,99,53,51,51,159,61,90,81,130,136,28,42,23,10,1,5,
|
||||
18,24,42,25,71,91,91,60,48,52,28,53,142,150,82,68,65,77,1,80,254,110,86,86,58,22,36,37,18,59,2,6,16,12,10,101,100,98,101,20,29,130,162,41,0,62,0,1,1,122,2,49,0,18,74,253,5,8,45,17,
|
||||
35,53,52,38,35,34,6,29,1,35,17,51,21,54,253,53,72,68,40,37,47,56,68,68,37,1,146,78,67,255,0,250,45,48,61,59,223,2,47,218,60,0,2,0,139,130,59,38,45,2,30,0,11,0,17,130,74,8,40,35,34,
|
||||
61,1,52,59,1,50,29,1,20,7,53,51,17,35,17,1,35,56,10,10,56,9,161,161,68,1,202,10,64,9,9,64,10,127,59,254,123,1,74,130,232,34,2,0,100,130,231,32,84,130,59,34,12,0,24,130,121,130,47,32,
|
||||
20,132,221,35,54,53,17,55,138,72,39,165,174,127,112,105,29,37,59,132,72,43,1,76,58,254,98,161,59,52,50,1,100,126,133,79,39,0,1,0,41,0,2,1,142,132,131,38,0,55,23,35,39,7,21,130,183,
|
||||
53,17,55,51,210,188,81,154,51,70,70,181,80,245,243,201,45,156,2,27,254,201,161,130,118,130,47,32,133,130,179,36,51,2,8,0,5,130,117,131,164,41,35,133,173,69,104,2,7,253,250,1,72,63,
|
||||
5,46,20,255,254,1,164,1,143,0,30,0,0,1,50,22,21,130,198,36,52,35,34,6,7,138,7,48,51,21,54,51,50,23,62,1,1,68,43,52,61,52,26,26,3,132,4,52,62,62,31,42,52,26,13,48,1,143,69,53,254,234,
|
||||
1,5,84,34,37,254,238,130,6,42,33,36,254,236,1,133,18,29,49,22,27,130,128,32,1,65,111,5,33,1,147,65,111,20,32,23,65,111,9,33,64,4,65,112,12,35,1,133,48,60,66,31,5,42,42,255,247,1,141,
|
||||
1,144,0,9,0,17,67,179,11,32,18,130,171,8,40,20,32,53,52,174,92,58,59,90,59,21,166,94,254,158,44,72,80,80,70,70,80,80,1,28,102,102,205,205,102,0,2,0,50,255,78,1,134,1,136,0,67,79,6,
|
||||
38,54,53,52,34,21,20,19,131,57,8,62,6,35,34,46,2,47,1,21,35,17,51,23,62,4,176,103,48,199,107,66,89,87,71,25,41,24,18,3,3,68,61,7,1,6,20,25,41,38,82,67,148,148,67,1,16,105,99,101,103,
|
||||
12,18,17,6,6,221,2,48,49,2,8,20,16,13,152,91,35,51,17,35,53,67,171,13,38,160,104,48,200,216,62,68,66,165,5,41,70,87,89,66,23,41,26,19,4,4,134,91,44,6,253,208,221,2,8,21,15,13,103,101,
|
||||
99,105,132,99,36,0,0,1,0,69,130,4,36,115,1,142,0,19,130,7,35,50,22,31,1,71,239,5,33,29,1,130,173,8,36,7,62,1,1,12,29,52,11,11,4,16,56,31,56,71,68,68,2,17,69,1,142,15,7,8,65,5,12,20,
|
||||
60,35,245,1,133,53,27,35,130,54,46,0,69,255,254,1,115,1,151,0,38,0,0,55,30,1,130,250,34,39,46,1,80,126,9,39,46,2,35,34,21,20,22,23,79,243,7,8,78,47,1,69,53,109,71,91,83,57,14,32,65,
|
||||
44,33,62,14,15,6,19,63,33,90,36,57,70,69,88,73,31,70,20,20,88,27,14,32,35,49,15,15,53,44,22,38,36,20,11,6,6,62,4,11,17,57,25,29,8,11,46,55,57,66,12,6,6,0,0,0,1,0,87,0,6,1,97,2,4,0,
|
||||
17,130,115,41,51,21,35,34,46,3,53,17,51,21,130,9,57,21,20,216,136,125,25,33,41,24,16,68,162,162,65,58,3,15,26,50,34,1,124,118,58,204,70,132,55,40,54,255,246,1,130,1,133,0,21,130,55,
|
||||
33,53,51,80,10,5,34,55,51,19,65,74,6,8,32,54,68,86,44,62,3,68,1,64,1,3,17,23,45,27,79,73,145,244,241,102,53,39,251,254,124,42,2,7,19,13,12,74,132,67,32,29,130,128,32,155,130,67,53,
|
||||
6,0,0,1,51,3,35,3,51,19,1,84,70,148,86,147,71,120,1,133,254,123,130,3,32,186,130,38,39,0,1,255,248,255,255,1,192,130,39,33,12,0,132,39,33,39,7,131,42,48,55,51,23,1,124,67,97,63,68,
|
||||
65,65,97,68,68,53,76,60,130,47,34,123,215,215,130,5,34,208,192,192,132,55,33,0,20,130,55,32,163,130,55,35,11,0,0,37,71,43,5,57,39,51,23,55,51,1,1,162,78,122,120,78,162,149,76,110,109,
|
||||
76,203,203,155,155,204,185,141,141,77,151,5,38,68,1,137,1,134,0,31,130,12,32,18,77,244,5,44,53,51,50,62,4,53,52,53,35,34,38,53,19,130,230,59,22,51,23,3,1,134,3,12,24,47,32,195,176,
|
||||
16,23,13,8,3,1,133,71,72,1,68,29,41,137,1,130,122,56,135,48,17,47,52,36,59,12,24,22,34,17,14,4,2,78,49,1,6,229,49,50,1,1,73,132,239,32,64,130,143,32,119,130,95,8,41,14,0,0,55,51,23,
|
||||
33,53,62,3,39,35,53,33,21,2,137,237,1,254,202,15,50,105,69,1,229,1,45,238,52,52,59,17,58,122,82,1,50,60,254,235,130,54,8,32,0,1,0,63,255,178,1,120,2,84,0,41,0,0,1,21,20,7,22,29,1,20,
|
||||
22,59,1,21,34,35,34,46,3,61,1,83,197,7,130,9,33,62,3,130,22,8,61,35,34,6,1,11,72,72,38,42,29,31,13,38,54,27,14,3,38,43,51,51,43,38,3,14,27,54,38,44,29,42,38,1,215,100,95,17,17,96,99,
|
||||
34,29,62,20,26,44,30,23,86,43,32,66,32,42,87,23,30,44,26,19,62,29,130,98,53,0,188,255,200,0,252,2,63,0,3,0,0,23,35,17,51,252,64,64,55,2,117,141,135,32,19,84,60,5,36,50,51,50,30,3,134,
|
||||
142,130,119,130,9,33,14,3,69,35,5,130,141,55,55,38,172,37,42,29,30,14,37,54,27,15,2,38,44,51,51,44,38,2,15,27,54,37,130,132,41,37,72,72,1,115,100,33,29,62,19,131,129,33,87,42,130,129,
|
||||
45,43,86,24,29,44,26,20,62,29,33,100,96,17,16,130,248,42,1,0,22,0,177,1,161,1,93,0,33,130,148,34,23,14,4,131,238,39,7,14,1,15,1,39,62,4,131,119,54,55,62,1,55,1,103,58,5,5,17,21,40,
|
||||
25,25,43,30,28,31,16,20,25,3,3,143,16,62,1,66,13,21,21,45,24,20,26,35,36,21,2,3,45,21,21,13,21,22,44,24,21,26,36,35,22,3,3,45,20,130,229,32,21,130,95,45,163,0,106,0,15,0,31,0,47,0,
|
||||
0,55,50,22,130,200,36,6,43,1,34,38,130,197,34,54,59,1,157,15,43,51,104,5,7,7,5,71,4,8,8,4,222,131,9,32,70,131,4,32,221,136,9,35,105,7,5,81,131,12,150,4,42,0,0,2,0,159,255,235,1,25,
|
||||
2,9,90,167,5,33,18,34,82,231,5,59,7,51,23,7,35,53,245,50,35,35,50,35,84,46,29,1,101,1,145,35,49,35,35,49,105,196,155,155,130,51,42,63,255,147,1,121,1,242,0,5,0,28,130,177,48,17,14,
|
||||
1,21,20,19,17,54,55,21,6,7,21,35,53,46,1,90,19,6,8,62,22,23,21,38,243,50,58,146,57,39,45,51,38,78,102,100,80,38,61,35,40,49,1,38,6,73,67,134,1,25,254,215,2,25,59,21,3,100,101,6,107,
|
||||
92,95,104,4,97,98,5,20,60,25,0,1,0,40,255,255,1,144,2,16,0,27,130,89,38,51,21,33,53,51,53,35,130,3,81,218,6,32,21,71,122,5,8,39,51,21,35,202,197,254,153,87,73,73,82,79,33,52,9,10,48,
|
||||
42,50,50,136,136,59,59,59,161,50,82,88,88,10,5,5,64,30,53,63,88,50,0,131,223,38,55,0,63,1,128,1,125,130,223,35,31,0,0,54,82,67,6,8,41,54,20,7,23,7,39,6,34,39,7,39,55,38,52,55,39,55,
|
||||
23,54,50,23,55,23,7,187,65,46,46,65,46,204,22,60,34,62,31,73,31,62,34,60,22,137,10,49,148,44,61,43,43,61,67,73,30,57,35,60,19,19,60,35,57,30,137,10,75,219,10,36,24,0,0,1,7,130,160,
|
||||
33,7,21,88,161,9,32,39,130,194,8,37,39,51,23,55,1,178,120,91,115,33,148,148,75,148,148,33,115,91,119,79,135,134,2,6,194,39,53,11,39,182,182,39,11,53,39,194,228,228,130,178,41,0,2,0,
|
||||
188,255,206,0,252,2,57,83,195,5,36,23,35,17,51,53,67,9,5,40,64,64,50,1,8,92,1,7,0,130,35,59,64,255,188,1,119,2,16,0,15,0,75,0,0,37,62,1,53,52,38,39,38,39,14,1,21,20,22,23,69,167,11,
|
||||
33,53,22,85,40,5,130,28,35,46,4,53,52,89,5,5,32,54,86,84,10,133,47,8,53,4,21,20,6,1,10,21,28,48,46,25,22,22,27,48,45,25,61,25,21,69,72,25,57,16,16,58,51,36,42,37,47,8,3,28,25,39,17,
|
||||
14,38,33,25,21,68,74,24,54,14,14,51,51,37,40,36,130,22,33,29,24,131,22,42,142,12,35,15,26,44,25,14,13,12,36,132,7,63,37,18,34,23,44,66,10,5,5,57,26,32,25,20,30,26,4,2,16,14,28,23,34,
|
||||
19,28,50,16,18,34,24,43,59,131,25,33,27,26,133,25,39,15,15,28,23,33,20,28,50,133,251,42,109,1,212,1,75,2,27,0,11,0,23,73,51,13,33,43,1,73,63,9,39,1,66,58,9,9,58,9,155,131,5,37,8,1,
|
||||
213,9,52,9,136,2,48,0,0,3,255,248,0,40,1,192,1,218,0,7,0,15,0,36,65,245,9,33,18,50,92,21,5,33,22,52,130,255,35,23,21,38,35,75,119,11,8,53,142,156,111,111,156,111,95,188,133,133,188,
|
||||
134,92,78,62,57,30,43,34,47,52,52,47,46,31,36,51,61,79,105,147,105,105,147,1,34,127,179,127,127,179,152,126,66,15,38,21,48,49,49,47,18,36,17,131,179,8,41,3,0,92,0,162,1,91,2,18,0,3,
|
||||
0,18,0,53,0,0,37,35,53,51,39,34,35,34,14,4,21,20,22,51,50,54,7,52,62,2,23,60,1,46,2,88,232,5,8,122,62,6,51,50,22,29,1,35,39,6,35,34,38,1,91,247,247,55,5,8,25,24,37,19,20,8,36,22,49,
|
||||
41,201,37,58,70,33,8,15,32,22,26,50,11,12,2,18,7,17,12,17,18,9,57,73,45,8,39,54,47,59,163,43,178,1,3,6,11,18,13,24,24,61,16,33,43,14,7,4,8,10,22,14,11,11,6,6,44,1,6,2,6,2,3,1,57,64,
|
||||
159,38,45,44,0,2,0,50,0,49,1,134,1,112,0,6,0,13,0,0,1,21,7,23,21,39,53,55,133,5,50,1,134,112,112,174,7,111,111,173,173,1,112,67,93,93,66,145,28,79,132,5,35,146,0,0,4,65,59,8,56,9,0,
|
||||
27,0,35,0,43,0,0,19,22,62,2,53,52,38,43,1,23,30,1,23,35,38,39,130,9,32,21,130,224,36,50,21,20,14,1,67,78,6,65,88,7,54,175,21,36,27,15,29,21,49,86,14,25,46,52,30,17,21,24,27,47,92,103,
|
||||
34,147,65,89,10,53,1,13,1,2,6,18,15,19,20,102,5,33,72,44,26,33,103,242,74,21,32,172,65,94,11,130,172,41,0,109,1,183,1,75,1,235,0,3,130,12,130,106,38,1,74,220,220,1,183,51,66,31,5,45,
|
||||
101,1,50,1,82,2,16,0,7,0,15,0,0,18,93,253,14,56,190,59,42,42,59,41,22,98,69,69,98,69,1,94,39,55,39,39,55,138,65,91,65,65,91,133,59,40,24,255,255,1,159,1,151,0,11,131,59,92,65,11,56,
|
||||
19,33,53,33,251,164,164,62,165,165,62,164,254,121,1,135,1,36,59,115,115,59,114,254,105,87,43,5,40,115,1,133,1,69,2,173,0,24,130,143,130,245,37,7,51,21,35,53,54,85,161,5,8,47,34,6,15,
|
||||
1,53,54,51,50,22,1,66,17,62,70,152,210,77,32,42,37,28,17,42,12,13,39,51,57,58,2,94,20,33,64,61,39,38,72,29,40,36,18,25,11,6,6,41,20,130,197,32,1,130,223,38,130,1,75,2,176,0,39,131,
|
||||
79,32,6,88,180,10,91,20,23,8,51,7,22,1,75,68,55,21,49,15,14,50,42,26,48,43,31,31,31,29,36,30,27,21,44,12,12,47,44,49,63,33,30,71,1,214,37,47,7,4,4,42,18,26,25,25,27,38,22,21,18,22,
|
||||
8,130,13,38,13,42,33,28,29,7,13,130,252,39,1,0,131,1,181,1,53,2,79,123,5,41,51,7,35,235,73,120,56,2,57,131,130,26,51,0,1,0,37,255,107,1,146,1,132,0,36,0,0,37,50,54,63,1,21,133,147,
|
||||
33,14,4,130,154,36,39,21,35,17,51,66,199,5,8,63,53,55,51,16,21,20,1,120,7,12,4,3,27,29,19,26,4,3,1,4,16,22,42,27,26,47,11,60,64,45,37,43,59,3,65,49,4,2,2,52,15,26,13,13,2,7,18,14,11,
|
||||
28,26,192,2,24,241,48,53,53,38,251,254,226,24,29,130,108,42,1,0,48,255,185,1,136,2,7,0,16,76,95,7,47,16,21,6,34,47,1,17,34,38,52,54,216,175,52,70,1,130,60,8,34,69,99,99,2,6,253,182,
|
||||
2,32,253,229,5,2,1,1,1,39,85,121,85,0,0,1,0,159,0,198,1,25,1,63,0,7,0,0,66,114,7,39,195,50,35,35,50,35,1,63,130,4,33,35,50,131,35,36,143,255,119,1,41,130,43,130,95,35,33,22,21,20,65,
|
||||
92,8,52,39,48,58,1,1,0,40,91,14,31,8,8,24,27,91,73,21,22,41,37,59,130,173,34,46,11,94,132,151,40,114,1,132,1,70,2,167,0,10,131,151,37,21,35,53,51,53,7,130,239,56,250,75,204,76,83,85,
|
||||
51,1,171,38,38,212,14,40,13,0,3,0,83,0,162,1,101,2,16,130,9,37,13,0,21,0,0,37,130,41,8,47,2,34,6,21,20,22,50,54,53,52,22,32,53,52,54,50,22,21,1,86,249,249,88,69,46,45,71,45,56,254,
|
||||
239,73,127,73,163,43,1,25,47,54,54,49,49,54,54,197,143,71,130,0,130,114,67,163,15,33,55,21,130,112,35,39,53,51,23,132,7,48,223,173,111,111,166,174,174,112,112,222,28,145,66,93,93,67,
|
||||
146,132,6,41,0,4,0,19,255,162,1,165,2,64,130,127,36,6,0,17,0,28,130,242,38,23,5,39,23,51,53,55,70,111,8,33,55,3,130,72,32,51,131,14,8,44,53,51,1,155,9,254,120,9,198,102,51,43,43,50,
|
||||
144,134,187,82,87,48,75,203,75,1,47,37,91,37,203,144,43,188,37,65,65,42,183,1,86,14,39,13,252,39,39,130,81,137,91,34,28,0,39,133,89,32,5,66,236,15,34,39,54,51,130,224,34,20,6,1,143,
|
||||
100,34,1,73,86,66,254,7,42,41,13,12,1,39,51,57,59,28,254,252,138,113,52,190,77,39,39,71,30,39,36,19,25,12,6,6,42,19,51,27,23,45,1,226,134,123,34,4,0,18,132,215,32,70,134,215,32,56,
|
||||
133,125,34,23,51,39,138,215,33,39,20,67,43,10,67,42,26,132,243,34,202,102,1,130,244,8,32,49,145,134,45,72,55,21,48,13,13,41,46,36,42,38,34,33,30,31,37,33,25,24,45,10,10,46,44,50,62,
|
||||
33,30,72,65,11,13,8,68,168,36,47,7,4,4,41,18,29,47,28,37,23,21,20,20,8,4,4,42,12,41,32,29,29,8,14,0,0,2,0,73,255,247,1,111,2,27,0,30,0,38,0,0,55,50,54,63,1,21,14,2,35,34,38,53,52,62,
|
||||
4,61,1,51,21,20,14,3,21,20,22,73,68,7,8,56,235,29,66,18,19,7,24,69,34,82,78,19,29,34,29,19,71,26,37,38,26,47,71,44,32,32,44,32,48,24,11,12,65,5,12,21,65,54,24,43,30,30,24,31,17,69,
|
||||
61,30,48,34,31,39,21,31,36,1,129,91,1,6,45,3,0,5,0,0,1,179,2,131,0,3,0,6,0,130,128,36,1,35,39,51,3,90,85,9,37,1,9,56,84,68,52,90,90,9,46,2,38,92,254,61,1,10,61,253,250,135,135,2,6,
|
||||
0,130,53,143,63,34,7,35,55,139,63,36,59,84,56,72,106,132,63,39,40,193,41,77,169,2,130,92,140,64,36,3,0,5,255,255,132,127,32,6,79,77,5,32,19,130,63,34,51,23,35,138,66,38,220,61,51,78,
|
||||
69,78,51,90,223,5,133,68,33,101,62,130,69,32,151,138,134,131,135,33,255,254,130,71,61,123,0,20,0,23,0,31,0,0,19,34,6,21,35,52,54,51,50,22,51,50,54,53,55,51,20,6,35,34,38,138,85,49,
|
||||
169,12,12,47,36,34,26,62,15,11,13,1,46,34,36,28,58,45,138,164,45,81,19,16,33,43,34,17,9,8,25,51,35,254,109,139,103,32,4,136,175,38,2,0,10,0,22,0,34,91,131,12,81,53,11,72,74,11,138,
|
||||
187,32,147,72,84,9,33,9,190,136,89,32,56,72,93,13,32,0,136,207,38,149,0,2,0,14,0,30,132,101,52,39,20,22,23,51,62,1,53,52,38,34,6,23,19,35,39,35,7,35,19,38,68,11,5,32,20,130,97,52,56,
|
||||
18,16,44,16,19,33,47,34,112,159,77,40,193,41,77,159,47,60,84,60,130,98,55,110,17,26,6,6,26,17,21,31,31,101,254,25,135,135,1,231,28,51,40,55,55,40,51,130,89,38,2,255,255,1,182,2,7,130,
|
||||
109,32,19,130,97,40,17,35,3,55,21,51,21,35,53,131,88,8,40,37,7,35,23,55,7,235,37,75,186,128,202,127,37,68,150,1,23,1,122,1,111,1,190,1,13,254,244,55,188,59,134,133,2,5,2,61,153,1,60,
|
||||
0,78,87,5,38,119,1,137,2,16,0,40,130,12,91,224,8,49,55,21,6,7,22,21,20,6,35,34,39,53,22,51,50,53,52,39,88,3,6,8,66,23,21,38,1,8,38,57,32,14,25,66,50,77,51,37,56,33,45,38,45,25,24,31,
|
||||
46,26,54,81,48,23,112,104,77,51,51,1,213,32,60,74,46,62,91,59,46,73,21,5,36,32,31,30,9,45,11,31,22,32,3,42,74,93,56,117,151,32,71,45,130,187,38,52,0,3,1,132,2,135,71,103,5,8,41,55,
|
||||
33,21,33,17,33,21,35,31,1,21,35,19,35,39,51,127,1,4,254,178,1,71,253,1,241,242,142,57,84,68,63,59,2,6,59,153,1,59,1,48,93,130,175,36,2,0,52,0,4,150,59,34,7,35,55,138,59,36,173,84,56,
|
||||
72,64,135,59,33,140,93,130,60,135,59,32,136,130,119,34,18,0,0,140,119,66,185,5,138,62,38,86,61,52,78,70,78,52,136,65,33,110,62,131,66,33,0,3,130,127,32,0,130,127,32,133,130,67,34,23,
|
||||
0,35,74,129,25,32,3,134,213,35,23,51,21,35,74,141,11,33,9,58,137,222,39,2,63,8,52,9,9,52,8,133,5,33,253,252,132,173,42,59,0,2,0,66,255,254,1,118,2,131,65,31,5,8,49,1,35,17,23,21,33,
|
||||
53,51,17,35,53,33,39,35,39,51,1,117,115,115,254,206,116,116,1,50,106,56,84,68,1,202,254,111,1,57,59,1,144,59,33,92,0,0,0,2,0,66,0,3,130,59,65,91,6,130,59,32,51,132,59,32,39,130,59,
|
||||
130,227,56,1,117,116,116,254,206,115,115,1,50,60,84,56,72,1,207,254,112,59,57,1,145,1,59,125,65,31,5,133,59,65,31,6,143,59,34,51,23,35,137,62,32,148,65,30,5,137,65,32,95,65,31,7,137,
|
||||
187,65,31,28,34,23,35,17,131,153,32,55,131,213,65,31,12,32,188,135,161,33,2,61,67,88,11,32,115,132,170,34,1,145,59,131,227,45,17,0,4,1,167,2,11,0,18,0,37,0,0,55,92,29,5,8,79,43,1,21,
|
||||
51,21,35,21,50,19,50,30,3,20,14,3,43,1,53,35,53,51,53,50,200,19,36,42,30,20,20,30,42,36,19,62,99,99,62,1,31,56,61,45,29,29,45,61,56,30,139,46,46,138,62,9,27,42,75,98,75,42,27,8,162,
|
||||
53,188,1,205,12,35,55,95,125,96,54,35,11,245,53,220,131,103,42,42,0,0,1,142,2,130,0,20,0,30,68,149,22,36,23,51,17,35,3,130,2,33,51,19,68,148,16,41,140,72,95,186,71,4,98,186,2,88,68,
|
||||
145,10,32,82,92,232,5,37,2,6,254,90,0,3,92,235,6,38,135,0,5,0,9,0,29,92,237,7,35,55,35,39,51,92,241,16,37,238,57,84,68,3,33,92,245,5,34,29,28,34,133,8,42,31,2,17,253,234,2,22,25,93,
|
||||
253,175,92,247,19,135,95,32,136,130,95,32,12,92,157,5,36,16,35,34,16,55,66,235,5,32,2,93,84,15,32,184,65,210,5,32,77,150,101,37,88,62,93,93,254,11,151,103,42,251,1,149,2,129,0,20,0,
|
||||
26,0,46,65,41,14,33,55,53,69,191,5,33,23,50,93,202,16,38,169,11,13,47,36,35,25,69,199,6,39,35,29,58,34,184,184,184,168,145,127,32,87,65,64,10,32,70,131,241,44,254,37,8,26,44,78,105,
|
||||
78,44,27,7,7,27,132,8,36,26,0,0,0,4,65,79,6,131,239,36,17,0,29,0,49,65,81,7,32,37,87,16,10,69,218,11,65,101,16,33,1,30,69,225,10,32,19,145,136,32,17,131,124,32,49,66,150,11,33,253,
|
||||
244,65,17,17,8,32,1,0,46,0,65,1,137,1,137,0,11,0,0,1,7,23,7,39,7,39,55,39,55,23,55,1,137,129,129,45,128,129,45,130,5,38,129,128,1,94,121,121,42,135,2,47,0,3,0,1,255,234,1,183,2,34,
|
||||
0,10,0,21,0,39,103,247,10,46,39,20,23,55,38,35,34,14,3,37,7,22,21,16,35,80,146,5,51,53,16,51,50,23,55,220,17,27,30,20,13,7,184,26,49,7,185,26,59,132,12,40,1,70,65,30,184,83,46,54,36,
|
||||
133,6,32,54,131,157,54,53,56,42,248,58,208,56,42,249,58,8,26,44,78,205,88,65,105,254,245,56,72,25,130,7,48,1,11,56,72,0,0,2,0,46,255,246,1,138,2,131,0,17,130,123,40,0,1,51,17,20,35,
|
||||
34,53,17,130,6,8,44,22,51,50,62,2,53,3,35,39,51,1,62,75,170,176,75,39,61,30,40,19,7,43,57,84,69,2,6,254,160,176,189,1,83,254,160,67,52,18,33,36,25,1,135,92,161,71,34,7,35,55,139,71,
|
||||
35,12,84,57,72,144,71,35,227,92,92,0,130,0,139,147,33,24,0,146,147,66,196,5,139,78,32,98,66,191,5,139,81,33,17,34,130,153,33,198,62,130,82,34,3,0,47,136,227,34,29,0,41,146,81,32,19,
|
||||
66,36,22,44,1,62,76,171,176,75,40,61,30,39,19,7,5,66,30,10,144,103,32,158,72,7,15,32,2,72,111,6,35,130,0,8,0,86,29,5,38,21,35,55,3,51,23,19,130,187,44,1,98,80,177,75,1,177,79,135,90,
|
||||
84,57,73,130,74,39,227,233,234,1,28,229,1,97,130,170,41,0,2,0,42,255,255,1,142,2,6,130,55,32,21,99,245,10,8,41,55,50,22,21,20,43,1,21,35,17,51,21,50,210,49,61,63,47,93,103,83,95,178,
|
||||
103,75,75,103,186,43,48,47,42,180,240,75,74,150,127,2,6,92,0,130,222,130,67,32,242,130,67,8,127,28,0,48,0,0,19,20,30,3,21,20,14,1,38,39,53,22,51,50,54,53,52,46,3,53,52,62,2,63,1,38,
|
||||
54,46,2,35,34,6,21,17,35,17,52,54,51,50,21,34,6,234,34,48,48,33,51,78,88,38,49,51,41,45,33,47,47,33,24,35,34,12,12,1,3,10,14,38,27,46,41,68,73,82,155,47,72,1,50,20,33,27,32,53,35,43,
|
||||
57,20,5,16,56,21,36,29,24,37,25,27,45,30,28,44,24,15,2,2,1,15,23,22,16,48,50,254,123,1,133,77,74,152,44,130,138,41,0,3,0,38,255,245,1,146,2,69,130,9,34,18,0,61,130,156,49,35,39,51,
|
||||
19,50,62,2,39,48,42,1,35,14,1,21,20,22,55,130,3,50,31,1,35,38,39,14,1,35,34,38,53,52,54,59,1,60,2,46,5,81,15,9,8,99,1,12,57,118,72,24,36,52,26,10,1,36,47,11,60,52,51,225,10,5,5,68,
|
||||
9,7,21,76,38,65,80,91,91,92,2,6,8,15,20,30,18,38,71,16,17,3,25,11,24,17,24,26,13,168,1,194,131,253,230,29,47,50,26,2,32,44,38,36,183,116,25,55,15,15,22,37,32,37,64,60,62,70,1,15,9,
|
||||
18,13,16,11,10,5,18,10,9,63,1,9,3,8,3,4,2,149,171,35,7,35,55,3,131,171,33,42,2,167,170,37,84,118,57,103,80,37,131,170,33,1,35,167,171,34,2,69,131,176,172,65,87,9,39,6,0,21,0,64,0,0,
|
||||
19,130,171,34,51,23,35,132,174,65,90,41,39,220,66,52,90,56,90,52,97,65,92,45,38,2,26,88,131,131,254,105,65,94,20,33,63,69,65,94,20,135,175,46,51,0,24,0,39,0,82,0,0,1,34,46,2,35,34,
|
||||
75,234,5,42,30,1,51,50,54,61,1,51,20,14,2,174,191,53,1,13,21,31,16,23,11,26,45,36,37,21,34,30,13,12,13,46,5,13,30,101,173,205,50,1,209,17,20,17,54,43,55,27,26,26,13,14,15,29,33,21,
|
||||
254,90,148,217,66,56,24,32,4,66,227,6,40,29,0,11,0,23,0,38,0,81,74,25,25,32,19,66,77,45,32,63,68,115,10,32,6,66,85,46,33,1,214,68,147,11,33,254,85,181,211,52,114,0,7,0,15,0,58,0,73,
|
||||
0,0,18,34,6,20,22,50,54,52,6,34,88,7,5,32,19,67,183,31,67,58,12,44,240,46,33,33,46,33,14,84,60,60,84,60,63,67,191,33,32,194,139,237,46,2,70,31,44,31,31,44,118,56,80,56,56,80,254,249,
|
||||
67,204,32,33,254,155,136,236,67,215,5,55,5,255,245,1,179,1,143,0,8,0,19,0,89,0,0,1,34,6,23,51,54,39,46,1,130,161,33,1,39,85,233,5,40,37,21,35,28,2,30,5,51,22,79,184,7,34,46,2,47,96,
|
||||
42,8,32,59,113,200,6,83,206,5,8,164,30,2,31,1,62,4,51,50,22,23,30,1,21,1,56,31,31,3,121,1,2,3,27,217,26,26,14,1,28,53,44,37,1,75,182,2,4,6,10,14,21,12,34,52,9,10,5,15,48,25,25,42,22,
|
||||
16,2,3,1,4,16,21,36,22,57,60,70,68,50,42,30,19,46,13,14,44,65,19,30,18,12,2,2,1,3,14,19,36,22,58,48,8,2,1,1,90,54,64,23,22,35,38,254,209,18,59,59,32,38,35,31,136,1,1,28,10,28,13,23,
|
||||
11,14,6,1,17,9,10,60,3,10,16,11,17,16,6,5,2,7,19,15,12,60,56,57,65,28,50,39,14,8,7,58,24,9,13,13,4,5,2,6,15,11,10,59,76,18,42,12,130,248,42,1,0,59,255,119,1,125,1,142,0,37,132,243,
|
||||
42,21,20,22,51,50,55,21,14,1,15,1,77,223,14,130,222,34,54,51,50,98,88,10,35,14,43,15,15,77,222,8,33,82,106,98,99,5,56,88,74,76,76,74,43,65,11,15,2,2,36,32,31,30,8,46,12,32,22,31,3,
|
||||
105,96,98,98,114,5,41,0,3,0,37,255,247,1,147,2,69,130,9,34,9,0,30,69,235,5,32,23,98,25,22,42,21,23,32,1,19,57,118,72,55,46,70,98,30,12,40,92,89,1,254,217,1,194,131,236,98,33,17,145,
|
||||
95,35,7,35,55,7,154,95,36,93,119,56,102,49,147,95,34,2,69,131,147,96,33,0,0,138,195,36,6,0,12,0,33,69,87,8,154,102,39,225,67,52,90,57,90,52,64,148,104,36,26,88,131,131,105,145,202,
|
||||
33,0,4,65,43,6,68,51,5,34,29,0,50,68,51,25,65,65,27,44,69,57,9,9,57,9,155,58,9,9,58,9,39,147,128,68,5,13,32,125,146,137,8,58,0,0,2,0,51,255,252,1,117,2,59,0,13,0,17,0,0,37,51,21,34,
|
||||
35,34,38,61,1,35,53,51,21,20,17,35,39,51,1,37,80,24,71,54,65,90,158,57,119,73,51,54,78,63,201,50,251,86,1,132,131,0,130,0,34,2,0,68,130,59,32,116,149,59,48,19,7,35,55,1,37,79,23,72,
|
||||
53,66,90,158,106,119,57,103,135,60,34,2,7,131,130,61,135,59,36,69,0,6,0,20,65,105,8,32,19,140,126,39,186,66,52,90,56,90,51,40,134,68,70,121,5,32,113,134,131,130,127,32,3,134,127,38,
|
||||
26,0,11,0,23,0,37,65,69,25,141,86,33,1,44,65,56,5,132,5,32,130,134,92,33,1,212,69,49,12,32,95,135,101,54,2,0,42,255,244,1,142,2,27,0,14,0,47,0,0,55,50,54,53,52,38,47,1,90,34,6,38,19,
|
||||
20,30,6,21,20,6,72,186,5,8,96,23,46,1,47,1,7,39,55,39,51,23,55,23,7,22,220,45,60,20,10,10,18,50,43,59,60,145,20,6,19,8,13,6,5,89,88,88,89,107,100,5,27,10,11,103,12,88,67,81,47,106,
|
||||
13,93,36,42,70,71,38,67,15,14,9,69,73,73,69,1,89,1,27,10,29,19,33,29,38,19,86,107,107,94,93,102,8,8,31,12,11,31,34,27,69,49,32,34,28,34,65,115,5,32,62,130,231,44,122,2,32,0,18,0,43,
|
||||
0,0,19,50,22,21,100,121,12,34,23,54,55,71,88,17,54,35,34,46,2,253,53,72,68,39,38,47,56,68,64,4,37,3,26,45,36,37,20,35,71,51,5,40,14,29,21,21,31,17,22,1,145,100,165,9,51,1,132,47,60,
|
||||
99,54,44,54,27,26,26,14,13,15,29,33,21,17,20,17,130,124,40,3,0,43,255,244,1,141,2,69,86,227,7,36,1,35,39,51,18,102,253,8,99,73,7,37,1,15,56,119,73,5,99,78,9,37,1,194,131,253,229,71,
|
||||
99,82,9,35,204,204,102,0,130,65,143,75,35,7,35,55,2,145,75,36,86,118,57,103,96,137,75,34,2,69,131,145,76,137,151,36,6,0,16,0,24,66,77,8,145,78,72,242,6,32,112,138,80,37,26,88,131,131,
|
||||
254,104,143,158,136,159,32,32,130,79,34,34,0,42,72,179,24,145,99,53,1,15,20,32,16,22,12,25,46,36,38,20,35,29,14,12,13,46,5,14,30,118,137,113,36,1,190,17,20,17,65,92,11,33,254,108,142,
|
||||
125,32,4,65,103,6,66,215,5,34,33,0,41,66,217,25,146,126,93,1,10,33,9,11,138,118,66,224,13,32,86,142,115,32,3,130,231,36,49,1,159,1,136,130,249,42,19,0,35,0,0,37,33,53,33,39,35,96,108,
|
||||
13,32,3,142,15,48,1,159,254,121,1,135,161,70,4,7,7,4,70,5,6,6,5,136,9,37,192,59,56,6,5,63,131,18,130,4,33,254,255,130,11,131,35,130,11,32,0,130,0,44,3,0,12,255,222,1,172,1,166,0,7,
|
||||
0,15,131,107,39,55,50,54,53,52,39,7,22,78,242,6,37,6,37,7,22,21,20,78,241,7,8,65,52,54,51,50,23,55,22,222,47,57,10,169,27,56,9,168,27,46,45,59,1,54,61,33,178,75,44,57,34,62,29,94,83,
|
||||
71,46,55,34,43,72,80,42,32,189,37,152,42,31,189,33,70,121,68,52,81,204,40,63,26,70,50,81,102,102,39,63,27,67,55,5,51,61,255,246,1,123,2,59,0,3,0,26,0,0,1,35,39,51,23,51,17,105,15,6,
|
||||
38,61,1,51,21,20,22,51,130,133,8,41,1,13,57,119,73,144,68,63,6,2,5,20,23,38,21,77,61,67,38,43,44,53,1,184,131,182,254,124,57,2,10,23,18,14,72,82,244,240,52,52,59,50,130,84,33,2,0,141,
|
||||
83,34,7,35,55,148,83,36,83,119,56,102,44,143,83,34,2,59,131,147,84,135,83,36,69,0,6,0,29,66,201,8,32,23,145,169,32,55,66,203,6,32,92,139,171,41,42,45,53,2,2,26,88,131,131,61,143,174,
|
||||
32,235,130,175,32,3,134,175,95,67,5,32,46,66,85,25,148,197,35,63,58,8,8,95,89,6,33,9,128,140,205,130,117,95,106,13,32,80,143,125,42,0,0,2,0,26,255,107,1,158,2,59,80,107,7,34,2,7,14,
|
||||
99,148,6,8,49,55,3,51,27,1,7,35,55,1,86,72,140,39,14,32,36,25,18,54,46,30,32,22,160,72,123,105,119,56,102,1,133,254,175,98,35,44,18,5,54,46,54,1,127,254,208,1,230,131,131,130,203,34,
|
||||
2,0,50,130,79,39,134,2,32,0,9,0,23,0,107,131,10,33,19,50,66,59,5,53,21,35,17,51,21,54,174,89,55,57,86,56,99,80,91,171,67,32,68,68,31,42,66,245,11,37,65,202,2,180,208,61,130,75,32,3,
|
||||
134,155,32,17,130,155,38,29,0,41,0,0,1,51,142,157,80,34,23,144,177,32,100,71,147,10,144,185,32,118,80,40,14,42,1,0,30,255,249,1,153,2,20,0,43,130,115,40,34,7,51,7,35,6,21,20,21,130,
|
||||
6,35,30,3,51,50,107,75,6,38,39,35,55,51,38,52,55,130,5,8,76,62,1,51,50,23,21,46,1,1,44,110,20,178,18,163,1,132,17,111,6,27,38,37,23,20,61,27,47,61,88,103,14,65,18,44,2,2,62,18,47,14,
|
||||
103,83,65,48,28,61,1,220,144,36,30,4,17,15,37,44,60,29,10,19,24,71,28,104,95,37,29,9,28,36,95,105,29,72,24,21,130,246,130,2,36,14,0,174,0,1,130,7,131,2,34,1,0,4,134,11,32,1,130,7,32,
|
||||
10,134,11,32,2,130,7,32,16,134,11,36,3,0,29,0,78,134,11,131,43,32,112,134,11,36,5,0,9,0,134,134,11,32,6,130,7,44,148,0,3,0,1,4,9,0,0,0,2,0,0,134,11,32,1,130,11,32,6,134,11,32,2,130,
|
||||
11,32,12,134,11,36,3,0,58,0,18,134,11,32,4,130,23,32,108,134,11,32,5,130,21,32,114,134,11,32,6,130,23,35,144,0,46,0,143,2,39,70,0,111,0,110,0,116,0,131,7,40,114,0,103,0,101,0,32,0,
|
||||
50,130,36,32,48,130,7,32,58,130,3,32,46,134,7,36,49,0,49,0,45,130,25,131,3,32,48,130,7,51,54,0,0,70,111,110,116,70,111,114,103,101,32,50,46,48,32,58,32,46,130,3,39,49,49,45,50,45,50,
|
||||
48,50,130,30,133,107,32,86,130,81,36,114,0,115,0,105,132,103,32,32,130,89,40,0,86,101,114,115,105,111,110,32,136,140,33,2,0,139,0,65,75,7,137,19,32,192,130,10,131,251,60,3,0,4,0,5,
|
||||
0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,130,235,8,50,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0,38,0,39,0,40,0,41,
|
||||
0,42,0,43,0,44,130,211,36,46,0,47,0,48,130,221,9,48,50,0,51,0,52,0,53,0,54,0,55,0,56,0,57,0,58,0,59,0,60,0,61,0,62,0,63,0,64,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0,72,0,73,0,74,0,75,
|
||||
0,76,0,77,0,78,0,79,0,80,0,81,0,82,0,83,0,84,0,85,0,86,0,87,0,88,0,89,0,90,0,91,0,92,0,93,0,94,1,2,0,96,0,97,1,3,0,163,0,132,0,133,0,189,0,150,0,232,0,134,0,142,0,139,0,157,0,169,0,
|
||||
138,1,4,0,131,0,147,0,242,0,243,0,141,0,151,0,136,0,195,0,222,0,241,0,158,0,170,0,245,0,244,0,246,0,162,0,173,0,201,0,199,0,174,0,98,0,99,0,144,0,100,0,203,0,101,0,200,0,202,0,207,
|
||||
0,204,0,205,0,206,0,233,0,102,0,211,0,209,0,175,0,103,0,240,0,145,0,214,0,212,0,213,0,104,0,235,0,237,0,137,0,106,0,105,0,107,0,109,0,108,0,110,0,160,0,111,0,113,0,112,0,114,0,115,
|
||||
0,117,0,116,0,118,0,119,0,234,0,120,0,122,0,121,0,123,0,125,0,124,0,184,0,161,0,127,0,126,0,128,0,129,0,236,0,238,0,186,1,5,11,118,101,114,116,105,99,97,108,98,97,114,7,117,110,105,
|
||||
48,48,56,53,9,111,130,20,42,115,99,111,114,101,4,69,117,114,111,0,132,0,38,1,255,255,0,2,0,1,130,11,32,12,130,3,32,22,130,3,131,13,32,98,130,183,34,1,0,4,132,13,130,4,130,2,32,1,130,
|
||||
3,36,0,229,13,183,147,132,7,42,175,187,66,0,0,0,0,229,178,59,232,5,250,48,120,202,241,
|
||||
};
|
||||
|
||||
static const char* GetDefaultCompressedFontDataProggyForever(int* out_size)
|
||||
{
|
||||
*out_size = proggy_forever_minimal_ttf_compressed_size;
|
||||
return (const char*)proggy_forever_minimal_ttf_compressed_data;
|
||||
}
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+7
-14
@@ -153,7 +153,7 @@ struct ImGui_ImplFreeType_Data
|
||||
struct ImGui_ImplFreeType_FontSrcData
|
||||
{
|
||||
// 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, ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_user_flags);
|
||||
bool InitFont(FT_Library ft_library, const ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_user_flags);
|
||||
void CloseFont();
|
||||
ImGui_ImplFreeType_FontSrcData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
~ImGui_ImplFreeType_FontSrcData() { CloseFont(); }
|
||||
@@ -172,9 +172,9 @@ struct ImGui_ImplFreeType_FontSrcBakedData
|
||||
ImGui_ImplFreeType_FontSrcBakedData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_font_loader_flags)
|
||||
bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, const ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_font_loader_flags)
|
||||
{
|
||||
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)src->FontData, (FT_Long)src->FontDataSize, (FT_Long)src->FontNo, &FtFace);
|
||||
FT_Error error = FT_New_Memory_Face(ft_library, (const FT_Byte*)src->FontData, (FT_Long)src->FontDataSize, (FT_Long)src->FontNo, &FtFace);
|
||||
if (error != 0)
|
||||
return false;
|
||||
error = FT_Select_Charmap(FtFace, FT_ENCODING_UNICODE);
|
||||
@@ -187,12 +187,8 @@ bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, ImFontConfi
|
||||
LoadFlags = 0;
|
||||
if ((UserFlags & ImGuiFreeTypeLoaderFlags_Bitmap) == 0)
|
||||
LoadFlags |= FT_LOAD_NO_BITMAP;
|
||||
|
||||
if (UserFlags & ImGuiFreeTypeLoaderFlags_NoHinting)
|
||||
LoadFlags |= FT_LOAD_NO_HINTING;
|
||||
else
|
||||
src->PixelSnapH = true; // FIXME: A bit weird to do this this way.
|
||||
|
||||
if (UserFlags & ImGuiFreeTypeLoaderFlags_NoAutoHint)
|
||||
LoadFlags |= FT_LOAD_NO_AUTOHINT;
|
||||
if (UserFlags & ImGuiFreeTypeLoaderFlags_ForceAutoHint)
|
||||
@@ -424,6 +420,7 @@ static bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* s
|
||||
float size = baked->Size;
|
||||
if (src->MergeMode && src->SizePixels != 0.0f)
|
||||
size *= (src->SizePixels / baked->OwnerFont->Sources[0]->SizePixels);
|
||||
size *= src->ExtraSizeScale;
|
||||
|
||||
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
|
||||
bd_font_data->BakedLastActivated = baked;
|
||||
@@ -454,7 +451,7 @@ static bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* s
|
||||
{
|
||||
// Read metrics
|
||||
FT_Size_Metrics metrics = bd_baked_data->FtSize->metrics;
|
||||
const float scale = 1.0f / rasterizer_density;
|
||||
const float scale = 1.0f / (rasterizer_density * src->ExtraSizeScale);
|
||||
baked->Ascent = (float)FT_CEIL(metrics.ascender) * scale; // The pixel extents above the baseline in pixels (typically positive).
|
||||
baked->Descent = (float)FT_CEIL(metrics.descender) * scale; // The extents below the baseline in pixels (typically negative).
|
||||
//LineSpacing = (float)FT_CEIL(metrics.height) * scale; // The baseline-to-baseline distance. Note that it usually is larger than the sum of the ascender and descender taken as absolute values. There is also no guarantee that no glyphs extend above or below subsequent baselines when using this distance. Think of it as a value the designer of the font finds appropriate.
|
||||
@@ -541,12 +538,8 @@ static bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConf
|
||||
|
||||
const float ref_size = baked->OwnerFont->Sources[0]->SizePixels;
|
||||
const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f;
|
||||
float font_off_x = (src->GlyphOffset.x * offsets_scale);
|
||||
float font_off_y = (src->GlyphOffset.y * offsets_scale) + baked->Ascent;
|
||||
if (src->PixelSnapH) // Snap scaled offset. This is to mitigate backward compatibility issues for GlyphOffset, but a better design would be welcome.
|
||||
font_off_x = IM_ROUND(font_off_x);
|
||||
if (src->PixelSnapV)
|
||||
font_off_y = IM_ROUND(font_off_y);
|
||||
float font_off_x = ImFloor(src->GlyphOffset.x * offsets_scale + 0.5f); // Snap scaled offset.
|
||||
float font_off_y = ImFloor(src->GlyphOffset.y * offsets_scale + 0.5f) + baked->Ascent;
|
||||
float recip_h = 1.0f / rasterizer_density;
|
||||
float recip_v = 1.0f / rasterizer_density;
|
||||
|
||||
|
||||
Vendored
+95
-91
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.5
|
||||
// dear imgui, v1.92.6
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@@ -240,6 +240,7 @@ Index of this file:
|
||||
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion" // warning: conversion to 'xxxx' from 'xxxx' may change the sign of the result
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -335,7 +336,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
// - always performing the GetOrAddByKey() O(log N) query in g.Tables.Map[].
|
||||
const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0;
|
||||
const ImVec2 avail_size = GetContentRegionAvail();
|
||||
const ImVec2 actual_outer_size = ImTrunc(CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f));
|
||||
const ImVec2 actual_outer_size = ImTrunc(CalcItemSize(outer_size, ImMax(avail_size.x, IMGUI_WINDOW_HARD_MIN_SIZE), use_child_window ? ImMax(avail_size.y, IMGUI_WINDOW_HARD_MIN_SIZE) : 0.0f));
|
||||
const ImRect outer_rect(outer_window->DC.CursorPos, outer_window->DC.CursorPos + actual_outer_size);
|
||||
const bool outer_window_is_measuring_size = (outer_window->AutoFitFramesX > 0) || (outer_window->AutoFitFramesY > 0); // Doesn't apply to AlwaysAutoResize windows!
|
||||
if (use_child_window && IsClippedEx(outer_rect, 0) && !outer_window_is_measuring_size)
|
||||
@@ -564,9 +565,9 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
const int old_columns_count = table->Columns.size();
|
||||
if (old_columns_count != 0 && old_columns_count != columns_count)
|
||||
{
|
||||
// Attempt to preserve width on column count change (#4046)
|
||||
// Attempt to preserve width and other settings on column count/specs change (#4046)
|
||||
old_columns_to_preserve = table->Columns.Data;
|
||||
old_columns_raw_data = table->RawData;
|
||||
old_columns_raw_data = table->RawData; // Free at end of function
|
||||
table->RawData = NULL;
|
||||
}
|
||||
if (table->RawData == NULL)
|
||||
@@ -592,7 +593,6 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
ImGuiTableColumn* column = &table->Columns[n];
|
||||
if (old_columns_to_preserve && n < old_columns_count)
|
||||
{
|
||||
// FIXME: We don't attempt to preserve column order in this path.
|
||||
*column = old_columns_to_preserve[n];
|
||||
}
|
||||
else
|
||||
@@ -602,8 +602,9 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
column->WidthAuto = width_auto;
|
||||
column->IsPreserveWidthAuto = true; // Preserve WidthAuto when reinitializing a live table: not technically necessary but remove a visible flicker
|
||||
column->IsEnabled = column->IsUserEnabled = column->IsUserEnabledNextFrame = true;
|
||||
column->DisplayOrder = (ImGuiTableColumnIdx)n;
|
||||
}
|
||||
column->DisplayOrder = table->DisplayOrderToIndex[n] = (ImGuiTableColumnIdx)n;
|
||||
table->DisplayOrderToIndex[n] = column->DisplayOrder;
|
||||
}
|
||||
}
|
||||
if (old_columns_raw_data)
|
||||
@@ -698,7 +699,7 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table)
|
||||
}
|
||||
|
||||
// Handle reordering request
|
||||
// Note: we don't clear ReorderColumn after handling the request.
|
||||
// Note: we don't clear ReorderColumn after handling the request (FIXME: clarify why or add a test).
|
||||
if (table->InstanceCurrent == 0)
|
||||
{
|
||||
if (table->HeldHeaderColumn == -1 && table->ReorderColumn != -1)
|
||||
@@ -710,24 +711,12 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table)
|
||||
// In the configuration below, moving C to the right of E will lead to:
|
||||
// ... C [D] E ---> ... [D] E C (Column name/index)
|
||||
// ... 2 3 4 ... 2 3 4 (Display order)
|
||||
const int reorder_dir = table->ReorderColumnDir;
|
||||
IM_ASSERT(reorder_dir == -1 || reorder_dir == +1);
|
||||
IM_ASSERT(table->ReorderColumnDir == -1 || table->ReorderColumnDir == +1);
|
||||
IM_ASSERT(table->Flags & ImGuiTableFlags_Reorderable);
|
||||
ImGuiTableColumn* src_column = &table->Columns[table->ReorderColumn];
|
||||
ImGuiTableColumn* dst_column = &table->Columns[(reorder_dir == -1) ? src_column->PrevEnabledColumn : src_column->NextEnabledColumn];
|
||||
IM_UNUSED(dst_column);
|
||||
const int src_order = src_column->DisplayOrder;
|
||||
const int dst_order = dst_column->DisplayOrder;
|
||||
src_column->DisplayOrder = (ImGuiTableColumnIdx)dst_order;
|
||||
for (int order_n = src_order + reorder_dir; order_n != dst_order + reorder_dir; order_n += reorder_dir)
|
||||
table->Columns[table->DisplayOrderToIndex[order_n]].DisplayOrder -= (ImGuiTableColumnIdx)reorder_dir;
|
||||
IM_ASSERT(dst_column->DisplayOrder == dst_order - reorder_dir);
|
||||
|
||||
// Display order is stored in both columns->IndexDisplayOrder and table->DisplayOrder[]. Rebuild later from the former.
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImGuiTableColumnIdx)column_n;
|
||||
ImGuiTableColumn* dst_column = &table->Columns[(table->ReorderColumnDir < 0) ? src_column->PrevEnabledColumn : src_column->NextEnabledColumn];
|
||||
TableSetColumnDisplayOrder(table, table->ReorderColumn, dst_column->DisplayOrder);
|
||||
table->ReorderColumnDir = 0;
|
||||
table->IsSettingsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,6 +730,31 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table)
|
||||
}
|
||||
}
|
||||
|
||||
// Note that TableSetupScrollFreeze() enforce a display order range for frozen columns.
|
||||
// So reordering a column across the frozen column barrier is illegal and will be undone.
|
||||
void ImGui::TableSetColumnDisplayOrder(ImGuiTable* table, int column_n, int dst_order)
|
||||
{
|
||||
IM_ASSERT(column_n >= 0 && column_n < table->ColumnsCount);
|
||||
IM_ASSERT(dst_order >= 0 && dst_order < table->ColumnsCount);
|
||||
|
||||
ImGuiTableColumn* src_column = &table->Columns[column_n];
|
||||
const int src_order = src_column->DisplayOrder;
|
||||
if (src_order == dst_order)
|
||||
return;
|
||||
const int reorder_dir = (dst_order < src_order) ? -1 : +1;
|
||||
|
||||
src_column->DisplayOrder = (ImGuiTableColumnIdx)dst_order;
|
||||
for (int order_n = src_order + reorder_dir; order_n != dst_order + reorder_dir; order_n += reorder_dir)
|
||||
table->Columns[table->DisplayOrderToIndex[order_n]].DisplayOrder -= (ImGuiTableColumnIdx)reorder_dir;
|
||||
//IM_ASSERT(dst_column->DisplayOrder == dst_order - reorder_dir);
|
||||
|
||||
// Display order is stored in both columns->IndexDisplayOrder and table->DisplayOrder[]. Rebuild later from the former.
|
||||
// FIXME-OPT: If this is called multiple times we'd effectively have a O(N^2) thing going on.
|
||||
for (int n = 0; n < table->ColumnsCount; n++)
|
||||
table->DisplayOrderToIndex[table->Columns[n].DisplayOrder] = (ImGuiTableColumnIdx)n;
|
||||
table->IsSettingsDirty = true;
|
||||
}
|
||||
|
||||
// Adjust flags: default width mode + stretch columns are not allowed when auto extending
|
||||
static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, ImGuiTableColumnFlags flags_in)
|
||||
{
|
||||
@@ -1348,11 +1362,7 @@ void ImGui::EndTable()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "EndTable() call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "EndTable() call should only be done while in BeginTable() scope!");
|
||||
|
||||
// This assert would be very useful to catch a common error... unfortunately it would probably trigger in some
|
||||
// cases, and for consistency user may sometimes output empty tables (and still benefit from e.g. outer border)
|
||||
@@ -1383,7 +1393,7 @@ void ImGui::EndTable()
|
||||
inner_window->DC.PrevLineSize = temp_data->HostBackupPrevLineSize;
|
||||
inner_window->DC.CurrLineSize = temp_data->HostBackupCurrLineSize;
|
||||
inner_window->DC.CursorMaxPos = temp_data->HostBackupCursorMaxPos;
|
||||
const float inner_content_max_y = table->RowPosY2;
|
||||
const float inner_content_max_y = ImCeil(table->RowPosY2); // Rounding final position is important as we currently don't round row height ('Demo->Tables->Outer Size' demo uses non-integer heights)
|
||||
IM_ASSERT(table->RowPosY2 == inner_window->DC.CursorPos.y);
|
||||
if (inner_window != outer_window)
|
||||
inner_window->DC.CursorMaxPos.y = inner_content_max_y;
|
||||
@@ -1601,18 +1611,10 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT_USER_ERROR_RET(table->DeclColumnsCount < table->ColumnsCount, "TableSetupColumn(): called too many times!");
|
||||
IM_ASSERT_USER_ERROR_RET(table->IsLayoutLocked == false, "TableSetupColumn(): need to call before first row!");
|
||||
IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 && "Illegal to pass StatusMask values to TableSetupColumn()");
|
||||
if (table->DeclColumnsCount >= table->ColumnsCount)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table->DeclColumnsCount < table->ColumnsCount, "Called TableSetupColumn() too many times!");
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiTableColumn* column = &table->Columns[table->DeclColumnsCount];
|
||||
table->DeclColumnsCount++;
|
||||
@@ -1620,7 +1622,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
// Assert when passing a width or weight if policy is entirely left to default, to avoid storing width into weight and vice-versa.
|
||||
// Give a grace to users of ImGuiTableFlags_ScrollX.
|
||||
if (table->IsDefaultSizingPolicy && (flags & ImGuiTableColumnFlags_WidthMask_) == 0 && (flags & ImGuiTableFlags_ScrollX) == 0)
|
||||
IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitly in either Table or Column.");
|
||||
IM_ASSERT_USER_ERROR_RET(init_width_or_weight <= 0.0f, "TableSetupColumn(): 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)
|
||||
@@ -1662,12 +1664,8 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "TableSetupColumn(): need to call before first row!");
|
||||
IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
|
||||
IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit
|
||||
|
||||
@@ -1743,11 +1741,7 @@ void ImGui::TableSetColumnEnabled(int column_n, bool enabled)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT(table->Flags & ImGuiTableFlags_Hideable); // See comments above
|
||||
if (column_n < 0)
|
||||
column_n = table->CurrentColumn;
|
||||
@@ -1825,12 +1819,8 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT(target != ImGuiTableBgTarget_None);
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (color == IM_COL32_DISABLE)
|
||||
color = 0;
|
||||
@@ -2128,11 +2118,7 @@ bool ImGui::TableSetColumnIndex(int column_n)
|
||||
{
|
||||
if (table->CurrentColumn != -1)
|
||||
TableEndCell(table);
|
||||
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;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RETV(column_n >= 0 && column_n < table->ColumnsCount, false, "TableSetColumnIndex() invalid column index!");
|
||||
TableBeginCell(table, column_n);
|
||||
}
|
||||
|
||||
@@ -2458,6 +2444,11 @@ void ImGui::TableUpdateColumnsWeightFromWidth(ImGuiTable* table)
|
||||
// - TableDrawBorders() [Internal]
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
|
||||
// FIXME: This could be abstracted and merged with PushColumnsBackground(), by creating a generic struct
|
||||
// with storage for backup cliprect + backup channel + storage for splitter pointer, new clip rect.
|
||||
// This would slightly simplify caller code.
|
||||
|
||||
// Bg2 is used by Selectable (and possibly other widgets) to render to the background.
|
||||
// Unlike our Bg0/1 channel which we uses for RowBg/CellBg/Borders and where we guarantee all shapes to be CPU-clipped, the Bg2 channel being widgets-facing will rely on regular ClipRect.
|
||||
void ImGui::TablePushBackgroundChannel()
|
||||
@@ -2619,7 +2610,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
const int size_for_masks_bitarrays_one = (int)ImBitArrayGetStorageSizeInBytes(max_draw_channels);
|
||||
g.TempBuffer.reserve(size_for_masks_bitarrays_one * 5);
|
||||
memset(g.TempBuffer.Data, 0, size_for_masks_bitarrays_one * 5);
|
||||
for (int n = 0; n < IM_ARRAYSIZE(merge_groups); n++)
|
||||
for (int n = 0; n < IM_COUNTOF(merge_groups); n++)
|
||||
merge_groups[n].ChannelsMask = (ImBitArrayPtr)(void*)(g.TempBuffer.Data + (size_for_masks_bitarrays_one * n));
|
||||
ImBitArrayPtr remaining_mask = (ImBitArrayPtr)(void*)(g.TempBuffer.Data + (size_for_masks_bitarrays_one * 4));
|
||||
|
||||
@@ -2676,7 +2667,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
// [DEBUG] Display merge groups
|
||||
#if 0
|
||||
if (g.IO.KeyShift)
|
||||
for (int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++)
|
||||
for (int merge_group_n = 0; merge_group_n < IM_COUNTOF(merge_groups); merge_group_n++)
|
||||
{
|
||||
MergeGroup* merge_group = &merge_groups[merge_group_n];
|
||||
if (merge_group->ChannelsCount == 0)
|
||||
@@ -2704,7 +2695,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS);
|
||||
//ImRect host_rect = (table->InnerWindow == table->OuterWindow) ? table->InnerClipRect : table->HostClipRect;
|
||||
ImRect host_rect = table->HostClipRect;
|
||||
for (int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++)
|
||||
for (int merge_group_n = 0; merge_group_n < IM_COUNTOF(merge_groups); merge_group_n++)
|
||||
{
|
||||
if (int merge_channels_count = merge_groups[merge_group_n].ChannelsCount)
|
||||
{
|
||||
@@ -3113,11 +3104,7 @@ void ImGui::TableHeadersRow()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
|
||||
// Call layout if not already done. This is automatically done by TableNextRow: we do it here _only_ to make
|
||||
// it easier to debug-step in TableUpdateLayout(). Your own version of this function doesn't need this.
|
||||
@@ -3162,12 +3149,7 @@ void ImGui::TableHeader(const char* label)
|
||||
return;
|
||||
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT(table->CurrentColumn != -1);
|
||||
const int column_n = table->CurrentColumn;
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
@@ -3197,7 +3179,7 @@ void ImGui::TableHeader(const char* label)
|
||||
sort_arrow = true;
|
||||
if (column->SortOrder > 0)
|
||||
{
|
||||
ImFormatString(sort_order_suf, IM_ARRAYSIZE(sort_order_suf), "%d", column->SortOrder + 1);
|
||||
ImFormatString(sort_order_suf, IM_COUNTOF(sort_order_suf), "%d", column->SortOrder + 1);
|
||||
w_sort_text = g.Style.ItemInnerSpacing.x + CalcTextSize(sort_order_suf).x;
|
||||
}
|
||||
}
|
||||
@@ -3342,11 +3324,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImDrawList* draw_list = window->DrawList;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT(table->CurrentRow == -1 && "Must be first row");
|
||||
|
||||
if (max_label_width == 0.0f)
|
||||
@@ -3787,7 +3765,6 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
|
||||
|
||||
// Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn
|
||||
ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
|
||||
ImU64 display_order_mask = 0;
|
||||
for (int data_n = 0; data_n < settings->ColumnsCount; data_n++, column_settings++)
|
||||
{
|
||||
int column_n = column_settings->Index;
|
||||
@@ -3804,24 +3781,51 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
|
||||
}
|
||||
if (settings->SaveFlags & ImGuiTableFlags_Reorderable)
|
||||
column->DisplayOrder = column_settings->DisplayOrder;
|
||||
display_order_mask |= (ImU64)1 << column->DisplayOrder;
|
||||
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;
|
||||
}
|
||||
|
||||
// Validate and fix invalid display order data
|
||||
const ImU64 expected_display_order_mask = (settings->ColumnsCount == 64) ? ~0 : ((ImU64)1 << settings->ColumnsCount) - 1;
|
||||
if (display_order_mask != expected_display_order_mask)
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
table->Columns[column_n].DisplayOrder = (ImGuiTableColumnIdx)column_n;
|
||||
|
||||
// Rebuild index
|
||||
// Fix display order and build index
|
||||
if (settings->SaveFlags & ImGuiTableFlags_Reorderable)
|
||||
TableFixDisplayOrder(table);
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImGuiTableColumnIdx)column_n;
|
||||
}
|
||||
|
||||
struct ImGuiTableFixDisplayOrderColumnData
|
||||
{
|
||||
ImGuiTableColumnIdx Idx;
|
||||
ImGuiTable* Table; // This is unfortunate but we don't have userdata in qsort api.
|
||||
};
|
||||
|
||||
// Sort by DisplayOrder and then Index
|
||||
static int IMGUI_CDECL TableFixDisplayOrderComparer(const void* lhs, const void* rhs)
|
||||
{
|
||||
const ImGuiTable* table = ((const ImGuiTableFixDisplayOrderColumnData*)lhs)->Table;
|
||||
const ImGuiTableColumnIdx lhs_idx = ((const ImGuiTableFixDisplayOrderColumnData*)lhs)->Idx;
|
||||
const ImGuiTableColumnIdx rhs_idx = ((const ImGuiTableFixDisplayOrderColumnData*)rhs)->Idx;
|
||||
const int order_delta = (table->Columns[lhs_idx].DisplayOrder - table->Columns[rhs_idx].DisplayOrder);
|
||||
return (order_delta > 0) ? +1 : (order_delta < 0) ? -1 : (lhs_idx > rhs_idx) ? +1 : -1;
|
||||
}
|
||||
|
||||
// Fix invalid display order data: compact values (0,1,3 -> 0,1,2); preserve relative order (0,3,1 -> 0,2,1); deduplicate (0,4,1,1 -> 0,3,1,2)
|
||||
void ImGui::TableFixDisplayOrder(ImGuiTable* table)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.TempBuffer.reserve((int)(sizeof(ImGuiTableFixDisplayOrderColumnData) * table->ColumnsCount)); // FIXME: Maybe wrap those two lines as a helper.
|
||||
ImGuiTableFixDisplayOrderColumnData* fdo_columns = (ImGuiTableFixDisplayOrderColumnData*)(void*)g.TempBuffer.Data;
|
||||
for (int n = 0; n < table->ColumnsCount; n++)
|
||||
{
|
||||
fdo_columns[n].Idx = (ImGuiTableColumnIdx)n;
|
||||
fdo_columns[n].Table = table;
|
||||
}
|
||||
ImQsort(fdo_columns, (size_t)table->ColumnsCount, sizeof(ImGuiTableFixDisplayOrderColumnData), TableFixDisplayOrderComparer);
|
||||
for (int n = 0; n < table->ColumnsCount; n++)
|
||||
table->Columns[fdo_columns[n].Idx].DisplayOrder = (ImGuiTableColumnIdx)n;
|
||||
}
|
||||
|
||||
static void TableSettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*)
|
||||
{
|
||||
ImGuiContext& g = *ctx;
|
||||
@@ -4063,7 +4067,7 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
|
||||
ImGuiTableColumn* column = &table->Columns[n];
|
||||
const char* name = TableGetColumnName(table, n);
|
||||
char buf[512];
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf),
|
||||
ImFormatString(buf, IM_COUNTOF(buf),
|
||||
"Column %d order %d '%s': offset %+.2f to %+.2f%s\n"
|
||||
"Enabled: %d, VisibleX/Y: %d/%d, RequestOutput: %d, SkipItems: %d, DrawChannels: %d,%d\n"
|
||||
"WidthGiven: %.1f, Request/Auto: %.1f/%.1f, StretchWeight: %.3f (%.1f%%)\n"
|
||||
|
||||
Vendored
+161
-134
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.5
|
||||
// dear imgui, v1.92.6
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@@ -92,6 +92,7 @@ Index of this file:
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion" // warning: conversion to 'xxxx' from 'xxxx' may change the sign of the result
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -134,7 +135,7 @@ static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1);
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// For InputTextEx()
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard = false);
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, ImGuiInputTextState* state, unsigned int* p_char, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard = false);
|
||||
static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin, const char* text_end_display, const char* text_end, const char** out_remaining = NULL, ImVec2* out_offset = NULL, ImDrawTextFlags flags = 0);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -836,11 +837,10 @@ bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg, ImGuiBut
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
// Cannot use zero-size for InvisibleButton(). Unlike Button() there is not way to fallback using the label size.
|
||||
IM_ASSERT(size_arg.x != 0.0f && size_arg.y != 0.0f);
|
||||
// Ensure zero-size fits to contents
|
||||
ImVec2 size = CalcItemSize(ImVec2(size_arg.x != 0.0f ? size_arg.x : -FLT_MIN, size_arg.y != 0.0f ? size_arg.y : -FLT_MIN), 0.0f, 0.0f);
|
||||
|
||||
const ImGuiID id = window->GetID(str_id);
|
||||
ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f);
|
||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
||||
ItemSize(size);
|
||||
if (!ItemAdd(bb, id, NULL, (flags & ImGuiButtonFlags_EnableNav) ? ImGuiItemFlags_None : ImGuiItemFlags_NoNav))
|
||||
@@ -982,20 +982,7 @@ void ImGui::Scrollbar(ImGuiAxis axis)
|
||||
|
||||
// Calculate scrollbar bounding box
|
||||
ImRect bb = GetWindowScrollbarRect(window, axis);
|
||||
ImDrawFlags rounding_corners = ImDrawFlags_RoundCornersNone;
|
||||
if (axis == ImGuiAxis_X)
|
||||
{
|
||||
rounding_corners |= ImDrawFlags_RoundCornersBottomLeft;
|
||||
if (!window->ScrollbarY)
|
||||
rounding_corners |= ImDrawFlags_RoundCornersBottomRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar))
|
||||
rounding_corners |= ImDrawFlags_RoundCornersTopRight;
|
||||
if (!window->ScrollbarX)
|
||||
rounding_corners |= ImDrawFlags_RoundCornersBottomRight;
|
||||
}
|
||||
ImDrawFlags rounding_corners = CalcRoundingFlagsForRectInRect(bb, window->Rect(), g.Style.WindowBorderSize);
|
||||
float size_visible = window->InnerRect.Max[axis] - window->InnerRect.Min[axis];
|
||||
float size_contents = window->ContentSize[axis] + window->WindowPadding[axis] * 2.0f;
|
||||
ImS64 scroll = (ImS64)window->Scroll[axis];
|
||||
@@ -1037,6 +1024,8 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
|
||||
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
|
||||
const float scrollbar_size_v = (axis == ImGuiAxis_X) ? bb.GetWidth() : bb.GetHeight();
|
||||
if (scrollbar_size_v < 1.0f)
|
||||
return false;
|
||||
|
||||
// Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount)
|
||||
// But we maintain a minimum size in pixel to allow for the user to still aim inside.
|
||||
@@ -1129,11 +1118,15 @@ void ImGui::ImageWithBg(ImTextureRef tex_ref, const ImVec2& image_size, const Im
|
||||
return;
|
||||
|
||||
// Render
|
||||
if (g.Style.ImageBorderSize > 0.0f)
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border), 0.0f, ImDrawFlags_None, g.Style.ImageBorderSize);
|
||||
float rounding = g.Style.ImageRounding;
|
||||
if (bg_col.w > 0.0f)
|
||||
window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col));
|
||||
window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||
window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col), rounding);
|
||||
if (rounding > 0.0f)
|
||||
window->DrawList->AddImageRounded(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col), rounding);
|
||||
else
|
||||
window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||
if (g.Style.ImageBorderSize > 0.0f)
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border), rounding, ImDrawFlags_None, g.Style.ImageBorderSize);
|
||||
}
|
||||
|
||||
void ImGui::Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1)
|
||||
@@ -1173,10 +1166,14 @@ bool ImGui::ImageButtonEx(ImGuiID id, ImTextureRef tex_ref, const ImVec2& image_
|
||||
// Render
|
||||
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||
RenderNavCursor(bb, id);
|
||||
RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, g.Style.FrameRounding));
|
||||
RenderFrame(bb.Min, bb.Max, col, true, g.Style.FrameRounding);
|
||||
if (bg_col.w > 0.0f)
|
||||
window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col));
|
||||
window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||
float image_rounding = ImMax(g.Style.FrameRounding - ImMax(padding.x, padding.y), g.Style.ImageRounding);
|
||||
if (image_rounding > 0.0f)
|
||||
window->DrawList->AddImageRounded(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col), image_rounding);
|
||||
else
|
||||
window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||
|
||||
return pressed;
|
||||
}
|
||||
@@ -1438,7 +1435,10 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
|
||||
// Render
|
||||
RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
||||
bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize));
|
||||
RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), fill_n0, fill_n1, style.FrameRounding);
|
||||
float fill_x0 = ImLerp(bb.Min.x, bb.Max.x, fill_n0);
|
||||
float fill_x1 = ImLerp(bb.Min.x, bb.Max.x, fill_n1);
|
||||
if (fill_x0 < fill_x1)
|
||||
RenderRectFilledInRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), fill_x0, fill_x1, style.FrameRounding);
|
||||
|
||||
// Default displaying the fraction as percentage string, but user can override it
|
||||
// Don't display text for indeterminate bars by default
|
||||
@@ -1447,14 +1447,14 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
|
||||
{
|
||||
if (!overlay)
|
||||
{
|
||||
ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction * 100 + 0.01f);
|
||||
ImFormatString(overlay_buf, IM_COUNTOF(overlay_buf), "%.0f%%", fraction * 100 + 0.01f);
|
||||
overlay = overlay_buf;
|
||||
}
|
||||
|
||||
ImVec2 overlay_size = CalcTextSize(overlay, NULL);
|
||||
if (overlay_size.x > 0.0f)
|
||||
{
|
||||
float text_x = is_indeterminate ? (bb.Min.x + bb.Max.x - overlay_size.x) * 0.5f : ImLerp(bb.Min.x, bb.Max.x, fill_n1) + style.ItemSpacing.x;
|
||||
float text_x = is_indeterminate ? (bb.Min.x + bb.Max.x - overlay_size.x) * 0.5f : fill_x1 + style.ItemSpacing.x;
|
||||
RenderTextClipped(ImVec2(ImClamp(text_x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb);
|
||||
}
|
||||
}
|
||||
@@ -1715,7 +1715,7 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
|
||||
const float separator_thickness = style.SeparatorTextBorderSize;
|
||||
const ImVec2 min_size(label_size.x + extra_w + padding.x * 2.0f, ImMax(label_size.y + padding.y * 2.0f, separator_thickness));
|
||||
const ImRect bb(pos, ImVec2(window->WorkRect.Max.x, pos.y + min_size.y));
|
||||
const float text_baseline_y = ImTrunc((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImFloor((style.SeparatorTextSize - label_size.y) * 0.5f));
|
||||
const float text_baseline_y = ImTrunc((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImTrunc((style.SeparatorTextSize - label_size.y) * 0.5f));
|
||||
ItemSize(min_size, text_baseline_y);
|
||||
if (!ItemAdd(bb, id))
|
||||
return;
|
||||
@@ -1832,7 +1832,7 @@ static int IMGUI_CDECL ShrinkWidthItemComparer(const void* lhs, const void* rhs)
|
||||
const ImGuiShrinkWidthItem* b = (const ImGuiShrinkWidthItem*)rhs;
|
||||
if (int d = (int)(b->Width - a->Width))
|
||||
return d;
|
||||
return (b->Index - a->Index);
|
||||
return b->Index - a->Index;
|
||||
}
|
||||
|
||||
// Shrink excess width from a set of item, by removing width from the larger items first.
|
||||
@@ -2014,7 +2014,7 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
|
||||
|
||||
// This is essentially a specialized version of BeginPopupEx()
|
||||
char name[16];
|
||||
ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.BeginComboDepth); // Recycle windows based on depth
|
||||
ImFormatString(name, IM_COUNTOF(name), "##Combo_%02d", g.BeginComboDepth); // Recycle windows based on depth
|
||||
|
||||
// Set position given a custom constraint (peak into expected window size so we can position it)
|
||||
// FIXME: This might be easier to express with an hypothetical SetNextWindowPosConstraints() function?
|
||||
@@ -2049,8 +2049,12 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
|
||||
void ImGui::EndCombo()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
EndPopup();
|
||||
g.BeginComboDepth--;
|
||||
char name[16];
|
||||
ImFormatString(name, IM_COUNTOF(name), "##Combo_%02d", g.BeginComboDepth); // FIXME: Move those to helpers?
|
||||
if (strcmp(g.CurrentWindow->Name, name) != 0)
|
||||
IM_ASSERT_USER_ERROR_RET(0, "Calling EndCombo() in wrong window!");
|
||||
EndPopup();
|
||||
}
|
||||
|
||||
// Call directly after the BeginCombo/EndCombo block. The preview is designed to only host non-interactive elements
|
||||
@@ -2235,6 +2239,11 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*old_getter)(void*
|
||||
// - RoundScalarWithFormat<>()
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
static const ImU32 GDefaultRgbaColorMarkers[4] =
|
||||
{
|
||||
IM_COL32(240,20,20,255), IM_COL32(20,240,20,255), IM_COL32(20,20,240,255), IM_COL32(140,140,140,255)
|
||||
};
|
||||
|
||||
static const ImGuiDataTypeInfo GDataTypeInfo[] =
|
||||
{
|
||||
{ sizeof(char), "S8", "%d", "%d" }, // ImGuiDataType_S8
|
||||
@@ -2255,7 +2264,7 @@ static const ImGuiDataTypeInfo GDataTypeInfo[] =
|
||||
{ sizeof(bool), "bool", "%d", "%d" }, // ImGuiDataType_Bool
|
||||
{ 0, "char*","%s", "%s" }, // ImGuiDataType_String
|
||||
};
|
||||
IM_STATIC_ASSERT(IM_ARRAYSIZE(GDataTypeInfo) == ImGuiDataType_COUNT);
|
||||
IM_STATIC_ASSERT(IM_COUNTOF(GDataTypeInfo) == ImGuiDataType_COUNT);
|
||||
|
||||
const ImGuiDataTypeInfo* ImGui::DataTypeGetInfo(ImGuiDataType data_type)
|
||||
{
|
||||
@@ -2364,7 +2373,7 @@ bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void
|
||||
if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double)
|
||||
format = type_info->ScanFmt;
|
||||
else
|
||||
format = ImParseFormatSanitizeForScanning(format, format_sanitized, IM_ARRAYSIZE(format_sanitized));
|
||||
format = ImParseFormatSanitizeForScanning(format, format_sanitized, IM_COUNTOF(format_sanitized));
|
||||
|
||||
// Small types need a 32-bit buffer to receive the result from scanf()
|
||||
int v32 = 0;
|
||||
@@ -2455,7 +2464,7 @@ static float GetMinimumStepAtDecimalPrecision(int decimal_precision)
|
||||
static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f };
|
||||
if (decimal_precision < 0)
|
||||
return FLT_MIN;
|
||||
return (decimal_precision < IM_ARRAYSIZE(min_steps)) ? min_steps[decimal_precision] : ImPow(10.0f, (float)-decimal_precision);
|
||||
return (decimal_precision < IM_COUNTOF(min_steps)) ? min_steps[decimal_precision] : ImPow(10.0f, (float)-decimal_precision);
|
||||
}
|
||||
|
||||
template<typename TYPE>
|
||||
@@ -2469,12 +2478,12 @@ TYPE ImGui::RoundScalarWithFormatT(const char* format, ImGuiDataType data_type,
|
||||
|
||||
// Sanitize format
|
||||
char fmt_sanitized[32];
|
||||
ImParseFormatSanitizeForPrinting(fmt_start, fmt_sanitized, IM_ARRAYSIZE(fmt_sanitized));
|
||||
ImParseFormatSanitizeForPrinting(fmt_start, fmt_sanitized, IM_COUNTOF(fmt_sanitized));
|
||||
fmt_start = fmt_sanitized;
|
||||
|
||||
// Format value with our rounding, and read back
|
||||
char v_str[64];
|
||||
ImFormatString(v_str, IM_ARRAYSIZE(v_str), fmt_start, v);
|
||||
ImFormatString(v_str, IM_COUNTOF(v_str), fmt_start, v);
|
||||
const char* p = v_str;
|
||||
while (*p == ' ')
|
||||
p++;
|
||||
@@ -2683,6 +2692,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const float w = CalcItemWidth();
|
||||
const ImU32 color_marker = (g.NextItemData.HasFlags & ImGuiNextItemDataFlags_HasColorMarker) ? g.NextItemData.ColorMarker : 0;
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||
@@ -2751,7 +2761,10 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
// Draw frame
|
||||
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
RenderNavCursor(frame_bb, id);
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding);
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, false, style.FrameRounding);
|
||||
if (color_marker != 0 && style.ColorMarkerSize > 0.0f)
|
||||
RenderColorComponentMarker(frame_bb, GetColorU32(color_marker), style.FrameRounding);
|
||||
RenderFrameBorder(frame_bb.Min, frame_bb.Max, g.Style.FrameRounding);
|
||||
|
||||
// Drag behavior
|
||||
const bool value_changed = DragBehavior(id, data_type, p_data, v_speed, p_min, p_max, format, flags);
|
||||
@@ -2760,7 +2773,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
|
||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format);
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("{", "}");
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||
@@ -2789,6 +2802,8 @@ bool ImGui::DragScalarN(const char* label, ImGuiDataType data_type, void* p_data
|
||||
PushID(i);
|
||||
if (i > 0)
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
if (flags & ImGuiSliderFlags_ColorMarkers)
|
||||
SetNextItemColorMarker(GDefaultRgbaColorMarkers[i]);
|
||||
value_changed |= DragScalar("", data_type, p_data, v_speed, p_min, p_max, format, flags);
|
||||
PopID();
|
||||
PopItemWidth();
|
||||
@@ -3287,6 +3302,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const float w = CalcItemWidth();
|
||||
const ImU32 color_marker = (g.NextItemData.HasFlags & ImGuiNextItemDataFlags_HasColorMarker) ? g.NextItemData.ColorMarker : 0;
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||
@@ -3337,7 +3353,10 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
// Draw frame
|
||||
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
RenderNavCursor(frame_bb, id);
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding);
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, false, style.FrameRounding);
|
||||
if (color_marker != 0 && style.ColorMarkerSize > 0.0f)
|
||||
RenderColorComponentMarker(frame_bb, GetColorU32(color_marker), style.FrameRounding);
|
||||
RenderFrameBorder(frame_bb.Min, frame_bb.Max, g.Style.FrameRounding);
|
||||
|
||||
// Slider behavior
|
||||
ImRect grab_bb;
|
||||
@@ -3351,7 +3370,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
|
||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format);
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("{", "}");
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||
@@ -3381,6 +3400,8 @@ bool ImGui::SliderScalarN(const char* label, ImGuiDataType data_type, void* v, i
|
||||
PushID(i);
|
||||
if (i > 0)
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
if (flags & ImGuiSliderFlags_ColorMarkers)
|
||||
SetNextItemColorMarker(GDefaultRgbaColorMarkers[i]);
|
||||
value_changed |= SliderScalar("", data_type, v, v_min, v_max, format, flags);
|
||||
PopID();
|
||||
PopItemWidth();
|
||||
@@ -3502,7 +3523,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||
// For the vertical slider we allow centered text to overlap the frame padding
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format);
|
||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f));
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
@@ -3702,16 +3723,16 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG
|
||||
const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type);
|
||||
char fmt_buf[32];
|
||||
char data_buf[32];
|
||||
format = ImParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf));
|
||||
format = ImParseFormatTrimDecorations(format, fmt_buf, IM_COUNTOF(fmt_buf));
|
||||
if (format[0] == 0)
|
||||
format = type_info->PrintFmt;
|
||||
DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, format);
|
||||
DataTypeFormatString(data_buf, IM_COUNTOF(data_buf), data_type, p_data, format);
|
||||
ImStrTrimBlanks(data_buf);
|
||||
|
||||
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint;
|
||||
g.LastItemData.ItemFlags |= ImGuiItemFlags_NoMarkEdited; // Because TempInputText() uses ImGuiInputTextFlags_MergedItem it doesn't submit a new item, so we poke LastItemData.
|
||||
bool value_changed = false;
|
||||
if (TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags))
|
||||
if (TempInputText(bb, id, label, data_buf, IM_COUNTOF(data_buf), flags))
|
||||
{
|
||||
// Backup old value
|
||||
size_t data_type_size = type_info->Size;
|
||||
@@ -3764,7 +3785,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
if ((flags & ImGuiInputTextFlags_DisplayEmptyRefVal) && DataTypeCompare(data_type, p_data, p_data_default) == 0)
|
||||
buf[0] = 0;
|
||||
else
|
||||
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format);
|
||||
DataTypeFormatString(buf, IM_COUNTOF(buf), data_type, p_data, format);
|
||||
|
||||
// Disable the MarkItemEdited() call in InputText but keep ImGuiItemStatusFlags_Edited.
|
||||
// We call MarkItemEdited() ourselves by comparing the actual data rather than the string.
|
||||
@@ -3774,7 +3795,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
bool value_changed = false;
|
||||
if (p_step == NULL)
|
||||
{
|
||||
if (InputText(label, buf, IM_ARRAYSIZE(buf), flags))
|
||||
if (InputText(label, buf, IM_COUNTOF(buf), flags))
|
||||
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL);
|
||||
}
|
||||
else
|
||||
@@ -3784,7 +3805,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
BeginGroup(); // The only purpose of the group here is to allow the caller to query item data e.g. IsItemActive()
|
||||
PushID(label);
|
||||
SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2));
|
||||
if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view
|
||||
if (InputText("", buf, IM_COUNTOF(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view
|
||||
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Inputable);
|
||||
|
||||
@@ -4230,7 +4251,7 @@ static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* st
|
||||
// We added an extra indirection where 'Stb' is heap-allocated, in order facilitate the work of bindings generators.
|
||||
ImGuiInputTextState::ImGuiInputTextState()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
Stb = IM_NEW(ImStbTexteditState);
|
||||
memset(Stb, 0, sizeof(*Stb));
|
||||
}
|
||||
@@ -4271,6 +4292,7 @@ void ImGuiInputTextState::ClearSelection() { Stb->select_start
|
||||
int ImGuiInputTextState::GetCursorPos() const { return Stb->cursor; }
|
||||
int ImGuiInputTextState::GetSelectionStart() const { return Stb->select_start; }
|
||||
int ImGuiInputTextState::GetSelectionEnd() const { return Stb->select_end; }
|
||||
void ImGuiInputTextState::SetSelection(int start, int end) { Stb->select_start = start; Stb->cursor = Stb->select_end = end; }
|
||||
float ImGuiInputTextState::GetPreferredOffsetX() const { return Stb->has_preferred_x ? Stb->preferred_x : -1; }
|
||||
void ImGuiInputTextState::SelectAll() { Stb->select_start = 0; Stb->cursor = Stb->select_end = TextLen; Stb->has_preferred_x = 0; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndSelectAll() { WantReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; }
|
||||
@@ -4279,7 +4301,7 @@ void ImGuiInputTextState::ReloadUserBufAndMoveToEnd() { WantReloadUserBuf
|
||||
|
||||
ImGuiInputTextCallbackData::ImGuiInputTextCallbackData()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
// Public API to manipulate UTF-8 text from within a callback.
|
||||
@@ -4375,9 +4397,10 @@ void ImGui::PopPasswordFont()
|
||||
}
|
||||
|
||||
// Return false to discard a character.
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard)
|
||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, ImGuiInputTextState* state, unsigned int* p_char, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard)
|
||||
{
|
||||
unsigned int c = *p_char;
|
||||
ImGuiInputTextFlags flags = state->Flags;
|
||||
|
||||
// Filter non-printable (NB: isprint is unreliable! see #2467)
|
||||
bool apply_named_filters = true;
|
||||
@@ -4467,9 +4490,11 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiInputTextCallbackData callback_data;
|
||||
callback_data.Ctx = &g;
|
||||
callback_data.ID = state->ID;
|
||||
callback_data.Flags = flags;
|
||||
callback_data.EventFlag = ImGuiInputTextFlags_CallbackCharFilter;
|
||||
callback_data.EventChar = (ImWchar)c;
|
||||
callback_data.Flags = flags;
|
||||
callback_data.EventActivated = (g.ActiveId == state->ID && g.ActiveIdIsJustActivated);
|
||||
callback_data.UserData = user_data;
|
||||
if (callback(&callback_data) != 0)
|
||||
return false;
|
||||
@@ -4826,6 +4851,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
SetActiveID(id, window);
|
||||
SetFocusID(id, window);
|
||||
FocusWindow(window);
|
||||
if (input_requested_by_nav)
|
||||
SetNavCursorVisibleAfterMove();
|
||||
}
|
||||
if (g.ActiveId == id)
|
||||
{
|
||||
@@ -4984,7 +5011,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (Shortcut(ImGuiKey_Tab, ImGuiInputFlags_Repeat, id))
|
||||
{
|
||||
unsigned int c = '\t'; // Insert TAB
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data))
|
||||
if (InputTextFilterCharacter(&g, state, &c, callback, callback_user_data))
|
||||
state->OnCharPressed(c);
|
||||
}
|
||||
// FIXME: Implement Shift+Tab
|
||||
@@ -5007,7 +5034,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
unsigned int c = (unsigned int)io.InputQueueCharacters[n];
|
||||
if (c == '\t') // Skip Tab, see above.
|
||||
continue;
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data))
|
||||
if (InputTextFilterCharacter(&g, state, &c, callback, callback_user_data))
|
||||
state->OnCharPressed(c);
|
||||
}
|
||||
|
||||
@@ -5093,7 +5120,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
// Insert new line
|
||||
unsigned int c = '\n';
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data))
|
||||
if (InputTextFilterCharacter(&g, state, &c, callback, callback_user_data))
|
||||
state->OnCharPressed(c);
|
||||
}
|
||||
}
|
||||
@@ -5162,7 +5189,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
unsigned int c;
|
||||
int in_len = ImTextCharFromUtf8(&c, s, clipboard_end);
|
||||
s += in_len;
|
||||
if (!InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, true))
|
||||
if (!InputTextFilterCharacter(&g, state, &c, callback, callback_user_data, true))
|
||||
continue;
|
||||
char c_utf8[5];
|
||||
ImTextCharToUtf8(c_utf8, c);
|
||||
@@ -5261,8 +5288,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
ImGuiInputTextCallbackData callback_data;
|
||||
callback_data.Ctx = &g;
|
||||
callback_data.EventFlag = event_flag;
|
||||
callback_data.ID = id;
|
||||
callback_data.Flags = flags;
|
||||
callback_data.EventFlag = event_flag;
|
||||
callback_data.EventActivated = (g.ActiveId == state->ID && g.ActiveIdIsJustActivated);
|
||||
callback_data.UserData = callback_user_data;
|
||||
|
||||
// FIXME-OPT: Undo stack reconcile needs a backup of the data until we rework API, see #7925
|
||||
@@ -5338,8 +5367,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
ImGuiInputTextCallbackData callback_data;
|
||||
callback_data.Ctx = &g;
|
||||
callback_data.EventFlag = ImGuiInputTextFlags_CallbackResize;
|
||||
callback_data.ID = id;
|
||||
callback_data.Flags = flags;
|
||||
callback_data.EventFlag = ImGuiInputTextFlags_CallbackResize;
|
||||
callback_data.EventActivated = (g.ActiveId == state->ID && g.ActiveIdIsJustActivated);
|
||||
callback_data.Buf = buf;
|
||||
callback_data.BufTextLen = apply_new_text_length;
|
||||
callback_data.BufSize = ImMax(buf_size, apply_new_text_length + 1);
|
||||
@@ -5369,7 +5400,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
|
||||
ImVec2 draw_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding;
|
||||
ImVec2 text_size(0.0f, 0.0f);
|
||||
ImRect clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + inner_size.x, frame_bb.Min.y + inner_size.y); // Not using frame_bb.Max because we have adjusted size
|
||||
if (is_multiline)
|
||||
clip_rect.ClipWith(draw_window->ClipRect);
|
||||
@@ -5427,7 +5457,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
line_visible_n1 = ImMin(line_visible_n1, line_count);
|
||||
|
||||
// Store text height (we don't need width)
|
||||
text_size = ImVec2(inner_size.x, line_count * g.FontSize);
|
||||
float text_size_y = line_count * g.FontSize;
|
||||
//GetForegroundDrawList()->AddRect(draw_pos + ImVec2(0, line_visible_n0 * g.FontSize), draw_pos + ImVec2(frame_size.x, line_visible_n1 * g.FontSize), IM_COL32(255, 0, 0, 255));
|
||||
|
||||
// Calculate blinking cursor position
|
||||
@@ -5487,7 +5517,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
if (new_scroll_y != scroll_y)
|
||||
{
|
||||
const float scroll_max_y = ImMax((text_size.y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f);
|
||||
const float scroll_max_y = ImMax((text_size_y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f);
|
||||
scroll_y = ImClamp(new_scroll_y, 0.0f, scroll_max_y);
|
||||
draw_pos.y += (draw_window->Scroll.y - scroll_y); // Manipulate cursor pos immediately avoid a frame of lag
|
||||
draw_window->Scroll.y = scroll_y;
|
||||
@@ -5580,7 +5610,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (is_multiline)
|
||||
{
|
||||
// For focus requests to work on our multiline we need to ensure our child ItemAdd() call specifies the ImGuiItemFlags_Inputable (see #4761, #7870)...
|
||||
Dummy(ImVec2(text_size.x, text_size.y + style.FramePadding.y));
|
||||
Dummy(ImVec2(0.0f, text_size_y + style.FramePadding.y));
|
||||
g.NextItemData.ItemFlags |= (ImGuiItemFlags)ImGuiItemFlags_Inputable | ImGuiItemFlags_NoTabStop;
|
||||
EndChild();
|
||||
item_data_backup.StatusFlags |= (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredWindow);
|
||||
@@ -5595,7 +5625,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
g.LastItemData.StatusFlags = item_data_backup.StatusFlags;
|
||||
}
|
||||
}
|
||||
if (state)
|
||||
if (state && is_readonly)
|
||||
state->TextSrc = NULL;
|
||||
|
||||
// Log as text
|
||||
@@ -5779,8 +5809,10 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
{
|
||||
// RGB/HSV 0..255 Sliders
|
||||
const float w_items = w_inputs - style.ItemInnerSpacing.x * (components - 1);
|
||||
const float w_per_component = IM_TRUNC(w_items / components);
|
||||
const bool draw_color_marker = (flags & (ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_NoColorMarkers)) == 0;
|
||||
|
||||
const bool hide_prefix = (IM_TRUNC(w_items / components) <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x);
|
||||
const bool hide_prefix = draw_color_marker || (w_per_component <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x);
|
||||
static const char* ids[4] = { "##X", "##Y", "##Z", "##W" };
|
||||
static const char* fmt_table_int[3][4] =
|
||||
{
|
||||
@@ -5795,6 +5827,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
{ "H:%0.3f", "S:%0.3f", "V:%0.3f", "A:%0.3f" } // Long display for HSVA
|
||||
};
|
||||
const int fmt_idx = hide_prefix ? 0 : (flags & ImGuiColorEditFlags_DisplayHSV) ? 2 : 1;
|
||||
const ImGuiSliderFlags drag_flags = draw_color_marker ? ImGuiSliderFlags_ColorMarkers : ImGuiSliderFlags_None;
|
||||
|
||||
float prev_split = 0.0f;
|
||||
for (int n = 0; n < components; n++)
|
||||
@@ -5804,16 +5837,18 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
float next_split = IM_TRUNC(w_items * (n + 1) / components);
|
||||
SetNextItemWidth(ImMax(next_split - prev_split, 1.0f));
|
||||
prev_split = next_split;
|
||||
if (draw_color_marker)
|
||||
SetNextItemColorMarker(GDefaultRgbaColorMarkers[n]);
|
||||
|
||||
// FIXME: When ImGuiColorEditFlags_HDR flag is passed HS values snap in weird ways when SV values go below 0.
|
||||
if (flags & ImGuiColorEditFlags_Float)
|
||||
{
|
||||
value_changed |= DragFloat(ids[n], &f[n], 1.0f / 255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]);
|
||||
value_changed |= DragFloat(ids[n], &f[n], 1.0f / 255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n], drag_flags);
|
||||
value_changed_as_float |= value_changed;
|
||||
}
|
||||
else
|
||||
{
|
||||
value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]);
|
||||
value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n], drag_flags);
|
||||
}
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
|
||||
@@ -5824,11 +5859,11 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
// RGB Hexadecimal Input
|
||||
char buf[64];
|
||||
if (alpha)
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255), ImClamp(i[3], 0, 255));
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "#%02X%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255), ImClamp(i[3], 0, 255));
|
||||
else
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255));
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "#%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255));
|
||||
SetNextItemWidth(w_inputs);
|
||||
if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsUppercase))
|
||||
if (InputText("##Text", buf, IM_COUNTOF(buf), ImGuiInputTextFlags_CharsUppercase))
|
||||
{
|
||||
value_changed = true;
|
||||
char* p = buf;
|
||||
@@ -6436,6 +6471,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
}
|
||||
|
||||
// Initialize/override default color options
|
||||
// FIXME: Could be moved to a simple IO field.
|
||||
void ImGui::SetColorEditOptions(ImGuiColorEditFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -6522,18 +6558,18 @@ void ImGui::ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags)
|
||||
{
|
||||
int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]);
|
||||
char buf[64];
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]);
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]);
|
||||
if (Selectable(buf))
|
||||
SetClipboardText(buf);
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "(%d,%d,%d,%d)", cr, cg, cb, ca);
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "(%d,%d,%d,%d)", cr, cg, cb, ca);
|
||||
if (Selectable(buf))
|
||||
SetClipboardText(buf);
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", cr, cg, cb);
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "#%02X%02X%02X", cr, cg, cb);
|
||||
if (Selectable(buf))
|
||||
SetClipboardText(buf);
|
||||
if (!(flags & ImGuiColorEditFlags_NoAlpha))
|
||||
{
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", cr, cg, cb, ca);
|
||||
ImFormatString(buf, IM_COUNTOF(buf), "#%02X%02X%02X%02X", cr, cg, cb, ca);
|
||||
if (Selectable(buf))
|
||||
SetClipboardText(buf);
|
||||
}
|
||||
@@ -6774,7 +6810,6 @@ static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags, float x1)
|
||||
window->DC.TreeRecordsClippedNodesY2Mask |= (1 << window->DC.TreeDepth);
|
||||
}
|
||||
|
||||
// When using public API, currently 'id == storage_id' is always true, but we separate the values to facilitate advanced user code doing storage queries outside of UI loop.
|
||||
bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
@@ -6783,26 +6818,28 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
// When not framed, we vertically increase height up to typical framed widget height
|
||||
const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0;
|
||||
const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y));
|
||||
const bool use_frame_padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding));
|
||||
const ImVec2 padding = use_frame_padding ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y));
|
||||
|
||||
if (!label_end)
|
||||
label_end = FindRenderedTextEnd(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, label_end, false);
|
||||
|
||||
const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapsing arrow width + Spacing
|
||||
const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it
|
||||
const float text_offset_y = use_frame_padding ? ImMax(style.FramePadding.y, window->DC.CurrLineTextBaseOffset) : window->DC.CurrLineTextBaseOffset; // Latch before ItemSize changes it
|
||||
const float text_width = g.FontSize + label_size.x + padding.x * 2; // Include collapsing arrow
|
||||
|
||||
// We vertically grow up to current line height up the typical widget height.
|
||||
const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2);
|
||||
const float frame_height = label_size.y + padding.y * 2;
|
||||
const bool span_all_columns = (flags & ImGuiTreeNodeFlags_SpanAllColumns) != 0 && (g.CurrentTable != NULL);
|
||||
const bool span_all_columns_label = (flags & ImGuiTreeNodeFlags_LabelSpanAllColumns) != 0 && (g.CurrentTable != NULL);
|
||||
ImRect frame_bb;
|
||||
frame_bb.Min.x = span_all_columns ? window->ParentWorkRect.Min.x : (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x;
|
||||
frame_bb.Min.y = window->DC.CursorPos.y;
|
||||
frame_bb.Min.y = window->DC.CursorPos.y + (text_offset_y - padding.y);
|
||||
frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : (flags & ImGuiTreeNodeFlags_SpanLabelWidth) ? window->DC.CursorPos.x + text_width + padding.x : window->WorkRect.Max.x;
|
||||
frame_bb.Max.y = window->DC.CursorPos.y + frame_height;
|
||||
frame_bb.Max.y = window->DC.CursorPos.y + (text_offset_y - padding.y) + frame_height;
|
||||
if (display_frame)
|
||||
{
|
||||
const float outer_extend = IM_TRUNC(window->WindowPadding.x * 0.5f); // Framed header expand a little outside of current limits
|
||||
@@ -7485,7 +7522,7 @@ ImGuiTypingSelectRequest* ImGui::GetTypingSelectRequest(ImGuiTypingSelectFlags f
|
||||
}
|
||||
|
||||
// Append to buffer
|
||||
const int buffer_max_len = IM_ARRAYSIZE(data->SearchBuffer) - 1;
|
||||
const int buffer_max_len = IM_COUNTOF(data->SearchBuffer) - 1;
|
||||
int buffer_len = (int)ImStrlen(data->SearchBuffer);
|
||||
bool select_request = false;
|
||||
for (ImWchar w : g.IO.InputQueueCharacters)
|
||||
@@ -8885,7 +8922,7 @@ void ImGui::Value(const char* prefix, float v, const char* float_format)
|
||||
if (float_format)
|
||||
{
|
||||
char fmt[64];
|
||||
ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%s: %s", float_format);
|
||||
ImFormatString(fmt, IM_COUNTOF(fmt), "%%s: %s", float_format);
|
||||
Text(fmt, prefix, v);
|
||||
}
|
||||
else
|
||||
@@ -8924,7 +8961,7 @@ void ImGuiMenuColumns::CalcNextTotalWidth(bool update_offsets)
|
||||
{
|
||||
ImU16 offset = 0;
|
||||
bool want_spacing = false;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(Widths); i++)
|
||||
for (int i = 0; i < IM_COUNTOF(Widths); i++)
|
||||
{
|
||||
ImU16 width = Widths[i];
|
||||
if (want_spacing && width > 0)
|
||||
@@ -9021,6 +9058,10 @@ void ImGui::EndMenuBar()
|
||||
NavMoveRequestForward(g.NavMoveDir, g.NavMoveClipDir, g.NavMoveFlags, g.NavMoveScrollFlags); // Repeat
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NavMoveRequestTryWrapping(window, ImGuiNavMoveFlags_WrapX);
|
||||
}
|
||||
|
||||
PopClipRect();
|
||||
PopID();
|
||||
@@ -9106,11 +9147,7 @@ bool ImGui::BeginMainMenuBar()
|
||||
void ImGui::EndMainMenuBar()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (!g.CurrentWindow->DC.MenuBarAppending)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(0, "Calling EndMainMenuBar() not from a menu-bar!"); // Not technically testing that it is the main menu bar
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(g.CurrentWindow->DC.MenuBarAppending, "Calling EndMainMenuBar() not from a menu-bar!"); // Not technically testing that it is the main menu bar
|
||||
|
||||
EndMenuBar();
|
||||
g.CurrentWindow->Flags |= ImGuiWindowFlags_NoSavedSettings; // Restore _NoSavedSettings (#8356)
|
||||
@@ -9190,7 +9227,8 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
// The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu,
|
||||
// However the final position is going to be different! It is chosen by FindBestWindowPosForPopup().
|
||||
// e.g. Menus tend to overlap each other horizontally to amplify relative Z-ordering.
|
||||
ImVec2 popup_pos, pos = window->DC.CursorPos;
|
||||
ImVec2 popup_pos;
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
PushID(label);
|
||||
if (!enabled)
|
||||
BeginDisabled();
|
||||
@@ -9204,34 +9242,34 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
// 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);
|
||||
window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * 0.5f);
|
||||
PushStyleVarX(ImGuiStyleVar_ItemSpacing, style.ItemSpacing.x * 2.0f);
|
||||
float w = label_size.x;
|
||||
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, pos.y + window->DC.CurrLineTextBaseOffset);
|
||||
pressed = Selectable("", menu_is_open, selectable_flags, ImVec2(w, label_size.y));
|
||||
LogSetNextTextDecoration("[", "]");
|
||||
RenderText(text_pos, label);
|
||||
PopStyleVar();
|
||||
window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
|
||||
popup_pos = ImVec2(pos.x - 1.0f - IM_TRUNC(style.ItemSpacing.x * 0.5f), text_pos.y - style.FramePadding.y + window->MenuBarHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Menu inside a regular/vertical menu
|
||||
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
|
||||
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.)
|
||||
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
|
||||
float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
|
||||
float checkmark_w = IM_TRUNC(g.FontSize * 1.20f);
|
||||
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame
|
||||
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
||||
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
ImVec2 text_pos(window->DC.CursorPos.x, pos.y + window->DC.CurrLineTextBaseOffset);
|
||||
pressed = Selectable("", menu_is_open, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, label_size.y));
|
||||
LogSetNextTextDecoration("", ">");
|
||||
RenderText(text_pos, label);
|
||||
RenderText(ImVec2(text_pos.x + offsets->OffsetLabel, text_pos.y), label);
|
||||
if (icon_w > 0.0f)
|
||||
RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
|
||||
RenderArrow(window->DrawList, pos + ImVec2(offsets->OffsetMark + extra_w + g.FontSize * 0.30f, 0.0f), GetColorU32(ImGuiCol_Text), ImGuiDir_Right);
|
||||
RenderText(ImVec2(text_pos.x + offsets->OffsetIcon, text_pos.y), icon);
|
||||
RenderArrow(window->DrawList, ImVec2(text_pos.x + offsets->OffsetMark + extra_w + g.FontSize * 0.30f, text_pos.y), GetColorU32(ImGuiCol_Text), ImGuiDir_Right);
|
||||
popup_pos = ImVec2(pos.x, text_pos.y - style.WindowPadding.y);
|
||||
}
|
||||
if (!enabled)
|
||||
EndDisabled();
|
||||
@@ -9369,7 +9407,8 @@ void ImGui::EndMenu()
|
||||
// Nav: When a left move request our menu failed, close ourselves.
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginMenu()/EndMenu() calls
|
||||
IM_ASSERT_USER_ERROR_RET((window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu), "Calling EndMenu() in wrong window!");
|
||||
|
||||
ImGuiWindow* parent_window = window->ParentWindow; // Should always be != NULL is we passed assert.
|
||||
if (window->BeginCount == window->BeginCountPreviousFrame)
|
||||
if (g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet())
|
||||
@@ -9432,21 +9471,22 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
||||
float checkmark_w = IM_TRUNC(g.FontSize * 1.20f);
|
||||
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame
|
||||
float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
||||
ImVec2 text_pos(pos.x, pos.y + window->DC.CurrLineTextBaseOffset);
|
||||
pressed = Selectable("", false, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, label_size.y));
|
||||
if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible)
|
||||
{
|
||||
RenderText(pos + ImVec2(offsets->OffsetLabel, 0.0f), label);
|
||||
RenderText(text_pos + ImVec2(offsets->OffsetLabel, 0.0f), label);
|
||||
if (icon_w > 0.0f)
|
||||
RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
|
||||
RenderText(text_pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
|
||||
if (shortcut_w > 0.0f)
|
||||
{
|
||||
PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
||||
LogSetNextTextDecoration("(", ")");
|
||||
RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false);
|
||||
RenderText(text_pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false);
|
||||
PopStyleColor();
|
||||
}
|
||||
if (selected)
|
||||
RenderCheckMark(window->DrawList, pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f);
|
||||
RenderCheckMark(window->DrawList, text_pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f);
|
||||
}
|
||||
}
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
|
||||
@@ -9507,7 +9547,7 @@ struct ImGuiTabBarSection
|
||||
float WidthAfterShrinkMinWidth;
|
||||
float Spacing; // Horizontal spacing at the end of the section.
|
||||
|
||||
ImGuiTabBarSection() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiTabBarSection() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
namespace ImGui
|
||||
@@ -9523,7 +9563,7 @@ namespace ImGui
|
||||
|
||||
ImGuiTabBar::ImGuiTabBar()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
CurrFrameVisible = PrevFrameVisible = -1;
|
||||
LastTabItemIdx = -1;
|
||||
}
|
||||
@@ -9665,11 +9705,7 @@ void ImGui::EndTabBar()
|
||||
return;
|
||||
|
||||
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||
if (tab_bar == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Mismatched BeginTabBar()/EndTabBar()!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(tab_bar != NULL, "Mismatched BeginTabBar()/EndTabBar()!");
|
||||
|
||||
// Fallback in case no TabItem have been submitted
|
||||
if (tab_bar->WantLayout)
|
||||
@@ -9758,11 +9794,17 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
ImQsort(tab_bar->Tabs.Data, tab_bar->Tabs.Size, sizeof(ImGuiTabItem), TabItemComparerBySection);
|
||||
|
||||
// Calculate spacing between sections
|
||||
sections[0].Spacing = sections[0].TabCount > 0 && (sections[1].TabCount + sections[2].TabCount) > 0 ? g.Style.ItemInnerSpacing.x : 0.0f;
|
||||
sections[1].Spacing = sections[1].TabCount > 0 && sections[2].TabCount > 0 ? g.Style.ItemInnerSpacing.x : 0.0f;
|
||||
const float tab_spacing = g.Style.ItemInnerSpacing.x;
|
||||
sections[0].Spacing = sections[0].TabCount > 0 && (sections[1].TabCount + sections[2].TabCount) > 0 ? tab_spacing : 0.0f;
|
||||
sections[1].Spacing = sections[1].TabCount > 0 && sections[2].TabCount > 0 ? tab_spacing : 0.0f;
|
||||
|
||||
// Setup next selected tab
|
||||
ImGuiID scroll_to_tab_id = 0;
|
||||
if (tab_bar->NextScrollToTabId)
|
||||
{
|
||||
scroll_to_tab_id = tab_bar->NextScrollToTabId;
|
||||
tab_bar->NextScrollToTabId = 0;
|
||||
}
|
||||
if (tab_bar->NextSelectedTabId)
|
||||
{
|
||||
tab_bar->SelectedTabId = tab_bar->NextSelectedTabId;
|
||||
@@ -9820,8 +9862,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
|
||||
int section_n = TabItemGetSectionIdx(tab);
|
||||
ImGuiTabBarSection* section = §ions[section_n];
|
||||
section->Width += tab->ContentWidth + (section_n == curr_section_n ? g.Style.ItemInnerSpacing.x : 0.0f);
|
||||
section->WidthAfterShrinkMinWidth += ImMin(tab->ContentWidth, shrink_min_width) + (section_n == curr_section_n ? g.Style.ItemInnerSpacing.x : 0.0f);
|
||||
section->Width += tab->ContentWidth + (section_n == curr_section_n ? tab_spacing : 0.0f);
|
||||
section->WidthAfterShrinkMinWidth += ImMin(tab->ContentWidth, shrink_min_width) + (section_n == curr_section_n ? tab_spacing : 0.0f);
|
||||
curr_section_n = section_n;
|
||||
|
||||
// Store data so we can build an array sorted by width if we need to shrink tabs down
|
||||
@@ -10126,6 +10168,7 @@ void ImGui::TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* s
|
||||
if ((tab_bar->Flags & ImGuiTabBarFlags_Reorderable) == 0)
|
||||
return;
|
||||
|
||||
const float tab_spacing = g.Style.ItemInnerSpacing.x;
|
||||
const bool is_central_section = (src_tab->Flags & ImGuiTabItemFlags_SectionMask_) == 0;
|
||||
const float bar_offset = tab_bar->BarRect.Min.x - (is_central_section ? tab_bar->ScrollingTarget : 0);
|
||||
|
||||
@@ -10144,8 +10187,8 @@ void ImGui::TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* s
|
||||
dst_idx = i;
|
||||
|
||||
// Include spacing after tab, so when mouse cursor is between tabs we would not continue checking further tabs that are not hovered.
|
||||
const float x1 = bar_offset + dst_tab->Offset - g.Style.ItemInnerSpacing.x;
|
||||
const float x2 = bar_offset + dst_tab->Offset + dst_tab->Width + g.Style.ItemInnerSpacing.x;
|
||||
const float x1 = bar_offset + dst_tab->Offset - tab_spacing;
|
||||
const float x2 = bar_offset + dst_tab->Offset + dst_tab->Width + tab_spacing;
|
||||
//GetForegroundDrawList()->AddRect(ImVec2(x1, tab_bar->BarRect.Min.y), ImVec2(x2, tab_bar->BarRect.Max.y), IM_COL32(255, 0, 0, 255));
|
||||
if ((dir < 0 && mouse_pos.x > x1) || (dir > 0 && mouse_pos.x < x2))
|
||||
break;
|
||||
@@ -10308,11 +10351,7 @@ bool ImGui::BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags f
|
||||
return false;
|
||||
|
||||
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||
if (tab_bar == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(tab_bar, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return false;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RETV(tab_bar != NULL, false, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
IM_ASSERT((flags & ImGuiTabItemFlags_Button) == 0); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
|
||||
|
||||
bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL);
|
||||
@@ -10332,11 +10371,7 @@ void ImGui::EndTabItem()
|
||||
return;
|
||||
|
||||
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||
if (tab_bar == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
IM_ASSERT(tab_bar->LastTabItemIdx >= 0);
|
||||
ImGuiTabItem* tab = &tab_bar->Tabs[tab_bar->LastTabItemIdx];
|
||||
if (!(tab->Flags & ImGuiTabItemFlags_NoPushId))
|
||||
@@ -10351,11 +10386,7 @@ bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags)
|
||||
return false;
|
||||
|
||||
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||
if (tab_bar == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return false;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RETV(tab_bar != NULL, false, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return TabItemEx(tab_bar, label, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, NULL);
|
||||
}
|
||||
|
||||
@@ -10367,11 +10398,7 @@ void ImGui::TabItemSpacing(const char* str_id, ImGuiTabItemFlags flags, float
|
||||
return;
|
||||
|
||||
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||
if (tab_bar == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR_RET(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
SetNextItemWidth(width);
|
||||
TabItemEx(tab_bar, str_id, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder | ImGuiTabItemFlags_Invisible, NULL);
|
||||
}
|
||||
|
||||
@@ -84,14 +84,10 @@ endif()
|
||||
if(_M_ARM64)
|
||||
message(WARNING "
|
||||
*************** UNSUPPORTED CONFIGURATION ***************
|
||||
|
||||
Apple Silicon support in PCSX2 is INCOMPLETE. There are
|
||||
currently no EE/VU/IOP recompilers, and games will run
|
||||
VERY slow. There is no date for completion yet, you
|
||||
should set -DCMAKE_OSX_ARCHITECTURES=x86_64 for now,
|
||||
unless you want to work on the recompilers.
|
||||
|
||||
We also ask that you read https://dont-ship.it/.
|
||||
|
||||
*********************************************************")
|
||||
endif()
|
||||
|
||||
@@ -1980,6 +1980,8 @@ SCAJ-20116:
|
||||
SCAJ-20117:
|
||||
name: "Fu-un Bakumatsu-den"
|
||||
region: "NTSC-Unk"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SCAJ-20118:
|
||||
name: "ラジアータ ストーリーズ"
|
||||
name-sort: "らじあーた すとーりーず"
|
||||
@@ -6268,19 +6270,23 @@ SCES-53880:
|
||||
region: "PAL-E"
|
||||
SCES-53881:
|
||||
name: "Buzz! Le Grand Quiz"
|
||||
name-en: "Buzz! The Big Quiz"
|
||||
region: "PAL-F"
|
||||
SCES-53882:
|
||||
name: "Buzz! The Big Quiz"
|
||||
name: "Buzz! Il Superquiz"
|
||||
name-en: "Buzz! The Big Quiz"
|
||||
region: "PAL-I"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes freezes.
|
||||
SCES-53883:
|
||||
name: "Buzz! The Big Quiz"
|
||||
name: "Buzz! Das große Quiz"
|
||||
name-en: "Buzz! The Big Quiz"
|
||||
region: "PAL-G"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes freezes.
|
||||
SCES-53884:
|
||||
name: "Buzz! El GRAN Reto"
|
||||
name: "Buzz! El Gran Reto"
|
||||
name-en: "Buzz! The Big Quiz"
|
||||
region: "PAL-S"
|
||||
compat: 2
|
||||
gameFixes:
|
||||
@@ -6317,10 +6323,12 @@ SCES-53926:
|
||||
name: "Buzz! The Big Quiz"
|
||||
region: "PAL-SC"
|
||||
SCES-53927:
|
||||
name: "Buzz! The Big Quiz"
|
||||
name: "Buzz! Suuri Tietovisa"
|
||||
name-en: "Buzz! The Big Quiz"
|
||||
region: "PAL-FI"
|
||||
SCES-53929:
|
||||
name: "Buzz! The Big Quiz"
|
||||
name: "Buzz! O Grande Quiz"
|
||||
name-en: "Buzz! The Big Quiz"
|
||||
region: "PAL-P"
|
||||
SCES-53931:
|
||||
name: "Shinobido - Way of the Ninja"
|
||||
@@ -6436,19 +6444,23 @@ SCES-54258:
|
||||
name: "Buzz! The Sports Quiz"
|
||||
region: "PAL-E"
|
||||
SCES-54259:
|
||||
name: "Buzz! The Sports Quiz"
|
||||
name: "Buzz! Das Sport-Quiz"
|
||||
name-en: "Buzz! The Sports Quiz"
|
||||
region: "PAL-G"
|
||||
SCES-54260:
|
||||
name: "Buzz! Le Quiz du Sport"
|
||||
name-en: "Buzz! The Sports Quiz"
|
||||
region: "PAL-F"
|
||||
SCES-54261:
|
||||
name: "Buzz! The Sports Quiz"
|
||||
region: "PAL-I"
|
||||
SCES-54262:
|
||||
name: "Buzz! - El Gran Concurso de Deportes"
|
||||
name: "Buzz! El Gran Concurso de Deportes"
|
||||
name-en: "Buzz! The Sports Quiz"
|
||||
region: "PAL-S"
|
||||
SCES-54263:
|
||||
name: "Buzz! The Sports Quiz"
|
||||
name: "Buzz! O Quiz Desportivo"
|
||||
name-en: "Buzz! The Sports Quiz"
|
||||
region: "PAL-P"
|
||||
SCES-54264:
|
||||
name: "Buzz! The Sports Quiz"
|
||||
@@ -6460,7 +6472,8 @@ SCES-54266:
|
||||
name: "Buzz! The Sports Quiz"
|
||||
region: "PAL-SC"
|
||||
SCES-54267:
|
||||
name: "Buzz! The Sports Quiz"
|
||||
name: "Buzz! Sporttivisa"
|
||||
name-en: "Buzz! The Sports Quiz"
|
||||
region: "PAL-FI"
|
||||
SCES-54268:
|
||||
name: "Buzz! The Sports Quiz"
|
||||
@@ -6496,24 +6509,29 @@ SCES-54496:
|
||||
region: "PAL-E"
|
||||
SCES-54497:
|
||||
name: "Buzz! Le Mega Quiz"
|
||||
name-en: "Buzz! The Mega Quiz"
|
||||
region: "PAL-F"
|
||||
SCES-54498:
|
||||
name: "Buzz! The Mega Quiz"
|
||||
region: "PAL-I"
|
||||
SCES-54499:
|
||||
name: "Buzz! Das Mega-Quiz"
|
||||
name-en: "Buzz! The Mega Quiz"
|
||||
region: "PAL-G"
|
||||
SCES-54500:
|
||||
name: "Buzz! El Mega Concurso"
|
||||
name-en: "Buzz! The Mega Quiz"
|
||||
region: "PAL-S"
|
||||
SCES-54501:
|
||||
name: "Buzz! The Mega Quiz"
|
||||
region: "PAL-A"
|
||||
SCES-54503:
|
||||
name: "Buzz! Megavisa"
|
||||
name-en: "Buzz! The Mega Quiz"
|
||||
region: "PAL-FI"
|
||||
SCES-54504:
|
||||
name: "Buzz! O Mega Quiz"
|
||||
name-en: "Buzz! The Mega Quiz"
|
||||
region: "PAL-P"
|
||||
SCES-54505:
|
||||
name: "Buzz! The Mega Quiz"
|
||||
@@ -13217,9 +13235,7 @@ SLAJ-25018:
|
||||
region: "NTSC-HK"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # Improves visual clarity whilst upscaling.
|
||||
roundSprite: 1 # Reduces graphics garbage on UI whilst upscaling.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLAJ-25019:
|
||||
name: "The Lord of the Rings - The Return of the King"
|
||||
region: "NTSC-C"
|
||||
@@ -22704,9 +22720,7 @@ SLES-53191:
|
||||
name: "Kaido Racer"
|
||||
region: "PAL-M5"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Rain/Storm.
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLES-53192:
|
||||
name: "Tim Burton's The Nightmare Before Christmas - Oogie's Reveng"
|
||||
name-sort: "Nightmare Before Christmas, The - Tim Burton's"
|
||||
@@ -24969,9 +24983,7 @@ SLES-53900:
|
||||
name: "Kaido Racer 2"
|
||||
region: "PAL-M3"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Storm.
|
||||
alignSprite: 1 # Fixes black lines when upscaling.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLES-53901:
|
||||
name: "Torino 2006"
|
||||
region: "PAL-M5"
|
||||
@@ -31336,9 +31348,7 @@ SLKA-25063:
|
||||
name-en: "Kaido Battle"
|
||||
region: "NTSC-K"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Rain.
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLKA-25064:
|
||||
name: "천주 3 천벌"
|
||||
name-en: "Tenchu - Wrath of Heaven"
|
||||
@@ -31433,9 +31443,7 @@ SLKA-25084:
|
||||
region: "NTSC-K"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # Improves visual clarity whilst upscaling.
|
||||
roundSprite: 1 # Reduces graphics garbage on UI whilst upscaling.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLKA-25085:
|
||||
name: "진・삼국무쌍 3 맹장전"
|
||||
name-en: "Jin Samguk Mussang 3 - Maengjangjeon"
|
||||
@@ -31723,9 +31731,7 @@ SLKA-25146:
|
||||
name-en: "Kaido Battle 2 - Chain Reaction"
|
||||
region: "NTSC-K"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Rain/Storm.
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLKA-25148:
|
||||
name: "MVP 베이스볼 2004"
|
||||
name-en: "MVP Baseball 2004"
|
||||
@@ -32312,9 +32318,11 @@ SLKA-25255:
|
||||
name-en: "Mobile Suit Gundam Seed - Never Ending Tomorrow"
|
||||
region: "NTSC-K"
|
||||
SLKA-25257:
|
||||
name: "풍운 막말전" # Undumped on ReDump as of 2025-08-28
|
||||
name-en: "Fu-un Bakumatsu Den"
|
||||
name: "풍운 막말전" # Undumped on ReDump as of 2025-08-28
|
||||
name-en: "Fu-un Bakumatsu-den"
|
||||
region: "NTSC-K"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLKA-25258:
|
||||
name: "요시츠네 영웅전"
|
||||
name-sort: "Yoshitsune Yeongungjeon"
|
||||
@@ -35575,9 +35583,7 @@ SLPM-60195:
|
||||
name-en: "Kaidō Battle - Nikko, Haruna, Rokko, Hakone [Trial]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Rain.
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-60197:
|
||||
name: "エキサイティングプロレス 4 [体験版]"
|
||||
name-sort: "えきさいてぃんぐぷろれす4 [たいけんばん]"
|
||||
@@ -35621,9 +35627,7 @@ SLPM-60206:
|
||||
name-en: "Shutokou Battle 01 [Trial]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # Improves visual clarity whilst upscaling.
|
||||
roundSprite: 1 # Reduces graphics garbage on UI whilst upscaling.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-60207:
|
||||
name: "ロックマンX7 [体験版]"
|
||||
name-sort: "ろっくまんえっくす7 [たいけんばん]"
|
||||
@@ -35718,10 +35722,12 @@ SLPM-60220:
|
||||
name-en: "Hajime no Ippo II - Victorious Road [Trial]"
|
||||
region: "NTSC-J"
|
||||
SLPM-60225:
|
||||
name: "風雲新撰組 [体験版]"
|
||||
name: "風雲 新撰組 [体験版]"
|
||||
name-sort: "ふううん しんせんぐみ [たいけんばん]"
|
||||
name-en: "Fuuun Shinsengumi [Trial]"
|
||||
name-en: "Fu-un Shinsen-gumi [Trial]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-60226:
|
||||
name: "シャドウハーツⅡ [体験版]"
|
||||
name-sort: "しゃどうはーつ2 [たいけんばん]"
|
||||
@@ -35737,9 +35743,7 @@ SLPM-60228:
|
||||
name-en: "Kaidō Battle 2 - Chain Reaction [Trial]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Rain/Storm.
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-60237:
|
||||
name: "電車でGO!FINAL [体験版]"
|
||||
name-sort: "でんしゃでごーFINAL [たいけんばん]"
|
||||
@@ -36489,10 +36493,12 @@ SLPM-61095:
|
||||
name-en: "Dengeki PS2 / DengekiPlayStation D74"
|
||||
region: "NTSC-J"
|
||||
SLPM-61096:
|
||||
name: "風雲幕末伝 [体験版]"
|
||||
name: "風雲 幕末伝 [体験版]"
|
||||
name-sort: "ふううんばくまつでん [たいけんばん]"
|
||||
name-en: "Fuuun Bakumatsu-den [Trial]"
|
||||
name-en: "Fu-un Bakumatsu-den [Trial]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-61097:
|
||||
name: "電撃PS2 / 電撃PlayStation D75"
|
||||
name-sort: "でんげき PS2 でんげきPlayStation D75"
|
||||
@@ -36601,8 +36607,7 @@ SLPM-61115:
|
||||
name-en: "Racing Battle - C1 Grand Prix [Trial]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-61116:
|
||||
name: "冒険王ビィト ダークネスセンチュリー [体験版]"
|
||||
name-sort: "ぼうけんおうびぃと だーくねすせんちゅりー [たいけんばん]"
|
||||
@@ -36649,9 +36654,7 @@ SLPM-61121:
|
||||
name-en: "Kaido Touge no Densetsu [Trial]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Rain/Storm.
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-61122:
|
||||
name: "電撃PS2 / 電撃PlayStation D81"
|
||||
name-sort: "でんげき PS2 でんげきPlayStation D81"
|
||||
@@ -42495,9 +42498,7 @@ SLPM-65246:
|
||||
name-en: "Kaidō Battle - Nikko, Haruna, Rokko, Hakone"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Rain.
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-65247:
|
||||
name: "三國志戦記2"
|
||||
name-sort: "さんごくしせんき2"
|
||||
@@ -42872,9 +42873,7 @@ SLPM-65308:
|
||||
region: "NTSC-J"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # Improves visual clarity whilst upscaling.
|
||||
roundSprite: 1 # Reduces graphics garbage on UI whilst upscaling.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-65309:
|
||||
name: "Splashdown [PlayStation2 the Best]"
|
||||
name-sort: "すぷらっしゅだうん [PlayStation2 the Best]"
|
||||
@@ -43907,10 +43906,12 @@ SLPM-65493:
|
||||
name-en: "Hurrah! Sailor [Limited Edition]"
|
||||
region: "NTSC-J"
|
||||
SLPM-65494:
|
||||
name: "風雲 新撰組"
|
||||
name: "風雲 新撰組"
|
||||
name-sort: "ふううん しんせんぐみ"
|
||||
name-en: "Fuuun Shinsengumi"
|
||||
name-en: "Fu-un Shinsen-gumi"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-65495:
|
||||
name: "モンスターハンター"
|
||||
name-sort: "もんすたーはんたー"
|
||||
@@ -44048,9 +44049,7 @@ SLPM-65514:
|
||||
name-en: "Kaidō Battle 2 - Chain Reaction"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Rain/Storm.
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-65515:
|
||||
name: "サクラ大戦物語 ~ミステリアス巴里~"
|
||||
name-sort: "さくらたいせんものがたり ~みすてりあすぱり~"
|
||||
@@ -45779,11 +45778,13 @@ SLPM-65812:
|
||||
name-en: "Bakushou! Jinsei Kaidou - NOVA Usagi ga Miteruzo! [TAITO BEST]"
|
||||
region: "NTSC-J"
|
||||
SLPM-65813:
|
||||
name: "風雲幕末伝"
|
||||
name: "風雲 幕末伝"
|
||||
name-sort: "ふううん ばくまつでん"
|
||||
name-en: "Fu-un Bakumatsu Den"
|
||||
name-en: "Fu-un Bakumatsu-den"
|
||||
region: "NTSC-J"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-65815:
|
||||
name: "トム・クランシーシリーズ スプリンターセル パンドラトゥモロー"
|
||||
name-sort: "とむくらんしーしりーず すぷりんたーせる ぱんどらとぅもろー"
|
||||
@@ -46249,8 +46250,7 @@ SLPM-65897:
|
||||
name-en: "Racing Battle - C1 Grand Prix"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-65898:
|
||||
name: "キャッスルファンタジア エレンシア戦記 DXパック"
|
||||
name-sort: "きゃっするふぁんたじあ えれんしあせんき DXぱっく"
|
||||
@@ -47001,9 +47001,7 @@ SLPM-66022:
|
||||
name-en: "Kaido - Touge no Densetsu"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Rain/Storm.
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-66023:
|
||||
name: "ふしぎ遊戯 玄武開伝 外伝 鏡の巫女 [限定版]"
|
||||
name-sort: "ふしぎゆうぎ げんぶかいでん がいでん かがみのみこ [げんていばん]"
|
||||
@@ -53752,10 +53750,12 @@ SLPM-74201:
|
||||
- "SLPM-65286"
|
||||
- "BWNETCNF"
|
||||
SLPM-74202:
|
||||
name: "風雲 新撰組 [PlayStation2 the Best]"
|
||||
name: "風雲 新撰組 [PlayStation2 the Best]"
|
||||
name-sort: "ふううん しんせんぐみ [PlayStation2 the Best]"
|
||||
name-en: "Fuuun Shinsengumi [PlayStation2 the Best]"
|
||||
name-en: "Fu-un Shinsen-gumi [PlayStation2 the Best]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-74204:
|
||||
name: "首都高バトル01 [PlayStation2 the Best]"
|
||||
name-sort: "しゅとこうばとる01 [PlayStation2 the Best]"
|
||||
@@ -53763,9 +53763,7 @@ SLPM-74204:
|
||||
region: "NTSC-J"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # Improves visual clarity whilst upscaling.
|
||||
roundSprite: 1 # Reduces graphics garbage on UI whilst upscaling.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-74205:
|
||||
name: "真・女神転生Ⅲ - NOCTURNE [PlayStation2 the Best]"
|
||||
name-sort: "しんめがみてんせい3 - NOCTURNE [PlayStation2 the Best]"
|
||||
@@ -53904,10 +53902,12 @@ SLPM-74227:
|
||||
halfPixelOffset: 4 # Fixes misaligned lighting and bloom.
|
||||
bilinearUpscale: 1 # Smooths out bloom.
|
||||
SLPM-74228:
|
||||
name: "風雲幕末伝 [PlayStation2 the Best]"
|
||||
name: "風雲 幕末伝 [PlayStation2 the Best]"
|
||||
name-sort: "ふううんばくまつでん [PlayStation2 the Best]"
|
||||
name-en: "Fuuun Bakumatsu-den [PlayStation2 the Best]"
|
||||
name-en: "Fu-un Bakumatsu-den [PlayStation2 the Best]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPM-74229:
|
||||
name: "バイオハザード4 [PlayStation2 the Best]"
|
||||
name-sort: "ばいおはざーど4 [PlayStation2 the Best]"
|
||||
@@ -63488,10 +63488,12 @@ SLPS-73227:
|
||||
name-en: "Another Century's Episode [PlayStation2 the Best]"
|
||||
region: "NTSC-J"
|
||||
SLPS-73228:
|
||||
name: "風雲幕末伝 [PlayStation2 the Best]"
|
||||
name: "風雲 幕末伝 [PlayStation2 the Best]"
|
||||
name-sort: "ふううんばくまつでん [PlayStation2 the Best]"
|
||||
name-en: "Fuuun Bakumatsu-den [PlayStation2 the Best]"
|
||||
name-en: "Fu-un Bakumatsu-den [PlayStation2 the Best]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLPS-73229:
|
||||
name: "ベルウィックサーガ [PlayStation2 the Best]"
|
||||
name-sort: "べるうぃっくさーが [PlayStation2 the Best]"
|
||||
@@ -68131,9 +68133,7 @@ SLUS-20831:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # Improves visual clarity whilst upscaling.
|
||||
roundSprite: 1 # Reduces graphics garbage on UI whilst upscaling.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLUS-20833:
|
||||
name: "Mega Man Anniversary Collection"
|
||||
region: "NTSC-U"
|
||||
@@ -70602,9 +70602,7 @@ SLUS-21236:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Rain.
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # Fixes double image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLUS-21237:
|
||||
name: "AND 1 Streetball"
|
||||
region: "NTSC-U"
|
||||
@@ -71786,9 +71784,7 @@ SLUS-21394:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting during Rain/Storm.
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
forceEvenSpritePosition: 1 # De-blurs the 3D image.
|
||||
halfPixelOffset: 5 # Fixes vertical lines.
|
||||
SLUS-21395:
|
||||
name: "Avatar - The Last Airbender"
|
||||
region: "NTSC-U"
|
||||
|
||||
@@ -236,8 +236,9 @@
|
||||
03000000ac0500005b05000000000000,GameSir G3w,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,
|
||||
03000000ac0500002d02000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000ac0500004d04000000000000,GameSir G4,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:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000373500002210000000000000,GameSir G7 Pro,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,lefty:a2,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,platform:Window,
|
||||
03000000373500002210000000000000,GameSir G7 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000ac0500001a06000000000000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000373500000410000000000000,GameSir T4 Kaleid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||
03000000373500009410000000000000,GameSir Tegenaria Lite,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
030000004c0e00001035000000000000,Gamester,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
|
||||
030000000d0f00001110000000000000,GameStick Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||
@@ -246,8 +247,6 @@
|
||||
03000000b62500000100000000000000,Gametel GT004 01,a:b3,b:b0,dpdown:b10,dpleft:b9,dpright:b8,dpup:b11,leftshoulder:b4,rightshoulder:b5,start:b7,x:b1,y:b2,platform:Windows,
|
||||
030000008f0e00001411000000000000,Gamo2 Divaller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000120c0000a857000000000000,Gator Claw,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000c21100000791000000000000,Nacon GC101 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||
03000000c9110000f055000000000000,Nacon GC100XF,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||
030000008305000009a0000000000000,Genius,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||
030000008305000031b0000000000000,Genius Maxfire Blaze 3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||
03000000451300000010000000000000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||
@@ -367,7 +366,7 @@
|
||||
03000000fd0500002a26000000000000,InterAct Hammerhead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,
|
||||
03000000fd0500002f26000000000000,InterAct Hammerhead FX,a:b4,b:b5,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b1,y:b2,platform:Windows,
|
||||
03000000fd0500005302000000000000,InterAct ProPad,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows,
|
||||
03000000ac0500002c02000000000000,Ipega Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000ac0500002c02000000000000,Ipega Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000491900000204000000000000,Ipega PG9023,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:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000491900000304000000000000,Ipega PG9087,+righty:+a5,-righty:-a4,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:a3,start:b11,x:b3,y:b4,platform:Windows,
|
||||
030000007e0500000620000000000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,
|
||||
@@ -464,6 +463,8 @@
|
||||
03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||
03000000091200004488000000000000,MUSIA PlayStation 2 Input Display,a:b0,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:b11,rightx:a2,righty:a3,start:b5,x:b1,y:b3,platform:Windows,
|
||||
03000000f70600000100000000000000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Windows,
|
||||
03000000c9110000f055000000000000,Nacon GC100XF,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||
03000000c21100000791000000000000,Nacon GC101 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||
030000006b140000010c000000000000,Nacon GC400ES,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:Windows,
|
||||
030000006b1400001106000000000000,Nacon Revolution 3 PS4 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:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
||||
0300000085320000170d000000000000,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:Windows,
|
||||
@@ -697,7 +698,7 @@
|
||||
03000000730700000601000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
|
||||
03000000b40400000a01000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
|
||||
030000003b07000004a1000000000000,SFX,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Windows,
|
||||
03000000632500002705000000000000,ShanWan Q36,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Windows,
|
||||
03000000632500002705000000000000,ShanWan Q36,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000f82100001900000000000000,Shogun Bros Chameleon X1,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||
03000000120c00001c1e000000000000,SnakeByte 4S PS4 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
||||
03000000140300000918000000000000,SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
|
||||
@@ -888,6 +889,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
03000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,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:b4,y:b3,platform:Mac OS X,
|
||||
03000000c82d00000660000000020000,8BitDo Pro 2,a:b1,b:b0,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:b4,y:b3,platform:Mac OS X,
|
||||
03000000c82d00000960000000000000,8BitDo Pro 3,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b17,paddle2:b16,paddle3:b2,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||
03000000c82d00000131000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||
03000000c82d00000231000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||
03000000c82d00000331000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||
@@ -1174,7 +1176,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||
05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,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:b4,y:b3,platform:Linux,
|
||||
05000000c82d00006a28000000010000,8BitDo GameCube,a:b0,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b9,paddle2:b8,rightshoulder:b10,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b1,y:b4,platform:Linux,
|
||||
03000000c82d00001251000011010000,8BitDo Lite 2,a:b1,b:b0,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:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||
03000000c82d00001251000011010000,8BitDo Lite 2,a:b1,b:b0,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:b4,y:b3,platform:Linux,
|
||||
05000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,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:b4,y:b3,platform:Linux,
|
||||
03000000c82d00001151000011010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||
05000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||
@@ -1352,7 +1354,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000280400000140000000010000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,
|
||||
030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||
0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,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,
|
||||
0500000047532067616d657061640000,GS Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,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,
|
||||
03000000f0250000c383000010010000,GT VX2,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:Linux,
|
||||
030000008a2e0000dd10000011010000,Hand Held Legend GC Ultimate,a:b0,b:b2,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,misc2:b24,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b1,y:b3,platform:Linux,
|
||||
030000008a2e0000df10000011010000,Hand Held Legend ProGCC,a:b1,b:b0,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b3,y:b2,platform:Linux,
|
||||
@@ -1397,11 +1399,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000242e00006a38000010010000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Linux,
|
||||
03000000242e00008816000001010000,Hyperkin X91,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,
|
||||
03000000f00300008d03000011010000,HyperX Clutch,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,
|
||||
05000000f00300008d04000000010000,HyperX Clutch,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,
|
||||
03000000830500006020000010010000,iBuffalo Super Famicom Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
|
||||
03000000d80400004bea000011010000,icedragon.io STAC Dance Pad,a:b0,b:b1,x:b2,y:b3,back:b4,platform:Linux,
|
||||
03000000d80400004aea000011010000,icedragon.io STAC Dance Pad,a:b0,b:b1,x:b2,y:b3,back:b4,platform:Linux,
|
||||
030000008a2e0000d910000011010000,icedragon.io STAC2 Dance Pad,a:b0,b:b1,x:b2,y:b3,back:b4,platform:Linux,
|
||||
030000008a2e0000e910000011010000,icedragon.io STAC2 Dance Pad,a:b8,b:b9,x:b10,y:b11,back:b12,platform:Linux,
|
||||
03000000d80400004aea000011010000,icedragon.io STAC Dance Pad,a:b0,b:b1,back:b4,x:b2,y:b3,platform:Linux,
|
||||
03000000d80400004bea000011010000,icedragon.io STAC Dance Pad,a:b0,b:b1,back:b4,x:b2,y:b3,platform:Linux,
|
||||
030000008a2e0000d910000011010000,icedragon.io STAC2 Dance Pad,a:b0,b:b1,back:b4,x:b2,y:b3,platform:Linux,
|
||||
030000008a2e0000e910000011010000,icedragon.io STAC2 Dance Pad,a:b8,b:b9,back:b12,x:b10,y:b11,platform:Linux,
|
||||
030000008f0e00001330000001010000,iCode Retro Adapter,b:b3,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b9,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b1,start:b7,x:b2,y:b0,platform:Linux,
|
||||
050000006964726f69643a636f6e0000,idroidcon 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,
|
||||
03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
|
||||
@@ -1487,6 +1490,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
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,
|
||||
060000005e040000120b000014050000,Microsoft Xbox One,a:b0,b:b1,x:b2,y:b3,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,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,
|
||||
030000005e040000000b000008040000,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,
|
||||
@@ -1504,7 +1508,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
05000000d6200000e589000001000000,Moga 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
|
||||
05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
|
||||
05000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
|
||||
03000000c82d00000960000000000000,8BitDo Pro 3,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b17,paddle2:b16,paddle3:b2,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||
03000000c62400002b89000011010000,MOGA XP5A Plus,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,
|
||||
05000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,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,
|
||||
05000000c62400001a89000000010000,MOGA XP5X Plus,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,
|
||||
@@ -1512,9 +1515,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,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,
|
||||
03000000f70600000100000000010000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Linux,
|
||||
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 GC400ES,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,
|
||||
0300000085320000030c000011010000,Nacon GC100,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||
03000000853200000706000012010000,Nacon GC100,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 GC400ES,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,
|
||||
05000000853200000503000000010000,Nacon MGX 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,
|
||||
@@ -1788,9 +1791,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
06000000f51000000870000003010000,Turtle Beach Recon,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
03000000100800000100000010010000,Twin PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||
03000000c0160000e105000010010000,Ultimate Atari Fight Stick,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,platform:Linux,
|
||||
03000000790000002601000011010000,SNES Controller,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,platform:Linux,
|
||||
03000000151900005678000010010000,Uniplay U6,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||
03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,
|
||||
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,
|
||||
@@ -1800,17 +1804,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
05000000434f4d4d414e440000000000,VX Gaming Command Series,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
0000000058626f782033363020576900,Xbox 360 Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
|
||||
030000005e0400001907000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
|
||||
030000005e0400008e02000000010000,Xbox 360 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,
|
||||
030000005e0400008e02000002010000,Xbox 360 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,
|
||||
030000005e0400008e02000010010000,Xbox 360 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,
|
||||
030000005e0400008e02000014010000,Xbox 360 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,
|
||||
030000005e0400008e02000047010000,Xbox 360 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,
|
||||
030000005e0400008e02000072050000,Xbox 360 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,
|
||||
030000005e0400009102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
|
||||
030000005e040000a102000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
|
||||
030000005e040000a102000007010000,Xbox 360 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,
|
||||
030000005e040000a102000030060000,Xbox 360 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,
|
||||
030000006f0e00001503000000020000,Xbox 360 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,
|
||||
030000005e0400008e02000000010000,Xbox 360 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,
|
||||
030000005e0400008e02000010010000,Xbox 360 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,
|
||||
030000005e0400008e02000002010000,Xbox 360 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,
|
||||
030000005e0400008e02000014010000,Xbox 360 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,
|
||||
030000005e0400008e02000047010000,Xbox 360 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,
|
||||
030000005e0400008e02000072050000,Xbox 360 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,
|
||||
030000005e040000a102000014010000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
|
||||
0000000058626f782047616d65706100,Xbox 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,
|
||||
030000005e0400000202000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||
|
||||
@@ -139,8 +139,12 @@ struct PS_OUTPUT
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if PS_ZCLAMP || PS_ZFLOOR
|
||||
float depth : SV_DepthLessEqual;
|
||||
#if (PS_ZFLOOR || PS_ZCLAMP)
|
||||
#if PS_HAS_CONSERVATIVE_DEPTH
|
||||
float depth : SV_DepthLessEqual;
|
||||
#else
|
||||
float depth : SV_Depth;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -380,14 +384,14 @@ float4x4 sample_4p(uint4 u)
|
||||
return c;
|
||||
}
|
||||
|
||||
int fetch_raw_depth(int2 xy)
|
||||
uint fetch_raw_depth(int2 xy)
|
||||
{
|
||||
#if PS_TEX_IS_FB == 1
|
||||
float4 col = RtTexture.Load(int3(xy, 0));
|
||||
#else
|
||||
float4 col = Texture.Load(int3(xy, 0));
|
||||
#endif
|
||||
return (int)(col.r * exp2(32.0f));
|
||||
return (uint)(col.r * exp2(32.0f));
|
||||
}
|
||||
|
||||
float4 fetch_raw_color(int2 xy)
|
||||
@@ -462,10 +466,10 @@ float4 sample_depth(float2 st, float2 pos)
|
||||
if (PS_TALES_OF_ABYSS_HLE == 1)
|
||||
{
|
||||
// Warning: UV can't be used in channel effect
|
||||
int depth = fetch_raw_depth(pos);
|
||||
uint depth = fetch_raw_depth(pos);
|
||||
|
||||
// Convert msb based on the palette
|
||||
t = Palette.Load(int3((depth >> 8) & 0xFF, 0, 0)) * 255.0f;
|
||||
t = Palette.Load(int3((depth >> 8u) & 0xFFu, 0, 0)) * 255.0f;
|
||||
}
|
||||
else if (PS_URBAN_CHAOS_HLE == 1)
|
||||
{
|
||||
@@ -476,13 +480,13 @@ float4 sample_depth(float2 st, float2 pos)
|
||||
// To be faster both steps (msb&lsb) are done in a single pass.
|
||||
|
||||
// Warning: UV can't be used in channel effect
|
||||
int depth = fetch_raw_depth(pos);
|
||||
uint depth = fetch_raw_depth(pos);
|
||||
|
||||
// Convert lsb based on the palette
|
||||
t = Palette.Load(int3(depth & 0xFF, 0, 0)) * 255.0f;
|
||||
t = Palette.Load(int3(depth & 0xFFu, 0, 0)) * 255.0f;
|
||||
|
||||
// Msb is easier
|
||||
float green = (float)((depth >> 8) & 0xFF) * 36.0f;
|
||||
float green = (float)((depth >> 8u) & 0xFFu) * 36.0f;
|
||||
green = min(green, 255.0f);
|
||||
t.g += green;
|
||||
}
|
||||
@@ -534,7 +538,7 @@ float4 fetch_red(int2 xy)
|
||||
|
||||
if ((PS_DEPTH_FMT == 1) || (PS_DEPTH_FMT == 2))
|
||||
{
|
||||
int depth = (fetch_raw_depth(xy)) & 0xFF;
|
||||
uint depth = (fetch_raw_depth(xy)) & 0xFFu;
|
||||
rt = (float4)(depth) / 255.0f;
|
||||
}
|
||||
else
|
||||
@@ -551,7 +555,7 @@ float4 fetch_green(int2 xy)
|
||||
|
||||
if ((PS_DEPTH_FMT == 1) || (PS_DEPTH_FMT == 2))
|
||||
{
|
||||
int depth = (fetch_raw_depth(xy) >> 8) & 0xFF;
|
||||
uint depth = (fetch_raw_depth(xy) >> 8u) & 0xFFu;
|
||||
rt = (float4)(depth) / 255.0f;
|
||||
}
|
||||
else
|
||||
@@ -568,7 +572,7 @@ float4 fetch_blue(int2 xy)
|
||||
|
||||
if ((PS_DEPTH_FMT == 1) || (PS_DEPTH_FMT == 2))
|
||||
{
|
||||
int depth = (fetch_raw_depth(xy) >> 16) & 0xFF;
|
||||
uint depth = (fetch_raw_depth(xy) >> 16u) & 0xFFu;
|
||||
rt = (float4)(depth) / 255.0f;
|
||||
}
|
||||
else
|
||||
@@ -596,8 +600,8 @@ float4 fetch_gXbY(int2 xy)
|
||||
{
|
||||
if ((PS_DEPTH_FMT == 1) || (PS_DEPTH_FMT == 2))
|
||||
{
|
||||
int depth = fetch_raw_depth(xy);
|
||||
int bg = (depth >> (8 + ChannelShuffle.w)) & 0xFF;
|
||||
uint depth = fetch_raw_depth(xy);
|
||||
uint bg = (depth >> (8u + uint(ChannelShuffle.w))) & 0xFFu;
|
||||
return (float4)(bg);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -113,7 +113,7 @@ layout(binding = 3) uniform sampler2D img_prim_min;
|
||||
//layout(pixel_center_integer) in vec4 gl_FragCoord;
|
||||
#endif
|
||||
|
||||
#if (PS_ZFLOOR || PS_ZCLAMP) && HAS_CONSERVATIVE_DEPTH
|
||||
#if (PS_ZFLOOR || PS_ZCLAMP) && PS_HAS_CONSERVATIVE_DEPTH
|
||||
layout(depth_less) out float gl_FragDepth;
|
||||
#endif
|
||||
|
||||
@@ -313,14 +313,14 @@ mat4 sample_4p(uvec4 u)
|
||||
return c;
|
||||
}
|
||||
|
||||
int fetch_raw_depth()
|
||||
uint fetch_raw_depth()
|
||||
{
|
||||
float multiplier = exp2(32.0f);
|
||||
|
||||
#if PS_TEX_IS_FB == 1
|
||||
return int(sample_from_rt().r * multiplier);
|
||||
return uint(sample_from_rt().r * multiplier);
|
||||
#else
|
||||
return int(texelFetch(TextureSampler, ivec2(gl_FragCoord.xy + ChannelShuffleOffset), 0).r * multiplier);
|
||||
return uint(texelFetch(TextureSampler, ivec2(gl_FragCoord.xy + ChannelShuffleOffset), 0).r * multiplier);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -393,10 +393,10 @@ vec4 sample_depth(vec2 st)
|
||||
|
||||
#if PS_TALES_OF_ABYSS_HLE == 1
|
||||
// Warning: UV can't be used in channel effect
|
||||
int depth = fetch_raw_depth();
|
||||
uint depth = fetch_raw_depth();
|
||||
|
||||
// Convert msb based on the palette
|
||||
t = texelFetch(PaletteSampler, ivec2((depth >> 8) & 0xFF, 0), 0) * 255.0f;
|
||||
t = texelFetch(PaletteSampler, ivec2((depth >> 8u) & 0xFFu, 0), 0) * 255.0f;
|
||||
|
||||
#elif PS_URBAN_CHAOS_HLE == 1
|
||||
// Depth buffer is read as a RGB5A1 texture. The game try to extract the green channel.
|
||||
@@ -406,13 +406,13 @@ vec4 sample_depth(vec2 st)
|
||||
// To be faster both steps (msb&lsb) are done in a single pass.
|
||||
|
||||
// Warning: UV can't be used in channel effect
|
||||
int depth = fetch_raw_depth();
|
||||
uint depth = fetch_raw_depth();
|
||||
|
||||
// Convert lsb based on the palette
|
||||
t = texelFetch(PaletteSampler, ivec2((depth & 0xFF), 0), 0) * 255.0f;
|
||||
t = texelFetch(PaletteSampler, ivec2((depth & 0xFFu), 0), 0) * 255.0f;
|
||||
|
||||
// Msb is easier
|
||||
float green = float((depth >> 8) & 0xFF) * 36.0f;
|
||||
float green = float((depth >> 8u) & 0xFFu) * 36.0f;
|
||||
green = min(green, 255.0f);
|
||||
|
||||
t.g += green;
|
||||
@@ -454,7 +454,7 @@ vec4 sample_depth(vec2 st)
|
||||
vec4 fetch_red()
|
||||
{
|
||||
#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2
|
||||
int depth = (fetch_raw_depth()) & 0xFF;
|
||||
uint depth = (fetch_raw_depth()) & 0xFFu;
|
||||
vec4 rt = vec4(depth) / 255.0f;
|
||||
#else
|
||||
vec4 rt = fetch_raw_color();
|
||||
@@ -465,7 +465,7 @@ vec4 fetch_red()
|
||||
vec4 fetch_green()
|
||||
{
|
||||
#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2
|
||||
int depth = (fetch_raw_depth() >> 8) & 0xFF;
|
||||
uint depth = (fetch_raw_depth() >> 8u) & 0xFFu;
|
||||
vec4 rt = vec4(depth) / 255.0f;
|
||||
#else
|
||||
vec4 rt = fetch_raw_color();
|
||||
@@ -476,7 +476,7 @@ vec4 fetch_green()
|
||||
vec4 fetch_blue()
|
||||
{
|
||||
#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2
|
||||
int depth = (fetch_raw_depth() >> 16) & 0xFF;
|
||||
uint depth = (fetch_raw_depth() >> 16u) & 0xFFu;
|
||||
vec4 rt = vec4(depth) / 255.0f;
|
||||
#else
|
||||
vec4 rt = fetch_raw_color();
|
||||
@@ -500,8 +500,8 @@ vec4 fetch_rgb()
|
||||
vec4 fetch_gXbY()
|
||||
{
|
||||
#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2
|
||||
int depth = fetch_raw_depth();
|
||||
int bg = (depth >> (8 + ChannelShuffle.w)) & 0xFF;
|
||||
uint depth = fetch_raw_depth();
|
||||
uint bg = (depth >> (8u + uint(ChannelShuffle.w))) & 0xFFu;
|
||||
return vec4(bg);
|
||||
#else
|
||||
ivec4 rt = ivec4(fetch_raw_color() * 255.0f);
|
||||
|
||||
@@ -556,14 +556,14 @@ mat4 sample_4p(uvec4 u)
|
||||
return c;
|
||||
}
|
||||
|
||||
int fetch_raw_depth(ivec2 xy)
|
||||
uint fetch_raw_depth(ivec2 xy)
|
||||
{
|
||||
#if PS_TEX_IS_FB
|
||||
vec4 col = sample_from_rt();
|
||||
#else
|
||||
vec4 col = texelFetch(Texture, xy, 0);
|
||||
#endif
|
||||
return int(col.r * exp2(32.0f));
|
||||
return uint(col.r * exp2(32.0f));
|
||||
}
|
||||
|
||||
vec4 fetch_raw_color(ivec2 xy)
|
||||
@@ -642,10 +642,10 @@ vec4 sample_depth(vec2 st, ivec2 pos)
|
||||
#if (PS_TALES_OF_ABYSS_HLE == 1)
|
||||
{
|
||||
// Warning: UV can't be used in channel effect
|
||||
int depth = fetch_raw_depth(pos);
|
||||
uint depth = fetch_raw_depth(pos);
|
||||
|
||||
// Convert msb based on the palette
|
||||
t = texelFetch(Palette, ivec2((depth >> 8) & 0xFF, 0), 0) * 255.0f;
|
||||
t = texelFetch(Palette, ivec2((depth >> 8u) & 0xFFu, 0), 0) * 255.0f;
|
||||
}
|
||||
#elif (PS_URBAN_CHAOS_HLE == 1)
|
||||
{
|
||||
@@ -656,13 +656,13 @@ vec4 sample_depth(vec2 st, ivec2 pos)
|
||||
// To be faster both steps (msb&lsb) are done in a single pass.
|
||||
|
||||
// Warning: UV can't be used in channel effect
|
||||
int depth = fetch_raw_depth(pos);
|
||||
uint depth = fetch_raw_depth(pos);
|
||||
|
||||
// Convert lsb based on the palette
|
||||
t = texelFetch(Palette, ivec2(depth & 0xFF, 0), 0) * 255.0f;
|
||||
t = texelFetch(Palette, ivec2(depth & 0xFFu, 0), 0) * 255.0f;
|
||||
|
||||
// Msb is easier
|
||||
float green = float(((depth >> 8) & 0xFF) * 36.0f);
|
||||
float green = float(((depth >> 8u) & 0xFFu) * 36.0f);
|
||||
green = min(green, 255.0f);
|
||||
t.g += green;
|
||||
}
|
||||
@@ -715,7 +715,7 @@ vec4 fetch_red(ivec2 xy)
|
||||
vec4 rt;
|
||||
|
||||
#if (PS_DEPTH_FMT == 1) || (PS_DEPTH_FMT == 2)
|
||||
int depth = (fetch_raw_depth(xy)) & 0xFF;
|
||||
uint depth = (fetch_raw_depth(xy)) & 0xFFu;
|
||||
rt = vec4(float(depth) / 255.0f);
|
||||
#else
|
||||
rt = fetch_raw_color(xy);
|
||||
@@ -729,7 +729,7 @@ vec4 fetch_green(ivec2 xy)
|
||||
vec4 rt;
|
||||
|
||||
#if (PS_DEPTH_FMT == 1) || (PS_DEPTH_FMT == 2)
|
||||
int depth = (fetch_raw_depth(xy) >> 8) & 0xFF;
|
||||
uint depth = (fetch_raw_depth(xy) >> 8u) & 0xFFu;
|
||||
rt = vec4(float(depth) / 255.0f);
|
||||
#else
|
||||
rt = fetch_raw_color(xy);
|
||||
@@ -743,7 +743,7 @@ vec4 fetch_blue(ivec2 xy)
|
||||
vec4 rt;
|
||||
|
||||
#if (PS_DEPTH_FMT == 1) || (PS_DEPTH_FMT == 2)
|
||||
int depth = (fetch_raw_depth(xy) >> 16) & 0xFF;
|
||||
uint depth = (fetch_raw_depth(xy) >> 16u) & 0xFFu;
|
||||
rt = vec4(float(depth) / 255.0f);
|
||||
#else
|
||||
rt = fetch_raw_color(xy);
|
||||
@@ -768,8 +768,8 @@ vec4 fetch_rgb(ivec2 xy)
|
||||
vec4 fetch_gXbY(ivec2 xy)
|
||||
{
|
||||
#if (PS_DEPTH_FMT == 1) || (PS_DEPTH_FMT == 2)
|
||||
int depth = fetch_raw_depth(xy);
|
||||
int bg = (depth >> (8 + ChannelShuffle.w)) & 0xFF;
|
||||
uint depth = fetch_raw_depth(xy);
|
||||
uint bg = (depth >> (8u + uint(ChannelShuffle.w))) & 0xFFu;
|
||||
return vec4(bg);
|
||||
#else
|
||||
ivec4 rt = ivec4(fetch_raw_color(xy) * 255.0);
|
||||
|
||||
@@ -108,7 +108,7 @@ disable_compiler_warnings_for_target(speex)
|
||||
|
||||
# Find the Qt components that we need.
|
||||
if(ENABLE_QT_UI)
|
||||
find_package(Qt6 6.10.0 COMPONENTS CoreTools Core GuiTools Gui WidgetsTools Widgets LinguistTools REQUIRED)
|
||||
find_package(Qt6 6.10.1 COMPONENTS CoreTools Core GuiTools Gui WidgetsTools Widgets LinguistTools REQUIRED)
|
||||
|
||||
if(NOT WIN32 AND NOT APPLE)
|
||||
if (Qt6_VERSION VERSION_GREATER_EQUAL 6.10.0)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "common/Threading.h"
|
||||
#include "common/WindowInfo.h"
|
||||
#include "common/HostSys.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
@@ -19,12 +20,15 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <thread>
|
||||
#include <time.h>
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/mach_port.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach/mach_vm.h>
|
||||
#include <mach/message.h>
|
||||
#include <mach/task.h>
|
||||
#include <mach/thread_state.h>
|
||||
#include <mach/vm_map.h>
|
||||
#include <mutex>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
@@ -294,7 +298,7 @@ static CPUInfo CalcCPUInfo()
|
||||
std::vector<DarwinMisc::CPUClass> classes = DarwinMisc::GetCPUClasses();
|
||||
out.num_clusters = static_cast<u32>(classes.size());
|
||||
out.num_big_cores = classes.empty() ? 0 : classes[0].num_physical;
|
||||
out.num_threads = classes.empty() ? 0 : classes[0].num_logical;
|
||||
out.num_threads = classes.empty() ? 0 : classes[0].num_logical;
|
||||
out.num_small_cores = 0;
|
||||
for (std::size_t i = 1; i < classes.size(); i++)
|
||||
{
|
||||
@@ -568,15 +572,206 @@ void HostSys::EndCodeWrite()
|
||||
|
||||
#endif // _M_ARM64
|
||||
|
||||
#define USE_MACH_EXCEPTION_PORTS
|
||||
|
||||
namespace PageFaultHandler
|
||||
{
|
||||
#ifdef USE_MACH_EXCEPTION_PORTS
|
||||
static void SignalHandler(mach_port_t port);
|
||||
#else
|
||||
static void SignalHandler(int sig, siginfo_t* info, void* ctx);
|
||||
#endif
|
||||
|
||||
static std::recursive_mutex s_exception_handler_mutex;
|
||||
static bool s_in_exception_handler = false;
|
||||
static bool s_installed = false;
|
||||
} // namespace PageFaultHandler
|
||||
|
||||
#ifdef USE_MACH_EXCEPTION_PORTS
|
||||
|
||||
#if defined(_M_X86)
|
||||
#define THREAD_STATE64_COUNT x86_THREAD_STATE64_COUNT
|
||||
#define THREAD_STATE64 x86_THREAD_STATE64
|
||||
#define thread_state64_t x86_thread_state64_t
|
||||
#elif defined(_M_ARM64)
|
||||
#define THREAD_STATE64_COUNT ARM_THREAD_STATE64_COUNT
|
||||
#define THREAD_STATE64 ARM_THREAD_STATE64
|
||||
#define thread_state64_t arm_thread_state64_t
|
||||
#else
|
||||
#error Unknown Darwin Platform
|
||||
#endif
|
||||
|
||||
void PageFaultHandler::SignalHandler(mach_port_t port)
|
||||
{
|
||||
Threading::SetNameOfCurrentThread("Mach Exception Thread");
|
||||
|
||||
#pragma pack(4)
|
||||
struct
|
||||
{
|
||||
mach_msg_header_t Head;
|
||||
NDR_record_t NDR;
|
||||
exception_type_t exception;
|
||||
mach_msg_type_number_t codeCnt;
|
||||
int64_t code[2];
|
||||
int flavor;
|
||||
mach_msg_type_number_t old_stateCnt;
|
||||
natural_t old_state[THREAD_STATE64_COUNT];
|
||||
mach_msg_trailer_t trailer;
|
||||
} msg_in;
|
||||
|
||||
struct
|
||||
{
|
||||
mach_msg_header_t Head;
|
||||
NDR_record_t NDR;
|
||||
kern_return_t RetCode;
|
||||
int flavor;
|
||||
mach_msg_type_number_t new_stateCnt;
|
||||
natural_t new_state[THREAD_STATE64_COUNT];
|
||||
} msg_out;
|
||||
#pragma pack()
|
||||
memset(&msg_in, 0xee, sizeof(msg_in));
|
||||
memset(&msg_out, 0xee, sizeof(msg_out));
|
||||
mach_msg_size_t send_size = 0;
|
||||
mach_msg_option_t option = MACH_RCV_MSG;
|
||||
while (true)
|
||||
{
|
||||
kern_return_t r;
|
||||
if ((r = mach_msg_overwrite(&msg_out.Head, option, send_size, sizeof(msg_in), port,
|
||||
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL, &msg_in.Head, 0)))
|
||||
{
|
||||
pxFail(fmt::format("CRITICAL: mach_msg_overwrite: {:x}", r).c_str());
|
||||
}
|
||||
|
||||
if (msg_in.Head.msgh_id == MACH_NOTIFY_NO_SENDERS)
|
||||
{
|
||||
// the other thread exited
|
||||
mach_port_deallocate(mach_task_self(), port);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg_in.Head.msgh_id != 2406)
|
||||
{
|
||||
pxFailRel("unknown message received");
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg_in.flavor != THREAD_STATE64)
|
||||
{
|
||||
pxFailRel(fmt::format("unknown flavour {}, expected {}", msg_in.flavor, THREAD_STATE64).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
s_exception_handler_mutex.lock();
|
||||
thread_state64_t* state = (thread_state64_t*)msg_in.old_state;
|
||||
|
||||
HandlerResult result = HandlerResult::ExecuteNextHandler;
|
||||
if (!s_in_exception_handler)
|
||||
{
|
||||
s_in_exception_handler = true;
|
||||
|
||||
#ifdef _M_ARM64
|
||||
result = HandlePageFault(reinterpret_cast<void*>(state->__pc), reinterpret_cast<void*>(msg_in.code[1]), (msg_in.code[0] & 2) != 0);
|
||||
#else
|
||||
result = HandlePageFault(reinterpret_cast<void*>(state->__rip), reinterpret_cast<void*>(msg_in.code[1]), (msg_in.code[0] & 2) != 0);
|
||||
#endif
|
||||
s_in_exception_handler = false;
|
||||
}
|
||||
|
||||
// Set up the reply.
|
||||
msg_out.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(msg_in.Head.msgh_bits), 0);
|
||||
msg_out.Head.msgh_remote_port = msg_in.Head.msgh_remote_port;
|
||||
msg_out.Head.msgh_local_port = MACH_PORT_NULL;
|
||||
msg_out.Head.msgh_id = msg_in.Head.msgh_id + 100;
|
||||
msg_out.NDR = msg_in.NDR;
|
||||
|
||||
if (result != HandlerResult::ContinueExecution) // cooked
|
||||
{
|
||||
msg_out.RetCode = KERN_FAILURE;
|
||||
msg_out.flavor = 0;
|
||||
msg_out.new_stateCnt = 0;
|
||||
|
||||
// The crash handler on macOS or Linux doesn't use context passed to it
|
||||
// Stubbing it here is fine
|
||||
CrashHandler::CrashSignalHandler(-1, nullptr, nullptr);
|
||||
|
||||
pxFailRel("CrashSignalHandler returned when it should have terminated us!");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Resumes execution right where we left off (re-executes instruction that caused the SIGSEGV)
|
||||
msg_out.RetCode = KERN_SUCCESS;
|
||||
msg_out.flavor = THREAD_STATE64;
|
||||
msg_out.new_stateCnt = THREAD_STATE64_COUNT;
|
||||
memcpy(msg_out.new_state, msg_in.old_state, THREAD_STATE64_COUNT * sizeof(natural_t));
|
||||
}
|
||||
|
||||
msg_out.Head.msgh_size =
|
||||
offsetof(__typeof__(msg_out), new_state) + msg_out.new_stateCnt * sizeof(natural_t);
|
||||
send_size = msg_out.Head.msgh_size;
|
||||
option |= MACH_SEND_MSG;
|
||||
|
||||
s_exception_handler_mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool PageFaultHandler::Install(Error* error)
|
||||
{
|
||||
exception_mask_t masks[EXC_TYPES_COUNT];
|
||||
mach_port_t ports[EXC_TYPES_COUNT];
|
||||
exception_behavior_t behaviors[EXC_TYPES_COUNT];
|
||||
thread_state_flavor_t flavors[EXC_TYPES_COUNT];
|
||||
mach_msg_type_number_t count = EXC_TYPES_COUNT;
|
||||
|
||||
kern_return_t r = task_get_exception_ports(mach_task_self(), EXC_MASK_ALL,
|
||||
masks, &count, ports, behaviors, flavors);
|
||||
|
||||
mach_port_t port;
|
||||
if ((r = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port)))
|
||||
{
|
||||
pxFailRel(fmt::format("mach_port_allocate: {:x}", r).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::thread sig_thread(PageFaultHandler::SignalHandler, port);
|
||||
sig_thread.detach();
|
||||
|
||||
if ((r = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
|
||||
{
|
||||
mach_port_deallocate(mach_task_self(), port);
|
||||
pxFailRel(fmt::format("mach_port_insert_right: {:x}", r).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, MACH_PORT_NULL, EXCEPTION_DEFAULT, THREAD_STATE_NONE);
|
||||
|
||||
if ((r = thread_set_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS, port, EXCEPTION_STATE | MACH_EXCEPTION_CODES, THREAD_STATE64)))
|
||||
{
|
||||
mach_port_deallocate(mach_task_self(), port);
|
||||
pxFailRel(fmt::format("thread_set_exception_ports: {:x}", r).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((r = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, -1)))
|
||||
{
|
||||
mach_port_deallocate(mach_task_self(), port);
|
||||
pxFailRel(fmt::format("mach_port_mod_refs: {:x}", r).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
mach_port_t previous;
|
||||
if ((r = mach_port_request_notification(mach_task_self(), port, MACH_NOTIFY_NO_SENDERS, 0, port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous)))
|
||||
{
|
||||
mach_port_deallocate(mach_task_self(), port);
|
||||
pxFailRel(fmt::format("mach_port_mod_refs: {:x}", r).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
s_installed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void PageFaultHandler::SignalHandler(int sig, siginfo_t* info, void* ctx)
|
||||
{
|
||||
#if defined(_M_X86)
|
||||
@@ -644,3 +839,4 @@ bool PageFaultHandler::Install(Error* error)
|
||||
s_installed = true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
+5
-7
@@ -3,6 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "HeterogeneousContainers.h"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
|
||||
@@ -75,12 +76,9 @@ public:
|
||||
{
|
||||
while (!m_items.empty() && count > 0)
|
||||
{
|
||||
typename MapType::iterator lowest = m_items.end();
|
||||
for (auto iter = m_items.begin(); iter != m_items.end(); ++iter)
|
||||
{
|
||||
if (lowest == m_items.end() || iter->second.last_access < lowest->second.last_access)
|
||||
lowest = iter;
|
||||
}
|
||||
auto lowest = std::min_element(m_items.begin(), m_items.end(), [](const auto& a, const auto& b) {
|
||||
return a.second.last_access < b.second.last_access;
|
||||
});
|
||||
m_items.erase(lowest);
|
||||
count--;
|
||||
}
|
||||
@@ -121,4 +119,4 @@ private:
|
||||
CounterType m_last_counter = 0;
|
||||
std::size_t m_max_capacity = 0;
|
||||
bool m_manual_evict = false;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -436,8 +436,8 @@ static void PrintCommandLineHelp(const char* progname)
|
||||
std::fprintf(stderr, " -help: Displays this information and exits.\n");
|
||||
std::fprintf(stderr, " -version: Displays version information and exits.\n");
|
||||
std::fprintf(stderr, " -dumpdir <dir>: Frame dump directory (will be dumped as filename_frameN.png).\n");
|
||||
std::fprintf(stderr, " -dump [rt|tex|z|f|a|i|tr|ds|fs]: Enabling dumping of render target, texture, z buffer, frame, "
|
||||
"alphas, and info (context, vertices, list of transfers), transfers images, draw stats, frame stats, respectively, per draw. Generates lots of data.\n");
|
||||
std::fprintf(stderr, " -dump [rt|tex|z|f|a|i|tr|ds|fs|hw]: Enabling dumping of render target, texture, z buffer, frame, "
|
||||
"alphas, and info (context, vertices, list of transfers), transfers images, draw stats, frame stats, HW config, respectively, per draw. Generates lots of data.\n");
|
||||
std::fprintf(stderr, " -dumprange N[,L,B]: Start dumping from draw N (base 0), stops after L draws, and only "
|
||||
"those draws that are multiples of B (intersection of -dumprange and -dumprangef used)."
|
||||
"Defaults to 0,-1,1 (all draws). Only used if -dump used.\n");
|
||||
@@ -527,6 +527,8 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveDrawStats", true);
|
||||
if (str.find("fs") != std::string::npos)
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveFrameStats", true);
|
||||
if (str.find("hw") != std::string::npos)
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveHWConfig", true);
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-dumprange"))
|
||||
|
||||
@@ -144,7 +144,7 @@ void AboutDialog::showHTMLDialog(QWidget* parent, const QString& title, const QS
|
||||
{
|
||||
tb->setSource(QUrl::fromLocalFile(path));
|
||||
}
|
||||
|
||||
|
||||
layout->addWidget(tb, 1);
|
||||
|
||||
QDialogButtonBox* bb = new QDialogButtonBox(QDialogButtonBox::Close, &dialog);
|
||||
|
||||
@@ -0,0 +1,356 @@
|
||||
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
|
||||
#include <QtWidgets/QPushButton>
|
||||
|
||||
template <typename Value>
|
||||
static std::function<void(std::optional<Value>)> wrapValueCallback(std::function<void(Value)> callback)
|
||||
{
|
||||
return [callback = std::move(callback)](std::optional<Value> input) {
|
||||
if (input.has_value())
|
||||
callback(std::move(*input));
|
||||
};
|
||||
}
|
||||
|
||||
void AsyncDialogs::getText(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
const QString& text,
|
||||
std::function<void(QString)> value_callback)
|
||||
{
|
||||
getText(parent, title, label, QLineEdit::Normal, text, {}, Qt::ImhNone, wrapValueCallback(std::move(value_callback)));
|
||||
}
|
||||
|
||||
void AsyncDialogs::getText(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
QLineEdit::EchoMode echo,
|
||||
const QString& text,
|
||||
Qt::WindowFlags flags,
|
||||
Qt::InputMethodHints input_method_hints,
|
||||
std::function<void(std::optional<QString>)> callback)
|
||||
{
|
||||
QInputDialog* dialog = new QInputDialog(parent, flags);
|
||||
dialog->setWindowTitle(title);
|
||||
dialog->setLabelText(label);
|
||||
dialog->setTextValue(text);
|
||||
dialog->setTextEchoMode(echo);
|
||||
dialog->setInputMethodHints(input_method_hints);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
if (callback)
|
||||
{
|
||||
QObject::connect(dialog, &QDialog::finished, [dialog, callback = std::move(callback)](int result) {
|
||||
callback(result ? std::make_optional<QString>(dialog->textValue()) : std::nullopt);
|
||||
});
|
||||
}
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
void AsyncDialogs::getMultiLineText(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
const QString& text,
|
||||
std::function<void(QString)> value_callback)
|
||||
{
|
||||
getMultiLineText(parent, title, label, text, {}, Qt::ImhNone, wrapValueCallback(std::move(value_callback)));
|
||||
}
|
||||
|
||||
void AsyncDialogs::getMultiLineText(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
const QString& text,
|
||||
Qt::WindowFlags flags,
|
||||
Qt::InputMethodHints input_method_hints,
|
||||
std::function<void(std::optional<QString>)> callback)
|
||||
{
|
||||
QInputDialog* dialog = new QInputDialog(parent, flags);
|
||||
dialog->setOptions(QInputDialog::UsePlainTextEditForTextInput);
|
||||
dialog->setWindowTitle(title);
|
||||
dialog->setLabelText(label);
|
||||
dialog->setTextValue(text);
|
||||
dialog->setInputMethodHints(input_method_hints);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
if (callback)
|
||||
{
|
||||
QObject::connect(dialog, &QDialog::finished, [dialog, callback = std::move(callback)](int result) {
|
||||
callback(result ? std::make_optional<QString>(dialog->textValue()) : std::nullopt);
|
||||
});
|
||||
}
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
void AsyncDialogs::getItem(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
const QStringList& items,
|
||||
int current,
|
||||
std::function<void(QString)> value_callback)
|
||||
{
|
||||
getItem(parent, title, label, items, current, true, {}, Qt::ImhNone, wrapValueCallback(std::move(value_callback)));
|
||||
}
|
||||
|
||||
void AsyncDialogs::getItem(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
const QStringList& items,
|
||||
int current,
|
||||
bool editable,
|
||||
Qt::WindowFlags flags,
|
||||
Qt::InputMethodHints input_method_hints,
|
||||
std::function<void(std::optional<QString>)> callback)
|
||||
{
|
||||
const QString text(items.value(current));
|
||||
|
||||
QInputDialog* dialog = new QInputDialog(parent, flags);
|
||||
dialog->setWindowTitle(title);
|
||||
dialog->setLabelText(label);
|
||||
dialog->setComboBoxItems(items);
|
||||
dialog->setTextValue(text);
|
||||
dialog->setComboBoxEditable(editable);
|
||||
dialog->setInputMethodHints(input_method_hints);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
if (callback)
|
||||
{
|
||||
QObject::connect(dialog, &QDialog::finished, [dialog, callback = std::move(callback)](int result) {
|
||||
callback(result ? std::make_optional<QString>(dialog->textValue()) : std::nullopt);
|
||||
});
|
||||
}
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
void AsyncDialogs::getInt(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
int value,
|
||||
std::function<void(int)> value_callback)
|
||||
{
|
||||
getInt(parent, title, label, value, -2147483647, 2147483647, 1, {}, wrapValueCallback(std::move(value_callback)));
|
||||
}
|
||||
|
||||
void AsyncDialogs::getInt(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
int value,
|
||||
int min_value,
|
||||
int max_value,
|
||||
int step,
|
||||
Qt::WindowFlags flags,
|
||||
std::function<void(std::optional<int>)> callback)
|
||||
{
|
||||
QInputDialog* dialog = new QInputDialog(parent, flags);
|
||||
dialog->setWindowTitle(title);
|
||||
dialog->setLabelText(label);
|
||||
dialog->setIntRange(min_value, max_value);
|
||||
dialog->setIntValue(value);
|
||||
dialog->setIntStep(step);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
if (callback)
|
||||
{
|
||||
QObject::connect(dialog, &QDialog::finished, [dialog, callback = std::move(callback)](int result) {
|
||||
callback(result ? std::make_optional<int>(dialog->intValue()) : std::nullopt);
|
||||
});
|
||||
}
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
void AsyncDialogs::getDouble(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
double value,
|
||||
std::function<void(double)> callback)
|
||||
{
|
||||
getDouble(parent, title, label, value, -2147483647, 2147483647, 1, {}, 1, wrapValueCallback(std::move(callback)));
|
||||
}
|
||||
|
||||
void AsyncDialogs::getDouble(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
double value,
|
||||
double min_value,
|
||||
double max_value,
|
||||
int decimals,
|
||||
Qt::WindowFlags flags,
|
||||
double step,
|
||||
std::function<void(std::optional<double>)> callback)
|
||||
{
|
||||
QInputDialog* dialog = new QInputDialog(parent, flags);
|
||||
dialog->setWindowTitle(title);
|
||||
dialog->setLabelText(label);
|
||||
dialog->setDoubleDecimals(decimals);
|
||||
dialog->setDoubleRange(min_value, max_value);
|
||||
dialog->setDoubleValue(value);
|
||||
dialog->setDoubleStep(step);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
if (callback)
|
||||
{
|
||||
QObject::connect(dialog, &QDialog::finished, [dialog, callback = std::move(callback)](int result) {
|
||||
callback(result ? std::make_optional<double>(dialog->doubleValue()) : std::nullopt);
|
||||
});
|
||||
}
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
// Based on the QMessageBoxPrivate::showNewMessageBox function from Qt Widgets.
|
||||
static void openAsyncMessageBox(QWidget* parent,
|
||||
QMessageBox::Icon icon,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton default_button,
|
||||
std::function<void(QMessageBox::StandardButton)> callback)
|
||||
{
|
||||
// Don't support the fallback for Qt 4.
|
||||
pxAssert(!(default_button && !(buttons & default_button)));
|
||||
|
||||
QMessageBox* message_box = new QMessageBox(icon, title, text, QMessageBox::NoButton, parent);
|
||||
message_box->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
const QDialogButtonBox* button_box = message_box->findChild<QDialogButtonBox*>();
|
||||
pxAssert(button_box);
|
||||
|
||||
u32 mask = QMessageBox::FirstButton;
|
||||
while (mask <= QMessageBox::LastButton)
|
||||
{
|
||||
QMessageBox::StandardButton standard_button =
|
||||
static_cast<QMessageBox::StandardButton>(static_cast<u32>(buttons) & mask);
|
||||
|
||||
mask <<= 1;
|
||||
|
||||
if (standard_button == QMessageBox::NoButton)
|
||||
continue;
|
||||
|
||||
QPushButton* button = message_box->addButton(standard_button);
|
||||
|
||||
if (message_box->defaultButton())
|
||||
continue;
|
||||
|
||||
if ((default_button == QMessageBox::NoButton &&
|
||||
button_box->buttonRole(button) == QDialogButtonBox::AcceptRole) ||
|
||||
(default_button != QMessageBox::NoButton &&
|
||||
standard_button == default_button))
|
||||
message_box->setDefaultButton(button);
|
||||
}
|
||||
|
||||
if (callback)
|
||||
{
|
||||
QObject::connect(message_box, &QMessageBox::finished, [message_box, callback = std::move(callback)](int result) {
|
||||
callback(message_box->standardButton(message_box->clickedButton()));
|
||||
});
|
||||
}
|
||||
|
||||
message_box->open();
|
||||
}
|
||||
|
||||
void AsyncDialogs::information(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
std::function<void(QMessageBox::StandardButton)> callback)
|
||||
{
|
||||
information(parent, title, text, QMessageBox::Ok, QMessageBox::NoButton, std::move(callback));
|
||||
}
|
||||
|
||||
void AsyncDialogs::information(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton default_button,
|
||||
std::function<void(QMessageBox::StandardButton)> callback)
|
||||
{
|
||||
openAsyncMessageBox(parent, QMessageBox::Information, title, text, buttons, default_button, std::move(callback));
|
||||
}
|
||||
|
||||
void AsyncDialogs::question(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
std::function<void()> yes_callback)
|
||||
{
|
||||
std::function<void(QMessageBox::StandardButton)> callback;
|
||||
if (yes_callback)
|
||||
{
|
||||
callback = [yes_callback = std::move(yes_callback)](QMessageBox::StandardButton result) {
|
||||
if (result == QMessageBox::Yes)
|
||||
yes_callback();
|
||||
};
|
||||
}
|
||||
|
||||
const QMessageBox::StandardButtons buttons(QMessageBox::Yes | QMessageBox::No);
|
||||
question(parent, title, text, buttons, QMessageBox::NoButton, std::move(callback));
|
||||
}
|
||||
|
||||
void AsyncDialogs::question(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton default_button,
|
||||
std::function<void(QMessageBox::StandardButton)> callback)
|
||||
{
|
||||
openAsyncMessageBox(parent, QMessageBox::Question, title, text, buttons, default_button, std::move(callback));
|
||||
}
|
||||
|
||||
void AsyncDialogs::warning(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
std::function<void(QMessageBox::StandardButton)> callback)
|
||||
{
|
||||
warning(parent, title, text, QMessageBox::Ok, QMessageBox::NoButton, std::move(callback));
|
||||
}
|
||||
|
||||
void AsyncDialogs::warning(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton default_button,
|
||||
std::function<void(QMessageBox::StandardButton)> callback)
|
||||
{
|
||||
openAsyncMessageBox(parent, QMessageBox::Warning, title, text, buttons, default_button, std::move(callback));
|
||||
}
|
||||
|
||||
void AsyncDialogs::critical(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
std::function<void(QMessageBox::StandardButton)> callback)
|
||||
{
|
||||
critical(parent, title, text, QMessageBox::Ok, QMessageBox::NoButton, std::move(callback));
|
||||
}
|
||||
|
||||
void AsyncDialogs::critical(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton default_button,
|
||||
std::function<void(QMessageBox::StandardButton)> callback)
|
||||
{
|
||||
openAsyncMessageBox(parent, QMessageBox::Critical, title, text, buttons, default_button, std::move(callback));
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#include <functional>
|
||||
|
||||
/// A collection of helper functions for opening asynchronous dialog boxes.
|
||||
/// These should be used in place of Qt's built-in blocking functions as those
|
||||
/// are prone to crashing if the parent is destroyed while the dialog is open.
|
||||
namespace AsyncDialogs
|
||||
{
|
||||
/// Replacement for QInputDialog::getText.
|
||||
void getText(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
const QString& text,
|
||||
std::function<void(QString)> value_callback);
|
||||
|
||||
/// Replacement for QInputDialog::getText.
|
||||
void getText(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
QLineEdit::EchoMode echo,
|
||||
const QString& text,
|
||||
Qt::WindowFlags flags,
|
||||
Qt::InputMethodHints input_method_hints,
|
||||
std::function<void(std::optional<QString>)> callback);
|
||||
|
||||
/// Replacement for QInputDialog::getMultiLineText.
|
||||
void getMultiLineText(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
const QString& text,
|
||||
std::function<void(QString)> value_callback);
|
||||
|
||||
/// Replacement for QInputDialog::getMultiLineText.
|
||||
void getMultiLineText(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
const QString& text,
|
||||
Qt::WindowFlags flags,
|
||||
Qt::InputMethodHints input_method_hints,
|
||||
std::function<void(std::optional<QString>)> callback);
|
||||
|
||||
/// Replacement for QInputDialog::getItem.
|
||||
void getItem(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
const QStringList& items,
|
||||
int current,
|
||||
std::function<void(QString)> value_callback);
|
||||
|
||||
/// Replacement for QInputDialog::getItem.
|
||||
void getItem(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
const QStringList& items,
|
||||
int current,
|
||||
bool editable,
|
||||
Qt::WindowFlags flags,
|
||||
Qt::InputMethodHints input_method_hints,
|
||||
std::function<void(std::optional<QString>)> callback);
|
||||
|
||||
/// Replacement for QInputDialog::getInt.
|
||||
void getInt(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
int value,
|
||||
std::function<void(int)> value_callback);
|
||||
|
||||
/// Replacement for QInputDialog::getInt.
|
||||
void getInt(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
int value,
|
||||
int min_value,
|
||||
int max_value,
|
||||
int step,
|
||||
Qt::WindowFlags flags,
|
||||
std::function<void(std::optional<int>)> callback);
|
||||
|
||||
/// Replacement for QInputDialog::getDouble.
|
||||
void getDouble(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
double value,
|
||||
std::function<void(double)> value_callback);
|
||||
|
||||
/// Replacement for QInputDialog::getDouble.
|
||||
void getDouble(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& label,
|
||||
double value,
|
||||
double min_value,
|
||||
double max_value,
|
||||
int decimals,
|
||||
Qt::WindowFlags flags,
|
||||
double step,
|
||||
std::function<void(std::optional<double>)> callback);
|
||||
|
||||
/// Replacement for QMessageBox::information.
|
||||
void information(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
std::function<void(QMessageBox::StandardButton)> callback = {});
|
||||
|
||||
/// Replacement for QMessageBox::information.
|
||||
void information(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton default_button,
|
||||
std::function<void(QMessageBox::StandardButton)> callback = {});
|
||||
|
||||
/// Replacement for QMessageBox::question.
|
||||
void question(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
std::function<void()> yes_callback);
|
||||
|
||||
/// Replacement for QMessageBox::question.
|
||||
void question(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton default_button,
|
||||
std::function<void(QMessageBox::StandardButton)> callback);
|
||||
|
||||
/// Replacement for QMessageBox::warning.
|
||||
void warning(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
std::function<void(QMessageBox::StandardButton)> callback = {});
|
||||
|
||||
/// Replacement for QMessageBox::warning.
|
||||
void warning(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton default_button,
|
||||
std::function<void(QMessageBox::StandardButton)> callback = {});
|
||||
|
||||
/// Replacement for QMessageBox::critical.
|
||||
void critical(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
std::function<void(QMessageBox::StandardButton)> callback = {});
|
||||
|
||||
/// Replacement for QMessageBox::critical.
|
||||
void critical(
|
||||
QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton default_button,
|
||||
std::function<void(QMessageBox::StandardButton)> callback = {});
|
||||
} // namespace AsyncDialogs
|
||||
@@ -10,6 +10,8 @@ target_sources(pcsx2-qt PRIVATE
|
||||
AboutDialog.cpp
|
||||
AboutDialog.h
|
||||
AboutDialog.ui
|
||||
AsyncDialogs.cpp
|
||||
AsyncDialogs.h
|
||||
AutoUpdaterDialog.cpp
|
||||
AutoUpdaterDialog.h
|
||||
AutoUpdaterDialog.ui
|
||||
@@ -324,6 +326,7 @@ elseif(APPLE)
|
||||
set_source_files_properties(${QM_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/translations/)
|
||||
endforeach()
|
||||
copy_base_translations(pcsx2-qt)
|
||||
extract_translation_from_ts(Translations/pcsx2-qt_en.ts source PermissionsDialogCamera PCSX2_CAMERA_USAGE_DESCRIPTION)
|
||||
extract_translation_from_ts(Translations/pcsx2-qt_en.ts source PermissionsDialogMicrophone PCSX2_MICROPHONE_USAGE_DESCRIPTION)
|
||||
else()
|
||||
qt_add_lrelease(pcsx2-qt TS_FILES ${TS_FILES} QM_FILES_OUTPUT_VARIABLE QM_FILES)
|
||||
|
||||
@@ -112,7 +112,8 @@ void CoverDownloadDialog::cancelThread()
|
||||
}
|
||||
|
||||
CoverDownloadDialog::CoverDownloadThread::CoverDownloadThread(QWidget* parent, const QString& urls, bool use_serials)
|
||||
: QtAsyncProgressThread(parent), m_use_serials(use_serials)
|
||||
: QtAsyncProgressThread(parent)
|
||||
, m_use_serials(use_serials)
|
||||
{
|
||||
for (const QString& str : urls.split(QChar('\n')))
|
||||
m_urls.push_back(str.toStdString());
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "BreakpointDialog.h"
|
||||
#include "DebugTools/Breakpoints.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "QtUtils.h"
|
||||
#include "QtHost.h"
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include "Debugger/DebuggerWindow.h"
|
||||
|
||||
#include "DebugTools/Breakpoints.h"
|
||||
|
||||
BreakpointDialog::BreakpointDialog(QWidget* parent, DebugInterface* cpu, BreakpointModel& model)
|
||||
: QDialog(parent)
|
||||
@@ -100,7 +101,7 @@ void BreakpointDialog::accept()
|
||||
u64 address;
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), address, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Address"), QString::fromStdString(error));
|
||||
AsyncDialogs::warning(g_debugger_window, tr("Invalid Address"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -116,7 +117,7 @@ void BreakpointDialog::accept()
|
||||
|
||||
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Condition"), QString::fromStdString(error));
|
||||
AsyncDialogs::warning(g_debugger_window, tr("Invalid Condition"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -134,14 +135,14 @@ void BreakpointDialog::accept()
|
||||
u64 startAddress;
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), startAddress, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Address"), QString::fromStdString(error));
|
||||
AsyncDialogs::warning(g_debugger_window, tr("Invalid Address"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
u64 size;
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtSize->text().toStdString().c_str(), size, error) || !size)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Size"), QString::fromStdString(error));
|
||||
AsyncDialogs::warning(g_debugger_window, tr("Invalid Size"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -157,7 +158,7 @@ void BreakpointDialog::accept()
|
||||
PostfixExpression expr;
|
||||
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Condition"), QString::fromStdString(error));
|
||||
AsyncDialogs::warning(g_debugger_window, tr("Invalid Condition"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
|
||||
#include "BreakpointModel.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "Debugger/DebuggerSettingsManager.h"
|
||||
#include "Debugger/DebuggerWindow.h"
|
||||
|
||||
#include "DebugTools/DebugInterface.h"
|
||||
#include "DebugTools/Breakpoints.h"
|
||||
@@ -13,7 +15,6 @@
|
||||
#include "common/Console.h"
|
||||
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -385,7 +386,7 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i
|
||||
std::string error;
|
||||
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(nullptr, "Condition Error", QString::fromStdString(error));
|
||||
AsyncDialogs::warning(g_debugger_window, "Condition Error", QString::fromStdString(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -419,7 +420,7 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i
|
||||
std::string error;
|
||||
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(nullptr, "Condition Error", QString::fromStdString(error));
|
||||
AsyncDialogs::warning(g_debugger_window, "Condition Error", QString::fromStdString(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "DebuggerWindow.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "Debugger/DebuggerView.h"
|
||||
#include "Debugger/Docking/DockManager.h"
|
||||
|
||||
@@ -15,8 +16,6 @@
|
||||
#include "MainWindow.h"
|
||||
#include "AnalysisOptionsDialog.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
DebuggerWindow* g_debugger_window = nullptr;
|
||||
|
||||
DebuggerWindow::DebuggerWindow(QWidget* parent)
|
||||
@@ -70,19 +69,21 @@ DebuggerWindow::DebuggerWindow(QWidget* parent)
|
||||
});
|
||||
|
||||
connect(m_ui.actionResetAllLayouts, &QAction::triggered, this, [this]() {
|
||||
QString text = tr("Are you sure you want to reset all layouts?");
|
||||
if (QMessageBox::question(g_debugger_window, tr("Confirmation"), text) != QMessageBox::Yes)
|
||||
return;
|
||||
const QString title = tr("Confirmation");
|
||||
const QString text = tr("Are you sure you want to reset all layouts?");
|
||||
|
||||
m_dock_manager->resetAllLayouts();
|
||||
AsyncDialogs::question(this, title, text, [this]() {
|
||||
m_dock_manager->resetAllLayouts();
|
||||
});
|
||||
});
|
||||
|
||||
connect(m_ui.actionResetDefaultLayouts, &QAction::triggered, this, [this]() {
|
||||
QString text = tr("Are you sure you want to reset the default layouts?");
|
||||
if (QMessageBox::question(g_debugger_window, tr("Confirmation"), text) != QMessageBox::Yes)
|
||||
return;
|
||||
const QString title = tr("Confirmation");
|
||||
const QString text = tr("Are you sure you want to reset the default layouts?");
|
||||
|
||||
m_dock_manager->resetDefaultLayouts();
|
||||
AsyncDialogs::question(this, title, text, [this]() {
|
||||
m_dock_manager->resetDefaultLayouts();
|
||||
});
|
||||
});
|
||||
|
||||
connect(g_emu_thread, &EmuThread::onVMPaused, this, []() {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "DisassemblyView.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "Debugger/DebuggerWindow.h"
|
||||
#include "Debugger/JsonValueWrapper.h"
|
||||
#include "Debugger/Breakpoints/BreakpointModel.h"
|
||||
@@ -18,8 +19,6 @@
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtWidgets/QMenu>
|
||||
#include <QtGui/QClipboard>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include "SymbolTree/NewSymbolDialogs.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
@@ -111,7 +110,7 @@ void DisassemblyView::contextPasteInstructionText()
|
||||
{
|
||||
if (!cpu().isCpuPaused())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Assemble Error"), tr("Unable to change assembly while core is running"));
|
||||
AsyncDialogs::warning(this, tr("Assemble Error"), tr("Unable to change assembly while core is running"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -130,7 +129,7 @@ void DisassemblyView::contextPasteInstructionText()
|
||||
bool valid = MipsAssembleOpcode(newInstructions[instructionIdx].c_str(), &cpu(), replaceAddress, encodedInstruction, errorText);
|
||||
if (!valid)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Assemble Error"), QString("%1 %2").arg(errorText.c_str()).arg(newInstructions[instructionIdx].c_str()));
|
||||
AsyncDialogs::warning(this, tr("Assemble Error"), QString("%1 %2").arg(errorText.c_str()).arg(newInstructions[instructionIdx].c_str()));
|
||||
return;
|
||||
}
|
||||
encodedInstructions.push_back(encodedInstruction);
|
||||
@@ -148,29 +147,28 @@ void DisassemblyView::contextAssembleInstruction()
|
||||
{
|
||||
if (!cpu().isCpuPaused())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Assemble Error"), tr("Unable to change assembly while core is running"));
|
||||
AsyncDialogs::warning(this, tr("Assemble Error"), tr("Unable to change assembly while core is running"));
|
||||
return;
|
||||
}
|
||||
|
||||
DisassemblyLineInfo line;
|
||||
bool ok;
|
||||
m_disassemblyManager.getLine(m_selectedAddressStart, false, line);
|
||||
QString instruction = QInputDialog::getText(this, tr("Assemble Instruction"), "",
|
||||
QLineEdit::Normal, QString("%1 %2").arg(line.name.c_str()).arg(line.params.c_str()), &ok);
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
const QString title = tr("Assemble Instruction");
|
||||
const QString text = QString("%1 %2").arg(line.name.c_str()).arg(line.params.c_str());
|
||||
|
||||
u32 encodedInstruction;
|
||||
std::string errorText;
|
||||
bool valid = MipsAssembleOpcode(instruction.toLocal8Bit().constData(), &cpu(), m_selectedAddressStart, encodedInstruction, errorText);
|
||||
if (!valid)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Assemble Error"), QString::fromStdString(errorText));
|
||||
return;
|
||||
}
|
||||
AsyncDialogs::getText(this, title, "", text, [this](QString instruction) {
|
||||
u32 encodedInstruction;
|
||||
std::string errorText;
|
||||
bool valid = MipsAssembleOpcode(instruction.toLocal8Bit().constData(), &cpu(), m_selectedAddressStart, encodedInstruction, errorText);
|
||||
if (!valid)
|
||||
{
|
||||
AsyncDialogs::warning(this, tr("Assemble Error"), QString::fromStdString(errorText));
|
||||
return;
|
||||
}
|
||||
|
||||
setInstructions(m_selectedAddressStart, m_selectedAddressEnd, encodedInstruction);
|
||||
setInstructions(m_selectedAddressStart, m_selectedAddressEnd, encodedInstruction);
|
||||
});
|
||||
}
|
||||
|
||||
void DisassemblyView::contextNoopInstruction()
|
||||
@@ -249,34 +247,34 @@ void DisassemblyView::contextFollowBranch()
|
||||
|
||||
void DisassemblyView::contextGoToAddress()
|
||||
{
|
||||
bool ok;
|
||||
const QString targetString = QInputDialog::getText(this, tr("Go To In Disassembly"), "",
|
||||
QLineEdit::Normal, "", &ok);
|
||||
const QString title = tr("Go To In Disassembly");
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
AsyncDialogs::getText(this, title, "", "", [this](QString expression) {
|
||||
u64 address = 0;
|
||||
std::string error;
|
||||
if (!cpu().evaluateExpression(expression.toStdString().c_str(), address, error))
|
||||
{
|
||||
AsyncDialogs::warning(this, tr("Cannot Go To"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
u64 address = 0;
|
||||
std::string error;
|
||||
if (!cpu().evaluateExpression(targetString.toStdString().c_str(), address, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Cannot Go To"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
gotoAddressAndSetFocus(static_cast<u32>(address) & ~3);
|
||||
gotoAddressAndSetFocus(static_cast<u32>(address) & ~3);
|
||||
});
|
||||
}
|
||||
|
||||
void DisassemblyView::contextAddFunction()
|
||||
{
|
||||
NewFunctionDialog* dialog = new NewFunctionDialog(cpu(), this);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->setName(QString("func_%1").arg(m_selectedAddressStart, 8, 16, QChar('0')));
|
||||
dialog->setAddress(m_selectedAddressStart);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
if (m_selectedAddressEnd != m_selectedAddressStart)
|
||||
dialog->setCustomSize(m_selectedAddressEnd - m_selectedAddressStart + 4);
|
||||
if (dialog->exec() == QDialog::Accepted)
|
||||
update();
|
||||
|
||||
connect(dialog, &QDialog::accepted, this, [this]() { update(); });
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
void DisassemblyView::contextCopyFunctionName()
|
||||
@@ -304,28 +302,26 @@ void DisassemblyView::contextRemoveFunction()
|
||||
void DisassemblyView::contextRenameFunction()
|
||||
{
|
||||
const FunctionInfo curFunc = cpu().GetSymbolGuardian().FunctionOverlappingAddress(m_selectedAddressStart);
|
||||
|
||||
if (!curFunc.address.valid())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Rename Function Error"), tr("No function / symbol is currently selected."));
|
||||
AsyncDialogs::warning(this, tr("Rename Function Error"), tr("No function / symbol is currently selected."));
|
||||
return;
|
||||
}
|
||||
|
||||
QString oldName = QString::fromStdString(curFunc.name);
|
||||
const QString title = tr("Rename Function");
|
||||
const QString label = tr("Function name");
|
||||
const QString oldName = QString::fromStdString(curFunc.name);
|
||||
|
||||
bool ok;
|
||||
QString newName = QInputDialog::getText(this, tr("Rename Function"), tr("Function name"), QLineEdit::Normal, oldName, &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
AsyncDialogs::getText(this, title, label, oldName, [this, curFunc](QString newName) {
|
||||
if (newName.isEmpty())
|
||||
{
|
||||
AsyncDialogs::warning(this, tr("Rename Function Error"), tr("Function name cannot be nothing."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (newName.isEmpty())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Rename Function Error"), tr("Function name cannot be nothing."));
|
||||
return;
|
||||
}
|
||||
|
||||
cpu().GetSymbolGuardian().ReadWrite([&](ccc::SymbolDatabase& database) {
|
||||
database.functions.rename_symbol(curFunc.handle, newName.toStdString());
|
||||
cpu().GetSymbolGuardian().ReadWrite([&](ccc::SymbolDatabase& database) {
|
||||
database.functions.rename_symbol(curFunc.handle, newName.toStdString());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -375,7 +371,7 @@ void DisassemblyView::contextRestoreFunction()
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::warning(this, tr("Restore Function Error"), tr("Unable to stub selected address."));
|
||||
AsyncDialogs::warning(this, tr("Restore Function Error"), tr("Unable to stub selected address."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public slots:
|
||||
void contextCopyInstructionHex();
|
||||
void contextCopyInstructionText();
|
||||
void contextCopyFunctionName();
|
||||
void contextPasteInstructionText();
|
||||
void contextPasteInstructionText();
|
||||
void contextAssembleInstruction();
|
||||
void contextNoopInstruction();
|
||||
void contextRestoreInstruction();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "DockManager.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "Debugger/DebuggerView.h"
|
||||
#include "Debugger/DebuggerWindow.h"
|
||||
#include "Debugger/Docking/DockTables.h"
|
||||
@@ -24,7 +25,6 @@
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QtTranslation>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QProxyStyle>
|
||||
#include <QtWidgets/QStyleFactory>
|
||||
|
||||
@@ -518,17 +518,19 @@ void DockManager::newLayoutClicked()
|
||||
if (m_menu_bar)
|
||||
m_menu_bar->onCurrentLayoutChanged(m_current_layout);
|
||||
|
||||
auto name_validator = [this](const QString& name) {
|
||||
const auto name_validator = [this](const QString& name) {
|
||||
return !hasNameConflict(name, DockLayout::INVALID_INDEX);
|
||||
};
|
||||
|
||||
bool can_clone_current_layout = m_current_layout != DockLayout::INVALID_INDEX;
|
||||
const 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);
|
||||
LayoutEditorDialog* dialog = new LayoutEditorDialog(name_validator, can_clone_current_layout, g_debugger_window);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
connect(dialog, &QDialog::accepted, this, [this, dialog, name_validator]() {
|
||||
if (!name_validator(dialog->name()))
|
||||
return;
|
||||
|
||||
if (dialog->exec() == QDialog::Accepted && name_validator(dialog->name()))
|
||||
{
|
||||
DockLayout::Index new_layout = DockLayout::INVALID_INDEX;
|
||||
|
||||
const auto [mode, index] = dialog->initialState();
|
||||
@@ -565,9 +567,9 @@ void DockManager::newLayoutClicked()
|
||||
updateLayoutSwitcher();
|
||||
switchToLayout(new_layout);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
delete dialog.get();
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
void DockManager::openLayoutSwitcherContextMenu(const QPoint& pos, QTabBar* layout_switcher)
|
||||
@@ -605,26 +607,33 @@ void DockManager::editLayoutClicked(DockLayout::Index layout_index)
|
||||
if (layout_index >= m_layouts.size())
|
||||
return;
|
||||
|
||||
DockLayout& layout = m_layouts[layout_index];
|
||||
const DockLayout& layout = m_layouts[layout_index];
|
||||
|
||||
auto name_validator = [this, layout_index](const QString& name) {
|
||||
const 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);
|
||||
LayoutEditorDialog* dialog = new LayoutEditorDialog(layout.name(), layout.cpu(), name_validator, g_debugger_window);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
if (dialog->exec() != QDialog::Accepted || !name_validator(dialog->name()))
|
||||
return;
|
||||
connect(dialog, &QDialog::accepted, this, [this, layout_index, dialog, name_validator]() {
|
||||
if (layout_index >= m_layouts.size())
|
||||
return;
|
||||
|
||||
layout.setName(dialog->name());
|
||||
layout.setCpu(dialog->cpu());
|
||||
DockLayout& layout = m_layouts[layout_index];
|
||||
|
||||
layout.save(layout_index);
|
||||
if (!name_validator(dialog->name()))
|
||||
return;
|
||||
|
||||
delete dialog.get();
|
||||
layout.setName(dialog->name());
|
||||
layout.setCpu(dialog->cpu());
|
||||
|
||||
updateLayoutSwitcher();
|
||||
layout.save(layout_index);
|
||||
|
||||
updateLayoutSwitcher();
|
||||
});
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
void DockManager::resetLayoutClicked(DockLayout::Index layout_index)
|
||||
@@ -636,20 +645,28 @@ void DockManager::resetLayoutClicked(DockLayout::Index 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;
|
||||
const QString title = tr("Confirmation");
|
||||
const QString text = tr("Are you sure you want to reset layout '%1'?").arg(layout.name());
|
||||
|
||||
bool current_layout = layout_index == m_current_layout;
|
||||
AsyncDialogs::question(g_debugger_window, title, text, [this, layout_index]() {
|
||||
if (layout_index >= m_layouts.size())
|
||||
return;
|
||||
|
||||
if (current_layout)
|
||||
switchToLayout(DockLayout::INVALID_INDEX);
|
||||
DockLayout& layout = m_layouts[layout_index];
|
||||
if (!layout.canReset())
|
||||
return;
|
||||
|
||||
layout.reset();
|
||||
layout.save(layout_index);
|
||||
bool current_layout = layout_index == m_current_layout;
|
||||
|
||||
if (current_layout)
|
||||
switchToLayout(layout_index);
|
||||
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)
|
||||
@@ -659,12 +676,16 @@ void DockManager::deleteLayoutClicked(DockLayout::Index layout_index)
|
||||
|
||||
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;
|
||||
const QString title = tr("Confirmation");
|
||||
const QString text = tr("Are you sure you want to delete layout '%1'?").arg(layout.name());
|
||||
|
||||
deleteLayout(layout_index);
|
||||
updateLayoutSwitcher();
|
||||
AsyncDialogs::question(g_debugger_window, title, text, [this, layout_index]() {
|
||||
if (layout_index >= m_layouts.size())
|
||||
return;
|
||||
|
||||
deleteLayout(layout_index);
|
||||
updateLayoutSwitcher();
|
||||
});
|
||||
}
|
||||
|
||||
void DockManager::layoutSwitcherTabMoved(DockLayout::Index from_index, DockLayout::Index to_index)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "DockViews.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "QtUtils.h"
|
||||
#include "Debugger/DebuggerView.h"
|
||||
#include "Debugger/DebuggerWindow.h"
|
||||
@@ -17,8 +18,6 @@
|
||||
|
||||
#include <QtGui/QActionGroup>
|
||||
#include <QtGui/QPalette>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QMenu>
|
||||
#include <QtWidgets/QStyleFactory>
|
||||
|
||||
@@ -176,19 +175,22 @@ void DockTabBar::openContextMenu(QPoint pos)
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
bool ok;
|
||||
QString new_name = QInputDialog::getText(
|
||||
this, tr("Rename Window"), tr("New name:"), QLineEdit::Normal, widget->displayNameWithoutSuffix(), &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
const QString title = tr("Rename Window");
|
||||
const QString label = tr("New name:");
|
||||
const QString text = widget->displayNameWithoutSuffix();
|
||||
|
||||
if (!widget->setCustomDisplayName(new_name))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Name"), tr("The specified name is too long."));
|
||||
return;
|
||||
}
|
||||
AsyncDialogs::getText(this, title, label, text, [this, widget = QPointer(widget)](QString name) {
|
||||
if (!widget || !g_debugger_window)
|
||||
return;
|
||||
|
||||
g_debugger_window->dockManager().updateDockWidgetTitles();
|
||||
if (!widget->setCustomDisplayName(name))
|
||||
{
|
||||
AsyncDialogs::warning(this, tr("Invalid Name"), tr("The specified name is too long."));
|
||||
return;
|
||||
}
|
||||
|
||||
g_debugger_window->dockManager().updateDockWidgetTitles();
|
||||
});
|
||||
});
|
||||
|
||||
QAction* reset_name_action = menu->addAction(tr("Reset Name"));
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
|
||||
#include "MemorySearchView.h"
|
||||
|
||||
#include "DebugTools/DebugInterface.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "DebugTools/DebugInterface.h"
|
||||
|
||||
#include "common/Console.h"
|
||||
|
||||
#include <QtGui/QClipboard>
|
||||
#include <QtWidgets/QMenu>
|
||||
#include <QtWidgets/QScrollBar>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QtCore/QFutureWatcher>
|
||||
#include <QtGui/QPainter>
|
||||
@@ -478,7 +478,7 @@ void MemorySearchView::onSearchButtonClicked()
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Debugger"), tr("Invalid start address"));
|
||||
AsyncDialogs::critical(this, tr("Debugger"), tr("Invalid start address"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -486,13 +486,13 @@ void MemorySearchView::onSearchButtonClicked()
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Debugger"), tr("Invalid end address"));
|
||||
AsyncDialogs::critical(this, tr("Debugger"), tr("Invalid end address"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (searchStart >= searchEnd)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Debugger"), tr("Start address can't be equal to or greater than the end address"));
|
||||
AsyncDialogs::critical(this, tr("Debugger"), tr("Start address can't be equal to or greater than the end address"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -527,7 +527,7 @@ void MemorySearchView::onSearchButtonClicked()
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Debugger"), tr("Invalid search value"));
|
||||
AsyncDialogs::critical(this, tr("Debugger"), tr("Invalid search value"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -551,7 +551,7 @@ void MemorySearchView::onSearchButtonClicked()
|
||||
if (value <= std::numeric_limits<unsigned char>::max())
|
||||
break;
|
||||
default:
|
||||
QMessageBox::critical(this, tr("Debugger"), tr("Value is larger than type"));
|
||||
AsyncDialogs::critical(this, tr("Debugger"), tr("Value is larger than type"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -565,7 +565,7 @@ void MemorySearchView::onSearchButtonClicked()
|
||||
searchComparison == SearchComparison::IncreasedBy ||
|
||||
searchComparison == SearchComparison::NotChanged))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Debugger"), tr("This search comparison can only be used with filter searches."));
|
||||
AsyncDialogs::critical(this, tr("Debugger"), tr("This search comparison can only be used with filter searches."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -578,7 +578,7 @@ void MemorySearchView::onSearchButtonClicked()
|
||||
searchComparison == SearchComparison::IncreasedBy ||
|
||||
searchComparison == SearchComparison::NotChanged))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Debugger"), tr("This search comparison can only be used with filter searches."));
|
||||
AsyncDialogs::critical(this, tr("Debugger"), tr("This search comparison can only be used with filter searches."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "MemoryView.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "Debugger/JsonValueWrapper.h"
|
||||
|
||||
#include "QtHost.h"
|
||||
@@ -12,8 +13,6 @@
|
||||
#include <QtGui/QActionGroup>
|
||||
#include <QtGui/QClipboard>
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
using namespace QtUtils;
|
||||
|
||||
@@ -305,36 +304,33 @@ bool MemoryViewTable::InsertFloatIntoSelectedHexView(DebugInterface& cpu)
|
||||
std::memcpy(¤tFloatVal, ¤tIntVal, sizeof(currentFloatVal));
|
||||
const QString currentfloatStr = QString("%1").arg(QString::number(currentFloatVal, 'g'), 14).trimmed();
|
||||
|
||||
// Prompt user to enter a new float value
|
||||
bool isValidInput = false;
|
||||
QString newFloatStr = QInputDialog::getText(parent, tr("Input New Float"), "",
|
||||
QLineEdit::Normal, currentfloatStr, &isValidInput);
|
||||
if (!isValidInput)
|
||||
return false;
|
||||
const QString title = tr("Input New Float");
|
||||
|
||||
// Convert string into float value
|
||||
bool isValidFloat = false;
|
||||
const float newFloatVal = newFloatStr.toFloat(&isValidFloat);
|
||||
if (!isValidFloat)
|
||||
{
|
||||
QMessageBox::warning(parent, tr("Input Error"), tr("Invalid float value"));
|
||||
return false;
|
||||
}
|
||||
AsyncDialogs::getText(parent, title, "", currentfloatStr, [this, &cpu](QString newFloatStr) {
|
||||
// Convert string into float value
|
||||
bool isValidFloat = false;
|
||||
const float newFloatVal = newFloatStr.toFloat(&isValidFloat);
|
||||
if (!isValidFloat)
|
||||
{
|
||||
AsyncDialogs::warning(parent, tr("Input Error"), tr("Invalid float value"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Write new float value back to memory
|
||||
u32 newIntVal = 0;
|
||||
std::memcpy(&newIntVal, &newFloatVal, sizeof(newIntVal));
|
||||
newIntVal = convertEndian(newIntVal);
|
||||
// Write new float value back to memory
|
||||
u32 newIntVal = 0;
|
||||
std::memcpy(&newIntVal, &newFloatVal, sizeof(newIntVal));
|
||||
newIntVal = convertEndian(newIntVal);
|
||||
|
||||
const QPointer<MemoryViewTable> table(this);
|
||||
Host::RunOnCPUThread([table, address = selectedAddress, &cpu, val = newIntVal] {
|
||||
cpu.write32(address, val);
|
||||
const QPointer<MemoryViewTable> table(this);
|
||||
Host::RunOnCPUThread([table, address = selectedAddress, &cpu, val = newIntVal] {
|
||||
cpu.write32(address, val);
|
||||
|
||||
QtHost::RunOnUIThread([table] {
|
||||
if (!table)
|
||||
return;
|
||||
QtHost::RunOnUIThread([table] {
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
table->parent->update();
|
||||
table->parent->update();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -353,7 +349,7 @@ void MemoryViewTable::InsertAtCurrentSelection(const QString& text, DebugInterfa
|
||||
const float newFloatVal = text.toFloat(&isValidFloat);
|
||||
if (!isValidFloat)
|
||||
{
|
||||
QMessageBox::warning(parent, tr("Input Error"), tr("Invalid float value"));
|
||||
AsyncDialogs::warning(parent, tr("Input Error"), tr("Invalid float value"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -899,22 +895,19 @@ void MemoryView::contextPaste()
|
||||
|
||||
void MemoryView::contextGoToAddress()
|
||||
{
|
||||
bool ok;
|
||||
QString targetString = QInputDialog::getText(this, tr("Go To In Memory View"), "",
|
||||
QLineEdit::Normal, "", &ok);
|
||||
const QString title = tr("Go To In Memory View");
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
AsyncDialogs::getText(this, title, "", "", [this](QString expression) {
|
||||
u64 address = 0;
|
||||
std::string error;
|
||||
if (!cpu().evaluateExpression(expression.toStdString().c_str(), address, error))
|
||||
{
|
||||
AsyncDialogs::warning(this, tr("Cannot Go To"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
u64 address = 0;
|
||||
std::string error;
|
||||
if (!cpu().evaluateExpression(targetString.toStdString().c_str(), address, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Cannot Go To"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
gotoAddress(static_cast<u32>(address));
|
||||
gotoAddress(static_cast<u32>(address));
|
||||
});
|
||||
}
|
||||
|
||||
void MemoryView::contextFollowAddress()
|
||||
|
||||
@@ -30,7 +30,8 @@ SavedAddressesView::SavedAddressesView(const DebuggerViewParameters& parameters)
|
||||
DebuggerSettingsManager::loadGameSettings(m_model);
|
||||
});
|
||||
|
||||
DebuggerSettingsManager::loadGameSettings(m_model);
|
||||
if (m_model->rowCount() == 0)
|
||||
DebuggerSettingsManager::loadGameSettings(m_model);
|
||||
|
||||
for (std::size_t i = 0; auto mode : SavedAddressesModel::HeaderResizeModes)
|
||||
{
|
||||
|
||||
@@ -101,7 +101,7 @@ QVariant ModuleModel::headerData(int section, Qt::Orientation orientation, int r
|
||||
//: Warning: short space limit. Abbreviate if needed.
|
||||
return tr("NAME");
|
||||
case ModuleColumns::VERSION:
|
||||
//: Warning: short space limit. Abbreviate if needed.
|
||||
//: Warning: short space limit. Abbreviate if needed.
|
||||
return tr("VERSION");
|
||||
case ModuleColumns::ENTRY:
|
||||
//: Warning: short space limit. Abbreviate if needed. // Entrypoint of the executable
|
||||
|
||||
@@ -3,17 +3,16 @@
|
||||
|
||||
#include "RegisterView.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "QtUtils.h"
|
||||
#include "Debugger/JsonValueWrapper.h"
|
||||
|
||||
#include "QtUtils.h"
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtWidgets/QTabBar>
|
||||
#include <QtWidgets/QStylePainter>
|
||||
#include <QtWidgets/QStyleOptionTab>
|
||||
#include <QtGui/QClipboard>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QProxyStyle>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#include <bit>
|
||||
|
||||
@@ -351,12 +350,11 @@ void RegisterView::contextCopySegment()
|
||||
QApplication::clipboard()->setText(FilledQStringFromValue(val._u32[3 - m_selected128Field], 16));
|
||||
}
|
||||
|
||||
bool RegisterView::contextFetchNewValue(u64& out, u64 currentValue, bool segment)
|
||||
void RegisterView::fetchNewValue(u64 currentValue, bool segment, std::function<void(u64)> callback)
|
||||
{
|
||||
const int categoryIndex = ui.registerTabs->currentIndex();
|
||||
const bool floatingPoint = CAT_SHOW_FLOAT && segment;
|
||||
const int regSize = cpu().getRegisterSize(categoryIndex);
|
||||
bool ok = false;
|
||||
|
||||
QString existingValue("%1");
|
||||
|
||||
@@ -366,79 +364,89 @@ bool RegisterView::contextFetchNewValue(u64& out, u64 currentValue, bool segment
|
||||
existingValue = existingValue.arg(std::bit_cast<float>((u32)currentValue));
|
||||
|
||||
//: Changing the value in a CPU register (e.g. "Change t0")
|
||||
QString input = QInputDialog::getText(this, tr("Change %1").arg(cpu().getRegisterName(categoryIndex, m_selectedRow)), "",
|
||||
QLineEdit::Normal, existingValue, &ok);
|
||||
const QString title = tr("Change %1").arg(cpu().getRegisterName(categoryIndex, m_selectedRow));
|
||||
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
if (!floatingPoint) // Get input as hexadecimal
|
||||
{
|
||||
out = input.toULongLong(&ok, 16);
|
||||
if (!ok)
|
||||
AsyncDialogs::getText(this, title, "", existingValue, [this, callback, floatingPoint](QString input) {
|
||||
u64 value;
|
||||
if (!floatingPoint) // Get input as hexadecimal
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid register value"), tr("Invalid hexadecimal register value."));
|
||||
return false;
|
||||
bool ok;
|
||||
value = input.toULongLong(&ok, 16);
|
||||
if (!ok)
|
||||
{
|
||||
AsyncDialogs::warning(this, tr("Invalid register value"), tr("Invalid hexadecimal register value."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out = std::bit_cast<u32>(input.toFloat(&ok));
|
||||
if (!ok)
|
||||
else
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid register value"), tr("Invalid floating-point register value."));
|
||||
return false;
|
||||
bool ok;
|
||||
value = std::bit_cast<u32>(input.toFloat(&ok));
|
||||
if (!ok)
|
||||
{
|
||||
AsyncDialogs::warning(this, tr("Invalid register value"), tr("Invalid floating-point register value."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
callback(value);
|
||||
});
|
||||
}
|
||||
|
||||
void RegisterView::contextChangeValue()
|
||||
{
|
||||
const int categoryIndex = ui.registerTabs->currentIndex();
|
||||
u64 newVal;
|
||||
if (contextFetchNewValue(newVal, cpu().getRegister(categoryIndex, m_selectedRow).lo))
|
||||
{
|
||||
cpu().setRegister(categoryIndex, m_selectedRow, u128::From64(newVal));
|
||||
const int category_index = ui.registerTabs->currentIndex();
|
||||
const s32 row = m_selectedRow;
|
||||
const u32 old_value = cpu().getRegister(category_index, row).lo;
|
||||
|
||||
fetchNewValue(old_value, false, [this, category_index, row](u64 input) {
|
||||
cpu().setRegister(category_index, row, u128::From64(input));
|
||||
DebuggerView::broadcastEvent(DebuggerEvents::VMUpdate());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void RegisterView::contextChangeTop()
|
||||
{
|
||||
u64 newVal;
|
||||
u128 oldVal = cpu().getRegister(ui.registerTabs->currentIndex(), m_selectedRow);
|
||||
if (contextFetchNewValue(newVal, oldVal.hi))
|
||||
{
|
||||
oldVal.hi = newVal;
|
||||
cpu().setRegister(ui.registerTabs->currentIndex(), m_selectedRow, oldVal);
|
||||
const int category_index = ui.registerTabs->currentIndex();
|
||||
const s32 row = m_selectedRow;
|
||||
const u128 old_value = cpu().getRegister(category_index, row);
|
||||
|
||||
fetchNewValue(old_value.hi, false, [this, category_index, row, old_value](u32 input) {
|
||||
u128 new_value = old_value;
|
||||
new_value.hi = input;
|
||||
cpu().setRegister(category_index, row, new_value);
|
||||
DebuggerView::broadcastEvent(DebuggerEvents::VMUpdate());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void RegisterView::contextChangeBottom()
|
||||
{
|
||||
u64 newVal;
|
||||
u128 oldVal = cpu().getRegister(ui.registerTabs->currentIndex(), m_selectedRow);
|
||||
if (contextFetchNewValue(newVal, oldVal.lo))
|
||||
{
|
||||
oldVal.lo = newVal;
|
||||
cpu().setRegister(ui.registerTabs->currentIndex(), m_selectedRow, oldVal);
|
||||
const int category_index = ui.registerTabs->currentIndex();
|
||||
const s32 row = m_selectedRow;
|
||||
const u128 old_value = cpu().getRegister(category_index, row);
|
||||
|
||||
fetchNewValue(old_value.lo, false, [this, category_index, row, old_value](u32 input) {
|
||||
u128 new_value = old_value;
|
||||
new_value.lo = input;
|
||||
cpu().setRegister(category_index, row, new_value);
|
||||
DebuggerView::broadcastEvent(DebuggerEvents::VMUpdate());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void RegisterView::contextChangeSegment()
|
||||
{
|
||||
u64 newVal;
|
||||
u128 oldVal = cpu().getRegister(ui.registerTabs->currentIndex(), m_selectedRow);
|
||||
if (contextFetchNewValue(newVal, oldVal._u32[3 - m_selected128Field], true))
|
||||
{
|
||||
oldVal._u32[3 - m_selected128Field] = (u32)newVal;
|
||||
cpu().setRegister(ui.registerTabs->currentIndex(), m_selectedRow, oldVal);
|
||||
const int category_index = ui.registerTabs->currentIndex();
|
||||
const s32 row = m_selectedRow;
|
||||
const s32 field = m_selected128Field;
|
||||
const u128 old_value = cpu().getRegister(category_index, row);
|
||||
const u32 segment = old_value._u32[3 - field];
|
||||
|
||||
fetchNewValue(segment, false, [this, category_index, row, field, old_value](u32 input) {
|
||||
u128 new_value = old_value;
|
||||
new_value._u32[3 - field] = input;
|
||||
cpu().setRegister(category_index, row, new_value);
|
||||
DebuggerView::broadcastEvent(DebuggerEvents::VMUpdate());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
std::optional<DebuggerEvents::GoToAddress> RegisterView::contextCreateGotoEvent()
|
||||
@@ -454,7 +462,7 @@ std::optional<DebuggerEvents::GoToAddress> RegisterView::contextCreateGotoEvent(
|
||||
|
||||
if (!cpu().isValidAddress(addr))
|
||||
{
|
||||
QMessageBox::warning(
|
||||
AsyncDialogs::warning(
|
||||
this,
|
||||
tr("Invalid target address"),
|
||||
tr("This register holds an invalid address."));
|
||||
|
||||
@@ -49,8 +49,7 @@ public slots:
|
||||
private:
|
||||
Ui::RegisterView ui;
|
||||
|
||||
// Returns true on success
|
||||
bool contextFetchNewValue(u64& out, u64 currentValue, bool segment = false);
|
||||
void fetchNewValue(u64 currentValue, bool segment, std::function<void(u64)> callback);
|
||||
|
||||
// Used for the height offset the tab bar creates
|
||||
// because we share a widget
|
||||
|
||||
@@ -25,8 +25,7 @@ public:
|
||||
COLUMN_COUNT
|
||||
};
|
||||
|
||||
static constexpr QHeaderView::ResizeMode HeaderResizeModes[StackColumns::COLUMN_COUNT] =
|
||||
{
|
||||
static constexpr QHeaderView::ResizeMode HeaderResizeModes[StackColumns::COLUMN_COUNT] = {
|
||||
QHeaderView::ResizeMode::ResizeToContents,
|
||||
QHeaderView::ResizeMode::Stretch,
|
||||
QHeaderView::ResizeMode::ResizeToContents,
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
#include "NewSymbolDialogs.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "Debugger/DebuggerWindow.h"
|
||||
#include "Debugger/SymbolTree/TypeString.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QMetaMethod>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QPushButton>
|
||||
|
||||
#include "TypeString.h"
|
||||
|
||||
NewSymbolDialog::NewSymbolDialog(u32 flags, u32 alignment, DebugInterface& cpu, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_cpu(cpu)
|
||||
@@ -359,7 +360,7 @@ void NewFunctionDialog::createSymbol()
|
||||
});
|
||||
|
||||
if (!error_message.isEmpty())
|
||||
QMessageBox::warning(this, tr("Cannot Create Function"), error_message);
|
||||
AsyncDialogs::warning(g_debugger_window, tr("Cannot Create Function"), error_message);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
@@ -416,7 +417,7 @@ void NewGlobalVariableDialog::createSymbol()
|
||||
});
|
||||
|
||||
if (!error_message.isEmpty())
|
||||
QMessageBox::warning(this, tr("Cannot Create Global Variable"), error_message);
|
||||
AsyncDialogs::warning(g_debugger_window, tr("Cannot Create Global Variable"), error_message);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
@@ -534,7 +535,7 @@ void NewLocalVariableDialog::createSymbol()
|
||||
});
|
||||
|
||||
if (!error_message.isEmpty())
|
||||
QMessageBox::warning(this, tr("Cannot Create Local Variable"), error_message);
|
||||
AsyncDialogs::warning(g_debugger_window, tr("Cannot Create Local Variable"), error_message);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
@@ -648,5 +649,5 @@ void NewParameterVariableDialog::createSymbol()
|
||||
});
|
||||
|
||||
if (!error_message.isEmpty())
|
||||
QMessageBox::warning(this, tr("Cannot Create Parameter Variable"), error_message);
|
||||
AsyncDialogs::warning(g_debugger_window, tr("Cannot Create Parameter Variable"), error_message);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "SymbolTreeDelegates.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "Debugger/SymbolTree/SymbolTreeModel.h"
|
||||
#include "Debugger/SymbolTree/TypeString.h"
|
||||
|
||||
@@ -10,7 +11,6 @@
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
#include <QtWidgets/QLineEdit>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
SymbolTreeValueDelegate::SymbolTreeValueDelegate(
|
||||
DebugInterface& cpu,
|
||||
@@ -495,7 +495,7 @@ void SymbolTreeTypeDelegate::setModelData(QWidget* editor, QAbstractItemModel* m
|
||||
symbol_tree_model->resetChildren(index);
|
||||
}
|
||||
else
|
||||
QMessageBox::warning(editor, tr("Cannot Change Type"), error_message);
|
||||
AsyncDialogs::warning(editor, tr("Cannot Change Type"), error_message);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
|
||||
@@ -19,7 +19,7 @@ struct SymbolTreeLocation
|
||||
MEMORY,
|
||||
NONE // Put NONE last so nodes of this type sort to the bottom.
|
||||
};
|
||||
|
||||
|
||||
Type type = NONE;
|
||||
u32 address = 0;
|
||||
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
|
||||
#include "SymbolTreeViews.h"
|
||||
|
||||
#include "AsyncDialogs.h"
|
||||
#include "Debugger/JsonValueWrapper.h"
|
||||
#include "Debugger/SymbolTree/NewSymbolDialogs.h"
|
||||
#include "Debugger/SymbolTree/SymbolTreeDelegates.h"
|
||||
|
||||
#include <QtGui/QActionGroup>
|
||||
#include <QtGui/QClipboard>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMenu>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QScrollBar>
|
||||
|
||||
static bool testName(const QString& name, const QString& filter);
|
||||
@@ -643,14 +642,16 @@ void SymbolTreeView::onDeleteButtonPressed()
|
||||
if (!node->symbol.valid())
|
||||
return;
|
||||
|
||||
if (QMessageBox::question(this, tr("Confirm Deletion"), tr("Delete '%1'?").arg(node->name)) != QMessageBox::Yes)
|
||||
return;
|
||||
const QString title = tr("Confirm Deletion");
|
||||
const QString text = tr("Delete '%1'?").arg(node->name);
|
||||
|
||||
cpu().GetSymbolGuardian().ReadWrite([&](ccc::SymbolDatabase& database) {
|
||||
node->symbol.destroy_symbol(database, true);
|
||||
AsyncDialogs::question(this, title, text, [this, handle = node->symbol]() {
|
||||
cpu().GetSymbolGuardian().ReadWrite([&](ccc::SymbolDatabase& database) {
|
||||
handle.destroy_symbol(database, true);
|
||||
});
|
||||
|
||||
reset();
|
||||
});
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
void SymbolTreeView::onCopyName()
|
||||
@@ -701,13 +702,10 @@ void SymbolTreeView::onRenameSymbol()
|
||||
text = QString::fromStdString(symbol->name());
|
||||
});
|
||||
|
||||
bool ok;
|
||||
std::string name = QInputDialog::getText(this, title, label, QLineEdit::Normal, text, &ok).toStdString();
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
cpu().GetSymbolGuardian().ReadWrite([&](ccc::SymbolDatabase& database) {
|
||||
node->symbol.rename_symbol(name, database);
|
||||
AsyncDialogs::getText(this, title, label, text, [this, handle = node->symbol](QString new_name) {
|
||||
cpu().GetSymbolGuardian().ReadWrite([&](ccc::SymbolDatabase& database) {
|
||||
handle.rename_symbol(new_name.toStdString(), database);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -737,18 +735,15 @@ void SymbolTreeView::onChangeTypeTemporarily()
|
||||
std::optional<QString> old_type = m_model->typeFromModelIndexToString(index);
|
||||
if (!old_type.has_value())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Cannot Change Type"), tr("That node cannot have a type."));
|
||||
AsyncDialogs::warning(this, tr("Cannot Change Type"), tr("That node cannot have a type."));
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok;
|
||||
QString type_string = QInputDialog::getText(this, title, label, QLineEdit::Normal, *old_type, &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
std::optional<QString> error_message = m_model->changeTypeTemporarily(index, type_string.toStdString());
|
||||
if (error_message.has_value() && !error_message->isEmpty())
|
||||
QMessageBox::warning(this, tr("Cannot Change Type"), *error_message);
|
||||
AsyncDialogs::getText(this, title, label, *old_type, [this, index](QString type_string) {
|
||||
std::optional<QString> error_message = m_model->changeTypeTemporarily(index, type_string.toStdString());
|
||||
if (error_message.has_value() && !error_message->isEmpty())
|
||||
AsyncDialogs::warning(this, tr("Cannot Change Type"), *error_message);
|
||||
});
|
||||
}
|
||||
|
||||
void SymbolTreeView::onTreeViewClicked(const QModelIndex& index)
|
||||
@@ -862,8 +857,10 @@ void FunctionTreeView::onNewButtonPressed()
|
||||
{
|
||||
NewFunctionDialog* dialog = new NewFunctionDialog(cpu(), this);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
if (dialog->exec() == QDialog::Accepted)
|
||||
reset();
|
||||
|
||||
connect(dialog, &QDialog::accepted, this, &FunctionTreeView::reset);
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
@@ -1005,8 +1002,10 @@ void GlobalVariableTreeView::onNewButtonPressed()
|
||||
{
|
||||
NewGlobalVariableDialog* dialog = new NewGlobalVariableDialog(cpu(), this);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
if (dialog->exec() == QDialog::Accepted)
|
||||
reset();
|
||||
|
||||
connect(dialog, &QDialog::accepted, this, &GlobalVariableTreeView::reset);
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
@@ -1134,8 +1133,10 @@ void LocalVariableTreeView::onNewButtonPressed()
|
||||
{
|
||||
NewLocalVariableDialog* dialog = new NewLocalVariableDialog(cpu(), this);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
if (dialog->exec() == QDialog::Accepted)
|
||||
reset();
|
||||
|
||||
connect(dialog, &QDialog::accepted, this, &LocalVariableTreeView::reset);
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
@@ -1261,8 +1262,10 @@ void ParameterVariableTreeView::onNewButtonPressed()
|
||||
{
|
||||
NewParameterVariableDialog* dialog = new NewParameterVariableDialog(cpu(), this);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
if (dialog->exec() == QDialog::Accepted)
|
||||
reset();
|
||||
|
||||
connect(dialog, &QDialog::accepted, this, &ParameterVariableTreeView::reset);
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
static bool testName(const QString& name, const QString& filter)
|
||||
|
||||
@@ -27,8 +27,7 @@ public:
|
||||
COLUMN_COUNT
|
||||
};
|
||||
|
||||
static constexpr QHeaderView::ResizeMode HeaderResizeModes[ThreadColumns::COLUMN_COUNT] =
|
||||
{
|
||||
static constexpr QHeaderView::ResizeMode HeaderResizeModes[ThreadColumns::COLUMN_COUNT] = {
|
||||
QHeaderView::ResizeMode::ResizeToContents,
|
||||
QHeaderView::ResizeMode::ResizeToContents,
|
||||
QHeaderView::ResizeMode::ResizeToContents,
|
||||
|
||||
@@ -479,8 +479,15 @@ bool DisplaySurface::eventFilter(QObject* object, QEvent* event)
|
||||
// macOS: When we (the display window) get focus from another window with a toolbar we update to the MainWindow toolbar.
|
||||
// This is because we are a different native window from our MainWindow. So, whenever we get focus, focus our MainWindow.
|
||||
// That way macOS will show the MainWindow toolbar when you click from the debugger / log window to the game.
|
||||
if (auto* w = qobject_cast<QWidget*>(object))
|
||||
|
||||
// Don't try to steal focus when we're showing a modal dialog
|
||||
// We end up ping ponging focus in a feedback loop
|
||||
if (QApplication::activeModalWidget() != nullptr)
|
||||
return false;
|
||||
|
||||
if (const auto* w = qobject_cast<QWidget*>(object))
|
||||
w->window()->activateWindow();
|
||||
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -160,7 +160,6 @@ void GameListModel::loadOrGenerateCover(const GameList::Entry* ge)
|
||||
|
||||
// Final check that scale is unchanged before we send out the produced image.
|
||||
return m_cover_scale_counter.load(std::memory_order_acquire) == counter ? image : QPixmap();
|
||||
|
||||
});
|
||||
|
||||
// Context must be 'this' so we run on the UI thread.
|
||||
@@ -221,7 +220,7 @@ QString GameListModel::formatTimespan(const time_t timespan)
|
||||
const u32 hours = static_cast<u32>(timespan / 3600);
|
||||
if (hours > 0)
|
||||
return qApp->translate("GameList", "%n hours", "", hours);
|
||||
|
||||
|
||||
const u32 minutes = static_cast<u32>((timespan % 3600) / 60);
|
||||
if (minutes > 0)
|
||||
return qApp->translate("GameList", "%n minutes", "", minutes);
|
||||
|
||||
@@ -282,7 +282,7 @@ void GameListWidget::initialize()
|
||||
connect(m_table_view, &QTableView::customContextMenuRequested, this,
|
||||
&GameListWidget::onTableViewContextMenuRequested);
|
||||
connect(m_table_view->horizontalHeader(), &QHeaderView::customContextMenuRequested, this,
|
||||
&GameListWidget::onTableViewHeaderContextMenuRequested);
|
||||
&GameListWidget::onTableViewHeaderContextMenuRequested);
|
||||
|
||||
// Save state when header state changes (hiding and showing handled within onTableViewHeaderContextMenuRequested).
|
||||
connect(m_table_view->horizontalHeader(), &QHeaderView::sectionMoved, this, &GameListWidget::onTableHeaderStateChanged);
|
||||
@@ -292,13 +292,27 @@ void GameListWidget::initialize()
|
||||
|
||||
// Load the last session's header state or create a new one.
|
||||
if (Host::ContainsBaseSettingValue("GameListTableView", "HeaderState"))
|
||||
{
|
||||
loadTableHeaderState();
|
||||
// Enforce at least one column is visible immediately after loading.
|
||||
// This handles cases where a config (perhaps from an older version) has 0 columns and
|
||||
// no games are visible to be changed (such as per-game config) or played as you can't click on any.
|
||||
// Will automatically repair a broken header state from config (PCSX2.ini) file.
|
||||
ensureMinimumOneColumnVisible();
|
||||
}
|
||||
else
|
||||
{
|
||||
applyTableHeaderDefaults();
|
||||
}
|
||||
|
||||
// After header state load to account for user-specified sort.
|
||||
m_table_view->setSortingEnabled(true);
|
||||
|
||||
// Safety Fallback: Ensure the header is actually visible and
|
||||
// force it to stretch correctly on the first launch. This is an edgecase in case it already broke for some people or broke on older versions
|
||||
m_table_view->horizontalHeader()->show();
|
||||
resizeTableViewColumnsToFit();
|
||||
|
||||
m_ui.stack->insertWidget(0, m_table_view);
|
||||
|
||||
m_list_view = new GameListGridListView(m_ui.stack);
|
||||
@@ -408,7 +422,7 @@ void GameListWidget::setCustomBackground()
|
||||
// Selected Custom background is valid, connect the signals and start animation in gamelist
|
||||
connect(m_background_movie, &QMovie::frameChanged, this, &GameListWidget::processBackgroundFrames, Qt::UniqueConnection);
|
||||
m_ui.stack->setAutoFillBackground(false);
|
||||
|
||||
|
||||
m_table_view->viewport()->setAutoFillBackground(false);
|
||||
m_list_view->viewport()->setAutoFillBackground(false);
|
||||
updateCustomBackgroundState(true);
|
||||
@@ -562,30 +576,35 @@ void GameListWidget::onListViewContextMenuRequested(const QPoint& point)
|
||||
|
||||
void GameListWidget::onTableViewHeaderContextMenuRequested(const QPoint& point)
|
||||
{
|
||||
QMenu menu;
|
||||
QHeaderView* header = m_table_view->horizontalHeader();
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
int column_visual = 0;
|
||||
QHeaderView* const header = m_table_view->horizontalHeader();
|
||||
QMenu menu(this);
|
||||
// Iterate through all available columns defined in the model.
|
||||
for (int column = 0; column < GameListModel::Column_Count; column++)
|
||||
{
|
||||
// The "cover" column is the game grid and cannot be hidden.
|
||||
// Skip the cover art column as it shouldn't be toggled manually.
|
||||
if (column == GameListModel::Column_Cover)
|
||||
continue;
|
||||
|
||||
column_visual = header->visualIndex(column);
|
||||
QAction* action = menu.addAction(m_model->getColumnDisplayName(column_visual));
|
||||
// Create a checkable menu item for each column title.
|
||||
const QString title = m_model->headerData(column, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
QAction* const action = menu.addAction(title);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(!m_table_view->isColumnHidden(column_visual));
|
||||
connect(action, &QAction::toggled, [this, column_visual](bool enabled) {
|
||||
m_table_view->setColumnHidden(column_visual, !enabled);
|
||||
action->setChecked(!header->isSectionHidden(column));
|
||||
// Update the GUI when the user toggles a column with left-click actions in the right-click menu on the column.
|
||||
connect(action, &QAction::triggered, [this, header, column, action]() {
|
||||
header->setSectionHidden(column, !action->isChecked());
|
||||
// Safety check: prevent the user from hiding every single column.
|
||||
ensureMinimumOneColumnVisible();
|
||||
// Lastly push the new header state to settings.
|
||||
onTableHeaderStateChanged();
|
||||
resizeTableViewColumnsToFit();
|
||||
});
|
||||
}
|
||||
|
||||
menu.exec(m_table_view->mapToGlobal(point));
|
||||
menu.addSeparator();
|
||||
// Add a "panic button" that fully restores the default column layout.
|
||||
// This allows users to recover without editing configuration files such as [GameListTableView] has a key with
|
||||
// and variable HeaderState which you can remove the line to also do the same effect but old method is not user-friendly.
|
||||
menu.addAction(tr("Reset All Columns"), this, &GameListWidget::resetTableHeaderToDefault);
|
||||
menu.exec(m_table_view->viewport()->mapToGlobal(point));
|
||||
}
|
||||
|
||||
void GameListWidget::onCoverScaleChanged()
|
||||
@@ -789,6 +808,34 @@ void GameListWidget::loadTableHeaderState()
|
||||
header->restoreState(QByteArray::fromBase64(QByteArray::fromStdString(state_setting)));
|
||||
}
|
||||
|
||||
void GameListWidget::ensureMinimumOneColumnVisible()
|
||||
{
|
||||
QHeaderView* header = m_table_view->horizontalHeader();
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
bool any_visible = false;
|
||||
for (int column = 0; column < GameListModel::Column_Count; column++)
|
||||
{
|
||||
if (column != GameListModel::Column_Cover && !header->isSectionHidden(column))
|
||||
{
|
||||
any_visible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If absolutely everything is hidden, force the Title column to be visible.
|
||||
// This ensures there is always a right-click menu on the column available to restore
|
||||
// other columns or access the "Reset All Columns" option or even re-order them with drag and drop.
|
||||
// By default Qt will hide everything if it sees 0 viable columns, so just enforce atleast 1 column.
|
||||
// Adding ghost columns would be hacky and ugly so let's not do that.
|
||||
if (!any_visible)
|
||||
{
|
||||
header->setSectionHidden(GameListModel::Column_Title, false);
|
||||
onTableHeaderStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void GameListWidget::onTableHeaderStateChanged()
|
||||
{
|
||||
QHeaderView* header = m_table_view->horizontalHeader();
|
||||
@@ -824,6 +871,8 @@ void GameListWidget::applyTableHeaderDefaults()
|
||||
}
|
||||
|
||||
// TODO (Tech): Create a button for this in the minibar. Currently unused.
|
||||
// TODO (Red): Not sure if I should integrate it in the minibar for now when I made sure they can't break their order and there is a reset function now when you right-click the column.
|
||||
// They could accidentaly press on it when they didn't want to, could be revised later still because people without mouses can't do it such as controller mode on the TV.
|
||||
void GameListWidget::resetTableHeaderToDefault()
|
||||
{
|
||||
QHeaderView* header = m_table_view->horizontalHeader();
|
||||
@@ -848,6 +897,8 @@ void GameListWidget::resetTableHeaderToDefault()
|
||||
}
|
||||
|
||||
Host::SetBaseStringSettingValue("GameListTableView", "HeaderState", header->saveState().toBase64());
|
||||
// This makes the columns expand to fill the window right now.
|
||||
resizeTableViewColumnsToFit();
|
||||
}
|
||||
|
||||
void GameListWidget::saveSortSettings(const int column, const Qt::SortOrder sort_order)
|
||||
|
||||
@@ -109,6 +109,7 @@ private:
|
||||
void loadTableHeaderState();
|
||||
void applyTableHeaderDefaults();
|
||||
void resetTableHeaderToDefault();
|
||||
void ensureMinimumOneColumnVisible();
|
||||
void saveSortSettings(int column, Qt::SortOrder sort_order);
|
||||
void listZoom(float delta);
|
||||
void updateToolbar();
|
||||
|
||||
+9
-12
@@ -52,7 +52,7 @@ void LogWindow::updateSettings()
|
||||
const bool curr_enabled = Log::IsHostOutputEnabled();
|
||||
const bool input_enabled = Host::GetBaseBoolSettingValue("Logging", "ShowEESIOInput");
|
||||
|
||||
if(g_log_window && g_log_window->m_line_input)
|
||||
if (g_log_window && g_log_window->m_line_input)
|
||||
{
|
||||
g_log_window->m_input_widget->setVisible(input_enabled);
|
||||
}
|
||||
@@ -199,18 +199,16 @@ void LogWindow::createUi()
|
||||
|
||||
m_line_input = new QLineEdit(this);
|
||||
connect(m_line_input, &QLineEdit::returnPressed, this, &LogWindow::onInputEntered);
|
||||
|
||||
|
||||
m_local_echo_checkbox = new QCheckBox(tr("Local Echo"), this);
|
||||
m_local_echo_checkbox->setChecked(m_local_echo);
|
||||
connect(m_local_echo_checkbox, &QCheckBox::checkStateChanged, this, [&](Qt::CheckState state)
|
||||
{
|
||||
connect(m_local_echo_checkbox, &QCheckBox::checkStateChanged, this, [&](Qt::CheckState state) {
|
||||
m_local_echo = state == Qt::CheckState::Checked;
|
||||
});
|
||||
|
||||
|
||||
m_newline_on_enter_checkbox = new QCheckBox(tr("Newline on send"), this);
|
||||
m_newline_on_enter_checkbox->setChecked(m_newline_on_enter);
|
||||
connect(m_newline_on_enter_checkbox, &QCheckBox::checkStateChanged, this, [&](Qt::CheckState state)
|
||||
{
|
||||
connect(m_newline_on_enter_checkbox, &QCheckBox::checkStateChanged, this, [&](Qt::CheckState state) {
|
||||
m_newline_on_enter = state == Qt::CheckState::Checked;
|
||||
});
|
||||
|
||||
@@ -243,7 +241,6 @@ void LogWindow::createUi()
|
||||
vlayout->addWidget(m_text);
|
||||
vlayout->addWidget(m_input_widget);
|
||||
|
||||
central_widget->setLayout(vlayout);
|
||||
setCentralWidget(central_widget);
|
||||
}
|
||||
|
||||
@@ -417,18 +414,18 @@ void LogWindow::onInputEntered()
|
||||
if (text.isEmpty() && !m_newline_on_enter)
|
||||
return;
|
||||
|
||||
if(m_newline_on_enter)
|
||||
if (m_newline_on_enter)
|
||||
text.append('\n');
|
||||
|
||||
std::string str = text.toUtf8().toStdString();
|
||||
|
||||
if(VMManager::WriteBytesToEESIORXFIFO({reinterpret_cast<const u8*>(str.data()), str.size()}))
|
||||
if (VMManager::WriteBytesToEESIORXFIFO({reinterpret_cast<const u8*>(str.data()), str.size()}))
|
||||
{
|
||||
m_line_input->clear();
|
||||
|
||||
if(m_local_echo)
|
||||
if (m_local_echo)
|
||||
// appendMessage expects a newline to be at the end of the string
|
||||
appendMessage(0, 0, m_newline_on_enter ? text : (text + '\n') );
|
||||
appendMessage(0, 0, m_newline_on_enter ? text : (text + '\n'));
|
||||
|
||||
QTextCursor cursor(m_text->textCursor());
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
|
||||
+20
-3
@@ -195,7 +195,7 @@ void EmuThread::stopFullscreenUI()
|
||||
{
|
||||
m_run_fullscreen_ui.store(false, std::memory_order_release);
|
||||
emit onFullscreenUIStateChange(false);
|
||||
|
||||
|
||||
// Resume and refresh background when FullscreenUI exits
|
||||
QMetaObject::invokeMethod(g_main_window, "updateGameListBackground", Qt::QueuedConnection);
|
||||
}
|
||||
@@ -1160,7 +1160,7 @@ void Host::OpenHostFileSelectorAsync(std::string_view title, bool select_directo
|
||||
if (!filters.empty())
|
||||
{
|
||||
filters_str.append(QStringLiteral("All File Types (%1)")
|
||||
.arg(QString::fromStdString(StringUtil::JoinString(filters.begin(), filters.end(), " "))));
|
||||
.arg(QString::fromStdString(StringUtil::JoinString(filters.begin(), filters.end(), " "))));
|
||||
for (const std::string& filter : filters)
|
||||
{
|
||||
filters_str.append(
|
||||
@@ -1369,7 +1369,6 @@ bool QtHost::InitializeConfig()
|
||||
.arg(QString::fromStdString(error.GetDescription())));
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Setup wizard was incomplete last time?
|
||||
@@ -2094,6 +2093,8 @@ void QtHost::PrintCommandLineHelp(const std::string_view progname)
|
||||
std::fprintf(stderr, " -testconfig: Initializes configuration and checks version, then exits.\n");
|
||||
std::fprintf(stderr, " -setupwizard: Forces initial setup wizard to run.\n");
|
||||
std::fprintf(stderr, " -debugger: Open debugger and break on entry point.\n");
|
||||
std::fprintf(stderr, " -turbo: Enters turbo (fast forward) mode after starting.\n");
|
||||
std::fprintf(stderr, " -unlimited: Enters unlimited (fast forward) mode after starting.\n");
|
||||
#ifdef ENABLE_RAINTEGRATION
|
||||
std::fprintf(stderr, " -raintegration: Use RAIntegration instead of built-in achievement support.\n");
|
||||
#endif
|
||||
@@ -2241,6 +2242,16 @@ bool QtHost::ParseCommandLineOptions(const QStringList& args, std::shared_ptr<VM
|
||||
s_cleanup_after_update = AutoUpdaterDialog::isSupported();
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG(QStringLiteral("-turbo")))
|
||||
{
|
||||
AutoBoot(autoboot)->start_turbo = true;
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG(QStringLiteral("-unlimited")))
|
||||
{
|
||||
AutoBoot(autoboot)->start_unlimited = true;
|
||||
continue;
|
||||
}
|
||||
#ifdef ENABLE_RAINTEGRATION
|
||||
else if (CHECK_ARG(QStringLiteral("-raintegration")))
|
||||
{
|
||||
@@ -2276,6 +2287,12 @@ bool QtHost::ParseCommandLineOptions(const QStringList& args, std::shared_ptr<VM
|
||||
Console.Warning("Skipping autoboot due to no boot parameters.");
|
||||
autoboot.reset();
|
||||
}
|
||||
|
||||
if(autoboot && autoboot->start_turbo.value_or(false) && autoboot->start_unlimited.value_or(false))
|
||||
{
|
||||
Console.Warning("Both turbo and unlimited frame limit modes requested. Using unlimited.");
|
||||
autoboot->start_turbo.reset();
|
||||
}
|
||||
|
||||
// if we don't have autoboot, we definitely don't want batch mode (because that'll skip
|
||||
// scanning the game list).
|
||||
|
||||
@@ -1357,8 +1357,18 @@ namespace SettingWidgetBinder
|
||||
widget->connect(widget, &QLineEdit::editingFinished, widget, std::move(value_changed));
|
||||
}
|
||||
|
||||
// No need to pass a section or key since this is only used once and has six keys associated with it
|
||||
static inline void BindWidgetToDateTimeSetting(SettingsInterface* sif, QDateTimeEdit* widget, std::string section)
|
||||
struct DateTimeKeys
|
||||
{
|
||||
const char* year = nullptr;
|
||||
const char* month = nullptr;
|
||||
const char* day = nullptr;
|
||||
const char* hour = nullptr;
|
||||
const char* minute = nullptr;
|
||||
const char* second = nullptr;
|
||||
};
|
||||
|
||||
static inline void BindWidgetToDateTimeSetting(
|
||||
SettingsInterface* sif, QDateTimeEdit* widget, std::string section, const DateTimeKeys& keys)
|
||||
{
|
||||
using Accessor = SettingAccessor<QDateTimeEdit>;
|
||||
|
||||
@@ -1370,58 +1380,36 @@ namespace SettingWidgetBinder
|
||||
const int DEFAULT_MINUTE = 0;
|
||||
const int DEFAULT_SECOND = 0;
|
||||
|
||||
const char* YEAR_KEY = "RtcYear";
|
||||
const char* MONTH_KEY = "RtcMonth";
|
||||
const char* DAY_KEY = "RtcDay";
|
||||
const char* HOUR_KEY = "RtcHour";
|
||||
const char* MINUTE_KEY = "RtcMinute";
|
||||
const char* SECOND_KEY = "RtcSecond";
|
||||
|
||||
// Fetch settings from .ini
|
||||
const s32 year_value =
|
||||
Host::GetBaseIntSettingValue(section.c_str(), YEAR_KEY, static_cast<s32>(DEFAULT_YEAR));
|
||||
const s32 month_value =
|
||||
Host::GetBaseIntSettingValue(section.c_str(), MONTH_KEY, static_cast<s32>(DEFAULT_MONTH));
|
||||
const s32 day_value =
|
||||
Host::GetBaseIntSettingValue(section.c_str(), DAY_KEY, static_cast<s32>(DEFAULT_DAY));
|
||||
const s32 hour_value =
|
||||
Host::GetBaseIntSettingValue(section.c_str(), HOUR_KEY, static_cast<s32>(DEFAULT_HOUR));
|
||||
const s32 minute_value =
|
||||
Host::GetBaseIntSettingValue(section.c_str(), MINUTE_KEY, static_cast<s32>(DEFAULT_MINUTE));
|
||||
const s32 second_value =
|
||||
Host::GetBaseIntSettingValue(section.c_str(), SECOND_KEY, static_cast<s32>(DEFAULT_SECOND));
|
||||
const int year_value = Host::GetBaseIntSettingValue(section.c_str(), keys.year, DEFAULT_YEAR);
|
||||
const int month_value = Host::GetBaseIntSettingValue(section.c_str(), keys.month, DEFAULT_MONTH);
|
||||
const int day_value = Host::GetBaseIntSettingValue(section.c_str(), keys.day, DEFAULT_DAY);
|
||||
const int hour_value = Host::GetBaseIntSettingValue(section.c_str(), keys.hour, DEFAULT_HOUR);
|
||||
const int minute_value = Host::GetBaseIntSettingValue(section.c_str(), keys.minute, DEFAULT_MINUTE);
|
||||
const int second_value = Host::GetBaseIntSettingValue(section.c_str(), keys.second, DEFAULT_SECOND);
|
||||
|
||||
if (sif)
|
||||
{
|
||||
int sif_year_value = DEFAULT_YEAR;
|
||||
int sif_month_value = DEFAULT_MONTH;
|
||||
int sif_day_value = DEFAULT_DAY;
|
||||
int sif_hour_value = DEFAULT_HOUR;
|
||||
int sif_minute_value = DEFAULT_MINUTE;
|
||||
int sif_second_value = DEFAULT_SECOND;
|
||||
|
||||
// Get Settings Interface values or default if that fails
|
||||
if (!sif->GetIntValue(section.c_str(), YEAR_KEY, &sif_year_value)) { sif_year_value = DEFAULT_YEAR; }
|
||||
if (!sif->GetIntValue(section.c_str(), MONTH_KEY, &sif_month_value)) { sif_month_value = DEFAULT_MONTH; }
|
||||
if (!sif->GetIntValue(section.c_str(), DAY_KEY, &sif_day_value)) { sif_day_value = DEFAULT_DAY; }
|
||||
if (!sif->GetIntValue(section.c_str(), HOUR_KEY, &sif_hour_value)) { sif_hour_value = DEFAULT_HOUR; }
|
||||
if (!sif->GetIntValue(section.c_str(), MINUTE_KEY, &sif_minute_value)) { sif_minute_value = DEFAULT_MINUTE; }
|
||||
if (!sif->GetIntValue(section.c_str(), SECOND_KEY, &sif_second_value)) { sif_second_value = DEFAULT_SECOND; }
|
||||
int sif_year_value = sif->GetIntValue(section.c_str(), keys.year, DEFAULT_YEAR);
|
||||
int sif_month_value = sif->GetIntValue(section.c_str(), keys.month, DEFAULT_MONTH);
|
||||
int sif_day_value = sif->GetIntValue(section.c_str(), keys.day, DEFAULT_DAY);
|
||||
int sif_hour_value = sif->GetIntValue(section.c_str(), keys.hour, DEFAULT_HOUR);
|
||||
int sif_minute_value = sif->GetIntValue(section.c_str(), keys.minute, DEFAULT_MINUTE);
|
||||
int sif_second_value = sif->GetIntValue(section.c_str(), keys.second, DEFAULT_SECOND);
|
||||
|
||||
// No need to check for valid date since QDateTime resets to minimum upon becoming invalid
|
||||
Accessor::setDateTime(widget, QDate(static_cast<int>(sif_year_value + YEAR_OFFSET), static_cast<int>(sif_month_value), static_cast<int>(sif_day_value)),
|
||||
QTime(static_cast<int>(sif_hour_value), static_cast<int>(sif_minute_value), static_cast<int>(sif_second_value)));
|
||||
QDate date(sif_year_value + YEAR_OFFSET, sif_month_value, sif_day_value);
|
||||
QTime time(sif_hour_value, sif_minute_value, sif_second_value);
|
||||
Accessor::setDateTime(widget, date, time);
|
||||
|
||||
// Update the settings interface and reload the game settings when changed
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), YEAR_KEY = std::move(YEAR_KEY), MONTH_KEY = std::move(MONTH_KEY),
|
||||
DAY_KEY = std::move(DAY_KEY), HOUR_KEY = std::move(HOUR_KEY), MINUTE_KEY = std::move(MINUTE_KEY), SECOND_KEY = std::move(SECOND_KEY), YEAR_OFFSET = std::move(YEAR_OFFSET)]() {
|
||||
|
||||
sif->SetIntValue(section.c_str(), YEAR_KEY, Accessor::getYear(widget) - YEAR_OFFSET);
|
||||
sif->SetIntValue(section.c_str(), MONTH_KEY, Accessor::getMonth(widget));
|
||||
sif->SetIntValue(section.c_str(), DAY_KEY, Accessor::getDay(widget));
|
||||
sif->SetIntValue(section.c_str(), HOUR_KEY, Accessor::getHour(widget));
|
||||
sif->SetIntValue(section.c_str(), MINUTE_KEY, Accessor::getMinute(widget));
|
||||
sif->SetIntValue(section.c_str(), SECOND_KEY, Accessor::getSecond(widget));
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), keys]() {
|
||||
sif->SetIntValue(section.c_str(), keys.year, Accessor::getYear(widget) - YEAR_OFFSET);
|
||||
sif->SetIntValue(section.c_str(), keys.month, Accessor::getMonth(widget));
|
||||
sif->SetIntValue(section.c_str(), keys.day, Accessor::getDay(widget));
|
||||
sif->SetIntValue(section.c_str(), keys.hour, Accessor::getHour(widget));
|
||||
sif->SetIntValue(section.c_str(), keys.minute, Accessor::getMinute(widget));
|
||||
sif->SetIntValue(section.c_str(), keys.second, Accessor::getSecond(widget));
|
||||
|
||||
QtHost::SaveGameSettings(sif, true);
|
||||
g_emu_thread->reloadGameSettings();
|
||||
@@ -1431,13 +1419,12 @@ namespace SettingWidgetBinder
|
||||
else
|
||||
{
|
||||
// No need to check for valid date since QDateTime resets to minimum upon becoming invalid
|
||||
Accessor::setDateTime(widget, QDate(static_cast<int>(year_value + YEAR_OFFSET), static_cast<int>(month_value), static_cast<int>(day_value)),
|
||||
QTime(static_cast<int>(hour_value), static_cast<int>(minute_value), static_cast<int>(second_value)));
|
||||
QDate date(year_value + YEAR_OFFSET, month_value, day_value);
|
||||
QTime time(hour_value, minute_value, second_value);
|
||||
Accessor::setDateTime(widget, date, time);
|
||||
|
||||
// Update and apply base settings with values from widget when user changes it in UI
|
||||
Accessor::connectValueChanged(widget, [widget, section = std::move(section), YEAR_KEY = std::move(YEAR_KEY), MONTH_KEY = std::move(MONTH_KEY),
|
||||
DAY_KEY = std::move(DAY_KEY), HOUR_KEY = std::move(HOUR_KEY), MINUTE_KEY = std::move(MINUTE_KEY), SECOND_KEY = std::move(SECOND_KEY), YEAR_OFFSET = std::move(YEAR_OFFSET)]() {
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section = std::move(section), keys]() {
|
||||
const int new_year_value = Accessor::getYear(widget);
|
||||
const int new_month_value = Accessor::getMonth(widget);
|
||||
const int new_day_value = Accessor::getDay(widget);
|
||||
@@ -1445,16 +1432,15 @@ namespace SettingWidgetBinder
|
||||
const int new_minute_value = Accessor::getMinute(widget);
|
||||
const int new_second_value = Accessor::getSecond(widget);
|
||||
|
||||
Host::SetBaseIntSettingValue(section.c_str(), YEAR_KEY, new_year_value - YEAR_OFFSET);
|
||||
Host::SetBaseIntSettingValue(section.c_str(), MONTH_KEY, new_month_value);
|
||||
Host::SetBaseIntSettingValue(section.c_str(), DAY_KEY, new_day_value);
|
||||
Host::SetBaseIntSettingValue(section.c_str(), HOUR_KEY, new_hour_value);
|
||||
Host::SetBaseIntSettingValue(section.c_str(), MINUTE_KEY, new_minute_value);
|
||||
Host::SetBaseIntSettingValue(section.c_str(), SECOND_KEY, new_second_value);
|
||||
Host::SetBaseIntSettingValue(section.c_str(), keys.year, new_year_value - YEAR_OFFSET);
|
||||
Host::SetBaseIntSettingValue(section.c_str(), keys.month, new_month_value);
|
||||
Host::SetBaseIntSettingValue(section.c_str(), keys.day, new_day_value);
|
||||
Host::SetBaseIntSettingValue(section.c_str(), keys.hour, new_hour_value);
|
||||
Host::SetBaseIntSettingValue(section.c_str(), keys.minute, new_minute_value);
|
||||
Host::SetBaseIntSettingValue(section.c_str(), keys.second, new_second_value);
|
||||
Host::CommitBaseSettingChanges();
|
||||
g_emu_thread->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace SettingWidgetBinder
|
||||
|
||||
@@ -133,19 +133,19 @@ void AchievementLoginDialog::processLoginResult(bool result, const QString& mess
|
||||
QMessageBox::information(
|
||||
this, tr("Login Successful"),
|
||||
tr("Successfully logged in to RetroAchievements as %1.").arg(QString::fromStdString(username)));
|
||||
|
||||
|
||||
m_ui.status->setText(tr("Successfully logged in as %1.").arg(QString::fromStdString(username)));
|
||||
m_ui.status->setStyleSheet("color: green; font-weight: bold;");
|
||||
|
||||
|
||||
disconnect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, &AchievementLoginDialog::loginClicked);
|
||||
|
||||
|
||||
m_login->setVisible(false);
|
||||
QPushButton* dismissButton = m_ui.buttonBox->addButton(tr("&Dismiss"), QDialogButtonBox::AcceptRole);
|
||||
dismissButton->setDefault(true);
|
||||
dismissButton->setFocus();
|
||||
|
||||
|
||||
connect(dismissButton, &QPushButton::clicked, this, [this]() { done(0); });
|
||||
|
||||
|
||||
enableUI(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -214,8 +214,8 @@ void AchievementSettingsWidget::updateLoginState()
|
||||
StringUtil::FromChars<u64>(Host::GetBaseStringSettingValue("Achievements", "LoginTimestamp", "0")).value_or(0);
|
||||
const QDateTime login_timestamp(QDateTime::fromSecsSinceEpoch(static_cast<qint64>(login_unix_timestamp)));
|
||||
m_ui.loginStatus->setText(tr("Username: %1\nLogin token generated on %2.")
|
||||
.arg(QString::fromStdString(username))
|
||||
.arg(login_timestamp.toString(Qt::TextDate)));
|
||||
.arg(QString::fromStdString(username))
|
||||
.arg(login_timestamp.toString(Qt::TextDate)));
|
||||
m_ui.loginButton->setText(tr("Logout"));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -262,17 +262,17 @@ void AudioSettingsWidget::updateLatencyLabel()
|
||||
if (expand_buffer_ms > 0)
|
||||
{
|
||||
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (%2 ms buffer + %3 ms expand + %4 ms output)")
|
||||
.arg(config_buffer_ms + expand_buffer_ms + output_latency_ms)
|
||||
.arg(config_buffer_ms)
|
||||
.arg(expand_buffer_ms)
|
||||
.arg(output_latency_ms));
|
||||
.arg(config_buffer_ms + expand_buffer_ms + output_latency_ms)
|
||||
.arg(config_buffer_ms)
|
||||
.arg(expand_buffer_ms)
|
||||
.arg(output_latency_ms));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (%2 ms buffer + %3 ms output)")
|
||||
.arg(config_buffer_ms + output_latency_ms)
|
||||
.arg(config_buffer_ms)
|
||||
.arg(output_latency_ms));
|
||||
.arg(config_buffer_ms + output_latency_ms)
|
||||
.arg(config_buffer_ms)
|
||||
.arg(output_latency_ms));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -280,8 +280,8 @@ void AudioSettingsWidget::updateLatencyLabel()
|
||||
if (expand_buffer_ms > 0)
|
||||
{
|
||||
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (%2 ms expand, minimum output latency unknown)")
|
||||
.arg(expand_buffer_ms + config_buffer_ms)
|
||||
.arg(expand_buffer_ms));
|
||||
.arg(expand_buffer_ms + config_buffer_ms)
|
||||
.arg(expand_buffer_ms));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -203,7 +203,7 @@ void ControllerBindingWidget::onAutomaticBindingClicked()
|
||||
{
|
||||
// we set it as data, because the device list could get invalidated while the menu is up
|
||||
QAction* action;
|
||||
if(dev.first.compare(dev.second, Qt::CaseInsensitive) == 0)
|
||||
if (dev.first.compare(dev.second, Qt::CaseInsensitive) == 0)
|
||||
action = menu.addAction(dev.first);
|
||||
else
|
||||
action = menu.addAction(QStringLiteral("%1: %2").arg(dev.first).arg(dev.second));
|
||||
@@ -1157,7 +1157,7 @@ void USBDeviceWidget::onAutomaticBindingClicked()
|
||||
{
|
||||
// we set it as data, because the device list could get invalidated while the menu is up
|
||||
QAction* action;
|
||||
if(dev.first.compare(dev.second, Qt::CaseInsensitive) == 0)
|
||||
if (dev.first.compare(dev.second, Qt::CaseInsensitive) == 0)
|
||||
action = menu.addAction(dev.first);
|
||||
else
|
||||
action = menu.addAction(QStringLiteral("%1: %2").arg(dev.first).arg(dev.second));
|
||||
|
||||
@@ -88,7 +88,7 @@ ControllerGlobalSettingsWidget::~ControllerGlobalSettingsWidget() = default;
|
||||
void ControllerGlobalSettingsWidget::addDeviceToList(const QString& identifier, const QString& name)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem();
|
||||
if(identifier.compare(name,Qt::CaseInsensitive) == 0)
|
||||
if (identifier.compare(name, Qt::CaseInsensitive) == 0)
|
||||
item->setText(identifier);
|
||||
else
|
||||
item->setText(QStringLiteral("%1: %2").arg(identifier).arg(name));
|
||||
|
||||
@@ -89,10 +89,10 @@ void ControllerSettingsWindow::onCurrentProfileChanged(int index)
|
||||
|
||||
void ControllerSettingsWindow::onNewProfileClicked()
|
||||
{
|
||||
const QString profile_name(QInputDialog::getText(this, tr("Create Input Profile"),
|
||||
tr("Custom input profiles are used to override the Shared input profile for specific games.\n"
|
||||
"To apply a custom input profile to a game, go to its Game Properties, then change the 'Input Profile' on the Summary tab.\n\n"
|
||||
"Enter the name for the new input profile:")));
|
||||
const QString profile_name(QInputDialog::getText(this, tr("Create Input Profile"),
|
||||
tr("Custom input profiles are used to override the Shared input profile for specific games.\n"
|
||||
"To apply a custom input profile to a game, go to its Game Properties, then change the 'Input Profile' on the Summary tab.\n\n"
|
||||
"Enter the name for the new input profile:")));
|
||||
if (profile_name.isEmpty())
|
||||
return;
|
||||
|
||||
@@ -457,10 +457,16 @@ void ControllerSettingsWindow::createWidgets()
|
||||
const QString display_name(QString::fromUtf8(ci ? ci->GetLocalizedName() : "Unknown"));
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem();
|
||||
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
|
||||
item->setText(mtap_enabled[port] ? (tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name))
|
||||
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
|
||||
: tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
|
||||
if (mtap_enabled[port])
|
||||
{
|
||||
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
|
||||
item->setText(tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
|
||||
item->setText(tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
|
||||
}
|
||||
item->setIcon(m_port_bindings[global_slot]->getIcon());
|
||||
item->setData(Qt::UserRole, QVariant(global_slot));
|
||||
m_ui.settingsCategory->addItem(item);
|
||||
@@ -513,10 +519,16 @@ void ControllerSettingsWindow::updateListDescription(u32 global_slot, Controller
|
||||
const Pad::ControllerInfo* ci = Pad::GetControllerInfo(widget->getControllerType());
|
||||
const QString display_name = QString::fromUtf8(ci ? ci->GetLocalizedName() : "Unknown");
|
||||
|
||||
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
|
||||
item->setText(mtap_enabled ? (tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name))
|
||||
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
|
||||
: tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
|
||||
if (mtap_enabled)
|
||||
{
|
||||
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
|
||||
item->setText(tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
|
||||
item->setText(tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
|
||||
}
|
||||
item->setIcon(widget->getIcon());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -92,6 +92,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="saveHWConfig">
|
||||
<property name="text">
|
||||
<string>Save HW Config</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
|
||||
@@ -112,6 +112,7 @@ DebugSettingsWidget::DebugSettingsWidget(SettingsWindow* settings_dialog, QWidge
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_gs.saveTransferImages, "EmuCore/GS", "SaveTransferImages", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_gs.saveDrawStats, "EmuCore/GS", "SaveDrawStats", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_gs.saveFrameStats, "EmuCore/GS", "SaveFrameStats", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_gs.saveHWConfig, "EmuCore/GS", "SaveHWConfig", false);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_gs.saveDrawStart, "EmuCore/GS", "SaveDrawStart", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_gs.saveDrawCount, "EmuCore/GS", "SaveDrawCount", 5000);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_gs.saveFrameStart, "EmuCore/GS", "SaveFrameStart", 0);
|
||||
@@ -219,6 +220,7 @@ void DebugSettingsWidget::onDrawDumpingChanged()
|
||||
m_gs.saveTransferImages->setEnabled(enabled);
|
||||
m_gs.saveDrawStats->setEnabled(enabled);
|
||||
m_gs.saveFrameStats->setEnabled(enabled);
|
||||
m_gs.saveHWConfig->setEnabled(enabled);
|
||||
m_gs.saveDrawStart->setEnabled(enabled);
|
||||
m_gs.saveDrawCount->setEnabled(enabled);
|
||||
m_gs.saveFrameStart->setEnabled(enabled);
|
||||
|
||||
@@ -47,7 +47,15 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsWindow* settings_dialog
|
||||
|
||||
if (dialog()->isPerGameSettings())
|
||||
{
|
||||
SettingWidgetBinder::BindWidgetToDateTimeSetting(sif, m_ui.rtcDateTime, "EmuCore");
|
||||
SettingWidgetBinder::DateTimeKeys rtc_keys;
|
||||
rtc_keys.year = "RtcYear";
|
||||
rtc_keys.month = "RtcMonth";
|
||||
rtc_keys.day = "RtcDay";
|
||||
rtc_keys.hour = "RtcHour";
|
||||
rtc_keys.minute = "RtcMinute";
|
||||
rtc_keys.second = "RtcSecond";
|
||||
|
||||
SettingWidgetBinder::BindWidgetToDateTimeSetting(sif, m_ui.rtcDateTime, "EmuCore", rtc_keys);
|
||||
m_ui.rtcDateTime->setDateRange(QDate(2000, 1, 1), QDate(2099, 12, 31));
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.manuallySetRealTimeClock, "EmuCore", "ManuallySetRealTimeClock", false);
|
||||
connect(m_ui.manuallySetRealTimeClock, &QCheckBox::checkStateChanged, this, &EmulationSettingsWidget::onManuallySetRealTimeClockChanged);
|
||||
|
||||
@@ -25,7 +25,7 @@ FolderSettingsWidget::FolderSettingsWidget(SettingsWindow* settings_dialog, QWid
|
||||
SettingWidgetBinder::BindWidgetToFolderSetting(sif, m_ui.videoDumpingDirectory, m_ui.videoDumpingDirectoryBrowse, m_ui.videoDumpingDirectoryOpen, m_ui.videoDumpingDirectoryReset,
|
||||
"Folders", "Videos", Path::Combine(EmuFolders::DataRoot, "videos"));
|
||||
dialog()->registerWidgetHelp(m_ui.organizeSnapshotsByGame, tr("Organize Snapshots by Game"), tr("Unchecked"),
|
||||
tr("Saves snapshots to per-game subfolders instead of a shared folder."));
|
||||
tr("Saves snapshots to per-game subfolders instead of a shared folder."));
|
||||
}
|
||||
|
||||
FolderSettingsWidget::~FolderSettingsWidget() = default;
|
||||
|
||||
@@ -118,9 +118,8 @@ void GameCheatSettingsWidget::onCheatListItemHovered(const QModelIndex& index)
|
||||
const QModelIndex source_index = m_model_proxy->mapToSource(index);
|
||||
const QModelIndex sibling_index = source_index.siblingAtColumn(0);
|
||||
QStandardItem* item = m_model->itemFromIndex(sibling_index);
|
||||
if (!item)
|
||||
if (!item || !item->isCheckable())
|
||||
{
|
||||
// No item is selected.
|
||||
m_ui.appliedLabel->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -342,15 +342,15 @@ void GameSummaryWidget::onVerifyClicked()
|
||||
if (!hentry->version.empty())
|
||||
{
|
||||
setVerifyResult(tr("Verified as %1 [%2] (Version %3).")
|
||||
.arg(QString::fromStdString(hentry->name))
|
||||
.arg(QString::fromStdString(hentry->serial))
|
||||
.arg(QString::fromStdString(hentry->version)));
|
||||
.arg(QString::fromStdString(hentry->name))
|
||||
.arg(QString::fromStdString(hentry->serial))
|
||||
.arg(QString::fromStdString(hentry->version)));
|
||||
}
|
||||
else
|
||||
{
|
||||
setVerifyResult(tr("Verified as %1 [%2].")
|
||||
.arg(QString::fromStdString(hentry->name))
|
||||
.arg(QString::fromStdString(hentry->serial)));
|
||||
.arg(QString::fromStdString(hentry->name))
|
||||
.arg(QString::fromStdString(hentry->serial)));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -11,7 +11,7 @@ class HddCreateQt : public HddCreate
|
||||
{
|
||||
public:
|
||||
HddCreateQt(QWidget* parent);
|
||||
virtual ~HddCreateQt(){};
|
||||
virtual ~HddCreateQt() {}
|
||||
|
||||
private:
|
||||
QWidget* m_parent;
|
||||
|
||||
@@ -197,8 +197,8 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* settings_dialog
|
||||
"and unpauses when you switch back."));
|
||||
dialog()->registerWidgetHelp(m_ui.pauseOnControllerDisconnection, tr("Pause On Controller Disconnection"),
|
||||
tr("Unchecked"), tr("Pauses the emulator when a controller with bindings is disconnected."));
|
||||
dialog()->registerWidgetHelp(m_ui.promptOnStateLoadSaveFailure, tr("Pause On State Load/Save Failure"),
|
||||
tr("Checked"), tr("Display a modal dialog when a save state load/save operation fails."));
|
||||
dialog()->registerWidgetHelp(m_ui.promptOnStateLoadSaveFailure, tr("Prompt On State Load/Save Failure"),
|
||||
tr("Checked"), tr("Displays a modal dialog when a save state load/save operation fails."));
|
||||
dialog()->registerWidgetHelp(m_ui.startFullscreen, tr("Start Fullscreen"), tr("Unchecked"),
|
||||
tr("Automatically switches to fullscreen mode when a game is started."));
|
||||
dialog()->registerWidgetHelp(m_ui.hideMouseCursor, tr("Hide Cursor In Fullscreen"), tr("Unchecked"),
|
||||
|
||||
@@ -37,41 +37,39 @@ MemoryCardConvertDialog::MemoryCardConvertDialog(QWidget* parent, QString select
|
||||
m_ui.progressBar->setRange(0, 100);
|
||||
m_ui.progressBar->setValue(0);
|
||||
|
||||
connect(m_ui.conversionTypeSelect, &QComboBox::currentIndexChanged, this, [this]()
|
||||
connect(m_ui.conversionTypeSelect, &QComboBox::currentIndexChanged, this, [this]() {
|
||||
switch (m_srcCardInfo.type)
|
||||
{
|
||||
switch (m_srcCardInfo.type)
|
||||
{
|
||||
case MemoryCardType::File:
|
||||
SetType(MemoryCardType::Folder, MemoryCardFileType::Unknown, tr("Uses a folder on your PC filesystem, instead of a file. Infinite capacity, while keeping the same compatibility as an 8 MB Memory Card."));
|
||||
break;
|
||||
case MemoryCardType::Folder:
|
||||
switch (m_ui.conversionTypeSelect->currentData().toInt())
|
||||
{
|
||||
case 8:
|
||||
SetType(MemoryCardType::File, MemoryCardFileType::PS2_8MB, tr("A standard, 8 MB Memory Card. Most compatible, but smallest capacity."));
|
||||
break;
|
||||
case 16:
|
||||
SetType(MemoryCardType::File, MemoryCardFileType::PS2_16MB, tr("2x larger than a standard Memory Card. May have some compatibility issues."));
|
||||
break;
|
||||
case 32:
|
||||
SetType(MemoryCardType::File, MemoryCardFileType::PS2_32MB, tr("4x larger than a standard Memory Card. Likely to have compatibility issues."));
|
||||
break;
|
||||
case 64:
|
||||
SetType(MemoryCardType::File, MemoryCardFileType::PS2_64MB, tr("8x larger than a standard Memory Card. Likely to have compatibility issues."));
|
||||
break;
|
||||
default:
|
||||
//: MemoryCardType should be left as-is.
|
||||
QMessageBox::critical(this, tr("Convert Memory Card Failed"), tr("Invalid MemoryCardType"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//: MemoryCardType should be left as-is.
|
||||
QMessageBox::critical(this, tr("Convert Memory Card Failed"), tr("Invalid MemoryCardType"));
|
||||
return;
|
||||
}
|
||||
case MemoryCardType::File:
|
||||
SetType(MemoryCardType::Folder, MemoryCardFileType::Unknown, tr("Uses a folder on your PC filesystem, instead of a file. Infinite capacity, while keeping the same compatibility as an 8 MB Memory Card."));
|
||||
break;
|
||||
case MemoryCardType::Folder:
|
||||
switch (m_ui.conversionTypeSelect->currentData().toInt())
|
||||
{
|
||||
case 8:
|
||||
SetType(MemoryCardType::File, MemoryCardFileType::PS2_8MB, tr("A standard, 8 MB Memory Card. Most compatible, but smallest capacity."));
|
||||
break;
|
||||
case 16:
|
||||
SetType(MemoryCardType::File, MemoryCardFileType::PS2_16MB, tr("2x larger than a standard Memory Card. May have some compatibility issues."));
|
||||
break;
|
||||
case 32:
|
||||
SetType(MemoryCardType::File, MemoryCardFileType::PS2_32MB, tr("4x larger than a standard Memory Card. Likely to have compatibility issues."));
|
||||
break;
|
||||
case 64:
|
||||
SetType(MemoryCardType::File, MemoryCardFileType::PS2_64MB, tr("8x larger than a standard Memory Card. Likely to have compatibility issues."));
|
||||
break;
|
||||
default:
|
||||
//: MemoryCardType should be left as-is.
|
||||
QMessageBox::critical(this, tr("Convert Memory Card Failed"), tr("Invalid MemoryCardType"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//: MemoryCardType should be left as-is.
|
||||
QMessageBox::critical(this, tr("Convert Memory Card Failed"), tr("Invalid MemoryCardType"));
|
||||
return;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
disconnect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, nullptr);
|
||||
|
||||
@@ -88,7 +86,6 @@ bool MemoryCardConvertDialog::IsSetup()
|
||||
|
||||
void MemoryCardConvertDialog::onStatusUpdated()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MemoryCardConvertDialog::onProgressUpdated(int value, int range)
|
||||
|
||||
@@ -64,4 +64,4 @@ namespace CardCapacity
|
||||
static constexpr size_t _16_MB = 0x3e80 * 512 * 2; //(0x3fa7 - 0x49) * 2 * 512;
|
||||
static constexpr size_t _32_MB = 0x7d00 * 512 * 2; //(0x7f67 - 0x89) * 2 * 512;
|
||||
static constexpr size_t _64_MB = 0xfde8 * 512 * 2; //(0xfee7 - 0x0109) * 2 * 512;
|
||||
}
|
||||
} // namespace CardCapacity
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "common/FileSystem.h"
|
||||
|
||||
MemoryCardConvertWorker::MemoryCardConvertWorker(QWidget* parent, MemoryCardType type, MemoryCardFileType fileType, const std::string& srcFileName, const std::string& destFileName)
|
||||
: QtAsyncProgressThread(parent)
|
||||
: QtAsyncProgressThread(parent)
|
||||
{
|
||||
this->type = type;
|
||||
this->fileType = fileType;
|
||||
|
||||
@@ -99,9 +99,8 @@ void MemoryCardCreateDialog::updateState()
|
||||
void MemoryCardCreateDialog::createCard()
|
||||
{
|
||||
const QString name = m_ui.name->text();
|
||||
const std::string name_str = QStringLiteral("%1.%2").arg(name)
|
||||
.arg((m_fileType == MemoryCardFileType::PS1) ? QStringLiteral("mcr") : QStringLiteral("ps2"))
|
||||
.toStdString();
|
||||
const QString type = (m_fileType == MemoryCardFileType::PS1) ? QStringLiteral("mcr") : QStringLiteral("ps2");
|
||||
const std::string name_str = QStringLiteral("%1.%2").arg(name).arg(type).toStdString();
|
||||
if (!Path::IsValidFileName(name_str, false))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Create Memory Card"),
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "ShortcutCreationDialog.h"
|
||||
#include "QtHost.h"
|
||||
#include <fmt/format.h>
|
||||
#include <QtWidgets/QButtonGroup>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include "common/Console.h"
|
||||
@@ -40,6 +41,12 @@ ShortcutCreationDialog::ShortcutCreationDialog(QWidget* parent, const QString& t
|
||||
m_ui.shortcutStartMenu->setText(tr("Application Launcher"));
|
||||
#endif
|
||||
|
||||
QButtonGroup* buttonGroup = new QButtonGroup(this);
|
||||
buttonGroup->setExclusive(true);
|
||||
buttonGroup->addButton(m_ui.fastForwardTurboOption);
|
||||
buttonGroup->addButton(m_ui.fastForwardUnlimitedOption);
|
||||
m_ui.fastForwardTurboOption->setChecked(true);
|
||||
|
||||
connect(m_ui.overrideBootELFButton, &QPushButton::clicked, [&]() {
|
||||
const QString path = QFileDialog::getOpenFileName(this, tr("Select ELF File"), QString(), tr("ELF Files (*.elf);;All Files (*.*)"));
|
||||
if (!path.isEmpty())
|
||||
@@ -60,6 +67,11 @@ ShortcutCreationDialog::ShortcutCreationDialog(QWidget* parent, const QString& t
|
||||
connect(m_ui.loadStateFileToggle, &QCheckBox::toggled, m_ui.loadStateFileBrowse, &QPushButton::setEnabled);
|
||||
connect(m_ui.bootOptionToggle, &QCheckBox::toggled, m_ui.bootOptionDropdown, &QPushButton::setEnabled);
|
||||
connect(m_ui.fullscreenMode, &QCheckBox::toggled, m_ui.fullscreenModeDropdown, &QPushButton::setEnabled);
|
||||
connect(m_ui.fastForwardOptionToggle, &QCheckBox::toggled, [this] {
|
||||
const bool enabled = m_ui.fastForwardOptionToggle->isChecked();
|
||||
m_ui.fastForwardTurboOption->setEnabled(enabled);
|
||||
m_ui.fastForwardUnlimitedOption->setEnabled(enabled);
|
||||
});
|
||||
|
||||
m_ui.loadStateIndex->setMaximum(VMManager::NUM_SAVE_STATE_SLOTS);
|
||||
|
||||
@@ -114,6 +126,14 @@ ShortcutCreationDialog::ShortcutCreationDialog(QWidget* parent, const QString& t
|
||||
if (m_ui.bigPictureModeToggle->isChecked())
|
||||
args.push_back("-bigpicture");
|
||||
|
||||
if (m_ui.fastForwardOptionToggle->isChecked())
|
||||
{
|
||||
if (m_ui.fastForwardTurboOption->isChecked())
|
||||
args.push_back("-turbo");
|
||||
else if (m_ui.fastForwardUnlimitedOption->isChecked())
|
||||
args.push_back("-unlimited");
|
||||
}
|
||||
|
||||
std::string custom_args = m_ui.customArgsInput->text().toStdString();
|
||||
|
||||
ShortcutCreationDialog::CreateShortcut(title.toStdString(), path.toStdString(), args, custom_args, m_ui.shortcutDesktop->isChecked());
|
||||
@@ -357,7 +377,6 @@ void ShortcutCreationDialog::CreateShortcut(const std::string name, const std::s
|
||||
{
|
||||
executable_path = "flatpak run net.pcsx2.PCSX2";
|
||||
icon_name = "net.pcsx2.PCSX2";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -395,9 +414,12 @@ void ShortcutCreationDialog::CreateShortcut(const std::string name, const std::s
|
||||
"Type=Application\n"
|
||||
"Terminal=false\n"
|
||||
"StartupWMClass=PCSX2\n"
|
||||
"Exec=" + final_args + "\n"
|
||||
"Name=" + clean_name + "\n"
|
||||
"Icon=" + icon_name + "\n"
|
||||
"Exec=" +
|
||||
final_args + "\n" +
|
||||
"Name=" +
|
||||
clean_name + "\n" +
|
||||
"Icon=" +
|
||||
icon_name + "\n" +
|
||||
"Categories=Game;Emulator;\n";
|
||||
std::string_view sv(file_content);
|
||||
|
||||
|
||||
@@ -20,28 +20,38 @@
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="displayOptionLabel">
|
||||
<property name="text">
|
||||
<string>Display Options</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="overrideBootELFToggle">
|
||||
<property name="text">
|
||||
<string>Override boot ELF:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="customArgsLabel">
|
||||
<property name="text">
|
||||
<string>Custom Arguments</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>customArgsInput</cstring>
|
||||
<item row="12" column="0" colspan="4">
|
||||
<widget class="QGroupBox" name="customArgsGroup">
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="customArgsGrid">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLineEdit" name="customArgsInput"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="customArgsInstruction">
|
||||
<property name="text">
|
||||
<string>You may add additional (space-separated) <a href="https://pcsx2.net/docs/advanced/cli/">custom arguments</a> that are not listed above here:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::TextFormat::RichText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextInteractionFlag::TextBrowserInteraction</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>customArgsInput</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="4">
|
||||
@@ -84,34 +94,10 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2" colspan="2">
|
||||
<widget class="QLineEdit" name="gameArgs">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2" colspan="2">
|
||||
<widget class="QComboBox" name="bootOptionDropdown">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Fast Boot</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Full Boot</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="bootOptionToggle">
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="fastForwardOptionToggle">
|
||||
<property name="text">
|
||||
<string>Boot mode:</string>
|
||||
<string>Fast Forward:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -125,13 +111,51 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="overrideBootELFPath">
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="displayOptionLabel">
|
||||
<property name="text">
|
||||
<string>Display Options</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="bootOptionToggle">
|
||||
<property name="text">
|
||||
<string>Boot mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="portableModeToggle">
|
||||
<property name="text">
|
||||
<string>Portable Mode (Stores data in local PCSX2 directory)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2" colspan="2">
|
||||
<widget class="QLineEdit" name="gameArgs">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="customArgsLabel">
|
||||
<property name="text">
|
||||
<string>Custom Arguments</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>customArgsInput</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="overrideBootELFToggle">
|
||||
<property name="text">
|
||||
<string>Override boot ELF:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="4">
|
||||
<widget class="QGroupBox" name="saveStateGroup">
|
||||
<property name="title">
|
||||
@@ -195,6 +219,13 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="overrideBootELFPath">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="saveStateLabel">
|
||||
<property name="text">
|
||||
@@ -209,45 +240,45 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="4">
|
||||
<widget class="QGroupBox" name="customArgsGroup">
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="customArgsGrid">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLineEdit" name="customArgsInput"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="customArgsInstruction">
|
||||
<property name="text">
|
||||
<string>You may add additional (space-separated) <a href="https://pcsx2.net/docs/advanced/cli/">custom arguments</a> that are not listed above here:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::TextFormat::RichText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextInteractionFlag::TextBrowserInteraction</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>customArgsInput</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<item row="5" column="2" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="fastForwardTurboOption">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Turbo</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="fastForwardUnlimitedOption">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unlimited</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="portableModeToggle">
|
||||
<property name="text">
|
||||
<string>Portable Mode (Stores data in local PCSX2 directory)</string>
|
||||
<item row="4" column="2" colspan="2">
|
||||
<widget class="QComboBox" name="bootOptionDropdown">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Fast Boot</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Full Boot</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -341,11 +341,12 @@ bool QtHost::DownloadMissingFont(QWidget* dialog_parent, const char* font_name,
|
||||
msgbox.setWindowModality(Qt::WindowModal);
|
||||
msgbox.setIcon(QMessageBox::Critical);
|
||||
msgbox.setTextFormat(Qt::RichText);
|
||||
msgbox.setText(qApp->translate("MainWindow",
|
||||
"The font file '%1' is required for the On-Screen Display and Big Picture Mode to show messages in your language.<br><br>"
|
||||
"Do you want to download this file now? These files are usually less than 10 megabytes in size.<br><br>"
|
||||
"<strong>If you do not download this file, on-screen messages will not be readable.</strong>")
|
||||
.arg(QLatin1StringView(font_name)));
|
||||
msgbox.setText(
|
||||
qApp->translate("MainWindow",
|
||||
"The font file '%1' is required for the On-Screen Display and Big Picture Mode to show messages in your language.<br><br>"
|
||||
"Do you want to download this file now? These files are usually less than 10 megabytes in size.<br><br>"
|
||||
"<strong>If you do not download this file, on-screen messages will not be readable.</strong>")
|
||||
.arg(QLatin1StringView(font_name)));
|
||||
msgbox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
if (msgbox.exec() != QMessageBox::Yes)
|
||||
return false;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -89,6 +89,7 @@
|
||||
<Manifest Include="..\pcsx2\windows\PCSX2.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AsyncDialogs.cpp" />
|
||||
<ClCompile Include="ColorPickerButton.cpp" />
|
||||
<ClCompile Include="Debugger\SymbolTree\NewSymbolDialogs.cpp" />
|
||||
<ClCompile Include="Debugger\SymbolTree\SymbolTreeDelegates.cpp" />
|
||||
@@ -183,6 +184,7 @@
|
||||
<ClCompile Include="VCRuntimeChecker.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AsyncDialogs.h" />
|
||||
<QtMoc Include="SetupWizardDialog.h" />
|
||||
<QtMoc Include="Settings\InterfaceSettingsWidget.h" />
|
||||
<QtMoc Include="Settings\GameListSettingsWidget.h" />
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="PrecompiledHeader.cpp" />
|
||||
<ClCompile Include="AsyncDialogs.cpp" />
|
||||
<ClCompile Include="QtHost.cpp" />
|
||||
<ClCompile Include="MainWindow.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_MainWindow.cpp">
|
||||
@@ -518,6 +519,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="PrecompiledHeader.h" />
|
||||
<ClInclude Include="AsyncDialogs.h" />
|
||||
<ClInclude Include="QtUtils.h" />
|
||||
<ClInclude Include="SettingWidgetBinder.h" />
|
||||
<ClInclude Include="Settings\HddCreateQt.h">
|
||||
|
||||
+331
-56
@@ -143,6 +143,7 @@ namespace Achievements
|
||||
static void HandleResetEvent(const rc_client_event_t* event);
|
||||
static void HandleUnlockEvent(const rc_client_event_t* event);
|
||||
static void HandleGameCompleteEvent(const rc_client_event_t* event);
|
||||
static void HandleSubsetCompleteEvent(const rc_client_event_t* event);
|
||||
static void HandleLeaderboardStartedEvent(const rc_client_event_t* event);
|
||||
static void HandleLeaderboardFailedEvent(const rc_client_event_t* event);
|
||||
static void HandleLeaderboardSubmittedEvent(const rc_client_event_t* event);
|
||||
@@ -169,6 +170,7 @@ namespace Achievements
|
||||
static void UpdateNotificationPosition();
|
||||
|
||||
static std::string GetAchievementBadgePath(const rc_client_achievement_t* achievement, int state);
|
||||
static std::string GetSubsetBadgePath(const rc_client_subset_t* subset);
|
||||
static std::string GetUserBadgePath(const std::string_view username);
|
||||
static std::string GetLeaderboardUserBadgePath(const rc_client_leaderboard_entry_t* entry);
|
||||
|
||||
@@ -176,6 +178,7 @@ namespace Achievements
|
||||
static void DrawLeaderboardListEntry(const rc_client_leaderboard_t* lboard);
|
||||
static void DrawLeaderboardEntry(const rc_client_leaderboard_entry_t& entry, bool is_self, float rank_column_width,
|
||||
float name_column_width, float time_column_width, float column_spacing);
|
||||
static void OpenSubset(const rc_client_subset_t* subset);
|
||||
static void OpenLeaderboard(const rc_client_leaderboard_t* lboard);
|
||||
static void LeaderboardFetchNearbyCallback(
|
||||
int result, const char* error_message, rc_client_leaderboard_entry_list_t* list, rc_client_t* client, void* callback_userdata);
|
||||
@@ -183,6 +186,7 @@ namespace Achievements
|
||||
int result, const char* error_message, rc_client_leaderboard_entry_list_t* list, rc_client_t* client, void* callback_userdata);
|
||||
static void FetchNextLeaderboardEntries();
|
||||
static void CloseLeaderboard();
|
||||
static void CloseSubset();
|
||||
|
||||
static bool s_hardcore_mode = false;
|
||||
|
||||
@@ -213,9 +217,11 @@ namespace Achievements
|
||||
static rc_client_async_handle_t* s_load_game_request;
|
||||
|
||||
static rc_client_achievement_list_t* s_achievement_list;
|
||||
static rc_client_subset_list_t* s_subset_list;
|
||||
static rc_client_leaderboard_list_t* s_leaderboard_list;
|
||||
static std::vector<std::pair<const void*, std::string>> s_achievement_badge_paths;
|
||||
static const rc_client_leaderboard_t* s_open_leaderboard = nullptr;
|
||||
static const rc_client_subset_t* s_open_subset = nullptr;
|
||||
static rc_client_async_handle_t* s_leaderboard_fetch_handle = nullptr;
|
||||
static std::vector<rc_client_leaderboard_entry_list_t*> s_leaderboard_entry_lists;
|
||||
static rc_client_leaderboard_entry_list_t* s_leaderboard_nearby_entries;
|
||||
@@ -820,6 +826,10 @@ void Achievements::ClientEventHandler(const rc_client_event_t* event, rc_client_
|
||||
HandleGameCompleteEvent(event);
|
||||
break;
|
||||
|
||||
case RC_CLIENT_EVENT_SUBSET_COMPLETED:
|
||||
HandleSubsetCompleteEvent(event);
|
||||
break;
|
||||
|
||||
case RC_CLIENT_EVENT_LEADERBOARD_STARTED:
|
||||
HandleLeaderboardStartedEvent(event);
|
||||
break;
|
||||
@@ -1211,6 +1221,33 @@ void Achievements::HandleGameCompleteEvent(const rc_client_event_t* event)
|
||||
}
|
||||
}
|
||||
|
||||
void Achievements::HandleSubsetCompleteEvent(const rc_client_event_t* event)
|
||||
{
|
||||
const rc_client_subset_t* subset = event->subset;
|
||||
Console.WriteLn("Achievements: Subset '%s' (%u) complete", subset->title, subset->id);
|
||||
UpdateGameSummary();
|
||||
|
||||
if (EmuConfig.Achievements.Notifications)
|
||||
{
|
||||
std::string title = fmt::format(TRANSLATE_FS("Achievements", "Mastered {}"), subset->title);
|
||||
std::string message = fmt::format(
|
||||
TRANSLATE_FS("Achievements", "{0}, {1}"),
|
||||
TRANSLATE_PLURAL_STR("Achievements", "%n achievements", "Mastery popup",
|
||||
s_game_summary.num_unlocked_achievements),
|
||||
TRANSLATE_PLURAL_STR("Achievements", "%n points", "Mastery popup", s_game_summary.points_unlocked));
|
||||
|
||||
std::string badge_path = GetSubsetBadgePath(subset);
|
||||
|
||||
MTGS::RunOnGSThread([title = std::move(title), message = std::move(message), badge_path = std::move(badge_path)]() {
|
||||
if (ImGuiManager::InitializeFullscreenUI())
|
||||
{
|
||||
ImGuiFullscreen::AddNotification(
|
||||
"achievement_subset_mastery", GAME_COMPLETE_NOTIFICATION_TIME, std::move(title), std::move(message), std::move(badge_path));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Achievements::HandleLeaderboardStartedEvent(const rc_client_event_t* event)
|
||||
{
|
||||
DevCon.WriteLn("Achievements: Leaderboard %u (%s) started", event->leaderboard->id, event->leaderboard->title);
|
||||
@@ -2333,6 +2370,15 @@ bool Achievements::PrepareAchievementsWindow()
|
||||
|
||||
s_achievement_badge_paths = {};
|
||||
|
||||
if (s_subset_list)
|
||||
{
|
||||
rc_client_destroy_subset_list(s_subset_list);
|
||||
s_subset_list = nullptr;
|
||||
}
|
||||
CloseSubset();
|
||||
|
||||
s_subset_list = rc_client_create_subset_list(s_client);
|
||||
|
||||
if (s_achievement_list)
|
||||
rc_client_destroy_achievement_list(s_achievement_list);
|
||||
s_achievement_list = rc_client_create_achievement_list(s_client, RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL,
|
||||
@@ -2360,6 +2406,9 @@ void Achievements::DrawAchievementsWindow()
|
||||
// ensure image downloads still happen while we're paused
|
||||
Achievements::IdleUpdate();
|
||||
|
||||
const bool has_multiple_subsets = (s_subset_list && s_subset_list->num_subsets > 1);
|
||||
bool s_sidebar_has_focus = false;
|
||||
|
||||
static constexpr float alpha = 0.8f;
|
||||
static constexpr float heading_alpha = 0.95f;
|
||||
static constexpr float heading_height_unscaled = 110.0f;
|
||||
@@ -2409,7 +2458,7 @@ void Achievements::DrawAchievementsWindow()
|
||||
}
|
||||
|
||||
const ImRect title_bb(ImVec2(left, top), ImVec2(right, top + g_large_font.second));
|
||||
text.assign(s_game_title);
|
||||
text.assign(s_open_subset ? s_open_subset->title : s_game_title);
|
||||
|
||||
if (s_hardcore_mode)
|
||||
text.append(TRANSLATE_SV("Achievements", " (Hardcore Mode)"));
|
||||
@@ -2421,18 +2470,28 @@ void Achievements::DrawAchievementsWindow()
|
||||
ImGui::PopFont();
|
||||
|
||||
const ImRect summary_bb(ImVec2(left, top), ImVec2(right, top + g_medium_font.second));
|
||||
if (s_game_summary.num_core_achievements > 0)
|
||||
UpdateGameSummary();
|
||||
|
||||
rc_client_user_game_summary_t display_summary = {};
|
||||
const rc_client_user_game_summary_t* summary_ptr = &s_game_summary;
|
||||
if (s_open_subset)
|
||||
{
|
||||
if (s_game_summary.num_unlocked_achievements == s_game_summary.num_core_achievements)
|
||||
rc_client_get_user_subset_summary(s_client, s_open_subset->id, &display_summary);
|
||||
summary_ptr = &display_summary;
|
||||
}
|
||||
|
||||
if (summary_ptr->num_core_achievements > 0)
|
||||
{
|
||||
if (summary_ptr->num_unlocked_achievements == summary_ptr->num_core_achievements)
|
||||
{
|
||||
text.format(TRANSLATE_FS("Achievements", "You have unlocked all achievements and earned {} points!"),
|
||||
s_game_summary.points_unlocked);
|
||||
summary_ptr->points_unlocked);
|
||||
}
|
||||
else
|
||||
{
|
||||
text.format(TRANSLATE_FS("Achievements", "You have unlocked {0} of {1} achievements, earning {2} of {3} possible points."),
|
||||
s_game_summary.num_unlocked_achievements, s_game_summary.num_core_achievements, s_game_summary.points_unlocked,
|
||||
s_game_summary.points_core);
|
||||
summary_ptr->num_unlocked_achievements, summary_ptr->num_core_achievements, summary_ptr->points_unlocked,
|
||||
summary_ptr->points_core);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2447,12 +2506,12 @@ void Achievements::DrawAchievementsWindow()
|
||||
summary_bb.Min, summary_bb.Max, text.c_str(), text.end_ptr(), nullptr, ImVec2(0.0f, 0.0f), &summary_bb);
|
||||
ImGui::PopFont();
|
||||
|
||||
if (s_game_summary.num_core_achievements > 0)
|
||||
if (summary_ptr->num_core_achievements > 0)
|
||||
{
|
||||
const float progress_height = ImGuiFullscreen::LayoutScale(20.0f);
|
||||
const ImRect progress_bb(ImVec2(left, top), ImVec2(right, top + progress_height));
|
||||
const float fraction =
|
||||
static_cast<float>(s_game_summary.num_unlocked_achievements) / static_cast<float>(s_game_summary.num_core_achievements);
|
||||
static_cast<float>(summary_ptr->num_unlocked_achievements) / static_cast<float>(summary_ptr->num_core_achievements);
|
||||
dl->AddRectFilled(progress_bb.Min, progress_bb.Max, ImGui::GetColorU32(ImGuiFullscreen::UIPrimaryDarkColor));
|
||||
dl->AddRectFilled(progress_bb.Min, ImVec2(progress_bb.Min.x + fraction * progress_bb.GetWidth(), progress_bb.Max.y),
|
||||
ImGui::GetColorU32(ImGuiFullscreen::UISecondaryColor));
|
||||
@@ -2473,68 +2532,203 @@ void Achievements::DrawAchievementsWindow()
|
||||
|
||||
ImGui::SetNextWindowBgAlpha(alpha);
|
||||
|
||||
const float sidebar_width = has_multiple_subsets ? LayoutScale(200.0f) : 0.0f;
|
||||
|
||||
if (has_multiple_subsets && !s_open_subset)
|
||||
{
|
||||
OpenSubset(s_subset_list->subsets[0]);
|
||||
}
|
||||
|
||||
if (ImGuiFullscreen::BeginFullscreenWindow(
|
||||
ImVec2(0.0f, heading_height),
|
||||
ImVec2(display_size.x, display_size.y - heading_height - LayoutScale(ImGuiFullscreen::LAYOUT_FOOTER_HEIGHT)),
|
||||
"achievements", background, 0.0f, ImVec2(ImGuiFullscreen::LAYOUT_MENU_WINDOW_X_PADDING, 0.0f), 0))
|
||||
"achievements", background, 0.0f, ImVec2(0.0f, 0.0f), 0))
|
||||
{
|
||||
static std::map<std::pair<u32, u32>, bool> buckets_collapsed;
|
||||
static const char* bucket_names[NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS] = {
|
||||
TRANSLATE_NOOP("Achievements", "Unknown"),
|
||||
TRANSLATE_NOOP("Achievements", "Locked"),
|
||||
TRANSLATE_NOOP("Achievements", "Unlocked"),
|
||||
TRANSLATE_NOOP("Achievements", "Unsupported"),
|
||||
TRANSLATE_NOOP("Achievements", "Unofficial"),
|
||||
TRANSLATE_NOOP("Achievements", "Recently Unlocked"),
|
||||
TRANSLATE_NOOP("Achievements", "Active Challenges"),
|
||||
TRANSLATE_NOOP("Achievements", "Almost There"),
|
||||
};
|
||||
|
||||
ImGuiFullscreen::BeginMenuButtons();
|
||||
|
||||
for (u32 bucket_type : {RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE, RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED,
|
||||
RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED, RC_CLIENT_ACHIEVEMENT_BUCKET_ALMOST_THERE, RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED,
|
||||
RC_CLIENT_ACHIEVEMENT_BUCKET_UNOFFICIAL, RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED})
|
||||
if (has_multiple_subsets)
|
||||
{
|
||||
for (u32 bucket_idx = 0; bucket_idx < s_achievement_list->num_buckets; bucket_idx++)
|
||||
const ImVec4 sidebar_bg(0.10f, 0.10f, 0.10f, alpha);
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, sidebar_bg);
|
||||
|
||||
if (ImGui::BeginChild("subset_sidebar", ImVec2(sidebar_width, 0.0f), ImGuiChildFlags_NavFlattened, 0))
|
||||
{
|
||||
const rc_client_achievement_bucket_t& bucket = s_achievement_list->buckets[bucket_idx];
|
||||
if (bucket.bucket_type != bucket_type)
|
||||
continue;
|
||||
ImGuiFullscreen::BeginMenuButtons();
|
||||
|
||||
pxAssert(bucket.bucket_type < NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS);
|
||||
|
||||
bool& bucket_collapsed = buckets_collapsed[std::make_pair(bucket.subset_id, bucket.bucket_type)];
|
||||
const char* translated_bucket_name = Host::TranslateToCString("Achievements", bucket_names[bucket.bucket_type]);
|
||||
|
||||
if (bucket.subset_id != 0)
|
||||
for (u32 i = 0; i < s_subset_list->num_subsets; i++)
|
||||
{
|
||||
const rc_client_subset_t* subset_info = rc_client_get_subset_info(s_client, bucket.subset_id);
|
||||
bucket_collapsed ^=
|
||||
ImGuiFullscreen::MenuHeadingButton(TinyString::from_format("{} - {}",
|
||||
subset_info != nullptr ? subset_info->title : TRANSLATE("Achievements", "Unknown Subset"),
|
||||
translated_bucket_name), bucket_collapsed ? ICON_FA_CHEVRON_DOWN : ICON_FA_CHEVRON_UP);
|
||||
const rc_client_subset_t* subset = s_subset_list->subsets[i];
|
||||
TinyString id_str;
|
||||
id_str.format("sidebar_subset_{}", subset->id);
|
||||
|
||||
ImRect bb;
|
||||
bool visible, hovered;
|
||||
ImGuiFullscreen::MenuButtonFrame(id_str, true, ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
|
||||
&visible, &hovered, &bb.Min, &bb.Max, 0, 1.0f);
|
||||
|
||||
if (ImGui::IsItemHovered() || ImGui::IsItemFocused())
|
||||
s_sidebar_has_focus = true;
|
||||
|
||||
const float padding = LayoutScale(10.0f);
|
||||
const float spacing = LayoutScale(8.0f);
|
||||
const float icon_size = LayoutScale(28.0f);
|
||||
|
||||
if (s_open_subset && s_open_subset->id == subset->id)
|
||||
{
|
||||
const float line_width = LayoutScale(4.0f);
|
||||
const ImVec2 line_min(bb.Min.x, bb.Min.y);
|
||||
const ImVec2 line_max(bb.Min.x + line_width, bb.Max.y);
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(line_min, line_max, IM_COL32(52, 152, 219, 255));
|
||||
}
|
||||
|
||||
const ImVec2 icon_min(bb.Min.x + padding, bb.Min.y + (bb.Max.y - bb.Min.y - icon_size) * 0.5f);
|
||||
const ImVec2 icon_max(icon_min.x + icon_size, icon_min.y + icon_size);
|
||||
|
||||
std::string badge_path = GetSubsetBadgePath(subset);
|
||||
if (!badge_path.empty())
|
||||
{
|
||||
GSTexture* badge = ImGuiFullscreen::GetCachedTextureAsync(badge_path);
|
||||
if (badge)
|
||||
{
|
||||
ImGui::GetWindowDrawList()->AddImage(reinterpret_cast<ImTextureID>(badge->GetNativeHandle()),
|
||||
icon_min, icon_max, ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), IM_COL32(255, 255, 255, 255));
|
||||
}
|
||||
}
|
||||
|
||||
const float text_x = icon_max.x + spacing;
|
||||
const ImRect text_bb(ImVec2(text_x, bb.Min.y), ImVec2(bb.Max.x - padding, bb.Max.y));
|
||||
|
||||
ImGui::PushFont(g_medium_font.first, g_medium_font.second);
|
||||
ImGui::RenderTextClipped(text_bb.Min, text_bb.Max, subset->title, nullptr, nullptr, ImVec2(0.0f, 0.5f), &text_bb);
|
||||
ImGui::PopFont();
|
||||
|
||||
if (ImGui::IsItemClicked() || ImGui::IsItemActivated())
|
||||
OpenSubset(subset);
|
||||
}
|
||||
else
|
||||
|
||||
ImGuiFullscreen::EndMenuButtons();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
if (ImGui::IsItemHovered() || ImGui::IsItemFocused())
|
||||
s_sidebar_has_focus = true;
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
const float content_width = has_multiple_subsets ? (display_size.x - sidebar_width) : display_size.x;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(ImGuiFullscreen::LAYOUT_MENU_WINDOW_X_PADDING, 0.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, background);
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetColorU32(ImGuiFullscreen::UIPrimaryDarkColor));
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImGui::GetColorU32(ImGuiFullscreen::UIPrimaryColor));
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImGui::GetColorU32(ImGuiFullscreen::UISecondaryColor));
|
||||
|
||||
if (ImGui::BeginChild("achievements_content", ImVec2(content_width, 0.0f), ImGuiChildFlags_NavFlattened, 0))
|
||||
{
|
||||
if (ImGui::IsWindowHovered() || ImGui::IsWindowFocused())
|
||||
s_sidebar_has_focus = false;
|
||||
|
||||
static std::map<std::pair<u32, u32>, bool> buckets_collapsed;
|
||||
static const char* bucket_names[NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS] = {
|
||||
TRANSLATE_NOOP("Achievements", "Unknown"),
|
||||
TRANSLATE_NOOP("Achievements", "Locked"),
|
||||
TRANSLATE_NOOP("Achievements", "Unlocked"),
|
||||
TRANSLATE_NOOP("Achievements", "Unsupported"),
|
||||
TRANSLATE_NOOP("Achievements", "Unofficial"),
|
||||
TRANSLATE_NOOP("Achievements", "Recently Unlocked"),
|
||||
TRANSLATE_NOOP("Achievements", "Active Challenges"),
|
||||
TRANSLATE_NOOP("Achievements", "Almost There"),
|
||||
};
|
||||
|
||||
ImGuiFullscreen::BeginMenuButtons();
|
||||
|
||||
for (u32 bucket_type : {RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE, RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED,
|
||||
RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED, RC_CLIENT_ACHIEVEMENT_BUCKET_ALMOST_THERE, RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED,
|
||||
RC_CLIENT_ACHIEVEMENT_BUCKET_UNOFFICIAL, RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED})
|
||||
{
|
||||
for (u32 bucket_idx = 0; bucket_idx < s_achievement_list->num_buckets; bucket_idx++)
|
||||
{
|
||||
// Game without subsets
|
||||
const rc_client_achievement_bucket_t& bucket = s_achievement_list->buckets[bucket_idx];
|
||||
if (bucket.bucket_type != bucket_type)
|
||||
continue;
|
||||
|
||||
if (s_open_subset && bucket.subset_id != 0 && bucket.subset_id != s_open_subset->id)
|
||||
continue;
|
||||
|
||||
pxAssert(bucket.bucket_type < NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS);
|
||||
|
||||
bool& bucket_collapsed = buckets_collapsed[std::make_pair(bucket.subset_id, bucket.bucket_type)];
|
||||
const char* translated_bucket_name = Host::TranslateToCString("Achievements", bucket_names[bucket.bucket_type]);
|
||||
|
||||
bucket_collapsed ^=
|
||||
ImGuiFullscreen::MenuHeadingButton(translated_bucket_name,
|
||||
bucket_collapsed ? ICON_FA_CHEVRON_DOWN : ICON_FA_CHEVRON_UP);
|
||||
}
|
||||
|
||||
if (!bucket_collapsed)
|
||||
{
|
||||
for (u32 i = 0; i < bucket.num_achievements; i++)
|
||||
DrawAchievement(bucket.achievements[i]);
|
||||
if (!bucket_collapsed)
|
||||
{
|
||||
for (u32 i = 0; i < bucket.num_achievements; i++)
|
||||
DrawAchievement(bucket.achievements[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiFullscreen::EndMenuButtons();
|
||||
ImGuiFullscreen::EndMenuButtons();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::PopStyleColor(4);
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
ImGuiFullscreen::EndFullscreenWindow();
|
||||
FullscreenUI::SetStandardSelectionFooterText(true);
|
||||
|
||||
if (has_multiple_subsets)
|
||||
{
|
||||
if (ImGuiFullscreen::IsGamepadInputSource())
|
||||
{
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
if (s_sidebar_has_focus)
|
||||
{
|
||||
ImGuiFullscreen::SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_DPAD_UP_DOWN, TRANSLATE_SV("Achievements", "Navigate Subsets")),
|
||||
std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, TRANSLATE_SV("Achievements", "Back to List")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, TRANSLATE_SV("Achievements", "Select")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, TRANSLATE_SV("Achievements", "Back")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiFullscreen::SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, TRANSLATE_SV("Achievements", "Navigate Subsets")),
|
||||
std::make_pair(ICON_PF_DPAD_UP_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, TRANSLATE_SV("Achievements", "Back")),
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_sidebar_has_focus)
|
||||
{
|
||||
ImGuiFullscreen::SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, TRANSLATE_SV("Achievements", "Navigate Subsets")),
|
||||
std::make_pair(ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, TRANSLATE_SV("Achievements", "Back to List")),
|
||||
std::make_pair(ICON_PF_ENTER, TRANSLATE_SV("Achievements", "Select")),
|
||||
std::make_pair(ICON_PF_ESC, TRANSLATE_SV("Achievements", "Back")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiFullscreen::SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, TRANSLATE_SV("Achievements", "Navigate Subsets")),
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_ESC, TRANSLATE_SV("Achievements", "Back")),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FullscreenUI::SetStandardSelectionFooterText(true);
|
||||
}
|
||||
}
|
||||
|
||||
void Achievements::DrawAchievement(const rc_client_achievement_t* cheevo)
|
||||
@@ -2610,23 +2804,36 @@ void Achievements::DrawAchievement(const rc_client_achievement_t* cheevo)
|
||||
const float points_start = points_template_start + ((points_template_size.x - points_size.x) * 0.5f);
|
||||
|
||||
const char* right_icon_text;
|
||||
const char* badge_text;
|
||||
const char* badge_icon;
|
||||
ImVec4 badge_color;
|
||||
switch (cheevo->type)
|
||||
{
|
||||
case RC_CLIENT_ACHIEVEMENT_TYPE_MISSABLE:
|
||||
right_icon_text = ICON_PF_ACHIEVEMENTS_MISSABLE; // Missable
|
||||
badge_text = TRANSLATE("Achievements", "Missable");
|
||||
badge_icon = ICON_PF_ACHIEVEMENTS_MISSABLE;
|
||||
badge_color = ImVec4(0.78f, 0.55f, 0.30f, 1.0f);
|
||||
right_icon_text = is_unlocked ? ICON_FA_LOCK_OPEN : ICON_FA_LOCK;
|
||||
break;
|
||||
|
||||
case RC_CLIENT_ACHIEVEMENT_TYPE_PROGRESSION:
|
||||
right_icon_text = ICON_PF_ACHIEVEMENTS_PROGRESSION; // Progression
|
||||
badge_text = TRANSLATE("Achievements", "Progression");
|
||||
badge_icon = ICON_PF_ACHIEVEMENTS_PROGRESSION;
|
||||
badge_color = ImVec4(0.62f, 0.48f, 0.80f, 1.0f);
|
||||
right_icon_text = is_unlocked ? ICON_FA_LOCK_OPEN : ICON_FA_LOCK;
|
||||
break;
|
||||
|
||||
case RC_CLIENT_ACHIEVEMENT_TYPE_WIN:
|
||||
right_icon_text = ICON_PF_ACHIEVEMENTS_WIN; // Win Condition
|
||||
badge_text = TRANSLATE("Achievements", "Win Condition");
|
||||
badge_icon = ICON_PF_ACHIEVEMENTS_WIN;
|
||||
badge_color = ImVec4(0.36f, 0.62f, 0.36f, 1.0f);
|
||||
right_icon_text = is_unlocked ? ICON_FA_LOCK_OPEN : ICON_FA_LOCK;
|
||||
break;
|
||||
|
||||
// Just use the lock for standard achievements.
|
||||
case RC_CLIENT_ACHIEVEMENT_TYPE_STANDARD:
|
||||
default:
|
||||
badge_text = nullptr;
|
||||
badge_icon = nullptr;
|
||||
right_icon_text = is_unlocked ? ICON_FA_LOCK_OPEN : ICON_FA_LOCK;
|
||||
break;
|
||||
}
|
||||
@@ -2634,7 +2841,34 @@ void Achievements::DrawAchievement(const rc_client_achievement_t* cheevo)
|
||||
const ImVec2 right_icon_size(g_large_font.first->CalcTextSizeA(g_large_font.second, FLT_MAX, 0.0f, right_icon_text));
|
||||
|
||||
const float text_start_x = bb.Min.x + image_size.x + LayoutScale(15.0f);
|
||||
const ImRect title_bb(ImVec2(text_start_x, bb.Min.y), ImVec2(points_start, midpoint));
|
||||
|
||||
const float badge_padding = LayoutScale(6.0f);
|
||||
const float icon_text_spacing = LayoutScale(4.0f);
|
||||
const float badge_title_spacing = LayoutScale(6.0f);
|
||||
ImVec2 badge_size = ImVec2(0.0f, 0.0f);
|
||||
ImVec2 badge_icon_size = ImVec2(0.0f, 0.0f);
|
||||
ImVec2 badge_text_size = ImVec2(0.0f, 0.0f);
|
||||
if (badge_text && badge_icon)
|
||||
{
|
||||
badge_icon_size = g_medium_font.first->CalcTextSizeA(g_medium_font.second, FLT_MAX, 0.0f, badge_icon);
|
||||
badge_text_size = g_medium_font.first->CalcTextSizeA(g_medium_font.second, FLT_MAX, 0.0f, badge_text);
|
||||
badge_size = ImVec2(badge_icon_size.x + icon_text_spacing + badge_text_size.x + (badge_padding * 2.0f),
|
||||
g_medium_font.second + badge_padding);
|
||||
}
|
||||
|
||||
const ImVec2 title_size(g_large_font.first->CalcTextSizeA(g_large_font.second, FLT_MAX, 0.0f, cheevo->title));
|
||||
const float title_text_end_x = text_start_x + title_size.x;
|
||||
|
||||
float title_max_x = points_start;
|
||||
float badge_x = 0.0f;
|
||||
if (badge_text && badge_icon)
|
||||
{
|
||||
const float effective_title_max_x = points_start - (badge_size.x + badge_title_spacing);
|
||||
badge_x = std::min(title_text_end_x + badge_title_spacing, effective_title_max_x);
|
||||
title_max_x = badge_x - badge_title_spacing;
|
||||
}
|
||||
|
||||
const ImRect title_bb(ImVec2(text_start_x, bb.Min.y), ImVec2(title_max_x, midpoint));
|
||||
const ImRect summary_bb(ImVec2(text_start_x, midpoint), ImVec2(points_start, midpoint + g_medium_font.second + extra_summary_height));
|
||||
const ImRect points_bb(ImVec2(points_start, midpoint), bb.Max);
|
||||
const ImRect lock_bb(
|
||||
@@ -2645,6 +2879,24 @@ void Achievements::DrawAchievement(const rc_client_achievement_t* cheevo)
|
||||
ImGui::RenderTextClipped(lock_bb.Min, lock_bb.Max, right_icon_text, nullptr, &right_icon_size, ImVec2(0.0f, 0.0f), &lock_bb);
|
||||
ImGui::PopFont();
|
||||
|
||||
if (badge_text && badge_icon)
|
||||
{
|
||||
ImDrawList* dl = ImGui::GetWindowDrawList();
|
||||
const ImVec2 badge_min(badge_x, bb.Min.y + ((midpoint - bb.Min.y) / 2.0f) - (badge_size.y / 2.0f));
|
||||
const ImVec2 badge_max(badge_min.x + badge_size.x, badge_min.y + badge_size.y);
|
||||
|
||||
dl->AddRectFilled(badge_min, badge_max, ImGui::GetColorU32(badge_color), LayoutScale(3.0f));
|
||||
|
||||
const float icon_y = badge_min.y + ((badge_size.y - badge_icon_size.y) * 0.5f);
|
||||
const float text_y = badge_min.y + ((badge_size.y - badge_text_size.y) * 0.5f);
|
||||
|
||||
const ImVec2 icon_pos(badge_min.x + badge_padding, icon_y);
|
||||
dl->AddText(g_medium_font.first, g_medium_font.second, icon_pos, IM_COL32(255, 255, 255, 255), badge_icon);
|
||||
|
||||
const ImVec2 text_pos(icon_pos.x + badge_icon_size.x + icon_text_spacing, text_y);
|
||||
dl->AddText(g_medium_font.first, g_medium_font.second, text_pos, IM_COL32(255, 255, 255, 255), badge_text);
|
||||
}
|
||||
|
||||
ImGui::PushFont(g_medium_font.first, g_medium_font.second);
|
||||
if (cheevo->description && summary_length > 0)
|
||||
{
|
||||
@@ -3286,6 +3538,29 @@ void Achievements::CloseLeaderboard()
|
||||
s_open_leaderboard = nullptr;
|
||||
}
|
||||
|
||||
std::string Achievements::GetSubsetBadgePath(const rc_client_subset_t* subset)
|
||||
{
|
||||
if (!subset || !subset->badge_name[0])
|
||||
return {};
|
||||
|
||||
std::string path = Path::Combine(s_image_directory, fmt::format("subset_{}.png", subset->badge_name));
|
||||
if (!path.empty() && subset->badge_url && !FileSystem::FileExists(path.c_str()))
|
||||
DownloadImage(subset->badge_url, path);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void Achievements::OpenSubset(const rc_client_subset_t* subset)
|
||||
{
|
||||
Console.WriteLn("Achievements: Opening subset '%s' (%u)", subset->title, subset->id);
|
||||
s_open_subset = subset;
|
||||
}
|
||||
|
||||
void Achievements::CloseSubset()
|
||||
{
|
||||
s_open_subset = nullptr;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RAINTEGRATION
|
||||
|
||||
#include "RA_Consoles.h"
|
||||
|
||||
+8
-2
@@ -102,10 +102,16 @@ static void CDVD_INT(int eCycle)
|
||||
// test (which will cause the exception to be handled).
|
||||
static void cdvdSetIrq(uint id = (1 << Irq_CommandComplete))
|
||||
{
|
||||
if (!(cdvd.IntrStat & id))
|
||||
{
|
||||
iopIntcIrq(2);
|
||||
psxSetNextBranchDelta(20);
|
||||
}
|
||||
else
|
||||
DevCon.Warning("CDVD trying to double issue IRQ %x", id);
|
||||
|
||||
cdvd.IntrStat |= id;
|
||||
cdvd.AbortRequested = false;
|
||||
iopIntcIrq(2);
|
||||
psxSetNextBranchDelta(20);
|
||||
}
|
||||
|
||||
static int mg_BIToffset(u8* buffer)
|
||||
|
||||
+12
-1
@@ -247,7 +247,6 @@ set(pcsx2SPU2Sources
|
||||
SPU2/ADSR.cpp
|
||||
SPU2/Debug.cpp
|
||||
SPU2/Dma.cpp
|
||||
SPU2/Mixer.cpp
|
||||
SPU2/spu2.cpp
|
||||
SPU2/ReadInput.cpp
|
||||
SPU2/RegTable.cpp
|
||||
@@ -258,6 +257,7 @@ set(pcsx2SPU2Sources
|
||||
)
|
||||
|
||||
set(pcsx2SPU2SourcesUnshared
|
||||
SPU2/Mixer.cpp
|
||||
SPU2/ReverbResample.cpp
|
||||
)
|
||||
|
||||
@@ -710,6 +710,13 @@ elseif(LINUX)
|
||||
list(APPEND pcsx2USBHeaders
|
||||
USB/usb-eyetoy/cam-linux.h
|
||||
)
|
||||
elseif(APPLE)
|
||||
list(APPEND pcsx2USBSources
|
||||
USB/usb-eyetoy/cam-macos.mm
|
||||
)
|
||||
list(APPEND pcsx2USBHeaders
|
||||
USB/usb-eyetoy/cam-macos.h
|
||||
)
|
||||
else()
|
||||
list(APPEND pcsx2USBSources
|
||||
USB/usb-eyetoy/cam-noop.cpp
|
||||
@@ -1243,11 +1250,15 @@ if (APPLE)
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
find_library(METAL_LIBRARY Metal)
|
||||
find_library(QUARTZCORE_LIBRARY QuartzCore)
|
||||
find_library(AVFOUNDATION_LIBRARY AVFoundation)
|
||||
find_library(COREMEDIA_LIBRARY CoreMedia)
|
||||
target_link_libraries(PCSX2_FLAGS INTERFACE
|
||||
${APPKIT_LIBRARY}
|
||||
${IOKIT_LIBRARY}
|
||||
${METAL_LIBRARY}
|
||||
${QUARTZCORE_LIBRARY}
|
||||
${AVFOUNDATION_LIBRARY}
|
||||
${COREMEDIA_LIBRARY}
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
+2
-1
@@ -788,6 +788,7 @@ struct Pcsx2Config
|
||||
SaveTransferImages : 1,
|
||||
SaveDrawStats : 1,
|
||||
SaveFrameStats : 1,
|
||||
SaveHWConfig : 1,
|
||||
DumpReplaceableTextures : 1,
|
||||
DumpReplaceableMipmaps : 1,
|
||||
DumpTexturesWithFMVActive : 1,
|
||||
@@ -917,7 +918,7 @@ struct Pcsx2Config
|
||||
bool operator!=(const GSOptions& right) const;
|
||||
|
||||
// Should we dump this draw/frame?
|
||||
bool ShouldDump(int draw, int frame) const;
|
||||
bool ShouldDump(u64 draw, int frame) const;
|
||||
};
|
||||
|
||||
struct SPU2Options
|
||||
|
||||
@@ -222,7 +222,7 @@ HANDLE TAPOpen(const std::string& device_guid)
|
||||
unsigned long minor;
|
||||
unsigned long debug;
|
||||
} version;
|
||||
LONG version_len;
|
||||
DWORD version_len;
|
||||
|
||||
std::string device_path = USERMODEDEVICEDIR + device_guid + TAPSUFFIX;
|
||||
|
||||
@@ -242,7 +242,7 @@ HANDLE TAPOpen(const std::string& device_guid)
|
||||
|
||||
const BOOL bret = DeviceIoControl(handle.get(), TAP_IOCTL_GET_VERSION,
|
||||
&version, sizeof(version),
|
||||
&version, sizeof(version), (LPDWORD)&version_len, NULL);
|
||||
&version, sizeof(version), &version_len, NULL);
|
||||
|
||||
if (bret == FALSE)
|
||||
{
|
||||
|
||||
+17
-2
@@ -9,6 +9,7 @@
|
||||
#include "GS/Renderers/Common/GSDevice.h"
|
||||
#include "GS/Renderers/Common/GSRenderer.h"
|
||||
#include "common/AlignedMalloc.h"
|
||||
#include "common/Console.h"
|
||||
|
||||
GSClut::GSClut(GSLocalMemory* mem)
|
||||
: m_mem(mem)
|
||||
@@ -409,7 +410,6 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
}
|
||||
}
|
||||
|
||||
m_current_gpu_clut = nullptr;
|
||||
if (GSConfig.UserHacks_GPUTargetCLUTMode != GSGPUTargetCLUTMode::Disabled)
|
||||
{
|
||||
const bool is_4bit = (TEX0.PSM == PSMT4 || TEX0.PSM == PSMT4HL || TEX0.PSM == PSMT4HH);
|
||||
@@ -440,21 +440,36 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
GSTexture* dst = is_4bit ? m_gpu_clut4 : m_gpu_clut8;
|
||||
const u32 dst_size = is_4bit ? 16 : 256;
|
||||
const u32 dOffset = (TEX0.CSA & ((TEX0.CPSM == PSMCT16 || TEX0.CPSM == PSMCT16S) ? 15u : 31u)) << 4;
|
||||
|
||||
if (src != m_current_gpu_clut && (src != m_last_gpu_clut || m_gpu_clut_last_offset != offset))
|
||||
m_gpu_clut_dirty = true;
|
||||
|
||||
if (!dst)
|
||||
{
|
||||
// allocate texture lazily
|
||||
dst = g_gs_device->CreateRenderTarget(dst_size, 1, GSTexture::Format::Color, false);
|
||||
is_4bit ? (m_gpu_clut4 = dst) : (m_gpu_clut8 = dst);
|
||||
m_gpu_clut_dirty = true;
|
||||
}
|
||||
if (dst)
|
||||
{
|
||||
GL_PUSH("Update GPU CLUT [CBP=%04X, CPSM=%s, CBW=%u, CSA=%u, Offset=(%d,%d)]",
|
||||
TEX0.CBP, GSUtil::GetPSMName(TEX0.CPSM), CBW, TEX0.CSA, offset.x, offset.y);
|
||||
g_gs_device->UpdateCLUTTexture(src, scale, offset.x, offset.y, dst, dOffset, dst_size);
|
||||
|
||||
if (m_gpu_clut_dirty)
|
||||
{
|
||||
m_last_gpu_clut = src;
|
||||
g_gs_device->UpdateCLUTTexture(src, scale, offset.x, offset.y, dst, dOffset, dst_size);
|
||||
}
|
||||
|
||||
m_gpu_clut_dirty = false;
|
||||
m_current_gpu_clut = dst;
|
||||
m_gpu_clut_last_offset = offset;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_current_gpu_clut = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-1
@@ -49,6 +49,10 @@ class alignas(32) GSClut final : public GSAlignedClass<32>
|
||||
GSTexture* m_gpu_clut4 = nullptr;
|
||||
GSTexture* m_gpu_clut8 = nullptr;
|
||||
GSTexture* m_current_gpu_clut = nullptr;
|
||||
GSTexture* m_last_gpu_clut = nullptr;
|
||||
GSVector2i m_gpu_clut_last_offset = 0;
|
||||
u64 m_gpu_clut_draw = 0;
|
||||
bool m_gpu_clut_dirty = true;
|
||||
|
||||
typedef void (GSClut::*writeCLUT)(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT);
|
||||
|
||||
@@ -97,7 +101,14 @@ public:
|
||||
~GSClut();
|
||||
|
||||
__fi GSTexture* GetGPUTexture() const { return m_current_gpu_clut; }
|
||||
|
||||
__fi void SetGPUTextureDirty(u64 draw, GSTexture* texture)
|
||||
{
|
||||
if (texture == m_last_gpu_clut && draw > m_gpu_clut_draw)
|
||||
{
|
||||
m_gpu_clut_draw = draw;
|
||||
m_gpu_clut_dirty = true;
|
||||
}
|
||||
}
|
||||
void Reset();
|
||||
bool InvalidateRange(u32 start_block, u32 end_block, bool is_draw = false);
|
||||
u8 IsInvalid();
|
||||
|
||||
+368
-103
@@ -19,9 +19,9 @@
|
||||
#include <iomanip>
|
||||
#include <bit>
|
||||
|
||||
int GSState::s_n = 0;
|
||||
int GSState::s_last_transfer_draw_n = 0;
|
||||
int GSState::s_transfer_n = 0;
|
||||
u64 GSState::s_n = 0;
|
||||
u64 GSState::s_last_transfer_draw_n = 0;
|
||||
u64 GSState::s_transfer_n = 0;
|
||||
|
||||
static __fi bool IsAutoFlushEnabled()
|
||||
{
|
||||
@@ -444,7 +444,7 @@ void GSState::DumpDrawInfo(bool dump_regs, bool dump_verts, bool dump_transfers)
|
||||
// Dump Register state
|
||||
if (dump_regs)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_context.txt", s_n);
|
||||
s = GetDrawDumpPath("%05lld_context.txt", s_n);
|
||||
|
||||
m_draw_env->Dump(s);
|
||||
m_context->Dump(s);
|
||||
@@ -453,14 +453,14 @@ void GSState::DumpDrawInfo(bool dump_regs, bool dump_verts, bool dump_transfers)
|
||||
// Dump vertices
|
||||
if (dump_verts)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_vertex.txt", s_n);
|
||||
s = GetDrawDumpPath("%05lld_vertex.txt", s_n);
|
||||
DumpVertices(s);
|
||||
}
|
||||
|
||||
// Dump transfers
|
||||
if (dump_transfers)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_transfers.txt", s_n);
|
||||
s = GetDrawDumpPath("%05lld_transfers.txt", s_n);
|
||||
DumpTransferList(s);
|
||||
}
|
||||
}
|
||||
@@ -860,14 +860,14 @@ void GSState::DumpTransferImages()
|
||||
if ((transfer.transfer_type == EEGS_TransferType::EE_to_GS) || transfer.zero_clear)
|
||||
{
|
||||
// clear or EE->GS: only the destination info is relevant.
|
||||
filename = GetDrawDumpPath("%05d_transfer%02d_%s_%04x_%d_%s_%d_%d_%d_%d.png",
|
||||
filename = GetDrawDumpPath("%05lld_transfer%02d_%s_%04x_%d_%s_%d_%d_%d_%d.png",
|
||||
s_n, transfer_n++, (transfer.zero_clear ? "clear" : "EE_to_GS"), transfer.blit.DBP, transfer.blit.DBW,
|
||||
GSUtil::GetPSMName(transfer.blit.DPSM), transfer.rect.x, transfer.rect.y, transfer.rect.z, transfer.rect.w);
|
||||
}
|
||||
else
|
||||
{
|
||||
// GS->GS: the source and destination info are both relevant.
|
||||
filename = GetDrawDumpPath("%05d_transfer%02d_GS_to_GS_%04x_%d_%s_%04x_%d_%s_%d_%d_%d_%d.bmp",
|
||||
filename = GetDrawDumpPath("%05lld_transfer%02d_GS_to_GS_%04x_%d_%s_%04x_%d_%s_%d_%d_%d_%d.bmp",
|
||||
s_n, transfer_n++, transfer.blit.SBP, transfer.blit.SBW, GSUtil::GetPSMName(transfer.blit.SPSM),
|
||||
transfer.blit.DBP, transfer.blit.DBW, GSUtil::GetPSMName(transfer.blit.DPSM),
|
||||
transfer.rect.x, transfer.rect.y, transfer.rect.z, transfer.rect.w);
|
||||
@@ -2157,7 +2157,7 @@ void GSState::FlushPrim()
|
||||
if (GSConfig.SaveDrawStats)
|
||||
{
|
||||
m_perfmon_draw = g_perfmon - m_perfmon_draw;
|
||||
m_perfmon_draw.Dump(GetDrawDumpPath("%05d_draw_stats.txt", s_n), GSIsHardwareRenderer());
|
||||
m_perfmon_draw.Dump(GetDrawDumpPath("%05lld_draw_stats.txt", s_n), GSIsHardwareRenderer());
|
||||
m_perfmon_draw = g_perfmon;
|
||||
}
|
||||
}
|
||||
@@ -2405,7 +2405,7 @@ void GSState::Write(const u8* mem, int len)
|
||||
m_draw_transfers.push_back(new_transfer);
|
||||
}
|
||||
|
||||
GL_CACHE("Write! %u ... => 0x%x W:%d F:%s (DIR %d%d), dPos(%d %d) size(%d %d) draw %d", s_transfer_n,
|
||||
GL_CACHE("Write! %u ... => 0x%x W:%d F:%s (DIR %d%d), dPos(%d %d) size(%d %d) draw %lld", s_transfer_n,
|
||||
blit.DBP, blit.DBW, GSUtil::GetPSMName(blit.DPSM),
|
||||
m_tr.m_pos.DIRX, m_tr.m_pos.DIRY,
|
||||
m_tr.x, m_tr.y, m_tr.w, m_tr.h, s_n);
|
||||
@@ -2466,7 +2466,7 @@ void GSState::InitReadFIFO(u8* mem, int len)
|
||||
if (GSConfig.SaveRT && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
const std::string s(GetDrawDumpPath(
|
||||
"%05d_read_%05x_%d_%s_%d_%d_%d_%d.bmp",
|
||||
"%05lld_read_%05x_%d_%s_%d_%d_%d_%d.bmp",
|
||||
s_n, (int)m_env.BITBLTBUF.SBP, (int)m_env.BITBLTBUF.SBW, GSUtil::GetPSMName(m_env.BITBLTBUF.SPSM),
|
||||
r.left, r.top, r.right, r.bottom));
|
||||
|
||||
@@ -2492,8 +2492,7 @@ void GSState::Read(u8* mem, int len)
|
||||
if (!m_tr.Update(w, h, bpp, len))
|
||||
return;
|
||||
|
||||
const int draw = s_n;
|
||||
|
||||
const u64 draw = s_n;
|
||||
|
||||
if (draw != s_n)
|
||||
DevCon.Warning("Warning! Possible incorrect data download");
|
||||
@@ -3754,12 +3753,11 @@ GSState::PRIM_OVERLAP GSState::GetPrimitiveOverlapDrawlistImpl(bool save_drawlis
|
||||
const u16* RESTRICT index = m_index.buff;
|
||||
const u32 count = m_index.tail;
|
||||
|
||||
// Optimize out using indices for sprites and points; probably not much difference.
|
||||
const auto GetIndex = [&](int i) {
|
||||
const auto GetPoint = [&](int i) -> GSVector4i {
|
||||
if constexpr (primclass == GS_SPRITE_CLASS || primclass == GS_POINT_CLASS)
|
||||
return i;
|
||||
return GSVector4i(v[i].m[1]).upl16(); // Optimize out using the indices.
|
||||
else
|
||||
return index[i];
|
||||
return GSVector4i(v[index[i]].m[1]).upl16();
|
||||
};
|
||||
|
||||
// Batch prim into groups so that within each group the cumulative bboxes are non-overlapping.
|
||||
@@ -3783,8 +3781,15 @@ GSState::PRIM_OVERLAP GSState::GetPrimitiveOverlapDrawlistImpl(bool save_drawlis
|
||||
|
||||
u32 i = 0;
|
||||
u32 skip = 0; // Number of indices to skip if we have the bbox from the previous iteration.
|
||||
|
||||
// To cache a tristrip for the next iteration if we cannot use it in this iteration.
|
||||
struct SavedTristrip {
|
||||
bool saved = false;
|
||||
u32 skip;
|
||||
BoundingOct bbox;
|
||||
} saved_tristrip;
|
||||
|
||||
GSVector4i all(INT_MAX, INT_MAX, -INT_MAX, -INT_MAX);
|
||||
BoundingOct all;
|
||||
|
||||
while (i < count)
|
||||
{
|
||||
@@ -3792,149 +3797,394 @@ GSState::PRIM_OVERLAP GSState::GetPrimitiveOverlapDrawlistImpl(bool save_drawlis
|
||||
|
||||
skip = 0;
|
||||
|
||||
GSVector4i bbox(INT_MAX, INT_MAX, -INT_MAX, -INT_MAX);
|
||||
BoundingOct bbox;
|
||||
|
||||
while (j < count)
|
||||
{
|
||||
bool got_bbox = false;
|
||||
|
||||
// Assuming that indices 0-5 represent two triangles:
|
||||
// Triangle strips: indices 1, 2 are identical to indices 3, 4. Indices 0, 5 are different.
|
||||
// Triangles fans: indices 0, 2 are identical to indices 3, 4. Indices 1, 5 are different.
|
||||
// Warning: this depends on how the vertices are arranged in the vertex kick.
|
||||
// if that changes this detection will break.
|
||||
constexpr std::array<std::array<std::array<int, 3>, 2>, 2> tri_order({
|
||||
// Triangle strip expected indices.
|
||||
std::array{ std::array<int, 3>{ 1, 2, 0 }, std::array<int, 3>{ 3, 4, 5 } },
|
||||
// Test overlap of two adjacent triangles give the indices of the
|
||||
// shared edge and two unshared points.
|
||||
const auto TrianglesOverlap = [GetPoint]
|
||||
(u32 s0, u32 s1, u32 u0, u32 u1, bool& sign_out) -> bool {
|
||||
|
||||
// Triangle fan expected indices.
|
||||
std::array{ std::array<int, 3>{ 0, 2, 1 }, std::array<int, 3>{ 3, 4, 5 } },
|
||||
});
|
||||
const GSVector4i shared0 = GetPoint(s0);
|
||||
const GSVector4i shared1 = GetPoint(s1) - shared0;
|
||||
const GSVector4i unshared0 = GetPoint(u0) - shared0;
|
||||
const GSVector4i unshared1 = GetPoint(u1) - shared0;
|
||||
|
||||
// Determine which side of the shared edge each triangle is on.
|
||||
const bool sign0 = unshared0.x * shared1.y - unshared0.y * shared1.x >= 0;
|
||||
const bool sign1 = unshared1.x * shared1.y - unshared1.y * shared1.x >= 0;
|
||||
|
||||
sign_out = sign0; // Output side of the first triangle with respect to the shared edge.
|
||||
|
||||
// Cross product signs comparison. If true, triangles are on same side of the shared edge.
|
||||
return sign0 == sign1;
|
||||
};
|
||||
|
||||
// Helper to detect triangles strips/fans (template 0 for strips, 1 for fans).
|
||||
const auto CheckTriangleQuads = [index, count, TrianglesOverlap, GetPoint]
|
||||
<int type>(u32 i, u32& skip, BoundingOct& bbox) -> bool {
|
||||
|
||||
// Assuming that indices 0-5 represent two triangles:
|
||||
// Triangle strips: indices 1, 2 are identical to indices 3, 4. Indices 0, 5 are different.
|
||||
// Triangles fans: indices 0, 2 are identical to indices 3, 4. Indices 1, 5 are different.
|
||||
// Warning: this depends on how the vertices are arranged in the vertex kick.
|
||||
// if that changes this detection will break.
|
||||
constexpr std::array<std::array<std::array<int, 3>, 2>, 2> tri_order({
|
||||
// Triangle strip expected indices.
|
||||
std::array{ std::array<int, 3>{ 1, 2, 0 }, std::array<int, 3>{ 3, 4, 5 } },
|
||||
|
||||
// Triangle fan expected indices.
|
||||
std::array{ std::array<int, 3>{ 0, 2, 1 }, std::array<int, 3>{ 3, 4, 5 } },
|
||||
});
|
||||
|
||||
const auto CheckTriangleQuads = [&]<int type>() {
|
||||
constexpr std::array<int, 3> tri0 = tri_order[type][0];
|
||||
constexpr std::array<int, 3> tri1 = tri_order[type][1];
|
||||
|
||||
if (!got_bbox && primclass == GS_TRIANGLE_CLASS && j + 3 < count &&
|
||||
index[j + tri0[0]] == index[j + tri1[0]] &&
|
||||
index[j + tri0[1]] == index[j + tri1[1]])
|
||||
// Check that the initial two triangles form a strip.
|
||||
if (!(primclass == GS_TRIANGLE_CLASS && i + 6 <= count &&
|
||||
index[i + tri0[0]] == index[i + tri1[0]] &&
|
||||
index[i + tri0[1]] == index[i + tri1[1]]))
|
||||
{
|
||||
// Get the initial triangle bbox.
|
||||
bbox = GSVector4i(v[index[j + 0]].m[1]).upl16().xyxy();
|
||||
bbox = bbox.runion(GSVector4i(v[index[j + 1]].m[1]).upl16().xyxy());
|
||||
bbox = bbox.runion(GSVector4i(v[index[j + 2]].m[1]).upl16().xyxy());
|
||||
return false;
|
||||
}
|
||||
|
||||
while (true)
|
||||
u32 j = i;
|
||||
|
||||
// Get the initial triangle bbox.
|
||||
bbox = BoundingOct::FromPoint(GetPoint(j + 0));
|
||||
bbox = bbox.Union(GetPoint(j + 1));
|
||||
bbox = bbox.Union(GetPoint(j + 2));
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Check if the two triangles overlap.
|
||||
[[maybe_unused]] bool sign;// ignore
|
||||
if (TrianglesOverlap(j + tri1[0], j + tri1[1], j + tri0[2], j + tri1[2], sign))
|
||||
{
|
||||
// There is a shared edge between this and next triangle.
|
||||
// Check if the unshared point is on opposite sides of the shared edge.
|
||||
const GSVector4i shared0 = GSVector4i(v[index[j + skip + tri0[0]]].m[1]).upl16();
|
||||
const GSVector4i shared1 = GSVector4i(v[index[j + skip + tri0[1]]].m[1]).upl16() - shared0;
|
||||
const GSVector4i unshared0 = GSVector4i(v[index[j + skip + tri0[2]]].m[1]).upl16() - shared0;
|
||||
const GSVector4i unshared1 = GSVector4i(v[index[j + skip + tri1[2]]].m[1]).upl16() - shared0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Cross product signs comparison.
|
||||
if ((unshared0.x * shared1.y - unshared0.y * shared1.x >= 0) ==
|
||||
(unshared1.x * shared1.y - unshared1.y * shared1.x >= 0))
|
||||
// Corners are on opposite sides so we can assume a non-axis-aligned quad.
|
||||
// Take union with the single unshared point.
|
||||
bbox = bbox.Union(GetPoint(j + tri1[2]));
|
||||
j += 3;
|
||||
|
||||
if (!(j + 6 <= count &&
|
||||
index[j + tri0[0]] == index[j + tri1[0]] &&
|
||||
index[j + tri0[1]] == index[j + tri1[1]]))
|
||||
{
|
||||
// Cannot continue the strip/fan.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == i)
|
||||
{
|
||||
return false; // Only a single triangle in the strip.
|
||||
}
|
||||
|
||||
skip = j - i + 3; // Number of vertices in the loop + first triangle.
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// Helper functions to find a common edge between two triangles and check if they overlap.
|
||||
// Template parameter indicates if the triangle is at the end of the strip or beginning.
|
||||
const auto MatchTriangles = [v, index, TrianglesOverlap]<bool end0, bool end1>
|
||||
(u32 tri0, u32 tri1, bool& sign) -> bool {
|
||||
|
||||
// For the end triangle only consider the last edge of the triangle.
|
||||
// For the start triangle only consider the first edge of the triangle.
|
||||
const u32 base0 = end0 ? 1 : 0;
|
||||
const u32 base1 = end1 ? 1 : 0;
|
||||
|
||||
for (int i0 = base0; i0 < base0 + 2; i0++)
|
||||
{
|
||||
for (int i1 = base1; i1 < base1 + 2; i1++)
|
||||
{
|
||||
if (v[index[tri0 + i0]].XYZ.U32[0] == v[index[tri1 + i1]].XYZ.U32[0])
|
||||
{
|
||||
break; // Triangles are on same side of the shared edge so there's overlap.
|
||||
}
|
||||
// Get the index that should be shared between the adjacent triangles.
|
||||
const int j0 = end0 ? (i0 == 2 ? 0 : i0 - 4) : (i0 == 0 ? 2 : i0 + 4);
|
||||
const int j1 = end1 ? (i1 == 2 ? 0 : i1 - 4) : (i1 == 0 ? 2 : i1 + 4);
|
||||
|
||||
// Corners are on opposite sides so we can assume a non-axis-aligned quad.
|
||||
// Take union with the single unshared point.
|
||||
bbox = bbox.runion(GSVector4i(v[index[j + skip + tri1[2]]].m[1]).upl16().xyxy());
|
||||
if (v[index[tri0 + j0]].XYZ.U32[0] != v[index[tri1 + j1]].XYZ.U32[0])
|
||||
{
|
||||
return false; // Edge is not shared.
|
||||
}
|
||||
|
||||
skip += 3;
|
||||
// Get the indices that should be unshared.
|
||||
const int k0 = end0 ? 3 - i0 : 1 - i0;
|
||||
const int k1 = end1 ? 3 - i1 : 1 - i1;
|
||||
|
||||
got_bbox = true;
|
||||
// Get the shared edge in the order of the first strip's increasing indices.
|
||||
// Consistency is important for the sign check to work correctly.
|
||||
const int s0 = std::min(i0, j0);
|
||||
const int t0 = std::max(i0, j0);
|
||||
|
||||
if (!(j + skip + 3 < count &&
|
||||
index[j + skip + tri0[0]] == index[j + skip + tri1[0]] &&
|
||||
index[j + skip + tri0[1]] == index[j + skip + tri1[1]]))
|
||||
{
|
||||
// Cannot continue the strip/fan. Consume the last triangle and exit.
|
||||
skip += 3;
|
||||
break;
|
||||
return !TrianglesOverlap(tri0 + s0, tri0 + t0, tri0 + k0, tri1 + k1, sign);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// First check: see if the triangles are part of triangle strip/fan.
|
||||
if (primclass == GS_TRIANGLE_CLASS)
|
||||
{
|
||||
CheckTriangleQuads.template operator()<0>(); // Check triangle strips.
|
||||
CheckTriangleQuads.template operator()<1>(); // Check triangle fans.
|
||||
}
|
||||
// Helper function to detect triangles strips and merge them together into
|
||||
// a grid of triangles strips.
|
||||
const auto CheckTriangleStrips = [count, CheckTriangleQuads, MatchTriangles, GetPoint]
|
||||
(u32 i, u32& skip, BoundingOct& bbox_all, SavedTristrip& saved_tristrip) -> bool {
|
||||
|
||||
// Second check: see if triangles form an axis-aligned quad.
|
||||
if (!got_bbox && primclass == GS_TRIANGLE_CLASS && check_quads && j + 3 < count)
|
||||
{
|
||||
const u16* RESTRICT idx0 = &index[j + 0];
|
||||
const u16* RESTRICT idx1 = &index[j + 3];
|
||||
if (!(primclass == GS_TRIANGLE_CLASS && i + 6 <= count))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 j = i;
|
||||
|
||||
u32 prev_tri0; // First triangle of previous tristrip.
|
||||
u32 prev_tri1; // Last triangle of previous tristrip.
|
||||
|
||||
bool all_small; // Whether all strips so far have 2 triangles only.
|
||||
|
||||
u32 n_tristrips = 0; // Number of tristrips merged so far.
|
||||
|
||||
// Used to make sure the tristrips are adjacent in the same direction so there's not overlap.
|
||||
bool expected_sign;
|
||||
|
||||
// For another heuristic to determine if the tristrips are overlapping themselves.
|
||||
// Stores the maximum difference in X/Y from the starting point.
|
||||
GSVector4i start_pt;
|
||||
GSVector4i max_delta(0, 0);
|
||||
|
||||
// Whether the current tristrip is oriented in the same direction as the first.
|
||||
bool orientation = true;
|
||||
|
||||
BoundingOct bbox; // BBox of current strip.
|
||||
|
||||
// Check for the first tristrip in the chain.
|
||||
if (saved_tristrip.saved)
|
||||
{
|
||||
// Have a tristrip saved from a previous iteration.
|
||||
skip = saved_tristrip.skip;
|
||||
bbox = saved_tristrip.bbox;
|
||||
saved_tristrip.saved = false;
|
||||
}
|
||||
else if (!CheckTriangleQuads.template operator()<0>(j, skip, bbox))
|
||||
{
|
||||
return false;// Could not find a new tristrip.
|
||||
}
|
||||
|
||||
// Initialize loop variables.
|
||||
prev_tri0 = j;
|
||||
prev_tri1 = j + skip - 3;
|
||||
all_small = (skip <= 6);
|
||||
bbox_all = bbox;
|
||||
start_pt = GetPoint(prev_tri0);
|
||||
n_tristrips++;
|
||||
j += skip;
|
||||
|
||||
while (j < count)
|
||||
{
|
||||
if (!CheckTriangleQuads.template operator()<0>(j, skip, bbox))
|
||||
{
|
||||
break; // Cannot continue tristrip grid.
|
||||
}
|
||||
|
||||
// Save the tristrip in case it can be used on the next iteration.
|
||||
saved_tristrip.saved = true;
|
||||
saved_tristrip.skip = skip;
|
||||
saved_tristrip.bbox = bbox;
|
||||
|
||||
// Get first/last triangle of current tristrip.
|
||||
const u32 tri0 = j;
|
||||
const u32 tri1 = j + skip - 3;
|
||||
|
||||
all_small = all_small && (skip <= 6);
|
||||
|
||||
// First heuristic: check if the previous and this tristrip are part of a grid by
|
||||
// checking if the first/last triangles in each strip have a common edge and do not overlap.
|
||||
bool sign0, sign1; // Orientation of how the first and last triangles are adjacent.
|
||||
bool flip; // Whether to flip the expected orientation because the two strips are in opposite directions.
|
||||
|
||||
// Check the first two vertices of first triangles and last two vertices of last triangles.
|
||||
if (MatchTriangles.template operator()<false, false>(prev_tri0, tri0, sign0) &&
|
||||
MatchTriangles.template operator()<true, true>(prev_tri1, tri1, sign1))
|
||||
{
|
||||
flip = false; // Tristrips are in the same directions.
|
||||
}
|
||||
else if (MatchTriangles.template operator()<false, true>(prev_tri0, tri1, sign0) &&
|
||||
MatchTriangles.template operator()<true, false>(prev_tri1, tri0, sign1))
|
||||
{
|
||||
flip = true; // Tristrips are in opposite directions.
|
||||
}
|
||||
else
|
||||
{
|
||||
break; // Cannot continue the tristrip chain.
|
||||
}
|
||||
|
||||
// Second heuristic: make sure the new tristrip is always on the same side as the previous one.
|
||||
if (n_tristrips >= 2)
|
||||
{
|
||||
if (!(sign0 == expected_sign && sign1 == expected_sign))
|
||||
{
|
||||
break; // New tristrip is on the wrong side.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sign0 != sign1)
|
||||
{
|
||||
break; // First/last triangles are on different sides.
|
||||
}
|
||||
expected_sign = sign0;
|
||||
}
|
||||
|
||||
if (flip)
|
||||
{
|
||||
expected_sign = !expected_sign;
|
||||
orientation = !orientation;
|
||||
}
|
||||
|
||||
// Third heuristic: for small tristrips make sure that we never move closer to
|
||||
// the first tristrip in the grid. Small tristrips appears to be more likely to
|
||||
// overlap themself.
|
||||
const GSVector4i curr_pt = GetPoint(orientation ? tri0 : tri1 + 2);
|
||||
const GSVector4i curr_delta = (curr_pt - start_pt).abs32();
|
||||
|
||||
// Check if we moved closer.
|
||||
if (n_tristrips >= 2 && all_small)
|
||||
{
|
||||
if (((curr_delta <= max_delta).mask() & 0xFF) == 0xFF)
|
||||
{
|
||||
break; // We moved closer to the start point in both X/Y so end the merging.
|
||||
}
|
||||
}
|
||||
|
||||
// Update maximum displacement from start.
|
||||
max_delta = max_delta.max_i32(curr_delta);
|
||||
|
||||
prev_tri0 = tri0;
|
||||
prev_tri1 = tri1;
|
||||
bbox_all = bbox_all.Union(bbox);
|
||||
j += skip;
|
||||
saved_tristrip.saved = false; // We consumed the new tristrip.
|
||||
n_tristrips++;
|
||||
}
|
||||
|
||||
skip = j - i;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// Helper functions to detect when two triangles form an axis-aligned quad.
|
||||
const auto GetBBoxAxisAlignedTriangles = [v, index, count, GetPoint]
|
||||
(u32 i, u32& skip, BoundingOct& bbox) -> bool {
|
||||
|
||||
if (!(primclass == GS_TRIANGLE_CLASS && i + 6 <= count))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const u32 off0 = i + 0;
|
||||
const u32 off1 = i + 3;
|
||||
TriangleOrdering tri0;
|
||||
TriangleOrdering tri1;
|
||||
|
||||
if (AreTrianglesQuad<0, 0>(v, idx0, idx1, &tri0, &tri1))
|
||||
if (!AreTrianglesQuad<0, 0>(v, index + off0, index + off1, &tri0, &tri1))
|
||||
{
|
||||
// tri.b is right angle corner
|
||||
bbox = GSVector4i(v[idx0[tri0.b]].m[1]).upl16().xyxy();
|
||||
bbox = bbox.runion(GSVector4i(v[idx1[tri1.b]].m[1]).upl16().xyxy());
|
||||
|
||||
skip = 6;
|
||||
return false;
|
||||
}
|
||||
|
||||
got_bbox = true;
|
||||
// tri.b is right angle corner
|
||||
const GSVector4i pt0 = GetPoint(off0 + tri0.b);
|
||||
const GSVector4i pt1 = GetPoint(off1 + tri1.b);
|
||||
bbox = BoundingOct::FromSprite(pt0, pt1);
|
||||
skip = 6;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// Helper functions to just get the individual prim bbox.
|
||||
const auto GetBBox = [GetPoint](u32 i, u32& skip, BoundingOct& bbox) -> bool {
|
||||
if constexpr (primclass == GS_SPRITE_CLASS)
|
||||
{
|
||||
bbox = BoundingOct::FromSprite(GetPoint(i + 0), GetPoint(i + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we fail a quad check assume the rest are not quads since the check is relatively expensive.
|
||||
check_quads = false;
|
||||
bbox = BoundingOct::FromPoint(GetPoint(i + 0));
|
||||
for (u32 j = 1; j < n; j++) // Unroll
|
||||
{
|
||||
bbox = bbox.Union(GetPoint(i + j));
|
||||
}
|
||||
}
|
||||
skip = n;
|
||||
return true;
|
||||
};
|
||||
|
||||
// First check: see if the triangles are part of a triangle strip.
|
||||
if (!got_bbox)
|
||||
{
|
||||
got_bbox = CheckTriangleStrips(j, skip, bbox, saved_tristrip);
|
||||
}
|
||||
|
||||
// Second check: see if the triangles are part of triangle fan.
|
||||
if (!got_bbox)
|
||||
{
|
||||
got_bbox = CheckTriangleQuads.template operator()<1>(j, skip, bbox);
|
||||
}
|
||||
|
||||
// Third check: see if a pair of triangles are an axis-aligned quad.
|
||||
// This doesn't require indices to match like the tristrip check.
|
||||
if (!got_bbox && check_quads)
|
||||
{
|
||||
got_bbox = GetBBoxAxisAlignedTriangles(j, skip, bbox);
|
||||
|
||||
// If we fail a quad check assume the rest are not quads since the check is relatively expensive.
|
||||
check_quads = got_bbox;
|
||||
}
|
||||
|
||||
// Default case: just take the bbox of the prim vertices.
|
||||
if (!got_bbox)
|
||||
{
|
||||
bbox = GSVector4i(v[GetIndex(j)].m[1]).upl16().xyxy();
|
||||
for (int k = 1; k < n; k++) // Unroll
|
||||
bbox = bbox.runion(GSVector4i(v[GetIndex(j + k)].m[1]).upl16().xyxy());
|
||||
|
||||
skip = n;
|
||||
|
||||
got_bbox = true;
|
||||
got_bbox = GetBBox(j, skip, bbox);
|
||||
}
|
||||
|
||||
// Avoid degenerate bbox.
|
||||
bbox = bbox.blend(bbox + GSVector4i(0, 0, 1, 1), bbox.xyxy() == bbox.zwzw());
|
||||
bbox = bbox.FixDegenerate();
|
||||
|
||||
if (all.rintersects(bbox))
|
||||
if (all.Intersects(bbox))
|
||||
{
|
||||
overlap = PRIM_OVERLAP_YES;
|
||||
break;
|
||||
}
|
||||
|
||||
all = all.runion(bbox);
|
||||
|
||||
all = all.Union(bbox);
|
||||
j += skip;
|
||||
|
||||
skip = 0;
|
||||
}
|
||||
|
||||
if (save_drawlist)
|
||||
{
|
||||
m_drawlist.push_back((j - i) / n); // Prim count
|
||||
}
|
||||
else if (j < count)
|
||||
{
|
||||
return PRIM_OVERLAP_YES; // Early exit if not saving drawlist.
|
||||
}
|
||||
|
||||
if (save_bbox)
|
||||
{
|
||||
m_drawlist_bbox.push_back(ProcessBBox(all));
|
||||
m_drawlist_bbox.push_back(ProcessBBox(all.ToBBox()));
|
||||
}
|
||||
|
||||
all = bbox;
|
||||
|
||||
i = j;
|
||||
}
|
||||
|
||||
return overlap;
|
||||
}
|
||||
|
||||
@@ -6112,15 +6362,30 @@ void GSState::GSPCRTCRegs::CalculateFramebufferOffset(bool scanmask, GSRegDISPFB
|
||||
|
||||
if (GSConfig.PCRTCAntiBlur && PCRTCSameSrc && !scanmask && abs(fb1.y - fb0.y) <= 1)
|
||||
{
|
||||
if (framebuffer0Reg.DBY != PCRTCDisplays[0].prevFramebufferReg.DBY)
|
||||
const bool alternating_0 = framebuffer0Reg.DBY != PCRTCDisplays[0].prevFramebufferReg.DBY;
|
||||
const bool alternating_1 = framebuffer1Reg.DBY != PCRTCDisplays[1].prevFramebufferReg.DBY;
|
||||
|
||||
if (alternating_0 && alternating_1)
|
||||
{
|
||||
PCRTCDisplays[0].framebufferRect.y = PCRTCDisplays[1].framebufferRect.y;
|
||||
PCRTCDisplays[0].framebufferRect.w = PCRTCDisplays[1].framebufferRect.w;
|
||||
const int index = (static_cast<u32>(PCRTCDisplays[1].framebufferRect.y) < static_cast<u32>(PCRTCDisplays[0].framebufferRect.y)) ? 0 : 1;
|
||||
const int offset = PCRTCDisplays[1 - index].framebufferRect.y - PCRTCDisplays[index].framebufferRect.y;
|
||||
|
||||
if (std::abs(offset) <= 4)
|
||||
{
|
||||
PCRTCDisplays[index].framebufferRect.y += offset;
|
||||
PCRTCDisplays[index].framebufferRect.w += offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
else // Only one rect is alternating
|
||||
{
|
||||
PCRTCDisplays[1].framebufferRect.y = PCRTCDisplays[0].framebufferRect.y;
|
||||
PCRTCDisplays[1].framebufferRect.w = PCRTCDisplays[0].framebufferRect.w;
|
||||
const int index = alternating_1 ? 1 : 0;
|
||||
const int offset = PCRTCDisplays[1 - index].framebufferRect.y - PCRTCDisplays[index].framebufferRect.y;
|
||||
|
||||
if (std::abs(offset) <= 4)
|
||||
{
|
||||
PCRTCDisplays[index].framebufferRect.y += offset;
|
||||
PCRTCDisplays[index].framebufferRect.w += offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -222,7 +222,7 @@ public:
|
||||
{
|
||||
GIFRegBITBLTBUF blit;
|
||||
GSVector4i rect;
|
||||
int draw;
|
||||
u64 draw;
|
||||
bool zero_clear;
|
||||
EEGS_TransferType transfer_type;
|
||||
};
|
||||
@@ -269,9 +269,9 @@ public:
|
||||
GSVector4i m_r = {};
|
||||
GSVector4i m_r_no_scissor = {};
|
||||
|
||||
static int s_n;
|
||||
static int s_last_transfer_draw_n;
|
||||
static int s_transfer_n;
|
||||
static u64 s_n;
|
||||
static u64 s_last_transfer_draw_n;
|
||||
static u64 s_transfer_n;
|
||||
|
||||
GSPerfMon m_perfmon_frame; // Track stat across a frame.
|
||||
GSPerfMon m_perfmon_draw; // Track stat across a draw.
|
||||
|
||||
@@ -76,3 +76,89 @@ public:
|
||||
return GetClassVertexCount(GetPrimClass(prim));
|
||||
}
|
||||
};
|
||||
|
||||
// Class that represents an octogonal bounding area with sides at 45 degree increments.
|
||||
class BoundingOct
|
||||
{
|
||||
private:
|
||||
GSVector4i bbox0; // Standard bbox.
|
||||
GSVector4i bbox1; // Bounding diamond (rotated 45 degrees axes and scaled, so (x, y) becomes (x + y, x - y)).
|
||||
|
||||
// Assumes that v is of the form { x, y, x, y }.
|
||||
static GSVector4i Rotate45(const GSVector4i& v)
|
||||
{
|
||||
const GSVector4i swap = v.yxwz();
|
||||
return (v + swap).blend32<0xa>(swap - v);
|
||||
}
|
||||
|
||||
BoundingOct(const GSVector4i& bbox0, const GSVector4i& bbox1)
|
||||
: bbox0(bbox0)
|
||||
, bbox1(bbox1)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
// Initialize to null bounding area.
|
||||
BoundingOct()
|
||||
: bbox0(GSVector4i(INT_MAX, INT_MAX, INT_MIN, INT_MIN))
|
||||
, bbox1(GSVector4i(INT_MAX, INT_MAX, INT_MIN, INT_MIN))
|
||||
{
|
||||
}
|
||||
|
||||
static BoundingOct FromPoint(GSVector4i v)
|
||||
{
|
||||
v = v.xyxy();
|
||||
return { v, Rotate45(v) };
|
||||
}
|
||||
|
||||
// The two inputs are assumed to be diagonally opposite to each other in an axis-aligned quad (i.e. sprite).
|
||||
static BoundingOct FromSprite(GSVector4i v0, GSVector4i v1)
|
||||
{
|
||||
const GSVector4i min = v0.min_i32(v1);
|
||||
const GSVector4i max = v0.max_i32(v1);
|
||||
const GSVector4i bbox = min.upl64(max);
|
||||
// Rotate45(x, y) => (x + y, x - y), we want the (min, max) result for any pair of (x, y)
|
||||
// Min: (min.x + min.y, min.x - max.y)
|
||||
// Max: (max.x + max.y, max.x - min.y)
|
||||
const GSVector4i x = GSVector4i::cast(GSVector4::cast(min).xxxx(GSVector4::cast(max))); // Don't use bbox immediately to help the compiler optimize.
|
||||
const GSVector4i y = bbox.ywwy();
|
||||
return {
|
||||
bbox,
|
||||
(x + y).blend32<0xa>(x - y),
|
||||
};
|
||||
}
|
||||
|
||||
BoundingOct Union(GSVector4i v) const
|
||||
{
|
||||
v = v.xyxy();
|
||||
return { bbox0.runion(v), bbox1.runion(Rotate45(v)) };
|
||||
}
|
||||
|
||||
BoundingOct Union(const BoundingOct& other) const
|
||||
{
|
||||
return { bbox0.runion(other.bbox0), bbox1.runion(other.bbox1) };
|
||||
}
|
||||
|
||||
BoundingOct UnionSprite(GSVector4i pt0, GSVector4i pt1) const
|
||||
{
|
||||
return Union(FromSprite(pt0, pt1));
|
||||
}
|
||||
|
||||
bool Intersects(const BoundingOct& other) const
|
||||
{
|
||||
return bbox0.rintersects(other.bbox0) && bbox1.rintersects(other.bbox1);
|
||||
}
|
||||
|
||||
BoundingOct FixDegenerate() const
|
||||
{
|
||||
return {
|
||||
bbox0.blend(bbox0 + GSVector4i(0, 0, 1, 1), bbox0.xyxy() == bbox0.zwzw()),
|
||||
bbox1.blend(bbox1 + GSVector4i(0, 0, 1, 1), bbox1.xyxy() == bbox1.zwzw()),
|
||||
};
|
||||
}
|
||||
|
||||
const GSVector4i& ToBBox()
|
||||
{
|
||||
return bbox0;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -494,6 +494,16 @@ public:
|
||||
return GSVector4i(_mm_packus_epi32(m, m));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i pkl32(const GSVector4i& a) const
|
||||
{
|
||||
return GSVector4i(_mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(m), _mm_castsi128_ps(a.m), _MM_SHUFFLE(2, 0, 2, 0))));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i pku32(const GSVector4i& a) const
|
||||
{
|
||||
return GSVector4i(_mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(m), _mm_castsi128_ps(a.m), _MM_SHUFFLE(3, 1, 3, 1))));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i upl8(const GSVector4i& a) const
|
||||
{
|
||||
return GSVector4i(_mm_unpacklo_epi8(m, a));
|
||||
@@ -840,6 +850,11 @@ public:
|
||||
return GSVector4i(_mm_srli_epi64(m, i));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i abs32() const
|
||||
{
|
||||
return GSVector4i(_mm_abs_epi32(m));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i add8(const GSVector4i& v) const
|
||||
{
|
||||
return GSVector4i(_mm_add_epi8(m, v.m));
|
||||
@@ -855,6 +870,11 @@ public:
|
||||
return GSVector4i(_mm_add_epi32(m, v.m));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i hadd32(const GSVector4i& v) const
|
||||
{
|
||||
return GSVector4i(_mm_hadd_epi32(m, v.m));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i adds8(const GSVector4i& v) const
|
||||
{
|
||||
return GSVector4i(_mm_adds_epi8(m, v.m));
|
||||
@@ -895,6 +915,11 @@ public:
|
||||
return GSVector4i(_mm_sub_epi32(m, v.m));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i hsub32(const GSVector4i& v) const
|
||||
{
|
||||
return GSVector4i(_mm_hsub_epi32(m, v.m));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i subs8(const GSVector4i& v) const
|
||||
{
|
||||
return GSVector4i(_mm_subs_epi8(m, v.m));
|
||||
@@ -1967,6 +1992,11 @@ public:
|
||||
return v ^ GSVector4i(i);
|
||||
}
|
||||
|
||||
__forceinline friend GSVector4i operator-(const GSVector4i& v)
|
||||
{
|
||||
return GSVector4i(_mm_sub_epi32(_mm_setzero_si128(), v));
|
||||
}
|
||||
|
||||
__forceinline friend GSVector4i operator~(const GSVector4i& v)
|
||||
{
|
||||
return v ^ (v == v);
|
||||
|
||||
@@ -506,6 +506,16 @@ public:
|
||||
return GSVector4i(vreinterpretq_s32_u16(vcombine_u16(vqmovun_s32(v4s), vqmovun_s32(v4s))));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i pkl32(const GSVector4i& a) const
|
||||
{
|
||||
return GSVector4i(vuzp1q_u32(v4s, a.v4s));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i pku32(const GSVector4i& a) const
|
||||
{
|
||||
return GSVector4i(vuzp2q_u32(v4s, a.v4s));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i upl8(const GSVector4i& a) const
|
||||
{
|
||||
return GSVector4i(vreinterpretq_s32_s8(vzip1q_s8(vreinterpretq_s8_s32(v4s), vreinterpretq_s8_s32(a.v4s))));
|
||||
@@ -807,6 +817,11 @@ public:
|
||||
vreinterpretq_s32_u64(vshlq_u64(vreinterpretq_u64_s32(v4s), vnegq_s64(vreinterpretq_s64_s32(v.v4s)))));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i abs32() const
|
||||
{
|
||||
return GSVector4i(vabsq_s32(v4s));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i add8(const GSVector4i& v) const
|
||||
{
|
||||
return GSVector4i(vreinterpretq_s32_s8(vaddq_s8(vreinterpretq_s8_s32(v4s), vreinterpretq_s8_s32(v.v4s))));
|
||||
@@ -822,6 +837,11 @@ public:
|
||||
return GSVector4i(vaddq_s32(v4s, v.v4s));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i hadd32(const GSVector4i& v) const
|
||||
{
|
||||
return GSVector4i(vpaddq_s32(v4s, v.v4s));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i adds8(const GSVector4i& v) const
|
||||
{
|
||||
return GSVector4i(vreinterpretq_s32_s8(vqaddq_s8(vreinterpretq_s8_s32(v4s), vreinterpretq_s8_s32(v.v4s))));
|
||||
@@ -866,6 +886,11 @@ public:
|
||||
return GSVector4i(vsubq_s32(v4s, v.v4s));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i hsub32(const GSVector4i& v) const
|
||||
{
|
||||
return GSVector4i(vsubq_u32(vuzp1q_u32(v4s, v.v4s), vuzp2q_u32(v4s, v.v4s)));
|
||||
}
|
||||
|
||||
__forceinline GSVector4i subs8(const GSVector4i& v) const
|
||||
{
|
||||
return GSVector4i(vreinterpretq_s32_s8(vqsubq_s8(vreinterpretq_s8_s32(v4s), vreinterpretq_s8_s32(v.v4s))));
|
||||
@@ -1920,6 +1945,11 @@ public:
|
||||
return v ^ GSVector4i(i);
|
||||
}
|
||||
|
||||
__forceinline friend GSVector4i operator-(const GSVector4i& v)
|
||||
{
|
||||
return GSVector4i(vnegq_s32(v.v4s));
|
||||
}
|
||||
|
||||
__forceinline friend GSVector4i operator~(const GSVector4i& v)
|
||||
{
|
||||
return GSVector4i(vmvnq_s32(v.v4s));
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "GS/Renderers/Common/GSDevice.h"
|
||||
#include "GS/GSGL.h"
|
||||
#include "GS/GS.h"
|
||||
#include "GS/GSUtil.h"
|
||||
#include "Host.h"
|
||||
|
||||
#include "common/Console.h"
|
||||
@@ -18,6 +19,8 @@
|
||||
#include "imgui.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <ostream>
|
||||
#include <fstream>
|
||||
|
||||
int SetDATMShader(SetDATM datm)
|
||||
{
|
||||
@@ -1054,6 +1057,457 @@ bool GSHWDrawConfig::BlendState::IsEffective(ColorMaskSelector colormask) const
|
||||
((colormask.key & 8u) && (src_factor_alpha != GSDevice::CONST_ONE || dst_factor_alpha != GSDevice::CONST_ZERO)));
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetTopologyName(u32 topology)
|
||||
{
|
||||
switch (static_cast<GSHWDrawConfig::Topology>(topology))
|
||||
{
|
||||
case GSHWDrawConfig::Topology::Point: return "Point";
|
||||
case GSHWDrawConfig::Topology::Line: return "Line";
|
||||
case GSHWDrawConfig::Topology::Triangle: return "Triangle";
|
||||
default: return std::to_string(topology);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetVSExpandName(u32 vsexpand)
|
||||
{
|
||||
switch (static_cast<GSHWDrawConfig::VSExpand>(vsexpand))
|
||||
{
|
||||
case GSHWDrawConfig::VSExpand::None: return "None";
|
||||
case GSHWDrawConfig::VSExpand::Point: return "Point";
|
||||
case GSHWDrawConfig::VSExpand::Line: return "Line";
|
||||
case GSHWDrawConfig::VSExpand::Sprite: return "Sprite";
|
||||
default: return std::to_string(vsexpand);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetPSDateName(u32 date)
|
||||
{
|
||||
switch (date)
|
||||
{
|
||||
case 0: return "None";
|
||||
case 1: return "0_pass_PrimID_init";
|
||||
case 2: return "1_pass_PrimID_init";
|
||||
case 3: return "PrimID_main";
|
||||
case 5: return "0_pass_main";
|
||||
case 6: return "1_pass_main";
|
||||
default: return std::to_string(date);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetPSAlphaTestName(u32 atst)
|
||||
{
|
||||
switch (static_cast<GSHWDrawConfig::PSAlphaTest>(atst))
|
||||
{
|
||||
case GSHWDrawConfig::PSAlphaTest::PS_ATST_NONE: return "NONE";
|
||||
case GSHWDrawConfig::PSAlphaTest::PS_ATST_LEQUAL: return "LEQUAL";
|
||||
case GSHWDrawConfig::PSAlphaTest::PS_ATST_GEQUAL: return "GEQUAL";
|
||||
case GSHWDrawConfig::PSAlphaTest::PS_ATST_EQUAL: return "EQUAL";
|
||||
case GSHWDrawConfig::PSAlphaTest::PS_ATST_NOTEQUAL: return "NOTEQUAL";
|
||||
default: return std::to_string(atst);
|
||||
};
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetPSDstFmtName(u32 dstfmt)
|
||||
{
|
||||
switch (dstfmt)
|
||||
{
|
||||
case 0: return "32bit";
|
||||
case 1: return "24bit";
|
||||
case 2: return "16bit";
|
||||
default: return std::to_string(dstfmt);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetPSDepthFmtName(u32 depthfmt)
|
||||
{
|
||||
switch (depthfmt)
|
||||
{
|
||||
case 0: return "None";
|
||||
case 1: return "32bit";
|
||||
case 2: return "16bit";
|
||||
case 3: return "RGBA";
|
||||
default: return std::to_string(depthfmt);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetPSBlendABDName(u32 abd)
|
||||
{
|
||||
switch (abd)
|
||||
{
|
||||
case 0: return "Cs";
|
||||
case 1: return "Cd";
|
||||
case 2: return "Zero";
|
||||
default: return std::to_string(abd);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetPSBlendCName(u32 c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 0: return "As";
|
||||
case 1: return "Ad";
|
||||
case 2: return "Af";
|
||||
default: return std::to_string(c);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetPSBlendHWName(u32 blendhw)
|
||||
{
|
||||
switch (static_cast<HWBlendType>(blendhw))
|
||||
{
|
||||
case HWBlendType::SRC_ONE_DST_FACTOR: return "SRC_ONE_DST_FACTOR";
|
||||
case HWBlendType::SRC_ALPHA_DST_FACTOR: return "SRC_ALPHA_DST_FACTOR";
|
||||
case HWBlendType::SRC_DOUBLE: return "SRC_DOUBLE";
|
||||
case HWBlendType::SRC_HALF_ONE_DST_FACTOR: return "SRC_HALF_ONE_DST_FACTOR";
|
||||
case HWBlendType::SRC_INV_DST_BLEND_HALF: return "SRC_INV_DST_BLEND_HALF";
|
||||
case HWBlendType::INV_SRC_DST_BLEND_HALF: return "INV_SRC_DST_BLEND_HALF";
|
||||
default: return std::to_string(blendhw);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetPSBlendMixName(u32 blendmix)
|
||||
{
|
||||
switch (static_cast<HWBlendType>(blendmix))
|
||||
{
|
||||
case HWBlendType::BMIX1_ALPHA_HIGH_ONE: return "BMIX1_ALPHA_HIGH_ONE";
|
||||
case HWBlendType::BMIX1_SRC_HALF: return "BMIX1_SRC_HALF";
|
||||
case HWBlendType::BMIX2_OVERFLOW: return "BMIX2_OVERFLOW";
|
||||
default: return std::to_string(blendmix);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetPSChannelName(u32 channel)
|
||||
{
|
||||
switch (channel)
|
||||
{
|
||||
case 0: return "None";
|
||||
case 1: return "FetchRed";
|
||||
case 2: return "FetchGreen";
|
||||
case 3: return "FetchBlue";
|
||||
case 4: return "FetchAlpha";
|
||||
case 5: return "FetchRGB";
|
||||
case 6: return "FetchGXBY";
|
||||
default: return std::to_string(channel);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetPSDitherName(u32 dither)
|
||||
{
|
||||
switch (dither)
|
||||
{
|
||||
case 0: return "None";
|
||||
case 1: return "Standard";
|
||||
case 2: return "ReciprocalScaled";
|
||||
default: return std::to_string(dither);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetSSTrilnName(u32 triln)
|
||||
{
|
||||
switch (static_cast<GS_MIN_FILTER>(triln))
|
||||
{
|
||||
case GS_MIN_FILTER::Nearest: return "Nearest";
|
||||
case GS_MIN_FILTER::Linear: return "Linear";
|
||||
case GS_MIN_FILTER::Nearest_Mipmap_Nearest: return "Nearest_Mipmap_Nearest";
|
||||
case GS_MIN_FILTER::Nearest_Mipmap_Linear: return "Nearest_Mipmap_Linear";
|
||||
case GS_MIN_FILTER::Linear_Mipmap_Nearest: return "Linear_Mipmap_Nearest";
|
||||
case GS_MIN_FILTER::Linear_Mipmap_Linear: return "Linear_Mipmap_Linear";
|
||||
default: return std::to_string(triln);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetBlendOpName(u32 blendop)
|
||||
{
|
||||
switch (blendop)
|
||||
{
|
||||
case 0: return "ADD";
|
||||
case 1: return "SUBTRACT";
|
||||
case 2: return "REVERSE_SUBTRACT";
|
||||
default: return std::to_string(blendop);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetBlendFactorName(u32 blendfactor)
|
||||
{
|
||||
switch (blendfactor)
|
||||
{
|
||||
case 0: return "SRC_COLOR";
|
||||
case 1: return "ONE_MINUS_SRC_COLOR";
|
||||
case 2: return "DST_COLOR";
|
||||
case 3: return "ONE_MINUS_DST_COLOR";
|
||||
case 4: return "SRC1_COLOR";
|
||||
case 5: return "ONE_MINUS_SRC1_COLOR";
|
||||
case 6: return "SRC_ALPHA";
|
||||
case 7: return "ONE_MINUS_SRC_ALPHA";
|
||||
case 8: return "DST_ALPHA";
|
||||
case 9: return "ONE_MINUS_DST_ALPHA";
|
||||
case 10: return "SRC1_ALPHA";
|
||||
case 11: return "ONE_MINUS_SRC1_ALPHA";
|
||||
case 12: return "CONSTANT_COLOR";
|
||||
case 13: return "ONE_MINUS_CONSTANT_COLOR";
|
||||
case 14: return "ONE";
|
||||
case 15: return "ZERO";
|
||||
default: return std::to_string(blendfactor);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetDestinationAlphaModeName(u32 datm)
|
||||
{
|
||||
switch (static_cast<GSHWDrawConfig::DestinationAlphaMode>(datm))
|
||||
{
|
||||
case GSHWDrawConfig::DestinationAlphaMode::Off: return "Off";
|
||||
case GSHWDrawConfig::DestinationAlphaMode::Stencil: return "Stencil";
|
||||
case GSHWDrawConfig::DestinationAlphaMode::StencilOne: return "StencilOne";
|
||||
case GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking: return "PrimIDTracking";
|
||||
case GSHWDrawConfig::DestinationAlphaMode::Full: return "Full";
|
||||
default: return std::to_string(datm);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetColClipModeName(u32 ccmode)
|
||||
{
|
||||
switch (static_cast<GSHWDrawConfig::ColClipMode>(ccmode))
|
||||
{
|
||||
case GSHWDrawConfig::ColClipMode::NoModify: return "NoModify";
|
||||
case GSHWDrawConfig::ColClipMode::ConvertOnly: return "ConvertOnly";
|
||||
case GSHWDrawConfig::ColClipMode::ResolveOnly: return "ResolveOnly";
|
||||
case GSHWDrawConfig::ColClipMode::ConvertAndResolve: return "ConvertAndResolve";
|
||||
case GSHWDrawConfig::ColClipMode::EarlyResolve: return "EarlyResolve";
|
||||
default: return std::to_string(ccmode);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSHWDrawConfig::GetSetDATMName(u32 datm)
|
||||
{
|
||||
switch (static_cast<SetDATM>(datm))
|
||||
{
|
||||
case SetDATM::DATM0: return "DATM0";
|
||||
case SetDATM::DATM1: return "DATM1";
|
||||
case SetDATM::DATM0_RTA_CORRECTION: return "DATM0_RTA_CORRECTION";
|
||||
case SetDATM::DATM1_RTA_CORRECTION: return "DATM1_RTA_CORRECTION";
|
||||
default: return std::to_string(datm);
|
||||
};
|
||||
}
|
||||
|
||||
static constexpr const char* INDENT = " ";
|
||||
|
||||
void GSHWDrawConfig::DumpPSSelector(std::ostream& out, const PSSelector& ps, const std::string& indent)
|
||||
{
|
||||
out.imbue(std::locale::classic()); // Disable integer separators
|
||||
out << std::dec;
|
||||
|
||||
out << indent << "aem_fmt: " << static_cast<u32>(ps.aem_fmt) << std::endl;
|
||||
out << indent << "pal_fmt: " << static_cast<u32>(ps.pal_fmt) << std::endl;
|
||||
out << indent << "dst_fmt: " << static_cast<u32>(ps.dst_fmt) << " # " << GetPSDstFmtName(static_cast<u32>(ps.dst_fmt)) << std::endl;
|
||||
out << indent << "depth_fmt: " << static_cast<u32>(ps.depth_fmt) << " # " << GetPSDepthFmtName(static_cast<u32>(ps.depth_fmt)) << std::endl;
|
||||
out << indent << "aem: " << static_cast<u32>(ps.aem) << std::endl;
|
||||
out << indent << "fba: " << static_cast<u32>(ps.fba) << std::endl;
|
||||
out << indent << "fog: " << static_cast<u32>(ps.fog) << std::endl;
|
||||
out << indent << "iip: " << static_cast<u32>(ps.iip) << std::endl;
|
||||
out << indent << "date: " << static_cast<u32>(ps.date) << " # " << GetPSDateName(static_cast<u32>(ps.date)) << std::endl;
|
||||
out << indent << "atst: " << static_cast<u32>(ps.atst) << " # " << GetPSAlphaTestName(static_cast<u32>(ps.atst)) << std::endl;
|
||||
out << indent << "afail: " << static_cast<u32>(ps.afail) << " # " << GSUtil::GetAFAILName(static_cast<u32>(ps.afail)) << std::endl;
|
||||
out << indent << "fst: " << static_cast<u32>(ps.fst) << std::endl;
|
||||
out << indent << "tfx: " << static_cast<u32>(ps.tfx) << std::endl;
|
||||
out << indent << "tcc: " << GSUtil::GetTCCName(static_cast<u32>(ps.tcc)) << std::endl;
|
||||
out << indent << "wms: " << static_cast<u32>(ps.tcc) << " # " << static_cast<u32>(ps.wms) << std::endl;
|
||||
out << indent << "wmt: " << static_cast<u32>(ps.wmt) << std::endl;
|
||||
out << indent << "adjs: " << static_cast<u32>(ps.adjs) << std::endl;
|
||||
out << indent << "adjt: " << static_cast<u32>(ps.adjt) << std::endl;
|
||||
out << indent << "ltf: " << static_cast<u32>(ps.ltf) << std::endl;
|
||||
out << indent << "shuffle: " << static_cast<u32>(ps.shuffle) << std::endl;
|
||||
out << indent << "shuffle_same: " << static_cast<u32>(ps.shuffle_same) << std::endl;
|
||||
out << indent << "real16src: " << static_cast<u32>(ps.real16src) << std::endl;
|
||||
out << indent << "process_ba: " << static_cast<u32>(ps.process_ba) << std::endl;
|
||||
out << indent << "process_rg: " << static_cast<u32>(ps.process_rg) << std::endl;
|
||||
out << indent << "shuffle_across: " << static_cast<u32>(ps.shuffle_across) << std::endl;
|
||||
out << indent << "write_rg: " << static_cast<u32>(ps.write_rg) << std::endl;
|
||||
out << indent << "fbmask: " << static_cast<u32>(ps.fbmask) << std::endl;
|
||||
out << indent << "blend_a: " << static_cast<u32>(ps.blend_a) << " # " << GetPSBlendABDName(static_cast<u32>(ps.blend_a)) << std::endl;
|
||||
out << indent << "blend_b: " << static_cast<u32>(ps.blend_b) << " # " << GetPSBlendABDName(static_cast<u32>(ps.blend_b)) << std::endl;
|
||||
out << indent << "blend_c: " << static_cast<u32>(ps.blend_c) << " # " << GetPSBlendCName(static_cast<u32>(ps.blend_c)) << std::endl;
|
||||
out << indent << "blend_d: " << static_cast<u32>(ps.blend_d) << " # " << GetPSBlendABDName(static_cast<u32>(ps.blend_d)) << std::endl;
|
||||
out << indent << "fixed_one_a: " << static_cast<u32>(ps.fixed_one_a) << std::endl;
|
||||
out << indent << "blend_hw: " << static_cast<u32>(ps.blend_hw) << " # " << GetPSBlendHWName(static_cast<u32>(ps.blend_hw)) << std::endl;
|
||||
out << indent << "a_masked: " << static_cast<u32>(ps.a_masked) << std::endl;
|
||||
out << indent << "colclip_hw: " << static_cast<u32>(ps.colclip_hw) << std::endl;
|
||||
out << indent << "rta_correction: " << static_cast<u32>(ps.rta_correction) << std::endl;
|
||||
out << indent << "rta_source_correction: " << static_cast<u32>(ps.rta_source_correction) << std::endl;
|
||||
out << indent << "colclip: " << static_cast<u32>(ps.colclip) << std::endl;
|
||||
out << indent << "blend_mix: " << static_cast<u32>(ps.blend_mix) << " # " << GetPSBlendMixName(static_cast<u32>(ps.blend_mix)) << std::endl;
|
||||
out << indent << "round_inv: " << static_cast<u32>(ps.round_inv) << std::endl;
|
||||
out << indent << "pabe: " << static_cast<u32>(ps.pabe) << std::endl;
|
||||
out << indent << "no_color: " << static_cast<u32>(ps.no_color) << std::endl;
|
||||
out << indent << "no_color1: " << static_cast<u32>(ps.no_color1) << std::endl;
|
||||
out << indent << "channel: " << static_cast<u32>(ps.channel) << " # " << GetPSChannelName(static_cast<u32>(ps.channel)) << std::endl;
|
||||
out << indent << "channel_fb: " << static_cast<u32>(ps.channel_fb) << std::endl;
|
||||
out << indent << "dither: " << static_cast<u32>(ps.dither) << " # " << GetPSDitherName(static_cast<u32>(ps.dither)) << std::endl;
|
||||
out << indent << "dither_adjust: " << static_cast<u32>(ps.dither_adjust) << std::endl;
|
||||
out << indent << "zclamp: " << static_cast<u32>(ps.zclamp) << std::endl;
|
||||
out << indent << "tcoffsethack: " << static_cast<u32>(ps.tcoffsethack) << std::endl;
|
||||
out << indent << "urban_chaos_hle: " << static_cast<u32>(ps.urban_chaos_hle) << std::endl;
|
||||
out << indent << "tales_of_abyss_hle: " << static_cast<u32>(ps.tales_of_abyss_hle) << std::endl;
|
||||
out << indent << "tex_is_fb: " << static_cast<u32>(ps.tex_is_fb) << std::endl;
|
||||
out << indent << "automatic_lod: " << static_cast<u32>(ps.automatic_lod) << std::endl;
|
||||
out << indent << "manual_lod: " << static_cast<u32>(ps.manual_lod) << std::endl;
|
||||
out << indent << "point_sampler: " << static_cast<u32>(ps.point_sampler) << std::endl;
|
||||
out << indent << "region_rect: " << static_cast<u32>(ps.region_rect) << std::endl;
|
||||
out << indent << "scanmsk: " << static_cast<u32>(ps.scanmsk) << " # " << GSUtil::GetSCANMSKName(static_cast<u32>(ps.scanmsk)) << std::endl;
|
||||
}
|
||||
|
||||
void GSHWDrawConfig::DumpVSSelector(std::ostream& out, const VSSelector& vs, const std::string& indent)
|
||||
{
|
||||
out.imbue(std::locale::classic()); // Disable integer separators
|
||||
out << std::dec;
|
||||
|
||||
out << indent << "fst: " << static_cast<u32>(vs.fst) << std::endl;
|
||||
out << indent << "tme: " << static_cast<u32>(vs.tme) << std::endl;
|
||||
out << indent << "iip: " << static_cast<u32>(vs.iip) << std::endl;
|
||||
out << indent << "point_size: " << static_cast<u32>(vs.point_size) << std::endl;
|
||||
out << indent << "expand: " << static_cast<u32>(vs.expand) << " # " << GetVSExpandName(static_cast<u32>(vs.expand)) << std::endl;
|
||||
}
|
||||
|
||||
void GSHWDrawConfig::DumpBlendState(std::ostream& out, const BlendState& bs, const std::string& indent)
|
||||
{
|
||||
out.imbue(std::locale::classic()); // Disable integer separators
|
||||
out << std::dec;
|
||||
|
||||
out << indent << "enable: " << static_cast<u32>(bs.enable) << std::endl;
|
||||
out << indent << "constant_enable: " << static_cast<u32>(bs.constant_enable) << std::endl;
|
||||
out << indent << "op: " << static_cast<u32>(bs.op) << " # " << GetBlendOpName(static_cast<u32>(bs.op)) << std::endl;
|
||||
out << indent << "src_factor: " << static_cast<u32>(bs.src_factor) << " # " << GetBlendFactorName(static_cast<u32>(bs.src_factor)) << std::endl;
|
||||
out << indent << "dst_factor: " << static_cast<u32>(bs.dst_factor) << " # " << GetBlendFactorName(static_cast<u32>(bs.dst_factor)) << std::endl;
|
||||
out << indent << "src_factor_alpha: " << static_cast<u32>(bs.src_factor_alpha) << " # " << GetBlendFactorName(static_cast<u32>(bs.src_factor_alpha)) << std::endl;
|
||||
out << indent << "dst_factor_alpha: " << static_cast<u32>(bs.dst_factor_alpha) << " # " << GetBlendFactorName(static_cast<u32>(bs.dst_factor_alpha)) << std::endl;
|
||||
out << indent << "constant: " << static_cast<u32>(bs.constant) << std::endl;
|
||||
}
|
||||
|
||||
void GSHWDrawConfig::DumpDepthStencilSelctor(std::ostream& out, const DepthStencilSelector& dss, const std::string& indent)
|
||||
{
|
||||
out.imbue(std::locale::classic()); // Disable integer separators
|
||||
out << std::dec;
|
||||
|
||||
out << indent << "ztst: " << static_cast<u32>(dss.ztst) << " # " << GSUtil::GetZTSTName(static_cast<u32>(dss.ztst)) << std::endl;
|
||||
out << indent << "zwe: " << static_cast<u32>(dss.zwe) << std::endl;
|
||||
out << indent << "date: " << static_cast<u32>(dss.date) << std::endl;
|
||||
out << indent << "date_one: " << static_cast<u32>(dss.date_one) << std::endl;
|
||||
}
|
||||
|
||||
void GSHWDrawConfig::DumpSamplerSelector(std::ostream& out, const SamplerSelector& ss, const std::string& indent)
|
||||
{
|
||||
out.imbue(std::locale::classic()); // Disable integer separators
|
||||
out << std::dec;
|
||||
|
||||
out << indent << "tau: " << static_cast<u32>(ss.tau) << std::endl;
|
||||
out << indent << "tav: " << static_cast<u32>(ss.tav) << std::endl;
|
||||
out << indent << "biln: " << static_cast<u32>(ss.biln) << std::endl;
|
||||
out << indent << "triln: " << static_cast<u32>(ss.triln) << " # " << GetSSTrilnName(static_cast<u32>(ss.triln)) << std::endl;
|
||||
out << indent << "aniso: " << static_cast<u32>(ss.aniso) << std::endl;
|
||||
out << indent << "lodclamp: " << static_cast<u32>(ss.lodclamp) << std::endl;
|
||||
}
|
||||
|
||||
void GSHWDrawConfig::DumpAlphaPass(std::ostream& out, const AlphaPass& ap, const std::string& indent)
|
||||
{
|
||||
out.imbue(std::locale::classic()); // Disable integer separators
|
||||
out << std::dec;
|
||||
|
||||
out << indent << "enable: " << static_cast<u32>(ap.enable) << std::endl;
|
||||
out << indent << "require_one_barrier: " << static_cast<u32>(ap.require_one_barrier) << std::endl;
|
||||
out << indent << "require_full_barrier: " << static_cast<u32>(ap.require_full_barrier) << std::endl;
|
||||
out << indent << "colormask: " << std::showbase << std::hex << static_cast<u32>(ap.colormask.wrgba) << std::dec << std::endl;
|
||||
out << indent << "ps_aref: " << static_cast<u32>(ap.ps_aref) << std::endl;
|
||||
|
||||
out << indent << "ps:" << std::endl;
|
||||
DumpPSSelector(out, ap.ps, indent + INDENT);
|
||||
|
||||
out << indent << "dss:" << std::endl;
|
||||
DumpDepthStencilSelctor(out, ap.depth, indent + INDENT);
|
||||
}
|
||||
|
||||
void GSHWDrawConfig::DumpBlendMultipass(std::ostream& out, const BlendMultiPass& bmp, const std::string& indent)
|
||||
{
|
||||
out.imbue(std::locale::classic()); // Disable integer separators
|
||||
out << std::dec;
|
||||
|
||||
out << indent << "enable: " << static_cast<u32>(bmp.enable) << std::endl;
|
||||
out << indent << "no_color1: " << static_cast<u32>(bmp.no_color1) << std::endl;
|
||||
out << indent << "blend_hw: " << static_cast<u32>(bmp.blend_hw) << " # " << GetPSBlendHWName(static_cast<u32>(bmp.blend_hw)) << std::endl;
|
||||
out << indent << "dither: " << static_cast<u32>(bmp.dither) << std::endl;
|
||||
|
||||
out << indent << "blend:" << std::endl;
|
||||
DumpBlendState(out, bmp.blend, indent + INDENT);
|
||||
}
|
||||
|
||||
void GSHWDrawConfig::DumpConfig(std::ostream& out, const GSHWDrawConfig& conf,
|
||||
bool ps, bool vs, bool bs, bool dss, bool ss, bool asp, bool bmp)
|
||||
{
|
||||
out.imbue(std::locale::classic()); // Disable integer separators
|
||||
out << std::dec;
|
||||
|
||||
out << "topology: " << static_cast<u32>(conf.topology) << " # " << GetTopologyName(static_cast<u32>(conf.topology)) << std::endl;
|
||||
out << "require_one_barrier: " << static_cast<u32>(conf.require_one_barrier) << std::endl;
|
||||
out << "require_full_barrier: " << static_cast<u32>(conf.require_full_barrier) << std::endl;
|
||||
|
||||
out << "destination_alpha: " << static_cast<u32>(conf.destination_alpha) << " # " << GetDestinationAlphaModeName(static_cast<u32>(conf.destination_alpha)) << std::endl;
|
||||
out << "datm: " << static_cast<u32>(conf.datm) << " # " << GetSetDATMName(static_cast<u32>(conf.datm)) << std::endl;
|
||||
out << "line_expand: " << conf.line_expand << std::endl;
|
||||
out << "colormask: " << std::hex << std::showbase << static_cast<u32>(conf.colormask.wrgba) << std::dec << std::endl;
|
||||
|
||||
if (ps)
|
||||
{
|
||||
out << "ps:" << std::endl;
|
||||
DumpPSSelector(out, conf.ps, INDENT);
|
||||
}
|
||||
|
||||
if (vs)
|
||||
{
|
||||
out << "vs:" << std::endl;
|
||||
DumpVSSelector(out, conf.vs, INDENT);
|
||||
}
|
||||
|
||||
if (bs)
|
||||
{
|
||||
out << "blend:" << std::endl;
|
||||
DumpBlendState(out, conf.blend, INDENT);
|
||||
}
|
||||
|
||||
if (ss)
|
||||
{
|
||||
out << "sampler:" << std::endl;
|
||||
DumpSamplerSelector(out, conf.sampler, INDENT);
|
||||
}
|
||||
|
||||
if (dss)
|
||||
{
|
||||
out << "depth:" << std::endl;
|
||||
DumpDepthStencilSelctor(out, conf.depth, INDENT);
|
||||
}
|
||||
|
||||
if (asp)
|
||||
{
|
||||
out << "alpha_second_pass:" << std::endl;
|
||||
DumpAlphaPass(out, conf.alpha_second_pass, INDENT);
|
||||
}
|
||||
|
||||
if (bmp)
|
||||
{
|
||||
out << "blend_multi_pass:" << std::endl;
|
||||
DumpBlendMultipass(out, conf.blend_multi_pass, INDENT);
|
||||
}
|
||||
}
|
||||
|
||||
void GSHWDrawConfig::DumpConfig(const std::string& fn, const GSHWDrawConfig& conf,
|
||||
bool ps, bool vs, bool bs, bool dss, bool ss, bool asp, bool bmp)
|
||||
{
|
||||
std::ofstream file(fn);
|
||||
|
||||
if (!file.is_open())
|
||||
return;
|
||||
|
||||
DumpConfig(file, conf, ps, vs, bs, dss, ss, asp, bmp);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
||||
// Maps PS2 blend modes to our best approximation of them with PC hardware
|
||||
|
||||
@@ -328,6 +328,16 @@ struct alignas(16) GSHWDrawConfig
|
||||
};
|
||||
static_assert(sizeof(VSSelector) == 1, "VSSelector is a single byte");
|
||||
#pragma pack(pop)
|
||||
|
||||
enum PSAlphaTest
|
||||
{
|
||||
PS_ATST_NONE = 0,
|
||||
PS_ATST_LEQUAL = 1,
|
||||
PS_ATST_GEQUAL = 2,
|
||||
PS_ATST_EQUAL = 3,
|
||||
PS_ATST_NOTEQUAL = 4
|
||||
};
|
||||
|
||||
#pragma pack(push, 4)
|
||||
struct PSSelector
|
||||
{
|
||||
@@ -780,6 +790,37 @@ struct alignas(16) GSHWDrawConfig
|
||||
ColClipMode colclip_mode;
|
||||
GIFRegFRAME colclip_frame;
|
||||
GSVector4i colclip_update_area; ///< Area in the framebuffer which colclip will modify;
|
||||
|
||||
// Dumping
|
||||
static std::string GetTopologyName(u32 topology);
|
||||
static std::string GetVSExpandName(u32 vsexpand);
|
||||
static std::string GetPSAlphaTestName(u32 dstfmt);
|
||||
static std::string GetPSDstFmtName(u32 dstfmt);
|
||||
static std::string GetPSDepthFmtName(u32 depthfmt);
|
||||
static std::string GetPSBlendABDName(u32 abd);
|
||||
static std::string GetPSBlendCName(u32 c);
|
||||
static std::string GetPSBlendHWName(u32 blendhw);
|
||||
static std::string GetPSBlendMixName(u32 blendmix);
|
||||
static std::string GetPSDitherName(u32 dither);
|
||||
static std::string GetPSChannelName(u32 channel);
|
||||
static std::string GetSSTrilnName(u32 triln);
|
||||
static std::string GetBlendOpName(u32 blendop);
|
||||
static std::string GetBlendFactorName(u32 blendfactor);
|
||||
static std::string GetDestinationAlphaModeName(u32 datm);
|
||||
static std::string GetPSDateName(u32 date);
|
||||
static std::string GetColClipModeName(u32 ccmode);
|
||||
static std::string GetSetDATMName(u32 setdatm);
|
||||
static void DumpPSSelector(std::ostream& out, const PSSelector& ps, const std::string& indent = "");
|
||||
static void DumpVSSelector(std::ostream& out, const VSSelector& vs, const std::string& indent = "");
|
||||
static void DumpBlendState(std::ostream& out, const BlendState& bs, const std::string& indent = "");
|
||||
static void DumpDepthStencilSelctor(std::ostream& out, const DepthStencilSelector& ds, const std::string& indent = "");
|
||||
static void DumpSamplerSelector(std::ostream& out, const SamplerSelector& ss, const std::string& indent = "");
|
||||
static void DumpAlphaPass(std::ostream& out, const AlphaPass& ap, const std::string& indent = "");
|
||||
static void DumpBlendMultipass(std::ostream& out, const BlendMultiPass& bmp, const std::string& indent = "");
|
||||
static void DumpConfig(std::ostream& out, const GSHWDrawConfig& conf,
|
||||
bool ps = true, bool vs = true, bool bs = true, bool dss = true, bool ss = true, bool asp = true, bool bmp = true);
|
||||
static void DumpConfig(const std::string& fn, const GSHWDrawConfig& conf,
|
||||
bool ps = true, bool vs = true, bool bs = true, bool dss = true, bool ss = true, bool asp = true, bool bmp = true);
|
||||
};
|
||||
|
||||
static inline u32 GetExpansionFactor(GSHWDrawConfig::VSExpand expand)
|
||||
|
||||
@@ -575,7 +575,7 @@ void GSRenderer::VSync(u32 field, bool registers_written, bool idle_frame)
|
||||
{
|
||||
if (GSConfig.SaveInfo)
|
||||
{
|
||||
DumpGSPrivRegs(*m_regs, GetDrawDumpPath("%05d_f%05lld_vsync_gs_reg.txt", s_n, g_perfmon.GetFrame()));
|
||||
DumpGSPrivRegs(*m_regs, GetDrawDumpPath("%05lld_f%05lld_vsync_gs_reg.txt", s_n, g_perfmon.GetFrame()));
|
||||
|
||||
DumpDrawInfo(false, false, true);
|
||||
}
|
||||
@@ -586,7 +586,7 @@ void GSRenderer::VSync(u32 field, bool registers_written, bool idle_frame)
|
||||
if (GSConfig.SaveFrameStats)
|
||||
{
|
||||
m_perfmon_frame = g_perfmon - m_perfmon_frame;
|
||||
m_perfmon_frame.Dump(GetDrawDumpPath("%05d_f%05lld_frame_stats.txt", s_n, g_perfmon.GetFrame()), GSIsHardwareRenderer());
|
||||
m_perfmon_frame.Dump(GetDrawDumpPath("%05lld_f%05lld_frame_stats.txt", s_n, g_perfmon.GetFrame()), GSIsHardwareRenderer());
|
||||
m_perfmon_frame = g_perfmon;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ private:
|
||||
u32 m_skipped_duplicate_frames = 0;
|
||||
|
||||
// Tracking draw counters for idle frame detection.
|
||||
int m_last_draw_n = 0;
|
||||
int m_last_transfer_n = 0;
|
||||
u64 m_last_draw_n = 0;
|
||||
u64 m_last_transfer_n = 0;
|
||||
|
||||
protected:
|
||||
GSVector2i m_real_size{0, 0};
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "IconsFontAwesome.h"
|
||||
|
||||
#include <appmodel.h>
|
||||
#include <array>
|
||||
#include <d3d11.h>
|
||||
#include <d3d12.h>
|
||||
@@ -382,29 +381,7 @@ GSRendererType D3D::GetPreferredRenderer()
|
||||
return device;
|
||||
};
|
||||
#ifdef ENABLE_VULKAN
|
||||
static constexpr auto check_for_mapping_layers = []() {
|
||||
PCWSTR familyName = L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe";
|
||||
UINT32 numPackages = 0, bufferLength = 0;
|
||||
const DWORD error = GetPackagesByPackageFamily(familyName, &numPackages, nullptr, &bufferLength, nullptr);
|
||||
if (error == ERROR_INSUFFICIENT_BUFFER || numPackages > 0)
|
||||
{
|
||||
Host::AddIconOSDMessage("VKDriverUnsupported", ICON_FA_TV,
|
||||
TRANSLATE_STR("GS",
|
||||
"Your system has the \"OpenCL, OpenGL, and Vulkan Compatibility Pack\" installed.\n"
|
||||
"This Vulkan driver crashes PCSX2 on some GPUs.\n"
|
||||
"To use the Vulkan renderer, you should remove this app package."),
|
||||
Host::OSD_WARNING_DURATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
static constexpr auto check_vulkan_supported = []() {
|
||||
// Don't try to enumerate Vulkan devices if the DX12 Vulkan driver is present.
|
||||
// It crashes on AMD GPUs.
|
||||
if (check_for_mapping_layers())
|
||||
return false;
|
||||
|
||||
if (!GSDeviceVK::EnumerateGPUs().empty())
|
||||
return true;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user