diff --git a/.github/workflows/cron_update_base_translation.yml b/.github/workflows/cron_update_base_translation.yml index 15706c166e..0baeb23377 100644 --- a/.github/workflows/cron_update_base_translation.yml +++ b/.github/workflows/cron_update_base_translation.yml @@ -17,7 +17,7 @@ jobs: run: ./.github/workflows/scripts/common/update_base_translation.sh - name: Create Pull Request - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79 with: title: "Qt: Update Base Translation" commit-message: "[ci skip] Qt: Update Base Translation." diff --git a/.github/workflows/cron_update_controller_db.yml b/.github/workflows/cron_update_controller_db.yml index d3cdf2605f..126e3739bf 100644 --- a/.github/workflows/cron_update_controller_db.yml +++ b/.github/workflows/cron_update_controller_db.yml @@ -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@v7 + uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79 with: title: "PAD: Update to latest controller database" commit-message: "[ci skip] PAD: Update to latest controller database." diff --git a/.github/workflows/macos_build.yml b/.github/workflows/macos_build.yml index cf42de647b..7a0898d4d2 100644 --- a/.github/workflows/macos_build.yml +++ b/.github/workflows/macos_build.yml @@ -35,7 +35,7 @@ jobs: name: ${{ inputs.jobName }} runs-on: ${{ inputs.os }} # Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them. - timeout-minutes: 90 + timeout-minutes: 120 env: POWERSHELL_TELEMETRY_OPTOUT: 1 CCACHE_BASEDIR: ${{ github.workspace }} @@ -160,7 +160,7 @@ jobs: - name: Sign the Application if: ${{ inputs.sign_and_notarize == true && env.SIGN_KEY }} - uses: indygreg/apple-code-sign-action@v1.1 + uses: indygreg/apple-code-sign-action@44d0985b7f4363198e80b6fea63ac3e9dd3e9957 with: input_path: 'PCSX2.app' p12_file: cert.p12 diff --git a/.github/workflows/release_cut_new.yml b/.github/workflows/release_cut_new.yml index a6a8abd91e..61280bde10 100644 --- a/.github/workflows/release_cut_new.yml +++ b/.github/workflows/release_cut_new.yml @@ -40,7 +40,7 @@ jobs: # Docs - https://github.com/mathieudutour/github-tag-action - name: Bump Version and Push Tag id: tag_version - uses: mathieudutour/github-tag-action@v6.2 + uses: mathieudutour/github-tag-action@a22cf08638b34d5badda920f9daf6e72c477b07b with: github_token: ${{ github.token }} tag_prefix: v @@ -68,7 +68,7 @@ jobs: mv ./release-notes.md ${GITHUB_WORKSPACE}/release-notes.md - name: Create a GitHub Release (Manual) - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda if: steps.tag_version.outputs.new_tag && github.event_name == 'workflow_dispatch' with: body_path: ./release-notes.md @@ -77,7 +77,7 @@ jobs: tag_name: ${{ steps.tag_version.outputs.new_tag }} - name: Create a GitHub Release (Push) - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda if: steps.tag_version.outputs.new_tag && github.event_name != 'workflow_dispatch' with: body_path: ./release-notes.md diff --git a/.github/workflows/scripts/linux/build-dependencies-qt.sh b/.github/workflows/scripts/linux/build-dependencies-qt.sh index cc854588fb..261898cbf9 100755 --- a/.github/workflows/scripts/linux/build-dependencies-qt.sh +++ b/.github/workflows/scripts/linux/build-dependencies-qt.sh @@ -15,14 +15,14 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then fi LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075 -LIBJPEG=9f +LIBJPEGTURBO=3.1.0 LIBPNG=1.6.45 LIBWEBP=1.5.0 LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29 -SDL=SDL3-3.2.8 -QT=6.8.2 +SDL=SDL3-3.2.10 +QT=6.9.0 ZSTD=1.5.7 -KDDOCKWIDGETS=2.2.1 +KDDOCKWIDGETS=2.2.3 SHADERC=2024.1 SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec @@ -34,28 +34,28 @@ cd deps-build cat > SHASUMS < " + exit 1 +fi + +DEPSDIR=$(realpath "$1") +INSTALLDIR=$(realpath "$2") + +if [ ! -d "$DEPSDIR/include/QtCore" ]; then + echo "Error: The build-dependencies-qt.sh script must be run on the deps directory first." + exit 1 +fi + +GAMMARAY=master + +mkdir -p gammaray-build +cd gammaray-build + +echo "Downloading..." +curl -L -o "GammaRay-$GAMMARAY.tar.gz" https://github.com/KDAB/GammaRay/archive/$GAMMARAY.tar.gz + +rm -fr "GammaRay-$GAMMARAY" + +echo "Extracting..." +tar xf "GammaRay-$GAMMARAY.tar.gz" + +cd "GammaRay-$GAMMARAY" +mkdir build +cd build + +echo "Configuring..." +cmake -DCMAKE_PREFIX_PATH="$DEPSDIR" -G Ninja -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DGAMMARAY_BUILD_DOCS=false .. + +echo "Building..." +cmake --build . --parallel + +echo "Installing..." +cmake --build . --target install + +cd ../.. + +echo "Cleaning up..." +cd .. +rm -r gammaray-build diff --git a/.github/workflows/scripts/linux/flatpak/modules/20-sdl3.json b/.github/workflows/scripts/linux/flatpak/modules/20-sdl3.json index 82223c39b8..626811736c 100644 --- a/.github/workflows/scripts/linux/flatpak/modules/20-sdl3.json +++ b/.github/workflows/scripts/linux/flatpak/modules/20-sdl3.json @@ -14,8 +14,8 @@ "sources": [ { "type": "archive", - "url": "https://libsdl.org/release/SDL3-3.2.8.tar.gz", - "sha256": "13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03" + "url": "https://libsdl.org/release/SDL3-3.2.10.tar.gz", + "sha256": "f87be7b4dec66db4098e9c167b2aa34e2ca10aeb5443bdde95ae03185ed513e0" } ], "cleanup": [ diff --git a/.github/workflows/scripts/linux/flatpak/modules/23-kddockwidgets.json b/.github/workflows/scripts/linux/flatpak/modules/23-kddockwidgets.json index f10cb70050..a37d141280 100644 --- a/.github/workflows/scripts/linux/flatpak/modules/23-kddockwidgets.json +++ b/.github/workflows/scripts/linux/flatpak/modules/23-kddockwidgets.json @@ -14,8 +14,8 @@ { "type": "git", "url": "https://github.com/KDAB/KDDockWidgets.git", - "tag": "v2.2.1", - "commit": "3aaccddc00a11a643e0959a24677838993de15ac", + "tag": "v2.2.3", + "commit": "28d16d0431d7cdc9f36cb619d22621146fdfab44", "disable-submodules": true }, { diff --git a/.github/workflows/scripts/macos/build-dependencies-universal.sh b/.github/workflows/scripts/macos/build-dependencies-universal.sh index b1a34ad4e9..8b92e2c719 100755 --- a/.github/workflows/scripts/macos/build-dependencies-universal.sh +++ b/.github/workflows/scripts/macos/build-dependencies-universal.sh @@ -40,16 +40,16 @@ fi FREETYPE=2.13.3 HARFBUZZ=10.0.1 -SDL=SDL3-3.2.8 +SDL=SDL3-3.2.10 ZSTD=1.5.7 LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29 LIBPNG=1.6.45 -LIBJPEG=9f +LIBJPEGTURBO=3.1.0 LIBWEBP=1.5.0 FFMPEG=6.0 MOLTENVK=1.2.9 -QT=6.7.2 -KDDOCKWIDGETS=2.2.1 +QT=6.7.3 +KDDOCKWIDGETS=2.2.3 SHADERC=2024.1 SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec @@ -77,24 +77,24 @@ CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" cat > SHASUMS < SHASUMS <= 18" - } - }, - "node_modules/@octokit/rest/node_modules/@octokit/auth-token": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz", "integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==", @@ -134,7 +22,7 @@ "node": ">= 18" } }, - "node_modules/@octokit/rest/node_modules/@octokit/core": { + "node_modules/@octokit/core": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz", "integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==", @@ -152,7 +40,22 @@ "node": ">= 18" } }, - "node_modules/@octokit/rest/node_modules/@octokit/endpoint": { + "node_modules/@octokit/core/node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "license": "MIT" + }, + "node_modules/@octokit/core/node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" + } + }, + "node_modules/@octokit/endpoint": { "version": "10.1.3", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz", "integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==", @@ -165,7 +68,22 @@ "node": ">= 18" } }, - "node_modules/@octokit/rest/node_modules/@octokit/graphql": { + "node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "license": "MIT" + }, + "node_modules/@octokit/endpoint/node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" + } + }, + "node_modules/@octokit/graphql": { "version": "8.2.1", "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz", "integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==", @@ -179,6 +97,139 @@ "node": ">= 18" } }, + "node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "license": "MIT" + }, + "node_modules/@octokit/graphql/node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz", + "integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw==" + }, + "node_modules/@octokit/plugin-retry": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz", + "integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==", + "dependencies": { + "@octokit/types": "^6.0.3", + "bottleneck": "^2.15.3" + } + }, + "node_modules/@octokit/plugin-throttling": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.6.0.tgz", + "integrity": "sha512-zn7m1N3vpJDaVzLqjCRdJ0cRzNiekHEWPi8Ww9xyPNrDt5PStHvVE0eR8wy4RSU8Eg7YO8MHyvn6sv25EGVhhg==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.7.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^6.1.3" + } + }, + "node_modules/@octokit/plugin-throttling/node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "license": "MIT" + }, + "node_modules/@octokit/plugin-throttling/node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" + } + }, + "node_modules/@octokit/request": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz", + "integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==", + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^10.1.3", + "@octokit/request-error": "^6.1.7", + "@octokit/types": "^13.6.2", + "fast-content-type-parse": "^2.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz", + "integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.6.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "license": "MIT" + }, + "node_modules/@octokit/request-error/node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" + } + }, + "node_modules/@octokit/request/node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "license": "MIT" + }, + "node_modules/@octokit/request/node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" + } + }, + "node_modules/@octokit/rest": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz", + "integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==", + "license": "MIT", + "dependencies": { + "@octokit/core": "^6.1.4", + "@octokit/plugin-paginate-rest": "^11.4.2", + "@octokit/plugin-request-log": "^5.3.1", + "@octokit/plugin-rest-endpoint-methods": "^13.3.0" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/@octokit/rest/node_modules/@octokit/openapi-types": { "version": "23.0.1", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz", @@ -227,34 +278,6 @@ "@octokit/core": ">=6" } }, - "node_modules/@octokit/rest/node_modules/@octokit/request": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz", - "integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==", - "license": "MIT", - "dependencies": { - "@octokit/endpoint": "^10.1.3", - "@octokit/request-error": "^6.1.7", - "@octokit/types": "^13.6.2", - "fast-content-type-parse": "^2.0.0", - "universal-user-agent": "^7.0.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/rest/node_modules/@octokit/request-error": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz", - "integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==", - "license": "MIT", - "dependencies": { - "@octokit/types": "^13.6.2" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/@octokit/rest/node_modules/@octokit/types": { "version": "13.8.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz", @@ -264,18 +287,6 @@ "@octokit/openapi-types": "^23.0.1" } }, - "node_modules/@octokit/rest/node_modules/before-after-hook": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz", - "integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==", - "license": "Apache-2.0" - }, - "node_modules/@octokit/rest/node_modules/universal-user-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", - "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==", - "license": "ISC" - }, "node_modules/@octokit/types": { "version": "6.33.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz", @@ -285,22 +296,16 @@ } }, "node_modules/before-after-hook": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", - "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", - "peer": true + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz", + "integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==", + "license": "Apache-2.0" }, "node_modules/bottleneck": { "version": "2.19.5", "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "peer": true - }, "node_modules/fast-content-type-parse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz", @@ -317,77 +322,11 @@ ], "license": "MIT" }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "peer": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "peer": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "peer": true - }, "node_modules/universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "peer": true - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "peer": true - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "peer": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "peer": true + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", + "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==", + "license": "ISC" } } } diff --git a/.github/workflows/scripts/releases/generate-release-notes/package.json b/.github/workflows/scripts/releases/generate-release-notes/package.json index d7c62c6620..4cd7b41ffa 100644 --- a/.github/workflows/scripts/releases/generate-release-notes/package.json +++ b/.github/workflows/scripts/releases/generate-release-notes/package.json @@ -11,7 +11,7 @@ "license": "ISC", "dependencies": { "@octokit/plugin-retry": "^3.0.9", - "@octokit/plugin-throttling": "^3.5.2", + "@octokit/plugin-throttling": "^9.6.0", "@octokit/rest": "^21.1.1" } } diff --git a/.github/workflows/scripts/windows/build-dependencies-arm64.bat b/.github/workflows/scripts/windows/build-dependencies-arm64.bat index 2daafd7ce8..dda956973a 100644 --- a/.github/workflows/scripts/windows/build-dependencies-arm64.bat +++ b/.github/workflows/scripts/windows/build-dependencies-arm64.bat @@ -44,17 +44,17 @@ cd "%BUILDDIR%" set FREETYPE=2.13.3 set HARFBUZZ=10.0.1 -set LIBJPEG=9f +set LIBJPEGTURBO=3.1.0 set LIBPNG=1645 set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29 -set QT=6.8.2 -set QTMINOR=6.8 -set SDL=SDL3-3.2.8 +set SDL=SDL3-3.2.10 +set QT=6.9.0 +set QTMINOR=6.9 set WEBP=1.5.0 set ZLIB=1.3.1 set ZLIBSHORT=131 set ZSTD=1.5.7 -set KDDOCKWIDGETS=2.2.1 +set KDDOCKWIDGETS=2.2.3 set SHADERC=2024.1 set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec @@ -64,18 +64,18 @@ set SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7 call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747 || goto error call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 8adf9f5a4b6022aa2744f45c89ce347df46fea8403e99f01d650b11c417d0aa8 || goto error call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1645.zip a66c4b1350b67776e90263e2550933067cd9ccbd318db489f84dcc0d2b033249 || goto error -call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error +call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error -call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 7f8ff5c8246db4145301bc122601a5f8cef25ee2c326eddb3e88668849c61ddf || goto error -call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error -call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error -call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error -call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error -call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error +call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 01d9ab20fc071b076be91df5396b464b4ef159e93b2b2addda1cc36750fc1f29 || goto error +call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 513df15a6365a40f6230ec9463ad8c71b824e181d4b661dac9707e103b24ae0c || goto error +call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" d428fd17a0d3f92c48a30f1d23806bf20352fbce2e80e5bbee27fa80576480ee || goto error +call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 54bf06afeb67035f1c6afcd00beec755c0d776626b4cce9ab56992a55215ba69 || goto error +call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 5f8a94a161bd2e71a82f478dc19f4ec77ac95a50709f5a68d5951001ed6bb856 || goto error +call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 5885ce1a114615cc5fa69e459f069d3fe2bcb1320fd9cc162821f3920ef44735 || goto error call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error -call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v2.2.1.zip" 78b5e242bf47476e150175b7de934ab84069459e151beb2d5ce84fd067138aa5 || goto error +call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v%KDDOCKWIDGETS%.zip" 1ba8e5b48f3b4d47d2de7121529d448532200fa36d9ed21f93909f6eb03f61cb || goto error call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error @@ -109,11 +109,10 @@ cmake --build build --parallel || goto error ninja -C build install || goto error cd .. || goto error -echo Building libjpeg... -rmdir /S /Q "jpeg-%LIBJPEG%" -%SEVENZIP% x "jpegsr%LIBJPEG%.zip" || goto error -cd "jpeg-%LIBJPEG%" || goto error -%PATCH% -p1 < "%SCRIPTDIR%\libjpeg-cmake.patch" || goto error +echo Building libjpegturbo... +rmdir /S /Q "libjpeg-turbo-%LIBJPEGTURBO%" +tar -xf "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" || goto error +cd "libjpeg-turbo-%LIBJPEGTURBO%" || goto error cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -B build -G Ninja || goto error cmake --build build --parallel || goto error ninja -C build install || goto error diff --git a/.github/workflows/scripts/windows/build-dependencies.bat b/.github/workflows/scripts/windows/build-dependencies.bat index f23d1ecc36..ccb94725a2 100644 --- a/.github/workflows/scripts/windows/build-dependencies.bat +++ b/.github/workflows/scripts/windows/build-dependencies.bat @@ -42,17 +42,17 @@ cd "%BUILDDIR%" set FREETYPE=2.13.3 set HARFBUZZ=10.0.1 -set LIBJPEG=9f +set LIBJPEGTURBO=3.1.0 set LIBPNG=1645 set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29 -set QT=6.8.2 -set QTMINOR=6.8 -set SDL=SDL3-3.2.8 +set SDL=SDL3-3.2.10 +set QT=6.9.0 +set QTMINOR=6.9 set WEBP=1.5.0 set ZLIB=1.3.1 set ZLIBSHORT=131 set ZSTD=1.5.7 -set KDDOCKWIDGETS=2.2.1 +set KDDOCKWIDGETS=2.2.3 set SHADERC=2024.1 set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec @@ -62,18 +62,18 @@ set SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7 call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747 || goto error call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 8adf9f5a4b6022aa2744f45c89ce347df46fea8403e99f01d650b11c417d0aa8 || goto error call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1645.zip a66c4b1350b67776e90263e2550933067cd9ccbd318db489f84dcc0d2b033249 || goto error -call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error +call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error -call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 7f8ff5c8246db4145301bc122601a5f8cef25ee2c326eddb3e88668849c61ddf || goto error -call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error -call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error -call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error -call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error -call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error +call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 01d9ab20fc071b076be91df5396b464b4ef159e93b2b2addda1cc36750fc1f29 || goto error +call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 513df15a6365a40f6230ec9463ad8c71b824e181d4b661dac9707e103b24ae0c || goto error +call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" d428fd17a0d3f92c48a30f1d23806bf20352fbce2e80e5bbee27fa80576480ee || goto error +call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 54bf06afeb67035f1c6afcd00beec755c0d776626b4cce9ab56992a55215ba69 || goto error +call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 5f8a94a161bd2e71a82f478dc19f4ec77ac95a50709f5a68d5951001ed6bb856 || goto error +call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 5885ce1a114615cc5fa69e459f069d3fe2bcb1320fd9cc162821f3920ef44735 || goto error call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error -call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v2.2.1.zip" 78b5e242bf47476e150175b7de934ab84069459e151beb2d5ce84fd067138aa5 || goto error +call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v%KDDOCKWIDGETS%.zip" 1ba8e5b48f3b4d47d2de7121529d448532200fa36d9ed21f93909f6eb03f61cb || goto error call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error @@ -106,11 +106,10 @@ cmake --build build --parallel || goto error ninja -C build install || goto error cd .. || goto error -echo Building libjpeg... -rmdir /S /Q "jpeg-%LIBJPEG%" -%SEVENZIP% x "jpegsr%LIBJPEG%.zip" || goto error -cd "jpeg-%LIBJPEG%" || goto error -%PATCH% -p1 < "%SCRIPTDIR%\libjpeg-cmake.patch" || goto error +echo Building libjpegturbo... +rmdir /S /Q "libjpeg-turbo-%LIBJPEGTURBO%" +tar -xf "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" || goto error +cd "libjpeg-turbo-%LIBJPEGTURBO%" || goto error cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -B build -G Ninja || goto error cmake --build build --parallel || goto error ninja -C build install || goto error diff --git a/.github/workflows/scripts/windows/build-gammaray.bat b/.github/workflows/scripts/windows/build-gammaray.bat new file mode 100644 index 0000000000..b9ca312f29 --- /dev/null +++ b/.github/workflows/scripts/windows/build-gammaray.bat @@ -0,0 +1,68 @@ +@echo off +setlocal enabledelayedexpansion + +echo Setting environment... +if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" ( + call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" +) else if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" ( + call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" +) else ( + echo Visual Studio 2022 not found. + goto error +) + +pushd %~dp0 + +cd ..\..\..\.. +cd deps || goto error +set "DEPSDIR=%CD%" +cd .. +mkdir gammaray +cd gammaray || goto error +set "INSTALLDIR=%CD%" +cd .. +mkdir gammaray-build +cd gammaray-build || goto error +set "BUILDDIR=%CD%" + +echo DEPSDIR=%DEPSDIR% +echo BUILDDIR=%BUILDDIR% +echo INSTALLDIR=%INSTALLDIR% + +set GAMMARAY="master" + +echo Downloading... +curl -L -o "GammaRay-%GAMMARAY%.tar.gz" "https://github.com/KDAB/GammaRay/archive/%GAMMARAY%.tar.gz" || goto error + +rmdir /s /q "GammaRay-%GAMMARAY%" + +echo Extracting... +tar -xf "GammaRay-%GAMMARAY%.tar.gz" || goto error + +echo Configuring... +cmake "GammaRay-%GAMMARAY%" -B build -DCMAKE_PREFIX_PATH="%DEPSDIR%" -G Ninja -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DGAMMARAY_BUILD_DOCS=false || goto error + +echo Building... +cmake --build build --parallel || goto error + +echo Installing... +cmake --build build --target install || goto errorlevel + +echo Copying DLLs... +xcopy /y "%DEPSDIR%\bin\*.dll" "%INSTALLDIR%\bin\" +xcopy /y /e /s "%DEPSDIR%\plugins" "%INSTALLDIR%\bin\" + +echo Cleaning up... +cd .. +rd /s /q gammaray-build + +echo Exiting with success. +popd +pause +exit 0 + +:error +echo Failed with error #%errorlevel%. +popd +pause +exit %errorlevel% diff --git a/.github/workflows/scripts/windows/libjpeg-cmake.patch b/.github/workflows/scripts/windows/libjpeg-cmake.patch deleted file mode 100644 index a2d8dec726..0000000000 --- a/.github/workflows/scripts/windows/libjpeg-cmake.patch +++ /dev/null @@ -1,422 +0,0 @@ -diff -ruN jpeg-9f/CMakeLists.txt jpeg-9f-new/CMakeLists.txt ---- jpeg-9f/CMakeLists.txt 1970-01-01 10:00:00.000000000 +1000 -+++ jpeg-9f-new/CMakeLists.txt 2024-03-23 21:29:37.969221600 +1000 -@@ -0,0 +1,110 @@ -+# CMake configuration for IJG libjpeg -+# Modified from https://github.com/csparker247/jpeg-cmake/blob/develop/resources/CMakeLists.txt -+# To install, copy this file and jconfig.h.in into a libjpeg source directory -+# Adapted from LuaDist's CMakeLists -+# https://github.com/LuaDist/libjpeg/blob/master/CMakeLists.txt -+ -+cmake_minimum_required(VERSION 3.5) -+ -+### Setup the project ### -+file(READ "configure.ac" ac) -+string(REGEX MATCH "AC_INIT\\(\\[libjpeg\\],\ \\[([0-9]*\\.[0-9]*\\.[0-9]*)\\]\\)" _ ${ac}) -+set(version ${CMAKE_MATCH_1}) -+project(libjpeg VERSION ${version} LANGUAGES C) -+set(C_STANDARD 99) -+ -+### Include extra packages ### -+include(CMakeDependentOption) -+include(GNUInstallDirs) -+ -+### Options ### -+option(BUILD_SHARED_LIBS "Build shared libraries" ON) -+option(BUILD_STATIC_LIBS "Build static libraries" ON) -+ -+# Make sure we build at least one library -+if(NOT(BUILD_SHARED_LIBS OR BUILD_STATIC_LIBS)) -+ message(FATAL_ERROR "Both static and shared libraries are disabled. Nothing will be built.") -+endif() -+ -+### Configure jconfig.h ### -+include(ConfigureJConfig.cmake) -+ -+### Build the object library ### -+set(PUBLIC_HDRS -+ jconfig.h -+ jerror.h -+ jmorecfg.h -+ jpeglib.h -+) -+ -+set(SRCS -+ jaricom.c jcapimin.c jcapistd.c jcarith.c jccoefct.c jccolor.c -+ jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c -+ jcparam.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdarith.c -+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdinput.c -+ jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdpostct.c jdsample.c jdtrans.c -+ jerror.c jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c -+ jmemmgr.c jmemnobs.c jquant1.c jquant2.c jutils.c -+) -+ -+### Create static and shared libs ### -+if(BUILD_SHARED_LIBS) -+ add_library(libjpeg SHARED ${SRCS}) -+ target_compile_definitions(libjpeg PRIVATE COMPILING_LIBJPEG) -+ target_include_directories(libjpeg -+ PUBLIC -+ $ -+ $ -+ ) -+ set_target_properties(libjpeg -+ PROPERTIES -+ VERSION ${PROJECT_VERSION_MAJOR} -+ POSITION_INDEPENDENT_CODE ON -+ CLEAN_DIRECT_OUTPUT ON -+ PUBLIC_HEADER "${PUBLIC_HDRS}" -+ ) -+ install(TARGETS libjpeg -+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} -+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} -+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} -+ ) -+endif() -+ -+if(BUILD_STATIC_LIBS) -+ add_library(libjpeg_static STATIC $) -+ target_include_directories(libjpeg_static -+ PUBLIC -+ $ -+ $ -+ ) -+ set_target_properties(libjpeg_static -+ PROPERTIES -+ OUTPUT_NAME jpeg -+ VERSION ${PROJECT_VERSION_MAJOR} -+ POSITION_INDEPENDENT_CODE ON -+ CLEAN_DIRECT_OUTPUT ON -+ PUBLIC_HEADER "${PUBLIC_HDRS}" -+ ) -+ install(TARGETS libjpeg_static -+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} -+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} -+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} -+ ) -+endif() -+ -+# Configure and install pkg-config and libtool files -+if(BUILD_STATIC_LIBS OR BUILD_SHARED_LIBS) -+ # Compute the la file's weird version number -+ math(EXPR JPEG_CONF_VER_MAJOR "${PROJECT_VERSION_MAJOR} + ${PROJECT_VERSION_MINOR}") -+ set(JPEG_LIB_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) -+ set(JPEG_LIB_VERSION_MINOR ${PROJECT_VERSION_MINOR}) -+ -+ # Configure and install -+ configure_file(libjpeg.pc.cmakein libjpeg.pc @ONLY) -+ install(FILES -+ ${CMAKE_CURRENT_BINARY_DIR}/libjpeg.pc -+ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig -+ ) -+endif() -+ -diff -ruN jpeg-9f/ConfigureJConfig.cmake jpeg-9f-new/ConfigureJConfig.cmake ---- jpeg-9f/ConfigureJConfig.cmake 1970-01-01 10:00:00.000000000 +1000 -+++ jpeg-9f-new/ConfigureJConfig.cmake 2024-03-23 21:09:37.223882900 +1000 -@@ -0,0 +1,95 @@ -+include(CheckIncludeFile) -+include(CheckSymbolExists) -+include(CheckTypeSize) -+ -+# Define this if your system has an ANSI-conforming file. -+check_include_file(stddef.h HAVE_STDDEF_H) -+ -+# Define this if your system has an ANSI-conforming file. -+check_include_file(stdlib.h HAVE_STDLIB_H) -+ -+# Does your compiler support function prototypes? -+# (If not, you also need to use ansi2knr, see install.txt) -+set(HAVE_PROTOTYPES true CACHE BOOL "Does your compiler support function prototypes?") -+ -+# Does your compiler support the declaration "unsigned char" ? -+# How about "unsigned short" ? -+check_type_size("unsigned char" UNSIGNED_CHAR LANGUAGE C) -+check_type_size("unsigned short" UNSIGNED_SHORT LANGUAGE C) -+ -+# Define "void" as "char" if your compiler doesn't know about type void. -+# NOTE: be sure to define void such that "void *" represents the most general -+# pointer type, e.g., that returned by malloc(). -+# NOT IMPLEMENTED: Modify in jconfig.h.in # -+ -+# Define "const" as empty if your compiler doesn't know the "const" keyword. -+# NOT IMPLEMENTED: Modify in jconfig.h.in # -+ -+# Define this if an ordinary "char" type is unsigned. -+# If you're not sure, leaving it undefined will work at some cost in speed. -+# If you defined HAVE_UNSIGNED_CHAR then the speed difference is minimal. -+set(CHAR_IS_UNSIGNED false CACHE BOOL "char type is unsigned") -+ -+# Define this if your system does not have an ANSI/SysV , -+# but does have a BSD-style . -+set(NEED_BSD_STRINGS false CACHE BOOL "Use BSD . Use only if system lacks ANSI/SysV ") -+ -+# Define this if your system does not provide typedef size_t in any of the -+# ANSI-standard places (stddef.h, stdlib.h, or stdio.h), but places it in -+# instead. -+set(NEED_SYS_TYPES_H false CACHE BOOL "size_t defined in ") -+ -+# For 80x86 machines, you need to define NEED_FAR_POINTERS, -+# unless you are using a large-data memory model or 80386 flat-memory mode. -+# On less brain-damaged CPUs this symbol must not be defined. -+# (Defining this symbol causes large data structures to be referenced through -+# "far" pointers and to be allocated with a special version of malloc.) -+set(NEED_FAR_POINTERS false CACHE BOOL "Reference large data structures through 'far' pointers allocated with a special version of malloc") -+ -+# Define this if your linker needs global names to be unique in less -+# than the first 15 characters. -+set(NEED_SHORT_EXTERNAL_NAMES false CACHE BOOL "Global names must be unique in less than the first 15 characters") -+ -+# Although a real ANSI C compiler can deal perfectly well with pointers to -+# unspecified structures (see "incomplete types" in the spec), a few pre-ANSI -+# and pseudo-ANSI compilers get confused. To keep one of these bozos happy, -+# define INCOMPLETE_TYPES_BROKEN. This is not recommended unless you -+# actually get "missing structure definition" warnings or errors while -+# compiling the JPEG code. -+set(INCOMPLETE_TYPES_BROKEN false CACHE BOOL "Disable pointers to unspecified structures") -+ -+# Define "boolean" as unsigned char, not enum, on Windows systems. -+# NOT IMPLEMENTED: Modify in jconfig.h.in # -+ -+# The following options affect code selection within the JPEG library, -+# but they don't need to be visible to applications using the library. -+# To minimize application namespace pollution, the symbols won't be -+# defined unless JPEG_INTERNALS has been defined. -+# -+ -+# Define this if your compiler implements ">>" on signed values as a logical -+# (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift, -+# which is the normal and rational definition. -+set(RIGHT_SHIFT_IS_UNSIGNED false CACHE BOOL "Compiler implements >> on signed values as a logical (unsigned) shift") -+ -+# The remaining options do not affect the JPEG library proper, -+# but only the sample applications cjpeg/djpeg (see cjpeg.c, djpeg.c). -+# Other applications can ignore these. -+# -+ -+mark_as_advanced(FORCE -+ HAVE_PROTOTYPES -+ HAVE_UNSIGNED_CHAR -+ HAVE_UNSIGNED_SHORT -+ CHAR_IS_UNSIGNED -+ HAVE_STDDEF_H -+ HAVE_STDLIB_H -+ NEED_BSD_STRINGS -+ NEED_SYS_TYPES_H -+ NEED_FAR_POINTERS -+ NEED_SHORT_EXTERNAL_NAMES -+ INCOMPLETE_TYPES_BROKEN -+ RIGHT_SHIFT_IS_UNSIGNED -+) -+ -+configure_file(jconfig.h.in ${CMAKE_CURRENT_SOURCE_DIR}/jconfig.h) -diff -ruN jpeg-9f/jconfig.h.in jpeg-9f-new/jconfig.h.in ---- jpeg-9f/jconfig.h.in 1970-01-01 10:00:00.000000000 +1000 -+++ jpeg-9f-new/jconfig.h.in 2024-03-23 21:06:05.204994600 +1000 -@@ -0,0 +1,173 @@ -+/* -+ * jconfig.h.in -+ * -+ * Copyright (C) 1991-1994, Thomas G. Lane. -+ * Modified 2009-2013 by Guido Vollbeding. -+ * This file is part of the Independent JPEG Group's software. -+ * For conditions of distribution and use, see the accompanying README file. -+ * -+ * This file is a modification of jconfig.txt from libjpeg. In addition to -+ * documenting the configuration options that are required to customize the -+ * JPEG software for a particular system, it is used by jpeg-cmake to configure -+ * jconfig.h -+ */ -+ -+ -+/* -+ * These symbols indicate the properties of your machine or compiler. -+ * #define the symbol if yes, #undef it if no. -+ */ -+ -+/* Does your compiler support function prototypes? -+ * (If not, you also need to use ansi2knr, see install.txt) -+ */ -+#cmakedefine HAVE_PROTOTYPES -+ -+/* Does your compiler support the declaration "unsigned char" ? -+ * How about "unsigned short" ? -+ */ -+#cmakedefine HAVE_UNSIGNED_CHAR -+#cmakedefine HAVE_UNSIGNED_SHORT -+ -+/* Define "void" as "char" if your compiler doesn't know about type void. -+ * NOTE: be sure to define void such that "void *" represents the most general -+ * pointer type, e.g., that returned by malloc(). -+ */ -+/* #define void char */ -+ -+/* Define "const" as empty if your compiler doesn't know the "const" keyword. -+ */ -+/* #define const */ -+ -+/* Define this if an ordinary "char" type is unsigned. -+ * If you're not sure, leaving it undefined will work at some cost in speed. -+ * If you defined HAVE_UNSIGNED_CHAR then the speed difference is minimal. -+ */ -+#cmakedefine CHAR_IS_UNSIGNED -+ -+/* Define this if your system has an ANSI-conforming file. -+ */ -+#cmakedefine HAVE_STDDEF_H -+ -+/* Define this if your system has an ANSI-conforming file. -+ */ -+#cmakedefine HAVE_STDLIB_H -+ -+/* Define this if your system does not have an ANSI/SysV , -+ * but does have a BSD-style . -+ */ -+#cmakedefine NEED_BSD_STRINGS -+ -+/* Define this if your system does not provide typedef size_t in any of the -+ * ANSI-standard places (stddef.h, stdlib.h, or stdio.h), but places it in -+ * instead. -+ */ -+#cmakedefine NEED_SYS_TYPES_H -+ -+/* For 80x86 machines, you need to define NEED_FAR_POINTERS, -+ * unless you are using a large-data memory model or 80386 flat-memory mode. -+ * On less brain-damaged CPUs this symbol must not be defined. -+ * (Defining this symbol causes large data structures to be referenced through -+ * "far" pointers and to be allocated with a special version of malloc.) -+ */ -+#cmakedefine NEED_FAR_POINTERS -+ -+/* Define this if your linker needs global names to be unique in less -+ * than the first 15 characters. -+ */ -+#cmakedefine NEED_SHORT_EXTERNAL_NAMES -+ -+/* Although a real ANSI C compiler can deal perfectly well with pointers to -+ * unspecified structures (see "incomplete types" in the spec), a few pre-ANSI -+ * and pseudo-ANSI compilers get confused. To keep one of these bozos happy, -+ * define INCOMPLETE_TYPES_BROKEN. This is not recommended unless you -+ * actually get "missing structure definition" warnings or errors while -+ * compiling the JPEG code. -+ */ -+#cmakedefine INCOMPLETE_TYPES_BROKEN -+ -+/* Define "boolean" as unsigned char, not enum, on Windows systems. -+ */ -+#ifdef _WIN32 -+#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ -+typedef unsigned char boolean; -+#endif -+#ifndef FALSE /* in case these macros already exist */ -+#define FALSE 0 /* values of boolean */ -+#endif -+#ifndef TRUE -+#define TRUE 1 -+#endif -+#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ -+#endif -+ -+ -+/* -+ * The following options affect code selection within the JPEG library, -+ * but they don't need to be visible to applications using the library. -+ * To minimize application namespace pollution, the symbols won't be -+ * defined unless JPEG_INTERNALS has been defined. -+ */ -+ -+#ifdef JPEG_INTERNALS -+ -+/* Define this if your compiler implements ">>" on signed values as a logical -+ * (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift, -+ * which is the normal and rational definition. -+ */ -+#cmakedefine RIGHT_SHIFT_IS_UNSIGNED -+ -+ -+#endif /* JPEG_INTERNALS */ -+ -+ -+/* -+ * The remaining options do not affect the JPEG library proper, -+ * but only the sample applications cjpeg/djpeg (see cjpeg.c, djpeg.c). -+ * Other applications can ignore these. -+ */ -+ -+#ifdef JPEG_CJPEG_DJPEG -+ -+/* These defines indicate which image (non-JPEG) file formats are allowed. */ -+ -+#cmakedefine BMP_SUPPORTED /* BMP image file format */ -+#cmakedefine GIF_SUPPORTED /* GIF image file format */ -+#cmakedefine PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ -+#cmakedefine RLE_SUPPORTED /* Utah RLE image file format */ -+#cmakedefine TARGA_SUPPORTED /* Targa image file format */ -+ -+/* -+ * This defines the default output format for djpeg. Must be one of the FMT_* -+ * enums found in djpeg.c or djpegalt.c -+ */ -+#cmakedefine DEFAULT_FMT @DEFAULT_FMT@ -+ -+/* Define this if you want to name both input and output files on the command -+ * line, rather than using stdout and optionally stdin. You MUST do this if -+ * your system can't cope with binary I/O to stdin/stdout. See comments at -+ * head of cjpeg.c or djpeg.c. -+ */ -+#cmakedefine TWO_FILE_COMMANDLINE -+ -+/* Define this if your system needs explicit cleanup of temporary files. -+ * This is crucial under MS-DOS, where the temporary "files" may be areas -+ * of extended memory; on most other systems it's not as important. -+ */ -+#cmakedefine NEED_SIGNAL_CATCHER -+ -+/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb"). -+ * This is necessary on systems that distinguish text files from binary files, -+ * and is harmless on most systems that don't. If you have one of the rare -+ * systems that complains about the "b" spec, define this symbol. -+ */ -+#cmakedefine DONT_USE_B_MODE -+ -+/* Define this if you want percent-done progress reports from cjpeg/djpeg. -+ */ -+#cmakedefine PROGRESS_REPORT -+ -+/* Define this if you *don't* want overwrite confirmation */ -+#cmakedefine NO_OVERWRITE_CHECK -+ -+#endif /* JPEG_CJPEG_DJPEG */ -diff -ruN jpeg-9f/jmorecfg.h jpeg-9f-new/jmorecfg.h ---- jpeg-9f/jmorecfg.h 2022-03-31 19:41:26.000000000 +1000 -+++ jpeg-9f-new/jmorecfg.h 2024-03-23 21:20:25.514814400 +1000 -@@ -244,8 +244,13 @@ - #define LOCAL(type) static type - /* a function referenced thru EXTERNs: */ - #define GLOBAL(type) type -+ - /* a reference to a GLOBAL function: */ --#define EXTERN(type) extern type -+#ifdef COMPILING_LIBJPEG -+#define EXTERN(type) __declspec(dllexport) extern type -+#else -+#define EXTERN(type) __declspec(dllimport) extern type -+#endif - - - /* This macro is used to declare a "method", that is, a function pointer. -diff -ruN jpeg-9f/libjpeg.pc.cmakein jpeg-9f-new/libjpeg.pc.cmakein ---- jpeg-9f/libjpeg.pc.cmakein 1970-01-01 10:00:00.000000000 +1000 -+++ jpeg-9f-new/libjpeg.pc.cmakein 2024-03-23 21:06:13.922695100 +1000 -@@ -0,0 +1,10 @@ -+prefix=@CMAKE_INSTALL_PREFIX@ -+exec_prefix=${prefix} -+libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ -+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ -+ -+Name: libjpeg -+Description: Reads and writes JPEG files -+Version: @JPEG_LIB_VERSION_MAJOR@.@JPEG_LIB_VERSION_MINOR@.0 -+Libs: -L${libdir} -ljpeg -+Cflags: -I${includedir} diff --git a/.github/workflows/triage_pr.yml b/.github/workflows/triage_pr.yml index 62a93ec4bc..7a433e7870 100644 --- a/.github/workflows/triage_pr.yml +++ b/.github/workflows/triage_pr.yml @@ -12,7 +12,7 @@ jobs: with: repo-token: ${{ secrets.GITHUB_TOKEN }} - - uses: xTVaser/first-interaction@v1.2.4 + - uses: xTVaser/first-interaction@d62d6eb3c1215eae9f9d6dbfabf12d6725834cb3 with: repo-token: ${{ secrets.GITHUB_TOKEN }} debug-mode: false diff --git a/.github/workflows/windows_build_qt.yml b/.github/workflows/windows_build_qt.yml index aa8d0a9498..4d9d808553 100644 --- a/.github/workflows/windows_build_qt.yml +++ b/.github/workflows/windows_build_qt.yml @@ -168,7 +168,7 @@ jobs: !./bin/**/*.lib - name: Install the Breakpad Symbol Generator - uses: baptiste0928/cargo-install@v3 + uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 with: crate: dump_syms diff --git a/.gitignore b/.gitignore index b59e873da7..9305218258 100644 --- a/.gitignore +++ b/.gitignore @@ -109,6 +109,8 @@ oprofile_data/ /deps-build /deps /deps-arm64 +/gammaray-build +/gammaray /ipch !/3rdparty/libjpeg/change.log diff --git a/3rdparty/cpuinfo/include/cpuinfo.h b/3rdparty/cpuinfo/include/cpuinfo.h index 6eb4b8c38e..5f93819e8b 100644 --- a/3rdparty/cpuinfo/include/cpuinfo.h +++ b/3rdparty/cpuinfo/include/cpuinfo.h @@ -522,6 +522,8 @@ enum cpuinfo_uarch { cpuinfo_uarch_falkor = 0x00400103, /** Qualcomm Saphira. */ cpuinfo_uarch_saphira = 0x00400104, + /** Qualcomm Oryon. */ + cpuinfo_uarch_oryon = 0x00400105, /** Nvidia Denver. */ cpuinfo_uarch_denver = 0x00500100, @@ -821,6 +823,7 @@ struct cpuinfo_x86_isa { bool avx512_4vnniw; bool avx512_4fmaps; bool avx10_1; + bool avx10_2; bool amx_bf16; bool amx_tile; bool amx_int8; @@ -1444,6 +1447,14 @@ static inline bool cpuinfo_has_x86_avx10_1(void) { #endif } +static inline bool cpuinfo_has_x86_avx10_2(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx10_2; +#else + return false; +#endif +} + static inline bool cpuinfo_has_x86_hle(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.hle; diff --git a/3rdparty/cpuinfo/src/arm/api.h b/3rdparty/cpuinfo/src/arm/api.h index ac735e3e78..32a271c4ce 100644 --- a/3rdparty/cpuinfo/src/arm/api.h +++ b/3rdparty/cpuinfo/src/arm/api.h @@ -1,5 +1,11 @@ #pragma once +#ifdef _MSC_VER +#define RESTRICT_STATIC /* nothing for MSVC */ +#else +#define RESTRICT_STATIC restrict static +#endif + #include #include @@ -82,11 +88,11 @@ struct cpuinfo_arm_chipset { #ifndef __cplusplus CPUINFO_INTERNAL void cpuinfo_arm_chipset_to_string( - const struct cpuinfo_arm_chipset chipset[restrict static 1], - char name[restrict static CPUINFO_ARM_CHIPSET_NAME_MAX]); + const struct cpuinfo_arm_chipset chipset[RESTRICT_STATIC 1], + char name[RESTRICT_STATIC CPUINFO_ARM_CHIPSET_NAME_MAX]); CPUINFO_INTERNAL void cpuinfo_arm_fixup_chipset( - struct cpuinfo_arm_chipset chipset[restrict static 1], + struct cpuinfo_arm_chipset chipset[RESTRICT_STATIC 1], uint32_t cores, uint32_t max_cpu_freq_max); @@ -95,23 +101,23 @@ CPUINFO_INTERNAL void cpuinfo_arm_decode_vendor_uarch( #if CPUINFO_ARCH_ARM bool has_vfpv4, #endif - enum cpuinfo_vendor vendor[restrict static 1], - enum cpuinfo_uarch uarch[restrict static 1]); + enum cpuinfo_vendor vendor[RESTRICT_STATIC 1], + enum cpuinfo_uarch uarch[RESTRICT_STATIC 1]); CPUINFO_INTERNAL void cpuinfo_arm_decode_cache( enum cpuinfo_uarch uarch, uint32_t cluster_cores, uint32_t midr, - const struct cpuinfo_arm_chipset chipset[restrict static 1], + const struct cpuinfo_arm_chipset chipset[RESTRICT_STATIC 1], uint32_t cluster_id, uint32_t arch_version, - struct cpuinfo_cache l1i[restrict static 1], - struct cpuinfo_cache l1d[restrict static 1], - struct cpuinfo_cache l2[restrict static 1], - struct cpuinfo_cache l3[restrict static 1]); + struct cpuinfo_cache l1i[RESTRICT_STATIC 1], + struct cpuinfo_cache l1d[RESTRICT_STATIC 1], + struct cpuinfo_cache l2[RESTRICT_STATIC 1], + struct cpuinfo_cache l3[RESTRICT_STATIC 1]); CPUINFO_INTERNAL uint32_t -cpuinfo_arm_compute_max_cache_size(const struct cpuinfo_processor processor[restrict static 1]); +cpuinfo_arm_compute_max_cache_size(const struct cpuinfo_processor processor[RESTRICT_STATIC 1]); #else /* defined(__cplusplus) */ CPUINFO_INTERNAL void cpuinfo_arm_decode_cache( enum cpuinfo_uarch uarch, diff --git a/3rdparty/cpuinfo/src/arm/mach/init.c b/3rdparty/cpuinfo/src/arm/mach/init.c index 47b1b18bc4..c4e6521b3c 100644 --- a/3rdparty/cpuinfo/src/arm/mach/init.c +++ b/3rdparty/cpuinfo/src/arm/mach/init.c @@ -101,7 +101,6 @@ static enum cpuinfo_uarch decode_uarch(uint32_t cpu_family, uint32_t core_index, return cpuinfo_uarch_unknown; } -/* Small bodge until cpuinfo merges PR #246 */ static int read_package_name_from_brand_string(char* package_name) { size_t size; if (sysctlbyname("machdep.cpu.brand_string", NULL, &size, NULL, 0) != 0) { diff --git a/3rdparty/cpuinfo/src/arm/uarch.c b/3rdparty/cpuinfo/src/arm/uarch.c index 68531e4d1d..9679f5004e 100644 --- a/3rdparty/cpuinfo/src/arm/uarch.c +++ b/3rdparty/cpuinfo/src/arm/uarch.c @@ -9,8 +9,8 @@ void cpuinfo_arm_decode_vendor_uarch( #if CPUINFO_ARCH_ARM bool has_vfpv4, #endif /* CPUINFO_ARCH_ARM */ - enum cpuinfo_vendor vendor[restrict static 1], - enum cpuinfo_uarch uarch[restrict static 1]) { + enum cpuinfo_vendor vendor[RESTRICT_STATIC 1], + enum cpuinfo_uarch uarch[RESTRICT_STATIC 1]) { switch (midr_get_implementer(midr)) { case 'A': *vendor = cpuinfo_vendor_arm; @@ -332,6 +332,9 @@ void cpuinfo_arm_decode_vendor_uarch( *uarch = cpuinfo_uarch_cortex_a55; break; #if CPUINFO_ARCH_ARM64 + case 0x001: + *uarch = cpuinfo_uarch_oryon; + break; case 0xC00: *uarch = cpuinfo_uarch_falkor; break; diff --git a/3rdparty/cpuinfo/src/arm/windows/init-by-logical-sys-info.c b/3rdparty/cpuinfo/src/arm/windows/init-by-logical-sys-info.c index a644b1d019..32c9b54683 100644 --- a/3rdparty/cpuinfo/src/arm/windows/init-by-logical-sys-info.c +++ b/3rdparty/cpuinfo/src/arm/windows/init-by-logical-sys-info.c @@ -750,11 +750,14 @@ void store_core_info_per_processor( if (cores) { processors[processor_global_index].core = cores + core_id; cores[core_id].core_id = core_id; - get_core_uarch_for_efficiency( - chip_info->chip_name, - core_info->Processor.EfficiencyClass, - &(cores[core_id].uarch), - &(cores[core_id].frequency)); + + if (chip_info->uarchs == NULL) { + cpuinfo_log_error("uarch is NULL for core %d", core_id); + return; + } + + cores[core_id].uarch = chip_info->uarchs[0].uarch; + cores[core_id].frequency = chip_info->uarchs[0].frequency; /* We don't have cluster information, so we handle it as * fixed 1 to (cluster / cores). diff --git a/3rdparty/cpuinfo/src/arm/windows/init.c b/3rdparty/cpuinfo/src/arm/windows/init.c index faa30ef567..ffbe554d16 100644 --- a/3rdparty/cpuinfo/src/arm/windows/init.c +++ b/3rdparty/cpuinfo/src/arm/windows/init.c @@ -7,6 +7,9 @@ #include #include +#include +#include + #include "windows-arm-init.h" struct cpuinfo_arm_isa cpuinfo_isa; @@ -14,62 +17,7 @@ struct cpuinfo_arm_isa cpuinfo_isa; static void set_cpuinfo_isa_fields(void); static struct woa_chip_info* get_system_info_from_registry(void); -static struct woa_chip_info woa_chip_unknown = { - L"Unknown", - woa_chip_name_unknown, - {{cpuinfo_vendor_unknown, cpuinfo_uarch_unknown, 0}}}; - -/* Please add new SoC/chip info here! */ -static struct woa_chip_info woa_chips[woa_chip_name_last] = { - /* Microsoft SQ1 Kryo 495 4 + 4 cores (3 GHz + 1.80 GHz) */ - [woa_chip_name_microsoft_sq_1] = - {L"Microsoft SQ1", - woa_chip_name_microsoft_sq_1, - {{ - cpuinfo_vendor_arm, - cpuinfo_uarch_cortex_a55, - 1800000000, - }, - { - cpuinfo_vendor_arm, - cpuinfo_uarch_cortex_a76, - 3000000000, - }}}, - /* Microsoft SQ2 Kryo 495 4 + 4 cores (3.15 GHz + 2.42 GHz) */ - [woa_chip_name_microsoft_sq_2] = - {L"Microsoft SQ2", - woa_chip_name_microsoft_sq_2, - {{ - cpuinfo_vendor_arm, - cpuinfo_uarch_cortex_a55, - 2420000000, - }, - {cpuinfo_vendor_arm, cpuinfo_uarch_cortex_a76, 3150000000}}}, - /* Snapdragon (TM) 8cx Gen 3 @ 3.0 GHz */ - [woa_chip_name_microsoft_sq_3] = - {L"Snapdragon (TM) 8cx Gen 3", - woa_chip_name_microsoft_sq_3, - {{ - cpuinfo_vendor_arm, - cpuinfo_uarch_cortex_a78, - 2420000000, - }, - {cpuinfo_vendor_arm, cpuinfo_uarch_cortex_x1, 3000000000}}}, - /* Microsoft Windows Dev Kit 2023 */ - [woa_chip_name_microsoft_sq_3_devkit] = - {L"Snapdragon Compute Platform", - woa_chip_name_microsoft_sq_3_devkit, - {{ - cpuinfo_vendor_arm, - cpuinfo_uarch_cortex_a78, - 2420000000, - }, - {cpuinfo_vendor_arm, cpuinfo_uarch_cortex_x1, 3000000000}}}, - /* Ampere Altra */ - [woa_chip_name_ampere_altra] = { - L"Ampere(R) Altra(R) Processor", - woa_chip_name_ampere_altra, - {{cpuinfo_vendor_arm, cpuinfo_uarch_neoverse_n1, 3000000000}}}}; +static struct woa_chip_info woa_chip_unknown = {L"Unknown", {{cpuinfo_vendor_unknown, cpuinfo_uarch_unknown, 0}}}; BOOL CALLBACK cpuinfo_arm_windows_init(PINIT_ONCE init_once, PVOID parameter, PVOID* context) { struct woa_chip_info* chip_info = NULL; @@ -87,23 +35,6 @@ BOOL CALLBACK cpuinfo_arm_windows_init(PINIT_ONCE init_once, PVOID parameter, PV return true; } -bool get_core_uarch_for_efficiency( - enum woa_chip_name chip, - BYTE EfficiencyClass, - enum cpuinfo_uarch* uarch, - uint64_t* frequency) { - /* For currently supported WoA chips, the Efficiency class selects - * the pre-defined little and big core. - * Any further supported SoC's logic should be implemented here. - */ - if (uarch && frequency && chip < woa_chip_name_last && EfficiencyClass < MAX_WOA_VALID_EFFICIENCY_CLASSES) { - *uarch = woa_chips[chip].uarchs[EfficiencyClass].uarch; - *frequency = woa_chips[chip].uarchs[EfficiencyClass].frequency; - return true; - } - return false; -} - /* Static helper functions */ static wchar_t* read_registry(LPCWSTR subkey, LPCWSTR value) { @@ -149,40 +80,112 @@ static wchar_t* read_registry(LPCWSTR subkey, LPCWSTR value) { return text_buffer; } +static uint64_t read_registry_qword(LPCWSTR subkey, LPCWSTR value) { + DWORD key_type = 0; + DWORD data_size = sizeof(uint64_t); + const DWORD flags = RRF_RT_REG_QWORD; /* Only read QWORD (REG_QWORD) values */ + uint64_t qword_value = 0; + LSTATUS result = RegGetValueW(HKEY_LOCAL_MACHINE, subkey, value, flags, &key_type, &qword_value, &data_size); + if (result != ERROR_SUCCESS || data_size != sizeof(uint64_t)) { + cpuinfo_log_error("Registry QWORD read error"); + return 0; + } + return qword_value; +} + +static uint64_t read_registry_dword(LPCWSTR subkey, LPCWSTR value) { + DWORD key_type = 0; + DWORD data_size = sizeof(DWORD); + DWORD dword_value = 0; + LSTATUS result = + RegGetValueW(HKEY_LOCAL_MACHINE, subkey, value, RRF_RT_REG_DWORD, &key_type, &dword_value, &data_size); + if (result != ERROR_SUCCESS || data_size != sizeof(DWORD)) { + cpuinfo_log_error("Registry DWORD read error"); + return 0; + } + return (uint64_t)dword_value; +} + +static wchar_t* wcsndup(const wchar_t* src, size_t n) { + size_t len = wcsnlen(src, n); + wchar_t* dup = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (len + 1) * sizeof(wchar_t)); + if (dup) { + wcsncpy_s(dup, len + 1, src, len); + dup[len] = L'\0'; + } + return dup; +} + +static struct core_info_by_chip_name get_core_info_from_midr(uint32_t midr, uint64_t frequency) { + struct core_info_by_chip_name info; + enum cpuinfo_vendor vendor; + enum cpuinfo_uarch uarch; + +#if CPUINFO_ARCH_ARM + bool has_vfpv4 = false; + cpuinfo_arm_decode_vendor_uarch(midr, has_vfpv4, &vendor, &uarch); +#else + cpuinfo_arm_decode_vendor_uarch(midr, &vendor, &uarch); +#endif + + info.vendor = vendor; + info.uarch = uarch; + info.frequency = frequency; + return info; +} + static struct woa_chip_info* get_system_info_from_registry(void) { wchar_t* text_buffer = NULL; LPCWSTR cpu0_subkey = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"; LPCWSTR chip_name_value = L"ProcessorNameString"; + LPCWSTR chip_midr_value = L"CP 4000"; + LPCWSTR chip_mhz_value = L"~MHz"; struct woa_chip_info* chip_info = NULL; - HANDLE heap = GetProcessHeap(); - /* Read processor model name from registry and find in the hard-coded * list. */ text_buffer = read_registry(cpu0_subkey, chip_name_value); if (text_buffer == NULL) { - cpuinfo_log_error("Registry read error"); + cpuinfo_log_error("Registry read error for processor name"); return NULL; } - for (uint32_t i = 0; i < (uint32_t)woa_chip_name_last; i++) { - size_t compare_length = wcsnlen(woa_chips[i].chip_name_string, CPUINFO_PACKAGE_NAME_MAX); - int compare_result = wcsncmp(text_buffer, woa_chips[i].chip_name_string, compare_length); - if (compare_result == 0) { - chip_info = woa_chips + i; - break; - } + + /* + * https://developer.arm.com/documentation/100442/0100/register-descriptions/aarch32-system-registers/midr--main-id-register + * Regedit for MIDR : + *HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0\CP 4000 + */ + uint64_t midr_qword = (uint32_t)read_registry_qword(cpu0_subkey, chip_midr_value); + if (midr_qword == 0) { + cpuinfo_log_error("Registry read error for MIDR value"); + return NULL; } + // MIDR is only 32 bits, so we need to cast it to uint32_t + uint32_t midr_value = (uint32_t)midr_qword; + + /* Read the frequency from the registry + * The value is in MHz, so we need to convert it to Hz */ + uint64_t frequency_mhz = read_registry_dword(cpu0_subkey, chip_mhz_value); + if (frequency_mhz == 0) { + cpuinfo_log_error("Registry read error for frequency value"); + return NULL; + } + // Convert MHz to Hz + uint64_t frequency_hz = frequency_mhz * 1000000; + + // Allocate chip_info before using it. + chip_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct woa_chip_info)); if (chip_info == NULL) { - /* No match was found, so print a warning and assign the unknown - * case. */ - cpuinfo_log_error( - "Unknown chip model name '%ls'.\nPlease add new Windows on Arm SoC/chip support to arm/windows/init.c!", - text_buffer); - } else { - cpuinfo_log_debug("detected chip model name: %s", chip_info->chip_name_string); + cpuinfo_log_error("Heap allocation error for chip_info"); + return NULL; } - HeapFree(heap, 0, text_buffer); + // set chip_info fields + chip_info->chip_name_string = wcsndup(text_buffer, CPUINFO_PACKAGE_NAME_MAX - 1); + chip_info->uarchs[0] = get_core_info_from_midr(midr_value, frequency_hz); + + cpuinfo_log_debug("detected chip model name: %ls", chip_info->chip_name_string); + return chip_info; } @@ -216,4 +219,4 @@ static void set_cpuinfo_isa_fields(void) { cpuinfo_isa.pmull = crypto; cpuinfo_isa.crc32 = IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) != 0; -} +} \ No newline at end of file diff --git a/3rdparty/cpuinfo/src/arm/windows/windows-arm-init.h b/3rdparty/cpuinfo/src/arm/windows/windows-arm-init.h index b054a29822..0448243d08 100644 --- a/3rdparty/cpuinfo/src/arm/windows/windows-arm-init.h +++ b/3rdparty/cpuinfo/src/arm/windows/windows-arm-init.h @@ -3,17 +3,6 @@ /* Efficiency class = 0 means little core, while 1 means big core for now. */ #define MAX_WOA_VALID_EFFICIENCY_CLASSES 2 -/* List of known and supported Windows on Arm SoCs/chips. */ -enum woa_chip_name { - woa_chip_name_microsoft_sq_1 = 0, - woa_chip_name_microsoft_sq_2 = 1, - woa_chip_name_microsoft_sq_3 = 2, - woa_chip_name_microsoft_sq_3_devkit = 3, - woa_chip_name_ampere_altra = 4, - woa_chip_name_unknown = 5, - woa_chip_name_last = woa_chip_name_unknown -}; - /* Topology information hard-coded by SoC/chip name */ struct core_info_by_chip_name { enum cpuinfo_vendor vendor; @@ -26,14 +15,7 @@ struct core_info_by_chip_name { */ struct woa_chip_info { wchar_t* chip_name_string; - enum woa_chip_name chip_name; struct core_info_by_chip_name uarchs[MAX_WOA_VALID_EFFICIENCY_CLASSES]; }; -bool get_core_uarch_for_efficiency( - enum woa_chip_name chip, - BYTE EfficiencyClass, - enum cpuinfo_uarch* uarch, - uint64_t* frequency); - bool cpu_info_init_by_logical_sys_info(const struct woa_chip_info* chip_info, enum cpuinfo_vendor vendor); diff --git a/3rdparty/cpuinfo/src/x86/isa.c b/3rdparty/cpuinfo/src/x86/isa.c index 47a6afa320..222bd231dd 100644 --- a/3rdparty/cpuinfo/src/x86/isa.c +++ b/3rdparty/cpuinfo/src/x86/isa.c @@ -46,6 +46,8 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( (max_base_index >= 7) ? cpuidex(7, 0) : (struct cpuid_regs){0, 0, 0, 0}; const struct cpuid_regs structured_feature_info1 = (max_base_index >= 7) ? cpuidex(7, 1) : (struct cpuid_regs){0, 0, 0, 0}; + const struct cpuid_regs structured_feature_info2 = + (max_base_index >= 7) ? cpuidex(0x24, 0) : (struct cpuid_regs){0, 0, 0, 0}; const uint32_t processor_capacity_info_index = UINT32_C(0x80000008); const struct cpuid_regs processor_capacity_info = (max_extended_index >= processor_capacity_info_index) @@ -430,10 +432,17 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( isa.avx512f = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00010000)); /* - * AVX 10.1 instructions: + * AVX 10.1 instructions: avx 10 isa supported. + * - Intel: edx[bit 19] in structured feature info (ecx = 1). */ isa.avx10_1 = avx512_regs && !!(structured_feature_info1.edx & UINT32_C(0x00080000)); + /* + * AVX 10.2 instructions: avx 10 version information. + * - Intel: ebx[bits 0-7] in structured features info (eax = 24 ecx = 0). + */ + isa.avx10_2 = ((structured_feature_info2.ebx & UINT32_C(0x000000FF)) >= 2) && isa.avx10_1; + /* * AVX512PF instructions: * - Intel: ebx[bit 26] in structured feature info (ecx = 0). diff --git a/3rdparty/cpuinfo/src/x86/linux/cpuinfo.c b/3rdparty/cpuinfo/src/x86/linux/cpuinfo.c index 7df72aba50..8f038b0702 100644 --- a/3rdparty/cpuinfo/src/x86/linux/cpuinfo.c +++ b/3rdparty/cpuinfo/src/x86/linux/cpuinfo.c @@ -83,8 +83,9 @@ struct proc_cpuinfo_parser_state { static bool parse_line( const char* line_start, const char* line_end, - struct proc_cpuinfo_parser_state state[restrict static 1], + void* context, uint64_t line_number) { + struct proc_cpuinfo_parser_state* restrict state = context; /* Empty line. Skip. */ if (line_start == line_end) { return true; @@ -215,5 +216,5 @@ bool cpuinfo_x86_linux_parse_proc_cpuinfo( .processors = processors, }; return cpuinfo_linux_parse_multiline_file( - "/proc/cpuinfo", BUFFER_SIZE, (cpuinfo_line_callback)parse_line, &state); + "/proc/cpuinfo", BUFFER_SIZE, parse_line, &state); } diff --git a/3rdparty/imgui/include/imconfig.h b/3rdparty/imgui/include/imconfig.h index 83f1b849e2..66eed8f767 100644 --- a/3rdparty/imgui/include/imconfig.h +++ b/3rdparty/imgui/include/imconfig.h @@ -88,8 +88,7 @@ //---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT) // Only works in combination with IMGUI_ENABLE_FREETYPE. -// - lunasvg is currently easier to acquire/install, as e.g. it is part of vcpkg. -// - plutosvg will support more fonts and may load them faster. It currently requires to be built manually but it is fairly easy. See misc/freetype/README for instructions. +// - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It will support more fonts and may load them faster. See misc/freetype/README for instructions. // - Both require headers to be available in the include path + program to be linked with the library code (not provided). // - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement) //#define IMGUI_ENABLE_FREETYPE_PLUTOSVG diff --git a/3rdparty/imgui/include/imgui.h b/3rdparty/imgui/include/imgui.h index 7b037a5840..75750ae109 100644 --- a/3rdparty/imgui/include/imgui.h +++ b/3rdparty/imgui/include/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.91.8 +// dear imgui, v1.91.9b // (headers) // Help: @@ -28,8 +28,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.91.8" -#define IMGUI_VERSION_NUM 19180 +#define IMGUI_VERSION "1.91.9b" +#define IMGUI_VERSION_NUM 19191 #define IMGUI_HAS_TABLE /* @@ -37,6 +37,7 @@ Index of this file: // [SECTION] Header mess // [SECTION] Forward declarations and basic types +// [SECTION] Texture identifier (ImTextureID) // [SECTION] Dear ImGui end-user API functions // [SECTION] Flags & Enumerations // [SECTION] Tables API flags and structures (ImGuiTableFlags, ImGuiTableColumnFlags, ImGuiTableRowFlags, ImGuiTableBgTarget, ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs) @@ -250,22 +251,6 @@ typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: f typedef int ImGuiViewportFlags; // -> enum ImGuiViewportFlags_ // Flags: for ImGuiViewport typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild() -// ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type] -// - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file. -// - This can be whatever to you want it to be! read the FAQ about ImTextureID for details. -// - You can make this a structure with various constructors if you need. You will have to implement ==/!= operators. -// - (note: before v1.91.4 (2024/10/08) the default type for ImTextureID was void*. Use intermediary intptr_t cast and read FAQ if you have casting warnings) -#ifndef ImTextureID -typedef ImU64 ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that) -#endif - -// ImDrawIdx: vertex index. [Compile-time configurable type] -// - To use 16-bit indices + allow large meshes: backend need to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset (recommended). -// - To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in your imconfig.h file. -#ifndef ImDrawIdx -typedef unsigned short ImDrawIdx; // Default: 16-bit (for maximum compatibility with renderer backends) -#endif - // Character types // (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display) typedef unsigned int ImWchar32; // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings. @@ -315,6 +300,19 @@ struct ImVec4 }; IM_MSVC_RUNTIME_CHECKS_RESTORE +//----------------------------------------------------------------------------- +// [SECTION] Texture identifier (ImTextureID) +//----------------------------------------------------------------------------- + +// ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type] +// - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file. +// - This can be whatever to you want it to be! read the FAQ about ImTextureID for details. +// - You can make this a structure with various constructors if you need. You will have to implement ==/!= operators. +// - (note: before v1.91.4 (2024/10/08) the default type for ImTextureID was void*. Use intermediary intptr_t cast and read FAQ if you have casting warnings) +#ifndef ImTextureID +typedef ImU64 ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that) +#endif + //----------------------------------------------------------------------------- // [SECTION] Dear ImGui end-user API functions // (Note that ImGui:: being a namespace, you can add extra ImGui:: functions in your own separate file. Please don't modify imgui source files!) @@ -544,7 +542,7 @@ namespace ImGui IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args) IM_FMTLIST(2); IMGUI_API void BulletText(const char* fmt, ...) IM_FMTARGS(1); // shortcut for Bullet()+Text() IMGUI_API void BulletTextV(const char* fmt, va_list args) IM_FMTLIST(1); - IMGUI_API void SeparatorText(const char* label); // currently: formatted text with an horizontal line + IMGUI_API void SeparatorText(const char* label); // currently: formatted text with a horizontal line // Widgets: Main // - Most widgets return true when the value has been changed or when pressed/selected @@ -566,9 +564,10 @@ namespace ImGui // Widgets: Images // - Read about ImTextureID here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples // - 'uv0' and 'uv1' are texture coordinates. Read about them from the same link above. - // - Note that Image() may add +2.0f to provided size if a border is visible, ImageButton() adds style.FramePadding*2.0f to provided size. + // - Image() pads adds style.ImageBorderSize on each side, ImageButton() adds style.FramePadding on each side. // - ImageButton() draws a background based on regular Button() color + optionally an inner background if specified. - IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec4& border_col = ImVec4(0, 0, 0, 0)); + IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1)); + IMGUI_API void ImageWithBg(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); IMGUI_API bool ImageButton(const char* str_id, ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); // Widgets: Combo Box (Dropdown) @@ -906,7 +905,7 @@ namespace ImGui IMGUI_API void PopClipRect(); // Focus, Activation - IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of of a newly appearing window. + IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a newly appearing window. IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. // Keyboard/Gamepad Navigation @@ -974,7 +973,7 @@ namespace ImGui IMGUI_API bool IsKeyReleased(ImGuiKey key); // was key released (went from Down to !Down)? IMGUI_API bool IsKeyChordPressed(ImGuiKeyChord key_chord); // was key chord (mods + key) pressed, e.g. you can pass 'ImGuiMod_Ctrl | ImGuiKey_S' as a key-chord. This doesn't do any routing or focus check, please consider using Shortcut() function instead. IMGUI_API int GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate - IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names a provided for debugging purpose and are not meant to be saved persistently not compared. + IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names are provided for debugging purpose and are not meant to be saved persistently nor compared. IMGUI_API void SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard); // Override io.WantCaptureKeyboard flag next frame (said flag is left for your application to handle, typically when true it instructs your app to ignore inputs). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting "io.WantCaptureKeyboard = want_capture_keyboard"; after the next NewFrame() call. // Inputs Utilities: Shortcut Testing & Routing [BETA] @@ -1177,7 +1176,7 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). // Elide display / Alignment - ImGuiInputTextFlags_ElideLeft = 1 << 17, // When text doesn't fit, elide left side to ensure right side stays visible. Useful for path/filenames. Single-line only! + ImGuiInputTextFlags_ElideLeft = 1 << 17, // When text doesn't fit, elide left side to ensure right side stays visible. Useful for path/filenames. Single-line only! // Callback features ImGuiInputTextFlags_CallbackCompletion = 1 << 18, // Callback on pressing TAB (for completion handling) @@ -1492,6 +1491,7 @@ enum ImGuiKey : int ImGuiKey_KeypadEqual, ImGuiKey_AppBack, // Available on some keyboard/mouses. Often referred as "Browser Back" ImGuiKey_AppForward, + ImGuiKey_Oem102, // Non-US backslash. // Gamepad (some of those are analog values, 0.0f to 1.0f) // NAVIGATION ACTION // (download controller mapping PNG/PSD at http://dearimgui.com/controls_sheets) @@ -1714,6 +1714,7 @@ enum ImGuiStyleVar_ ImGuiStyleVar_ScrollbarRounding, // float ScrollbarRounding ImGuiStyleVar_GrabMinSize, // float GrabMinSize ImGuiStyleVar_GrabRounding, // float GrabRounding + ImGuiStyleVar_ImageBorderSize, // float ImageBorderSize ImGuiStyleVar_TabRounding, // float TabRounding ImGuiStyleVar_TabBorderSize, // float TabBorderSize ImGuiStyleVar_TabBarBorderSize, // float TabBarBorderSize @@ -1833,6 +1834,8 @@ enum ImGuiMouseCursor_ ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window ImGuiMouseCursor_Hand, // (Unused by Dear ImGui functions. Use for e.g. hyperlinks) + ImGuiMouseCursor_Wait, // When waiting for something to process/load. + ImGuiMouseCursor_Progress, // When waiting for something to process/load, but application is still interactive. ImGuiMouseCursor_NotAllowed, // When hovering something with disallowed interaction. Usually a crossed circle. ImGuiMouseCursor_COUNT }; @@ -2146,6 +2149,7 @@ struct ImGuiStyle ImVec2 WindowPadding; // Padding within a window. float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended. float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). + float WindowBorderHoverPadding; // Hit-testing extent outside/inside resizing border. Also extend determination of hovered window. Generally meaningfully larger than WindowBorderSize to make it easy to reach borders. ImVec2 WindowMinSize; // Minimum window size. This is a global setting. If you want to constrain individual windows, use SetNextWindowSizeConstraints(). ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. ImGuiDir WindowMenuButtonPosition; // Side of the collapsing/docking button in the title bar (None/Left/Right). Defaults to ImGuiDir_Left. @@ -2167,9 +2171,11 @@ struct ImGuiStyle float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar. float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. float LogSliderDeadzone; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero. + float ImageBorderSize; // Thickness of border around Image() calls. float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. float TabBorderSize; // Thickness of border around tabs. - float TabMinWidthForCloseButton; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. + float TabCloseButtonMinWidthSelected; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width. + float TabCloseButtonMinWidthUnselected; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width. FLT_MAX: never show close button when unselected. float TabBarBorderSize; // Thickness of tab-bar separator, which takes on the tab active color to denote focus. float TabBarOverlineSize; // Thickness of tab-bar overline, which highlights the selected tab-bar. float TableAngledHeadersAngle; // Angle of angled headers (supported values range from -50.0f degrees to +50.0f degrees). @@ -2188,6 +2194,8 @@ struct ImGuiStyle bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. + + // Colors ImVec4 Colors[ImGuiCol_COUNT]; // Behaviors @@ -2200,6 +2208,11 @@ struct ImGuiStyle IMGUI_API ImGuiStyle(); IMGUI_API void ScaleAllSizes(float scale_factor); + + // Obsolete names +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + // TabMinWidthForCloseButton = TabCloseButtonMinWidthUnselected // Renamed in 1.91.9. +#endif }; //----------------------------------------------------------------------------- @@ -2310,7 +2323,8 @@ struct ImGuiIO // - Code should use PushID()/PopID() in loops, or append "##xx" to same-label identifiers. // - Empty label e.g. Button("") == same ID as parent widget/node. Use Button("##xx") instead! // - See FAQ https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#q-about-the-id-stack-system - bool ConfigDebugHighlightIdConflicts;// = true // Highlight and show an error message when multiple items have conflicting identifiers. + bool ConfigDebugHighlightIdConflicts;// = true // Highlight and show an error message popup when multiple items have conflicting identifiers. + bool ConfigDebugHighlightIdConflictsShowItemPicker;//=true // Show "Item Picker" button in aforementioned popup. // Tools to test correct Begin/End and BeginChild/EndChild behaviors. // - Presently Begin()/End() and BeginChild()/EndChild() needs to ALWAYS be called in tandem, regardless of return value of BeginXXX() @@ -2420,7 +2434,7 @@ struct ImGuiIO bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds. bool MouseDownOwnedUnlessPopupClose[5]; // Track if button was clicked inside a dear imgui window. bool MouseWheelRequestAxisSwap; // On a non-Mac system, holding SHIFT requests WheelY to perform the equivalent of a WheelX event. On a Mac system this is already enforced by the system. - bool MouseCtrlLeftAsRightClick; // (OSX) Set to true when the current click was a ctrl-click that spawned a simulated right click + bool MouseCtrlLeftAsRightClick; // (OSX) Set to true when the current click was a Ctrl+click that spawned a simulated right click float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked) float MouseDownDurationPrev[5]; // Previous time the mouse button has been down float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point (used for moving thresholds) @@ -2585,10 +2599,11 @@ struct ImGuiTextBuffer ImGuiTextBuffer() { } inline char operator[](int i) const { IM_ASSERT(Buf.Data != NULL); return Buf.Data[i]; } const char* begin() const { return Buf.Data ? &Buf.front() : EmptyString; } - const char* end() const { return Buf.Data ? &Buf.back() : EmptyString; } // Buf is zero-terminated, so end() will point on the zero-terminator + const char* end() const { return Buf.Data ? &Buf.back() : EmptyString; } // Buf is zero-terminated, so end() will point on the zero-terminator int size() const { return Buf.Size ? Buf.Size - 1 : 0; } bool empty() const { return Buf.Size <= 1; } void clear() { Buf.clear(); } + void resize(int size) { if (Buf.Size > size) Buf.Data[size] = 0; Buf.resize(size ? size + 1 : 0, 0); } // Similar to resize(0) on ImVector: empty string but don't free buffer. void reserve(int capacity) { Buf.reserve(capacity); } const char* c_str() const { return Buf.Data ? Buf.Data : EmptyString; } IMGUI_API void append(const char* str, const char* str_end = NULL); @@ -2940,6 +2955,13 @@ struct ImGuiSelectionExternalStorage #define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (32) #endif +// ImDrawIdx: vertex index. [Compile-time configurable type] +// - To use 16-bit indices + allow large meshes: backend need to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset (recommended). +// - To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in your imconfig.h file. +#ifndef ImDrawIdx +typedef unsigned short ImDrawIdx; // Default: 16-bit (for maximum compatibility with renderer backends) +#endif + // ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h] // NB: You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering, // you can poke into the draw list for that! Draw callback may be useful for example to: @@ -3131,7 +3153,7 @@ struct ImDrawList // General polygon // - Only simple polygons are supported by filling functions (no self-intersections, no holes). - // - Concave polygon fill is more expensive than convex one: it has O(N^2) complexity. Provided as a convenience fo user but not used by main library. + // - Concave polygon fill is more expensive than convex one: it has O(N^2) complexity. Provided as a convenience for the user but not used by the main library. IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness); IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); IMGUI_API void AddConcavePolyFilled(const ImVec2* points, int num_points, ImU32 col); @@ -3257,11 +3279,12 @@ struct ImFontConfig int OversampleH; // 0 (2) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1 or 2 depending on size. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details. int OversampleV; // 0 (1) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1. This is not really useful as we don't use sub-pixel positions on the Y axis. float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height). - ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs when rendered: essentially add to glyph->AdvanceX. Only X axis is supported for now. + //ImVec2 GlyphExtraSpacing; // 0, 0 // (REMOVED IN 1.91.9: use GlyphExtraAdvanceX) ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input. const ImWchar* GlyphRanges; // NULL // THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs + float GlyphExtraAdvanceX; // 0 // Extra spacing (in pixels) between glyphs. Please contact us if you are using this. unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure. float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future. float RasterizerDensity; // 1.0f // DPI scale for rasterization, not altering other font metrics: make it easy to swap between e.g. a 100% and a 400% fonts for a zooming display. IMPORTANT: If you increase this it is expected that you increase font scale accordingly, otherwise quality may look lowered. @@ -3281,7 +3304,7 @@ struct ImFontGlyph unsigned int Colored : 1; // Flag to indicate glyph is colored and should generally ignore tinting (make it usable with no shift on little-endian as this is used in loops) unsigned int Visible : 1; // Flag to indicate glyph has no visible pixels (e.g. space). Allow early out when rendering. unsigned int Codepoint : 30; // 0x0000..0x10FFFF - float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in) + float AdvanceX; // Horizontal distance to advance layout with float X0, Y0, X1, Y1; // Glyph corners float U0, V0, U1, V1; // Texture coordinates }; @@ -3405,12 +3428,12 @@ struct ImFontAtlas // [Internal] IMGUI_API void CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) const; - IMGUI_API bool GetMouseCursorTexData(ImGuiMouseCursor cursor, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]); //------------------------------------------- // Members //------------------------------------------- + // Input ImFontAtlasFlags Flags; // Build flags (see ImFontAtlasFlags_) ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. @@ -3430,7 +3453,7 @@ struct ImFontAtlas ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. ImVector CustomRects; // Rectangles for packing custom texture data into the atlas. - ImVector ConfigData; // Configuration data + ImVector Sources; // Source/configuration data ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1]; // UVs for baked anti-aliased lines // [Internal] Font builder @@ -3442,8 +3465,8 @@ struct ImFontAtlas int PackIdLines; // Custom texture rectangle ID for baked anti-aliased lines // [Obsolete] - //typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+ - //typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+ + //typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+ + //typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+ }; // Font runtime data and rendering @@ -3458,13 +3481,13 @@ struct ImFont // [Internal] Members: Hot ~28/40 bytes (for RenderText loop) ImVector IndexLookup; // 12-16 // out // Sparse. Index glyphs by Unicode code-point. ImVector Glyphs; // 12-16 // out // All glyphs. - const ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar) + ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar) // [Internal] Members: Cold ~32/40 bytes - // Conceptually ConfigData[] is the list of font sources merged to create this font. + // Conceptually Sources[] is the list of font sources merged to create this font. ImFontAtlas* ContainerAtlas; // 4-8 // out // What we has been loaded into - const ImFontConfig* ConfigData; // 4-8 // in // Pointer within ContainerAtlas->ConfigData to ConfigDataCount instances - short ConfigDataCount; // 2 // in // Number of ImFontConfig involved in creating this font. Usually 1, or >1 when merging multiple font sources into one ImFont. + ImFontConfig* Sources; // 4-8 // in // Pointer within ContainerAtlas->Sources[], to SourcesCount instances + short SourcesCount; // 2 // in // Number of ImFontConfig involved in creating this font. Usually 1, or >1 when merging multiple font sources into one ImFont. short EllipsisCharCount; // 1 // out // 1 or 3 ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...'). ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?') @@ -3479,12 +3502,13 @@ struct ImFont // Methods IMGUI_API ImFont(); IMGUI_API ~ImFont(); - IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c); - IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c); + IMGUI_API ImFontGlyph* FindGlyph(ImWchar c); + IMGUI_API ImFontGlyph* FindGlyphNoFallback(ImWchar c); float GetCharAdvance(ImWchar c) { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; } bool IsLoaded() const { return ContainerAtlas != NULL; } - const char* GetDebugName() const { return ConfigData ? ConfigData->Name : ""; } + const char* GetDebugName() const { return Sources ? Sources->Name : ""; } + // [Internal] Don't use! // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL); // utf8 @@ -3498,7 +3522,6 @@ struct ImFont IMGUI_API void GrowIndex(int new_size); IMGUI_API void AddGlyph(const ImFontConfig* src_cfg, ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x); IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. - IMGUI_API void SetGlyphVisible(ImWchar c, bool visible); IMGUI_API bool IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last); }; @@ -3552,7 +3575,7 @@ struct ImGuiPlatformIO IMGUI_API ImGuiPlatformIO(); //------------------------------------------------------------------ - // Interface with OS and Platform backend + // Input - Interface with OS and Platform backend (most common stuff) //------------------------------------------------------------------ // Optional: Access OS clipboard @@ -3562,7 +3585,7 @@ struct ImGuiPlatformIO void* Platform_ClipboardUserData; // Optional: Open link/folder/file in OS Shell - // (default to use ShellExecuteA() on Windows, system() on Linux/Mac) + // (default to use ShellExecuteW() on Windows, system() on Linux/Mac) bool (*Platform_OpenInShellFn)(ImGuiContext* ctx, const char* path); void* Platform_OpenInShellUserData; @@ -3577,7 +3600,7 @@ struct ImGuiPlatformIO ImWchar Platform_LocaleDecimalPoint; // '.' //------------------------------------------------------------------ - // Interface with Renderer Backend + // Input - Interface with Renderer Backend //------------------------------------------------------------------ // Written by some backends during ImGui_ImplXXXX_RenderDrawData() call to point backend_specific ImGui_ImplXXXX_RenderState* structure. @@ -3603,6 +3626,8 @@ struct ImGuiPlatformImeData #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { + // OBSOLETED in 1.91.9 (from February 2025) + IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); // <-- border_col was removed in favor of ImGuiCol_ImageBorder. // OBSOLETED in 1.91.0 (from July 2024) static inline void PushButtonRepeat(bool repeat) { PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); } static inline void PopButtonRepeat() { PopItemFlag(); } diff --git a/3rdparty/imgui/include/imgui_internal.h b/3rdparty/imgui/include/imgui_internal.h index af52d0feae..ddf9ea3e9a 100644 --- a/3rdparty/imgui/include/imgui_internal.h +++ b/3rdparty/imgui/include/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.91.8 +// dear imgui, v1.91.9b // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. @@ -14,6 +14,7 @@ Index of this file: // [SECTION] Macros // [SECTION] Generic helpers // [SECTION] ImDrawList support +// [SECTION] Style support // [SECTION] Data types support // [SECTION] Widgets support: flags, enums, data structures // [SECTION] Popup support @@ -145,7 +146,6 @@ struct ImGuiBoxSelectState; // Box-selection state (currently used by mu struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it struct ImGuiContext; // Main Dear ImGui context struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine -struct ImGuiDataVarInfo; // Variable information (e.g. to access style variables from an enum) struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum struct ImGuiDeactivatedItemData; // Data for IsItemDeactivated()/IsItemDeactivatedAfterEdit() function. struct ImGuiErrorRecoveryState; // Storage of stack sizes for error handling and recovery @@ -166,6 +166,7 @@ struct ImGuiOldColumns; // Storage data for a columns set for legacy struct ImGuiPopupData; // Storage for current popup stack struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it +struct ImGuiStyleVarInfo; // Style variable information (e.g. to access style variables from an enum) struct ImGuiTabBar; // Storage for a tab bar struct ImGuiTabItem; // Storage for a tab item (within a tab bar) struct ImGuiTable; // Storage for a table @@ -366,11 +367,14 @@ static inline void ImQsort(void* base, size_t count, size_t size_of_element IMGUI_API ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b); // Helpers: Bit manipulation -static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; } -static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; } -static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } +static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; } +static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; } +static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } +static inline unsigned int ImCountSetBits(unsigned int v) { unsigned int count = 0; while (v > 0) { v = v & (v - 1); count++; } return count; } // Helpers: String +#define ImStrlen strlen +#define ImMemchr memchr IMGUI_API int ImStricmp(const char* str1, const char* str2); // Case insensitive compare. IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); // Case insensitive compare to a certain count. IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); // Copy to a certain count and always zero terminate (strncpy doesn't). @@ -786,8 +790,9 @@ struct IMGUI_API ImDrawListSharedData float FontScale; // Current/default font scale (== FontSize / Font->FontSize) float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() float CircleSegmentMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc - ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() + float InitialFringeScale; // Initial scale to apply to AA fringe ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards) + ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() ImVector TempBuffer; // Temporary write buffer // Lookup tables @@ -808,17 +813,38 @@ struct ImDrawDataBuilder }; //----------------------------------------------------------------------------- -// [SECTION] Data types support +// [SECTION] Style support //----------------------------------------------------------------------------- -struct ImGuiDataVarInfo +struct ImGuiStyleVarInfo { - ImGuiDataType Type; - ImU32 Count; // 1+ - ImU32 Offset; // Offset in parent structure + ImU32 Count : 8; // 1+ + ImGuiDataType DataType : 8; + ImU32 Offset : 16; // Offset in parent structure void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); } }; +// Stacked color modifier, backup of modified data so we can restore it +struct ImGuiColorMod +{ + ImGuiCol Col; + ImVec4 BackupValue; +}; + +// Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable. +struct ImGuiStyleMod +{ + ImGuiStyleVar VarIdx; + union { int BackupInt[2]; float BackupFloat[2]; }; + ImGuiStyleMod(ImGuiStyleVar idx, int v) { VarIdx = idx; BackupInt[0] = v; } + ImGuiStyleMod(ImGuiStyleVar idx, float v) { VarIdx = idx; BackupFloat[0] = v; } + ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v) { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Data types support +//----------------------------------------------------------------------------- + struct ImGuiDataTypeStorage { ImU8 Data[8]; // Opaque storage to fit any data up to ImGuiDataType_COUNT @@ -836,7 +862,7 @@ struct ImGuiDataTypeInfo // Extend ImGuiDataType_ enum ImGuiDataTypePrivate_ { - ImGuiDataType_Pointer = ImGuiDataType_COUNT + 1, + ImGuiDataType_Pointer = ImGuiDataType_COUNT, ImGuiDataType_ID, }; @@ -1037,23 +1063,6 @@ enum ImGuiPlotType ImGuiPlotType_Histogram, }; -// Stacked color modifier, backup of modified data so we can restore it -struct ImGuiColorMod -{ - ImGuiCol Col; - ImVec4 BackupValue; -}; - -// Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable. -struct ImGuiStyleMod -{ - ImGuiStyleVar VarIdx; - union { int BackupInt[2]; float BackupFloat[2]; }; - ImGuiStyleMod(ImGuiStyleVar idx, int v) { VarIdx = idx; BackupInt[0] = v; } - ImGuiStyleMod(ImGuiStyleVar idx, float v) { VarIdx = idx; BackupFloat[0] = v; } - ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v) { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; } -}; - // Storage data for BeginComboPreview()/EndComboPreview() struct IMGUI_API ImGuiComboPreviewData { @@ -1194,14 +1203,17 @@ enum ImGuiNextWindowDataFlags_ ImGuiNextWindowDataFlags_HasFocus = 1 << 5, ImGuiNextWindowDataFlags_HasBgAlpha = 1 << 6, ImGuiNextWindowDataFlags_HasScroll = 1 << 7, - ImGuiNextWindowDataFlags_HasChildFlags = 1 << 8, - ImGuiNextWindowDataFlags_HasRefreshPolicy = 1 << 9, + ImGuiNextWindowDataFlags_HasWindowFlags = 1 << 8, + ImGuiNextWindowDataFlags_HasChildFlags = 1 << 9, + ImGuiNextWindowDataFlags_HasRefreshPolicy = 1 << 10, }; // Storage for SetNexWindow** functions struct ImGuiNextWindowData { - ImGuiNextWindowDataFlags Flags; + ImGuiNextWindowDataFlags HasFlags; + + // Members below are NOT cleared. Always rely on HasFlags. ImGuiCond PosCond; ImGuiCond SizeCond; ImGuiCond CollapsedCond; @@ -1210,6 +1222,7 @@ struct ImGuiNextWindowData ImVec2 SizeVal; ImVec2 ContentSizeVal; ImVec2 ScrollVal; + ImGuiWindowFlags WindowFlags; // Only honored by BeginTable() ImGuiChildFlags ChildFlags; bool CollapsedVal; ImRect SizeConstraintRect; @@ -1220,7 +1233,7 @@ struct ImGuiNextWindowData ImGuiWindowRefreshFlags RefreshFlagsVal; ImGuiNextWindowData() { memset(this, 0, sizeof(*this)); } - inline void ClearFlags() { Flags = ImGuiNextWindowDataFlags_None; } + inline void ClearFlags() { HasFlags = ImGuiNextWindowDataFlags_None; } }; enum ImGuiNextItemDataFlags_ @@ -1237,7 +1250,8 @@ struct ImGuiNextItemData { ImGuiNextItemDataFlags HasFlags; // Called HasFlags instead of Flags to avoid mistaking this ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemFlags_AllowOverlap and ImGuiItemFlags_HasSelectionUserData. - // Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem() + + // Members below are NOT cleared by ItemAdd() meaning they are still valid during e.g. NavProcessItem(). Always rely on HasFlags. ImGuiID FocusScopeId; // Set by SetNextItemSelectionUserData() ImGuiSelectionUserData SelectionUserData; // Set by SetNextItemSelectionUserData() (note that NULL/0 is a valid value, we use -1 == ImGuiSelectionUserData_Invalid to mark invalid values) float Width; // Set by SetNextItemWidth() @@ -1305,6 +1319,7 @@ struct ImGuiWindowStackData ImGuiLastItemData ParentLastItemDataBackup; ImGuiErrorRecoveryState StackSizesInBegin; // Store size of various stacks for asserting bool DisabledOverrideReenable; // Non-child window override disabled flag + float DisabledOverrideReenableAlphaBackup; }; struct ImGuiShrinkWidthItem @@ -1992,7 +2007,6 @@ struct ImGuiMetricsConfig bool ShowDrawCmdMesh = true; bool ShowDrawCmdBoundingBoxes = true; bool ShowTextEncodingViewer = false; - bool ShowAtlasTintedWithTextColor = false; int ShowWindowsRectsType = -1; int ShowTablesRectsType = -1; int HighlightMonitorIdx = -1; @@ -2019,6 +2033,7 @@ struct ImGuiIDStackTool ImVector Results; bool CopyToClipboardOnCtrlC; float CopyToClipboardLastTime; + ImGuiTextBuffer ResultPathBuf; ImGuiIDStackTool() { memset(this, 0, sizeof(*this)); CopyToClipboardLastTime = -FLT_MAX; } }; @@ -2083,7 +2098,7 @@ struct ImGuiContext ImVector CurrentWindowStack; ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow* int WindowsActiveCount; // Number of unique windows submitted by frame - ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING). + float WindowsBorderHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, style.WindowBorderHoverPadding). This isn't so multi-dpi friendly. ImGuiID DebugBreakInWindow; // Set to break in Begin() call. ImGuiWindow* CurrentWindow; // Window being drawn into ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs. @@ -2500,6 +2515,8 @@ struct IMGUI_API ImGuiWindow ImVec2 ScrollTargetEdgeSnapDist; // 0.0f = no snapping, >0.0f snapping threshold ImVec2 ScrollbarSizes; // Size taken by each scrollbars on their smaller axis. Pay attention! ScrollbarSizes.x == width of the vertical scrollbar, ScrollbarSizes.y = height of the horizontal scrollbar. bool ScrollbarX, ScrollbarY; // Are scrollbars visible? + bool ScrollbarXStabilizeEnabled; // Was ScrollbarX previously auto-stabilized? + ImU8 ScrollbarXStabilizeToggledHistory; // Used to stabilize scrollbar visibility in case of feedback loops bool Active; // Set to true on Begin(), unless Collapsed bool WasActive; bool WriteAccessed; // Set to true when any widget access the current window @@ -2787,7 +2804,7 @@ struct IMGUI_API ImGuiTable { ImGuiID ID; ImGuiTableFlags Flags; - void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[] and RowCellData[] + void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[], and RowCellData[] ImGuiTableTempData* TempData; // Transient data while table is active. Point within g.CurrentTableStack[] ImSpan Columns; // Point within RawData[] ImSpan DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1) @@ -2801,7 +2818,7 @@ struct IMGUI_API ImGuiTable int ColumnsCount; // Number of columns declared in BeginTable() int CurrentRow; int CurrentColumn; - ImS16 InstanceCurrent; // Count of BeginTable() calls with same ID in the same frame (generally 0). This is a little bit similar to BeginCount for a window, but multiple table with same ID look are multiple tables, they are just synched. + ImS16 InstanceCurrent; // Count of BeginTable() calls with same ID in the same frame (generally 0). This is a little bit similar to BeginCount for a window, but multiple tables with the same ID are multiple tables, they are just synced. ImS16 InstanceInteracted; // Mark which instance (generally 0) of the same ID is being interacted with float RowPosY1; float RowPosY2; @@ -2833,7 +2850,7 @@ struct IMGUI_API ImGuiTable float AngledHeadersHeight; // Set by TableAngledHeadersRow(), used in TableUpdateLayout() float AngledHeadersSlope; // Set by TableAngledHeadersRow(), used in TableUpdateLayout() ImRect OuterRect; // Note: for non-scrolling table, OuterRect.Max.y is often FLT_MAX until EndTable(), unless a height has been specified in BeginTable(). - ImRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is + ImRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is " ImRect WorkRect; ImRect InnerClipRect; ImRect BgClipRect; // We use this to cpu-clip cell background color fill, evolve during the frame as we cross frozen rows boundaries @@ -2930,7 +2947,7 @@ struct IMGUI_API ImGuiTableTempData ImGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; } }; -// sizeof() ~ 12 +// sizeof() ~ 16 struct ImGuiTableColumnSettings { float WidthOrWeight; @@ -2939,7 +2956,7 @@ struct ImGuiTableColumnSettings ImGuiTableColumnIdx DisplayOrder; ImGuiTableColumnIdx SortOrder; ImU8 SortDirection : 2; - ImU8 IsEnabled : 1; // "Visible" in ini file + ImS8 IsEnabled : 2; // "Visible" in ini file ImU8 IsStretch : 1; ImGuiTableColumnSettings() @@ -2949,7 +2966,7 @@ struct ImGuiTableColumnSettings Index = -1; DisplayOrder = SortOrder = -1; SortDirection = ImGuiSortDirection_None; - IsEnabled = 1; + IsEnabled = -1; IsStretch = 0; } }; @@ -2980,7 +2997,8 @@ namespace ImGui // If this ever crashes because g.CurrentWindow is NULL, it means that either: // - ImGui::NewFrame() has never been called, which is illegal. // - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal. - IMGUI_API ImGuiIO& GetIOEx(ImGuiContext* ctx); + IMGUI_API ImGuiIO& GetIO(ImGuiContext* ctx); + IMGUI_API ImGuiPlatformIO& GetPlatformIO(ImGuiContext* ctx); inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; } inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; } IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id); @@ -3108,7 +3126,7 @@ namespace ImGui IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess); // Parameter stacks (shared) - IMGUI_API const ImGuiDataVarInfo* GetStyleVarInfo(ImGuiStyleVar idx); + IMGUI_API const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx); IMGUI_API void BeginDisabledOverrideReenable(); IMGUI_API void EndDisabledOverrideReenable(); @@ -3123,6 +3141,7 @@ namespace ImGui // Popups, Modals IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags); + IMGUI_API bool BeginPopupMenuEx(ImGuiID id, const char* label, ImGuiWindowFlags extra_window_flags); IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None); IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup); IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup); @@ -3474,6 +3493,7 @@ namespace ImGui inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); } inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active IMGUI_API void SetNextItemRefVal(ImGuiDataType data_type, void* p_data); + inline bool IsItemActiveAsInputText() { ImGuiContext& g = *GImGui; return g.ActiveId != 0 && g.ActiveId == g.LastItemData.ID && g.InputTextState.ID == g.LastItemData.ID; } // This may be useful to apply workaround that a based on distinguish whenever an item is active as a text input field. // Color IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); @@ -3569,16 +3589,18 @@ struct ImFontBuilderIO #ifdef IMGUI_ENABLE_STB_TRUETYPE IMGUI_API const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype(); #endif -IMGUI_API void ImFontAtlasUpdateConfigDataPointers(ImFontAtlas* atlas); +IMGUI_API void ImFontAtlasUpdateSourcesPointers(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas); -IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); +IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src, float ascent, float descent); IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque); IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value); IMGUI_API void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value); IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor); IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride); -IMGUI_API void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* cfg, int* out_oversample_h, int* out_oversample_v); +IMGUI_API void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* src, int* out_oversample_h, int* out_oversample_v); + +IMGUI_API bool ImFontAtlasGetMouseCursorTexData(ImFontAtlas* atlas, ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]); //----------------------------------------------------------------------------- // [SECTION] Test Engine specific hooks (imgui_test_engine) diff --git a/3rdparty/imgui/src/imgui.cpp b/3rdparty/imgui/src/imgui.cpp index 9be594c8b0..39a5e9c444 100644 --- a/3rdparty/imgui/src/imgui.cpp +++ b/3rdparty/imgui/src/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.91.8 +// dear imgui, v1.91.9b // (main code and documentation) // Help: @@ -142,7 +142,8 @@ CODE - CTRL+Shift+Left/Right: Select words. - CTRL+A or Double-Click: Select All. - CTRL+X, CTRL+C, CTRL+V: Use OS clipboard. - - CTRL+Z, CTRL+Y: Undo, Redo. + - CTRL+Z Undo. + - CTRL+Y or CTRL+Shift+Z: Redo. - ESCAPE: Revert text to its original value. - On OSX, controls are automatically adjusted to match standard OSX text editing 2ts and behaviors. @@ -430,6 +431,18 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2025/03/05 (1.91.9) - BeginMenu(): Internals: reworked mangling of menu windows to use "###Menu_00" etc. instead of "##Menu_00", allowing them to also store the menu name before it. This shouldn't affect code unless directly accessing menu window from their mangled name. + - 2025/02/27 (1.91.9) - Image(): removed 'tint_col' and 'border_col' parameter from Image() function. Added ImageWithBg() replacement. (#8131, #8238) + - old: void Image (ImTextureID tex_id, ImVec2 image_size, ImVec2 uv0 = (0,0), ImVec2 uv1 = (1,1), ImVec4 tint_col = (1,1,1,1), ImVec4 border_col = (0,0,0,0)); + - new: void Image (ImTextureID tex_id, ImVec2 image_size, ImVec2 uv0 = (0,0), ImVec2 uv1 = (1,1)); + - new: void ImageWithBg(ImTextureID tex_id, ImVec2 image_size, ImVec2 uv0 = (0,0), ImVec2 uv1 = (1,1), ImVec4 bg_col = (0,0,0,0), ImVec4 tint_col = (1,1,1,1)); + - TL;DR: 'border_col' had misleading side-effect on layout, 'bg_col' was missing, parameter order couldn't be consistent with ImageButton(). + - new behavior always use ImGuiCol_Border color + style.ImageBorderSize / ImGuiStyleVar_ImageBorderSize. + - old behavior altered border size (and therefore layout) based on border color's alpha, which caused variety of problems + old behavior a fixed 1.0f for border size which was not tweakable. + - kept legacy signature (will obsolete), which mimics the old behavior, but uses Max(1.0f, style.ImageBorderSize) when border_col is specified. + - added ImageWithBg() function which has both 'bg_col' (which was missing) and 'tint_col'. It was impossible to add 'bg_col' to Image() with a parameter order consistent with other functions, so we decided to remove 'tint_col' and introduce ImageWithBg(). + - 2025/02/25 (1.91.9) - internals: fonts: ImFontAtlas::ConfigData[] has been renamed to ImFontAtlas::Sources[]. ImFont::ConfigData[], ConfigDataCount has been renamed to Sources[], SourcesCount. + - 2025/02/06 (1.91.9) - renamed ImFontConfig::GlyphExtraSpacing.x to ImFontConfig::GlyphExtraAdvanceX. - 2025/01/22 (1.91.8) - removed ImGuiColorEditFlags_AlphaPreview (made value 0): it is now the default behavior. prior to 1.91.8: alpha was made opaque in the preview by default _unless_ using ImGuiColorEditFlags_AlphaPreview. We now display the preview as transparent by default. You can use ImGuiColorEditFlags_AlphaOpaque to use old behavior. the new flags (ImGuiColorEditFlags_AlphaOpaque, ImGuiColorEditFlags_AlphaNoBg + existing ImGuiColorEditFlags_AlphaPreviewHalf) may be combined better and allow finer controls: @@ -643,7 +656,7 @@ CODE - 2022/04/05 (1.88) - inputs: renamed ImGuiKeyModFlags to ImGuiModFlags. Kept inline redirection enums (will obsolete). This was never used in public API functions but technically present in imgui.h and ImGuiIO. - 2022/01/20 (1.87) - inputs: reworded gamepad IO. - Backend writing to io.NavInputs[] -> backend should call io.AddKeyEvent()/io.AddKeyAnalogEvent() with ImGuiKey_GamepadXXX values. - - 2022/01/19 (1.87) - sliders, drags: removed support for legacy arithmetic operators (+,+-,*,/) when inputing text. This doesn't break any api/code but a feature that used to be accessible by end-users (which seemingly no one used). + - 2022/01/19 (1.87) - sliders, drags: removed support for legacy arithmetic operators (+,+-,*,/) when inputting text. This doesn't break any api/code but a feature that used to be accessible by end-users (which seemingly no one used). - 2022/01/17 (1.87) - inputs: reworked mouse IO. - Backend writing to io.MousePos -> backend should call io.AddMousePosEvent() - Backend writing to io.MouseDown[] -> backend should call io.AddMouseButtonEvent() @@ -1133,17 +1146,19 @@ CODE #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok. +#pragma clang diagnostic ignored "-Wformat" // warning: format specifies type 'int' but the argument has type 'unsigned int' #pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. +#pragma clang diagnostic ignored "-Wformat-pedantic" // warning: format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic. #pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. #pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is. #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness -#pragma clang diagnostic ignored "-Wformat-pedantic" // warning: format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic. #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type 'int' #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type +#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label #elif defined(__GNUC__) // We disable -Wpragmas because GCC doesn't provide a has_warning equivalent and some forks/patches may not follow the warning/version association. #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind @@ -1166,11 +1181,7 @@ CODE // When using CTRL+TAB (or Gamepad Square+L/R) we delay the visual a little in order to reduce visual noise doing a fast switch. static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f; // Time before the highlight and screen dimming starts fading in static const float NAV_WINDOWING_LIST_APPEAR_DELAY = 0.15f; // Time before the window list starts to appear - static const float NAV_ACTIVATE_HIGHLIGHT_TIMER = 0.10f; // Time to highlight an item activated by a shortcut. - -// Window resizing from edges (when io.ConfigWindowsResizeFromEdges = true and ImGuiBackendFlags_HasMouseCursors is set in io.BackendFlags by backend) -static const float WINDOWS_HOVER_PADDING = 4.0f; // Extend outside window for hovering/resizing (maxxed with TouchPadding) and inside windows for borders. Affect FindHoveredWindow(). static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduce visual noise by only highlighting the border after a certain time. static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 0.70f; // Lock scrolled window (so it doesn't pick child windows that are scrolling through) for a certain time, unless mouse moved. @@ -1214,6 +1225,7 @@ static void UpdateWindowInFocusOrderList(ImGuiWindow* window, bool j // Navigation static void NavUpdate(); static void NavUpdateWindowing(); +static void NavUpdateWindowingApplyFocus(ImGuiWindow* window); static void NavUpdateWindowingOverlay(); static void NavUpdateCancelRequest(); static void NavUpdateCreateMoveRequest(); @@ -1317,6 +1329,7 @@ ImGuiStyle::ImGuiStyle() WindowPadding = ImVec2(8,8); // Padding within a window WindowRounding = 0.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended. WindowBorderSize = 1.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested. + WindowBorderHoverPadding = 4.0f; // Hit-testing extent outside/inside resizing border. Also extend determination of hovered window. Generally meaningfully larger than WindowBorderSize to make it easy to reach borders. WindowMinSize = ImVec2(32,32); // Minimum window size WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text WindowMenuButtonPosition = ImGuiDir_Left; // Position of the collapsing/docking button in the title bar (left/right). Defaults to ImGuiDir_Left. @@ -1338,9 +1351,11 @@ ImGuiStyle::ImGuiStyle() GrabMinSize = 12.0f; // Minimum width/height of a grab box for slider/scrollbar GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero. + ImageBorderSize = 0.0f; // Thickness of border around tabs. TabRounding = 5.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. TabBorderSize = 0.0f; // Thickness of border around tabs. - TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. + TabCloseButtonMinWidthSelected = -1.0f; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width. + TabCloseButtonMinWidthUnselected = 0.0f; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width. FLT_MAX: never show close button when unselected. TabBarBorderSize = 1.0f; // Thickness of tab-bar separator, which takes on the tab active color to denote focus. TabBarOverlineSize = 1.0f; // Thickness of tab-bar overline, which highlights the selected tab-bar. TableAngledHeadersAngle = 35.0f * (IM_PI / 180.0f); // Angle of angled headers (supported values range from -50 degrees to +50 degrees). @@ -1378,6 +1393,7 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor) WindowPadding = ImTrunc(WindowPadding * scale_factor); WindowRounding = ImTrunc(WindowRounding * scale_factor); WindowMinSize = ImTrunc(WindowMinSize * scale_factor); + WindowBorderHoverPadding = ImTrunc(WindowBorderHoverPadding * scale_factor); ChildRounding = ImTrunc(ChildRounding * scale_factor); PopupRounding = ImTrunc(PopupRounding * scale_factor); FramePadding = ImTrunc(FramePadding * scale_factor); @@ -1393,8 +1409,10 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor) GrabMinSize = ImTrunc(GrabMinSize * scale_factor); GrabRounding = ImTrunc(GrabRounding * scale_factor); LogSliderDeadzone = ImTrunc(LogSliderDeadzone * scale_factor); + ImageBorderSize = ImTrunc(ImageBorderSize * scale_factor); TabRounding = ImTrunc(TabRounding * scale_factor); - TabMinWidthForCloseButton = (TabMinWidthForCloseButton != FLT_MAX) ? ImTrunc(TabMinWidthForCloseButton * scale_factor) : FLT_MAX; + TabCloseButtonMinWidthSelected = (TabCloseButtonMinWidthSelected > 0.0f && TabCloseButtonMinWidthSelected != FLT_MAX) ? ImTrunc(TabCloseButtonMinWidthSelected * scale_factor) : TabCloseButtonMinWidthSelected; + TabCloseButtonMinWidthUnselected = (TabCloseButtonMinWidthUnselected > 0.0f && TabCloseButtonMinWidthUnselected != FLT_MAX) ? ImTrunc(TabCloseButtonMinWidthUnselected * scale_factor) : TabCloseButtonMinWidthUnselected; TabBarOverlineSize = ImTrunc(TabBarOverlineSize * scale_factor); SeparatorTextPadding = ImTrunc(SeparatorTextPadding * scale_factor); DisplayWindowPadding = ImTrunc(DisplayWindowPadding * scale_factor); @@ -1451,6 +1469,7 @@ ImGuiIO::ImGuiIO() ConfigMemoryCompactTimer = 60.0f; ConfigDebugIsDebuggerPresent = false; ConfigDebugHighlightIdConflicts = true; + ConfigDebugHighlightIdConflictsShowItemPicker = true; ConfigDebugBeginReturnValueOnce = false; ConfigDebugBeginReturnValueLoop = false; @@ -1970,15 +1989,15 @@ void ImStrncpy(char* dst, const char* src, size_t count) char* ImStrdup(const char* str) { - size_t len = strlen(str); + size_t len = ImStrlen(str); void* buf = IM_ALLOC(len + 1); return (char*)memcpy(buf, (const void*)str, len + 1); } char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src) { - size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1; - size_t src_size = strlen(src) + 1; + size_t dst_buf_size = p_dst_size ? *p_dst_size : ImStrlen(dst) + 1; + size_t src_size = ImStrlen(src) + 1; if (dst_buf_size < src_size) { IM_FREE(dst); @@ -1991,7 +2010,7 @@ char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src) const char* ImStrchrRange(const char* str, const char* str_end, char c) { - const char* p = (const char*)memchr(str, (int)c, str_end - str); + const char* p = (const char*)ImMemchr(str, (int)c, str_end - str); return p; } @@ -2006,12 +2025,13 @@ int ImStrlenW(const ImWchar* str) // Find end-of-line. Return pointer will point to either first \n, either str_end. const char* ImStreolRange(const char* str, const char* str_end) { - const char* p = (const char*)memchr(str, '\n', str_end - str); + const char* p = (const char*)ImMemchr(str, '\n', str_end - str); return p ? p : str_end; } const char* ImStrbol(const char* buf_mid_line, const char* buf_begin) // find beginning-of-line { + IM_ASSERT_PARANOID(buf_mid_line >= buf_begin && buf_mid_line <= buf_begin + ImStrlen(buf_begin)); while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n') buf_mid_line--; return buf_mid_line; @@ -2020,7 +2040,7 @@ const char* ImStrbol(const char* buf_mid_line, const char* buf_begin) // find be const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end) { if (!needle_end) - needle_end = needle + strlen(needle); + needle_end = needle + ImStrlen(needle); const char un0 = (char)ImToUpper(*needle); while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end)) @@ -2141,7 +2161,7 @@ void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, if (buf == NULL) buf = "(null)"; *out_buf = buf; - if (out_buf_end) { *out_buf_end = buf + strlen(buf); } + if (out_buf_end) { *out_buf_end = buf + ImStrlen(buf); } } else if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*' && fmt[3] == 's' && fmt[4] == 0) { @@ -2399,7 +2419,7 @@ int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* int e = 0; e = (*out_char < mins[len]) << 6; // non-canonical encoding e |= ((*out_char >> 11) == 0x1b) << 7; // surrogate half? - e |= (*out_char > IM_UNICODE_CODEPOINT_MAX) << 8; // out of range? + e |= (*out_char > IM_UNICODE_CODEPOINT_MAX) << 8; // out of range we can store in ImWchar (FIXME: May evolve) e |= (s[1] & 0xc0) >> 2; e |= (s[2] & 0xc0) >> 4; e |= (s[3] ) >> 6; @@ -2550,11 +2570,11 @@ const char* ImTextFindPreviousUtf8Codepoint(const char* in_text_start, const cha int ImTextCountLines(const char* in_text, const char* in_text_end) { if (in_text_end == NULL) - in_text_end = in_text + strlen(in_text); // FIXME-OPT: Not optimal approach, discourage use for now. + in_text_end = in_text + ImStrlen(in_text); // FIXME-OPT: Not optimal approach, discourage use for now. int count = 0; while (in_text < in_text_end) { - const char* line_end = (const char*)memchr(in_text, '\n', in_text_end - in_text); + const char* line_end = (const char*)ImMemchr(in_text, '\n', in_text_end - in_text); in_text = line_end ? line_end + 1 : in_text_end; count++; } @@ -2835,7 +2855,7 @@ void ImGuiTextFilter::ImGuiTextRange::split(char separator, ImVectorDisplayStart = ImMax(data->Ranges[data->StepNo].Min, already_submitted); clipper->DisplayEnd = ImMin(data->Ranges[data->StepNo].Max, clipper->ItemsCount); - if (clipper->DisplayStart > already_submitted) //-V1051 - clipper->SeekCursorForItem(clipper->DisplayStart); data->StepNo++; - if (clipper->DisplayStart == clipper->DisplayEnd && data->StepNo < data->Ranges.Size) + if (clipper->DisplayStart >= clipper->DisplayEnd) continue; + if (clipper->DisplayStart > already_submitted) + clipper->SeekCursorForItem(clipper->DisplayStart); return true; } @@ -3263,7 +3283,7 @@ bool ImGuiListClipper::Step() ImGuiContext& g = *Ctx; bool need_items_height = (ItemsHeight <= 0.0f); bool ret = ImGuiListClipper_StepInternal(this); - if (ret && (DisplayStart == DisplayEnd)) + if (ret && (DisplayStart >= DisplayEnd)) ret = false; if (g.CurrentTable && g.CurrentTable->IsUnfrozenRows == false) IMGUI_DEBUG_LOG_CLIPPER("Clipper: Step(): inside frozen table row.\n"); @@ -3364,55 +3384,56 @@ void ImGui::PopStyleColor(int count) } } -static const ImGuiDataVarInfo GStyleVarInfo[] = +static const ImGuiStyleVarInfo GStyleVarsInfo[] = { - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, CellPadding) }, // ImGuiStyleVar_CellPadding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBorderSize) }, // ImGuiStyleVar_TabBorderSize - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarBorderSize) }, // ImGuiStyleVar_TabBarBorderSize - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarOverlineSize) }, // ImGuiStyleVar_TabBarOverlineSize - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersAngle)}, // ImGuiStyleVar_TableAngledHeadersAngle - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},// ImGuiStyleVar_TableAngledHeadersTextAlign - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)}, // ImGuiStyleVar_SeparatorTextBorderSize - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, CellPadding) }, // ImGuiStyleVar_CellPadding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ImageBorderSize) }, // ImGuiStyleVar_ImageBorderSize + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TabBorderSize) }, // ImGuiStyleVar_TabBorderSize + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TabBarBorderSize) }, // ImGuiStyleVar_TabBarBorderSize + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TabBarOverlineSize) }, // ImGuiStyleVar_TabBarOverlineSize + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersAngle)}, // ImGuiStyleVar_TableAngledHeadersAngle + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},// ImGuiStyleVar_TableAngledHeadersTextAlign + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)}, // ImGuiStyleVar_SeparatorTextBorderSize + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign + { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding }; -const ImGuiDataVarInfo* ImGui::GetStyleVarInfo(ImGuiStyleVar idx) +const ImGuiStyleVarInfo* ImGui::GetStyleVarInfo(ImGuiStyleVar idx) { IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_COUNT); - IM_STATIC_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_COUNT); - return &GStyleVarInfo[idx]; + IM_STATIC_ASSERT(IM_ARRAYSIZE(GStyleVarsInfo) == ImGuiStyleVar_COUNT); + return &GStyleVarsInfo[idx]; } void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) { ImGuiContext& g = *GImGui; - const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx); - if (var_info->Type != ImGuiDataType_Float || var_info->Count != 1) + const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); + if (var_info->DataType != ImGuiDataType_Float || var_info->Count != 1) { IM_ASSERT_USER_ERROR(0, "Calling PushStyleVar() variant with wrong type!"); return; @@ -3425,8 +3446,8 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) void ImGui::PushStyleVarX(ImGuiStyleVar idx, float val_x) { ImGuiContext& g = *GImGui; - const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx); - if (var_info->Type != ImGuiDataType_Float || var_info->Count != 2) + const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); + if (var_info->DataType != ImGuiDataType_Float || var_info->Count != 2) { IM_ASSERT_USER_ERROR(0, "Calling PushStyleVar() variant with wrong type!"); return; @@ -3439,8 +3460,8 @@ void ImGui::PushStyleVarX(ImGuiStyleVar idx, float val_x) void ImGui::PushStyleVarY(ImGuiStyleVar idx, float val_y) { ImGuiContext& g = *GImGui; - const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx); - if (var_info->Type != ImGuiDataType_Float || var_info->Count != 2) + const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); + if (var_info->DataType != ImGuiDataType_Float || var_info->Count != 2) { IM_ASSERT_USER_ERROR(0, "Calling PushStyleVar() variant with wrong type!"); return; @@ -3453,8 +3474,8 @@ void ImGui::PushStyleVarY(ImGuiStyleVar idx, float val_y) void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) { ImGuiContext& g = *GImGui; - const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx); - if (var_info->Type != ImGuiDataType_Float || var_info->Count != 2) + const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); + if (var_info->DataType != ImGuiDataType_Float || var_info->Count != 2) { IM_ASSERT_USER_ERROR(0, "Calling PushStyleVar() variant with wrong type!"); return; @@ -3476,10 +3497,10 @@ void ImGui::PopStyleVar(int count) { // We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it. ImGuiStyleMod& backup = g.StyleVarStack.back(); - const ImGuiDataVarInfo* info = GetStyleVarInfo(backup.VarIdx); - void* data = info->GetVarPtr(&g.Style); - if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; } - else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; } + const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(backup.VarIdx); + void* data = var_info->GetVarPtr(&g.Style); + if (var_info->DataType == ImGuiDataType_Float && var_info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; } + else if (var_info->DataType == ImGuiDataType_Float && var_info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; } g.StyleVarStack.pop_back(); count--; } @@ -3585,7 +3606,7 @@ void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool else { if (!text_end) - text_end = text + strlen(text); // FIXME-OPT + text_end = text + ImStrlen(text); // FIXME-OPT text_display_end = text_end; } @@ -3603,7 +3624,7 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end ImGuiWindow* window = g.CurrentWindow; if (!text_end) - text_end = text + strlen(text); // FIXME-OPT + text_end = text + ImStrlen(text); // FIXME-OPT if (text != text_end) { @@ -3790,7 +3811,7 @@ void ImGui::RenderMouseCursor(ImVec2 base_pos, float base_scale, ImGuiMouseCurso { // We scale cursor with current viewport/monitor, however Windows 10 for its own hardware cursor seems to be using a different scale factor. ImVec2 offset, size, uv[4]; - if (!font_atlas->GetMouseCursorTexData(mouse_cursor, &offset, &size, &uv[0], &uv[2])) + if (!ImFontAtlasGetMouseCursorTexData(font_atlas, mouse_cursor, &offset, &size, &uv[0], &uv[2])) continue; const ImVec2 pos = base_pos - offset; const float scale = base_scale; @@ -3803,6 +3824,13 @@ void ImGui::RenderMouseCursor(ImVec2 base_pos, float base_scale, ImGuiMouseCurso draw_list->AddImage(tex_id, pos + ImVec2(2, 0) * scale, pos + (ImVec2(2, 0) + size) * scale, uv[2], uv[3], col_shadow); draw_list->AddImage(tex_id, pos, pos + size * scale, uv[2], uv[3], col_border); draw_list->AddImage(tex_id, pos, pos + size * scale, uv[0], uv[1], col_fill); + if (mouse_cursor == ImGuiMouseCursor_Wait || mouse_cursor == ImGuiMouseCursor_Progress) + { + float a_min = ImFmod((float)g.Time * 5.0f, 2.0f * IM_PI); + float a_max = a_min + IM_PI * 1.65f; + draw_list->PathArcTo(pos + ImVec2(14, -1) * scale, 6.0f * scale, a_min, a_max); + draw_list->PathStroke(col_fill, ImDrawFlags_None, 3.0f * scale); + } draw_list->PopTextureID(); } } @@ -3903,6 +3931,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas) InputEventsNextEventId = 1; WindowsActiveCount = 0; + WindowsBorderHoverPadding = 0.0f; CurrentWindow = NULL; HoveredWindow = NULL; HoveredWindowUnderMovingWindow = NULL; @@ -4268,7 +4297,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* ctx, const char* name) : DrawListInst(NUL memset(this, 0, sizeof(*this)); Ctx = ctx; Name = ImStrdup(name); - NameBufLen = (int)strlen(name) + 1; + NameBufLen = (int)ImStrlen(name) + 1; ID = ImHashStr(name); IDStack.push_back(ID); MoveId = GetID("#MOVE"); @@ -4440,8 +4469,11 @@ void ImGui::MarkItemEdited(ImGuiID id) return; if (g.ActiveId == id || g.ActiveId == 0) { + // FIXME: Can't we fully rely on LastItemData yet? g.ActiveIdHasBeenEditedThisFrame = true; g.ActiveIdHasBeenEditedBefore = true; + if (g.DeactivatedItemData.ID == id) + g.DeactivatedItemData.HasBeenEditedBefore = true; } // We accept a MarkItemEdited() on drag and drop targets (see https://github.com/ocornut/imgui/issues/1875#issuecomment-978243343) @@ -4814,7 +4846,7 @@ ImGuiIO& ImGui::GetIO() } // This variant exists to facilitate backends experimenting with multi-threaded parallel context. (#8069, #6293, #5856) -ImGuiIO& ImGui::GetIOEx(ImGuiContext* ctx) +ImGuiIO& ImGui::GetIO(ImGuiContext* ctx) { IM_ASSERT(ctx != NULL); return ctx->IO; @@ -4826,6 +4858,13 @@ ImGuiPlatformIO& ImGui::GetPlatformIO() return GImGui->PlatformIO; } +// This variant exists to facilitate backends experimenting with multi-threaded parallel context. (#8069, #6293, #5856) +ImGuiPlatformIO& ImGui::GetPlatformIO(ImGuiContext* ctx) +{ + IM_ASSERT(ctx != NULL); + return ctx->PlatformIO; +} + // Pass this to your backend rendering function! Valid after Render() and until the next call to NewFrame() ImDrawData* ImGui::GetDrawData() { @@ -4918,7 +4957,7 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window) // Handle mouse moving window // Note: moving window with the navigation keys (Square + d-pad / CTRL+TAB + Arrows) are processed in NavUpdateWindowing() -// FIXME: We don't have strong guarantee that g.MovingWindow stay synched with g.ActiveId == g.MovingWindow->MoveId. +// FIXME: We don't have strong guarantee that g.MovingWindow stay synced with g.ActiveId == g.MovingWindow->MoveId. // This is currently enforced by the fact that BeginDragDropSource() is setting all g.ActiveIdUsingXXXX flags to inhibit navigation inputs, // but if we should more thoroughly test cases where g.ActiveId or g.MovingWindow gets changed and not the other. void ImGui::UpdateMouseMovingWindowNewFrame() @@ -5025,7 +5064,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() // FIXME-DPI: This storage was added on 2021/03/31 for test engine, but if we want to multiply WINDOWS_HOVER_PADDING // by DpiScale, we need to make this window-agnostic anyhow, maybe need storing inside ImGuiWindow. - g.WindowsHoverPadding = ImMax(g.Style.TouchExtraPadding, ImVec2(WINDOWS_HOVER_PADDING, WINDOWS_HOVER_PADDING)); + g.WindowsBorderHoverPadding = ImMax(ImMax(g.Style.TouchExtraPadding.x, g.Style.TouchExtraPadding.y), g.Style.WindowBorderHoverPadding); // Find the window hovered by mouse: // - Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow. @@ -5122,6 +5161,7 @@ static void SetupDrawListSharedData() g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill; if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset; + g.DrawListSharedData.InitialFringeScale = 1.0f; // FIXME-DPI: Change this for some DPI scaling experiments. } void ImGui::NewFrame() @@ -5788,7 +5828,7 @@ void ImGui::FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_vi hovered_window = g.MovingWindow; ImVec2 padding_regular = g.Style.TouchExtraPadding; - ImVec2 padding_for_resize = g.IO.ConfigWindowsResizeFromEdges ? g.WindowsHoverPadding : padding_regular; + ImVec2 padding_for_resize = ImMax(g.Style.TouchExtraPadding, ImVec2(g.Style.WindowBorderHoverPadding, g.Style.WindowBorderHoverPadding)); for (int i = g.Windows.Size - 1; i >= 0; i--) { ImGuiWindow* window = g.Windows[i]; @@ -6058,7 +6098,7 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, I // A SetNextWindowSize() call always has priority (#8020) // (since the code in Begin() never supported SizeVal==0.0f aka auto-resize via SetNextWindowSize() call, we don't support it here for now) // FIXME: We only support ImGuiCond_Always in this path. Supporting other paths would requires to obtain window pointer. - if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) != 0 && (g.NextWindowData.SizeCond & ImGuiCond_Always) != 0) + if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSize) != 0 && (g.NextWindowData.SizeCond & ImGuiCond_Always) != 0) { if (g.NextWindowData.SizeVal.x > 0.0f) { @@ -6074,11 +6114,11 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, I SetNextWindowSize(size); // Forward child flags (we allow prior settings to merge but it'll only work for adding flags) - if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasChildFlags) + if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) g.NextWindowData.ChildFlags |= child_flags; else g.NextWindowData.ChildFlags = child_flags; - g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasChildFlags; + g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasChildFlags; // Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value. // FIXME: 2023/11/14: commented out shorted version. We had an issue with multiple ### in child window path names, which the trailing hash helped workaround. @@ -6292,7 +6332,7 @@ static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, const ImVec2& s { ImGuiContext& g = *GImGui; ImVec2 new_size = size_desired; - if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint) + if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSizeConstraint) { // See comments in SetNextWindowSizeConstraints() for details about setting size_min an size_max. ImRect cr = g.NextWindowData.SizeConstraintRect; @@ -6490,7 +6530,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si int ret_auto_fit_mask = 0x00; const float grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f)); const float grip_hover_inner_size = (resize_grip_count > 0) ? IM_TRUNC(grip_draw_size * 0.75f) : 0.0f; - const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f; + const float grip_hover_outer_size = g.WindowsBorderHoverPadding; ImRect clamp_rect = visibility_rect; const bool window_move_from_title_bar = g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar); @@ -6526,7 +6566,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si { // Auto-fit when double-clicking size_target = CalcWindowSizeAfterConstraint(window, size_auto_fit); - ret_auto_fit_mask = 0x03; // Both axises + ret_auto_fit_mask = 0x03; // Both axes ClearActiveID(); } else if (held) @@ -6558,7 +6598,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si const ImGuiAxis axis = (border_n == ImGuiDir_Left || border_n == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y; bool hovered, held; - ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_HOVER_PADDING); + ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, g.WindowsBorderHoverPadding); ImGuiID border_id = window->GetID(border_n + 4); // == GetWindowResizeBorderID() ItemAdd(border_rect, border_id, NULL, ImGuiItemFlags_NoNav); ButtonBehavior(border_rect, border_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); @@ -6596,7 +6636,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si const ImVec2 border_curr = (window->Pos + ImMin(def.SegmentN1, def.SegmentN2) * window->Size); const float border_target_rel_mode_for_axis = border_curr[axis] + g.IO.MouseDelta[axis]; - const float border_target_abs_mode_for_axis = g.IO.MousePos[axis] - g.ActiveIdClickOffset[axis] + WINDOWS_HOVER_PADDING; // Match ButtonBehavior() padding above. + const float border_target_abs_mode_for_axis = g.IO.MousePos[axis] - g.ActiveIdClickOffset[axis] + g.WindowsBorderHoverPadding; // Match ButtonBehavior() padding above. // Use absolute mode position ImVec2 border_target = window->Pos; @@ -6685,7 +6725,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si // Recalculate next expected border expected coordinates if (*border_held != -1) - g.WindowResizeBorderExpectedRect = GetResizeBorderRect(window, *border_held, grip_hover_inner_size, WINDOWS_HOVER_PADDING); + g.WindowResizeBorderExpectedRect = GetResizeBorderRect(window, *border_held, grip_hover_inner_size, g.WindowsBorderHoverPadding); return ret_auto_fit_mask; } @@ -6770,7 +6810,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar ImU32 bg_col = GetColorU32(GetWindowBgColorIdx(window)); bool override_alpha = false; float alpha = 1.0f; - if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasBgAlpha) + if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasBgAlpha) { alpha = g.NextWindowData.BgAlphaVal; override_alpha = true; @@ -6940,7 +6980,7 @@ void ImGui::UpdateWindowSkipRefresh(ImGuiWindow* window) { ImGuiContext& g = *GImGui; window->SkipRefresh = false; - if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasRefreshPolicy) == 0) + if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasRefreshPolicy) == 0) return; if (g.NextWindowData.RefreshFlagsVal & ImGuiWindowRefreshFlags_TryToAvoidRefresh) { @@ -7021,7 +7061,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { UpdateWindowInFocusOrderList(window, window_just_created, flags); window->Flags = (ImGuiWindowFlags)flags; - window->ChildFlags = (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasChildFlags) ? g.NextWindowData.ChildFlags : 0; + window->ChildFlags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) ? g.NextWindowData.ChildFlags : 0; window->LastFrameActive = current_frame; window->LastTimeActive = (float)g.Time; window->BeginOrderWithinParent = 0; @@ -7048,6 +7088,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window_stack_data.Window = window; window_stack_data.ParentLastItemDataBackup = g.LastItemData; window_stack_data.DisabledOverrideReenable = (flags & ImGuiWindowFlags_Tooltip) && (g.CurrentItemFlags & ImGuiItemFlags_Disabled); + window_stack_data.DisabledOverrideReenableAlphaBackup = 0.0f; ErrorRecoveryStoreState(&window_stack_data.StackSizesInBegin); g.StackSizesInBeginForCurrentWindow = &window_stack_data.StackSizesInBegin; if (flags & ImGuiWindowFlags_ChildMenu) @@ -7085,7 +7126,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // (FIXME: Consider splitting the HasXXX flags into X/Y components bool window_pos_set_by_api = false; bool window_size_x_set_by_api = false, window_size_y_set_by_api = false; - if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) + if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasPos) { window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.NextWindowData.PosCond) != 0; if (window_pos_set_by_api && ImLengthSqr(g.NextWindowData.PosPivotVal) > 0.00001f) @@ -7101,7 +7142,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) SetWindowPos(window, g.NextWindowData.PosVal, g.NextWindowData.PosCond); } } - if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) + if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSize) { window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.x > 0.0f); window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.y > 0.0f); @@ -7111,7 +7152,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) g.NextWindowData.SizeVal.y = window->SizeFull.y; SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond); } - if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasScroll) + if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasScroll) { if (g.NextWindowData.ScrollVal.x >= 0.0f) { @@ -7124,13 +7165,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->ScrollTargetCenterRatio.y = 0.0f; } } - if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasContentSize) + if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasContentSize) window->ContentSizeExplicit = g.NextWindowData.ContentSizeVal; else if (first_begin_of_the_frame) window->ContentSizeExplicit = ImVec2(0.0f, 0.0f); - if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasCollapsed) + if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasCollapsed) SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond); - if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasFocus) + if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasFocus) FocusWindow(window); if (window->Appearing) SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false); @@ -7165,7 +7206,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Update stored window name when it changes (which can _only_ happen with the "###" operator, so the ID would stay unchanged). // The title bar always display the 'name' parameter, so we only update the string storage if it needs to be visible to the end-user elsewhere. bool window_title_visible_elsewhere = false; - if (g.NavWindowingListWindow != NULL && (window->Flags & ImGuiWindowFlags_NoNavFocus) == 0) // Window titles visible when using CTRL+TAB + if (g.NavWindowingListWindow != NULL && (flags & ImGuiWindowFlags_NoNavFocus) == 0) // Window titles visible when using CTRL+TAB + window_title_visible_elsewhere = true; + if (flags & ImGuiWindowFlags_ChildMenu) window_title_visible_elsewhere = true; if (window_title_visible_elsewhere && !window_just_created && strcmp(name, window->Name) != 0) { @@ -7416,9 +7459,23 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) ImVec2 needed_size_from_last_frame = window_just_created ? ImVec2(0, 0) : window->ContentSize + window->WindowPadding * 2.0f; float size_x_for_scrollbars = use_current_size_for_scrollbar_x ? avail_size_from_current_frame.x : avail_size_from_last_frame.x; float size_y_for_scrollbars = use_current_size_for_scrollbar_y ? avail_size_from_current_frame.y : avail_size_from_last_frame.y; + bool scrollbar_x_prev = window->ScrollbarX; //bool scrollbar_y_from_last_frame = window->ScrollbarY; // FIXME: May want to use that in the ScrollbarX expression? How many pros vs cons? window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar)); window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((needed_size_from_last_frame.x > size_x_for_scrollbars - (window->ScrollbarY ? style.ScrollbarSize : 0.0f)) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + + // Track when ScrollbarX visibility keeps toggling, which is a sign of a feedback loop, and stabilize by enforcing visibility (#3285, #8488) + // (Feedback loops of this sort can manifest in various situations, but combining horizontal + vertical scrollbar + using a clipper with varying width items is one frequent cause. + // The better solution is to, either (1) enforce visibility by using ImGuiWindowFlags_AlwaysHorizontalScrollbar or (2) declare stable contents width with SetNextWindowContentSize(), if you can compute it) + window->ScrollbarXStabilizeToggledHistory <<= 1; + window->ScrollbarXStabilizeToggledHistory |= (scrollbar_x_prev != window->ScrollbarX) ? 0x01 : 0x00; + const bool scrollbar_x_stabilize = (window->ScrollbarXStabilizeToggledHistory != 0) && ImCountSetBits(window->ScrollbarXStabilizeToggledHistory) >= 4; // 4 == half of bits in our U8 history. + if (scrollbar_x_stabilize) + window->ScrollbarX = true; + //if (scrollbar_x_stabilize && !window->ScrollbarXStabilizeEnabled) + // IMGUI_DEBUG_LOG("[scroll] Stabilize ScrollbarX for Window '%s'\n", window->Name); + window->ScrollbarXStabilizeEnabled = scrollbar_x_stabilize; + if (window->ScrollbarX && !window->ScrollbarY) window->ScrollbarY = (needed_size_from_last_frame.y > size_y_for_scrollbars - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); @@ -7692,7 +7749,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Hide along with parent or if parent is collapsed if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCanSkipItems > 0)) window->HiddenFramesCanSkipItems = 1; - if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCannotSkipItems > 0)) + if (parent_window && parent_window->HiddenFramesCannotSkipItems > 0) window->HiddenFramesCannotSkipItems = 1; } @@ -7914,6 +7971,7 @@ void ImGui::BeginDisabledOverrideReenable() { ImGuiContext& g = *GImGui; IM_ASSERT(g.CurrentItemFlags & ImGuiItemFlags_Disabled); + g.CurrentWindowStack.back().DisabledOverrideReenableAlphaBackup = g.Style.Alpha; g.Style.Alpha = g.DisabledAlphaBackup; g.CurrentItemFlags &= ~ImGuiItemFlags_Disabled; g.ItemFlagsStack.push_back(g.CurrentItemFlags); @@ -7927,7 +7985,7 @@ void ImGui::EndDisabledOverrideReenable() IM_ASSERT(g.DisabledStackSize > 0); g.ItemFlagsStack.pop_back(); g.CurrentItemFlags = g.ItemFlagsStack.back(); - g.Style.Alpha = g.DisabledAlphaBackup * g.Style.DisabledAlpha; + g.Style.Alpha = g.CurrentWindowStack.back().DisabledOverrideReenableAlphaBackup; } void ImGui::PushTextWrapPos(float wrap_pos_x) @@ -8213,7 +8271,7 @@ void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pi { ImGuiContext& g = *GImGui; IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. - g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasPos; + g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasPos; g.NextWindowData.PosVal = pos; g.NextWindowData.PosPivotVal = pivot; g.NextWindowData.PosCond = cond ? cond : ImGuiCond_Always; @@ -8223,7 +8281,7 @@ void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) { ImGuiContext& g = *GImGui; IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. - g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasSize; + g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasSize; g.NextWindowData.SizeVal = size; g.NextWindowData.SizeCond = cond ? cond : ImGuiCond_Always; } @@ -8235,7 +8293,7 @@ void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback, void* custom_callback_user_data) { ImGuiContext& g = *GImGui; - g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasSizeConstraint; + g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasSizeConstraint; g.NextWindowData.SizeConstraintRect = ImRect(size_min, size_max); g.NextWindowData.SizeCallback = custom_callback; g.NextWindowData.SizeCallbackUserData = custom_callback_user_data; @@ -8246,14 +8304,14 @@ void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& s void ImGui::SetNextWindowContentSize(const ImVec2& size) { ImGuiContext& g = *GImGui; - g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasContentSize; + g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasContentSize; g.NextWindowData.ContentSizeVal = ImTrunc(size); } void ImGui::SetNextWindowScroll(const ImVec2& scroll) { ImGuiContext& g = *GImGui; - g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasScroll; + g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasScroll; g.NextWindowData.ScrollVal = scroll; } @@ -8261,7 +8319,7 @@ void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) { ImGuiContext& g = *GImGui; IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. - g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasCollapsed; + g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasCollapsed; g.NextWindowData.CollapsedVal = collapsed; g.NextWindowData.CollapsedCond = cond ? cond : ImGuiCond_Always; } @@ -8269,7 +8327,7 @@ void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) void ImGui::SetNextWindowBgAlpha(float alpha) { ImGuiContext& g = *GImGui; - g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasBgAlpha; + g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasBgAlpha; g.NextWindowData.BgAlphaVal = alpha; } @@ -8277,7 +8335,7 @@ void ImGui::SetNextWindowBgAlpha(float alpha) void ImGui::SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags) { ImGuiContext& g = *GImGui; - g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasRefreshPolicy; + g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasRefreshPolicy; g.NextWindowData.RefreshFlagsVal = flags; } @@ -8731,7 +8789,7 @@ ImGuiKeyData* ImGui::GetKeyData(ImGuiContext* ctx, ImGuiKey key) return &g.IO.KeysData[key - ImGuiKey_NamedKey_BEGIN]; } -// Those names a provided for debugging purpose and are not meant to be saved persistently not compared. +// Those names are provided for debugging purpose and are not meant to be saved persistently nor compared. static const char* const GKeyNames[] = { "Tab", "LeftArrow", "RightArrow", "UpArrow", "DownArrow", "PageUp", "PageDown", @@ -8746,7 +8804,7 @@ static const char* const GKeyNames[] = "Pause", "Keypad0", "Keypad1", "Keypad2", "Keypad3", "Keypad4", "Keypad5", "Keypad6", "Keypad7", "Keypad8", "Keypad9", "KeypadDecimal", "KeypadDivide", "KeypadMultiply", "KeypadSubtract", "KeypadAdd", "KeypadEnter", "KeypadEqual", - "AppBack", "AppForward", + "AppBack", "AppForward", "Oem102", "GamepadStart", "GamepadBack", "GamepadFaceLeft", "GamepadFaceRight", "GamepadFaceUp", "GamepadFaceDown", "GamepadDpadLeft", "GamepadDpadRight", "GamepadDpadUp", "GamepadDpadDown", @@ -8788,7 +8846,7 @@ const char* ImGui::GetKeyChordName(ImGuiKeyChord key_chord) (key != ImGuiKey_None || key_chord == ImGuiKey_None) ? GetKeyName(key) : ""); size_t len; if (key == ImGuiKey_None && key_chord != 0) - if ((len = strlen(g.TempKeychordName)) != 0) // Remove trailing '+' + if ((len = ImStrlen(g.TempKeychordName)) != 0) // Remove trailing '+' g.TempKeychordName[len - 1] = 0; return g.TempKeychordName; } @@ -9660,7 +9718,7 @@ void ImGui::UpdateMouseWheel() if (g.IO.MouseWheelRequestAxisSwap) wheel = ImVec2(wheel.y, 0.0f); - // Maintain a rough average of moving magnitude on both axises + // Maintain a rough average of moving magnitude on both axes // FIXME: should by based on wall clock time rather than frame-counter g.WheelingAxisAvg.x = ImExponentialMovingAverage(g.WheelingAxisAvg.x, ImAbs(wheel.x), 30); g.WheelingAxisAvg.y = ImExponentialMovingAverage(g.WheelingAxisAvg.y, ImAbs(wheel.y), 30); @@ -9673,7 +9731,7 @@ void ImGui::UpdateMouseWheel() // Mouse wheel scrolling: find target and apply // - don't renew lock if axis doesn't apply on the window. - // - select a main axis when both axises are being moved. + // - select a main axis when both axes are being moved. if (ImGuiWindow* window = (g.WheelingWindow ? g.WheelingWindow : FindBestWheelingWindow(wheel))) if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)) { @@ -10172,7 +10230,8 @@ static void ImGui::ErrorCheckNewFrameSanityChecks() IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting!"); IM_ASSERT(g.Style.CircleTessellationMaxError > 0.0f && "Invalid style setting!"); IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting!"); // Allows us to avoid a few clamps in color computations - IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting."); + IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting!"); + IM_ASSERT(g.Style.WindowBorderHoverPadding > 0.0f && "Invalid style setting!"); // Required otherwise cannot resize from borders. IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right); IM_ASSERT(g.Style.ColorButtonPosition == ImGuiDir_Left || g.Style.ColorButtonPosition == ImGuiDir_Right); @@ -10421,15 +10480,24 @@ void ImGui::ErrorCheckEndFrameFinalizeErrorTooltip() //BulletText("Code intending to use duplicate ID may use e.g. PushItemFlag(ImGuiItemFlags_AllowDuplicateId, true); ... PopItemFlag()"); // Not making this too visible for fear of it being abused. BulletText("Set io.ConfigDebugHighlightIdConflicts=false to disable this warning in non-programmers builds."); Separator(); - Text("(Hold CTRL to: use"); - SameLine(); - if (SmallButton("Item Picker")) - DebugStartItemPicker(); - SameLine(); - Text("to break in item call-stack, or"); - SameLine(); + if (g.IO.ConfigDebugHighlightIdConflictsShowItemPicker) + { + Text("(Hold CTRL to: use "); + SameLine(0.0f, 0.0f); + if (SmallButton("Item Picker")) + DebugStartItemPicker(); + SameLine(0.0f, 0.0f); + Text(" to break in item call-stack, or "); + } + else + { + Text("(Hold CTRL to "); + } + SameLine(0.0f, 0.0f); if (SmallButton("Open FAQ->About ID Stack System") && g.PlatformIO.Platform_OpenInShellFn != NULL) g.PlatformIO.Platform_OpenInShellFn(&g, "https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#qa-usage"); + SameLine(0.0f, 0.0f); + Text(")"); EndErrorTooltip(); } @@ -11290,7 +11358,7 @@ bool ImGui::BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags ext // See FindBestWindowPosForPopup() for positionning logic of other tooltips (not drag and drop ones). //ImVec2 tooltip_pos = g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding; const bool is_touchscreen = (g.IO.MouseSource == ImGuiMouseSource_TouchScreen); - if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) == 0) + if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasPos) == 0) { ImVec2 tooltip_pos = is_touchscreen ? (g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET_TOUCH * g.Style.MouseCursorScale) : (g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET_MOUSE * g.Style.MouseCursorScale); ImVec2 tooltip_pivot = is_touchscreen ? TOOLTIP_DEFAULT_PIVOT_TOUCH : ImVec2(0.0f, 0.0f); @@ -11666,17 +11734,32 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags) } char name[20]; - if (extra_window_flags & ImGuiWindowFlags_ChildMenu) - ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.BeginMenuDepth); // Recycle windows based on depth - else - ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame + IM_ASSERT((extra_window_flags & ImGuiWindowFlags_ChildMenu) == 0); // Use BeginPopupMenuEx() + ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // No recycling, so we can close/open during the same frame bool is_open = Begin(name, NULL, extra_window_flags | ImGuiWindowFlags_Popup); if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) EndPopup(); - //g.CurrentWindow->FocusRouteParentWindow = g.CurrentWindow->ParentWindowInBeginStack; + return is_open; +} +bool ImGui::BeginPopupMenuEx(ImGuiID id, const char* label, ImGuiWindowFlags extra_window_flags) +{ + ImGuiContext& g = *GImGui; + if (!IsPopupOpen(id, ImGuiPopupFlags_None)) + { + g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values + return false; + } + + char name[128]; + IM_ASSERT(extra_window_flags & ImGuiWindowFlags_ChildMenu); + ImFormatString(name, IM_ARRAYSIZE(name), "%s###Menu_%02d", label, g.BeginMenuDepth); // Recycle windows based on depth + bool is_open = Begin(name, NULL, extra_window_flags | ImGuiWindowFlags_Popup); + if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) + EndPopup(); + //g.CurrentWindow->FocusRouteParentWindow = g.CurrentWindow->ParentWindowInBeginStack; return is_open; } @@ -11713,7 +11796,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla // Center modal windows by default for increased visibility // (this won't really last as settings will kick in, and is mostly for backward compatibility. user may do the same themselves) // FIXME: Should test for (PosCond & window->SetWindowPosAllowFlags) with the upcoming window. - if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) == 0) + if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasPos) == 0) { const ImGuiViewport* viewport = GetMainViewport(); SetNextWindowPos(viewport->GetCenter(), ImGuiCond_FirstUseEver, ImVec2(0.5f, 0.5f)); @@ -12006,7 +12089,7 @@ void ImGui::SetWindowFocus(const char* name) void ImGui::SetNextWindowFocus() { ImGuiContext& g = *GImGui; - g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasFocus; + g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasFocus; } // Similar to IsWindowHovered() @@ -13628,6 +13711,33 @@ static void NavUpdateWindowingTarget(int focus_change_dir) g.NavWindowingToggleLayer = false; } +// Apply focus and close overlay +static void ImGui::NavUpdateWindowingApplyFocus(ImGuiWindow* apply_focus_window) +{ + ImGuiContext& g = *GImGui; + if (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindow) + { + ClearActiveID(); + SetNavCursorVisibleAfterMove(); + ClosePopupsOverWindow(apply_focus_window, false); + FocusWindow(apply_focus_window, ImGuiFocusRequestFlags_RestoreFocusedChild); + apply_focus_window = g.NavWindow; + if (apply_focus_window->NavLastIds[0] == 0) + NavInitWindow(apply_focus_window, false); + + // If the window has ONLY a menu layer (no main layer), select it directly + // Use NavLayersActiveMaskNext since windows didn't have a chance to be Begin()-ed on this frame, + // so CTRL+Tab where the keys are only held for 1 frame will be able to use correct layers mask since + // the target window as already been previewed once. + // FIXME-NAV: This should be done in NavInit.. or in FocusWindow... However in both of those cases, + // we won't have a guarantee that windows has been visible before and therefore NavLayersActiveMask* + // won't be valid. + if (apply_focus_window->DC.NavLayersActiveMaskNext == (1 << ImGuiNavLayer_Menu)) + g.NavLayer = ImGuiNavLayer_Menu; + } + g.NavWindowingTarget = NULL; +} + // Windowing management mode // Keyboard: CTRL+Tab (change focus/move/resize), Alt (toggle menu layer) // Gamepad: Hold Menu/Square (change focus/move/resize), Tap Menu/Square (toggle menu layer) @@ -13654,7 +13764,7 @@ static void ImGui::NavUpdateWindowing() // Start CTRL+Tab or Square+L/R window selection // (g.ConfigNavWindowingKeyNext/g.ConfigNavWindowingKeyPrev defaults are ImGuiMod_Ctrl|ImGuiKey_Tab and ImGuiMod_Ctrl|ImGuiMod_Shift|ImGuiKey_Tab) - const ImGuiID owner_id = ImHashStr("###NavUpdateWindowing"); + const ImGuiID owner_id = ImHashStr("##NavUpdateWindowing"); const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; const bool keyboard_next_window = allow_windowing && g.ConfigNavWindowingKeyNext && Shortcut(g.ConfigNavWindowingKeyNext, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id); @@ -13681,6 +13791,7 @@ static void ImGui::NavUpdateWindowing() SetKeyOwnersForKeyChord((g.ConfigNavWindowingKeyNext | g.ConfigNavWindowingKeyPrev) & ImGuiMod_Mask_, owner_id); } */ + // Gamepad update g.NavWindowingTimer += io.DeltaTime; if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_Gamepad) @@ -13690,7 +13801,7 @@ static void ImGui::NavUpdateWindowing() // Select window to focus const int focus_change_dir = (int)IsKeyPressed(ImGuiKey_GamepadL1) - (int)IsKeyPressed(ImGuiKey_GamepadR1); - if (focus_change_dir != 0 && !false /*just_started_windowing_from_null_focus*/) + if (focus_change_dir != 0 && !false /*just_started_windowing_from_null_focus*/) { NavUpdateWindowingTarget(focus_change_dir); g.NavWindowingHighlightAlpha = 1.0f; @@ -13782,28 +13893,8 @@ static void ImGui::NavUpdateWindowing() } // Apply final focus - if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindow)) - { - ClearActiveID(); - SetNavCursorVisibleAfterMove(); - ClosePopupsOverWindow(apply_focus_window, false); - FocusWindow(apply_focus_window, ImGuiFocusRequestFlags_RestoreFocusedChild); - apply_focus_window = g.NavWindow; - if (apply_focus_window->NavLastIds[0] == 0) - NavInitWindow(apply_focus_window, false); - - // If the window has ONLY a menu layer (no main layer), select it directly - // Use NavLayersActiveMaskNext since windows didn't have a chance to be Begin()-ed on this frame, - // so CTRL+Tab where the keys are only held for 1 frame will be able to use correct layers mask since - // the target window as already been previewed once. - // FIXME-NAV: This should be done in NavInit.. or in FocusWindow... However in both of those cases, - // we won't have a guarantee that windows has been visible before and therefore NavLayersActiveMask* - // won't be valid. - if (apply_focus_window->DC.NavLayersActiveMaskNext == (1 << ImGuiNavLayer_Menu)) - g.NavLayer = ImGuiNavLayer_Menu; - } if (apply_focus_window) - g.NavWindowingTarget = NULL; + NavUpdateWindowingApplyFocus(apply_focus_window); // Apply menu/layer toggle if (apply_toggle_layer && g.NavWindow) @@ -13857,12 +13948,12 @@ void ImGui::NavUpdateWindowingOverlay() return; if (g.NavWindowingListWindow == NULL) - g.NavWindowingListWindow = FindWindowByName("###NavWindowingOverlay"); + g.NavWindowingListWindow = FindWindowByName("##NavWindowingOverlay"); const ImGuiViewport* viewport = GetMainViewport(); SetNextWindowSizeConstraints(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y * 0.20f), ImVec2(FLT_MAX, FLT_MAX)); SetNextWindowPos(viewport->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f); - Begin("###NavWindowingOverlay", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings); + Begin("##NavWindowingOverlay", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings); if (g.ContextName[0] != 0) SeparatorText(g.ContextName); for (int n = g.WindowsFocusOrder.Size - 1; n >= 0; n--) @@ -14064,7 +14155,7 @@ bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_s cond = ImGuiCond_Always; IM_ASSERT(type != NULL); - IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 32 characters long"); + IM_ASSERT(ImStrlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 32 characters long"); IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0)); IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once); IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource() @@ -14308,7 +14399,7 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* } if (prefix) - LogRenderedText(ref_pos, prefix, prefix + strlen(prefix)); // Calculate end ourself to ensure "##" are included here. + LogRenderedText(ref_pos, prefix, prefix + ImStrlen(prefix)); // Calculate end ourself to ensure "##" are included here. // Re-adjust padding if we have popped out of our starting depth if (g.LogDepthRef > window->DC.TreeDepth) @@ -14341,7 +14432,7 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* } if (suffix) - LogRenderedText(ref_pos, suffix, suffix + strlen(suffix)); + LogRenderedText(ref_pos, suffix, suffix + ImStrlen(suffix)); } // Start logging/capturing text output @@ -14607,7 +14698,7 @@ void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size) // For user convenience, we allow passing a non zero-terminated string (hence the ini_size parameter). // For our convenience and to make the code simpler, we'll also write zero-terminators within the buffer. So let's create a writable copy.. if (ini_size == 0) - ini_size = strlen(ini_data); + ini_size = ImStrlen(ini_data); g.SettingsIniData.Buf.resize((int)ini_size + 1); char* const buf = g.SettingsIniData.Buf.Data; char* const buf_end = buf + ini_size; @@ -14708,7 +14799,7 @@ ImGuiWindowSettings* ImGui::CreateNewWindowSettings(const char* name) if (const char* p = strstr(name, "###")) name = p; } - const size_t name_len = strlen(name); + const size_t name_len = ImStrlen(name); // Allocate chunk const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1; @@ -15000,7 +15091,7 @@ static void Platform_SetClipboardTextFn_DefaultImpl(ImGuiContext*, const char* t if (!main_clipboard) PasteboardCreate(kPasteboardClipboard, &main_clipboard); PasteboardClear(main_clipboard); - CFDataRef cf_data = CFDataCreate(kCFAllocatorDefault, (const UInt8*)text, strlen(text)); + CFDataRef cf_data = CFDataCreate(kCFAllocatorDefault, (const UInt8*)text, ImStrlen(text)); if (cf_data) { PasteboardPutItemFlavor(main_clipboard, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), cf_data, 0); @@ -15054,7 +15145,7 @@ static void Platform_SetClipboardTextFn_DefaultImpl(ImGuiContext* ctx, const cha { ImGuiContext& g = *ctx; g.ClipboardHandlerData.clear(); - const char* text_end = text + strlen(text); + const char* text_end = text + ImStrlen(text); g.ClipboardHandlerData.resize((int)(text_end - text) + 1); memcpy(&g.ClipboardHandlerData[0], text, (size_t)(text_end - text)); g.ClipboardHandlerData[(int)(text_end - text)] = 0; @@ -15068,11 +15159,13 @@ static void Platform_SetClipboardTextFn_DefaultImpl(ImGuiContext* ctx, const cha #if defined(__APPLE__) && TARGET_OS_IPHONE #define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS #endif - +#if defined(__3DS__) +#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS +#endif #if defined(_WIN32) && defined(IMGUI_DISABLE_WIN32_FUNCTIONS) #define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS #endif -#endif +#endif // #ifndef IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS #ifndef IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS #ifdef _WIN32 @@ -15082,7 +15175,11 @@ static void Platform_SetClipboardTextFn_DefaultImpl(ImGuiContext* ctx, const cha #endif static bool Platform_OpenInShellFn_DefaultImpl(ImGuiContext*, const char* path) { - return (INT_PTR)::ShellExecuteA(NULL, "open", path, NULL, NULL, SW_SHOWDEFAULT) > 32; + const int path_wsize = ::MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); + ImVector path_wbuf; + path_wbuf.resize(path_wsize); + ::MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wbuf.Data, path_wsize); + return (INT_PTR)::ShellExecuteW(NULL, L"open", path_wbuf.Data, NULL, NULL, SW_SHOWDEFAULT) > 32; } #else #include @@ -15380,11 +15477,9 @@ void ImGui::ShowFontAtlas(ImFontAtlas* atlas) if (TreeNode("Font Atlas", "Font Atlas (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight)) { ImGuiContext& g = *GImGui; - ImGuiMetricsConfig* cfg = &g.DebugMetricsConfig; - Checkbox("Tint with Text Color", &cfg->ShowAtlasTintedWithTextColor); // Using text color ensure visibility of core atlas data, but will alter custom colored icons - ImVec4 tint_col = cfg->ShowAtlasTintedWithTextColor ? GetStyleColorVec4(ImGuiCol_Text) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f); - ImVec4 border_col = GetStyleColorVec4(ImGuiCol_Border); - Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), tint_col, border_col); + PushStyleVar(ImGuiStyleVar_ImageBorderSize, ImMax(1.0f, g.Style.ImageBorderSize)); + ImageWithBg(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + PopStyleVar(); TreePop(); } } @@ -16173,7 +16268,7 @@ void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, co void ImGui::DebugNodeFont(ImFont* font) { bool opened = TreeNode(font, "Font: \"%s\": %.2f px, %d glyphs, %d sources(s)", - font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size, font->ConfigDataCount); + font->Sources ? font->Sources[0].Name : "", font->FontSize, font->Glyphs.Size, font->SourcesCount); // Display preview text if (!opened) @@ -16206,14 +16301,14 @@ void ImGui::DebugNodeFont(ImFont* font) Text("Ellipsis character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->EllipsisChar), font->EllipsisChar); const int surface_sqrt = (int)ImSqrt((float)font->MetricsTotalSurface); Text("Texture Area: about %d px ~%dx%d px", font->MetricsTotalSurface, surface_sqrt, surface_sqrt); - for (int config_i = 0; config_i < font->ConfigDataCount; config_i++) - if (font->ConfigData) + for (int config_i = 0; config_i < font->SourcesCount; config_i++) + if (font->Sources) { - const ImFontConfig* cfg = &font->ConfigData[config_i]; + const ImFontConfig* src = &font->Sources[config_i]; int oversample_h, oversample_v; - ImFontAtlasBuildGetOversampleFactors(cfg, &oversample_h, &oversample_v); + ImFontAtlasBuildGetOversampleFactors(src, &oversample_h, &oversample_v); BulletText("Input %d: \'%s\', Oversample: (%d=>%d,%d=>%d), PixelSnapH: %d, Offset: (%.1f,%.1f)", - config_i, cfg->Name, cfg->OversampleH, oversample_h, cfg->OversampleV, oversample_v, cfg->PixelSnapH, cfg->GlyphOffset.x, cfg->GlyphOffset.y); + config_i, src->Name, src->OversampleH, oversample_h, src->OversampleV, oversample_v, src->PixelSnapH, src->GlyphOffset.x, src->GlyphOffset.y); } // Display all glyphs of the fonts in separate pages of 256 characters @@ -16540,7 +16635,7 @@ static void ShowDebugLogFlag(const char* name, ImGuiDebugLogFlags flags) void ImGui::ShowDebugLogWindow(bool* p_open) { ImGuiContext& g = *GImGui; - if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) == 0) + if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSize) == 0) SetNextWindowSize(ImVec2(0.0f, GetFontSize() * 12.0f), ImGuiCond_FirstUseEver); if (!Begin("Dear ImGui Debug Log", p_open) || GetCurrentWindow()->BeginCount > 1) { @@ -16822,7 +16917,7 @@ void ImGui::DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* dat ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%d", (int)(intptr_t)data_id); break; case ImGuiDataType_String: - ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%.*s", data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)strlen((const char*)data_id), (const char*)data_id); + ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%.*s", data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)ImStrlen((const char*)data_id), (const char*)data_id); break; case ImGuiDataType_Pointer: ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "(void*)0x%p", data_id); @@ -16860,7 +16955,7 @@ static int StackToolFormatLevelInfo(ImGuiIDStackTool* tool, int n, bool format_f void ImGui::ShowIDStackToolWindow(bool* p_open) { ImGuiContext& g = *GImGui; - if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) == 0) + if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSize) == 0) SetNextWindowSize(ImVec2(0.0f, GetFontSize() * 8.0f), ImGuiCond_FirstUseEver); if (!Begin("Dear ImGui ID Stack Tool", p_open) || GetCurrentWindow()->BeginCount > 1) { @@ -16870,42 +16965,44 @@ void ImGui::ShowIDStackToolWindow(bool* p_open) // Display hovered/active status ImGuiIDStackTool* tool = &g.DebugIDStackTool; - const ImGuiID hovered_id = g.HoveredIdPreviousFrame; - const ImGuiID active_id = g.ActiveId; -#ifdef IMGUI_ENABLE_TEST_ENGINE - Text("HoveredId: 0x%08X (\"%s\"), ActiveId: 0x%08X (\"%s\")", hovered_id, hovered_id ? ImGuiTestEngine_FindItemDebugLabel(&g, hovered_id) : "", active_id, active_id ? ImGuiTestEngine_FindItemDebugLabel(&g, active_id) : ""); -#else - Text("HoveredId: 0x%08X, ActiveId: 0x%08X", hovered_id, active_id); -#endif + + // Build and display path + tool->ResultPathBuf.resize(0); + for (int stack_n = 0; stack_n < tool->Results.Size; stack_n++) + { + char level_desc[256]; + StackToolFormatLevelInfo(tool, stack_n, false, level_desc, IM_ARRAYSIZE(level_desc)); + tool->ResultPathBuf.append(stack_n == 0 ? "//" : "/"); + for (int n = 0; level_desc[n]; n++) + { + if (level_desc[n] == '/') + tool->ResultPathBuf.append("\\"); + tool->ResultPathBuf.append(level_desc + n, level_desc + n + 1); + } + } + Text("0x%08X", tool->QueryId); SameLine(); MetricsHelpMarker("Hover an item with the mouse to display elements of the ID Stack leading to the item's final ID.\nEach level of the stack correspond to a PushID() call.\nAll levels of the stack are hashed together to make the final ID of a widget (ID displayed at the bottom level of the stack).\nRead FAQ entry about the ID stack for details."); // CTRL+C to copy path const float time_since_copy = (float)g.Time - tool->CopyToClipboardLastTime; - Checkbox("Ctrl+C: copy path to clipboard", &tool->CopyToClipboardOnCtrlC); + SameLine(); + PushStyleVarY(ImGuiStyleVar_FramePadding, 0.0f); Checkbox("Ctrl+C: copy path", &tool->CopyToClipboardOnCtrlC); PopStyleVar(); SameLine(); TextColored((time_since_copy >= 0.0f && time_since_copy < 0.75f && ImFmod(time_since_copy, 0.25f) < 0.25f * 0.5f) ? ImVec4(1.f, 1.f, 0.3f, 1.f) : ImVec4(), "*COPIED*"); if (tool->CopyToClipboardOnCtrlC && Shortcut(ImGuiMod_Ctrl | ImGuiKey_C, ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused)) { tool->CopyToClipboardLastTime = (float)g.Time; - char* p = g.TempBuffer.Data; - char* p_end = p + g.TempBuffer.Size; - for (int stack_n = 0; stack_n < tool->Results.Size && p + 3 < p_end; stack_n++) - { - *p++ = '/'; - char level_desc[256]; - StackToolFormatLevelInfo(tool, stack_n, false, level_desc, IM_ARRAYSIZE(level_desc)); - for (int n = 0; level_desc[n] && p + 2 < p_end; n++) - { - if (level_desc[n] == '/') - *p++ = '\\'; - *p++ = level_desc[n]; - } - } - *p = '\0'; - SetClipboardText(g.TempBuffer.Data); + SetClipboardText(tool->ResultPathBuf.c_str()); } + Text("- Path \"%s\"", tool->ResultPathBuf.c_str()); +#ifdef IMGUI_ENABLE_TEST_ENGINE + Text("- Label \"%s\"", tool->QueryId ? ImGuiTestEngine_FindItemDebugLabel(&g, tool->QueryId) : ""); +#endif + + Separator(); + // Display decorated stack tool->LastActiveFrame = g.FrameCount; if (tool->Results.Size > 0 && BeginTable("##table", 3, ImGuiTableFlags_Borders)) diff --git a/3rdparty/imgui/src/imgui_demo.cpp b/3rdparty/imgui/src/imgui_demo.cpp index 03ce4710ad..10fa434dca 100644 --- a/3rdparty/imgui/src/imgui_demo.cpp +++ b/3rdparty/imgui/src/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.91.8 +// dear imgui, v1.91.9b // (demo code) // Help: @@ -70,15 +70,38 @@ Index of this file: // [SECTION] Forward Declarations // [SECTION] Helpers -// [SECTION] Helpers: ExampleTreeNode, ExampleMemberInfo (for use by Property Editor & Multi-Select demos) // [SECTION] Demo Window / ShowDemoWindow() -// [SECTION] ShowDemoWindowMenuBar() -// [SECTION] ShowDemoWindowWidgets() -// [SECTION] ShowDemoWindowMultiSelect() -// [SECTION] ShowDemoWindowLayout() -// [SECTION] ShowDemoWindowPopups() -// [SECTION] ShowDemoWindowTables() -// [SECTION] ShowDemoWindowInputs() +// [SECTION] DemoWindowMenuBar() +// [SECTION] Helpers: ExampleTreeNode, ExampleMemberInfo (for use by Property Editor & Multi-Select demos) +// [SECTION] DemoWindowWidgetsBasic() +// [SECTION] DemoWindowWidgetsBullets() +// [SECTION] DemoWindowWidgetsCollapsingHeaders() +// [SECTION] DemoWindowWidgetsComboBoxes() +// [SECTION] DemoWindowWidgetsColorAndPickers() +// [SECTION] DemoWindowWidgetsDataTypes() +// [SECTION] DemoWindowWidgetsDisableBlocks() +// [SECTION] DemoWindowWidgetsDragAndDrop() +// [SECTION] DemoWindowWidgetsDragsAndSliders() +// [SECTION] DemoWindowWidgetsImages() +// [SECTION] DemoWindowWidgetsListBoxes() +// [SECTION] DemoWindowWidgetsMultiComponents() +// [SECTION] DemoWindowWidgetsPlotting() +// [SECTION] DemoWindowWidgetsProgressBars() +// [SECTION] DemoWindowWidgetsQueryingStatuses() +// [SECTION] DemoWindowWidgetsSelectables() +// [SECTION] DemoWindowWidgetsSelectionAndMultiSelect() +// [SECTION] DemoWindowWidgetsTabs() +// [SECTION] DemoWindowWidgetsText() +// [SECTION] DemoWindowWidgetsTextFilter() +// [SECTION] DemoWindowWidgetsTextInput() +// [SECTION] DemoWindowWidgetsTooltips() +// [SECTION] DemoWindowWidgetsTreeNodes() +// [SECTION] DemoWindowWidgetsVerticalSliders() +// [SECTION] DemoWindowWidgets() +// [SECTION] DemoWindowLayout() +// [SECTION] DemoWindowPopups() +// [SECTION] DemoWindowTables() +// [SECTION] DemoWindowInputs() // [SECTION] About Window / ShowAboutWindow() // [SECTION] Style Editor / ShowStyleEditor() // [SECTION] User Guide / ShowUserGuide() @@ -136,6 +159,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning: 'xx' is deprecated: The POSIX name for this.. // for strdup used in demo code (so user can copy & paste the code) #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type +#pragma clang diagnostic ignored "-Wformat" // warning: format specifies type 'int' but the argument has type 'unsigned int' #pragma clang diagnostic ignored "-Wformat-security" // warning: format string is not a string literal #pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. #pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used. @@ -144,6 +168,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access +#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe @@ -225,14 +250,18 @@ static void ShowExampleMenuFile(); // We split the contents of the big ShowDemoWindow() function into smaller functions // (because the link time of very large functions tends to grow non-linearly) -static void ShowDemoWindowMenuBar(ImGuiDemoWindowData* demo_data); -static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data); -static void ShowDemoWindowMultiSelect(ImGuiDemoWindowData* demo_data); -static void ShowDemoWindowLayout(); -static void ShowDemoWindowPopups(); -static void ShowDemoWindowTables(); -static void ShowDemoWindowColumns(); -static void ShowDemoWindowInputs(); +static void DemoWindowMenuBar(ImGuiDemoWindowData* demo_data); +static void DemoWindowWidgets(ImGuiDemoWindowData* demo_data); +static void DemoWindowLayout(); +static void DemoWindowPopups(); +static void DemoWindowTables(); +static void DemoWindowColumns(); +static void DemoWindowInputs(); + +// Helper tree functions used by Property Editor & Multi-Select demos +struct ExampleTreeNode; +static ExampleTreeNode* ExampleTree_CreateNode(const char* name, int uid, ExampleTreeNode* parent); +static void ExampleTree_DestroyNode(ExampleTreeNode* node); //----------------------------------------------------------------------------- // [SECTION] Helpers @@ -260,97 +289,6 @@ ImGuiDemoMarkerCallback GImGuiDemoMarkerCallback = NULL; void* GImGuiDemoMarkerCallbackUserData = NULL; #define IMGUI_DEMO_MARKER(section) do { if (GImGuiDemoMarkerCallback != NULL) GImGuiDemoMarkerCallback(__FILE__, __LINE__, section, GImGuiDemoMarkerCallbackUserData); } while (0) -//----------------------------------------------------------------------------- -// [SECTION] Helpers: ExampleTreeNode, ExampleMemberInfo (for use by Property Editor etc.) -//----------------------------------------------------------------------------- - -// Simple representation for a tree -// (this is designed to be simple to understand for our demos, not to be fancy or efficient etc.) -struct ExampleTreeNode -{ - // Tree structure - char Name[28] = ""; - int UID = 0; - ExampleTreeNode* Parent = NULL; - ImVector Childs; - unsigned short IndexInParent = 0; // Maintaining this allows us to implement linear traversal more easily - - // Leaf Data - bool HasData = false; // All leaves have data - bool DataMyBool = true; - int DataMyInt = 128; - ImVec2 DataMyVec2 = ImVec2(0.0f, 3.141592f); -}; - -// Simple representation of struct metadata/serialization data. -// (this is a minimal version of what a typical advanced application may provide) -struct ExampleMemberInfo -{ - const char* Name; // Member name - ImGuiDataType DataType; // Member type - int DataCount; // Member count (1 when scalar) - int Offset; // Offset inside parent structure -}; - -// Metadata description of ExampleTreeNode struct. -static const ExampleMemberInfo ExampleTreeNodeMemberInfos[] -{ - { "MyName", ImGuiDataType_String, 1, offsetof(ExampleTreeNode, Name) }, - { "MyBool", ImGuiDataType_Bool, 1, offsetof(ExampleTreeNode, DataMyBool) }, - { "MyInt", ImGuiDataType_S32, 1, offsetof(ExampleTreeNode, DataMyInt) }, - { "MyVec2", ImGuiDataType_Float, 2, offsetof(ExampleTreeNode, DataMyVec2) }, -}; - -static ExampleTreeNode* ExampleTree_CreateNode(const char* name, int uid, ExampleTreeNode* parent) -{ - ExampleTreeNode* node = IM_NEW(ExampleTreeNode); - snprintf(node->Name, IM_ARRAYSIZE(node->Name), "%s", name); - node->UID = uid; - node->Parent = parent; - node->IndexInParent = parent ? (unsigned short)parent->Childs.Size : 0; - if (parent) - parent->Childs.push_back(node); - return node; -} - -static void ExampleTree_DestroyNode(ExampleTreeNode* node) -{ - for (ExampleTreeNode* child_node : node->Childs) - ExampleTree_DestroyNode(child_node); - IM_DELETE(node); -} - -// Create example tree data -// (this allocates _many_ more times than most other code in either Dear ImGui or others demo) -static ExampleTreeNode* ExampleTree_CreateDemoTree() -{ - static const char* root_names[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pear", "Pineapple", "Strawberry", "Watermelon" }; - const size_t NAME_MAX_LEN = sizeof(ExampleTreeNode::Name); - char name_buf[NAME_MAX_LEN]; - int uid = 0; - ExampleTreeNode* node_L0 = ExampleTree_CreateNode("", ++uid, NULL); - const int root_items_multiplier = 2; - for (int idx_L0 = 0; idx_L0 < IM_ARRAYSIZE(root_names) * root_items_multiplier; idx_L0++) - { - snprintf(name_buf, IM_ARRAYSIZE(name_buf), "%s %d", root_names[idx_L0 / root_items_multiplier], idx_L0 % root_items_multiplier); - ExampleTreeNode* node_L1 = ExampleTree_CreateNode(name_buf, ++uid, node_L0); - const int number_of_childs = (int)strlen(node_L1->Name); - for (int idx_L1 = 0; idx_L1 < number_of_childs; idx_L1++) - { - snprintf(name_buf, IM_ARRAYSIZE(name_buf), "Child %d", idx_L1); - ExampleTreeNode* node_L2 = ExampleTree_CreateNode(name_buf, ++uid, node_L1); - node_L2->HasData = true; - if (idx_L1 == 0) - { - snprintf(name_buf, IM_ARRAYSIZE(name_buf), "Sub-child %d", 0); - ExampleTreeNode* node_L3 = ExampleTree_CreateNode(name_buf, ++uid, node_L2); - node_L3->HasData = true; - } - } - } - return node_L0; -} - //----------------------------------------------------------------------------- // [SECTION] Demo Window / ShowDemoWindow() //----------------------------------------------------------------------------- @@ -382,6 +320,7 @@ struct ImGuiDemoWindowData bool ShowAbout = false; // Other data + bool DisableSections = false; ExampleTreeNode* DemoTree = NULL; ~ImGuiDemoWindowData() { if (DemoTree) ExampleTree_DestroyNode(DemoTree); } @@ -475,7 +414,7 @@ void ImGui::ShowDemoWindow(bool* p_open) //ImGui::PushItemWidth(-ImGui::GetWindowWidth() * 0.35f); // e.g. Use 2/3 of the space for widgets and 1/3 for labels (right align) // Menu Bar - ShowDemoWindowMenuBar(&demo_data); + DemoWindowMenuBar(&demo_data); ImGui::Text("dear imgui says hello! (%s) (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM); ImGui::Spacing(); @@ -584,7 +523,7 @@ void ImGui::ShowDemoWindow(bool* p_open) "- Error recovery is not perfect nor guaranteed! It is a feature to ease development.\n" "- You not are not supposed to rely on it in the course of a normal application run.\n" "- Possible usage: facilitate recovery from errors triggered from a scripting language or after specific exceptions handlers.\n" - "- Always ensure that on programmers seat you have at minimum Asserts or Tooltips enabled when making direct imgui API call!" + "- Always ensure that on programmers seat you have at minimum Asserts or Tooltips enabled when making direct imgui API call! " "Otherwise it would severely hinder your ability to catch and correct mistakes!"); ImGui::Checkbox("io.ConfigErrorRecoveryEnableAssert", &io.ConfigErrorRecoveryEnableAssert); ImGui::Checkbox("io.ConfigErrorRecoveryEnableDebugLog", &io.ConfigErrorRecoveryEnableDebugLog); @@ -683,11 +622,11 @@ void ImGui::ShowDemoWindow(bool* p_open) } // All demo contents - ShowDemoWindowWidgets(&demo_data); - ShowDemoWindowLayout(); - ShowDemoWindowPopups(); - ShowDemoWindowTables(); - ShowDemoWindowInputs(); + DemoWindowWidgets(&demo_data); + DemoWindowLayout(); + DemoWindowPopups(); + DemoWindowTables(); + DemoWindowInputs(); // End of ShowDemoWindow() ImGui::PopItemWidth(); @@ -695,10 +634,10 @@ void ImGui::ShowDemoWindow(bool* p_open) } //----------------------------------------------------------------------------- -// [SECTION] ShowDemoWindowMenuBar() +// [SECTION] DemoWindowMenuBar() //----------------------------------------------------------------------------- -static void ShowDemoWindowMenuBar(ImGuiDemoWindowData* demo_data) +static void DemoWindowMenuBar(ImGuiDemoWindowData* demo_data) { IMGUI_DEMO_MARKER("Menu"); if (ImGui::BeginMenuBar()) @@ -770,20 +709,102 @@ static void ShowDemoWindowMenuBar(ImGuiDemoWindowData* demo_data) } //----------------------------------------------------------------------------- -// [SECTION] ShowDemoWindowWidgets() +// [SECTION] Helpers: ExampleTreeNode, ExampleMemberInfo (for use by Property Editor & Multi-Select demos) //----------------------------------------------------------------------------- -static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) +// Simple representation for a tree +// (this is designed to be simple to understand for our demos, not to be fancy or efficient etc.) +struct ExampleTreeNode { - IMGUI_DEMO_MARKER("Widgets"); - //ImGui::SetNextItemOpen(true, ImGuiCond_Once); - if (!ImGui::CollapsingHeader("Widgets")) - return; + // Tree structure + char Name[28] = ""; + int UID = 0; + ExampleTreeNode* Parent = NULL; + ImVector Childs; + unsigned short IndexInParent = 0; // Maintaining this allows us to implement linear traversal more easily - static bool disable_all = false; // The Checkbox for that is inside the "Disabled" section at the bottom - if (disable_all) - ImGui::BeginDisabled(); + // Leaf Data + bool HasData = false; // All leaves have data + bool DataMyBool = true; + int DataMyInt = 128; + ImVec2 DataMyVec2 = ImVec2(0.0f, 3.141592f); +}; +// Simple representation of struct metadata/serialization data. +// (this is a minimal version of what a typical advanced application may provide) +struct ExampleMemberInfo +{ + const char* Name; // Member name + ImGuiDataType DataType; // Member type + int DataCount; // Member count (1 when scalar) + int Offset; // Offset inside parent structure +}; + +// Metadata description of ExampleTreeNode struct. +static const ExampleMemberInfo ExampleTreeNodeMemberInfos[] +{ + { "MyName", ImGuiDataType_String, 1, offsetof(ExampleTreeNode, Name) }, + { "MyBool", ImGuiDataType_Bool, 1, offsetof(ExampleTreeNode, DataMyBool) }, + { "MyInt", ImGuiDataType_S32, 1, offsetof(ExampleTreeNode, DataMyInt) }, + { "MyVec2", ImGuiDataType_Float, 2, offsetof(ExampleTreeNode, DataMyVec2) }, +}; + +static ExampleTreeNode* ExampleTree_CreateNode(const char* name, int uid, ExampleTreeNode* parent) +{ + ExampleTreeNode* node = IM_NEW(ExampleTreeNode); + snprintf(node->Name, IM_ARRAYSIZE(node->Name), "%s", name); + node->UID = uid; + node->Parent = parent; + node->IndexInParent = parent ? (unsigned short)parent->Childs.Size : 0; + if (parent) + parent->Childs.push_back(node); + return node; +} + +static void ExampleTree_DestroyNode(ExampleTreeNode* node) +{ + for (ExampleTreeNode* child_node : node->Childs) + ExampleTree_DestroyNode(child_node); + IM_DELETE(node); +} + +// Create example tree data +// (this allocates _many_ more times than most other code in either Dear ImGui or others demo) +static ExampleTreeNode* ExampleTree_CreateDemoTree() +{ + static const char* root_names[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pear", "Pineapple", "Strawberry", "Watermelon" }; + const size_t NAME_MAX_LEN = sizeof(ExampleTreeNode::Name); + char name_buf[NAME_MAX_LEN]; + int uid = 0; + ExampleTreeNode* node_L0 = ExampleTree_CreateNode("", ++uid, NULL); + const int root_items_multiplier = 2; + for (int idx_L0 = 0; idx_L0 < IM_ARRAYSIZE(root_names) * root_items_multiplier; idx_L0++) + { + snprintf(name_buf, IM_ARRAYSIZE(name_buf), "%s %d", root_names[idx_L0 / root_items_multiplier], idx_L0 % root_items_multiplier); + ExampleTreeNode* node_L1 = ExampleTree_CreateNode(name_buf, ++uid, node_L0); + const int number_of_childs = (int)strlen(node_L1->Name); + for (int idx_L1 = 0; idx_L1 < number_of_childs; idx_L1++) + { + snprintf(name_buf, IM_ARRAYSIZE(name_buf), "Child %d", idx_L1); + ExampleTreeNode* node_L2 = ExampleTree_CreateNode(name_buf, ++uid, node_L1); + node_L2->HasData = true; + if (idx_L1 == 0) + { + snprintf(name_buf, IM_ARRAYSIZE(name_buf), "Sub-child %d", 0); + ExampleTreeNode* node_L3 = ExampleTree_CreateNode(name_buf, ++uid, node_L2); + node_L3->HasData = true; + } + } + } + return node_L0; +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsBasic() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsBasic() +{ IMGUI_DEMO_MARKER("Widgets/Basic"); if (ImGui::TreeNode("Basic")) { @@ -861,8 +882,8 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) "Hold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or Double-Click to select all.\n" - "CTRL+X,CTRL+C,CTRL+V clipboard.\n" - "CTRL+Z,CTRL+Y undo/redo.\n" + "CTRL+X,CTRL+C,CTRL+V for clipboard.\n" + "CTRL+Z to undo, CTRL+Y/CTRL+SHIFT+Z to redo.\n" "ESCAPE to revert.\n\n" "PROGRAMMER:\n" "You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() " @@ -979,233 +1000,44 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) "Refer to the \"List boxes\" section below for an explanation of how to use the more flexible and general BeginListBox/EndListBox API."); } - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Tooltips"); - if (ImGui::TreeNode("Tooltips")) - { - // Tooltips are windows following the mouse. They do not take focus away. - ImGui::SeparatorText("General"); - - // Typical use cases: - // - Short-form (text only): SetItemTooltip("Hello"); - // - Short-form (any contents): if (BeginItemTooltip()) { Text("Hello"); EndTooltip(); } - - // - Full-form (text only): if (IsItemHovered(...)) { SetTooltip("Hello"); } - // - Full-form (any contents): if (IsItemHovered(...) && BeginTooltip()) { Text("Hello"); EndTooltip(); } - - HelpMarker( - "Tooltip are typically created by using a IsItemHovered() + SetTooltip() sequence.\n\n" - "We provide a helper SetItemTooltip() function to perform the two with standards flags."); - - ImVec2 sz = ImVec2(-FLT_MIN, 0.0f); - - ImGui::Button("Basic", sz); - ImGui::SetItemTooltip("I am a tooltip"); - - ImGui::Button("Fancy", sz); - if (ImGui::BeginItemTooltip()) - { - ImGui::Text("I am a fancy tooltip"); - static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; - ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr)); - ImGui::Text("Sin(time) = %f", sinf((float)ImGui::GetTime())); - ImGui::EndTooltip(); - } - - ImGui::SeparatorText("Always On"); - - // Showcase NOT relying on a IsItemHovered() to emit a tooltip. - // Here the tooltip is always emitted when 'always_on == true'. - static int always_on = 0; - ImGui::RadioButton("Off", &always_on, 0); - ImGui::SameLine(); - ImGui::RadioButton("Always On (Simple)", &always_on, 1); - ImGui::SameLine(); - ImGui::RadioButton("Always On (Advanced)", &always_on, 2); - if (always_on == 1) - ImGui::SetTooltip("I am following you around."); - else if (always_on == 2 && ImGui::BeginTooltip()) - { - ImGui::ProgressBar(sinf((float)ImGui::GetTime()) * 0.5f + 0.5f, ImVec2(ImGui::GetFontSize() * 25, 0.0f)); - ImGui::EndTooltip(); - } - - ImGui::SeparatorText("Custom"); - - HelpMarker( - "Passing ImGuiHoveredFlags_ForTooltip to IsItemHovered() is the preferred way to standardize" - "tooltip activation details across your application. You may however decide to use custom" - "flags for a specific tooltip instance."); - - // The following examples are passed for documentation purpose but may not be useful to most users. - // Passing ImGuiHoveredFlags_ForTooltip to IsItemHovered() will pull ImGuiHoveredFlags flags values from - // 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or keyboard/gamepad is being used. - // With default settings, ImGuiHoveredFlags_ForTooltip is equivalent to ImGuiHoveredFlags_DelayShort + ImGuiHoveredFlags_Stationary. - ImGui::Button("Manual", sz); - if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip)) - ImGui::SetTooltip("I am a manually emitted tooltip."); - - ImGui::Button("DelayNone", sz); - if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNone)) - ImGui::SetTooltip("I am a tooltip with no delay."); - - ImGui::Button("DelayShort", sz); - if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_NoSharedDelay)) - ImGui::SetTooltip("I am a tooltip with a short delay (%0.2f sec).", ImGui::GetStyle().HoverDelayShort); - - ImGui::Button("DelayLong", sz); - if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay)) - ImGui::SetTooltip("I am a tooltip with a long delay (%0.2f sec).", ImGui::GetStyle().HoverDelayNormal); - - ImGui::Button("Stationary", sz); - if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary)) - ImGui::SetTooltip("I am a tooltip requiring mouse to be stationary before activating."); - - // Using ImGuiHoveredFlags_ForTooltip will pull flags from 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav', - // which default value include the ImGuiHoveredFlags_AllowWhenDisabled flag. - ImGui::BeginDisabled(); - ImGui::Button("Disabled item", sz); - if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip)) - ImGui::SetTooltip("I am a a tooltip for a disabled item."); - ImGui::EndDisabled(); + // Testing ImGuiOnceUponAFrame helper. + //static ImGuiOnceUponAFrame once; + //for (int i = 0; i < 5; i++) + // if (once) + // ImGui::Text("This will be displayed only once."); ImGui::TreePop(); } +} - // Testing ImGuiOnceUponAFrame helper. - //static ImGuiOnceUponAFrame once; - //for (int i = 0; i < 5; i++) - // if (once) - // ImGui::Text("This will be displayed only once."); +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsBullets() +//----------------------------------------------------------------------------- - IMGUI_DEMO_MARKER("Widgets/Tree Nodes"); - if (ImGui::TreeNode("Tree Nodes")) +static void DemoWindowWidgetsBullets() +{ + IMGUI_DEMO_MARKER("Widgets/Bullets"); + if (ImGui::TreeNode("Bullets")) { - IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Basic trees"); - if (ImGui::TreeNode("Basic trees")) + ImGui::BulletText("Bullet point 1"); + ImGui::BulletText("Bullet point 2\nOn multiple lines"); + if (ImGui::TreeNode("Tree node")) { - for (int i = 0; i < 5; i++) - { - // Use SetNextItemOpen() so set the default state of a node to be open. We could - // also use TreeNodeEx() with the ImGuiTreeNodeFlags_DefaultOpen flag to achieve the same thing! - if (i == 0) - ImGui::SetNextItemOpen(true, ImGuiCond_Once); - - // Here we use PushID() to generate a unique base ID, and then the "" used as TreeNode id won't conflict. - // An alternative to using 'PushID() + TreeNode("", ...)' to generate a unique ID is to use 'TreeNode((void*)(intptr_t)i, ...)', - // aka generate a dummy pointer-sized value to be hashed. The demo below uses that technique. Both are fine. - ImGui::PushID(i); - if (ImGui::TreeNode("", "Child %d", i)) - { - ImGui::Text("blah blah"); - ImGui::SameLine(); - if (ImGui::SmallButton("button")) {} - ImGui::TreePop(); - } - ImGui::PopID(); - } - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Advanced, with Selectable nodes"); - if (ImGui::TreeNode("Advanced, with Selectable nodes")) - { - HelpMarker( - "This is a more typical looking tree with selectable nodes.\n" - "Click to select, CTRL+Click to toggle, click on arrows or double-click to open."); - static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; - static bool align_label_with_current_x_position = false; - static bool test_drag_and_drop = false; - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", &base_flags, ImGuiTreeNodeFlags_OpenOnArrow); - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick); - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node."); - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth); - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanLabelWidth", &base_flags, ImGuiTreeNodeFlags_SpanLabelWidth); ImGui::SameLine(); HelpMarker("Reduce hit area to the text label and a bit of margin."); - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &base_flags, ImGuiTreeNodeFlags_SpanAllColumns); ImGui::SameLine(); HelpMarker("For use in Tables only."); - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_AllowOverlap", &base_flags, ImGuiTreeNodeFlags_AllowOverlap); - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_Framed", &base_flags, ImGuiTreeNodeFlags_Framed); ImGui::SameLine(); HelpMarker("Draw frame with background (e.g. for CollapsingHeader)"); - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_NavLeftJumpsBackHere", &base_flags, ImGuiTreeNodeFlags_NavLeftJumpsBackHere); - ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position); - ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop); - ImGui::Text("Hello!"); - if (align_label_with_current_x_position) - ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing()); - - // 'selection_mask' is dumb representation of what may be user-side selection state. - // You may retain selection state inside or outside your objects in whatever format you see fit. - // 'node_clicked' is temporary storage of what node we have clicked to process selection at the end - /// of the loop. May be a pointer to your own node type, etc. - static int selection_mask = (1 << 2); - int node_clicked = -1; - for (int i = 0; i < 6; i++) - { - // Disable the default "open on single-click behavior" + set Selected flag according to our selection. - // To alter selection we use IsItemClicked() && !IsItemToggledOpen(), so clicking on an arrow doesn't alter selection. - ImGuiTreeNodeFlags node_flags = base_flags; - const bool is_selected = (selection_mask & (1 << i)) != 0; - if (is_selected) - node_flags |= ImGuiTreeNodeFlags_Selected; - if (i < 3) - { - // Items 0..2 are Tree Node - bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i); - if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) - node_clicked = i; - if (test_drag_and_drop && ImGui::BeginDragDropSource()) - { - ImGui::SetDragDropPayload("_TREENODE", NULL, 0); - ImGui::Text("This is a drag and drop source"); - ImGui::EndDragDropSource(); - } - if (i == 2 && (base_flags & ImGuiTreeNodeFlags_SpanLabelWidth)) - { - // Item 2 has an additional inline button to help demonstrate SpanLabelWidth. - ImGui::SameLine(); - if (ImGui::SmallButton("button")) {} - } - if (node_open) - { - ImGui::BulletText("Blah blah\nBlah Blah"); - ImGui::SameLine(); - ImGui::SmallButton("Button"); - ImGui::TreePop(); - } - } - else - { - // Items 3..5 are Tree Leaves - // The only reason we use TreeNode at all is to allow selection of the leaf. Otherwise we can - // use BulletText() or advance the cursor by GetTreeNodeToLabelSpacing() and call Text(). - node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet - ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i); - if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) - node_clicked = i; - if (test_drag_and_drop && ImGui::BeginDragDropSource()) - { - ImGui::SetDragDropPayload("_TREENODE", NULL, 0); - ImGui::Text("This is a drag and drop source"); - ImGui::EndDragDropSource(); - } - } - } - if (node_clicked != -1) - { - // Update selection state - // (process outside of tree loop to avoid visual inconsistencies during the clicking frame) - if (ImGui::GetIO().KeyCtrl) - selection_mask ^= (1 << node_clicked); // CTRL+click to toggle - else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, may want to preserve selection when clicking on item that is part of the selection - selection_mask = (1 << node_clicked); // Click to single-select - } - if (align_label_with_current_x_position) - ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing()); + ImGui::BulletText("Another bullet point"); ImGui::TreePop(); } + ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)"); + ImGui::Bullet(); ImGui::SmallButton("Button"); ImGui::TreePop(); } +} +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsCollapsingHeaders() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsCollapsingHeaders() +{ IMGUI_DEMO_MARKER("Widgets/Collapsing Headers"); if (ImGui::TreeNode("Collapsing Headers")) { @@ -1229,890 +1061,14 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) */ ImGui::TreePop(); } +} - IMGUI_DEMO_MARKER("Widgets/Bullets"); - if (ImGui::TreeNode("Bullets")) - { - ImGui::BulletText("Bullet point 1"); - ImGui::BulletText("Bullet point 2\nOn multiple lines"); - if (ImGui::TreeNode("Tree node")) - { - ImGui::BulletText("Another bullet point"); - ImGui::TreePop(); - } - ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)"); - ImGui::Bullet(); ImGui::SmallButton("Button"); - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Text"); - if (ImGui::TreeNode("Text")) - { - IMGUI_DEMO_MARKER("Widgets/Text/Colored Text"); - if (ImGui::TreeNode("Colorful Text")) - { - // Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility. - ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "Pink"); - ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Yellow"); - ImGui::TextDisabled("Disabled"); - ImGui::SameLine(); HelpMarker("The TextDisabled color is stored in ImGuiStyle."); - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Text/Word Wrapping"); - if (ImGui::TreeNode("Word Wrapping")) - { - // Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility. - ImGui::TextWrapped( - "This text should automatically wrap on the edge of the window. The current implementation " - "for text wrapping follows simple rules suitable for English and possibly other languages."); - ImGui::Spacing(); - - static float wrap_width = 200.0f; - ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f"); - - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - for (int n = 0; n < 2; n++) - { - ImGui::Text("Test paragraph %d:", n); - ImVec2 pos = ImGui::GetCursorScreenPos(); - ImVec2 marker_min = ImVec2(pos.x + wrap_width, pos.y); - ImVec2 marker_max = ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()); - ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); - if (n == 0) - ImGui::Text("The lazy dog is a good dog. This paragraph should fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width); - else - ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh"); - - // Draw actual text bounding box, following by marker of our expected limit (should not overlap!) - draw_list->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255)); - draw_list->AddRectFilled(marker_min, marker_max, IM_COL32(255, 0, 255, 255)); - ImGui::PopTextWrapPos(); - } - - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Text/UTF-8 Text"); - if (ImGui::TreeNode("UTF-8 Text")) - { - // UTF-8 test with Japanese characters - // (Needs a suitable font? Try "Google Noto" or "Arial Unicode". See docs/FONTS.md for details.) - // - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8 - // - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. in Visual Studio, you - // can save your source files as 'UTF-8 without signature'). - // - FOR THIS DEMO FILE ONLY, BECAUSE WE WANT TO SUPPORT OLD COMPILERS, WE ARE *NOT* INCLUDING RAW UTF-8 - // CHARACTERS IN THIS SOURCE FILE. Instead we are encoding a few strings with hexadecimal constants. - // Don't do this in your application! Please use u8"text in any language" in your application! - // Note that characters values are preserved even by InputText() if the font cannot be displayed, - // so you can safely copy & paste garbled characters into another application. - ImGui::TextWrapped( - "CJK text will only appear if the font was loaded with the appropriate CJK character ranges. " - "Call io.Fonts->AddFontFromFileTTF() manually to load extra character ranges. " - "Read docs/FONTS.md for details."); - ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); - ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)"); - static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; - //static char buf[32] = u8"NIHONGO"; // <- this is how you would write it with C++11, using real kanjis - ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); - ImGui::TreePop(); - } - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Images"); - if (ImGui::TreeNode("Images")) - { - ImGuiIO& io = ImGui::GetIO(); - ImGui::TextWrapped( - "Below we are displaying the font texture (which is the only texture we have access to in this demo). " - "Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. " - "Hover the texture for a zoomed view!"); - - // Below we are displaying the font texture because it is the only texture we have access to inside the demo! - // Remember that ImTextureID is just storage for whatever you want it to be. It is essentially a value that - // will be passed to the rendering backend via the ImDrawCmd structure. - // If you use one of the default imgui_impl_XXXX.cpp rendering backend, they all have comments at the top - // of their respective source file to specify what they expect to be stored in ImTextureID, for example: - // - The imgui_impl_dx11.cpp renderer expect a 'ID3D11ShaderResourceView*' pointer - // - The imgui_impl_opengl3.cpp renderer expect a GLuint OpenGL texture identifier, etc. - // More: - // - If you decided that ImTextureID = MyEngineTexture*, then you can pass your MyEngineTexture* pointers - // to ImGui::Image(), and gather width/height through your own functions, etc. - // - You can use ShowMetricsWindow() to inspect the draw data that are being passed to your renderer, - // it will help you debug issues if you are confused about it. - // - Consider using the lower-level ImDrawList::AddImage() API, via ImGui::GetWindowDrawList()->AddImage(). - // - Read https://github.com/ocornut/imgui/blob/master/docs/FAQ.md - // - Read https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples - ImTextureID my_tex_id = io.Fonts->TexID; - float my_tex_w = (float)io.Fonts->TexWidth; - float my_tex_h = (float)io.Fonts->TexHeight; - { - static bool use_text_color_for_tint = false; - ImGui::Checkbox("Use Text Color for Tint", &use_text_color_for_tint); - ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h); - ImVec2 pos = ImGui::GetCursorScreenPos(); - ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left - ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right - ImVec4 tint_col = use_text_color_for_tint ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint - ImVec4 border_col = ImGui::GetStyleColorVec4(ImGuiCol_Border); - ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, tint_col, border_col); - if (ImGui::BeginItemTooltip()) - { - float region_sz = 32.0f; - float region_x = io.MousePos.x - pos.x - region_sz * 0.5f; - float region_y = io.MousePos.y - pos.y - region_sz * 0.5f; - float zoom = 4.0f; - if (region_x < 0.0f) { region_x = 0.0f; } - else if (region_x > my_tex_w - region_sz) { region_x = my_tex_w - region_sz; } - if (region_y < 0.0f) { region_y = 0.0f; } - else if (region_y > my_tex_h - region_sz) { region_y = my_tex_h - region_sz; } - ImGui::Text("Min: (%.2f, %.2f)", region_x, region_y); - ImGui::Text("Max: (%.2f, %.2f)", region_x + region_sz, region_y + region_sz); - ImVec2 uv0 = ImVec2((region_x) / my_tex_w, (region_y) / my_tex_h); - ImVec2 uv1 = ImVec2((region_x + region_sz) / my_tex_w, (region_y + region_sz) / my_tex_h); - ImGui::Image(my_tex_id, ImVec2(region_sz * zoom, region_sz * zoom), uv0, uv1, tint_col, border_col); - ImGui::EndTooltip(); - } - } - - IMGUI_DEMO_MARKER("Widgets/Images/Textured buttons"); - ImGui::TextWrapped("And now some textured buttons.."); - static int pressed_count = 0; - for (int i = 0; i < 8; i++) - { - // UV coordinates are often (0.0f, 0.0f) and (1.0f, 1.0f) to display an entire textures. - // Here are trying to display only a 32x32 pixels area of the texture, hence the UV computation. - // Read about UV coordinates here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples - ImGui::PushID(i); - if (i > 0) - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(i - 1.0f, i - 1.0f)); - ImVec2 size = ImVec2(32.0f, 32.0f); // Size of the image we want to make visible - ImVec2 uv0 = ImVec2(0.0f, 0.0f); // UV coordinates for lower-left - ImVec2 uv1 = ImVec2(32.0f / my_tex_w, 32.0f / my_tex_h); // UV coordinates for (32,32) in our texture - ImVec4 bg_col = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); // Black background - ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint - if (ImGui::ImageButton("", my_tex_id, size, uv0, uv1, bg_col, tint_col)) - pressed_count += 1; - if (i > 0) - ImGui::PopStyleVar(); - ImGui::PopID(); - ImGui::SameLine(); - } - ImGui::NewLine(); - ImGui::Text("Pressed %d times.", pressed_count); - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Combo"); - if (ImGui::TreeNode("Combo")) - { - // Combo Boxes are also called "Dropdown" in other systems - // Expose flags as checkbox for the demo - static ImGuiComboFlags flags = 0; - ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", &flags, ImGuiComboFlags_PopupAlignLeft); - ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo"); - if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", &flags, ImGuiComboFlags_NoArrowButton)) - flags &= ~ImGuiComboFlags_NoPreview; // Clear incompatible flags - if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", &flags, ImGuiComboFlags_NoPreview)) - flags &= ~(ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_WidthFitPreview); // Clear incompatible flags - if (ImGui::CheckboxFlags("ImGuiComboFlags_WidthFitPreview", &flags, ImGuiComboFlags_WidthFitPreview)) - flags &= ~ImGuiComboFlags_NoPreview; - - // Override default popup height - if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightSmall", &flags, ImGuiComboFlags_HeightSmall)) - flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightSmall); - if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightRegular", &flags, ImGuiComboFlags_HeightRegular)) - flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightRegular); - if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightLargest", &flags, ImGuiComboFlags_HeightLargest)) - flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightLargest); - - // Using the generic BeginCombo() API, you have full control over how to display the combo contents. - // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively - // stored in the object itself, etc.) - const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; - static int item_selected_idx = 0; // Here we store our selection data as an index. - - // Pass in the preview value visible before opening the combo (it could technically be different contents or not pulled from items[]) - const char* combo_preview_value = items[item_selected_idx]; - - if (ImGui::BeginCombo("combo 1", combo_preview_value, flags)) - { - for (int n = 0; n < IM_ARRAYSIZE(items); n++) - { - const bool is_selected = (item_selected_idx == n); - if (ImGui::Selectable(items[n], is_selected)) - item_selected_idx = n; - - // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) - if (is_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - - ImGui::Spacing(); - ImGui::SeparatorText("One-liner variants"); - HelpMarker("Flags above don't apply to this section."); - - // Simplified one-liner Combo() API, using values packed in a single constant string - // This is a convenience for when the selection set is small and known at compile-time. - static int item_current_2 = 0; - ImGui::Combo("combo 2 (one-liner)", &item_current_2, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); - - // Simplified one-liner Combo() using an array of const char* - // This is not very useful (may obsolete): prefer using BeginCombo()/EndCombo() for full control. - static int item_current_3 = -1; // If the selection isn't within 0..count, Combo won't display a preview - ImGui::Combo("combo 3 (array)", &item_current_3, items, IM_ARRAYSIZE(items)); - - // Simplified one-liner Combo() using an accessor function - static int item_current_4 = 0; - ImGui::Combo("combo 4 (function)", &item_current_4, [](void* data, int n) { return ((const char**)data)[n]; }, items, IM_ARRAYSIZE(items)); - - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/List Boxes"); - if (ImGui::TreeNode("List boxes")) - { - // BeginListBox() is essentially a thin wrapper to using BeginChild()/EndChild() - // using the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label. - // You may be tempted to simply use BeginChild() directly. However note that BeginChild() requires EndChild() - // to always be called (inconsistent with BeginListBox()/EndListBox()). - - // Using the generic BeginListBox() API, you have full control over how to display the combo contents. - // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively - // stored in the object itself, etc.) - const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; - static int item_selected_idx = 0; // Here we store our selected data as an index. - - static bool item_highlight = false; - int item_highlighted_idx = -1; // Here we store our highlighted data as an index. - ImGui::Checkbox("Highlight hovered item in second listbox", &item_highlight); - - if (ImGui::BeginListBox("listbox 1")) - { - for (int n = 0; n < IM_ARRAYSIZE(items); n++) - { - const bool is_selected = (item_selected_idx == n); - if (ImGui::Selectable(items[n], is_selected)) - item_selected_idx = n; - - if (item_highlight && ImGui::IsItemHovered()) - item_highlighted_idx = n; - - // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) - if (is_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndListBox(); - } - ImGui::SameLine(); HelpMarker("Here we are sharing selection state between both boxes."); - - // Custom size: use all width, 5 items tall - ImGui::Text("Full-width:"); - if (ImGui::BeginListBox("##listbox 2", ImVec2(-FLT_MIN, 5 * ImGui::GetTextLineHeightWithSpacing()))) - { - for (int n = 0; n < IM_ARRAYSIZE(items); n++) - { - bool is_selected = (item_selected_idx == n); - ImGuiSelectableFlags flags = (item_highlighted_idx == n) ? ImGuiSelectableFlags_Highlight : 0; - if (ImGui::Selectable(items[n], is_selected, flags)) - item_selected_idx = n; - - // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) - if (is_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndListBox(); - } - - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Selectables"); - //ImGui::SetNextItemOpen(true, ImGuiCond_Once); - if (ImGui::TreeNode("Selectables")) - { - // Selectable() has 2 overloads: - // - The one taking "bool selected" as a read-only selection information. - // When Selectable() has been clicked it returns true and you can alter selection state accordingly. - // - The one taking "bool* p_selected" as a read-write selection information (convenient in some cases) - // The earlier is more flexible, as in real application your selection may be stored in many different ways - // and not necessarily inside a bool value (e.g. in flags within objects, as an external list, etc). - IMGUI_DEMO_MARKER("Widgets/Selectables/Basic"); - if (ImGui::TreeNode("Basic")) - { - static bool selection[5] = { false, true, false, false }; - ImGui::Selectable("1. I am selectable", &selection[0]); - ImGui::Selectable("2. I am selectable", &selection[1]); - ImGui::Selectable("3. I am selectable", &selection[2]); - if (ImGui::Selectable("4. I am double clickable", selection[3], ImGuiSelectableFlags_AllowDoubleClick)) - if (ImGui::IsMouseDoubleClicked(0)) - selection[3] = !selection[3]; - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Selectables/Rendering more items on the same line"); - if (ImGui::TreeNode("Rendering more items on the same line")) - { - // (1) Using SetNextItemAllowOverlap() - // (2) Using the Selectable() override that takes "bool* p_selected" parameter, the bool value is toggled automatically. - static bool selected[3] = { false, false, false }; - ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(); ImGui::SmallButton("Link 1"); - ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(); ImGui::SmallButton("Link 2"); - ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(); ImGui::SmallButton("Link 3"); - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Selectables/In Tables"); - if (ImGui::TreeNode("In Tables")) - { - static bool selected[10] = {}; - - if (ImGui::BeginTable("split1", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) - { - for (int i = 0; i < 10; i++) - { - char label[32]; - sprintf(label, "Item %d", i); - ImGui::TableNextColumn(); - ImGui::Selectable(label, &selected[i]); // FIXME-TABLE: Selection overlap - } - ImGui::EndTable(); - } - ImGui::Spacing(); - if (ImGui::BeginTable("split2", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) - { - for (int i = 0; i < 10; i++) - { - char label[32]; - sprintf(label, "Item %d", i); - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::Selectable(label, &selected[i], ImGuiSelectableFlags_SpanAllColumns); - ImGui::TableNextColumn(); - ImGui::Text("Some other contents"); - ImGui::TableNextColumn(); - ImGui::Text("123456"); - } - ImGui::EndTable(); - } - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Selectables/Grid"); - if (ImGui::TreeNode("Grid")) - { - static char selected[4][4] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; - - // Add in a bit of silly fun... - const float time = (float)ImGui::GetTime(); - const bool winning_state = memchr(selected, 0, sizeof(selected)) == NULL; // If all cells are selected... - if (winning_state) - ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f + 0.5f * cosf(time * 2.0f), 0.5f + 0.5f * sinf(time * 3.0f))); - - for (int y = 0; y < 4; y++) - for (int x = 0; x < 4; x++) - { - if (x > 0) - ImGui::SameLine(); - ImGui::PushID(y * 4 + x); - if (ImGui::Selectable("Sailor", selected[y][x] != 0, 0, ImVec2(50, 50))) - { - // Toggle clicked cell + toggle neighbors - selected[y][x] ^= 1; - if (x > 0) { selected[y][x - 1] ^= 1; } - if (x < 3) { selected[y][x + 1] ^= 1; } - if (y > 0) { selected[y - 1][x] ^= 1; } - if (y < 3) { selected[y + 1][x] ^= 1; } - } - ImGui::PopID(); - } - - if (winning_state) - ImGui::PopStyleVar(); - ImGui::TreePop(); - } - IMGUI_DEMO_MARKER("Widgets/Selectables/Alignment"); - if (ImGui::TreeNode("Alignment")) - { - HelpMarker( - "By default, Selectables uses style.SelectableTextAlign but it can be overridden on a per-item " - "basis using PushStyleVar(). You'll probably want to always keep your default situation to " - "left-align otherwise it becomes difficult to layout multiple items on a same line"); - static bool selected[3 * 3] = { true, false, true, false, true, false, true, false, true }; - for (int y = 0; y < 3; y++) - { - for (int x = 0; x < 3; x++) - { - ImVec2 alignment = ImVec2((float)x / 2.0f, (float)y / 2.0f); - char name[32]; - sprintf(name, "(%.1f,%.1f)", alignment.x, alignment.y); - if (x > 0) ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, alignment); - ImGui::Selectable(name, &selected[3 * y + x], ImGuiSelectableFlags_None, ImVec2(80, 80)); - ImGui::PopStyleVar(); - } - } - ImGui::TreePop(); - } - ImGui::TreePop(); - } - - ShowDemoWindowMultiSelect(demo_data); - - // To wire InputText() with std::string or any other custom string type, - // see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file. - IMGUI_DEMO_MARKER("Widgets/Text Input"); - if (ImGui::TreeNode("Text Input")) - { - IMGUI_DEMO_MARKER("Widgets/Text Input/Multi-line Text Input"); - if (ImGui::TreeNode("Multi-line Text Input")) - { - // Note: we are using a fixed-sized buffer for simplicity here. See ImGuiInputTextFlags_CallbackResize - // and the code in misc/cpp/imgui_stdlib.h for how to setup InputText() for dynamically resizing strings. - static char text[1024 * 16] = - "/*\n" - " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n" - " the hexadecimal encoding of one offending instruction,\n" - " more formally, the invalid operand with locked CMPXCHG8B\n" - " instruction bug, is a design flaw in the majority of\n" - " Intel Pentium, Pentium MMX, and Pentium OverDrive\n" - " processors (all in the P5 microarchitecture).\n" - "*/\n\n" - "label:\n" - "\tlock cmpxchg8b eax\n"; - - static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput; - HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp because we don't want to include in here)"); - ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly); - ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput); - ImGui::SameLine(); HelpMarker("When _AllowTabInput is set, passing through the widget with Tabbing doesn't automatically activate it, in order to also cycling through subsequent widgets."); - ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine); - ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags); - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Text Input/Filtered Text Input"); - if (ImGui::TreeNode("Filtered Text Input")) - { - struct TextFilters - { - // Modify character input by altering 'data->Eventchar' (ImGuiInputTextFlags_CallbackCharFilter callback) - static int FilterCasingSwap(ImGuiInputTextCallbackData* data) - { - if (data->EventChar >= 'a' && data->EventChar <= 'z') { data->EventChar -= 'a' - 'A'; } // Lowercase becomes uppercase - else if (data->EventChar >= 'A' && data->EventChar <= 'Z') { data->EventChar += 'a' - 'A'; } // Uppercase becomes lowercase - return 0; - } - - // Return 0 (pass) if the character is 'i' or 'm' or 'g' or 'u' or 'i', otherwise return 1 (filter out) - static int FilterImGuiLetters(ImGuiInputTextCallbackData* data) - { - if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) - return 0; - return 1; - } - }; - - static char buf1[32] = ""; ImGui::InputText("default", buf1, 32); - static char buf2[32] = ""; ImGui::InputText("decimal", buf2, 32, ImGuiInputTextFlags_CharsDecimal); - static char buf3[32] = ""; ImGui::InputText("hexadecimal", buf3, 32, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase); - static char buf4[32] = ""; ImGui::InputText("uppercase", buf4, 32, ImGuiInputTextFlags_CharsUppercase); - static char buf5[32] = ""; ImGui::InputText("no blank", buf5, 32, ImGuiInputTextFlags_CharsNoBlank); - static char buf6[32] = ""; ImGui::InputText("casing swap", buf6, 32, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterCasingSwap); // Use CharFilter callback to replace characters. - static char buf7[32] = ""; ImGui::InputText("\"imgui\"", buf7, 32, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); // Use CharFilter callback to disable some characters. - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Text Input/Password input"); - if (ImGui::TreeNode("Password Input")) - { - static char password[64] = "password123"; - ImGui::InputText("password", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); - ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); - ImGui::InputTextWithHint("password (w/ hint)", "", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); - ImGui::InputText("password (clear)", password, IM_ARRAYSIZE(password)); - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Text Input/Completion, History, Edit Callbacks"); - if (ImGui::TreeNode("Completion, History, Edit Callbacks")) - { - struct Funcs - { - static int MyCallback(ImGuiInputTextCallbackData* data) - { - if (data->EventFlag == ImGuiInputTextFlags_CallbackCompletion) - { - data->InsertChars(data->CursorPos, ".."); - } - else if (data->EventFlag == ImGuiInputTextFlags_CallbackHistory) - { - if (data->EventKey == ImGuiKey_UpArrow) - { - data->DeleteChars(0, data->BufTextLen); - data->InsertChars(0, "Pressed Up!"); - data->SelectAll(); - } - else if (data->EventKey == ImGuiKey_DownArrow) - { - data->DeleteChars(0, data->BufTextLen); - data->InsertChars(0, "Pressed Down!"); - data->SelectAll(); - } - } - else if (data->EventFlag == ImGuiInputTextFlags_CallbackEdit) - { - // Toggle casing of first character - char c = data->Buf[0]; - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) data->Buf[0] ^= 32; - data->BufDirty = true; - - // Increment a counter - int* p_int = (int*)data->UserData; - *p_int = *p_int + 1; - } - return 0; - } - }; - static char buf1[64]; - ImGui::InputText("Completion", buf1, 64, ImGuiInputTextFlags_CallbackCompletion, Funcs::MyCallback); - ImGui::SameLine(); HelpMarker( - "Here we append \"..\" each time Tab is pressed. " - "See 'Examples>Console' for a more meaningful demonstration of using this callback."); - - static char buf2[64]; - ImGui::InputText("History", buf2, 64, ImGuiInputTextFlags_CallbackHistory, Funcs::MyCallback); - ImGui::SameLine(); HelpMarker( - "Here we replace and select text each time Up/Down are pressed. " - "See 'Examples>Console' for a more meaningful demonstration of using this callback."); - - static char buf3[64]; - static int edit_count = 0; - ImGui::InputText("Edit", buf3, 64, ImGuiInputTextFlags_CallbackEdit, Funcs::MyCallback, (void*)&edit_count); - ImGui::SameLine(); HelpMarker( - "Here we toggle the casing of the first character on every edit + count edits."); - ImGui::SameLine(); ImGui::Text("(%d)", edit_count); - - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Text Input/Resize Callback"); - if (ImGui::TreeNode("Resize Callback")) - { - // To wire InputText() with std::string or any other custom string type, - // you can use the ImGuiInputTextFlags_CallbackResize flag + create a custom ImGui::InputText() wrapper - // using your preferred type. See misc/cpp/imgui_stdlib.h for an implementation of this using std::string. - HelpMarker( - "Using ImGuiInputTextFlags_CallbackResize to wire your custom string type to InputText().\n\n" - "See misc/cpp/imgui_stdlib.h for an implementation of this for std::string."); - struct Funcs - { - static int MyResizeCallback(ImGuiInputTextCallbackData* data) - { - if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) - { - ImVector* my_str = (ImVector*)data->UserData; - IM_ASSERT(my_str->begin() == data->Buf); - my_str->resize(data->BufSize); // NB: On resizing calls, generally data->BufSize == data->BufTextLen + 1 - data->Buf = my_str->begin(); - } - return 0; - } - - // Note: Because ImGui:: is a namespace you would typically add your own function into the namespace. - // For example, you code may declare a function 'ImGui::InputText(const char* label, MyString* my_str)' - static bool MyInputTextMultiline(const char* label, ImVector* my_str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0) - { - IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); - return ImGui::InputTextMultiline(label, my_str->begin(), (size_t)my_str->size(), size, flags | ImGuiInputTextFlags_CallbackResize, Funcs::MyResizeCallback, (void*)my_str); - } - }; - - // For this demo we are using ImVector as a string container. - // Note that because we need to store a terminating zero character, our size/capacity are 1 more - // than usually reported by a typical string class. - static ImVector my_str; - if (my_str.empty()) - my_str.push_back(0); - Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16)); - ImGui::Text("Data: %p\nSize: %d\nCapacity: %d", (void*)my_str.begin(), my_str.size(), my_str.capacity()); - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Text Input/Eliding, Alignment"); - if (ImGui::TreeNode("Eliding, Alignment")) - { - static char buf1[128] = "/path/to/some/folder/with/long/filename.cpp"; - static ImGuiInputTextFlags flags = ImGuiInputTextFlags_ElideLeft; - ImGui::CheckboxFlags("ImGuiInputTextFlags_ElideLeft", &flags, ImGuiInputTextFlags_ElideLeft); - ImGui::InputText("Path", buf1, IM_ARRAYSIZE(buf1), flags); - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Text Input/Miscellaneous"); - if (ImGui::TreeNode("Miscellaneous")) - { - static char buf1[16]; - static ImGuiInputTextFlags flags = ImGuiInputTextFlags_EscapeClearsAll; - ImGui::CheckboxFlags("ImGuiInputTextFlags_EscapeClearsAll", &flags, ImGuiInputTextFlags_EscapeClearsAll); - ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly); - ImGui::CheckboxFlags("ImGuiInputTextFlags_NoUndoRedo", &flags, ImGuiInputTextFlags_NoUndoRedo); - ImGui::InputText("Hello", buf1, IM_ARRAYSIZE(buf1), flags); - ImGui::TreePop(); - } - - ImGui::TreePop(); - } - - // Tabs - IMGUI_DEMO_MARKER("Widgets/Tabs"); - if (ImGui::TreeNode("Tabs")) - { - IMGUI_DEMO_MARKER("Widgets/Tabs/Basic"); - if (ImGui::TreeNode("Basic")) - { - ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None; - if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) - { - if (ImGui::BeginTabItem("Avocado")) - { - ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah"); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("Broccoli")) - { - ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah"); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("Cucumber")) - { - ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah"); - ImGui::EndTabItem(); - } - ImGui::EndTabBar(); - } - ImGui::Separator(); - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Tabs/Advanced & Close Button"); - if (ImGui::TreeNode("Advanced & Close Button")) - { - // Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0). - static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable; - ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", &tab_bar_flags, ImGuiTabBarFlags_Reorderable); - ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", &tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs); - ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton); - ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton); - ImGui::CheckboxFlags("ImGuiTabBarFlags_DrawSelectedOverline", &tab_bar_flags, ImGuiTabBarFlags_DrawSelectedOverline); - if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0) - tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_; - if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown)) - tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown); - if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll)) - tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll); - - // Tab Bar - ImGui::AlignTextToFramePadding(); - ImGui::Text("Opened:"); - const char* names[4] = { "Artichoke", "Beetroot", "Celery", "Daikon" }; - static bool opened[4] = { true, true, true, true }; // Persistent user state - for (int n = 0; n < IM_ARRAYSIZE(opened); n++) - { - ImGui::SameLine(); - ImGui::Checkbox(names[n], &opened[n]); - } - - // Passing a bool* to BeginTabItem() is similar to passing one to Begin(): - // the underlying bool will be set to false when the tab is closed. - if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) - { - for (int n = 0; n < IM_ARRAYSIZE(opened); n++) - if (opened[n] && ImGui::BeginTabItem(names[n], &opened[n], ImGuiTabItemFlags_None)) - { - ImGui::Text("This is the %s tab!", names[n]); - if (n & 1) - ImGui::Text("I am an odd tab."); - ImGui::EndTabItem(); - } - ImGui::EndTabBar(); - } - ImGui::Separator(); - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Tabs/TabItemButton & Leading-Trailing flags"); - if (ImGui::TreeNode("TabItemButton & Leading/Trailing flags")) - { - static ImVector active_tabs; - static int next_tab_id = 0; - if (next_tab_id == 0) // Initialize with some default tabs - for (int i = 0; i < 3; i++) - active_tabs.push_back(next_tab_id++); - - // TabItemButton() and Leading/Trailing flags are distinct features which we will demo together. - // (It is possible to submit regular tabs with Leading/Trailing flags, or TabItemButton tabs without Leading/Trailing flags... - // but they tend to make more sense together) - static bool show_leading_button = true; - static bool show_trailing_button = true; - ImGui::Checkbox("Show Leading TabItemButton()", &show_leading_button); - ImGui::Checkbox("Show Trailing TabItemButton()", &show_trailing_button); - - // Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs - static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown; - ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton); - if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown)) - tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown); - if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll)) - tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll); - - if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) - { - // Demo a Leading TabItemButton(): click the "?" button to open a menu - if (show_leading_button) - if (ImGui::TabItemButton("?", ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_NoTooltip)) - ImGui::OpenPopup("MyHelpMenu"); - if (ImGui::BeginPopup("MyHelpMenu")) - { - ImGui::Selectable("Hello!"); - ImGui::EndPopup(); - } - - // Demo Trailing Tabs: click the "+" button to add a new tab. - // (In your app you may want to use a font icon instead of the "+") - // We submit it before the regular tabs, but thanks to the ImGuiTabItemFlags_Trailing flag it will always appear at the end. - if (show_trailing_button) - if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip)) - active_tabs.push_back(next_tab_id++); // Add new tab - - // Submit our regular tabs - for (int n = 0; n < active_tabs.Size; ) - { - bool open = true; - char name[16]; - snprintf(name, IM_ARRAYSIZE(name), "%04d", active_tabs[n]); - if (ImGui::BeginTabItem(name, &open, ImGuiTabItemFlags_None)) - { - ImGui::Text("This is the %s tab!", name); - ImGui::EndTabItem(); - } - - if (!open) - active_tabs.erase(active_tabs.Data + n); - else - n++; - } - - ImGui::EndTabBar(); - } - ImGui::Separator(); - ImGui::TreePop(); - } - ImGui::TreePop(); - } - - // Plot/Graph widgets are not very good. - // Consider using a third-party library such as ImPlot: https://github.com/epezent/implot - // (see others https://github.com/ocornut/imgui/wiki/Useful-Extensions) - IMGUI_DEMO_MARKER("Widgets/Plotting"); - if (ImGui::TreeNode("Plotting")) - { - static bool animate = true; - ImGui::Checkbox("Animate", &animate); - - // Plot as lines and plot as histogram - static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; - ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); - ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0, 80.0f)); - //ImGui::SameLine(); HelpMarker("Consider using ImPlot instead!"); - - // Fill an array of contiguous float values to plot - // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float - // and the sizeof() of your structure in the "stride" parameter. - static float values[90] = {}; - static int values_offset = 0; - static double refresh_time = 0.0; - if (!animate || refresh_time == 0.0) - refresh_time = ImGui::GetTime(); - while (refresh_time < ImGui::GetTime()) // Create data at fixed 60 Hz rate for the demo - { - static float phase = 0.0f; - values[values_offset] = cosf(phase); - values_offset = (values_offset + 1) % IM_ARRAYSIZE(values); - phase += 0.10f * values_offset; - refresh_time += 1.0f / 60.0f; - } - - // Plots can display overlay texts - // (in this example, we will display an average value) - { - float average = 0.0f; - for (int n = 0; n < IM_ARRAYSIZE(values); n++) - average += values[n]; - average /= (float)IM_ARRAYSIZE(values); - char overlay[32]; - sprintf(overlay, "avg %f", average); - ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, overlay, -1.0f, 1.0f, ImVec2(0, 80.0f)); - } - - // Use functions to generate output - // FIXME: This is actually VERY awkward because current plot API only pass in indices. - // We probably want an API passing floats and user provide sample rate/count. - struct Funcs - { - static float Sin(void*, int i) { return sinf(i * 0.1f); } - static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; } - }; - static int func_type = 0, display_count = 70; - ImGui::SeparatorText("Functions"); - ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); - ImGui::Combo("func", &func_type, "Sin\0Saw\0"); - ImGui::SameLine(); - ImGui::SliderInt("Sample count", &display_count, 1, 400); - float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw; - ImGui::PlotLines("Lines##2", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); - ImGui::PlotHistogram("Histogram##2", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); - ImGui::Separator(); - - ImGui::Text("Need better plotting and graphing? Consider using ImPlot:"); - ImGui::TextLinkOpenURL("https://github.com/epezent/implot"); - ImGui::Separator(); - - ImGui::TreePop(); - } - - IMGUI_DEMO_MARKER("Widgets/Progress Bars"); - if (ImGui::TreeNode("Progress Bars")) - { - // Animate a simple progress bar - static float progress = 0.0f, progress_dir = 1.0f; - progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; - if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } - if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } - - // Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width, - // or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. - ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f)); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::Text("Progress Bar"); - - float progress_saturated = IM_CLAMP(progress, 0.0f, 1.0f); - char buf[32]; - sprintf(buf, "%d/%d", (int)(progress_saturated * 1753), 1753); - ImGui::ProgressBar(progress, ImVec2(0.f, 0.f), buf); - - // Pass an animated negative value, e.g. -1.0f * (float)ImGui::GetTime() is the recommended value. - // Adjust the factor if you want to adjust the animation speed. - ImGui::ProgressBar(-1.0f * (float)ImGui::GetTime(), ImVec2(0.0f, 0.0f), "Searching.."); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::Text("Indeterminate"); - - ImGui::TreePop(); - } +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsColorAndPickers() +//----------------------------------------------------------------------------- +static void DemoWindowWidgetsColorAndPickers() +{ IMGUI_DEMO_MARKER("Widgets/Color"); if (ImGui::TreeNode("Color/Picker Widgets")) { @@ -2271,8 +1227,8 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) ImGui::Text("Set defaults in code:"); ImGui::SameLine(); HelpMarker( "SetColorEditOptions() is designed to allow you to set boot-time default.\n" - "We don't have Push/Pop functions because you can force options on a per-widget basis if needed," - "and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid" + "We don't have Push/Pop functions because you can force options on a per-widget basis if needed, " + "and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid " "encouraging you to persistently save values that aren't forward-compatible."); if (ImGui::Button("Default: Uint8 + HSV + Hue Bar")) ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_PickerHueBar); @@ -2295,8 +1251,8 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) ImGui::Spacing(); ImGui::Text("HSV encoded colors"); ImGui::SameLine(); HelpMarker( - "By default, colors are given to ColorEdit and ColorPicker in RGB, but ImGuiColorEditFlags_InputHSV" - "allows you to store colors as HSV and pass them to ColorEdit and ColorPicker as HSV. This comes with the" + "By default, colors are given to ColorEdit and ColorPicker in RGB, but ImGuiColorEditFlags_InputHSV " + "allows you to store colors as HSV and pass them to ColorEdit and ColorPicker as HSV. This comes with the " "added benefit that you can manipulate hue values with the picker even when saturation or value are zero."); ImGui::Text("Color widget with InputHSV:"); ImGui::ColorEdit4("HSV shown as RGB##1", (float*)&color_hsv, ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputHSV | ImGuiColorEditFlags_Float); @@ -2305,62 +1261,111 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) ImGui::TreePop(); } +} - IMGUI_DEMO_MARKER("Widgets/Drag and Slider Flags"); - if (ImGui::TreeNode("Drag/Slider Flags")) +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsComboBoxes() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsComboBoxes() +{ + IMGUI_DEMO_MARKER("Widgets/Combo"); + if (ImGui::TreeNode("Combo")) { - // Demonstrate using advanced flags for DragXXX and SliderXXX functions. Note that the flags are the same! - static ImGuiSliderFlags flags = ImGuiSliderFlags_None; - ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", &flags, ImGuiSliderFlags_AlwaysClamp); - ImGui::CheckboxFlags("ImGuiSliderFlags_ClampOnInput", &flags, ImGuiSliderFlags_ClampOnInput); - ImGui::SameLine(); HelpMarker("Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds."); - ImGui::CheckboxFlags("ImGuiSliderFlags_ClampZeroRange", &flags, ImGuiSliderFlags_ClampZeroRange); - ImGui::SameLine(); HelpMarker("Clamp even if min==max==0.0f. Otherwise DragXXX functions don't clamp."); - ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", &flags, ImGuiSliderFlags_Logarithmic); - ImGui::SameLine(); HelpMarker("Enable logarithmic editing (more precision for small values)."); - ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", &flags, ImGuiSliderFlags_NoRoundToFormat); - ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits)."); - ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput); - ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget."); - ImGui::CheckboxFlags("ImGuiSliderFlags_NoSpeedTweaks", &flags, ImGuiSliderFlags_NoSpeedTweaks); - ImGui::SameLine(); HelpMarker("Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic."); - ImGui::CheckboxFlags("ImGuiSliderFlags_WrapAround", &flags, ImGuiSliderFlags_WrapAround); - ImGui::SameLine(); HelpMarker("Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions)"); + // Combo Boxes are also called "Dropdown" in other systems + // Expose flags as checkbox for the demo + static ImGuiComboFlags flags = 0; + ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", &flags, ImGuiComboFlags_PopupAlignLeft); + ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo"); + if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", &flags, ImGuiComboFlags_NoArrowButton)) + flags &= ~ImGuiComboFlags_NoPreview; // Clear incompatible flags + if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", &flags, ImGuiComboFlags_NoPreview)) + flags &= ~(ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_WidthFitPreview); // Clear incompatible flags + if (ImGui::CheckboxFlags("ImGuiComboFlags_WidthFitPreview", &flags, ImGuiComboFlags_WidthFitPreview)) + flags &= ~ImGuiComboFlags_NoPreview; - // Drags - static float drag_f = 0.5f; - static int drag_i = 50; - ImGui::Text("Underlying float value: %f", drag_f); - ImGui::DragFloat("DragFloat (0 -> 1)", &drag_f, 0.005f, 0.0f, 1.0f, "%.3f", flags); - ImGui::DragFloat("DragFloat (0 -> +inf)", &drag_f, 0.005f, 0.0f, FLT_MAX, "%.3f", flags); - ImGui::DragFloat("DragFloat (-inf -> 1)", &drag_f, 0.005f, -FLT_MAX, 1.0f, "%.3f", flags); - ImGui::DragFloat("DragFloat (-inf -> +inf)", &drag_f, 0.005f, -FLT_MAX, +FLT_MAX, "%.3f", flags); - //ImGui::DragFloat("DragFloat (0 -> 0)", &drag_f, 0.005f, 0.0f, 0.0f, "%.3f", flags); // To test ClampZeroRange - //ImGui::DragFloat("DragFloat (100 -> 100)", &drag_f, 0.005f, 100.0f, 100.0f, "%.3f", flags); - ImGui::DragInt("DragInt (0 -> 100)", &drag_i, 0.5f, 0, 100, "%d", flags); + // Override default popup height + if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightSmall", &flags, ImGuiComboFlags_HeightSmall)) + flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightSmall); + if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightRegular", &flags, ImGuiComboFlags_HeightRegular)) + flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightRegular); + if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightLargest", &flags, ImGuiComboFlags_HeightLargest)) + flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightLargest); - // Sliders - static float slider_f = 0.5f; - static int slider_i = 50; - const ImGuiSliderFlags flags_for_sliders = flags & ~ImGuiSliderFlags_WrapAround; - ImGui::Text("Underlying float value: %f", slider_f); - ImGui::SliderFloat("SliderFloat (0 -> 1)", &slider_f, 0.0f, 1.0f, "%.3f", flags_for_sliders); - ImGui::SliderInt("SliderInt (0 -> 100)", &slider_i, 0, 100, "%d", flags_for_sliders); + // Using the generic BeginCombo() API, you have full control over how to display the combo contents. + // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively + // stored in the object itself, etc.) + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; + static int item_selected_idx = 0; // Here we store our selection data as an index. + + // Pass in the preview value visible before opening the combo (it could technically be different contents or not pulled from items[]) + const char* combo_preview_value = items[item_selected_idx]; + if (ImGui::BeginCombo("combo 1", combo_preview_value, flags)) + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + const bool is_selected = (item_selected_idx == n); + if (ImGui::Selectable(items[n], is_selected)) + item_selected_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + + // Show case embedding a filter using a simple trick: displaying the filter inside combo contents. + // See https://github.com/ocornut/imgui/issues/718 for advanced/esoteric alternatives. + if (ImGui::BeginCombo("combo 2 (w/ filter)", combo_preview_value, flags)) + { + static ImGuiTextFilter filter; + if (ImGui::IsWindowAppearing()) + { + ImGui::SetKeyboardFocusHere(); + filter.Clear(); + } + ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_F); + filter.Draw("##Filter", -FLT_MIN); + + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + const bool is_selected = (item_selected_idx == n); + if (filter.PassFilter(items[n])) + if (ImGui::Selectable(items[n], is_selected)) + item_selected_idx = n; + } + ImGui::EndCombo(); + } + + ImGui::Spacing(); + ImGui::SeparatorText("One-liner variants"); + HelpMarker("The Combo() function is not greatly useful apart from cases were you want to embed all options in a single strings.\nFlags above don't apply to this section."); + + // Simplified one-liner Combo() API, using values packed in a single constant string + // This is a convenience for when the selection set is small and known at compile-time. + static int item_current_2 = 0; + ImGui::Combo("combo 3 (one-liner)", &item_current_2, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); + + // Simplified one-liner Combo() using an array of const char* + // This is not very useful (may obsolete): prefer using BeginCombo()/EndCombo() for full control. + static int item_current_3 = -1; // If the selection isn't within 0..count, Combo won't display a preview + ImGui::Combo("combo 4 (array)", &item_current_3, items, IM_ARRAYSIZE(items)); + + // Simplified one-liner Combo() using an accessor function + static int item_current_4 = 0; + ImGui::Combo("combo 5 (function)", &item_current_4, [](void* data, int n) { return ((const char**)data)[n]; }, items, IM_ARRAYSIZE(items)); ImGui::TreePop(); } +} - IMGUI_DEMO_MARKER("Widgets/Range Widgets"); - if (ImGui::TreeNode("Range Widgets")) - { - static float begin = 10, end = 90; - static int begin_i = 100, end_i = 1000; - ImGui::DragFloatRange2("range float", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%", ImGuiSliderFlags_AlwaysClamp); - ImGui::DragIntRange2("range int", &begin_i, &end_i, 5, 0, 1000, "Min: %d units", "Max: %d units"); - ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %d units", "Max: %d units"); - ImGui::TreePop(); - } +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsDataTypes() +//----------------------------------------------------------------------------- +static void DemoWindowWidgetsDataTypes() +{ IMGUI_DEMO_MARKER("Widgets/Data Types"); if (ImGui::TreeNode("Data Types")) { @@ -2488,105 +1493,29 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) ImGui::TreePop(); } +} - IMGUI_DEMO_MARKER("Widgets/Multi-component Widgets"); - if (ImGui::TreeNode("Multi-component Widgets")) +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsDisableBlocks() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsDisableBlocks(ImGuiDemoWindowData* demo_data) +{ + IMGUI_DEMO_MARKER("Widgets/Disable Blocks"); + if (ImGui::TreeNode("Disable Blocks")) { - static float vec4f[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; - static int vec4i[4] = { 1, 5, 100, 255 }; - - ImGui::SeparatorText("2-wide"); - ImGui::InputFloat2("input float2", vec4f); - ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f); - ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f); - ImGui::InputInt2("input int2", vec4i); - ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); - ImGui::SliderInt2("slider int2", vec4i, 0, 255); - - ImGui::SeparatorText("3-wide"); - ImGui::InputFloat3("input float3", vec4f); - ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f); - ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f); - ImGui::InputInt3("input int3", vec4i); - ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); - ImGui::SliderInt3("slider int3", vec4i, 0, 255); - - ImGui::SeparatorText("4-wide"); - ImGui::InputFloat4("input float4", vec4f); - ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f); - ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f); - ImGui::InputInt4("input int4", vec4i); - ImGui::DragInt4("drag int4", vec4i, 1, 0, 255); - ImGui::SliderInt4("slider int4", vec4i, 0, 255); - + ImGui::Checkbox("Disable entire section above", &demo_data->DisableSections); + ImGui::SameLine(); HelpMarker("Demonstrate using BeginDisabled()/EndDisabled() across other sections."); ImGui::TreePop(); } +} - IMGUI_DEMO_MARKER("Widgets/Vertical Sliders"); - if (ImGui::TreeNode("Vertical Sliders")) - { - const float spacing = 4; - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing)); - - static int int_value = 0; - ImGui::VSliderInt("##int", ImVec2(18, 160), &int_value, 0, 5); - ImGui::SameLine(); - - static float values[7] = { 0.0f, 0.60f, 0.35f, 0.9f, 0.70f, 0.20f, 0.0f }; - ImGui::PushID("set1"); - for (int i = 0; i < 7; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::PushStyleColor(ImGuiCol_FrameBg, (ImVec4)ImColor::HSV(i / 7.0f, 0.5f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, (ImVec4)ImColor::HSV(i / 7.0f, 0.6f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_FrameBgActive, (ImVec4)ImColor::HSV(i / 7.0f, 0.7f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_SliderGrab, (ImVec4)ImColor::HSV(i / 7.0f, 0.9f, 0.9f)); - ImGui::VSliderFloat("##v", ImVec2(18, 160), &values[i], 0.0f, 1.0f, ""); - if (ImGui::IsItemActive() || ImGui::IsItemHovered()) - ImGui::SetTooltip("%.3f", values[i]); - ImGui::PopStyleColor(4); - ImGui::PopID(); - } - ImGui::PopID(); - - ImGui::SameLine(); - ImGui::PushID("set2"); - static float values2[4] = { 0.20f, 0.80f, 0.40f, 0.25f }; - const int rows = 3; - const ImVec2 small_slider_size(18, (float)(int)((160.0f - (rows - 1) * spacing) / rows)); - for (int nx = 0; nx < 4; nx++) - { - if (nx > 0) ImGui::SameLine(); - ImGui::BeginGroup(); - for (int ny = 0; ny < rows; ny++) - { - ImGui::PushID(nx * rows + ny); - ImGui::VSliderFloat("##v", small_slider_size, &values2[nx], 0.0f, 1.0f, ""); - if (ImGui::IsItemActive() || ImGui::IsItemHovered()) - ImGui::SetTooltip("%.3f", values2[nx]); - ImGui::PopID(); - } - ImGui::EndGroup(); - } - ImGui::PopID(); - - ImGui::SameLine(); - ImGui::PushID("set3"); - for (int i = 0; i < 4; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40); - ImGui::VSliderFloat("##v", ImVec2(40, 160), &values[i], 0.0f, 1.0f, "%.2f\nsec"); - ImGui::PopStyleVar(); - ImGui::PopID(); - } - ImGui::PopID(); - ImGui::PopStyleVar(); - ImGui::TreePop(); - } +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsDragAndDrop() +//----------------------------------------------------------------------------- +static void DemoWindowWidgetsDragAndDrop() +{ IMGUI_DEMO_MARKER("Widgets/Drag and drop"); if (ImGui::TreeNode("Drag and Drop")) { @@ -2737,7 +1666,378 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) ImGui::TreePop(); } +} +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsDragsAndSliders() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsDragsAndSliders() +{ + IMGUI_DEMO_MARKER("Widgets/Drag and Slider Flags"); + if (ImGui::TreeNode("Drag/Slider Flags")) + { + // Demonstrate using advanced flags for DragXXX and SliderXXX functions. Note that the flags are the same! + static ImGuiSliderFlags flags = ImGuiSliderFlags_None; + ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", &flags, ImGuiSliderFlags_AlwaysClamp); + ImGui::CheckboxFlags("ImGuiSliderFlags_ClampOnInput", &flags, ImGuiSliderFlags_ClampOnInput); + ImGui::SameLine(); HelpMarker("Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds."); + ImGui::CheckboxFlags("ImGuiSliderFlags_ClampZeroRange", &flags, ImGuiSliderFlags_ClampZeroRange); + ImGui::SameLine(); HelpMarker("Clamp even if min==max==0.0f. Otherwise DragXXX functions don't clamp."); + ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", &flags, ImGuiSliderFlags_Logarithmic); + ImGui::SameLine(); HelpMarker("Enable logarithmic editing (more precision for small values)."); + ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", &flags, ImGuiSliderFlags_NoRoundToFormat); + ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits)."); + ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput); + ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget."); + ImGui::CheckboxFlags("ImGuiSliderFlags_NoSpeedTweaks", &flags, ImGuiSliderFlags_NoSpeedTweaks); + ImGui::SameLine(); HelpMarker("Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic."); + ImGui::CheckboxFlags("ImGuiSliderFlags_WrapAround", &flags, ImGuiSliderFlags_WrapAround); + ImGui::SameLine(); HelpMarker("Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions)"); + + // Drags + static float drag_f = 0.5f; + static int drag_i = 50; + ImGui::Text("Underlying float value: %f", drag_f); + ImGui::DragFloat("DragFloat (0 -> 1)", &drag_f, 0.005f, 0.0f, 1.0f, "%.3f", flags); + ImGui::DragFloat("DragFloat (0 -> +inf)", &drag_f, 0.005f, 0.0f, FLT_MAX, "%.3f", flags); + ImGui::DragFloat("DragFloat (-inf -> 1)", &drag_f, 0.005f, -FLT_MAX, 1.0f, "%.3f", flags); + ImGui::DragFloat("DragFloat (-inf -> +inf)", &drag_f, 0.005f, -FLT_MAX, +FLT_MAX, "%.3f", flags); + //ImGui::DragFloat("DragFloat (0 -> 0)", &drag_f, 0.005f, 0.0f, 0.0f, "%.3f", flags); // To test ClampZeroRange + //ImGui::DragFloat("DragFloat (100 -> 100)", &drag_f, 0.005f, 100.0f, 100.0f, "%.3f", flags); + ImGui::DragInt("DragInt (0 -> 100)", &drag_i, 0.5f, 0, 100, "%d", flags); + + // Sliders + static float slider_f = 0.5f; + static int slider_i = 50; + const ImGuiSliderFlags flags_for_sliders = flags & ~ImGuiSliderFlags_WrapAround; + ImGui::Text("Underlying float value: %f", slider_f); + ImGui::SliderFloat("SliderFloat (0 -> 1)", &slider_f, 0.0f, 1.0f, "%.3f", flags_for_sliders); + ImGui::SliderInt("SliderInt (0 -> 100)", &slider_i, 0, 100, "%d", flags_for_sliders); + + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsImages() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsImages() +{ + IMGUI_DEMO_MARKER("Widgets/Images"); + if (ImGui::TreeNode("Images")) + { + ImGuiIO& io = ImGui::GetIO(); + ImGui::TextWrapped( + "Below we are displaying the font texture (which is the only texture we have access to in this demo). " + "Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. " + "Hover the texture for a zoomed view!"); + + // Below we are displaying the font texture because it is the only texture we have access to inside the demo! + // Remember that ImTextureID is just storage for whatever you want it to be. It is essentially a value that + // will be passed to the rendering backend via the ImDrawCmd structure. + // If you use one of the default imgui_impl_XXXX.cpp rendering backend, they all have comments at the top + // of their respective source file to specify what they expect to be stored in ImTextureID, for example: + // - The imgui_impl_dx11.cpp renderer expect a 'ID3D11ShaderResourceView*' pointer + // - The imgui_impl_opengl3.cpp renderer expect a GLuint OpenGL texture identifier, etc. + // More: + // - If you decided that ImTextureID = MyEngineTexture*, then you can pass your MyEngineTexture* pointers + // to ImGui::Image(), and gather width/height through your own functions, etc. + // - You can use ShowMetricsWindow() to inspect the draw data that are being passed to your renderer, + // it will help you debug issues if you are confused about it. + // - Consider using the lower-level ImDrawList::AddImage() API, via ImGui::GetWindowDrawList()->AddImage(). + // - Read https://github.com/ocornut/imgui/blob/master/docs/FAQ.md + // - Read https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples + ImTextureID my_tex_id = io.Fonts->TexID; + float my_tex_w = (float)io.Fonts->TexWidth; + float my_tex_h = (float)io.Fonts->TexHeight; + { + ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left + ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right + ImGui::PushStyleVar(ImGuiStyleVar_ImageBorderSize, IM_MAX(1.0f, ImGui::GetStyle().ImageBorderSize)); + ImGui::ImageWithBg(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + if (ImGui::BeginItemTooltip()) + { + float region_sz = 32.0f; + float region_x = io.MousePos.x - pos.x - region_sz * 0.5f; + float region_y = io.MousePos.y - pos.y - region_sz * 0.5f; + float zoom = 4.0f; + if (region_x < 0.0f) { region_x = 0.0f; } + else if (region_x > my_tex_w - region_sz) { region_x = my_tex_w - region_sz; } + if (region_y < 0.0f) { region_y = 0.0f; } + else if (region_y > my_tex_h - region_sz) { region_y = my_tex_h - region_sz; } + ImGui::Text("Min: (%.2f, %.2f)", region_x, region_y); + ImGui::Text("Max: (%.2f, %.2f)", region_x + region_sz, region_y + region_sz); + ImVec2 uv0 = ImVec2((region_x) / my_tex_w, (region_y) / my_tex_h); + ImVec2 uv1 = ImVec2((region_x + region_sz) / my_tex_w, (region_y + region_sz) / my_tex_h); + ImGui::ImageWithBg(my_tex_id, ImVec2(region_sz * zoom, region_sz * zoom), uv0, uv1, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + ImGui::EndTooltip(); + } + ImGui::PopStyleVar(); + } + + IMGUI_DEMO_MARKER("Widgets/Images/Textured buttons"); + ImGui::TextWrapped("And now some textured buttons.."); + static int pressed_count = 0; + for (int i = 0; i < 8; i++) + { + // UV coordinates are often (0.0f, 0.0f) and (1.0f, 1.0f) to display an entire textures. + // Here are trying to display only a 32x32 pixels area of the texture, hence the UV computation. + // Read about UV coordinates here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples + ImGui::PushID(i); + if (i > 0) + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(i - 1.0f, i - 1.0f)); + ImVec2 size = ImVec2(32.0f, 32.0f); // Size of the image we want to make visible + ImVec2 uv0 = ImVec2(0.0f, 0.0f); // UV coordinates for lower-left + ImVec2 uv1 = ImVec2(32.0f / my_tex_w, 32.0f / my_tex_h); // UV coordinates for (32,32) in our texture + ImVec4 bg_col = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); // Black background + ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint + if (ImGui::ImageButton("", my_tex_id, size, uv0, uv1, bg_col, tint_col)) + pressed_count += 1; + if (i > 0) + ImGui::PopStyleVar(); + ImGui::PopID(); + ImGui::SameLine(); + } + ImGui::NewLine(); + ImGui::Text("Pressed %d times.", pressed_count); + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsListBoxes() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsListBoxes() +{ + IMGUI_DEMO_MARKER("Widgets/List Boxes"); + if (ImGui::TreeNode("List Boxes")) + { + // BeginListBox() is essentially a thin wrapper to using BeginChild()/EndChild() + // using the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label. + // You may be tempted to simply use BeginChild() directly. However note that BeginChild() requires EndChild() + // to always be called (inconsistent with BeginListBox()/EndListBox()). + + // Using the generic BeginListBox() API, you have full control over how to display the combo contents. + // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively + // stored in the object itself, etc.) + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; + static int item_selected_idx = 0; // Here we store our selected data as an index. + + static bool item_highlight = false; + int item_highlighted_idx = -1; // Here we store our highlighted data as an index. + ImGui::Checkbox("Highlight hovered item in second listbox", &item_highlight); + + if (ImGui::BeginListBox("listbox 1")) + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + const bool is_selected = (item_selected_idx == n); + if (ImGui::Selectable(items[n], is_selected)) + item_selected_idx = n; + + if (item_highlight && ImGui::IsItemHovered()) + item_highlighted_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndListBox(); + } + ImGui::SameLine(); HelpMarker("Here we are sharing selection state between both boxes."); + + // Custom size: use all width, 5 items tall + ImGui::Text("Full-width:"); + if (ImGui::BeginListBox("##listbox 2", ImVec2(-FLT_MIN, 5 * ImGui::GetTextLineHeightWithSpacing()))) + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + bool is_selected = (item_selected_idx == n); + ImGuiSelectableFlags flags = (item_highlighted_idx == n) ? ImGuiSelectableFlags_Highlight : 0; + if (ImGui::Selectable(items[n], is_selected, flags)) + item_selected_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndListBox(); + } + + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsMultiComponents() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsMultiComponents() +{ + IMGUI_DEMO_MARKER("Widgets/Multi-component Widgets"); + if (ImGui::TreeNode("Multi-component Widgets")) + { + static float vec4f[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; + static int vec4i[4] = { 1, 5, 100, 255 }; + + ImGui::SeparatorText("2-wide"); + ImGui::InputFloat2("input float2", vec4f); + ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f); + ImGui::InputInt2("input int2", vec4i); + ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); + ImGui::SliderInt2("slider int2", vec4i, 0, 255); + + ImGui::SeparatorText("3-wide"); + ImGui::InputFloat3("input float3", vec4f); + ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f); + ImGui::InputInt3("input int3", vec4i); + ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); + ImGui::SliderInt3("slider int3", vec4i, 0, 255); + + ImGui::SeparatorText("4-wide"); + ImGui::InputFloat4("input float4", vec4f); + ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f); + ImGui::InputInt4("input int4", vec4i); + ImGui::DragInt4("drag int4", vec4i, 1, 0, 255); + ImGui::SliderInt4("slider int4", vec4i, 0, 255); + + ImGui::SeparatorText("Ranges"); + static float begin = 10, end = 90; + static int begin_i = 100, end_i = 1000; + ImGui::DragFloatRange2("range float", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%", ImGuiSliderFlags_AlwaysClamp); + ImGui::DragIntRange2("range int", &begin_i, &end_i, 5, 0, 1000, "Min: %d units", "Max: %d units"); + ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %d units", "Max: %d units"); + + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsPlotting() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsPlotting() +{ + // Plot/Graph widgets are not very good. +// Consider using a third-party library such as ImPlot: https://github.com/epezent/implot +// (see others https://github.com/ocornut/imgui/wiki/Useful-Extensions) + IMGUI_DEMO_MARKER("Widgets/Plotting"); + if (ImGui::TreeNode("Plotting")) + { + ImGui::Text("Need better plotting and graphing? Consider using ImPlot:"); + ImGui::TextLinkOpenURL("https://github.com/epezent/implot"); + ImGui::Separator(); + + static bool animate = true; + ImGui::Checkbox("Animate", &animate); + + // Plot as lines and plot as histogram + static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; + ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); + ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0, 80.0f)); + //ImGui::SameLine(); HelpMarker("Consider using ImPlot instead!"); + + // Fill an array of contiguous float values to plot + // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float + // and the sizeof() of your structure in the "stride" parameter. + static float values[90] = {}; + static int values_offset = 0; + static double refresh_time = 0.0; + if (!animate || refresh_time == 0.0) + refresh_time = ImGui::GetTime(); + while (refresh_time < ImGui::GetTime()) // Create data at fixed 60 Hz rate for the demo + { + static float phase = 0.0f; + values[values_offset] = cosf(phase); + values_offset = (values_offset + 1) % IM_ARRAYSIZE(values); + phase += 0.10f * values_offset; + refresh_time += 1.0f / 60.0f; + } + + // Plots can display overlay texts + // (in this example, we will display an average value) + { + float average = 0.0f; + for (int n = 0; n < IM_ARRAYSIZE(values); n++) + average += values[n]; + average /= (float)IM_ARRAYSIZE(values); + char overlay[32]; + sprintf(overlay, "avg %f", average); + ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, overlay, -1.0f, 1.0f, ImVec2(0, 80.0f)); + } + + // Use functions to generate output + // FIXME: This is actually VERY awkward because current plot API only pass in indices. + // We probably want an API passing floats and user provide sample rate/count. + struct Funcs + { + static float Sin(void*, int i) { return sinf(i * 0.1f); } + static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; } + }; + static int func_type = 0, display_count = 70; + ImGui::SeparatorText("Functions"); + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); + ImGui::Combo("func", &func_type, "Sin\0Saw\0"); + ImGui::SameLine(); + ImGui::SliderInt("Sample count", &display_count, 1, 400); + float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw; + ImGui::PlotLines("Lines##2", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); + ImGui::PlotHistogram("Histogram##2", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); + + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsProgressBars() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsProgressBars() +{ + IMGUI_DEMO_MARKER("Widgets/Progress Bars"); + if (ImGui::TreeNode("Progress Bars")) + { + // Animate a simple progress bar + static float progress = 0.0f, progress_dir = 1.0f; + progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; + if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } + if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } + + // Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width, + // or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. + ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f)); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::Text("Progress Bar"); + + float progress_saturated = IM_CLAMP(progress, 0.0f, 1.0f); + char buf[32]; + sprintf(buf, "%d/%d", (int)(progress_saturated * 1753), 1753); + ImGui::ProgressBar(progress, ImVec2(0.f, 0.f), buf); + + // Pass an animated negative value, e.g. -1.0f * (float)ImGui::GetTime() is the recommended value. + // Adjust the factor if you want to adjust the animation speed. + ImGui::ProgressBar(-1.0f * (float)ImGui::GetTime(), ImVec2(0.0f, 0.0f), "Searching.."); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::Text("Indeterminate"); + + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsQueryingStatuses() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsQueryingStatuses() +{ IMGUI_DEMO_MARKER("Widgets/Querying Item Status (Edited,Active,Hovered etc.)"); if (ImGui::TreeNode("Querying Item Status (Edited/Active/Hovered etc.)")) { @@ -2752,7 +2052,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) ImGui::Combo("Item Type", &item_type, item_names, IM_ARRAYSIZE(item_names), IM_ARRAYSIZE(item_names)); ImGui::SameLine(); HelpMarker("Testing how various types of items are interacting with the IsItemXXX functions. Note that the bool return value of most ImGui function is generally equivalent to calling ImGui::IsItemHovered()."); - ImGui::Checkbox("Item Disabled", &item_disabled); + ImGui::Checkbox("Item Disabled", &item_disabled); // Submit selected items so we can query their status in the code following it. bool ret = false; @@ -2771,12 +2071,12 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) if (item_type == 7) { ret = ImGui::InputFloat("ITEM: InputFloat", col4f, 1.0f); } // Testing +/- buttons on scalar input if (item_type == 8) { ret = ImGui::InputFloat3("ITEM: InputFloat3", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged) if (item_type == 9) { ret = ImGui::ColorEdit4("ITEM: ColorEdit4", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged) - if (item_type == 10){ ret = ImGui::Selectable("ITEM: Selectable"); } // Testing selectable item - if (item_type == 11){ ret = ImGui::MenuItem("ITEM: MenuItem"); } // Testing menu item (they use ImGuiButtonFlags_PressedOnRelease button policy) - if (item_type == 12){ ret = ImGui::TreeNode("ITEM: TreeNode"); if (ret) ImGui::TreePop(); } // Testing tree node - if (item_type == 13){ ret = ImGui::TreeNodeEx("ITEM: TreeNode w/ ImGuiTreeNodeFlags_OpenOnDoubleClick", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_NoTreePushOnOpen); } // Testing tree node with ImGuiButtonFlags_PressedOnDoubleClick button policy. - if (item_type == 14){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::Combo("ITEM: Combo", ¤t, items, IM_ARRAYSIZE(items)); } - if (item_type == 15){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", ¤t, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); } + if (item_type == 10) { ret = ImGui::Selectable("ITEM: Selectable"); } // Testing selectable item + if (item_type == 11) { ret = ImGui::MenuItem("ITEM: MenuItem"); } // Testing menu item (they use ImGuiButtonFlags_PressedOnRelease button policy) + if (item_type == 12) { ret = ImGui::TreeNode("ITEM: TreeNode"); if (ret) ImGui::TreePop(); } // Testing tree node + if (item_type == 13) { ret = ImGui::TreeNodeEx("ITEM: TreeNode w/ ImGuiTreeNodeFlags_OpenOnDoubleClick", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_NoTreePushOnOpen); } // Testing tree node with ImGuiButtonFlags_PressedOnDoubleClick button policy. + if (item_type == 14) { const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::Combo("ITEM: Combo", ¤t, items, IM_ARRAYSIZE(items)); } + if (item_type == 15) { const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", ¤t, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); } bool hovered_delay_none = ImGui::IsItemHovered(); bool hovered_delay_stationary = ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary); @@ -2931,41 +2231,152 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data) ImGui::TreePop(); } +} - // Demonstrate BeginDisabled/EndDisabled using a checkbox located at the bottom of the section (which is a bit odd: - // logically we'd have this checkbox at the top of the section, but we don't want this feature to steal that space) - if (disable_all) - ImGui::EndDisabled(); +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsSelectables() +//----------------------------------------------------------------------------- - IMGUI_DEMO_MARKER("Widgets/Disable Block"); - if (ImGui::TreeNode("Disable block")) +static void DemoWindowWidgetsSelectables() +{ + IMGUI_DEMO_MARKER("Widgets/Selectables"); + //ImGui::SetNextItemOpen(true, ImGuiCond_Once); + if (ImGui::TreeNode("Selectables")) { - ImGui::Checkbox("Disable entire section above", &disable_all); - ImGui::SameLine(); HelpMarker("Demonstrate using BeginDisabled()/EndDisabled() across this section."); - ImGui::TreePop(); - } + // Selectable() has 2 overloads: + // - The one taking "bool selected" as a read-only selection information. + // When Selectable() has been clicked it returns true and you can alter selection state accordingly. + // - The one taking "bool* p_selected" as a read-write selection information (convenient in some cases) + // The earlier is more flexible, as in real application your selection may be stored in many different ways + // and not necessarily inside a bool value (e.g. in flags within objects, as an external list, etc). + IMGUI_DEMO_MARKER("Widgets/Selectables/Basic"); + if (ImGui::TreeNode("Basic")) + { + static bool selection[5] = { false, true, false, false }; + ImGui::Selectable("1. I am selectable", &selection[0]); + ImGui::Selectable("2. I am selectable", &selection[1]); + ImGui::Selectable("3. I am selectable", &selection[2]); + if (ImGui::Selectable("4. I am double clickable", selection[3], ImGuiSelectableFlags_AllowDoubleClick)) + if (ImGui::IsMouseDoubleClicked(0)) + selection[3] = !selection[3]; + ImGui::TreePop(); + } - IMGUI_DEMO_MARKER("Widgets/Text Filter"); - if (ImGui::TreeNode("Text Filter")) - { - // Helper class to easy setup a text filter. - // You may want to implement a more feature-full filtering scheme in your own application. - HelpMarker("Not a widget per-se, but ImGuiTextFilter is a helper to perform simple filtering on text strings."); - static ImGuiTextFilter filter; - ImGui::Text("Filter usage:\n" - " \"\" display all lines\n" - " \"xxx\" display lines containing \"xxx\"\n" - " \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n" - " \"-xxx\" hide lines containing \"xxx\""); - filter.Draw(); - const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" }; - for (int i = 0; i < IM_ARRAYSIZE(lines); i++) - if (filter.PassFilter(lines[i])) - ImGui::BulletText("%s", lines[i]); + IMGUI_DEMO_MARKER("Widgets/Selectables/Rendering more items on the same line"); + if (ImGui::TreeNode("Rendering more items on the same line")) + { + // (1) Using SetNextItemAllowOverlap() + // (2) Using the Selectable() override that takes "bool* p_selected" parameter, the bool value is toggled automatically. + static bool selected[3] = { false, false, false }; + ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(); ImGui::SmallButton("Link 1"); + ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(); ImGui::SmallButton("Link 2"); + ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(); ImGui::SmallButton("Link 3"); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Selectables/In Tables"); + if (ImGui::TreeNode("In Tables")) + { + static bool selected[10] = {}; + + if (ImGui::BeginTable("split1", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) + { + for (int i = 0; i < 10; i++) + { + char label[32]; + sprintf(label, "Item %d", i); + ImGui::TableNextColumn(); + ImGui::Selectable(label, &selected[i]); // FIXME-TABLE: Selection overlap + } + ImGui::EndTable(); + } + ImGui::Spacing(); + if (ImGui::BeginTable("split2", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) + { + for (int i = 0; i < 10; i++) + { + char label[32]; + sprintf(label, "Item %d", i); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Selectable(label, &selected[i], ImGuiSelectableFlags_SpanAllColumns); + ImGui::TableNextColumn(); + ImGui::Text("Some other contents"); + ImGui::TableNextColumn(); + ImGui::Text("123456"); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Selectables/Grid"); + if (ImGui::TreeNode("Grid")) + { + static char selected[4][4] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; + + // Add in a bit of silly fun... + const float time = (float)ImGui::GetTime(); + const bool winning_state = memchr(selected, 0, sizeof(selected)) == NULL; // If all cells are selected... + if (winning_state) + ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f + 0.5f * cosf(time * 2.0f), 0.5f + 0.5f * sinf(time * 3.0f))); + + for (int y = 0; y < 4; y++) + for (int x = 0; x < 4; x++) + { + if (x > 0) + ImGui::SameLine(); + ImGui::PushID(y * 4 + x); + if (ImGui::Selectable("Sailor", selected[y][x] != 0, 0, ImVec2(50, 50))) + { + // Toggle clicked cell + toggle neighbors + selected[y][x] ^= 1; + if (x > 0) { selected[y][x - 1] ^= 1; } + if (x < 3) { selected[y][x + 1] ^= 1; } + if (y > 0) { selected[y - 1][x] ^= 1; } + if (y < 3) { selected[y + 1][x] ^= 1; } + } + ImGui::PopID(); + } + + if (winning_state) + ImGui::PopStyleVar(); + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/Alignment"); + if (ImGui::TreeNode("Alignment")) + { + HelpMarker( + "By default, Selectables uses style.SelectableTextAlign but it can be overridden on a per-item " + "basis using PushStyleVar(). You'll probably want to always keep your default situation to " + "left-align otherwise it becomes difficult to layout multiple items on a same line"); + static bool selected[3 * 3] = { true, false, true, false, true, false, true, false, true }; + for (int y = 0; y < 3; y++) + { + for (int x = 0; x < 3; x++) + { + ImVec2 alignment = ImVec2((float)x / 2.0f, (float)y / 2.0f); + char name[32]; + sprintf(name, "(%.1f,%.1f)", alignment.x, alignment.y); + if (x > 0) ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, alignment); + ImGui::Selectable(name, &selected[3 * y + x], ImGuiSelectableFlags_None, ImVec2(80, 80)); + ImGui::PopStyleVar(); + } + } + ImGui::TreePop(); + } ImGui::TreePop(); } } +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsSelectionAndMultiSelect() +//----------------------------------------------------------------------------- +// Multi-selection demos +// Also read: https://github.com/ocornut/imgui/wiki/Multi-Select +//----------------------------------------------------------------------------- + static const char* ExampleNames[] = { "Artichoke", "Arugula", "Asparagus", "Avocado", "Bamboo Shoots", "Bean Sprouts", "Beans", "Beet", "Belgian Endive", "Bell Pepper", @@ -3191,14 +2602,7 @@ struct ExampleDualListBox } }; -//----------------------------------------------------------------------------- -// [SECTION] ShowDemoWindowMultiSelect() -//----------------------------------------------------------------------------- -// Multi-selection demos -// Also read: https://github.com/ocornut/imgui/wiki/Multi-Select -//----------------------------------------------------------------------------- - -static void ShowDemoWindowMultiSelect(ImGuiDemoWindowData* demo_data) +static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_data) { IMGUI_DEMO_MARKER("Widgets/Selection State & Multi-Select"); if (ImGui::TreeNode("Selection State & Multi-Select")) @@ -3558,7 +2962,7 @@ static void ShowDemoWindowMultiSelect(ImGuiDemoWindowData* demo_data) if (ImGui::TreeNode("Multi-Select (trees)")) { HelpMarker( - "This is rather advanced and experimental. If you are getting started with multi-select," + "This is rather advanced and experimental. If you are getting started with multi-select, " "please don't start by looking at how to use it for a tree!\n\n" "Future versions will try to simplify and formalize some of this."); @@ -3934,10 +3338,839 @@ static void ShowDemoWindowMultiSelect(ImGuiDemoWindowData* demo_data) } //----------------------------------------------------------------------------- -// [SECTION] ShowDemoWindowLayout() +// [SECTION] DemoWindowWidgetsTabs() //----------------------------------------------------------------------------- -static void ShowDemoWindowLayout() +static void DemoWindowWidgetsTabs() +{ + IMGUI_DEMO_MARKER("Widgets/Tabs"); + if (ImGui::TreeNode("Tabs")) + { + IMGUI_DEMO_MARKER("Widgets/Tabs/Basic"); + if (ImGui::TreeNode("Basic")) + { + ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None; + if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) + { + if (ImGui::BeginTabItem("Avocado")) + { + ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Broccoli")) + { + ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Cucumber")) + { + ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Tabs/Advanced & Close Button"); + if (ImGui::TreeNode("Advanced & Close Button")) + { + // Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0). + static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable; + ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", &tab_bar_flags, ImGuiTabBarFlags_Reorderable); + ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", &tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs); + ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton); + ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton); + ImGui::CheckboxFlags("ImGuiTabBarFlags_DrawSelectedOverline", &tab_bar_flags, ImGuiTabBarFlags_DrawSelectedOverline); + if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0) + tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_; + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown); + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll); + + // Tab Bar + ImGui::AlignTextToFramePadding(); + ImGui::Text("Opened:"); + const char* names[4] = { "Artichoke", "Beetroot", "Celery", "Daikon" }; + static bool opened[4] = { true, true, true, true }; // Persistent user state + for (int n = 0; n < IM_ARRAYSIZE(opened); n++) + { + ImGui::SameLine(); + ImGui::Checkbox(names[n], &opened[n]); + } + + // Passing a bool* to BeginTabItem() is similar to passing one to Begin(): + // the underlying bool will be set to false when the tab is closed. + if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) + { + for (int n = 0; n < IM_ARRAYSIZE(opened); n++) + if (opened[n] && ImGui::BeginTabItem(names[n], &opened[n], ImGuiTabItemFlags_None)) + { + ImGui::Text("This is the %s tab!", names[n]); + if (n & 1) + ImGui::Text("I am an odd tab."); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Tabs/TabItemButton & Leading-Trailing flags"); + if (ImGui::TreeNode("TabItemButton & Leading/Trailing flags")) + { + static ImVector active_tabs; + static int next_tab_id = 0; + if (next_tab_id == 0) // Initialize with some default tabs + for (int i = 0; i < 3; i++) + active_tabs.push_back(next_tab_id++); + + // TabItemButton() and Leading/Trailing flags are distinct features which we will demo together. + // (It is possible to submit regular tabs with Leading/Trailing flags, or TabItemButton tabs without Leading/Trailing flags... + // but they tend to make more sense together) + static bool show_leading_button = true; + static bool show_trailing_button = true; + ImGui::Checkbox("Show Leading TabItemButton()", &show_leading_button); + ImGui::Checkbox("Show Trailing TabItemButton()", &show_trailing_button); + + // Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs + static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown; + ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton); + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown); + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll); + + if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) + { + // Demo a Leading TabItemButton(): click the "?" button to open a menu + if (show_leading_button) + if (ImGui::TabItemButton("?", ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_NoTooltip)) + ImGui::OpenPopup("MyHelpMenu"); + if (ImGui::BeginPopup("MyHelpMenu")) + { + ImGui::Selectable("Hello!"); + ImGui::EndPopup(); + } + + // Demo Trailing Tabs: click the "+" button to add a new tab. + // (In your app you may want to use a font icon instead of the "+") + // We submit it before the regular tabs, but thanks to the ImGuiTabItemFlags_Trailing flag it will always appear at the end. + if (show_trailing_button) + if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip)) + active_tabs.push_back(next_tab_id++); // Add new tab + + // Submit our regular tabs + for (int n = 0; n < active_tabs.Size; ) + { + bool open = true; + char name[16]; + snprintf(name, IM_ARRAYSIZE(name), "%04d", active_tabs[n]); + if (ImGui::BeginTabItem(name, &open, ImGuiTabItemFlags_None)) + { + ImGui::Text("This is the %s tab!", name); + ImGui::EndTabItem(); + } + + if (!open) + active_tabs.erase(active_tabs.Data + n); + else + n++; + } + + ImGui::EndTabBar(); + } + ImGui::Separator(); + ImGui::TreePop(); + } + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsText() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsText() +{ + IMGUI_DEMO_MARKER("Widgets/Text"); + if (ImGui::TreeNode("Text")) + { + IMGUI_DEMO_MARKER("Widgets/Text/Colored Text"); + if (ImGui::TreeNode("Colorful Text")) + { + // Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility. + ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "Pink"); + ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Yellow"); + ImGui::TextDisabled("Disabled"); + ImGui::SameLine(); HelpMarker("The TextDisabled color is stored in ImGuiStyle."); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text/Word Wrapping"); + if (ImGui::TreeNode("Word Wrapping")) + { + // Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility. + ImGui::TextWrapped( + "This text should automatically wrap on the edge of the window. The current implementation " + "for text wrapping follows simple rules suitable for English and possibly other languages."); + ImGui::Spacing(); + + static float wrap_width = 200.0f; + ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f"); + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + for (int n = 0; n < 2; n++) + { + ImGui::Text("Test paragraph %d:", n); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImVec2 marker_min = ImVec2(pos.x + wrap_width, pos.y); + ImVec2 marker_max = ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); + if (n == 0) + ImGui::Text("The lazy dog is a good dog. This paragraph should fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width); + else + ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh"); + + // Draw actual text bounding box, following by marker of our expected limit (should not overlap!) + draw_list->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255)); + draw_list->AddRectFilled(marker_min, marker_max, IM_COL32(255, 0, 255, 255)); + ImGui::PopTextWrapPos(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text/UTF-8 Text"); + if (ImGui::TreeNode("UTF-8 Text")) + { + // UTF-8 test with Japanese characters + // (Needs a suitable font? Try "Google Noto" or "Arial Unicode". See docs/FONTS.md for details.) + // - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8 + // - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. in Visual Studio, you + // can save your source files as 'UTF-8 without signature'). + // - FOR THIS DEMO FILE ONLY, BECAUSE WE WANT TO SUPPORT OLD COMPILERS, WE ARE *NOT* INCLUDING RAW UTF-8 + // CHARACTERS IN THIS SOURCE FILE. Instead we are encoding a few strings with hexadecimal constants. + // Don't do this in your application! Please use u8"text in any language" in your application! + // Note that characters values are preserved even by InputText() if the font cannot be displayed, + // so you can safely copy & paste garbled characters into another application. + ImGui::TextWrapped( + "CJK text will only appear if the font was loaded with the appropriate CJK character ranges. " + "Call io.Fonts->AddFontFromFileTTF() manually to load extra character ranges. " + "Read docs/FONTS.md for details."); + ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); + ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)"); + static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; + //static char buf[32] = u8"NIHONGO"; // <- this is how you would write it with C++11, using real kanjis + ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsTextFilter() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsTextFilter() +{ + IMGUI_DEMO_MARKER("Widgets/Text Filter"); + if (ImGui::TreeNode("Text Filter")) + { + // Helper class to easy setup a text filter. + // You may want to implement a more feature-full filtering scheme in your own application. + HelpMarker("Not a widget per-se, but ImGuiTextFilter is a helper to perform simple filtering on text strings."); + static ImGuiTextFilter filter; + ImGui::Text("Filter usage:\n" + " \"\" display all lines\n" + " \"xxx\" display lines containing \"xxx\"\n" + " \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n" + " \"-xxx\" hide lines containing \"xxx\""); + filter.Draw(); + const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" }; + for (int i = 0; i < IM_ARRAYSIZE(lines); i++) + if (filter.PassFilter(lines[i])) + ImGui::BulletText("%s", lines[i]); + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsTextInput() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsTextInput() +{ + // To wire InputText() with std::string or any other custom string type, + // see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file. + IMGUI_DEMO_MARKER("Widgets/Text Input"); + if (ImGui::TreeNode("Text Input")) + { + IMGUI_DEMO_MARKER("Widgets/Text Input/Multi-line Text Input"); + if (ImGui::TreeNode("Multi-line Text Input")) + { + // Note: we are using a fixed-sized buffer for simplicity here. See ImGuiInputTextFlags_CallbackResize + // and the code in misc/cpp/imgui_stdlib.h for how to setup InputText() for dynamically resizing strings. + static char text[1024 * 16] = + "/*\n" + " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n" + " the hexadecimal encoding of one offending instruction,\n" + " more formally, the invalid operand with locked CMPXCHG8B\n" + " instruction bug, is a design flaw in the majority of\n" + " Intel Pentium, Pentium MMX, and Pentium OverDrive\n" + " processors (all in the P5 microarchitecture).\n" + "*/\n\n" + "label:\n" + "\tlock cmpxchg8b eax\n"; + + static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput; + HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp because we don't want to include in here)"); + ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly); + ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput); + ImGui::SameLine(); HelpMarker("When _AllowTabInput is set, passing through the widget with Tabbing doesn't automatically activate it, in order to also cycling through subsequent widgets."); + ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine); + ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Filtered Text Input"); + if (ImGui::TreeNode("Filtered Text Input")) + { + struct TextFilters + { + // Modify character input by altering 'data->Eventchar' (ImGuiInputTextFlags_CallbackCharFilter callback) + static int FilterCasingSwap(ImGuiInputTextCallbackData* data) + { + if (data->EventChar >= 'a' && data->EventChar <= 'z') { data->EventChar -= 'a' - 'A'; } // Lowercase becomes uppercase + else if (data->EventChar >= 'A' && data->EventChar <= 'Z') { data->EventChar += 'a' - 'A'; } // Uppercase becomes lowercase + return 0; + } + + // Return 0 (pass) if the character is 'i' or 'm' or 'g' or 'u' or 'i', otherwise return 1 (filter out) + static int FilterImGuiLetters(ImGuiInputTextCallbackData* data) + { + if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) + return 0; + return 1; + } + }; + + static char buf1[32] = ""; ImGui::InputText("default", buf1, 32); + static char buf2[32] = ""; ImGui::InputText("decimal", buf2, 32, ImGuiInputTextFlags_CharsDecimal); + static char buf3[32] = ""; ImGui::InputText("hexadecimal", buf3, 32, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase); + static char buf4[32] = ""; ImGui::InputText("uppercase", buf4, 32, ImGuiInputTextFlags_CharsUppercase); + static char buf5[32] = ""; ImGui::InputText("no blank", buf5, 32, ImGuiInputTextFlags_CharsNoBlank); + static char buf6[32] = ""; ImGui::InputText("casing swap", buf6, 32, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterCasingSwap); // Use CharFilter callback to replace characters. + static char buf7[32] = ""; ImGui::InputText("\"imgui\"", buf7, 32, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); // Use CharFilter callback to disable some characters. + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Password input"); + if (ImGui::TreeNode("Password Input")) + { + static char password[64] = "password123"; + ImGui::InputText("password", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); + ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); + ImGui::InputTextWithHint("password (w/ hint)", "", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); + ImGui::InputText("password (clear)", password, IM_ARRAYSIZE(password)); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Completion, History, Edit Callbacks"); + if (ImGui::TreeNode("Completion, History, Edit Callbacks")) + { + struct Funcs + { + static int MyCallback(ImGuiInputTextCallbackData* data) + { + if (data->EventFlag == ImGuiInputTextFlags_CallbackCompletion) + { + data->InsertChars(data->CursorPos, ".."); + } + else if (data->EventFlag == ImGuiInputTextFlags_CallbackHistory) + { + if (data->EventKey == ImGuiKey_UpArrow) + { + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, "Pressed Up!"); + data->SelectAll(); + } + else if (data->EventKey == ImGuiKey_DownArrow) + { + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, "Pressed Down!"); + data->SelectAll(); + } + } + else if (data->EventFlag == ImGuiInputTextFlags_CallbackEdit) + { + // Toggle casing of first character + char c = data->Buf[0]; + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) data->Buf[0] ^= 32; + data->BufDirty = true; + + // Increment a counter + int* p_int = (int*)data->UserData; + *p_int = *p_int + 1; + } + return 0; + } + }; + static char buf1[64]; + ImGui::InputText("Completion", buf1, 64, ImGuiInputTextFlags_CallbackCompletion, Funcs::MyCallback); + ImGui::SameLine(); HelpMarker( + "Here we append \"..\" each time Tab is pressed. " + "See 'Examples>Console' for a more meaningful demonstration of using this callback."); + + static char buf2[64]; + ImGui::InputText("History", buf2, 64, ImGuiInputTextFlags_CallbackHistory, Funcs::MyCallback); + ImGui::SameLine(); HelpMarker( + "Here we replace and select text each time Up/Down are pressed. " + "See 'Examples>Console' for a more meaningful demonstration of using this callback."); + + static char buf3[64]; + static int edit_count = 0; + ImGui::InputText("Edit", buf3, 64, ImGuiInputTextFlags_CallbackEdit, Funcs::MyCallback, (void*)&edit_count); + ImGui::SameLine(); HelpMarker( + "Here we toggle the casing of the first character on every edit + count edits."); + ImGui::SameLine(); ImGui::Text("(%d)", edit_count); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Resize Callback"); + if (ImGui::TreeNode("Resize Callback")) + { + // To wire InputText() with std::string or any other custom string type, + // you can use the ImGuiInputTextFlags_CallbackResize flag + create a custom ImGui::InputText() wrapper + // using your preferred type. See misc/cpp/imgui_stdlib.h for an implementation of this using std::string. + HelpMarker( + "Using ImGuiInputTextFlags_CallbackResize to wire your custom string type to InputText().\n\n" + "See misc/cpp/imgui_stdlib.h for an implementation of this for std::string."); + struct Funcs + { + static int MyResizeCallback(ImGuiInputTextCallbackData* data) + { + if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) + { + ImVector* my_str = (ImVector*)data->UserData; + IM_ASSERT(my_str->begin() == data->Buf); + my_str->resize(data->BufSize); // NB: On resizing calls, generally data->BufSize == data->BufTextLen + 1 + data->Buf = my_str->begin(); + } + return 0; + } + + // Note: Because ImGui:: is a namespace you would typically add your own function into the namespace. + // For example, you code may declare a function 'ImGui::InputText(const char* label, MyString* my_str)' + static bool MyInputTextMultiline(const char* label, ImVector* my_str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0) + { + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + return ImGui::InputTextMultiline(label, my_str->begin(), (size_t)my_str->size(), size, flags | ImGuiInputTextFlags_CallbackResize, Funcs::MyResizeCallback, (void*)my_str); + } + }; + + // For this demo we are using ImVector as a string container. + // Note that because we need to store a terminating zero character, our size/capacity are 1 more + // than usually reported by a typical string class. + static ImVector my_str; + if (my_str.empty()) + my_str.push_back(0); + Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16)); + ImGui::Text("Data: %p\nSize: %d\nCapacity: %d", (void*)my_str.begin(), my_str.size(), my_str.capacity()); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Eliding, Alignment"); + if (ImGui::TreeNode("Eliding, Alignment")) + { + static char buf1[128] = "/path/to/some/folder/with/long/filename.cpp"; + static ImGuiInputTextFlags flags = ImGuiInputTextFlags_ElideLeft; + ImGui::CheckboxFlags("ImGuiInputTextFlags_ElideLeft", &flags, ImGuiInputTextFlags_ElideLeft); + ImGui::InputText("Path", buf1, IM_ARRAYSIZE(buf1), flags); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Miscellaneous"); + if (ImGui::TreeNode("Miscellaneous")) + { + static char buf1[16]; + static ImGuiInputTextFlags flags = ImGuiInputTextFlags_EscapeClearsAll; + ImGui::CheckboxFlags("ImGuiInputTextFlags_EscapeClearsAll", &flags, ImGuiInputTextFlags_EscapeClearsAll); + ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly); + ImGui::CheckboxFlags("ImGuiInputTextFlags_NoUndoRedo", &flags, ImGuiInputTextFlags_NoUndoRedo); + ImGui::InputText("Hello", buf1, IM_ARRAYSIZE(buf1), flags); + ImGui::TreePop(); + } + + ImGui::TreePop(); + } + +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsTooltips() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsTooltips() +{ + IMGUI_DEMO_MARKER("Widgets/Tooltips"); + if (ImGui::TreeNode("Tooltips")) + { + // Tooltips are windows following the mouse. They do not take focus away. + ImGui::SeparatorText("General"); + + // Typical use cases: + // - Short-form (text only): SetItemTooltip("Hello"); + // - Short-form (any contents): if (BeginItemTooltip()) { Text("Hello"); EndTooltip(); } + + // - Full-form (text only): if (IsItemHovered(...)) { SetTooltip("Hello"); } + // - Full-form (any contents): if (IsItemHovered(...) && BeginTooltip()) { Text("Hello"); EndTooltip(); } + + HelpMarker( + "Tooltip are typically created by using a IsItemHovered() + SetTooltip() sequence.\n\n" + "We provide a helper SetItemTooltip() function to perform the two with standards flags."); + + ImVec2 sz = ImVec2(-FLT_MIN, 0.0f); + + ImGui::Button("Basic", sz); + ImGui::SetItemTooltip("I am a tooltip"); + + ImGui::Button("Fancy", sz); + if (ImGui::BeginItemTooltip()) + { + ImGui::Text("I am a fancy tooltip"); + static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; + ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr)); + ImGui::Text("Sin(time) = %f", sinf((float)ImGui::GetTime())); + ImGui::EndTooltip(); + } + + ImGui::SeparatorText("Always On"); + + // Showcase NOT relying on a IsItemHovered() to emit a tooltip. + // Here the tooltip is always emitted when 'always_on == true'. + static int always_on = 0; + ImGui::RadioButton("Off", &always_on, 0); + ImGui::SameLine(); + ImGui::RadioButton("Always On (Simple)", &always_on, 1); + ImGui::SameLine(); + ImGui::RadioButton("Always On (Advanced)", &always_on, 2); + if (always_on == 1) + ImGui::SetTooltip("I am following you around."); + else if (always_on == 2 && ImGui::BeginTooltip()) + { + ImGui::ProgressBar(sinf((float)ImGui::GetTime()) * 0.5f + 0.5f, ImVec2(ImGui::GetFontSize() * 25, 0.0f)); + ImGui::EndTooltip(); + } + + ImGui::SeparatorText("Custom"); + + HelpMarker( + "Passing ImGuiHoveredFlags_ForTooltip to IsItemHovered() is the preferred way to standardize " + "tooltip activation details across your application. You may however decide to use custom " + "flags for a specific tooltip instance."); + + // The following examples are passed for documentation purpose but may not be useful to most users. + // Passing ImGuiHoveredFlags_ForTooltip to IsItemHovered() will pull ImGuiHoveredFlags flags values from + // 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or keyboard/gamepad is being used. + // With default settings, ImGuiHoveredFlags_ForTooltip is equivalent to ImGuiHoveredFlags_DelayShort + ImGuiHoveredFlags_Stationary. + ImGui::Button("Manual", sz); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip)) + ImGui::SetTooltip("I am a manually emitted tooltip."); + + ImGui::Button("DelayNone", sz); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNone)) + ImGui::SetTooltip("I am a tooltip with no delay."); + + ImGui::Button("DelayShort", sz); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_NoSharedDelay)) + ImGui::SetTooltip("I am a tooltip with a short delay (%0.2f sec).", ImGui::GetStyle().HoverDelayShort); + + ImGui::Button("DelayLong", sz); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay)) + ImGui::SetTooltip("I am a tooltip with a long delay (%0.2f sec).", ImGui::GetStyle().HoverDelayNormal); + + ImGui::Button("Stationary", sz); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary)) + ImGui::SetTooltip("I am a tooltip requiring mouse to be stationary before activating."); + + // Using ImGuiHoveredFlags_ForTooltip will pull flags from 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav', + // which default value include the ImGuiHoveredFlags_AllowWhenDisabled flag. + ImGui::BeginDisabled(); + ImGui::Button("Disabled item", sz); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip)) + ImGui::SetTooltip("I am a a tooltip for a disabled item."); + ImGui::EndDisabled(); + + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsTreeNodes() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsTreeNodes() +{ + IMGUI_DEMO_MARKER("Widgets/Tree Nodes"); + if (ImGui::TreeNode("Tree Nodes")) + { + IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Basic trees"); + if (ImGui::TreeNode("Basic trees")) + { + for (int i = 0; i < 5; i++) + { + // Use SetNextItemOpen() so set the default state of a node to be open. We could + // also use TreeNodeEx() with the ImGuiTreeNodeFlags_DefaultOpen flag to achieve the same thing! + if (i == 0) + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + + // Here we use PushID() to generate a unique base ID, and then the "" used as TreeNode id won't conflict. + // An alternative to using 'PushID() + TreeNode("", ...)' to generate a unique ID is to use 'TreeNode((void*)(intptr_t)i, ...)', + // aka generate a dummy pointer-sized value to be hashed. The demo below uses that technique. Both are fine. + ImGui::PushID(i); + if (ImGui::TreeNode("", "Child %d", i)) + { + ImGui::Text("blah blah"); + ImGui::SameLine(); + if (ImGui::SmallButton("button")) {} + ImGui::TreePop(); + } + ImGui::PopID(); + } + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Advanced, with Selectable nodes"); + if (ImGui::TreeNode("Advanced, with Selectable nodes")) + { + HelpMarker( + "This is a more typical looking tree with selectable nodes.\n" + "Click to select, CTRL+Click to toggle, click on arrows or double-click to open."); + static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; + static bool align_label_with_current_x_position = false; + static bool test_drag_and_drop = false; + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", &base_flags, ImGuiTreeNodeFlags_OpenOnArrow); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node."); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanLabelWidth", &base_flags, ImGuiTreeNodeFlags_SpanLabelWidth); ImGui::SameLine(); HelpMarker("Reduce hit area to the text label and a bit of margin."); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &base_flags, ImGuiTreeNodeFlags_SpanAllColumns); ImGui::SameLine(); HelpMarker("For use in Tables only."); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_AllowOverlap", &base_flags, ImGuiTreeNodeFlags_AllowOverlap); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_Framed", &base_flags, ImGuiTreeNodeFlags_Framed); ImGui::SameLine(); HelpMarker("Draw frame with background (e.g. for CollapsingHeader)"); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_NavLeftJumpsBackHere", &base_flags, ImGuiTreeNodeFlags_NavLeftJumpsBackHere); + ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position); + ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop); + ImGui::Text("Hello!"); + if (align_label_with_current_x_position) + ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing()); + + // 'selection_mask' is dumb representation of what may be user-side selection state. + // You may retain selection state inside or outside your objects in whatever format you see fit. + // 'node_clicked' is temporary storage of what node we have clicked to process selection at the end + /// of the loop. May be a pointer to your own node type, etc. + static int selection_mask = (1 << 2); + int node_clicked = -1; + for (int i = 0; i < 6; i++) + { + // Disable the default "open on single-click behavior" + set Selected flag according to our selection. + // To alter selection we use IsItemClicked() && !IsItemToggledOpen(), so clicking on an arrow doesn't alter selection. + ImGuiTreeNodeFlags node_flags = base_flags; + const bool is_selected = (selection_mask & (1 << i)) != 0; + if (is_selected) + node_flags |= ImGuiTreeNodeFlags_Selected; + if (i < 3) + { + // Items 0..2 are Tree Node + bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + node_clicked = i; + if (test_drag_and_drop && ImGui::BeginDragDropSource()) + { + ImGui::SetDragDropPayload("_TREENODE", NULL, 0); + ImGui::Text("This is a drag and drop source"); + ImGui::EndDragDropSource(); + } + if (i == 2 && (base_flags & ImGuiTreeNodeFlags_SpanLabelWidth)) + { + // Item 2 has an additional inline button to help demonstrate SpanLabelWidth. + ImGui::SameLine(); + if (ImGui::SmallButton("button")) {} + } + if (node_open) + { + ImGui::BulletText("Blah blah\nBlah Blah"); + ImGui::SameLine(); + ImGui::SmallButton("Button"); + ImGui::TreePop(); + } + } + else + { + // Items 3..5 are Tree Leaves + // The only reason we use TreeNode at all is to allow selection of the leaf. Otherwise we can + // use BulletText() or advance the cursor by GetTreeNodeToLabelSpacing() and call Text(). + node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet + ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + node_clicked = i; + if (test_drag_and_drop && ImGui::BeginDragDropSource()) + { + ImGui::SetDragDropPayload("_TREENODE", NULL, 0); + ImGui::Text("This is a drag and drop source"); + ImGui::EndDragDropSource(); + } + } + } + if (node_clicked != -1) + { + // Update selection state + // (process outside of tree loop to avoid visual inconsistencies during the clicking frame) + if (ImGui::GetIO().KeyCtrl) + selection_mask ^= (1 << node_clicked); // CTRL+click to toggle + else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, may want to preserve selection when clicking on item that is part of the selection + selection_mask = (1 << node_clicked); // Click to single-select + } + if (align_label_with_current_x_position) + ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing()); + ImGui::TreePop(); + } + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgetsVerticalSliders() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgetsVerticalSliders() +{ + IMGUI_DEMO_MARKER("Widgets/Vertical Sliders"); + if (ImGui::TreeNode("Vertical Sliders")) + { + const float spacing = 4; + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing)); + + static int int_value = 0; + ImGui::VSliderInt("##int", ImVec2(18, 160), &int_value, 0, 5); + ImGui::SameLine(); + + static float values[7] = { 0.0f, 0.60f, 0.35f, 0.9f, 0.70f, 0.20f, 0.0f }; + ImGui::PushID("set1"); + for (int i = 0; i < 7; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleColor(ImGuiCol_FrameBg, (ImVec4)ImColor::HSV(i / 7.0f, 0.5f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, (ImVec4)ImColor::HSV(i / 7.0f, 0.6f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgActive, (ImVec4)ImColor::HSV(i / 7.0f, 0.7f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_SliderGrab, (ImVec4)ImColor::HSV(i / 7.0f, 0.9f, 0.9f)); + ImGui::VSliderFloat("##v", ImVec2(18, 160), &values[i], 0.0f, 1.0f, ""); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) + ImGui::SetTooltip("%.3f", values[i]); + ImGui::PopStyleColor(4); + ImGui::PopID(); + } + ImGui::PopID(); + + ImGui::SameLine(); + ImGui::PushID("set2"); + static float values2[4] = { 0.20f, 0.80f, 0.40f, 0.25f }; + const int rows = 3; + const ImVec2 small_slider_size(18, (float)(int)((160.0f - (rows - 1) * spacing) / rows)); + for (int nx = 0; nx < 4; nx++) + { + if (nx > 0) ImGui::SameLine(); + ImGui::BeginGroup(); + for (int ny = 0; ny < rows; ny++) + { + ImGui::PushID(nx * rows + ny); + ImGui::VSliderFloat("##v", small_slider_size, &values2[nx], 0.0f, 1.0f, ""); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) + ImGui::SetTooltip("%.3f", values2[nx]); + ImGui::PopID(); + } + ImGui::EndGroup(); + } + ImGui::PopID(); + + ImGui::SameLine(); + ImGui::PushID("set3"); + for (int i = 0; i < 4; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40); + ImGui::VSliderFloat("##v", ImVec2(40, 160), &values[i], 0.0f, 1.0f, "%.2f\nsec"); + ImGui::PopStyleVar(); + ImGui::PopID(); + } + ImGui::PopID(); + ImGui::PopStyleVar(); + ImGui::TreePop(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowWidgets() +//----------------------------------------------------------------------------- + +static void DemoWindowWidgets(ImGuiDemoWindowData* demo_data) +{ + IMGUI_DEMO_MARKER("Widgets"); + //ImGui::SetNextItemOpen(true, ImGuiCond_Once); + if (!ImGui::CollapsingHeader("Widgets")) + return; + + const bool disable_all = demo_data->DisableSections; // The Checkbox for that is inside the "Disabled" section at the bottom + if (disable_all) + ImGui::BeginDisabled(); + + DemoWindowWidgetsBasic(); + DemoWindowWidgetsBullets(); + DemoWindowWidgetsCollapsingHeaders(); + DemoWindowWidgetsComboBoxes(); + DemoWindowWidgetsColorAndPickers(); + DemoWindowWidgetsDataTypes(); + + if (disable_all) + ImGui::EndDisabled(); + DemoWindowWidgetsDisableBlocks(demo_data); + if (disable_all) + ImGui::BeginDisabled(); + + DemoWindowWidgetsDragAndDrop(); + DemoWindowWidgetsDragsAndSliders(); + DemoWindowWidgetsImages(); + DemoWindowWidgetsListBoxes(); + DemoWindowWidgetsMultiComponents(); + DemoWindowWidgetsPlotting(); + DemoWindowWidgetsProgressBars(); + DemoWindowWidgetsQueryingStatuses(); + DemoWindowWidgetsSelectables(); + DemoWindowWidgetsSelectionAndMultiSelect(demo_data); + DemoWindowWidgetsTabs(); + DemoWindowWidgetsText(); + DemoWindowWidgetsTextFilter(); + DemoWindowWidgetsTextInput(); + DemoWindowWidgetsTooltips(); + DemoWindowWidgetsTreeNodes(); + DemoWindowWidgetsVerticalSliders(); + + if (disable_all) + ImGui::EndDisabled(); +} + +//----------------------------------------------------------------------------- +// [SECTION] DemoWindowLayout() +//----------------------------------------------------------------------------- + +static void DemoWindowLayout() { IMGUI_DEMO_MARKER("Layout"); if (!ImGui::CollapsingHeader("Layout & Scrolling")) @@ -4800,10 +5033,10 @@ static void ShowDemoWindowLayout() } //----------------------------------------------------------------------------- -// [SECTION] ShowDemoWindowPopups() +// [SECTION] DemoWindowPopups() //----------------------------------------------------------------------------- -static void ShowDemoWindowPopups() +static void DemoWindowPopups() { IMGUI_DEMO_MARKER("Popups"); if (!ImGui::CollapsingHeader("Popups & Modal windows")) @@ -5264,10 +5497,10 @@ static void ShowTableColumnsStatusFlags(ImGuiTableColumnFlags flags) } //----------------------------------------------------------------------------- -// [SECTION] ShowDemoWindowTables() +// [SECTION] DemoWindowTables() //----------------------------------------------------------------------------- -static void ShowDemoWindowTables() +static void DemoWindowTables() { //ImGui::SetNextItemOpen(true, ImGuiCond_Once); IMGUI_DEMO_MARKER("Tables"); @@ -7164,7 +7397,7 @@ static void ShowDemoWindowTables() ImGui::PopID(); - ShowDemoWindowColumns(); + DemoWindowColumns(); if (disable_indent) ImGui::PopStyleVar(); @@ -7172,7 +7405,7 @@ static void ShowDemoWindowTables() // Demonstrate old/legacy Columns API! // [2020: Columns are under-featured and not maintained. Prefer using the more flexible and powerful BeginTable() API!] -static void ShowDemoWindowColumns() +static void DemoWindowColumns() { IMGUI_DEMO_MARKER("Columns (legacy API)"); bool open = ImGui::TreeNode("Legacy Columns API"); @@ -7379,10 +7612,10 @@ static void ShowDemoWindowColumns() } //----------------------------------------------------------------------------- -// [SECTION] ShowDemoWindowInputs() +// [SECTION] DemoWindowInputs() //----------------------------------------------------------------------------- -static void ShowDemoWindowInputs() +static void DemoWindowInputs() { IMGUI_DEMO_MARKER("Inputs & Focus"); if (ImGui::CollapsingHeader("Inputs & Focus")) @@ -7571,7 +7804,7 @@ static void ShowDemoWindowInputs() IMGUI_DEMO_MARKER("Inputs & Focus/Mouse Cursors"); if (ImGui::TreeNode("Mouse Cursors")) { - const char* mouse_cursors_names[] = { "Arrow", "TextInput", "ResizeAll", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE", "Hand", "NotAllowed" }; + const char* mouse_cursors_names[] = { "Arrow", "TextInput", "ResizeAll", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE", "Hand", "Wait", "Progress", "NotAllowed" }; IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_COUNT); ImGuiMouseCursor current = ImGui::GetMouseCursor(); @@ -7749,6 +7982,9 @@ void ImGui::ShowAboutWindow(bool* p_open) #ifdef IMGUI_DISABLE_WIN32_FUNCTIONS ImGui::Text("define: IMGUI_DISABLE_WIN32_FUNCTIONS"); #endif +#ifdef IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS"); +#endif #ifdef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS ImGui::Text("define: IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS"); #endif @@ -7966,10 +8202,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f, "%.0f"); ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f"); ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f"); - ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f"); - ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f, 2.0f, "%.0f"); - ImGui::SliderFloat("TabBarOverlineSize", &style.TabBarOverlineSize, 0.0f, 3.0f, "%.0f"); - ImGui::SameLine(); HelpMarker("Overline is only drawn over the selected tab when ImGuiTabBarFlags_DrawSelectedOverline is set."); ImGui::SeparatorText("Rounding"); ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f, "%.0f"); @@ -7978,6 +8210,14 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f, "%.0f"); ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f"); ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f"); + + ImGui::SeparatorText("Tabs"); + ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f, 2.0f, "%.0f"); + ImGui::SliderFloat("TabBarOverlineSize", &style.TabBarOverlineSize, 0.0f, 3.0f, "%.0f"); + ImGui::SameLine(); HelpMarker("Overline is only drawn over the selected tab when ImGuiTabBarFlags_DrawSelectedOverline is set."); + ImGui::DragFloat("TabCloseButtonMinWidthSelected", &style.TabCloseButtonMinWidthSelected, 0.1f, -1.0f, 100.0f, (style.TabCloseButtonMinWidthSelected < 0.0f) ? "%.0f (Always)" : "%.0f"); + ImGui::DragFloat("TabCloseButtonMinWidthUnselected", &style.TabCloseButtonMinWidthUnselected, 0.1f, -1.0f, 100.0f, (style.TabCloseButtonMinWidthUnselected < 0.0f) ? "%.0f (Always)" : "%.0f"); ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f"); ImGui::SeparatorText("Tables"); @@ -7985,11 +8225,14 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SliderAngle("TableAngledHeadersAngle", &style.TableAngledHeadersAngle, -50.0f, +50.0f); ImGui::SliderFloat2("TableAngledHeadersTextAlign", (float*)&style.TableAngledHeadersTextAlign, 0.0f, 1.0f, "%.2f"); - ImGui::SeparatorText("Widgets"); + ImGui::SeparatorText("Windows"); ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); + ImGui::SliderFloat("WindowBorderHoverPadding", &style.WindowBorderHoverPadding, 1.0f, 20.0f, "%.0f"); int window_menu_button_position = style.WindowMenuButtonPosition + 1; if (ImGui::Combo("WindowMenuButtonPosition", (int*)&window_menu_button_position, "None\0Left\0Right\0")) style.WindowMenuButtonPosition = (ImGuiDir)(window_menu_button_position - 1); + + ImGui::SeparatorText("Widgets"); ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition, "Left\0Right\0"); ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Alignment applies when a button is larger than its text content."); @@ -7999,6 +8242,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SliderFloat2("SeparatorTextAlign", (float*)&style.SeparatorTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SliderFloat2("SeparatorTextPadding", (float*)&style.SeparatorTextPadding, 0.0f, 40.0f, "%.0f"); ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("ImageBorderSize", &style.ImageBorderSize, 0.0f, 1.0f, "%.0f"); ImGui::SeparatorText("Tooltips"); for (int n = 0; n < 2; n++) @@ -8173,7 +8417,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::EndTooltip(); } ImGui::SameLine(); - HelpMarker("When drawing circle primitives with \"num_segments == 0\" tesselation will be calculated automatically."); + HelpMarker("When drawing circle primitives with \"num_segments == 0\" tessellation will be calculated automatically."); ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero. ImGui::DragFloat("Disabled Alpha", &style.DisabledAlpha, 0.005f, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Additional alpha multiplier for disabled items (multiply over current value of Alpha)."); @@ -8204,12 +8448,12 @@ void ImGui::ShowUserGuide() ImGui::BulletText("CTRL+Tab to select a window."); if (io.FontAllowUserScaling) ImGui::BulletText("CTRL+Mouse Wheel to zoom window contents."); - ImGui::BulletText("While inputing text:\n"); + ImGui::BulletText("While inputting text:\n"); ImGui::Indent(); ImGui::BulletText("CTRL+Left/Right to word jump."); ImGui::BulletText("CTRL+A or double-click to select all."); ImGui::BulletText("CTRL+X/C/V to use clipboard cut/copy/paste."); - ImGui::BulletText("CTRL+Z,CTRL+Y to undo/redo."); + ImGui::BulletText("CTRL+Z to undo, CTRL+Y/CTRL+SHIFT+Z to redo."); ImGui::BulletText("ESCAPE to revert."); ImGui::Unindent(); ImGui::BulletText("With keyboard navigation enabled:"); @@ -8245,7 +8489,7 @@ static void ShowExampleAppMainMenuBar() if (ImGui::BeginMenu("Edit")) { if (ImGui::MenuItem("Undo", "CTRL+Z")) {} - if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item + if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item ImGui::Separator(); if (ImGui::MenuItem("Cut", "CTRL+X")) {} if (ImGui::MenuItem("Copy", "CTRL+C")) {} @@ -8635,7 +8879,7 @@ struct ExampleAppConsole else { // Multiple matches. Complete as much as we can.. - // So inputing "C"+Tab will complete to "CL" then display "CLEAR" and "CLASSIFY" as matches. + // So inputting "C"+Tab will complete to "CL" then display "CLEAR" and "CLASSIFY" as matches. int match_len = (int)(word_end - word_start); for (;;) { @@ -9493,7 +9737,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) float th = (n == 0) ? 1.0f : thickness; draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle - draw_list->AddEllipse(ImVec2(x + sz*0.5f, y + sz*0.5f), ImVec2(sz*0.5f, sz*0.3f), col, -0.3f, circle_segments, th); x += sz + spacing; // Ellipse + draw_list->AddEllipse(ImVec2(x + sz*0.5f, y + sz*0.5f), ImVec2(sz*0.5f, sz*0.3f), col, -0.3f, circle_segments, th); x += sz + spacing; // Ellipse draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, ImDrawFlags_None, th); x += sz + spacing; // Square draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, ImDrawFlags_None, th); x += sz + spacing; // Square with all rounded corners draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners diff --git a/3rdparty/imgui/src/imgui_draw.cpp b/3rdparty/imgui/src/imgui_draw.cpp index 442ee0ae39..5018be307a 100644 --- a/3rdparty/imgui/src/imgui_draw.cpp +++ b/3rdparty/imgui/src/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.91.8 +// dear imgui, v1.91.9b // (drawing and font code) /* @@ -68,6 +68,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type #pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier +#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used @@ -143,6 +144,7 @@ namespace IMGUI_STB_NAMESPACE #define STBTT_fabs(x) ImFabs(x) #define STBTT_ifloor(x) ((int)ImFloor(x)) #define STBTT_iceil(x) ((int)ImCeil(x)) +#define STBTT_strlen(x) ImStrlen(x) #define STBTT_STATIC #define STB_TRUETYPE_IMPLEMENTATION #else @@ -374,6 +376,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) ImDrawListSharedData::ImDrawListSharedData() { memset(this, 0, sizeof(*this)); + InitialFringeScale = 1.0f; for (int i = 0; i < IM_ARRAYSIZE(ArcFastVtx); i++) { const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(ArcFastVtx); @@ -433,7 +436,7 @@ void ImDrawList::_ResetForNewFrame() _Path.resize(0); _Splitter.Clear(); CmdBuffer.push_back(ImDrawCmd()); - _FringeScale = 1.0f; + _FringeScale = _Data->InitialFringeScale; } void ImDrawList::_ClearFreeMemory() @@ -2401,13 +2404,13 @@ ImFontConfig::ImFontConfig() // - ImFontAtlas::AddCustomRectRegular() // - ImFontAtlas::AddCustomRectFontGlyph() // - ImFontAtlas::CalcCustomRectUV() -// - ImFontAtlas::GetMouseCursorTexData() +// - ImFontAtlasGetMouseCursorTexData() // - ImFontAtlas::Build() // - ImFontAtlasBuildMultiplyCalcLookupTable() // - ImFontAtlasBuildMultiplyRectAlpha8() // - ImFontAtlasBuildWithStbTruetype() // - ImFontAtlasGetBuilderForStbTruetype() -// - ImFontAtlasUpdateConfigDataPointers() +// - ImFontAtlasUpdateSourcesPointers() // - ImFontAtlasBuildSetupFont() // - ImFontAtlasBuildPackCustomRects() // - ImFontAtlasBuildRender8bppRectFromString() @@ -2465,6 +2468,8 @@ static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3 { ImVec2(73,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNESW { ImVec2(55,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNWSE { ImVec2(91,0), ImVec2(17,22), ImVec2( 5, 0) }, // ImGuiMouseCursor_Hand + { ImVec2(0,3), ImVec2(12,19), ImVec2(0, 0) }, // ImGuiMouseCursor_Wait // Arrow + custom code in ImGui::RenderMouseCursor() + { ImVec2(0,3), ImVec2(12,19), ImVec2(0, 0) }, // ImGuiMouseCursor_Progress // Arrow + custom code in ImGui::RenderMouseCursor() { ImVec2(109,0),ImVec2(13,15), ImVec2( 6, 7) }, // ImGuiMouseCursor_NotAllowed }; @@ -2484,7 +2489,7 @@ ImFontAtlas::~ImFontAtlas() void ImFontAtlas::ClearInputData() { IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); - for (ImFontConfig& font_cfg : ConfigData) + for (ImFontConfig& font_cfg : Sources) if (font_cfg.FontData && font_cfg.FontDataOwnedByAtlas) { IM_FREE(font_cfg.FontData); @@ -2493,12 +2498,12 @@ void ImFontAtlas::ClearInputData() // When clearing this we lose access to the font name and other information used to build the font. for (ImFont* font : Fonts) - if (font->ConfigData >= ConfigData.Data && font->ConfigData < ConfigData.Data + ConfigData.Size) + if (font->Sources >= Sources.Data && font->Sources < Sources.Data + Sources.Size) { - font->ConfigData = NULL; - font->ConfigDataCount = 0; + font->Sources = NULL; + font->SourcesCount = 0; } - ConfigData.clear(); + Sources.clear(); CustomRects.clear(); PackIdMouseCursors = PackIdLines = -1; // Important: we leave TexReady untouched @@ -2581,8 +2586,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg) else IM_ASSERT(Fonts.Size > 0 && "Cannot use MergeMode for the first font"); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font. - ConfigData.push_back(*font_cfg); - ImFontConfig& new_font_cfg = ConfigData.back(); + Sources.push_back(*font_cfg); + ImFontConfig& new_font_cfg = Sources.back(); if (new_font_cfg.DstFont == NULL) new_font_cfg.DstFont = Fonts.back(); if (!new_font_cfg.FontDataOwnedByAtlas) @@ -2598,8 +2603,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg) // - We may support it better later and remove this rounding. new_font_cfg.SizePixels = ImTrunc(new_font_cfg.SizePixels); - // Pointers to ConfigData and BuilderData are otherwise dangling - ImFontAtlasUpdateConfigDataPointers(this); + // Pointers to Sources data are otherwise dangling + ImFontAtlasUpdateSourcesPointers(this); // Invalidate texture TexReady = false; @@ -2669,7 +2674,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, { // Store a short copy of filename into into the font name for convenience const char* p; - for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {} + for (p = filename + ImStrlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {} ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels); } return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges); @@ -2704,7 +2709,7 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_d ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges) { - int compressed_ttf_size = (((int)strlen(compressed_ttf_data_base85) + 4) / 5) * 4; + int compressed_ttf_size = (((int)ImStrlen(compressed_ttf_data_base85) + 4) / 5) * 4; void* compressed_ttf = IM_ALLOC((size_t)compressed_ttf_size); Decode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf); ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges); @@ -2751,24 +2756,24 @@ void ImFontAtlas::CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* ou *out_uv_max = ImVec2((float)(rect->X + rect->Width) * TexUvScale.x, (float)(rect->Y + rect->Height) * TexUvScale.y); } -bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]) +bool ImFontAtlasGetMouseCursorTexData(ImFontAtlas* atlas, ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]) { if (cursor_type <= ImGuiMouseCursor_None || cursor_type >= ImGuiMouseCursor_COUNT) return false; - if (Flags & ImFontAtlasFlags_NoMouseCursors) + if (atlas->Flags & ImFontAtlasFlags_NoMouseCursors) return false; - IM_ASSERT(PackIdMouseCursors != -1); - ImFontAtlasCustomRect* r = GetCustomRectByIndex(PackIdMouseCursors); + IM_ASSERT(atlas->PackIdMouseCursors != -1); + ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdMouseCursors); ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r->X, (float)r->Y); ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1]; *out_size = size; *out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2]; - out_uv_border[0] = (pos) * TexUvScale; - out_uv_border[1] = (pos + size) * TexUvScale; + out_uv_border[0] = (pos) * atlas->TexUvScale; + out_uv_border[1] = (pos + size) * atlas->TexUvScale; pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W + 1; - out_uv_fill[0] = (pos) * TexUvScale; - out_uv_fill[1] = (pos + size) * TexUvScale; + out_uv_fill[0] = (pos) * atlas->TexUvScale; + out_uv_fill[1] = (pos + size) * atlas->TexUvScale; return true; } @@ -2777,7 +2782,7 @@ bool ImFontAtlas::Build() IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); // Default font is none are specified - if (ConfigData.Size == 0) + if (Sources.Size == 0) AddFontDefault(); // Select builder @@ -2819,11 +2824,11 @@ void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsig *data = table[*data]; } -void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* cfg, int* out_oversample_h, int* out_oversample_v) +void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* src, int* out_oversample_h, int* out_oversample_v) { // Automatically disable horizontal oversampling over size 36 - *out_oversample_h = (cfg->OversampleH != 0) ? cfg->OversampleH : (cfg->SizePixels * cfg->RasterizerDensity > 36.0f || cfg->PixelSnapH) ? 1 : 2; - *out_oversample_v = (cfg->OversampleV != 0) ? cfg->OversampleV : 1; + *out_oversample_h = (src->OversampleH != 0) ? src->OversampleH : (src->SizePixels * src->RasterizerDensity > 36.0f || src->PixelSnapH) ? 1 : 2; + *out_oversample_v = (src->OversampleV != 0) ? src->OversampleV : 1; } #ifdef IMGUI_ENABLE_STB_TRUETYPE @@ -2866,7 +2871,7 @@ static void UnpackBitVectorToFlatIndexList(const ImBitVector* in, ImVector* static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) { - IM_ASSERT(atlas->ConfigData.Size > 0); + IM_ASSERT(atlas->Sources.Size > 0); ImFontAtlasBuildInit(atlas); @@ -2880,32 +2885,32 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) // Temporary storage for building ImVector src_tmp_array; ImVector dst_tmp_array; - src_tmp_array.resize(atlas->ConfigData.Size); + src_tmp_array.resize(atlas->Sources.Size); dst_tmp_array.resize(atlas->Fonts.Size); memset(src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes()); memset(dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes()); // 1. Initialize font loading structure, check font data validity - for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++) + for (int src_i = 0; src_i < atlas->Sources.Size; src_i++) { ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; - ImFontConfig& cfg = atlas->ConfigData[src_i]; - IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas)); + ImFontConfig& src = atlas->Sources[src_i]; + IM_ASSERT(src.DstFont && (!src.DstFont->IsLoaded() || src.DstFont->ContainerAtlas == atlas)); - // Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices) + // Find index from src.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices) src_tmp.DstIndex = -1; for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++) - if (cfg.DstFont == atlas->Fonts[output_i]) + if (src.DstFont == atlas->Fonts[output_i]) src_tmp.DstIndex = output_i; if (src_tmp.DstIndex == -1) { - IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array? + IM_ASSERT(src_tmp.DstIndex != -1); // src.DstFont not pointing within atlas->Fonts[] array? return false; } // Initialize helper structure for font loading and verify that the TTF/OTF data is correct - const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); + const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)src.FontData, src.FontNo); IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found."); - if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) + if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)src.FontData, font_offset)) { IM_ASSERT(0 && "stbtt_InitFont(): failed to parse FontData. It is correct and complete? Check FontDataSize."); return false; @@ -2913,7 +2918,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) // Measure highest codepoints ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex]; - src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault(); + src_tmp.SrcRanges = src.GlyphRanges ? src.GlyphRanges : atlas->GetGlyphRangesDefault(); for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2) { // Check for valid range. This may also help detect *some* dangling pointers, because a common @@ -2992,12 +2997,12 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) buf_packedchars_out_n += src_tmp.GlyphsCount; // Automatic selection of oversampling parameters - ImFontConfig& cfg = atlas->ConfigData[src_i]; + ImFontConfig& src = atlas->Sources[src_i]; int oversample_h, oversample_v; - ImFontAtlasBuildGetOversampleFactors(&cfg, &oversample_h, &oversample_v); + ImFontAtlasBuildGetOversampleFactors(&src, &oversample_h, &oversample_v); // Convert our ranges in the format stb_truetype wants - src_tmp.PackRange.font_size = cfg.SizePixels * cfg.RasterizerDensity; + src_tmp.PackRange.font_size = src.SizePixels * src.RasterizerDensity; src_tmp.PackRange.first_unicode_codepoint_in_range = 0; src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data; src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size; @@ -3006,7 +3011,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) src_tmp.PackRange.v_oversample = (unsigned char)oversample_v; // Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects) - const float scale = (cfg.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels * cfg.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels * cfg.RasterizerDensity); + const float scale = (src.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, src.SizePixels * src.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -src.SizePixels * src.RasterizerDensity); for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++) { int x0, y0, x1, y1; @@ -3066,7 +3071,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) // 8. Render/rasterize font characters into the texture for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) { - ImFontConfig& cfg = atlas->ConfigData[src_i]; + ImFontConfig& src = atlas->Sources[src_i]; ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; if (src_tmp.GlyphsCount == 0) continue; @@ -3074,10 +3079,10 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) stbtt_PackFontRangesRenderIntoRects(&spc, &src_tmp.FontInfo, &src_tmp.PackRange, 1, src_tmp.Rects); // Apply multiply operator - if (cfg.RasterizerMultiply != 1.0f) + if (src.RasterizerMultiply != 1.0f) { unsigned char multiply_table[256]; - ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply); + ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, src.RasterizerMultiply); stbrp_rect* r = &src_tmp.Rects[0]; for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++, r++) if (r->was_packed) @@ -3095,22 +3100,22 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) { // When merging fonts with MergeMode=true: // - We can have multiple input fonts writing into a same destination font. - // - dst_font->ConfigData is != from cfg which is our source configuration. + // - dst_font->Sources is != from src which is our source configuration. ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; - ImFontConfig& cfg = atlas->ConfigData[src_i]; - ImFont* dst_font = cfg.DstFont; + ImFontConfig& src = atlas->Sources[src_i]; + ImFont* dst_font = src.DstFont; - const float font_scale = stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels); + const float font_scale = stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, src.SizePixels); int unscaled_ascent, unscaled_descent, unscaled_line_gap; stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap); const float ascent = ImCeil(unscaled_ascent * font_scale); const float descent = ImFloor(unscaled_descent * font_scale); - ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); - const float font_off_x = cfg.GlyphOffset.x; - const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent); + ImFontAtlasBuildSetupFont(atlas, dst_font, &src, ascent, descent); + const float font_off_x = src.GlyphOffset.x; + const float font_off_y = src.GlyphOffset.y + IM_ROUND(dst_font->Ascent); - const float inv_rasterization_scale = 1.0f / cfg.RasterizerDensity; + const float inv_rasterization_scale = 1.0f / src.RasterizerDensity; for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++) { @@ -3124,7 +3129,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) float y0 = q.y0 * inv_rasterization_scale + font_off_y; float x1 = q.x1 * inv_rasterization_scale + font_off_x; float y1 = q.y1 * inv_rasterization_scale + font_off_y; - dst_font->AddGlyph(&cfg, (ImWchar)codepoint, x0, y0, x1, y1, q.s0, q.t0, q.s1, q.t1, pc.xadvance * inv_rasterization_scale); + dst_font->AddGlyph(&src, (ImWchar)codepoint, x0, y0, x1, y1, q.s0, q.t0, q.s1, q.t1, pc.xadvance * inv_rasterization_scale); } } @@ -3144,17 +3149,17 @@ const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype() #endif // IMGUI_ENABLE_STB_TRUETYPE -void ImFontAtlasUpdateConfigDataPointers(ImFontAtlas* atlas) +void ImFontAtlasUpdateSourcesPointers(ImFontAtlas* atlas) { - for (ImFontConfig& font_cfg : atlas->ConfigData) + for (ImFontConfig& src : atlas->Sources) { - ImFont* font = font_cfg.DstFont; - if (!font_cfg.MergeMode) + ImFont* font = src.DstFont; + if (!src.MergeMode) { - font->ConfigData = &font_cfg; - font->ConfigDataCount = 0; + font->Sources = &src; + font->SourcesCount = 0; } - font->ConfigDataCount++; + font->SourcesCount++; } } @@ -3164,7 +3169,7 @@ void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* f { font->ClearOutputData(); font->FontSize = font_config->SizePixels; - IM_ASSERT(font->ConfigData == font_config); + IM_ASSERT(font->Sources == font_config); font->ContainerAtlas = atlas; font->Ascent = ascent; font->Descent = descent; @@ -3349,7 +3354,7 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas) if (r->Font == NULL || r->GlyphID == 0) continue; - // Will ignore ImFontConfig settings: GlyphMinAdvanceX, GlyphMinAdvanceY, GlyphExtraSpacing, PixelSnapH + // Will ignore ImFontConfig settings: GlyphMinAdvanceX, GlyphMinAdvanceY, PixelSnapH IM_ASSERT(r->Font->ContainerAtlas == atlas); ImVec2 uv0, uv1; atlas->CalcCustomRectUV(r, &uv0, &uv1); @@ -3685,21 +3690,8 @@ void ImFontGlyphRangesBuilder::BuildRanges(ImVector* out_ranges) ImFont::ImFont() { - FontSize = 0.0f; - FallbackAdvanceX = 0.0f; - FallbackChar = 0; - EllipsisChar = 0; - EllipsisWidth = EllipsisCharStep = 0.0f; - EllipsisCharCount = 0; - FallbackGlyph = NULL; - ContainerAtlas = NULL; - ConfigData = NULL; - ConfigDataCount = 0; - DirtyLookupTables = false; + memset(this, 0, sizeof(*this)); Scale = 1.0f; - Ascent = Descent = 0.0f; - MetricsTotalSurface = 0; - memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap)); } ImFont::~ImFont() @@ -3770,8 +3762,10 @@ void ImFont::BuildLookupTable() } // Mark special glyphs as not visible (note that AddGlyph already mark as non-visible glyphs with zero-size polygons) - SetGlyphVisible((ImWchar)' ', false); - SetGlyphVisible((ImWchar)'\t', false); + if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)' ')) + glyph->Visible = false; + if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)'\t')) + glyph->Visible = false; // Setup Fallback character const ImWchar fallback_chars[] = { (ImWchar)IM_UNICODE_CODEPOINT_INVALID, (ImWchar)'?', (ImWchar)' ' }; @@ -3794,7 +3788,7 @@ void ImFont::BuildLookupTable() // Setup Ellipsis character. It is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis). // However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character. // FIXME: Note that 0x2026 is rarely included in our font ranges. Because of this we are more likely to use three individual dots. - const ImWchar ellipsis_chars[] = { ConfigData->EllipsisChar, (ImWchar)0x2026, (ImWchar)0x0085 }; + const ImWchar ellipsis_chars[] = { Sources->EllipsisChar, (ImWchar)0x2026, (ImWchar)0x0085 }; const ImWchar dots_chars[] = { (ImWchar)'.', (ImWchar)0xFF0E }; if (EllipsisChar == 0) EllipsisChar = FindFirstExistingGlyph(this, ellipsis_chars, IM_ARRAYSIZE(ellipsis_chars)); @@ -3827,12 +3821,6 @@ bool ImFont::IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last) return true; } -void ImFont::SetGlyphVisible(ImWchar c, bool visible) -{ - if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)c)) - glyph->Visible = visible ? 1 : 0; -} - void ImFont::GrowIndex(int new_size) { IM_ASSERT(IndexAdvanceX.Size == IndexLookup.Size); @@ -3844,27 +3832,27 @@ void ImFont::GrowIndex(int new_size) // x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero. // Not to be mistaken with texture coordinates, which are held by u0/v0/u1/v1 in normalized format (0.0..1.0 on each texture axis). -// 'cfg' is not necessarily == 'this->ConfigData' because multiple source fonts+configs can be used to build one target font. -void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x) +// 'src' is not necessarily == 'this->Sources' because multiple source fonts+configs can be used to build one target font. +void ImFont::AddGlyph(const ImFontConfig* src, ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x) { - if (cfg != NULL) + if (src != NULL) { // Clamp & recenter if needed const float advance_x_original = advance_x; - advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX); + advance_x = ImClamp(advance_x, src->GlyphMinAdvanceX, src->GlyphMaxAdvanceX); if (advance_x != advance_x_original) { - float char_off_x = cfg->PixelSnapH ? ImTrunc((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f; + float char_off_x = src->PixelSnapH ? ImTrunc((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f; x0 += char_off_x; x1 += char_off_x; } // Snap to pixel - if (cfg->PixelSnapH) + if (src->PixelSnapH) advance_x = IM_ROUND(advance_x); - // Bake spacing - advance_x += cfg->GlyphExtraSpacing.x; + // Bake extra spacing + advance_x += src->GlyphExtraAdvanceX; } int glyph_idx = Glyphs.Size; @@ -3907,7 +3895,7 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) } // Find glyph, return fallback if missing -const ImFontGlyph* ImFont::FindGlyph(ImWchar c) +ImFontGlyph* ImFont::FindGlyph(ImWchar c) { if (c >= (size_t)IndexLookup.Size) return FallbackGlyph; @@ -3917,7 +3905,7 @@ const ImFontGlyph* ImFont::FindGlyph(ImWchar c) return &Glyphs.Data[i]; } -const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) +ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) { if (c >= (size_t)IndexLookup.Size) return NULL; @@ -4043,7 +4031,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) { if (!text_end) - text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this. + text_end = text_begin + ImStrlen(text_begin); // FIXME-OPT: Need to avoid this. const float line_height = size; const float scale = size / FontSize; @@ -4143,7 +4131,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im return; if (!text_end) - text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls. + text_end = text_begin + ImStrlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls. const float scale = size / FontSize; const float line_height = FontSize * scale; @@ -4155,7 +4143,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im if (y + line_height < clip_rect.y) while (y + line_height < clip_rect.y && s < text_end) { - const char* line_end = (const char*)memchr(s, '\n', text_end - s); + const char* line_end = (const char*)ImMemchr(s, '\n', text_end - s); if (word_wrap_enabled) { // FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPositionA(). @@ -4179,7 +4167,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im float y_end = y; while (y_end < clip_rect.w && s_end < text_end) { - s_end = (const char*)memchr(s_end, '\n', text_end - s_end); + s_end = (const char*)ImMemchr(s_end, '\n', text_end - s_end); s_end = s_end ? s_end + 1 : text_end; y_end += line_height; } diff --git a/3rdparty/imgui/src/imgui_freetype.cpp b/3rdparty/imgui/src/imgui_freetype.cpp index 029991bbde..73b9862bcf 100644 --- a/3rdparty/imgui/src/imgui_freetype.cpp +++ b/3rdparty/imgui/src/imgui_freetype.cpp @@ -166,7 +166,7 @@ namespace // NB: No ctor/dtor, explicitly call Init()/Shutdown() struct FreeTypeFont { - bool InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime. + bool InitFont(FT_Library ft_library, const ImFontConfig& src, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime. void CloseFont(); void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint); @@ -185,9 +185,9 @@ namespace float InvRasterizationDensity; }; - bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags) + bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& src, unsigned int extra_font_builder_flags) { - FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face); + FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)src.FontData, (uint32_t)src.FontDataSize, (uint32_t)src.FontNo, &Face); if (error != 0) return false; error = FT_Select_Charmap(Face, FT_ENCODING_UNICODE); @@ -195,7 +195,7 @@ namespace return false; // Convert to FreeType flags (NB: Bold and Oblique are processed separately) - UserFlags = cfg.FontBuilderFlags | extra_font_builder_flags; + UserFlags = src.FontBuilderFlags | extra_font_builder_flags; LoadFlags = 0; if ((UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) == 0) @@ -222,11 +222,11 @@ namespace if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor) LoadFlags |= FT_LOAD_COLOR; - RasterizationDensity = cfg.RasterizerDensity; + RasterizationDensity = src.RasterizerDensity; InvRasterizationDensity = 1.0f / RasterizationDensity; memset(&Info, 0, sizeof(Info)); - SetPixelHeight((uint32_t)cfg.SizePixels); + SetPixelHeight((uint32_t)src.SizePixels); return true; } @@ -269,11 +269,11 @@ namespace if (glyph_index == 0) return nullptr; - // If this crash for you: FreeType 2.11.0 has a crash bug on some bitmap/colored fonts. - // - https://gitlab.freedesktop.org/freetype/freetype/-/issues/1076 - // - https://github.com/ocornut/imgui/issues/4567 - // - https://github.com/ocornut/imgui/issues/4566 - // You can use FreeType 2.10, or the patched version of 2.11.0 in VcPkg, or probably any upcoming FreeType version. + // If this crash for you: FreeType 2.11.0 has a crash bug on some bitmap/colored fonts. + // - https://gitlab.freedesktop.org/freetype/freetype/-/issues/1076 + // - https://github.com/ocornut/imgui/issues/4567 + // - https://github.com/ocornut/imgui/issues/4566 + // You can use FreeType 2.10, or the patched version of 2.11.0 in VcPkg, or probably any upcoming FreeType version. FT_Error error = FT_Load_Glyph(Face, glyph_index, LoadFlags); if (error) return nullptr; @@ -443,7 +443,7 @@ struct ImFontBuildDstDataFT bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags) { - IM_ASSERT(atlas->ConfigData.Size > 0); + IM_ASSERT(atlas->Sources.Size > 0); ImFontAtlasBuildInit(atlas); @@ -458,36 +458,36 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u bool src_load_color = false; ImVector src_tmp_array; ImVector dst_tmp_array; - src_tmp_array.resize(atlas->ConfigData.Size); + src_tmp_array.resize(atlas->Sources.Size); dst_tmp_array.resize(atlas->Fonts.Size); memset((void*)src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes()); memset((void*)dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes()); // 1. Initialize font loading structure, check font data validity - for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++) + for (int src_i = 0; src_i < atlas->Sources.Size; src_i++) { ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i]; - ImFontConfig& cfg = atlas->ConfigData[src_i]; + ImFontConfig& src = atlas->Sources[src_i]; FreeTypeFont& font_face = src_tmp.Font; - IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas)); + IM_ASSERT(src.DstFont && (!src.DstFont->IsLoaded() || src.DstFont->ContainerAtlas == atlas)); - // Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices) + // Find index from src.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices) src_tmp.DstIndex = -1; for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++) - if (cfg.DstFont == atlas->Fonts[output_i]) + if (src.DstFont == atlas->Fonts[output_i]) src_tmp.DstIndex = output_i; - IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array? + IM_ASSERT(src_tmp.DstIndex != -1); // src.DstFont not pointing within atlas->Fonts[] array? if (src_tmp.DstIndex == -1) return false; // Load font - if (!font_face.InitFont(ft_library, cfg, extra_flags)) + if (!font_face.InitFont(ft_library, src, extra_flags)) return false; // Measure highest codepoints - src_load_color |= (cfg.FontBuilderFlags & ImGuiFreeTypeBuilderFlags_LoadColor) != 0; + src_load_color |= (src.FontBuilderFlags & ImGuiFreeTypeBuilderFlags_LoadColor) != 0; ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex]; - src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault(); + src_tmp.SrcRanges = src.GlyphRanges ? src.GlyphRanges : atlas->GetGlyphRangesDefault(); for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2) { // Check for valid range. This may also help detect *some* dangling pointers, because a common @@ -577,7 +577,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) { ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i]; - ImFontConfig& cfg = atlas->ConfigData[src_i]; + ImFontConfig& src = atlas->Sources[src_i]; if (src_tmp.GlyphsCount == 0) continue; @@ -585,10 +585,10 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u buf_rects_out_n += src_tmp.GlyphsCount; // Compute multiply table if requested - const bool multiply_enabled = (cfg.RasterizerMultiply != 1.0f); + const bool multiply_enabled = (src.RasterizerMultiply != 1.0f); unsigned char multiply_table[256]; if (multiply_enabled) - ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply); + ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, src.RasterizerMultiply); // Gather the sizes of all rectangles we will need to pack for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++) @@ -687,18 +687,18 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u // When merging fonts with MergeMode=true: // - We can have multiple input fonts writing into a same destination font. - // - dst_font->ConfigData is != from cfg which is our source configuration. - ImFontConfig& cfg = atlas->ConfigData[src_i]; - ImFont* dst_font = cfg.DstFont; + // - dst_font->Sources is != from src which is our source configuration. + ImFontConfig& src = atlas->Sources[src_i]; + ImFont* dst_font = src.DstFont; const float ascent = src_tmp.Font.Info.Ascender; const float descent = src_tmp.Font.Info.Descender; - ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); + ImFontAtlasBuildSetupFont(atlas, dst_font, &src, ascent, descent); if (src_tmp.GlyphsCount == 0) continue; - const float font_off_x = cfg.GlyphOffset.x; - const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent); + const float font_off_x = src.GlyphOffset.x; + const float font_off_y = src.GlyphOffset.y + IM_ROUND(dst_font->Ascent); const int padding = atlas->TexGlyphPadding; for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++) @@ -724,7 +724,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u float v0 = (ty) / (float)atlas->TexHeight; float u1 = (tx + info.Width) / (float)atlas->TexWidth; float v1 = (ty + info.Height) / (float)atlas->TexHeight; - dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX * src_tmp.Font.InvRasterizationDensity); + dst_font->AddGlyph(&src, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX * src_tmp.Font.InvRasterizationDensity); ImFontGlyph* dst_glyph = &dst_font->Glyphs.back(); IM_ASSERT(dst_glyph->Codepoint == src_glyph.Codepoint); diff --git a/3rdparty/imgui/src/imgui_tables.cpp b/3rdparty/imgui/src/imgui_tables.cpp index e7a3b8e8d1..c98aea2d1c 100644 --- a/3rdparty/imgui/src/imgui_tables.cpp +++ b/3rdparty/imgui/src/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.91.8 +// dear imgui, v1.91b // (tables and columns code) /* @@ -221,6 +221,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok. +#pragma clang diagnostic ignored "-Wformat" // warning: format specifies type 'int' but the argument has type 'unsigned int' #pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 @@ -230,6 +231,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type +#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe @@ -340,6 +342,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG { ItemSize(outer_rect); ItemAdd(outer_rect, id); + g.NextWindowData.ClearFlags(); return false; } @@ -415,12 +418,15 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG // Reset scroll if we are reactivating it if ((previous_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0) - if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasScroll) == 0) + if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasScroll) == 0) SetNextWindowScroll(ImVec2(0.0f, 0.0f)); // Create scrolling region (without border and zero window padding) - ImGuiWindowFlags child_window_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None; - BeginChildEx(name, instance_id, outer_rect.GetSize(), ImGuiChildFlags_None, child_window_flags); + ImGuiChildFlags child_child_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) ? g.NextWindowData.ChildFlags : ImGuiChildFlags_None; + ImGuiWindowFlags child_window_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasWindowFlags) ? g.NextWindowData.WindowFlags : ImGuiWindowFlags_None; + if (flags & ImGuiTableFlags_ScrollX) + child_window_flags |= ImGuiWindowFlags_HorizontalScrollbar; + BeginChildEx(name, instance_id, outer_rect.GetSize(), child_child_flags, child_window_flags); table->InnerWindow = g.CurrentWindow; table->WorkRect = table->InnerWindow->WorkRect; table->OuterRect = table->InnerWindow->Rect(); @@ -573,6 +579,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG // Initialize table->SettingsOffset = -1; table->IsSortSpecsDirty = true; + table->IsSettingsDirty = true; // Records itself into .ini file even when in default state (#7934) table->InstanceInteracted = -1; table->ContextPopupColumn = -1; table->ReorderColumn = table->ResizedColumn = table->LastResizedColumn = -1; @@ -972,7 +979,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) // [Part 4] Apply final widths based on requested widths const ImRect work_rect = table->WorkRect; const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1); - const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synched tables with mismatching scrollbar state (#5920) + const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synced tables with mismatching scrollbar state (#5920) const float width_avail = ImMax(1.0f, (((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth()) - width_removed); const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests; float width_remaining_for_stretched_columns = width_avail_for_stretched_columns; @@ -1385,7 +1392,7 @@ void ImGui::EndTable() // Setup inner scrolling range // FIXME: This ideally should be done earlier, in BeginTable() SetNextWindowContentSize call, just like writing to inner_window->DC.CursorMaxPos.y, - // but since the later is likely to be impossible to do we'd rather update both axises together. + // but since the later is likely to be impossible to do we'd rather update both axes together. if (table->Flags & ImGuiTableFlags_ScrollX) { const float outer_padding_for_border = (table->Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f; @@ -1560,6 +1567,31 @@ void ImGui::EndTable() NavUpdateCurrentWindowIsScrollPushableX(); } +// Called in TableSetupColumn() when initializing and in TableLoadSettings() for defaults before applying stored settings. +// 'init_mask' specify which fields to initialize. +static void TableInitColumnDefaults(ImGuiTable* table, ImGuiTableColumn* column, ImGuiTableColumnFlags init_mask) +{ + ImGuiTableColumnFlags flags = column->Flags; + if (init_mask & ImGuiTableFlags_Resizable) + { + float init_width_or_weight = column->InitStretchWeightOrWidth; + column->WidthRequest = ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f; + column->StretchWeight = (init_width_or_weight > 0.0f && (flags & ImGuiTableColumnFlags_WidthStretch)) ? init_width_or_weight : -1.0f; + if (init_width_or_weight > 0.0f) // Disable auto-fit if an explicit width/weight has been specified + column->AutoFitQueue = 0x00; + } + if (init_mask & ImGuiTableFlags_Reorderable) + column->DisplayOrder = (ImGuiTableColumnIdx)table->Columns.index_from_ptr(column); + if (init_mask & ImGuiTableFlags_Hideable) + column->IsUserEnabled = column->IsUserEnabledNextFrame = (flags & ImGuiTableColumnFlags_DefaultHide) ? 0 : 1; + if (init_mask & ImGuiTableFlags_Sortable) + { + // Multiple columns using _DefaultSort will be reassigned unique SortOrder values when building the sort specs. + column->SortOrder = (flags & ImGuiTableColumnFlags_DefaultSort) ? 0 : -1; + column->SortDirection = (flags & ImGuiTableColumnFlags_DefaultSort) ? ((flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending)) : (ImS8)ImGuiSortDirection_None; + } +} + // See "COLUMNS SIZING POLICIES" comments at the top of this file // If (init_width_or_weight <= 0.0f) it is ignored void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id) @@ -1588,7 +1620,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitly in either Table or Column."); // When passing a width automatically enforce WidthFixed policy - // (whereas TableSetupColumnFlags would default to WidthAuto if table is not Resizable) + // (whereas TableSetupColumnFlags would default to WidthAuto if table is not resizable) if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f) if ((table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedFit || (table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame) flags |= ImGuiTableColumnFlags_WidthFixed; @@ -1606,27 +1638,10 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo column->InitStretchWeightOrWidth = init_width_or_weight; if (table->IsInitializing) { - // Init width or weight + ImGuiTableFlags init_flags = ~table->SettingsLoadedFlags; if (column->WidthRequest < 0.0f && column->StretchWeight < 0.0f) - { - if ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f) - column->WidthRequest = init_width_or_weight; - if (flags & ImGuiTableColumnFlags_WidthStretch) - column->StretchWeight = (init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f; - - // Disable auto-fit if an explicit width/weight has been specified - if (init_width_or_weight > 0.0f) - column->AutoFitQueue = 0x00; - } - - // Init default visibility/sort state - if ((flags & ImGuiTableColumnFlags_DefaultHide) && (table->SettingsLoadedFlags & ImGuiTableFlags_Hideable) == 0) - column->IsUserEnabled = column->IsUserEnabledNextFrame = false; - if (flags & ImGuiTableColumnFlags_DefaultSort && (table->SettingsLoadedFlags & ImGuiTableFlags_Sortable) == 0) - { - column->SortOrder = 0; // Multiple columns using _DefaultSort will be reassigned unique SortOrder values when building the sort specs. - column->SortDirection = (column->Flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending); - } + init_flags |= ImGuiTableFlags_Resizable; + TableInitColumnDefaults(table, column, init_flags); } // Store name (append with zero-terminator in contiguous buffer) @@ -1635,7 +1650,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo if (label != NULL && label[0] != 0) { column->NameOffset = (ImS16)table->ColumnsNames.size(); - table->ColumnsNames.append(label, label + strlen(label) + 1); + table->ColumnsNames.append(label, label + ImStrlen(label) + 1); } } @@ -2101,7 +2116,11 @@ bool ImGui::TableSetColumnIndex(int column_n) { if (table->CurrentColumn != -1) TableEndCell(table); - IM_ASSERT(column_n >= 0 && table->ColumnsCount); + if ((column_n >= 0 && column_n < table->ColumnsCount) == false) + { + IM_ASSERT_USER_ERROR(column_n >= 0 && column_n < table->ColumnsCount, "TableSetColumnIndex() invalid column index!"); + return false; + } TableBeginCell(table, column_n); } @@ -3714,6 +3733,14 @@ void ImGui::TableLoadSettings(ImGuiTable* table) table->SettingsLoadedFlags = settings->SaveFlags; table->RefScale = settings->RefScale; + // Initialize default columns settings + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImGuiTableColumn* column = &table->Columns[column_n]; + TableInitColumnDefaults(table, column, ~0); + column->AutoFitQueue = 0x00; + } + // Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings(); ImU64 display_order_mask = 0; @@ -3730,14 +3757,12 @@ void ImGui::TableLoadSettings(ImGuiTable* table) column->StretchWeight = column_settings->WidthOrWeight; else column->WidthRequest = column_settings->WidthOrWeight; - column->AutoFitQueue = 0x00; } if (settings->SaveFlags & ImGuiTableFlags_Reorderable) column->DisplayOrder = column_settings->DisplayOrder; - else - column->DisplayOrder = (ImGuiTableColumnIdx)column_n; display_order_mask |= (ImU64)1 << column->DisplayOrder; - column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled; + if ((settings->SaveFlags & ImGuiTableFlags_Hideable) && column_settings->IsEnabled != -1) + column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled == 1; column->SortOrder = column_settings->SortOrder; column->SortDirection = column_settings->SortDirection; } @@ -3833,8 +3858,7 @@ static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandle const bool save_visible = (settings->SaveFlags & ImGuiTableFlags_Hideable) != 0; const bool save_order = (settings->SaveFlags & ImGuiTableFlags_Reorderable) != 0; const bool save_sort = (settings->SaveFlags & ImGuiTableFlags_Sortable) != 0; - if (!save_size && !save_visible && !save_order && !save_sort) - continue; + // We need to save the [Table] entry even if all the bools are false, since this records a table with "default settings". buf->reserve(buf->size() + 30 + settings->ColumnsCount * 50); // ballpark reserve buf->appendf("[%s][0x%08X,%d]\n", handler->TypeName, settings->ID, settings->ColumnsCount); diff --git a/3rdparty/imgui/src/imgui_widgets.cpp b/3rdparty/imgui/src/imgui_widgets.cpp index 1e4297fcbd..c997e17b61 100644 --- a/3rdparty/imgui/src/imgui_widgets.cpp +++ b/3rdparty/imgui/src/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.91.8 +// dear imgui, v1.91b // (widgets code) /* @@ -70,6 +70,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok. +#pragma clang diagnostic ignored "-Wformat" // warning: format specifies type 'int' but the argument has type 'unsigned int' #pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness #pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used. @@ -80,6 +81,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type +#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe @@ -169,7 +171,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags) // Calculate length const char* text_begin = text; if (text_end == NULL) - text_end = text + strlen(text); // FIXME-OPT + text_end = text + ImStrlen(text); // FIXME-OPT const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); const float wrap_pos_x = window->DC.TextWrapPos; @@ -209,7 +211,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags) int lines_skipped = 0; while (line < text_end && lines_skipped < lines_skippable) { - const char* line_end = (const char*)memchr(line, '\n', text_end - line); + const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line); if (!line_end) line_end = text_end; if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0) @@ -230,7 +232,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags) if (IsClippedEx(line_rect, 0)) break; - const char* line_end = (const char*)memchr(line, '\n', text_end - line); + const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line); if (!line_end) line_end = text_end; text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x); @@ -245,7 +247,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags) int lines_skipped = 0; while (line < text_end) { - const char* line_end = (const char*)memchr(line, '\n', text_end - line); + const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line); if (!line_end) line_end = text_end; if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0) @@ -913,7 +915,7 @@ ImRect ImGui::GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis) const ImRect outer_rect = window->Rect(); const ImRect inner_rect = window->InnerRect; const float scrollbar_size = window->ScrollbarSizes[axis ^ 1]; // (ScrollbarSizes.x = width of Y scrollbar; ScrollbarSizes.y = height of X scrollbar) - IM_ASSERT(scrollbar_size > 0.0f); + IM_ASSERT(scrollbar_size >= 0.0f); const float border_size = IM_ROUND(window->WindowBorderSize * 0.5f); const float border_top = (window->Flags & ImGuiWindowFlags_MenuBar) ? IM_ROUND(g.Style.FrameBorderSize * 0.5f) : 0.0f; if (axis == ImGuiAxis_X) @@ -971,8 +973,8 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6 // When we are too small, start hiding and disabling the grab (this reduce visual noise on very small window and facilitate using the window resize grab) float alpha = 1.0f; - if ((axis == ImGuiAxis_Y) && bb_frame_height < g.FontSize + g.Style.FramePadding.y * 2.0f) - alpha = ImSaturate((bb_frame_height - g.FontSize) / (g.Style.FramePadding.y * 2.0f)); + if ((axis == ImGuiAxis_Y) && bb_frame_height < bb_frame_width) + alpha = ImSaturate(bb_frame_height / ImMax(bb_frame_width * 2.0f, 1.0f)); if (alpha <= 0.0f) return false; @@ -989,7 +991,8 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6 // But we maintain a minimum size in pixel to allow for the user to still aim inside. IM_ASSERT(ImMax(size_contents_v, size_visible_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers. const ImS64 win_size_v = ImMax(ImMax(size_contents_v, size_visible_v), (ImS64)1); - const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_visible_v / (float)win_size_v), style.GrabMinSize, scrollbar_size_v); + const float grab_h_minsize = ImMin(bb.GetSize()[axis], style.GrabMinSize); + const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_visible_v / (float)win_size_v), grab_h_minsize, scrollbar_size_v); const float grab_h_norm = grab_h_pixels / scrollbar_size_v; // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). @@ -1061,25 +1064,45 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6 // - Read about ImTextureID here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples // - 'uv0' and 'uv1' are texture coordinates. Read about them from the same link above. -void ImGui::Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col) +void ImGui::ImageWithBg(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col) { + ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return; - const float border_size = (border_col.w > 0.0f) ? 1.0f : 0.0f; - const ImVec2 padding(border_size, border_size); + const ImVec2 padding(g.Style.ImageBorderSize, g.Style.ImageBorderSize); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + image_size + padding * 2.0f); ItemSize(bb); if (!ItemAdd(bb, 0)) return; // Render - if (border_size > 0.0f) - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(border_col), 0.0f, ImDrawFlags_None, border_size); + if (g.Style.ImageBorderSize > 0.0f) + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border), 0.0f, ImDrawFlags_None, g.Style.ImageBorderSize); + if (bg_col.w > 0.0f) + window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col)); window->DrawList->AddImage(user_texture_id, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col)); } +void ImGui::Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1) +{ + ImageWithBg(user_texture_id, image_size, uv0, uv1); +} + +// 1.91.9 (February 2025) removed 'tint_col' and 'border_col' parameters, made border size not depend on color value. (#8131, #8238) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +void ImGui::Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col) +{ + ImGuiContext& g = *GImGui; + PushStyleVar(ImGuiStyleVar_ImageBorderSize, (border_col.w > 0.0f) ? ImMax(1.0f, g.Style.ImageBorderSize) : 0.0f); // Preserve legacy behavior where border is always visible when border_col's Alpha is >0.0f + PushStyleColor(ImGuiCol_Border, border_col); + ImageWithBg(user_texture_id, image_size, uv0, uv1, ImVec4(0, 0, 0, 0), tint_col); + PopStyleColor(); + PopStyleVar(); +} +#endif + bool ImGui::ImageButtonEx(ImGuiID id, ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags) { ImGuiContext& g = *GImGui; @@ -1423,7 +1446,7 @@ bool ImGui::TextLink(const char* label) const ImGuiID id = window->GetID(label); const char* label_end = FindRenderedTextEnd(label); - ImVec2 pos = window->DC.CursorPos; + ImVec2 pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); ImVec2 size = CalcTextSize(label, label_end, true); ImRect bb(pos, pos + size); ItemSize(size, 0.0f); @@ -1828,7 +1851,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - ImGuiNextWindowDataFlags backup_next_window_data_flags = g.NextWindowData.Flags; + ImGuiNextWindowDataFlags backup_next_window_data_flags = g.NextWindowData.HasFlags; g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values if (window->SkipItems) return false; @@ -1897,7 +1920,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF if (!popup_open) return false; - g.NextWindowData.Flags = backup_next_window_data_flags; + g.NextWindowData.HasFlags = backup_next_window_data_flags; return BeginComboPopup(popup_id, bb, flags); } @@ -1912,7 +1935,7 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags // Set popup size float w = bb.GetWidth(); - if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint) + if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSizeConstraint) { g.NextWindowData.SizeConstraintRect.Min.x = ImMax(g.NextWindowData.SizeConstraintRect.Min.x, w); } @@ -1926,9 +1949,9 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags else if (flags & ImGuiComboFlags_HeightSmall) popup_max_height_in_items = 4; else if (flags & ImGuiComboFlags_HeightLarge) popup_max_height_in_items = 20; ImVec2 constraint_min(0.0f, 0.0f), constraint_max(FLT_MAX, FLT_MAX); - if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.x <= 0.0f) // Don't apply constraints if user specified a size + if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.x <= 0.0f) // Don't apply constraints if user specified a size constraint_min.x = w; - if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.y <= 0.0f) + if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.y <= 0.0f) constraint_max.y = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items); SetNextWindowSizeConstraints(constraint_min, constraint_max); } @@ -2043,7 +2066,7 @@ static const char* Items_SingleStringGetter(void* data, int idx) { if (idx == items_count) break; - p += strlen(p) + 1; + p += ImStrlen(p) + 1; items_count++; } return *p ? p : NULL; @@ -2060,7 +2083,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* (*getter)(vo preview_value = getter(user_data, *current_item); // The old Combo() API exposed "popup_max_height_in_items". The new more general BeginCombo() API doesn't have/need it, but we emulate it here. - if (popup_max_height_in_items != -1 && !(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint)) + if (popup_max_height_in_items != -1 && !(g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasSizeConstraint)) SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); if (!BeginCombo(label, preview_value, ImGuiComboFlags_None)) @@ -2111,7 +2134,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open while (*p) { - p += strlen(p) + 1; + p += ImStrlen(p) + 1; items_count++; } bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items); @@ -2621,7 +2644,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id); if (!temp_input_is_active) { - // Tabbing or CTRL-clicking on Drag turns it into an InputText + // Tabbing or CTRL+click on Drag turns it into an InputText const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id); const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2 && TestKeyOwner(ImGuiKey_MouseLeft, id)); const bool make_active = (clicked || double_clicked || g.NavActivateId == id); @@ -3225,7 +3248,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id); if (!temp_input_is_active) { - // Tabbing or CTRL-clicking on Slider turns it into an input box + // Tabbing or CTRL+click on Slider turns it into an input box const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id); const bool make_active = (clicked || g.NavActivateId == id); if (make_active && clicked) @@ -3878,7 +3901,7 @@ static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** line_count++; if (s_eol == NULL) { - s = s + strlen(s); + s = s + ImStrlen(s); break; } s = s_eol + 1; @@ -4166,7 +4189,7 @@ void ImGuiInputTextState::OnCharPressed(unsigned int c) // The changes we had to make to stb_textedit_key made it very much UTF-8 specific which is not too great. char utf8[5]; ImTextCharToUtf8(utf8, c); - stb_textedit_text(this, Stb, utf8, (int)strlen(utf8)); + stb_textedit_text(this, Stb, utf8, (int)ImStrlen(utf8)); CursorFollow = true; CursorAnimReset(); } @@ -4217,7 +4240,7 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons // Grow internal buffer if needed const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0; - const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text); + const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)ImStrlen(new_text); if (new_text_len + BufTextLen >= BufSize) { if (!is_resizable) @@ -4251,7 +4274,7 @@ void ImGui::PushPasswordFont() ImGuiContext& g = *GImGui; ImFont* in_font = g.Font; ImFont* out_font = &g.InputTextPasswordFont; - const ImFontGlyph* glyph = in_font->FindGlyph('*'); + ImFontGlyph* glyph = in_font->FindGlyph('*'); out_font->FontSize = in_font->FontSize; out_font->Scale = in_font->Scale; out_font->Ascent = in_font->Ascent; @@ -4273,7 +4296,13 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im if (c < 0x20) { bool pass = false; - pass |= (c == '\n') && (flags & ImGuiInputTextFlags_Multiline) != 0; // Note that an Enter KEY will emit \r and be ignored (we poll for KEY in InputText() code) + pass |= (c == '\n') && (flags & ImGuiInputTextFlags_Multiline) != 0; // Note that an Enter KEY will emit \r and be ignored (we poll for KEY in InputText() code) + if (c == '\n' && input_source_is_clipboard && (flags & ImGuiInputTextFlags_Multiline) == 0) // In single line mode, replace \n with a space + { + c = *p_char = ' '; + pass = true; + } + pass |= (c == '\n') && (flags & ImGuiInputTextFlags_Multiline) != 0; pass |= (c == '\t') && (flags & ImGuiInputTextFlags_AllowTabInput) != 0; if (!pass) return false; @@ -4539,7 +4568,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ const bool init_state = (init_make_active || user_scroll_active); if (init_reload_from_user_buf) { - int new_len = (int)strlen(buf); + int new_len = (int)ImStrlen(buf); IM_ASSERT(new_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?"); state->WantReloadUserBuf = false; InputTextReconcileUndoState(state, state->TextA.Data, state->TextLen, buf, new_len); @@ -4561,7 +4590,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Take a copy of the initial buffer value. // From the moment we focused we are normally ignoring the content of 'buf' (unless we are in read-only mode) - const int buf_len = (int)strlen(buf); + const int buf_len = (int)ImStrlen(buf); IM_ASSERT(buf_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?"); state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string. memcpy(state->TextToRevertTo.Data, buf, buf_len + 1); @@ -4646,7 +4675,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Read-only mode always ever read from source buffer. Refresh TextLen when active. if (is_readonly && state != NULL) - state->TextLen = (int)strlen(buf); + state->TextLen = (int)ImStrlen(buf); //if (is_readonly && state != NULL) // state->TextA.clear(); // Uncomment to facilitate debugging, but we otherwise prefer to keep/amortize th allocation. } @@ -4669,7 +4698,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Select the buffer to render. const bool buf_display_from_state = (render_cursor || render_selection || g.ActiveId == id) && !is_readonly && state; - const bool is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0); + bool is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0); // Password pushes a temporary font with only a fallback glyph if (is_password && !is_displaying_hint) @@ -4803,14 +4832,14 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl const bool is_startend_key_down = is_osx && io.KeyCtrl && !io.KeySuper && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End - // Using Shortcut() with ImGuiInputFlags_RouteFocused (default policy) to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: formet would be handled by InputText) + // Using Shortcut() with ImGuiInputFlags_RouteFocused (default policy) to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: former would be handled by InputText) // Otherwise we could simply assume that we own the keys as we are active. const ImGuiInputFlags f_repeat = ImGuiInputFlags_Repeat; const bool is_cut = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_X, f_repeat, id) || Shortcut(ImGuiMod_Shift | ImGuiKey_Delete, f_repeat, id)) && !is_readonly && !is_password && (!is_multiline || state->HasSelection()); const bool is_copy = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_C, 0, id) || Shortcut(ImGuiMod_Ctrl | ImGuiKey_Insert, 0, id)) && !is_password && (!is_multiline || state->HasSelection()); const bool is_paste = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_V, f_repeat, id) || Shortcut(ImGuiMod_Shift | ImGuiKey_Insert, f_repeat, id)) && !is_readonly; const bool is_undo = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_Z, f_repeat, id)) && !is_readonly && is_undoable; - const bool is_redo = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_Y, f_repeat, id) || (is_osx && Shortcut(ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Z, f_repeat, id))) && !is_readonly && is_undoable; + const bool is_redo = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_Y, f_repeat, id) || Shortcut(ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Z, f_repeat, id)) && !is_readonly && is_undoable; const bool is_select_all = Shortcut(ImGuiMod_Ctrl | ImGuiKey_A, 0, id); // We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful. @@ -4925,7 +4954,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (const char* clipboard = GetClipboardText()) { // Filter pasted buffer - const int clipboard_len = (int)strlen(clipboard); + const int clipboard_len = (int)ImStrlen(clipboard); ImVector clipboard_filtered; clipboard_filtered.reserve(clipboard_len + 1); for (const char* s = clipboard; *s != 0; ) @@ -4937,7 +4966,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ continue; char c_utf8[5]; ImTextCharToUtf8(c_utf8, c); - int out_len = (int)strlen(c_utf8); + int out_len = (int)ImStrlen(c_utf8); clipboard_filtered.resize(clipboard_filtered.Size + out_len); memcpy(clipboard_filtered.Data + clipboard_filtered.Size - out_len, c_utf8, out_len); } @@ -5067,7 +5096,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (buf_dirty) { // Callback may update buffer and thus set buf_dirty even in read-only mode. - IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text! + IM_ASSERT(callback_data.BufTextLen == (int)ImStrlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text! InputTextReconcileUndoState(state, state->CallbackTextBackup.Data, state->CallbackTextBackup.Size - 1, callback_data.Buf, callback_data.BufTextLen); state->TextLen = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen() state->CursorAnimReset(); @@ -5151,10 +5180,22 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ const int buf_display_max_length = 2 * 1024 * 1024; const char* buf_display = buf_display_from_state ? state->TextA.Data : buf; //-V595 const char* buf_display_end = NULL; // We have specialized paths below for setting the length + + // Display hint when contents is empty + // At this point we need to handle the possibility that a callback could have modified the underlying buffer (#8368) + const bool new_is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0); + if (new_is_displaying_hint != is_displaying_hint) + { + if (is_password && !is_displaying_hint) + PopFont(); + is_displaying_hint = new_is_displaying_hint; + if (is_password && !is_displaying_hint) + PushPasswordFont(); + } if (is_displaying_hint) { buf_display = hint; - buf_display_end = hint + strlen(hint); + buf_display_end = hint + ImStrlen(hint); } // Render text. We currently only render selection when the widget is active or while scrolling. @@ -5187,7 +5228,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ int line_count = 1; if (is_multiline) { - for (const char* s = text_begin; (s = (const char*)memchr(s, '\n', (size_t)(text_end - s))) != NULL; s++) + for (const char* s = text_begin; (s = (const char*)ImMemchr(s, '\n', (size_t)(text_end - s))) != NULL; s++) { if (cursor_line_no == -1 && s >= cursor_ptr) { cursor_line_no = line_count; } if (selmin_line_no == -1 && s >= selmin_ptr) { selmin_line_no = line_count; } @@ -5265,7 +5306,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ break; if (rect_pos.y < clip_rect.y) { - p = (const char*)memchr((void*)p, '\n', text_selected_end - p); + p = (const char*)ImMemchr((void*)p, '\n', text_selected_end - p); p = p ? p + 1 : text_selected_end; } else @@ -5317,7 +5358,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ else if (!is_displaying_hint && g.ActiveId == id) buf_display_end = buf_display + state->TextLen; else if (!is_displaying_hint) - buf_display_end = buf_display + strlen(buf_display); + buf_display_end = buf_display + ImStrlen(buf_display); if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length) { @@ -5462,7 +5503,7 @@ static void ColorEditRestoreHS(const float* col, float* H, float* S, float* V) // Edit colors components (each component in 0.0f..1.0f range). // See enum ImGuiColorEditFlags_ for available options. e.g. Only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. -// With typical options: Left-click on color square to open color picker. Right-click to open option menu. CTRL-Click over input fields to edit them and TAB to go to next item. +// With typical options: Left-click on color square to open color picker. Right-click to open option menu. CTRL+Click over input fields to edit them and TAB to go to next item. bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags) { ImGuiWindow* window = GetCurrentWindow(); @@ -6166,7 +6207,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl if (g.Style.FrameBorderSize > 0.0f) RenderFrameBorder(bb.Min, bb.Max, rounding); else - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color buttons are often in need of some sort of border } // Drag and Drop Source @@ -7088,7 +7129,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl // Text stays at the submission position. Alignment/clipping extents ignore SpanAllColumns. if (is_visible) - RenderTextClipped(pos, ImVec2(window->WorkRect.Max.x, pos.y + size.y), label, NULL, &label_size, style.SelectableTextAlign, &bb); + RenderTextClipped(pos, ImVec2(ImMin(pos.x + size.x, window->WorkRect.Max.x), pos.y + size.y), label, NULL, &label_size, style.SelectableTextAlign, &bb); // Automatically close popups if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_NoAutoClosePopups) && (g.LastItemData.ItemFlags & ImGuiItemFlags_AutoClosePopups)) @@ -7151,7 +7192,7 @@ ImGuiTypingSelectRequest* ImGui::GetTypingSelectRequest(ImGuiTypingSelectFlags f // Append to buffer const int buffer_max_len = IM_ARRAYSIZE(data->SearchBuffer) - 1; - int buffer_len = (int)strlen(data->SearchBuffer); + int buffer_len = (int)ImStrlen(data->SearchBuffer); bool select_request = false; for (ImWchar w : g.IO.InputQueueCharacters) { @@ -8834,7 +8875,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) if (g.MenusIdSubmittedThisFrame.contains(id)) { if (menu_is_open) - menu_is_open = BeginPopupEx(id, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + menu_is_open = BeginPopupMenuEx(id, label, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) else g.NextWindowData.ClearFlags(); // we behave like Begin() and need to consume those values return menu_is_open; @@ -8865,7 +8906,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_NoAutoClosePopups; if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { - // Menu inside an horizontal menu bar + // Menu inside a horizontal menu bar // Selectable extend their highlight by half ItemSpacing in each direction. // For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin() popup_pos = ImVec2(pos.x - 1.0f - IM_TRUNC(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight); @@ -8996,7 +9037,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) ImGuiLastItemData last_item_in_parent = g.LastItemData; SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: misleading: the value will serve as reference for FindBestWindowPosForPopup(), not actual pos. PushStyleVar(ImGuiStyleVar_ChildRounding, style.PopupRounding); // First level will use _PopupRounding, subsequent will use _ChildRounding - menu_is_open = BeginPopupEx(id, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + menu_is_open = BeginPopupMenuEx(id, label, window_flags); // menu_is_open may be 'false' when the popup is completely clipped (e.g. zero size display) PopStyleVar(); if (menu_is_open) { @@ -10078,7 +10119,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, else { tab->NameOffset = (ImS32)tab_bar->TabsNames.size(); - tab_bar->TabsNames.append(label, label + strlen(label) + 1); + tab_bar->TabsNames.append(label, label + ImStrlen(label) + 1); } // Update selected tab @@ -10355,13 +10396,24 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, // 'g.ActiveId==close_button_id' will be true when we are holding on the close button, in which case both hovered booleans are false bool close_button_pressed = false; bool close_button_visible = false; - if (close_button_id != 0) - if (is_contents_visible || bb.GetWidth() >= ImMax(button_sz, g.Style.TabMinWidthForCloseButton)) - if (g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == tab_id || g.ActiveId == close_button_id) - close_button_visible = true; - bool unsaved_marker_visible = (flags & ImGuiTabItemFlags_UnsavedDocument) != 0 && (button_pos.x + button_sz <= bb.Max.x); + bool is_hovered = g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == tab_id || g.ActiveId == close_button_id; // Any interaction account for this too. - if (close_button_visible) + if (close_button_id != 0) + { + if (is_contents_visible) + close_button_visible = (g.Style.TabCloseButtonMinWidthSelected < 0.0f) ? true : (is_hovered && bb.GetWidth() >= ImMax(button_sz, g.Style.TabCloseButtonMinWidthSelected)); + else + close_button_visible = (g.Style.TabCloseButtonMinWidthUnselected < 0.0f) ? true : (is_hovered && bb.GetWidth() >= ImMax(button_sz, g.Style.TabCloseButtonMinWidthUnselected)); + } + + // When tabs/document is unsaved, the unsaved marker takes priority over the close button. + const bool unsaved_marker_visible = (flags & ImGuiTabItemFlags_UnsavedDocument) != 0 && (button_pos.x + button_sz <= bb.Max.x) && (!close_button_visible || !is_hovered); + if (unsaved_marker_visible) + { + const ImRect bullet_bb(button_pos, button_pos + ImVec2(button_sz, button_sz)); + RenderBullet(draw_list, bullet_bb.GetCenter(), GetColorU32(ImGuiCol_Text)); + } + else if (close_button_visible) { ImGuiLastItemData last_item_backup = g.LastItemData; if (CloseButton(close_button_id, button_pos)) @@ -10369,14 +10421,9 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, g.LastItemData = last_item_backup; // Close with middle mouse button - if (!(flags & ImGuiTabItemFlags_NoCloseWithMiddleMouseButton) && IsMouseClicked(2)) + if (is_hovered && !(flags & ImGuiTabItemFlags_NoCloseWithMiddleMouseButton) && IsMouseClicked(2)) close_button_pressed = true; } - else if (unsaved_marker_visible) - { - const ImRect bullet_bb(button_pos, button_pos + ImVec2(button_sz, button_sz)); - RenderBullet(draw_list, bullet_bb.GetCenter(), GetColorU32(ImGuiCol_Text)); - } // This is all rather complicated // (the main idea is that because the close button only appears on hover, we don't want it to alter the ellipsis position) diff --git a/bin/docs/ThirdPartyLicenses.html b/bin/docs/ThirdPartyLicenses.html index c52ebf5a8e..c8e5434196 100644 --- a/bin/docs/ThirdPartyLicenses.html +++ b/bin/docs/ThirdPartyLicenses.html @@ -1221,43 +1221,32 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -

libjpeg - https://ijg.org/

+

libjpeg-turbo - https://github.com/libjpeg-turbo/libjpeg-turbo/

-The authors make NO WARRANTY or representation, either express or implied,
-with respect to this software, its quality, accuracy, merchantability, or
-fitness for a particular purpose.  This software is provided "AS IS", and you,
-its user, assume the entire risk as to its quality and accuracy.
+Copyright (C)2009-2024 D. R. Commander. All Rights Reserved.
+Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
 
-This software is copyright (C) 1991-2024, Thomas G. Lane, Guido Vollbeding.
-All Rights Reserved except as specified below.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
 
-Permission is hereby granted to use, copy, modify, and distribute this
-software (or portions thereof) for any purpose, without fee, subject to these
-conditions:
-(1) If any part of the source code for this software is distributed, then this
-README file must be included, with this copyright and no-warranty notice
-unaltered; and any additions, deletions, or changes to the original files
-must be clearly indicated in accompanying documentation.
-(2) If only executable code is distributed, then the accompanying
-documentation must state that "this software is based in part on the work of
-the Independent JPEG Group".
-(3) Permission for use of this software is granted only if the user accepts
-full responsibility for any undesirable consequences; the authors accept
-NO LIABILITY for damages of any kind.
+Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list
+of conditions and the following disclaimer in the documentation and/or other materials
+provided with the distribution. Neither the name of the libjpeg-turbo Project nor the
+names of its contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
 
-These conditions apply to any software derived from or based on the IJG code,
-not just to the unmodified library.  If you use our work, you ought to
-acknowledge us.
-
-Permission is NOT granted for the use of any IJG author's name or company name
-in advertising or publicity relating to this software or products derived from
-it.  This software may be referred to only as "the Independent JPEG Group's
-software".
-
-We specifically permit and encourage the use of this software as the basis of
-commercial products, provided that all warranty or liability claims are
-assumed by the product vendor.
-
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

LLVM - https://github.com/llvm/llvm-project

                                 Apache License
diff --git a/bin/resources/GameIndex.yaml b/bin/resources/GameIndex.yaml
index 74b4d71513..13f27b7b7a 100644
--- a/bin/resources/GameIndex.yaml
+++ b/bin/resources/GameIndex.yaml
@@ -174,9 +174,8 @@ PAPX-90020:
     recommendedBlendingLevel: 4 # Improves banding and effect emulation.
     autoFlush: 1 # Fixes light bloom intensity.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
-    halfPixelOffset: 4 # Aligns post effects.
+    halfPixelOffset: 2 # Aligns post effects.
     nativeScaling: 1 # Fixes post effects.
-    getSkipCount: "GSC_GiTS"
 PAPX-90201:
   name: "ファンタビジョン [体験版]"
   name-sort: "ふぁんたびじょん [たいけんばん]"
@@ -524,7 +523,7 @@ PAPX-90524:
   region: "NTSC-J"
   gsHWFixes:
     roundSprite: 1 # Fixes font sizes and lines in UI.
-    cpuFramebufferConversion: 1 # Fixes sepia-tone flashback sequences.
+    textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
     forceEvenSpritePosition: 1 # Fixes font artifacts and out-of-bound 2D textures.
     gpuPaletteConversion: 2 # Fixes micro-stuttering and reduces HC size.
 PBGP-0061:
@@ -1250,27 +1249,32 @@ SCAJ-10011:
   region: "NTSC-Unk"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SCAJ-10012:
   name: "Taiko Drum Master"
   region: "NTSC-Unk"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SCAJ-10013:
   name: "Taiko no Tatsujin - Tobikkiri! Anime Special"
   region: "NTSC-Unk"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SCAJ-10014:
   name: "Taiko no Tatsujin - Wai Wai Happy! Rokudaime"
   region: "NTSC-Unk"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SCAJ-10015:
   name: "Taiko no Tatsujin - Doka! to Oomori Nanadaime"
   region: "NTSC-Unk"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
-    getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
+    textureInsideRT: 1 # Fixes post effects.
+    getSkipCount: "GSC_NamcoGames" # Fixes upscaling grid, same engine.
 SCAJ-20001:
   name: "Ratchet & Clank"
   region: "NTSC-Unk"
@@ -1330,7 +1334,6 @@ SCAJ-20010:
   region: "NTSC-Unk"
   gsHWFixes:
     textureInsideRT: 1 # Fixes inside RT shuffling.
-    getSkipCount: "GSC_BigMuthaTruckers"
 SCAJ-20011:
   name: "Armored Core 3 - Silent Line"
   region: "NTSC-HK"
@@ -1395,6 +1398,8 @@ SCAJ-20020:
     texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
     mergeSprite: 1 # Fixes misaligned white lines.
     PCRTCOverscan: 1 # Fixes missing HUD.
+    textureInsideRT: 1 # Fixes post shuffle effect.
+    halfPixelOffset: 2 # Fixes boxes around shuffle effect pages.
 SCAJ-20021:
   name: "Metal Slug 3"
   region: "NTSC-Unk"
@@ -1408,6 +1413,8 @@ SCAJ-20023:
   region: "NTSC-Unk"
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
 SCAJ-20024:
@@ -1511,6 +1518,8 @@ SCAJ-20047:
   region: "NTSC-Unk"
   gsHWFixes:
     texturePreloading: 0 # Performs much better with no preload.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
 SCAJ-20048:
   name: "R:RACING EVOLUTION"
   name-sort: "Rれーしんぐえぼりゅーしょん"
@@ -1560,6 +1569,8 @@ SCAJ-20060:
   region: "NTSC-Unk"
   gsHWFixes:
     texturePreloading: 0 # Performs much better with no preload.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
 SCAJ-20061:
   name: "Seven Samurai 20XX"
   region: "NTSC-Unk"
@@ -1631,9 +1642,9 @@ SCAJ-20072:
     recommendedBlendingLevel: 4 # Improves banding and effect emulation.
     autoFlush: 1 # Fixes light bloom intensity.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
-    halfPixelOffset: 4 # Aligns post effects.
+    halfPixelOffset: 2 # Aligns post effects.
     nativeScaling: 1 # Fixes post effects.
-    getSkipCount: "GSC_GiTS"
+    textureInsideRT: 1 # Fixes post shuffles.
 SCAJ-20073:
   name: "Jak and Daxter II"
   region: "NTSC-Unk"
@@ -1654,7 +1665,7 @@ SCAJ-20076:
   name: "Armored Core - Nexus [Disc 1]"
   region: "NTSC-Unk"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SCAJ-20076"
@@ -1667,7 +1678,7 @@ SCAJ-20077:
   name: "Armored Core - Nexus [Disc 2]"
   region: "NTSC-Unk"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SCAJ-20076"
@@ -1826,7 +1837,7 @@ SCAJ-20105:
   name: "Armored Core - Nine Breaker"
   region: "NTSC-Unk"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
     cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
     cpuSpriteRenderLevel: 2 # Needed for above.
@@ -1899,9 +1910,8 @@ SCAJ-20116:
   region: "NTSC-C-J"
   gsHWFixes:
     alignSprite: 1 # Fixes FMV lines.
-    cpuSpriteRenderBW: 2 # Prevents Death By VRAM explosion.
-    cpuSpriteRenderLevel: 2 # Needed for above.
-    getSkipCount: "GSC_DeathByDegreesTekkenNinaWilliams"
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
+    textureInsideRT: 1 # Fixes post shuffles.
 SCAJ-20117:
   name: "Fu-un Bakumatsu-den"
   region: "NTSC-Unk"
@@ -1941,9 +1951,7 @@ SCAJ-20121:
   name: "Armored Core - Formula Front"
   region: "NTSC-Unk"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
-    cpuSpriteRenderBW: 1 # Fixes broken shadow caused by HPO 1.
-    cpuSpriteRenderLevel: 2 # Needed for above.
+    halfPixelOffset: 5 # Fixes misaligned blur.
 SCAJ-20122:
   name: "Swords of Destiny"
   region: "NTSC-Unk"
@@ -1975,20 +1983,22 @@ SCAJ-20125:
   clampModes:
     eeClampMode: 2 # Fixes camera and stops constant coin noises on Pirates Cove.
   gsHWFixes:
+    textureInsideRT: 1 # Fixes heat haze half screen problem.
     alignSprite: 1
     halfPixelOffset: 4 # Align post.
     nativeScaling: 1 # Fixes depth of field effect.
-    getSkipCount: "GSC_Tekken5"
+    getSkipCount: "GSC_NamcoGames"
 SCAJ-20126:
   name: "Tekken 5"
   region: "NTSC-Unk"
   clampModes:
     eeClampMode: 2 # Fixes camera and stops constant coin noises on Pirates Cove.
   gsHWFixes:
+    textureInsideRT: 1 # Fixes heat haze half screen problem.
     alignSprite: 1
     halfPixelOffset: 4 # Align post.
     nativeScaling: 1 # Fixes depth of field effect.
-    getSkipCount: "GSC_Tekken5"
+    getSkipCount: "GSC_NamcoGames"
 SCAJ-20127:
   name: "EyeToy - Play 2 [with Camera]"
   region: "NTSC-Unk"
@@ -2198,10 +2208,11 @@ SCAJ-20158:
 SCAJ-20159:
   name: "SoulCalibur III"
   region: "NTSC-C"
-  gameFixes:
-    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
     nativeScaling: 2 # Fixes misaligned bloom.
@@ -2237,7 +2248,7 @@ SCAJ-20163:
   gsHWFixes:
     halfPixelOffset: 2 # Fixes ghosting.
     autoFlush: 2 # Fixes post lighting.
-    getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
+    getSkipCount: "GSC_NamcoGames" # Fixes upscaling grid, same engine.
 SCAJ-20164:
   name: "Kingdom Hearts II"
   region: "NTSC-Unk"
@@ -2266,15 +2277,15 @@ SCAJ-20167:
     preloadFrameData: 1 # Fixes some missing effects.
 SCAJ-20168:
   name: "Rule of Rose"
-  region: "NTSC-Unk"
-  gsHWFixes:
-    preloadFrameData: 1 # Fixes Black FMV's.
+  region: "NTSC-C"
+  gameFixes:
+    - SoftwareRendererFMVHack # Fixes black FMVs in hardware and hash cache disabling itself.
 SCAJ-20169:
   name: "Dirge of Cerberus - Final Fantasy VII"
   region: "NTSC-Unk"
   gsHWFixes:
     autoFlush: 1 # Fixes lighting.
-    halfPixelOffset: 4 # Fixes ghosting.
+    halfPixelOffset: 5 # Fixes ghosting.
     nativeScaling: 2 # Fixes post processing.
     recommendedBlendingLevel: 4 # Fixes missing light brightness.
 SCAJ-20170:
@@ -2373,7 +2384,7 @@ SCAJ-20183:
   region: "NTSC-J"
   gsHWFixes:
     roundSprite: 1 # Fixes font sizes and lines in UI.
-    cpuFramebufferConversion: 1 # Fixes sepia-tone flashback sequences.
+    textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
     forceEvenSpritePosition: 1 # Fixes font artifacts and out-of-bound 2D textures.
     gpuPaletteConversion: 2 # Fixes micro-stuttering and reduces HC size.
 SCAJ-20184:
@@ -2462,10 +2473,11 @@ SCAJ-20199:
   clampModes:
     eeClampMode: 2 # Fixes camera and stops constant coin noises on Pirates Cove.
   gsHWFixes:
+    textureInsideRT: 1 # Fixes heat haze half screen problem.
     alignSprite: 1
     halfPixelOffset: 4 # Align post.
     nativeScaling: 1 # Fixes depth of field effect.
-    getSkipCount: "GSC_Tekken5"
+    getSkipCount: "GSC_NamcoGames"
 SCAJ-25002:
   name: "Shinobi"
   region: "NTSC-Unk"
@@ -3570,6 +3582,7 @@ SCED-52137:
     autoFlush: 2 # Fixes sun luminosity.
     halfPixelOffset: 2 # Aligns Depth of Field.
     nativeScaling: 2 # Fixes Depth of Field effect.
+    textureInsideRT: 1 # Fixes half screen fog effect.
 SCED-52141:
   name: "WRC 3 [Demo]"
   region: "PAL-E"
@@ -3581,6 +3594,7 @@ SCED-52141:
     autoFlush: 2 # Fixes sun luminosity.
     halfPixelOffset: 2 # Aligns Depth of Field.
     nativeScaling: 2 # Fixes Depth of Field effect.
+    textureInsideRT: 1 # Fixes half screen fog effect.
 SCED-52147:
   name: "EyeToy - Christmas Wishi Washi"
   region: "PAL-E"
@@ -3876,9 +3890,13 @@ SCED-52899:
 SCED-52932:
   name: "Bonus Demo 8"
   region: "PAL-M5"
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes shadows in TOCA Race Driver 2.
 SCED-52933:
   name: "Bonus Demo 8"
   region: "PAL-M5"
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes shadows in TOCA Race Driver 2.
 SCED-52935:
   name: "SingStar Party [Demo]"
   region: "PAL-E"
@@ -3952,6 +3970,8 @@ SCED-52997:
 SCED-53018:
   name: "Bonus Demo 8 (Geu)"
   region: "PAL-G"
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes shadows in TOCA Race Driver 2.
 SCED-53043:
   name: "Magazine Ufficiale PlayStation 2 Speciale Platinum Italia"
   region: "PAL-I"
@@ -4164,10 +4184,11 @@ SCED-53538:
   clampModes:
     eeClampMode: 2 # Fixes camera and stops constant coin noises on Pirates Cove.
   gsHWFixes:
+    textureInsideRT: 1 # Fixes heat haze half screen problem.
     alignSprite: 1
     halfPixelOffset: 4 # Align post.
     nativeScaling: 1 # Fixes depth of field effect.
-    getSkipCount: "GSC_Tekken5"
+    getSkipCount: "GSC_NamcoGames"
 SCED-53611:
   name: "Official PlayStation 2 Magazine - German Kids Special"
   region: "PAL-G"
@@ -4194,10 +4215,11 @@ SCED-53662:
 SCED-53674:
   name: "SoulCalibur III [Demo]"
   region: "PAL-E"
-  gameFixes:
-    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
     nativeScaling: 2 # Fixes misaligned bloom.
@@ -4556,6 +4578,17 @@ SCED-55120:
 SCED-55432:
   name: "Buzz! Junior - Ace Racers [Demo]"
   region: "PAL-M15"
+SCES-00000:
+  name: "Ico [Preview]"
+  region: "PAL-M5"
+  compat: 5
+  clampModes:
+    eeClampMode: 2 # Otherwise freezes in various spots, check full intro.
+    vuClampMode: 1 # Otherwise camera does not focus correctly on main character.
+  gsHWFixes:
+    mipmap: 1
+    halfPixelOffset: 1 # Fixes effect misalignment.
+    moveHandler: "MV_Ico" # Fixes depth buffer post-processing.
 SCES-50000:
   name: "Ridge Racer V"
   region: "PAL-M5"
@@ -4563,8 +4596,7 @@ SCES-50000:
   clampModes:
     vuClampMode: 2 # Fixes texture rendering in the intro.
   gsHWFixes:
-    cpuFramebufferConversion: 1
-    textureInsideRT: 1
+    textureInsideRT: 1 # Fixes post effects
     halfPixelOffset: 2 # Fixes title screen and some intro post processing alignment.
     roundSprite: 1 # Fixes ui and hud alignment.
     gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
@@ -5287,6 +5319,7 @@ SCES-51684:
     autoFlush: 2 # Fixes sun luminosity.
     halfPixelOffset: 2 # Aligns Depth of Field.
     nativeScaling: 2 # Fixes Depth of Field effect.
+    textureInsideRT: 1 # Fixes half screen fog effect.
   patches:
     80802EA9:
       content: |-
@@ -5329,6 +5362,8 @@ SCES-51844:
   region: "PAL-M5"
   gsHWFixes:
     texturePreloading: 0 # Performs much better with no preload.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
 SCES-51895:
   name: "EyeToy - Groove"
   region: "PAL-M11"
@@ -5426,6 +5461,7 @@ SCES-52137:
     autoFlush: 2 # Fixes sun luminosity.
     halfPixelOffset: 2 # Aligns Depth of Field.
     nativeScaling: 2 # Fixes Depth of Field effect.
+    textureInsideRT: 1 # Fixes half screen fog effect.
 SCES-52154:
   name: "EyeToy - Chat"
   region: "PAL-M11"
@@ -5633,9 +5669,8 @@ SCES-52586:
   compat: 5
   gsHWFixes:
     alignSprite: 1 # Fixes FMV lines.
-    cpuSpriteRenderBW: 2 # Prevents Death By VRAM explosion.
-    cpuSpriteRenderLevel: 2 # Needed for above.
-    getSkipCount: "GSC_DeathByDegreesTekkenNinaWilliams"
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
+    textureInsideRT: 1 # Fixes post shuffles.
 SCES-52596:
   name: "This is Football 2005"
   region: "PAL-Unk"
@@ -5655,6 +5690,7 @@ SCES-52684:
     autoFlush: 2 # Fixes sun luminosity.
     halfPixelOffset: 2 # Aligns Depth of Field.
     nativeScaling: 2 # Fixes Depth of Field effect.
+    textureInsideRT: 1 # Fixes half screen fog effect.
 SCES-52748:
   name: "EyeToy - Play 2"
   region: "PAL-M12"
@@ -5735,18 +5771,16 @@ SCES-53053:
   region: "PAL-F-I"
   gsHWFixes:
     alignSprite: 1 # Fixes FMV lines.
-    cpuSpriteRenderBW: 2 # Prevents Death By VRAM explosion.
-    cpuSpriteRenderLevel: 2 # Needed for above.
-    getSkipCount: "GSC_DeathByDegreesTekkenNinaWilliams"
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
+    textureInsideRT: 1 # Fixes post shuffles.
 SCES-53054:
   name: "Death by Degrees"
   region: "PAL-E-G"
   compat: 5
   gsHWFixes:
     alignSprite: 1 # Fixes FMV lines.
-    cpuSpriteRenderBW: 2 # Prevents Death By VRAM explosion.
-    cpuSpriteRenderLevel: 2 # Needed for above.
-    getSkipCount: "GSC_DeathByDegreesTekkenNinaWilliams"
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
+    textureInsideRT: 1 # Fixes post shuffles.
 SCES-53055:
   name: "Eyetoy - Antigrav"
   region: "PAL-M5"
@@ -5789,10 +5823,11 @@ SCES-53202:
   clampModes:
     eeClampMode: 2 # Fixes camera and stops constant coin noises on Pirates Cove.
   gsHWFixes:
+    textureInsideRT: 1 # Fixes heat haze half screen problem.
     alignSprite: 1
     halfPixelOffset: 4 # Align post.
     nativeScaling: 1 # Fixes depth of field effect.
-    getSkipCount: "GSC_Tekken5"
+    getSkipCount: "GSC_NamcoGames"
 SCES-53247:
   name: "WRC Rally Evolved"
   region: "PAL-M8"
@@ -5868,10 +5903,11 @@ SCES-53312:
   name: "SoulCalibur III"
   region: "PAL-M5"
   compat: 5
-  gameFixes:
-    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
     nativeScaling: 2 # Fixes misaligned bloom.
@@ -6514,7 +6550,12 @@ SCES-54941:
   region: "PAL-E"
 SCES-55019:
   name: "Ratchet & Clank - Size Matters"
-  region: "PAL-M5"
+  region: "PAL-M13"
+  gsHWFixes:
+    recommendedBlendingLevel: 4 # Fixes vendor and other bloom.
+    autoFlush: 2 # Fixes missing bloom and shadow definition.
+    halfPixelOffset: 5 # Fixes misaligned bloom.
+    nativeScaling: 2 # Fixes pixelated bloom.
 SCES-55038:
   name: "EyeToy Play - Hero"
   region: "PAL-M15"
@@ -6990,12 +7031,16 @@ SCKA-20015:
   compat: 5
   gsHWFixes:
     texturePreloading: 0 # Performs much better with no preload.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
 SCKA-20016:
   name: "SoulCalibur II"
   region: "NTSC-K"
   compat: 5
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
 SCKA-20017:
@@ -7063,9 +7108,9 @@ SCKA-20027:
     recommendedBlendingLevel: 4 # Improves banding and effect emulation.
     autoFlush: 1 # Fixes light bloom intensity.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
-    halfPixelOffset: 4 # Aligns post effects.
+    halfPixelOffset: 2 # Aligns post effects.
     nativeScaling: 1 # Fixes post effects.
-    getSkipCount: "GSC_GiTS"
+    textureInsideRT: 1 # Fixes post shuffles.
 SCKA-20028:
   name: "Ico [PlayStation2 Big Hit Series]"
   region: "NTSC-K"
@@ -7117,6 +7162,8 @@ SCKA-20034:
   region: "NTSC-K"
   gsHWFixes:
     texturePreloading: 0 # Performs much better with no preload.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
 SCKA-20035:
   name: "Hot Shots Golf 3 [PlayStation 2 Big Hit Series]"
   region: "NTSC-K"
@@ -7147,9 +7194,8 @@ SCKA-20039:
   region: "NTSC-K"
   gsHWFixes:
     alignSprite: 1 # Fixes FMV lines.
-    cpuSpriteRenderBW: 2 # Prevents Death By VRAM explosion.
-    cpuSpriteRenderLevel: 2 # Needed for above.
-    getSkipCount: "GSC_DeathByDegreesTekkenNinaWilliams"
+    halfPixelOffset: 2 # Aligns post effects.
+    textureInsideRT: 1 # Fixes post shuffles.
 SCKA-20040:
   name: "Jak 3"
   region: "NTSC-K"
@@ -7203,7 +7249,7 @@ SCKA-20047:
   name: "Armored Core - Nine Breaker"
   region: "NTSC-K"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
     cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
     cpuSpriteRenderLevel: 2 # Needed for above.
@@ -7235,10 +7281,11 @@ SCKA-20049:
   clampModes:
     eeClampMode: 2 # Fixes camera and stops constant coin noises on Pirates Cove.
   gsHWFixes:
+    textureInsideRT: 1 # Fixes heat haze half screen problem.
     alignSprite: 1
     halfPixelOffset: 4 # Align post.
     nativeScaling: 1 # Fixes depth of field effect.
-    getSkipCount: "GSC_Tekken5"
+    getSkipCount: "GSC_NamcoGames"
 SCKA-20050:
   name: "Tales of Legendia"
   region: "NTSC-K"
@@ -7295,10 +7342,11 @@ SCKA-20059:
   name: "SoulCalibur III"
   region: "NTSC-K"
   compat: 5
-  gameFixes:
-    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
     nativeScaling: 2 # Fixes misaligned bloom.
@@ -7460,10 +7508,11 @@ SCKA-20081:
   clampModes:
     eeClampMode: 2 # Fixes camera and stops constant coin noises on Pirates Cove.
   gsHWFixes:
+    textureInsideRT: 1 # Fixes heat haze half screen problem.
     alignSprite: 1
     halfPixelOffset: 4 # Align post.
     nativeScaling: 1 # Fixes depth of field effect.
-    getSkipCount: "GSC_Tekken5"
+    getSkipCount: "GSC_NamcoGames"
 SCKA-20082:
   name: "Ace Combat 5 - The Unsung War [PlayStation 2 Big Hit Series]"
   region: "NTSC-K"
@@ -7653,6 +7702,8 @@ SCKA-20120:
   gsHWFixes:
     recommendedBlendingLevel: 4 # Fixes vendor and other bloom.
     autoFlush: 2 # Fixes missing bloom and shadow definition.
+    halfPixelOffset: 5 # Fixes misaligned bloom.
+    nativeScaling: 2 # Fixes pixelated bloom.
 SCKA-20124:
   name: "Piposarugetchu 3" # Ape Escape 3
   region: "NTSC-K"
@@ -8639,9 +8690,8 @@ SCPS-15064:
     recommendedBlendingLevel: 4 # Improves banding and effect emulation.
     autoFlush: 1 # Fixes light bloom intensity.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
-    halfPixelOffset: 4 # Aligns post effects.
+    halfPixelOffset: 2 # Aligns post effects.
     nativeScaling: 1 # Fixes post effects.
-    getSkipCount: "GSC_GiTS"
   patches:
     A5768F53:
       content: |-
@@ -8891,8 +8941,8 @@ SCPS-15093:
   name-en: "Rule of Rose"
   region: "NTSC-J"
   compat: 5
-  gsHWFixes:
-    preloadFrameData: 1 # Fixes Black FMV's.
+  gameFixes:
+    - SoftwareRendererFMVHack # Fixes black FMVs in hardware and hash cache disabling itself.
 SCPS-15094:
   name: "アイトーイ プレイ2 [ソフト単体]"
   name-sort: "あいとーい ぷれい2 [そふとたんたい]"
@@ -9133,7 +9183,7 @@ SCPS-15118:
   region: "NTSC-J"
   gsHWFixes:
     roundSprite: 1 # Fixes font sizes and lines in UI.
-    cpuFramebufferConversion: 1 # Fixes sepia-tone flashback sequences.
+    textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
     forceEvenSpritePosition: 1 # Fixes font artifacts and out-of-bound 2D textures.
     gpuPaletteConversion: 2 # Fixes micro-stuttering and reduces HC size.
 SCPS-15119:
@@ -9834,7 +9884,7 @@ SCPS-19333:
   region: "NTSC-J"
   gsHWFixes:
     roundSprite: 1 # Fixes font sizes and lines in UI.
-    cpuFramebufferConversion: 1 # Fixes sepia-tone flashback sequences.
+    textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
     forceEvenSpritePosition: 1 # Fixes font artifacts and out-of-bound 2D textures.
     gpuPaletteConversion: 2 # Fixes micro-stuttering and reduces HC size.
 SCPS-19335:
@@ -12436,6 +12486,8 @@ SCUS-97615:
   gsHWFixes:
     recommendedBlendingLevel: 4 # Fixes vendor and other bloom.
     autoFlush: 2 # Fixes missing bloom and shadow definition.
+    halfPixelOffset: 5 # Fixes misaligned bloom.
+    nativeScaling: 2 # Fixes pixelated bloom.
 SCUS-97616:
   name: "SingStar '80s"
   region: "NTSC-U"
@@ -13156,6 +13208,8 @@ SLED-51901:
   region: "PAL-E"
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
 SLED-51902:
@@ -13245,8 +13299,9 @@ SLED-52441:
   speedHacks:
     mtvu: 0
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes depth line.
+    halfPixelOffset: 5 # Fixes depth line.
     textureInsideRT: 1 # Fixes shadow and sky rendering.
+    nativeScaling: 2 # Fixes light rays.
     deinterlace: 9 # Any other method causes very bad lines on movement of the camera.
 SLED-52473:
   name: "Transformers - Optimus Prime [Demo]"
@@ -13256,8 +13311,9 @@ SLED-52473:
   speedHacks:
     mtvu: 0
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes depth line.
+    halfPixelOffset: 5 # Fixes depth line.
     textureInsideRT: 1 # Fixes shadow and sky rendering.
+    nativeScaling: 2 # Fixes light rays.
     deinterlace: 9 # Any other method causes very bad lines on movement of the camera.
 SLED-52474:
   name: "Transformers - Red Alert [Demo]"
@@ -13267,8 +13323,9 @@ SLED-52474:
   speedHacks:
     mtvu: 0
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes depth line.
+    halfPixelOffset: 5 # Fixes depth line.
     textureInsideRT: 1 # Fixes shadow and sky rendering.
+    nativeScaling: 2 # Fixes light rays.
     deinterlace: 9 # Any other method causes very bad lines on movement of the camera.
 SLED-52476:
   name: "UEFA Euro 2004 - Portugal [Demo]"
@@ -13322,6 +13379,12 @@ SLED-52736:
 SLED-52851:
   name: "TOCA Race Driver 2"
   region: "PAL-Unk"
+  gsHWFixes:
+    alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
+    roundSprite: 1 # Fixes misaligned map.
+    halfPixelOffset: 2 # Fixes depth of field alignment.
+    nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
 SLED-52852:
   name: "Forgotten Realms - Demon Stone [Demo]"
   region: "PAL-E"
@@ -13408,8 +13471,13 @@ SLED-53109:
     cpuCLUTRender: 1 # Fixes broken headlights.
     minimumBlendingLevel: 3
 SLED-53137:
-  name: "Stolen"
-  region: "PAL-Unk"
+  name: "Stolen [Demo]"
+  region: "PAL-M5"
+  gsHWFixes:
+    halfPixelOffset: 2 # Fixes misaligned bloom effects.
+    texturePreloading: 1 # Performs much better with partial preload.
+    textureInsideRT: 1 # Fixes post effects.
+    nativeScaling: 1 # Fixes lighting quality and positioning.
 SLED-53198:
   name: "Rugby 2005"
   region: "PAL-Unk"
@@ -13567,6 +13635,7 @@ SLED-53723:
     autoFlush: 1 # Corrects vignette to match software.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
     halfPixelOffset: 4 # Aligns blur more correctly to match software.
+    textureInsideRT: 1 # Fixes post processing effects.
 SLED-53731:
   name: "Battlefield 2 - Modern Combat [Demo]"
   region: "PAL-E"
@@ -13575,8 +13644,8 @@ SLED-53731:
     autoFlush: 1 # Post-processing.
     halfPixelOffset: 2 # Offset post-processing.
     texturePreloading: 1 # Improves performance.
+    textureInsideRT: 1 # Fixes per line drawing.
     getSkipCount: "GSC_Battlefield2" # Depth clear.
-    beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
 SLED-53732:
   name: "Spartan - Total Warrior [Demo]"
   region: "PAL"
@@ -13613,10 +13682,9 @@ SLED-53888:
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
     roundSprite: 1 # Fixes misaligned map.
-    skipDrawStart: 1 # Removes large black box around player car till we properly emulate it.
-    skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
     halfPixelOffset: 2 # Fixes depth of field alignment.
     nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
 SLED-53937:
   name: "Black [Demo]"
   region: "PAL-M5"
@@ -15868,8 +15936,6 @@ SLES-50876:
   gsHWFixes:
     autoFlush: 1 # Aligns and corrects shadows.
     halfPixelOffset: 2 # Fixes sun and depth line.
-    cpuCLUTRender: 1 # Fixes janky coloured cars.
-    gpuTargetCLUT: 1 # Fixes janky coloured cars.
     textureInsideRT: 1 # Fixes car textures.
     cpuSpriteRenderBW: 4 # Alleviates text and sky rendering issues.
     cpuSpriteRenderLevel: 2 # Needed for above.
@@ -17048,7 +17114,6 @@ SLES-51355:
   compat: 5
   gsHWFixes:
     textureInsideRT: 1 # Fixes inside RT shuffling.
-    getSkipCount: "GSC_BigMuthaTruckers"
 SLES-51356:
   name: "Road Trip Adventure"
   region: "PAL-M3"
@@ -17530,6 +17595,8 @@ SLES-51619:
   name: "Clock Tower 3"
   region: "PAL-M5"
   compat: 5
+  gameFixes:
+    - SoftwareRendererFMVHack # Fixes brightness and striped lines in FMVs.
 SLES-51620:
   name: "Black and Bruised"
   region: "PAL-M5"
@@ -17919,6 +17986,8 @@ SLES-51799:
   compat: 5
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
 SLES-51800:
@@ -18531,6 +18600,9 @@ SLES-51997:
   compat: 5
   clampModes:
     eeClampMode: 3 # For grey screen ingame.
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes post effects on player 2.
+    halfPixelOffset: 4 # Fixes chromatic effect.
 SLES-51998:
   name: "Kao the Kangaroo - Round 2"
   region: "PAL-M5"
@@ -18730,11 +18802,14 @@ SLES-52096:
     halfPixelOffset: 4 # Fixes post processing alignment.
     roundSprite: 1 # Fixes sprite misaligment.
 SLES-52097:
-  name: "SWAT - Global Strike Force"
+  name: "SWAT - Global Strike Team"
   region: "PAL-E-G"
   compat: 5
   clampModes:
     eeClampMode: 3 # For grey screen ingame.
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes post effects on player 2.
+    halfPixelOffset: 4 # Fixes chromatic effect.
 SLES-52100:
   name: "NRL Rugby League"
   region: "PAL-E"
@@ -18742,7 +18817,7 @@ SLES-52101:
   name: "Wrath Unleashed"
   region: "PAL-M5"
   gsHWFixes:
-    textureInsideRT: 1 # Fixes flashing and some models still very broken in hardware mode.
+    textureInsideRT: 1 # Fixes colors.
 SLES-52102:
   name: "Hugo Bukkazoom!"
   region: "PAL-M12"
@@ -18805,6 +18880,8 @@ SLES-52132:
   gsHWFixes:
     texturePreloading: 1 # Performs much better with partial preload.
     autoFlush: 1 # Fixes bloom rendering.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
   roundModes:
     vu1RoundMode: 0 # Fixes missing light cones curtains and certain effects.
   speedHacks:
@@ -18815,6 +18892,8 @@ SLES-52133:
   gsHWFixes:
     texturePreloading: 1 # Performs much better with partial preload.
     autoFlush: 1 # Fixes bloom rendering.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
   roundModes:
     vu1RoundMode: 0 # Fixes missing light cones curtains and certain effects.
   speedHacks:
@@ -18826,6 +18905,8 @@ SLES-52134:
   gsHWFixes:
     texturePreloading: 1 # Performs much better with partial preload.
     autoFlush: 1 # Fixes bloom rendering.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
   roundModes:
     vu1RoundMode: 0 # Fixes missing light cones curtains and certain effects.
   speedHacks:
@@ -18836,6 +18917,8 @@ SLES-52135:
   gsHWFixes:
     texturePreloading: 1 # Performs much better with partial preload.
     autoFlush: 1 # Fixes bloom rendering.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
   roundModes:
     vu1RoundMode: 0 # Fixes missing light cones curtains and certain effects.
   speedHacks:
@@ -18846,6 +18929,8 @@ SLES-52136:
   gsHWFixes:
     texturePreloading: 1 # Performs much better with partial preload.
     autoFlush: 1 # Fixes bloom rendering.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
   roundModes:
     vu1RoundMode: 0 # Fixes missing light cones curtains and certain effects.
   speedHacks:
@@ -18884,8 +18969,6 @@ SLES-52153:
   gsHWFixes:
     autoFlush: 1 # Aligns and corrects shadows.
     halfPixelOffset: 2 # Fixes sun and depth line.
-    cpuCLUTRender: 1 # Fixes janky coloured cars.
-    gpuTargetCLUT: 1 # Fixes janky coloured cars.
     textureInsideRT: 1 # Fixes car textures.
     cpuSpriteRenderBW: 4 # Alleviates text and sky rendering issues.
     cpuSpriteRenderLevel: 2 # Needed for above.
@@ -19228,6 +19311,8 @@ SLES-52322:
     texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
     mergeSprite: 1 # Fixes misaligned white lines.
     PCRTCOverscan: 1 # Fixes missing HUD.
+    textureInsideRT: 1 # Fixes post shuffle effect.
+    halfPixelOffset: 2 # Fixes boxes around shuffle effect pages.
 SLES-52323:
   name: "Richard Burns Rally"
   region: "PAL-M5"
@@ -19401,8 +19486,9 @@ SLES-52388:
   speedHacks:
     mtvu: 0
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes depth line.
+    halfPixelOffset: 5 # Fixes depth line.
     textureInsideRT: 1 # Fixes shadow and sky rendering.
+    nativeScaling: 2 # Fixes light rays.
     deinterlace: 9 # Any other method causes very bad lines on movement of the camera.
 SLES-52392:
   name: "Combat Elite - WWII Paratroopers [Preview]"
@@ -20106,12 +20192,17 @@ SLES-52637:
   region: "PAL-M5"
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
+    textureInsideRT: 1 # Fixes shadows.
 SLES-52638:
   name: "DTM Race Driver 2"
   region: "PAL-M5"
   compat: 5
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
+    roundSprite: 1 # Fixes misaligned map.
+    halfPixelOffset: 2 # Fixes depth of field alignment.
+    nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
 SLES-52639:
   name: "V8 Supercars 2"
   region: "PAL-M5"
@@ -20774,7 +20865,7 @@ SLES-52859:
   gsHWFixes:
     autoFlush: 1 # Fixes the post processing positioning.
     textureInsideRT: 1 # Fixes post processing.
-    halfPixelOffset: 4 # Aligns bloom effect.
+    halfPixelOffset: 5 # Aligns bloom effect.
     nativeScaling: 2 # Fixes post processing smoothness and position.
 SLES-52861:
   name: "King Arthur"
@@ -20822,9 +20913,10 @@ SLES-52882:
   region: "PAL-M5"
   compat: 4
   gsHWFixes:
-    disablePartialInvalidation: 1 # Improves performance.
     halfPixelOffset: 2 # Fixes misaligned bloom effects.
     texturePreloading: 1 # Performs much better with partial preload.
+    textureInsideRT: 1 # Fixes post effects.
+    nativeScaling: 1 # Fixes lighting quality and positioning.
 SLES-52884:
   name: "Duel Masters"
   region: "PAL-M5"
@@ -21002,6 +21094,8 @@ SLES-52942:
   gsHWFixes:
     halfPixelOffset: 2 # Aligns post bloom.
     nativeScaling: 2 # Fixes light blooms.
+    textureInsideRT: 1 # Improves performance.
+    preloadFrameData: 1 # Fixes light trails.
     getSkipCount: "GSC_MidnightClub3"
   patches:
     EBE1972D:
@@ -21266,9 +21360,9 @@ SLES-53020:
     recommendedBlendingLevel: 4 # Improves banding and effect emulation.
     autoFlush: 1 # Fixes light bloom intensity.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
-    halfPixelOffset: 4 # Aligns post effects.
+    halfPixelOffset: 2 # Aligns post effects.
     nativeScaling: 1 # Fixes post effects.
-    getSkipCount: "GSC_GiTS"
+    textureInsideRT: 1 # Fixes post shuffles.
   patches:
     BF6F101F:
       content: |-
@@ -21335,7 +21429,7 @@ SLES-53028:
   clampModes:
     vuClampMode: 0 # Fixes bump mapping issues.
   gsHWFixes:
-    halfPixelOffset: 4 # Fixes post processing position.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
     autoFlush: 1 # Fixes sun intensity.
     textureInsideRT: 1 # Fixes post processing.
     getSkipCount: "GSC_HitmanBloodMoney"
@@ -21345,7 +21439,7 @@ SLES-53029:
   clampModes:
     vuClampMode: 0 # Fixes bump mapping issues.
   gsHWFixes:
-    halfPixelOffset: 4 # Fixes post processing position.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
     autoFlush: 1 # Fixes sun intensity.
     textureInsideRT: 1 # Fixes post processing.
     getSkipCount: "GSC_HitmanBloodMoney"
@@ -21355,7 +21449,7 @@ SLES-53030:
   clampModes:
     vuClampMode: 0 # Fixes bump mapping issues.
   gsHWFixes:
-    halfPixelOffset: 4 # Fixes post processing position.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
     autoFlush: 1 # Fixes sun intensity.
     textureInsideRT: 1 # Fixes post processing.
     getSkipCount: "GSC_HitmanBloodMoney"
@@ -21365,7 +21459,7 @@ SLES-53031:
   clampModes:
     vuClampMode: 0 # Fixes bump mapping issues.
   gsHWFixes:
-    halfPixelOffset: 4 # Fixes post processing position.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
     autoFlush: 1 # Fixes sun intensity.
     textureInsideRT: 1 # Fixes post processing.
     getSkipCount: "GSC_HitmanBloodMoney"
@@ -21375,7 +21469,7 @@ SLES-53032:
   clampModes:
     vuClampMode: 0 # Fixes bump mapping issues.
   gsHWFixes:
-    halfPixelOffset: 4 # Fixes post processing position.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
     autoFlush: 1 # Fixes sun intensity.
     textureInsideRT: 1 # Fixes post processing.
     getSkipCount: "GSC_HitmanBloodMoney"
@@ -21541,10 +21635,9 @@ SLES-53087:
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
     roundSprite: 1 # Fixes misaligned map.
-    skipDrawStart: 1 # Removes large black box around player car till we properly emulate it.
-    skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
     halfPixelOffset: 2 # Fixes depth of field alignment.
     nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
   memcardFilters:
     - "SLES-53087"
     - "SLES-52637" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
@@ -21554,10 +21647,9 @@ SLES-53088:
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
     roundSprite: 1 # Fixes misaligned map.
-    skipDrawStart: 1 # Removes large black box around player car till we properly emulate it.
-    skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
     halfPixelOffset: 2 # Fixes depth of field alignment.
     nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
   memcardFilters:
     - "SLES-53088"
     - "SLES-52638" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
@@ -21567,10 +21659,9 @@ SLES-53089:
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
     roundSprite: 1 # Fixes misaligned map.
-    skipDrawStart: 1 # Removes large black box around player car till we properly emulate it.
-    skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
     halfPixelOffset: 2 # Fixes depth of field alignment.
     nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
   memcardFilters:
     - "SLES-53089"
     - "SLES-52639" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
@@ -21660,7 +21751,7 @@ SLES-53124:
   gsHWFixes:
     autoFlush: 1 # Fixes the post processing positioning.
     textureInsideRT: 1 # Fixes post processing.
-    halfPixelOffset: 4 # Aligns bloom effect.
+    halfPixelOffset: 5 # Aligns bloom effect.
     nativeScaling: 2 # Fixes post processing smoothness and position.
 SLES-53125:
   name: "Enthusia Professional Racing"
@@ -22018,8 +22109,9 @@ SLES-53309:
   speedHacks:
     mtvu: 0
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes depth line.
+    halfPixelOffset: 5 # Fixes depth line.
     textureInsideRT: 1 # Fixes shadow and sky rendering.
+    nativeScaling: 2 # Fixes light rays.
     deinterlace: 9 # Any other method causes very bad lines on movement of the camera.
 SLES-53311:
   name: "Graffiti Kingdom"
@@ -22357,6 +22449,7 @@ SLES-53415:
     halfPixelOffset: 2 # Fix text and post blur.
     nativeScaling: 2 # Fixes post effects.
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
 SLES-53416:
   name: "Call of Duty 2 - Big Red One"
   region: "PAL-M3"
@@ -22366,6 +22459,7 @@ SLES-53416:
     halfPixelOffset: 2 # Fix text and post blur.
     nativeScaling: 2 # Fixes post effects.
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
 SLES-53417:
   name: "Call of Duty 2 - Big Red One"
   region: "PAL-G"
@@ -22375,6 +22469,7 @@ SLES-53417:
     halfPixelOffset: 2 # Fix text and post blur.
     nativeScaling: 2 # Fixes post effects.
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
 SLES-53418:
   name: "Tak - The Great JuJu Challenge"
   region: "PAL-A"
@@ -23120,6 +23215,7 @@ SLES-53616:
     eeRoundMode: 0 # Fixes scene switching in intro.
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
     preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
     roundSprite: 1 # Fixes lines in some post-effects.
     gpuTargetCLUT: 1 # Fixes light occlusion.
@@ -23134,6 +23230,7 @@ SLES-53617:
     eeRoundMode: 0 # Fixes scene switching in intro.
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
     preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
     roundSprite: 1 # Fixes lines in some post-effects.
     gpuTargetCLUT: 1 # Fixes light occlusion.
@@ -23148,6 +23245,7 @@ SLES-53618:
     eeRoundMode: 0 # Fixes scene switching in intro.
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
     preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
     roundSprite: 1 # Fixes lines in some post-effects.
     gpuTargetCLUT: 1 # Fixes light occlusion.
@@ -23409,7 +23507,7 @@ SLES-53702:
   region: "PAL-M5"
   compat: 5
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes blurriness.
+    halfPixelOffset: 5 # Fixes blurriness.
 SLES-53703:
   name: "Peter Jackson's King Kong - The Official Game of the Movie"
   name-sort: "King Kong, Peter Jackson's - The Official Game of the Movie"
@@ -23420,6 +23518,7 @@ SLES-53703:
     autoFlush: 1 # Corrects vignette to match software.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
     halfPixelOffset: 4 # Aligns blur more correctly to match software.
+    textureInsideRT: 1 # Fixes post processing effects.
 SLES-53704:
   name: "Peter Jackson's King Kong - The Official Game of the Movie"
   name-sort: "King Kong, Peter Jackson's - The Official Game of the Movie"
@@ -23429,6 +23528,7 @@ SLES-53704:
     autoFlush: 1 # Corrects vignette to match software.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
     halfPixelOffset: 4 # Aligns blur more correctly to match software.
+    textureInsideRT: 1 # Fixes post processing effects.
 SLES-53705:
   name: "Peter Jackson's King Kong - The Official Game of the Movie"
   name-sort: "King Kong, Peter Jackson's - The Official Game of the Movie"
@@ -23438,6 +23538,7 @@ SLES-53705:
     autoFlush: 1 # Corrects vignette to match software.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
     halfPixelOffset: 4 # Aligns blur more correctly to match software.
+    textureInsideRT: 1 # Fixes post processing effects.
 SLES-53706:
   name: "The Chronicles of Narnia - The Lion, the Witch and the Wardrobe"
   name-sort: "Chronicles of Narnia, The - The Lion, the Witch and the Wardrobe"
@@ -23491,6 +23592,8 @@ SLES-53717:
   gsHWFixes:
     halfPixelOffset: 2 # Aligns post bloom.
     nativeScaling: 2 # Fixes light blooms.
+    textureInsideRT: 1 # Improves performance.
+    preloadFrameData: 1 # Fixes light trails.
     getSkipCount: "GSC_MidnightClub3"
   patches:
     208183AF:
@@ -23522,6 +23625,7 @@ SLES-53722:
     halfPixelOffset: 2 # Fix text and post blur.
     nativeScaling: 2 # Fixes post effects.
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
 SLES-53724:
   name: "World Series of Poker"
   region: "PAL-E"
@@ -23545,8 +23649,8 @@ SLES-53729:
     autoFlush: 1 # Post-processing.
     halfPixelOffset: 2 # Offset post-processing.
     texturePreloading: 1 # Improves performance.
+    textureInsideRT: 1 # Fixes per line drawing.
     getSkipCount: "GSC_Battlefield2" # Depth clear.
-    beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
 SLES-53730:
   name: "Battlefield 2 - Modern Combat"
   region: "PAL-M3"
@@ -23555,8 +23659,8 @@ SLES-53730:
     autoFlush: 1 # Post-processing.
     halfPixelOffset: 2 # Offset post-processing.
     texturePreloading: 1 # Improves performance.
+    textureInsideRT: 1 # Fixes per line drawing.
     getSkipCount: "GSC_Battlefield2" # Depth clear.
-    beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
 SLES-53734:
   name: "50 Cent - Bulletproof"
   region: "PAL-E"
@@ -23643,7 +23747,7 @@ SLES-53756:
   name: "Resident Evil 4"
   region: "PAL-M5"
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes blurriness.
+    halfPixelOffset: 5 # Fixes blurriness.
 SLES-53758:
   name: "Sniper Elite [Pre-Production]"
   region: "PAL-E"
@@ -23809,7 +23913,7 @@ SLES-53819:
   name: "Armored Core - Nine Breaker"
   region: "PAL-E"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
     cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
     cpuSpriteRenderLevel: 2 # Needed for above.
@@ -24849,7 +24953,7 @@ SLES-54185:
   compat: 5
   gsHWFixes:
     autoFlush: 1 # Fixes lighting.
-    halfPixelOffset: 4 # Fixes ghosting.
+    halfPixelOffset: 5 # Fixes ghosting.
     nativeScaling: 2 # Fixes post processing.
     recommendedBlendingLevel: 4 # Fixes missing light brightness.
 SLES-54186:
@@ -24951,8 +25055,8 @@ SLES-54217:
 SLES-54218:
   name: "Rule of Rose"
   region: "PAL-M5"
-  gsHWFixes:
-    preloadFrameData: 1 # Fixes Black FMV's.
+  gameFixes:
+    - SoftwareRendererFMVHack # Fixes black FMVs in hardware and hash cache disabling itself.
 SLES-54221:
   name: "LEGO Star Wars II - The Original Trilogy"
   region: "PAL-M6"
@@ -25886,12 +25990,21 @@ SLES-54510:
 SLES-54511:
   name: "UEFA Champions League 2006-2007"
   region: "PAL-E"
+  gsHWFixes:
+    cpuSpriteRenderBW: 2 # Fixes broken lights due to copying around P8 data.
+    cpuSpriteRenderLevel: 2 # Needed for above.
 SLES-54512:
   name: "UEFA Champions League 2006-2007"
   region: "PAL-F-G"
+  gsHWFixes:
+    cpuSpriteRenderBW: 2 # Fixes broken lights due to copying around P8 data.
+    cpuSpriteRenderLevel: 2 # Needed for above.
 SLES-54513:
   name: "UEFA Champions League 2006-2007"
   region: "PAL-I-S"
+  gsHWFixes:
+    cpuSpriteRenderBW: 2 # Fixes broken lights due to copying around P8 data.
+    cpuSpriteRenderLevel: 2 # Needed for above.
 SLES-54516:
   name: "Thrillville"
   region: "PAL-F-G"
@@ -26835,8 +26948,9 @@ SLES-54819:
   region: "PAL-M5"
   compat: 5
   gsHWFixes:
-    getSkipCount: "GSC_Manhunt2"
     autoFlush: 1 # Fixes missing lights and light intensity.
+    textureInsideRT: 1 # Fixes post lighting.
+    halfPixelOffset: 2 # Fixes post effects.
 SLES-54820:
   name: "Stuntman - Ignition"
   region: "PAL-M5"
@@ -27270,6 +27384,7 @@ SLES-54962:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLES-54963:
   name: "Tony Hawk's Proving Ground"
   region: "PAL-E"
@@ -27301,7 +27416,7 @@ SLES-54972:
   region: "PAL-M3"
   gsHWFixes:
     roundSprite: 1 # Fixes font sizes and lines in UI.
-    cpuFramebufferConversion: 1 # Fixes sepia-tone flashback sequences.
+    textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
     forceEvenSpritePosition: 1 # Fixes font artifacts and out-of-bound 2D textures.
     gpuPaletteConversion: 2 # Fixes micro-stuttering and reduces HC size.
 SLES-54973:
@@ -27317,6 +27432,7 @@ SLES-54974:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLES-54975:
   name: "George Of The Jungle"
   region: "PAL-E"
@@ -27630,6 +27746,8 @@ SLES-55019:
   gsHWFixes:
     recommendedBlendingLevel: 4 # Fixes vendor and other bloom.
     autoFlush: 2 # Fixes missing bloom and shadow definition.
+    halfPixelOffset: 5 # Fixes misaligned bloom.
+    nativeScaling: 2 # Fixes pixelated bloom.
 SLES-55020:
   name: "Die Simpsons - Das Spiel"
   region: "PAL-G"
@@ -27701,6 +27819,7 @@ SLES-55031:
   region: "PAL-F"
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
     halfPixelOffset: 4 # Aligns post processing.
     autoFlush: 1 # Fixes post processing.
 SLES-55032:
@@ -27853,6 +27972,8 @@ SLES-55109:
   region: "PAL-E"
   roundModes:
     vu0RoundMode: 0 # Fixes invisible wall collision in bedroom.
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes half screen.
 SLES-55110:
   name: "Odin Sphere"
   region: "PAL-M5"
@@ -28065,6 +28186,7 @@ SLES-55191:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLES-55192:
   name: "Steam Express"
   region: "PAL-M5"
@@ -28130,6 +28252,7 @@ SLES-55200:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLES-55201:
   name: "Riding Star"
   region: "PAL-M4"
@@ -28213,6 +28336,7 @@ SLES-55234:
   region: "PAL-SW"
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
     halfPixelOffset: 4 # Aligns post processing.
     autoFlush: 1 # Fixes post processing.
 SLES-55235:
@@ -28220,6 +28344,7 @@ SLES-55235:
   region: "PAL-I"
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
     halfPixelOffset: 4 # Aligns post processing.
     autoFlush: 1 # Fixes post processing.
 SLES-55236:
@@ -28227,6 +28352,7 @@ SLES-55236:
   region: "PAL-G-S"
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
     halfPixelOffset: 4 # Aligns post processing.
     autoFlush: 1 # Fixes post processing.
 SLES-55237:
@@ -29509,7 +29635,7 @@ SLES-82036:
   name: "Armored Core - Nexus [Disc 1]"
   region: "PAL-M5"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SLES-82036"
@@ -29518,7 +29644,7 @@ SLES-82037:
   name: "Armored Core - Nexus [Disc 2]"
   region: "PAL-M5"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SLES-82036"
@@ -30027,6 +30153,8 @@ SLKA-25051:
   name: "Clock Tower 3"
   region: "NTSC-K"
   compat: 5
+  gameFixes:
+    - SoftwareRendererFMVHack # Fixes brightness and striped lines in FMVs.
 SLKA-25052:
   name: "Air Ranger 2 - Rescue Helicopter"
   region: "NTSC-K"
@@ -30504,8 +30632,9 @@ SLKA-25175:
   speedHacks:
     mtvu: 0
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes depth line.
+    halfPixelOffset: 5 # Fixes depth line.
     textureInsideRT: 1 # Fixes shadow and sky rendering.
+    nativeScaling: 2 # Fixes light rays.
     deinterlace: 9 # Any other method causes very bad lines on movement of the camera.
 SLKA-25176:
   name: "Pump It Up - Exceed"
@@ -30573,8 +30702,6 @@ SLKA-25196:
   gsHWFixes:
     autoFlush: 1 # Aligns and corrects shadows.
     halfPixelOffset: 2 # Fixes sun and depth line.
-    cpuCLUTRender: 1 # Fixes janky coloured cars.
-    gpuTargetCLUT: 1 # Fixes janky coloured cars.
     textureInsideRT: 1 # Fixes car textures.
     cpuSpriteRenderBW: 4 # Alleviates text and sky rendering issues.
     cpuSpriteRenderLevel: 2 # Needed for above.
@@ -30598,7 +30725,7 @@ SLKA-25201:
   name: "Armored Core - Nexus [Disc 1]"
   region: "NTSC-K"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SLKA-25201"
@@ -30607,7 +30734,7 @@ SLKA-25202:
   name: "Armored Core - Nexus [Disc 2]"
   region: "NTSC-K"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SLKA-25201"
@@ -30699,6 +30826,8 @@ SLKA-25218:
   gsHWFixes:
     texturePreloading: 1 # Performs much better with partial preload.
     autoFlush: 1 # Fixes bloom rendering.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
   roundModes:
     vu1RoundMode: 0 # Fixes missing light cones curtains and certain effects.
   speedHacks:
@@ -30925,9 +31054,7 @@ SLKA-25270:
   name: "Armored Core - Formula Front"
   region: "NTSC-K"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
-    cpuSpriteRenderBW: 1 # Fixes broken shadow caused by HPO 1.
-    cpuSpriteRenderLevel: 2 # Needed for above.
+    halfPixelOffset: 5 # Fixes misaligned blur.
 SLKA-25271:
   name: "Harry Potter and the Order of the Phoenix"
   region: "NTSC-K"
@@ -31206,13 +31333,12 @@ SLKA-25330:
   name: "Battlefield 2 - Modern Combat"
   region: "NTSC-K"
   gsHWFixes:
-    autoFlush: 2 # Post-processing.
+    minimumBlendingLevel: 4 # Fixes ground texture rendering.
+    autoFlush: 1 # Post-processing.
     halfPixelOffset: 2 # Offset post-processing.
-    texturePreloading: 1 # Spikes all over the place otherwise.
-    textureInsideRT: 1 # Fixes light shinging through objects.
-    cpuCLUTRender: 1 # Fixes light shining through objects.
+    texturePreloading: 1 # Improves performance.
+    textureInsideRT: 1 # Fixes per line drawing.
     getSkipCount: "GSC_Battlefield2" # Depth clear.
-    beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
 SLKA-25331:
   name: "Marc Ecko's Getting Up - Contents Under Pressure"
   region: "NTSC-K"
@@ -31250,6 +31376,7 @@ SLKA-25337:
     autoFlush: 1 # Corrects vignette to match software.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
     halfPixelOffset: 4 # Aligns blur more correctly to match software.
+    textureInsideRT: 1 # Fixes post processing effects.
 SLKA-25338:
   name: "The Godfather"
   name-sort: "Godfather, The"
@@ -31588,7 +31715,7 @@ SLKA-25410:
   gameFixes:
     - BlitInternalFPSHack # Fixes internal FPS detection.
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes blurriness.
+    halfPixelOffset: 5 # Fixes blurriness.
 SLKA-25411:
   name: "Need for Speed - ProStreet"
   region: "NTSC-K"
@@ -31615,6 +31742,7 @@ SLKA-25414:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLKA-25417:
   name: "Jin Samguk Mussang 4 - Empires"
   region: "NTSC-K"
@@ -31670,6 +31798,7 @@ SLKA-25434:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLKA-25435:
   name: "Sengoku Basara X"
   region: "NTSC-J-K"
@@ -31678,6 +31807,7 @@ SLKA-25436:
   region: "NTSC-K"
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
 SLKA-25437:
   name: "Street Fighter Anniversary Collection"
   region: "NTSC-K"
@@ -32096,8 +32226,8 @@ SLPM-55034:
     autoFlush: 1 # Post-processing.
     halfPixelOffset: 2 # Offset post-processing.
     texturePreloading: 1 # Improves performance.
+    textureInsideRT: 1 # Fixes per line drawing.
     getSkipCount: "GSC_Battlefield2" # Depth clear.
-    beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
 SLPM-55035:
   name: "ファイトナイト ラウンド2 [EA:SY! 1980]"
   name-sort: "ふぁいとないと らうんど2 [EA:SY! 1980]"
@@ -32169,10 +32299,9 @@ SLPM-55046:
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
     roundSprite: 1 # Fixes misaligned map.
-    skipDrawStart: 1 # Removes large black box around player car till we properly emulate it.
-    skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
     halfPixelOffset: 2 # Fixes depth of field alignment.
     nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
   memcardFilters:
     - "SLPM-55046"
     - "SLPM-66498" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
@@ -32350,6 +32479,8 @@ SLPM-55080:
     texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
     mergeSprite: 1 # Fixes misaligned white lines.
     PCRTCOverscan: 1 # Fixes missing HUD.
+    textureInsideRT: 1 # Fixes post shuffle effect.
+    halfPixelOffset: 2 # Fixes boxes around shuffle effect pages.
 SLPM-55081:
   name: "ドラッグオンドラグーン2 ~封印の紅 背徳の黒~"
   name-sort: "どらっぐおんどらぐーん2 ~ふういんのあか はいとくのくろ~"
@@ -33440,8 +33571,7 @@ SLPM-60109:
   clampModes:
     vuClampMode: 2 # Fixes texture rendering in the intro.
   gsHWFixes:
-    cpuFramebufferConversion: 1
-    textureInsideRT: 1
+    textureInsideRT: 1 # Fixes post effects
     halfPixelOffset: 2 # Fixes title screen and some intro post processing alignment.
     roundSprite: 1 # Fixes ui and hud alignment.
     gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
@@ -33945,6 +34075,8 @@ SLPM-60217:
   region: "NTSC-J"
   gsHWFixes:
     texturePreloading: 0 # Performs much better with no preload.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
 SLPM-60218:
   name: "GUNGRAVE O.D. [体験版]"
   name-sort: "がんぐれいぶ おーでぃー [たいけんばん]"
@@ -34117,9 +34249,8 @@ SLPM-60257:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes FMV lines.
-    cpuSpriteRenderBW: 2 # Prevents Death By VRAM explosion.
-    cpuSpriteRenderLevel: 2 # Needed for above.
-    getSkipCount: "GSC_DeathByDegreesTekkenNinaWilliams"
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
+    textureInsideRT: 1 # Fixes post shuffles.
 SLPM-60258:
   name: "THE TYPING OF THE DEAD ZOMBIE PANIC [体験版]"
   name-sort: "ざ たいぴんぐおぶ ざ でっど ぞんび ぱにっく [たいけんばん]"
@@ -34673,8 +34804,6 @@ SLPM-61092:
   gsHWFixes:
     autoFlush: 1 # Aligns and corrects shadows.
     halfPixelOffset: 2 # Fixes sun and depth line.
-    cpuCLUTRender: 1 # Fixes janky coloured cars.
-    gpuTargetCLUT: 1 # Fixes janky coloured cars.
     textureInsideRT: 1 # Fixes car textures.
     cpuSpriteRenderBW: 4 # Alleviates text and sky rendering issues.
     cpuSpriteRenderLevel: 2 # Needed for above.
@@ -34934,10 +35063,11 @@ SLPM-61133:
   name-sort: "そうるきゃりばー3 [たいけんばん]"
   name-en: "SoulCalibur III [Trial]"
   region: "NTSC-J"
-  gameFixes:
-    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
     nativeScaling: 2 # Fixes misaligned bloom.
@@ -36960,7 +37090,6 @@ SLPM-62378:
   region: "NTSC-J"
   gsHWFixes:
     textureInsideRT: 1 # Fixes inside RT shuffling.
-    getSkipCount: "GSC_BigMuthaTruckers"
 SLPM-62379:
   name: "カラオケレボリューション J-POPベストVol.2"
   name-sort: "からおけれぼりゅーしょん J-POPべすとVol.2"
@@ -39585,6 +39714,9 @@ SLPM-65073:
   name-sort: "げんそうすいこでん3 [しょかいせいさんぶん:とくしゅしよう]"
   name-en: "Gensou Suikoden III [Limited Edition]"
   region: "NTSC-J"
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes half screen.
+    halfPixelOffset: 4 # Fixes post effects.
   memcardFilters: # This looks like a mess because it includes all serials for Suikoden 3, Suikoden 2, Suikogaiden 1, and Suikogaiden 2. A lot of these probably aren't actually required but it's not really hurting anything to have them here.
     - "SLPM-65073"
     - "SLPM-65074"
@@ -39604,6 +39736,9 @@ SLPM-65074:
   name-sort: "げんそうすいこでん3"
   name-en: "Gensou Suikoden III"
   region: "NTSC-J"
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes half screen.
+    halfPixelOffset: 4 # Fixes post effects.
   memcardFilters:
     - "SLPM-65073"
     - "SLPM-65074"
@@ -40421,6 +40556,8 @@ SLPM-65221:
   name-en: "Clock Tower 3"
   region: "NTSC-J"
   compat: 5
+  gameFixes:
+    - SoftwareRendererFMVHack # Fixes brightness and striped lines in FMVs.
 SLPM-65222:
   name: "遊戯王真デュエルモンスターズⅡ 継承されし記憶 [コナミ殿堂セレクション]"
   name-sort: "ゆうぎおうしんでゅえるもんすたーず2 けいしょうされしきおく [こなみでんどうせれくしょん]"
@@ -40521,7 +40658,6 @@ SLPM-65234:
   region: "NTSC-J"
   gsHWFixes:
     textureInsideRT: 1 # Fixes inside RT shuffling.
-    getSkipCount: "GSC_BigMuthaTruckers"
 SLPM-65235:
   name: "ニュールーマニア ポロリ青春"
   name-sort: "にゅーるーまにあ ぽろりせいしゅん"
@@ -40717,6 +40853,8 @@ SLPM-65266:
     texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
     mergeSprite: 1 # Fixes misaligned white lines.
     PCRTCOverscan: 1 # Fixes missing HUD.
+    textureInsideRT: 1 # Fixes post shuffle effect.
+    halfPixelOffset: 2 # Fixes boxes around shuffle effect pages.
 SLPM-65267:
   name: "鋼鉄の咆哮2 - ウォーシップガンナー"
   name-sort: "くろがねのほうこう2 うぉーしっぷがんなー"
@@ -40942,6 +41080,9 @@ SLPM-65305:
   name-sort: "げんそうすいこでん3 [KONAMI THE BEST]"
   name-en: "Gensou Suikoden 3"
   region: "NTSC-J"
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes half screen.
+    halfPixelOffset: 4 # Fixes post effects.
   memcardFilters:
     - "SLPM-65073"
     - "SLPM-65074"
@@ -42486,6 +42627,7 @@ SLPM-65583:
     autoFlush: 2 # Fixes sun luminosity.
     halfPixelOffset: 2 # Aligns Depth of Field.
     nativeScaling: 2 # Fixes Depth of Field effect.
+    textureInsideRT: 1 # Fixes half screen fog effect.
 SLPM-65584:
   name: "真・三國無双3 猛将伝"
   name-sort: "しんさんごくむそう3 もうしょうでん"
@@ -43109,6 +43251,9 @@ SLPM-65694:
   name-sort: "げんそうすいこでん3 [こなみでんどうせれくしょん]"
   name-en: "Gensou Suikoden 3 [KONAMI Dendou Selection]"
   region: "NTSC-J"
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes half screen.
+    halfPixelOffset: 4 # Fixes post effects.
   memcardFilters:
     - "SLPM-65073"
     - "SLPM-65074"
@@ -43381,8 +43526,6 @@ SLPM-65741:
   gsHWFixes:
     autoFlush: 1 # Aligns and corrects shadows.
     halfPixelOffset: 2 # Fixes sun and depth line.
-    cpuCLUTRender: 1 # Fixes janky coloured cars.
-    gpuTargetCLUT: 1 # Fixes janky coloured cars.
     textureInsideRT: 1 # Fixes car textures.
     cpuSpriteRenderBW: 4 # Alleviates text and sky rendering issues.
     cpuSpriteRenderLevel: 2 # Needed for above.
@@ -45519,6 +45662,7 @@ SLPM-66103:
     autoFlush: 2 # Fixes sun luminosity.
     halfPixelOffset: 2 # Aligns Depth of Field.
     nativeScaling: 2 # Fixes Depth of Field effect.
+    textureInsideRT: 1 # Fixes half screen fog effect.
 SLPM-66104:
   name: "ぷよぷよフィーバー2 [チュー!]"
   name-sort: "ぷよぷよふぃーばー2"
@@ -46195,8 +46339,8 @@ SLPM-66206:
     autoFlush: 1 # Post-processing.
     halfPixelOffset: 2 # Offset post-processing.
     texturePreloading: 1 # Improves performance.
+    textureInsideRT: 1 # Fixes per line drawing.
     getSkipCount: "GSC_Battlefield2" # Depth clear.
-    beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
 SLPM-66207:
   name: "どろろ [SEGA THE BEST 2800]"
   name-sort: "どろろ [SEGA THE BEST 2800]"
@@ -46229,6 +46373,7 @@ SLPM-66211:
     autoFlush: 1 # Corrects vignette to match software.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
     halfPixelOffset: 4 # Aligns blur more correctly to match software.
+    textureInsideRT: 1 # Fixes post processing effects.
 SLPM-66212:
   name: "SEGA RALLY 2006"
   name-sort: "せが らりー 2006"
@@ -46639,7 +46784,7 @@ SLPM-66271:
   compat: 5
   gsHWFixes:
     autoFlush: 1 # Fixes lighting.
-    halfPixelOffset: 4 # Fixes ghosting.
+    halfPixelOffset: 5 # Fixes ghosting.
     nativeScaling: 2 # Fixes post processing.
     recommendedBlendingLevel: 4 # Fixes missing light brightness.
 SLPM-66272:
@@ -47011,6 +47156,7 @@ SLPM-66328:
     halfPixelOffset: 2 # Fix text and post blur.
     nativeScaling: 2 # Fixes post effects.
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
 SLPM-66329:
   name: "魔法先生ネギま! 課外授業 乙女のドキドキ・ビーチサイド"
   name-sort: "まほうせんせいねぎま! かがいじゅぎょう おとめのどきどき びーちさいど"
@@ -47893,6 +48039,7 @@ SLPM-66473:
     eeRoundMode: 0 # Fixes scene switching in intro.
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
     preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
     roundSprite: 1 # Fixes lines in some post-effects.
     gpuTargetCLUT: 1 # Fixes light occlusion.
@@ -48069,6 +48216,10 @@ SLPM-66498:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
+    roundSprite: 1 # Fixes misaligned map.
+    halfPixelOffset: 2 # Fixes depth of field alignment.
+    nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
 SLPM-66499:
   name: "神様家族 応援願望"
   name-sort: "かみさまかぞく おうえんがんぼう"
@@ -48855,7 +49006,7 @@ SLPM-66629:
   region: "NTSC-J"
   gsHWFixes:
     autoFlush: 1 # Fixes lighting.
-    halfPixelOffset: 4 # Fixes ghosting.
+    halfPixelOffset: 5 # Fixes ghosting.
     nativeScaling: 2 # Fixes post processing.
     recommendedBlendingLevel: 4 # Fixes missing light brightness.
 SLPM-66630:
@@ -48980,8 +49131,8 @@ SLPM-66651:
     autoFlush: 1 # Post-processing.
     halfPixelOffset: 2 # Offset post-processing.
     texturePreloading: 1 # Improves performance.
+    textureInsideRT: 1 # Fixes per line drawing.
     getSkipCount: "GSC_Battlefield2" # Depth clear.
-    beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
 SLPM-66652:
   name: "バーンアウト リベンジ [EA BEST HITS]"
   name-sort: "ばーんあうと りべんじ [EA BEST HITS]"
@@ -50385,10 +50536,9 @@ SLPM-66881:
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
     roundSprite: 1 # Fixes misaligned map.
-    skipDrawStart: 1 # Removes large black box around player car till we properly emulate it.
-    skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
     halfPixelOffset: 2 # Fixes depth of field alignment.
     nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
   memcardFilters:
     - "SLPM-66881"
     - "SLPM-66498" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
@@ -51409,7 +51559,7 @@ SLPM-68016:
   region: "NTSC-J"
   gsHWFixes:
     autoFlush: 1 # Fixes lighting.
-    halfPixelOffset: 4 # Fixes ghosting.
+    halfPixelOffset: 5 # Fixes ghosting.
     nativeScaling: 2 # Fixes post processing.
     recommendedBlendingLevel: 4 # Fixes missing light brightness.
 SLPM-68017:
@@ -51477,6 +51627,9 @@ SLPM-68505:
   name-sort: "げんそうすいこでん3"
   name-en: "Gensou Suikoden III"
   region: "NTSC-J"
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes half screen.
+    halfPixelOffset: 4 # Fixes post effects.
 SLPM-68509:
   name: "頭文字D Special Stage [講談社懸賞品]"
   name-sort: "いにしゃるD すぺしゃる すてーじ [こうだんしゃけんしょうひん]"
@@ -51905,6 +52058,7 @@ SLPM-74243:
     eeRoundMode: 0 # Fixes scene switching in intro.
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
     preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
     roundSprite: 1 # Fixes lines in some post-effects.
     gpuTargetCLUT: 1 # Fixes light occlusion.
@@ -52306,6 +52460,8 @@ SLPM-74416:
   name-sort: "くろっくたわー3 [PlayStation2 the Best]"
   name-en: "Clock Tower 3 [PlayStation2 the Best]"
   region: "NTSC-J"
+  gameFixes:
+    - SoftwareRendererFMVHack # Fixes brightness and striped lines in FMVs.
 SLPM-74420:
   name: "頭文字D Special Stage [PlayStation2 the Best]"
   name-sort: "いにしゃるD すぺしゃる すてーじ [PlayStation2 the Best]"
@@ -52364,8 +52520,7 @@ SLPS-20001:
   clampModes:
     vuClampMode: 2 # Fixes texture rendering in the intro.
   gsHWFixes:
-    cpuFramebufferConversion: 1
-    textureInsideRT: 1
+    textureInsideRT: 1 # Fixes post effects
     halfPixelOffset: 2 # Fixes title screen and some intro post processing alignment.
     roundSprite: 1 # Fixes ui and hud alignment.
     gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
@@ -54188,6 +54343,7 @@ SLPS-20382:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SLPS-20383:
   name: "太鼓の達人 あつまれ!祭りだ!!四代目"
   name-sort: "たいこのたつじん あつまれ!まつりだ!!よんだいめ"
@@ -54195,6 +54351,7 @@ SLPS-20383:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SLPS-20384:
   name: "流行り神 警視庁怪異事件ファイル [初回限定版]"
   name-sort: "はやりがみ けいしちょうかいいじけんふぁいる [しょかいげんていばん]"
@@ -54262,6 +54419,7 @@ SLPS-20399:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SLPS-20400:
   name: "太鼓の達人 ゴー!ゴー!五代目 [ソフト単体]"
   name-sort: "たいこのたつじん ごー!ごー!ごだいめ [そふとたんたい]"
@@ -54269,6 +54427,7 @@ SLPS-20400:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SLPS-20401:
   name: "テクモ ヒットパレード"
   name-sort: "てくも ひっとぱれーど"
@@ -54340,6 +54499,7 @@ SLPS-20413:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SLPS-20414:
   name: "太鼓の達人 TAIKO DRUM MASTER"
   name-sort: "たいこのたつじん TAIKO DRUM MASTER"
@@ -54348,6 +54508,7 @@ SLPS-20414:
   compat: 5
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SLPS-20416:
   name: "陰陽大戦記 白虎演舞 [“EyeToy”カメラ同梱版]"
   name-sort: "おんみょうたいせんき びゃっこえんぶ [あいとーいかめらどうこんばん]"
@@ -54399,6 +54560,7 @@ SLPS-20424:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SLPS-20425:
   name: "太鼓の達人 とびっきり!アニメスペシャル [ソフト単体]"
   name-sort: "たいこのたつじん とびっきり!あにめすぺしゃる [そふとたんたい]"
@@ -54406,6 +54568,7 @@ SLPS-20425:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SLPS-20426:
   name: "マダガスカル"
   name-sort: "まだかすかる"
@@ -54515,6 +54678,7 @@ SLPS-20450:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SLPS-20451:
   name: "太鼓の達人 わいわいハッピー!六代目"
   name-sort: "たいこのたつじん わいわいはっぴー!ろくだいめ"
@@ -54522,6 +54686,7 @@ SLPS-20451:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
+    textureInsideRT: 1 # Fixes post effects.
 SLPS-20452:
   name: "SIMPLE2000シリーズ Ultimate Vol.30 降臨!族車ゴッド~仏恥義理★愛羅武勇~"
   name-sort: "しんぷる2000しりーず あるてぃめっと Vol.30 こうりん!ぞくしゃごっど ぶっちぎりあいらぶゆう"
@@ -54722,7 +54887,8 @@ SLPS-20485:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
-    getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
+    textureInsideRT: 1 # Fixes post effects.
+    getSkipCount: "GSC_NamcoGames" # Fixes upscaling grid, same engine.
 SLPS-20486:
   name: "太鼓の達人 ドカッ!と大盛り七代目 [ソフト単体]"
   name-sort: "たいこのたつじん どかっ!とおおもりななだいめ [そふとたんたい]"
@@ -54730,7 +54896,8 @@ SLPS-20486:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
-    getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
+    textureInsideRT: 1 # Fixes post effects.
+    getSkipCount: "GSC_NamcoGames" # Fixes upscaling grid, same engine.
 SLPS-20487:
   name: "パチスロキング! 科学忍者隊ガッチャマン"
   name-sort: "ぱちすろきんぐ! かがくにんじゃたいがっちゃまん"
@@ -56202,6 +56369,8 @@ SLPS-25230:
   compat: 5
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
 SLPS-25231:
@@ -56521,6 +56690,8 @@ SLPS-25289:
   region: "NTSC-J"
   gsHWFixes:
     texturePreloading: 0 # Performs much better with no preload.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
 SLPS-25290:
   name: "タイムクライシス3 [ソフト単体]"
   name-sort: "たいむくらいしす3 [そふとたんたい]"
@@ -56528,6 +56699,8 @@ SLPS-25290:
   region: "NTSC-J"
   gsHWFixes:
     texturePreloading: 0 # Performs much better with no preload.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
 SLPS-25291:
   name: "Baldur's Gate - DARK ALLIANCE - [PCCW Japan The BEST]"
   name-sort: "ばるだーずげーと だーくあらいあんす [PCCW Japan The BEST]"
@@ -56797,7 +56970,7 @@ SLPS-25338:
   name-en: "Armored Core - Nexus [Disc 1]"
   region: "NTSC-J"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SCAJ-20076"
@@ -56812,7 +56985,7 @@ SLPS-25339:
   name-en: "Armored Core - Nexus [Disc 2]"
   region: "NTSC-J"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SCAJ-20076"
@@ -57250,6 +57423,8 @@ SLPS-25406:
   gsHWFixes:
     texturePreloading: 1 # Performs much better with partial preload.
     autoFlush: 1 # Fixes bloom rendering.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
   roundModes:
     vu1RoundMode: 0 # Fixes missing light cones curtains and certain effects.
   speedHacks:
@@ -57265,7 +57440,7 @@ SLPS-25408:
   name-en: "Armored Core - Nine Breaker"
   region: "NTSC-J"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
     cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
     cpuSpriteRenderLevel: 2 # Needed for above.
@@ -57379,9 +57554,8 @@ SLPS-25422:
   region: "NTSC-J"
   gsHWFixes:
     alignSprite: 1 # Fixes FMV lines.
-    cpuSpriteRenderBW: 2 # Prevents Death By VRAM explosion.
-    cpuSpriteRenderLevel: 2 # Needed for above.
-    getSkipCount: "GSC_DeathByDegreesTekkenNinaWilliams"
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
+    textureInsideRT: 1 # Fixes post shuffles.
 SLPS-25423:
   name: "怪盗アプリコット 完全版 [限定版]"
   name-sort: "かいとうあぷりこっと かんぜんばん [げんていばん]"
@@ -57590,9 +57764,7 @@ SLPS-25461:
   name-en: "Armored Core - Formula Front"
   region: "NTSC-J"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
-    cpuSpriteRenderBW: 1 # Fixes broken shadow caused by HPO 1.
-    cpuSpriteRenderLevel: 2 # Needed for above.
+    halfPixelOffset: 5 # Fixes misaligned blur.
 SLPS-25462:
   name: "アーマード・コア ラストレイヴン"
   name-sort: "あーまーどこあ らすとれいゔん"
@@ -57867,10 +58039,11 @@ SLPS-25510:
   clampModes:
     eeClampMode: 2 # Fixes camera and stops constant coin noises on Pirates Cove.
   gsHWFixes:
+    textureInsideRT: 1 # Fixes heat haze half screen problem.
     alignSprite: 1 # Fixes vertical lines.
     halfPixelOffset: 4 # Align post.
     nativeScaling: 1 # Fixes depth of field effect.
-    getSkipCount: "GSC_Tekken5"
+    getSkipCount: "GSC_NamcoGames"
 SLPS-25511:
   name: "羅刹 -Alternative-"
   name-sort: "らせつ -Alternative-"
@@ -58153,6 +58326,8 @@ SLPS-25563:
   gsHWFixes:
     texturePreloading: 1 # Performs much better with partial preload.
     autoFlush: 1 # Fixes bloom rendering.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
   roundModes:
     vu1RoundMode: 0 # Fixes missing light cones curtains and certain effects.
   speedHacks:
@@ -58240,10 +58415,11 @@ SLPS-25577:
   name-en: "SoulCalibur III"
   region: "NTSC-J"
   compat: 5
-  gameFixes:
-    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
     nativeScaling: 2 # Fixes misaligned bloom.
@@ -58308,7 +58484,7 @@ SLPS-25586:
     halfPixelOffset: 4 # Fixes post positioning.
     nativeScaling: 1 # Fixes post effects.
     autoFlush: 2 # Fixes post lighting.
-    getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
+    getSkipCount: "GSC_NamcoGames" # Fixes upscaling grid, same engine.
 SLPS-25587:
   name: "シュガシュガルーン 恋もおしゃれもピックアップ!"
   name-sort: "しゅがしゅがるーん こいもおしゃれもぴっくあっぷ!"
@@ -59849,6 +60025,7 @@ SLPS-25840:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLPS-25841:
   name: "テイルズ オブ デスティニー ディレクターズカット [プレミアムBOX]"
   name-sort: "ているず おぶ ですてぃにー でぃれくたーずかっと [ぷれみあむBOX]"
@@ -60105,6 +60282,7 @@ SLPS-25886:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLPS-25887:
   name: "スーパーロボット大戦Z"
   name-sort: "すーぱーろぼっとたいせんZ"
@@ -60141,6 +60319,7 @@ SLPS-25889:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLPS-25890:
   name: "ギターヒーロー3 レジェンドオブロック [ソフト単体]"
   name-sort: "ぎたーひーろー3 れじぇんどおぶろっく [そふとたんたい]"
@@ -60153,6 +60332,7 @@ SLPS-25890:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLPS-25891:
   name: "乃木坂春香の秘密 こすぷれ、はじめました♥ [限定版]"
   name-sort: "のぎざかはるかのひみつ こすぷれ はじめました [げんていばん]"
@@ -60725,8 +60905,7 @@ SLPS-71502:
   name-en: "Ridge Racer V [MEGA HITS!]"
   region: "NTSC-J"
   gsHWFixes:
-    cpuFramebufferConversion: 1
-    textureInsideRT: 1
+    textureInsideRT: 1 # Fixes post effects
     halfPixelOffset: 2 # Fixes title screen and some intro post processing alignment.
     roundSprite: 1 # Fixes ui and hud alignment.
     gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
@@ -60857,7 +61036,7 @@ SLPS-73202:
   name-en: "Armored Core - Nexus [Disc 1] [PlayStation2 the Best]"
   region: "NTSC-J"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SCAJ-20076"
@@ -60872,7 +61051,7 @@ SLPS-73203:
   name-en: "Armored Core - Nexus [Disc 2] [PlayStation2 the Best]"
   region: "NTSC-J"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SCAJ-20076"
@@ -61039,10 +61218,11 @@ SLPS-73223:
   clampModes:
     eeClampMode: 2 # Fixes camera and stops constant coin noises on Pirates Cove.
   gsHWFixes:
+    textureInsideRT: 1 # Fixes heat haze half screen problem.
     alignSprite: 1 # Fixes vertical lines.
     halfPixelOffset: 4 # Align post.
     nativeScaling: 1 # Fixes depth of field effect.
-    getSkipCount: "GSC_Tekken5"
+    getSkipCount: "GSC_NamcoGames"
 SLPS-73224:
   name: "ゼノサーガ エピソードⅡ [善悪の彼岸] [PlayStation2 the Best] [ディスク1/2]"
   name-sort: "ぜのさーが えぴそーど2 ぜんあくのひがん [PlayStation2 the Best] [でぃすく1/2]"
@@ -61342,7 +61522,7 @@ SLPS-73252:
     halfPixelOffset: 4 # Fixes post positioning.
     nativeScaling: 1 # Fixes post effects.
     autoFlush: 2 # Fixes post lighting.
-    getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
+    getSkipCount: "GSC_NamcoGames" # Fixes upscaling grid, same engine.
 SLPS-73253:
   name: "るろうに剣心-明治剣客浪漫譚- 炎上!京都輪廻 [PlayStation2 the Best]"
   name-sort: "るろうにけんしん めいじけんかくろまんたん えんじょう きょうとりんね [PlayStation2 the Best]"
@@ -61644,8 +61824,7 @@ SLUS-20002:
   clampModes:
     vuClampMode: 2 # Fixes texture rendering in the intro.
   gsHWFixes:
-    cpuFramebufferConversion: 1
-    textureInsideRT: 1
+    textureInsideRT: 1 # Fixes post effects
     halfPixelOffset: 2 # Fixes title screen and some intro post processing alignment.
     roundSprite: 1 # Fixes ui and hud alignment.
     gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
@@ -62827,7 +63006,6 @@ SLUS-20291:
   compat: 5
   gsHWFixes:
     textureInsideRT: 1 # Fixes inside RT shuffling.
-    getSkipCount: "GSC_BigMuthaTruckers"
 SLUS-20292:
   name: "Tsugunai - Atonement"
   region: "NTSC-U"
@@ -63302,6 +63480,9 @@ SLUS-20387:
   name: "Suikoden III"
   region: "NTSC-U"
   compat: 5
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes half screen.
+    halfPixelOffset: 4 # Fixes post effects.
   memcardFilters: # Allows import of Suikoden II clear data.
     - "SLUS-20387"
     - "SLUS-00958"
@@ -63548,6 +63729,9 @@ SLUS-20433:
   compat: 5
   clampModes:
     eeClampMode: 3 # For grey screen ingame.
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes post effects on player 2.
+    halfPixelOffset: 4 # Fixes chromatic effect.
 SLUS-20434:
   name: "Myst III - Exile"
   region: "NTSC-U"
@@ -64370,8 +64554,6 @@ SLUS-20587:
   gsHWFixes:
     autoFlush: 1 # Aligns and corrects shadows.
     halfPixelOffset: 2 # Fixes sun and depth line.
-    cpuCLUTRender: 1 # Fixes janky coloured cars.
-    gpuTargetCLUT: 1 # Fixes janky coloured cars.
     textureInsideRT: 1 # Fixes car textures.
     cpuSpriteRenderBW: 4 # Alleviates text and sky rendering issues.
     cpuSpriteRenderLevel: 2 # Needed for above.
@@ -64468,7 +64650,6 @@ SLUS-20605:
   region: "NTSC-U"
   gsHWFixes:
     textureInsideRT: 1 # Fixes inside RT shuffling.
-    getSkipCount: "GSC_BigMuthaTruckers"
 SLUS-20606:
   name: "Bounty Hunter - Seek & Destroy"
   region: "NTSC-U"
@@ -64590,6 +64771,8 @@ SLUS-20633:
   name: "Clock Tower 3"
   region: "NTSC-U"
   compat: 5
+  gameFixes:
+    - SoftwareRendererFMVHack # Fixes brightness and striped lines in FMVs.
 SLUS-20634:
   name: "Summer Heat Beach Volleyball"
   region: "NTSC-U"
@@ -64641,6 +64824,8 @@ SLUS-20643:
   compat: 5
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
 SLUS-20644:
@@ -64658,6 +64843,8 @@ SLUS-20645:
   compat: 5
   gsHWFixes:
     texturePreloading: 0 # Performs much better with no preload.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
 SLUS-20646:
   name: "Mark Davis Pro Bass Challenge"
   region: "NTSC-U"
@@ -64759,8 +64946,9 @@ SLUS-20668:
   speedHacks:
     mtvu: 0
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes depth line.
+    halfPixelOffset: 5 # Fixes depth line.
     textureInsideRT: 1 # Fixes shadow and sky rendering.
+    nativeScaling: 2 # Fixes light rays.
     deinterlace: 9 # Any other method causes very bad lines on movement of the camera.
 SLUS-20669:
   name: "Resident Evil - Dead Aim"
@@ -65126,6 +65314,8 @@ SLUS-20732:
     texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
     mergeSprite: 1 # Fixes misaligned white lines.
     PCRTCOverscan: 1 # Fixes missing HUD.
+    textureInsideRT: 1 # Fixes post shuffle effect.
+    halfPixelOffset: 2 # Fixes boxes around shuffle effect pages.
 SLUS-20733:
   name: "Castlevania - Lament of Innocence"
   region: "NTSC-U"
@@ -65672,7 +65862,7 @@ SLUS-20840:
   region: "NTSC-U"
   compat: 5
   gsHWFixes:
-    textureInsideRT: 1 # Fixes flashing and some models still very broken in hardware mode.
+    textureInsideRT: 1 # Fixes colors.
 SLUS-20841:
   name: "NFL Street"
   region: "NTSC-U"
@@ -65926,6 +66116,8 @@ SLUS-20882:
   gsHWFixes:
     texturePreloading: 1 # Performs much better with partial preload.
     autoFlush: 1 # Fixes bloom rendering.
+    textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
   roundModes:
     vu1RoundMode: 0 # Fixes missing light cones curtains and certain effects.
   speedHacks:
@@ -66255,9 +66447,8 @@ SLUS-20934:
   compat: 5
   gsHWFixes:
     alignSprite: 1 # Fixes FMV lines.
-    cpuSpriteRenderBW: 2 # Prevents Death By VRAM explosion.
-    cpuSpriteRenderLevel: 2 # Needed for above.
-    getSkipCount: "GSC_DeathByDegreesTekkenNinaWilliams"
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
+    textureInsideRT: 1 # Fixes post shuffles.
 SLUS-20935:
   name: "IHRA Professional Drag Racing 2005"
   region: "NTSC-U"
@@ -66576,7 +66767,7 @@ SLUS-20986:
   region: "NTSC-U"
   compat: 5
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SLUS-20986"
@@ -66691,9 +66882,9 @@ SLUS-21006:
     recommendedBlendingLevel: 4 # Improves banding and effect emulation.
     autoFlush: 1 # Fixes light bloom intensity.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
-    halfPixelOffset: 4 # Aligns post effects.
+    halfPixelOffset: 2 # Aligns post effects.
     nativeScaling: 1 # Fixes post effects.
-    getSkipCount: "GSC_GiTS"
+    textureInsideRT: 1 # Fixes post shuffles.
   patches:
     default:
       content: |-
@@ -66837,8 +67028,8 @@ SLUS-21026:
     autoFlush: 1 # Post-processing.
     halfPixelOffset: 2 # Offset post-processing.
     texturePreloading: 1 # Improves performance.
+    textureInsideRT: 1 # Fixes per line drawing.
     getSkipCount: "GSC_Battlefield2" # Depth clear.
-    beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
 SLUS-21027:
   name: "The Lord of the Rings - The Third Age"
   name-sort: "Lord of the Rings, The - The Third Age"
@@ -66858,6 +67049,8 @@ SLUS-21029:
   gsHWFixes:
     halfPixelOffset: 2 # Aligns post bloom.
     nativeScaling: 2 # Fixes light blooms.
+    textureInsideRT: 1 # Improves performance.
+    preloadFrameData: 1 # Fixes light trails.
     getSkipCount: "GSC_MidnightClub3"
   patches:
     0DD3417A:
@@ -66921,7 +67114,7 @@ SLUS-21037:
     autoFlush: 1 # Fixes the post processing positioning.
     textureInsideRT: 1 # Fixes post processing.
     nativeScaling: 2 # Fixes post processing smoothness and position.
-    halfPixelOffset: 4 # Makes bloom alignment slightly less awful.
+    halfPixelOffset: 5 # Makes bloom alignment slightly less awful.
 SLUS-21038:
   name: "Pinball Hall of Fame - The Gottlieb Collection"
   region: "NTSC-U"
@@ -66932,6 +67125,10 @@ SLUS-21039:
   compat: 5
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
+    roundSprite: 1 # Fixes misaligned map.
+    halfPixelOffset: 2 # Fixes depth of field alignment.
+    nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
 SLUS-21040:
   name: "The Shield"
   name-sort: "Shield, The"
@@ -67048,10 +67245,11 @@ SLUS-21059:
   clampModes:
     eeClampMode: 2 # Fixes camera and stops constant coin noises on Pirates Cove.
   gsHWFixes:
+    textureInsideRT: 1 # Fixes heat haze half screen problem.
     alignSprite: 1 # Fixes vertical lines.
     halfPixelOffset: 4 # Align post.
     nativeScaling: 1 # Fixes depth of field effect.
-    getSkipCount: "GSC_Tekken5"
+    getSkipCount: "GSC_NamcoGames"
 SLUS-21060:
   name: "WWE SmackDown! vs. RAW"
   region: "NTSC-U"
@@ -67150,7 +67348,7 @@ SLUS-21079:
   name: "Armored Core - Nexus [Disc 2]"
   region: "NTSC-U"
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
   memcardFilters:
     - "SLUS-20986"
@@ -67244,9 +67442,10 @@ SLUS-21099:
   region: "NTSC-U"
   compat: 4
   gsHWFixes:
-    disablePartialInvalidation: 1 # Improves performance.
     halfPixelOffset: 2 # Fixes misaligned bloom effects.
     texturePreloading: 1 # Performs much better with partial preload.
+    textureInsideRT: 1 # Fixes post effects.
+    nativeScaling: 1 # Fixes lighting quality and positioning.
 SLUS-21100:
   name: "NCAA March Madness 2005"
   region: "NTSC-U"
@@ -67289,6 +67488,7 @@ SLUS-21106:
     eeRoundMode: 0 # Fixes scene switching in intro.
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
     preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
     roundSprite: 1 # Fixes lines in some post-effects.
     gpuTargetCLUT: 1 # Fixes light occlusion.
@@ -67305,7 +67505,7 @@ SLUS-21108:
   clampModes:
     vuClampMode: 0 # Fixes bump mapping issues
   gsHWFixes:
-    halfPixelOffset: 4 # Fixes post processing position.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing.
     autoFlush: 1 # Fixes sun intensity.
     textureInsideRT: 1 # Fixes post processing.
     getSkipCount: "GSC_HitmanBloodMoney"
@@ -67457,7 +67657,7 @@ SLUS-21134:
   gameFixes:
     - BlitInternalFPSHack # Fixes internal FPS detection.
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes blurriness.
+    halfPixelOffset: 5 # Fixes blurriness.
 SLUS-21135:
   name: "MVP Baseball 2005"
   region: "NTSC-U"
@@ -67597,10 +67797,11 @@ SLUS-21160:
   clampModes:
     eeClampMode: 2 # Fixes camera and stops constant coin noises on Pirates Cove.
   gsHWFixes:
+    textureInsideRT: 1 # Fixes heat haze half screen problem.
     alignSprite: 1 # Fixes vertical lines.
     halfPixelOffset: 4 # Align post.
     nativeScaling: 1 # Fixes depth of field effect.
-    getSkipCount: "GSC_Tekken5"
+    getSkipCount: "GSC_NamcoGames"
 SLUS-21161:
   name: "Fight Night Round 2"
   region: "NTSC-U"
@@ -67715,10 +67916,9 @@ SLUS-21182:
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
     roundSprite: 1 # Fixes misaligned map.
-    skipDrawStart: 1 # Removes large black box around player car till we properly emulate it.
-    skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
     halfPixelOffset: 2 # Fixes depth of field alignment.
     nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
   memcardFilters:
     - "SLUS-21182"
     - "SLUS-21039" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
@@ -67828,7 +68028,7 @@ SLUS-21200:
   region: "NTSC-U"
   compat: 5
   gsHWFixes:
-    halfPixelOffset: 1 # Fixes misaligned blur.
+    halfPixelOffset: 5 # Fixes misaligned blur.
     recommendedBlendingLevel: 3 # Fixes level brightness.
     cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
     cpuSpriteRenderLevel: 2 # Needed for above.
@@ -67939,10 +68139,11 @@ SLUS-21216:
   name: "SoulCalibur III"
   region: "NTSC-U"
   compat: 5
-  gameFixes:
-    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - EETimingHack # Fixes bad colours on character select when in Progressive Scan.
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
     nativeScaling: 2 # Fixes misaligned bloom.
@@ -68015,6 +68216,7 @@ SLUS-21228:
     halfPixelOffset: 2 # Fix text and post blur.
     nativeScaling: 2 # Fixes post effects.
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
 SLUS-21229:
   name: "Motocross Mania 3"
   region: "NTSC-U"
@@ -68653,6 +68855,7 @@ SLUS-21311:
     autoFlush: 1 # Corrects vignette to match software.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
     halfPixelOffset: 4 # Aligns blur more correctly to match software.
+    textureInsideRT: 1 # Fixes post processing effects.
 SLUS-21312:
   name: "Wallace & Gromit - The Curse of the Were-Rabbit"
   region: "NTSC-U"
@@ -68703,6 +68906,7 @@ SLUS-21318:
   gsHWFixes:
     roundSprite: 1 # Fixes lines in sprites.
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
 SLUS-21319:
   name: "Flow - Urban Dance Uprising"
   region: "NTSC-U"
@@ -68937,6 +69141,8 @@ SLUS-21355:
   gsHWFixes:
     halfPixelOffset: 2 # Aligns post bloom.
     nativeScaling: 2 # Fixes light blooms.
+    textureInsideRT: 1 # Improves performance.
+    preloadFrameData: 1 # Fixes light trails.
     getSkipCount: "GSC_MidnightClub3"
   patches:
     60A42FF5:
@@ -69181,7 +69387,7 @@ SLUS-21386:
     halfPixelOffset: 4 # Fixes post positioning.
     nativeScaling: 1 # Fixes post effects.
     autoFlush: 2 # Fixes post lighting.
-    getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
+    getSkipCount: "GSC_NamcoGames" # Fixes upscaling grid, same engine.
 SLUS-21387:
   name: "Warship Gunner 2"
   region: "NTSC-U"
@@ -69326,6 +69532,9 @@ SLUS-21410:
   name: "Mortal Kombat - Armageddon"
   region: "NTSC-U"
   compat: 5
+  memcardFilters: # Saves from the non-Premium can be imported
+    - "SLUS-21410"
+    - "SLUS-21543"
 SLUS-21411:
   name: "M2 Rock"
   region: "NTSC-U"
@@ -69401,7 +69610,7 @@ SLUS-21419:
   compat: 5
   gsHWFixes:
     autoFlush: 1 # Fixes lighting.
-    halfPixelOffset: 4 # Fixes ghosting.
+    halfPixelOffset: 5 # Fixes ghosting.
     nativeScaling: 2 # Fixes post processing.
     recommendedBlendingLevel: 4 # Fixes missing light brightness.
 SLUS-21420:
@@ -69580,8 +69789,8 @@ SLUS-21448:
   name: "Rule of Rose"
   region: "NTSC-U"
   compat: 5
-  gsHWFixes:
-    preloadFrameData: 1 # Fixes Black FMV's.
+  gameFixes:
+    - SoftwareRendererFMVHack # Fixes black FMVs in hardware and hash cache disabling itself.
 SLUS-21449:
   name: "The Fast and the Furious"
   name-sort: "Fast and the Furious, The"
@@ -69968,6 +70177,9 @@ SLUS-21543:
   name: "Mortal Kombat - Armageddon [Premium Edition]"
   region: "NTSC-U"
   compat: 5
+  memcardFilters: # Saves from the non-Premium can be imported
+    - "SLUS-21543"
+    - "SLUS-21410"
 SLUS-21544:
   name: "Fantastic 4 - Rise of Silver Surfer"
   region: "NTSC-U"
@@ -70160,6 +70372,9 @@ SLUS-21581:
   name: "UEFA Champions League 2006-2007"
   region: "NTSC-U"
   compat: 5
+  gsHWFixes:
+    cpuSpriteRenderBW: 2 # Fixes broken lights due to copying around P8 data.
+    cpuSpriteRenderLevel: 2 # Needed for above.
 SLUS-21582:
   name: "MVP '07 - NCAA Baseball"
   region: "NTSC-U"
@@ -70355,8 +70570,9 @@ SLUS-21613:
   region: "NTSC-U"
   compat: 5
   gsHWFixes:
-    getSkipCount: "GSC_Manhunt2"
     autoFlush: 1 # Fixes missing lights and light intensity.
+    textureInsideRT: 1 # Fixes post lighting.
+    halfPixelOffset: 2 # Fixes Post effects.
 SLUS-21614:
   name: "Star Wars - The Force Unleashed"
   region: "NTSC-U"
@@ -70380,7 +70596,7 @@ SLUS-21615:
   compat: 5
   gsHWFixes:
     roundSprite: 1 # Fixes font sizes and lines in UI.
-    cpuFramebufferConversion: 1 # Fixes sepia-tone flashback sequences.
+    textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
     forceEvenSpritePosition: 1 # Fixes font artifacts and out-of-bound 2D textures.
     gpuPaletteConversion: 2 # Fixes micro-stuttering and reduces HC size.
 SLUS-21616:
@@ -70716,6 +70932,7 @@ SLUS-21672:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLUS-21673:
   name: "College Hoops 2K8"
   region: "NTSC-U"
@@ -70939,6 +71156,8 @@ SLUS-21716:
   compat: 5
   roundModes:
     vu0RoundMode: 0 # Fixes invisible wall collision in bedroom.
+  gsHWFixes:
+    textureInsideRT: 1 # Fixes half screen.
 SLUS-21717:
   name: "Dora the Explorer - Dora Saves the Mermaids"
   region: "NTSC-U"
@@ -71087,6 +71306,7 @@ SLUS-21740:
     autoFlush: 1 # Fixes bloom intensity.
     halfPixelOffset: 4 # Mostly aligns post processing.
     nativeScaling: 1 # Fixes post processing smoothness and position.
+    getSkipCount: "GSC_GuitarHero"
 SLUS-21741:
   name: "Sea Monsters - A Prehistoric Adventure"
   region: "NTSC-U"
@@ -71176,6 +71396,7 @@ SLUS-21757:
   compat: 5
   gsHWFixes:
     cpuSpriteRenderBW: 1 # Fixes textures.
+    cpuSpriteRenderLevel: 1 # Needed for above.
     halfPixelOffset: 4 # Aligns post processing.
     autoFlush: 1 # Fixes post processing.
 SLUS-21758:
@@ -72291,8 +72512,9 @@ SLUS-28040:
   speedHacks:
     mtvu: 0
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes depth line.
+    halfPixelOffset: 5 # Fixes depth line.
     textureInsideRT: 1 # Fixes shadow and sky rendering.
+    nativeScaling: 2 # Fixes light rays.
     deinterlace: 9 # Any other method causes very bad lines on movement of the camera.
 SLUS-28043:
   name: "Test Drive - Eve of Destruction [Trade Demo]"
@@ -72352,8 +72574,8 @@ SLUS-28062:
 SLUS-28063:
   name: "Rule of Rose [Trade Demo]"
   region: "NTSC-U"
-  gsHWFixes:
-    preloadFrameData: 1 # Fixes Black FMV's.
+  gameFixes:
+    - SoftwareRendererFMVHack # Fixes black FMVs in hardware and hash cache disabling itself.
 SLUS-28064:
   name: "Shin Megami Tensei - Devil Summoner [Trade Demo]"
   region: "NTSC-U"
@@ -72563,6 +72785,8 @@ SLUS-29058:
   region: "NTSC-U"
   clampModes:
     vuClampMode: 2 # Respawn issues, Fixes SPS, avoids teleporting characters.
+  gameFixes:
+    - SoftwareRendererFMVHack # Horizontal bottom line in FMV.
   gsHWFixes:
     alignSprite: 1 # Fixes vertical lines.
 SLUS-29059:
@@ -72667,6 +72891,8 @@ SLUS-29087:
     eeClampMode: 3 # Characters are visible in-game.
   gsHWFixes:
     texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
+    textureInsideRT: 1 # Fixes post shuffle effect.
+    halfPixelOffset: 2 # Fixes boxes around shuffle effect pages.
 SLUS-29088:
   name: "Champions of Norrath - Realms of EverQuest [Demo]"
   region: "NTSC-U"
@@ -72721,8 +72947,9 @@ SLUS-29107:
   speedHacks:
     mtvu: 0
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes depth line.
+    halfPixelOffset: 5 # Fixes depth line.
     textureInsideRT: 1 # Fixes shadow and sky rendering.
+    nativeScaling: 2 # Fixes light rays.
     deinterlace: 9 # Any other method causes very bad lines on movement of the camera.
 SLUS-29108:
   name: "Def Jam - Fight for NY [Demo]"
@@ -72765,8 +72992,8 @@ SLUS-29117:
     autoFlush: 1 # Post-processing.
     halfPixelOffset: 2 # Offset post-processing.
     texturePreloading: 1 # Improves performance.
+    textureInsideRT: 1 # Fixes per line drawing.
     getSkipCount: "GSC_Battlefield2" # Depth clear.
-    beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
 SLUS-29118:
   name: "Need for Speed - Underground 2 [Demo]"
   region: "NTSC-U"
@@ -72781,9 +73008,9 @@ SLUS-29123:
     recommendedBlendingLevel: 4 # Improves banding and effect emulation.
     autoFlush: 1 # Fixes light bloom intensity.
     estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
-    halfPixelOffset: 4 # Aligns post effects.
+    halfPixelOffset: 2 # Aligns post effects.
     nativeScaling: 1 # Fixes post effects.
-    getSkipCount: "GSC_GiTS"
+    textureInsideRT: 1 # Fixes post shuffles.
 SLUS-29124:
   name: "Fight Club [Demo]"
   region: "NTSC-U"
@@ -72824,7 +73051,7 @@ SLUS-29131:
   gsHWFixes:
     autoFlush: 1 # Fixes the post processing positioning.
     textureInsideRT: 1 # Fixes post processing.
-    halfPixelOffset: 4 # Aligns bloom effect.
+    halfPixelOffset: 5 # Aligns bloom effect.
     nativeScaling: 2 # Fixes post processing smoothness and position.
 SLUS-29132:
   name: "S.L.A.I. - Steel Lancer Arena International - Phantom Crash [Public Beta Vol.1.0]"
@@ -72918,8 +73145,8 @@ SLUS-29152:
     autoFlush: 1 # Post-processing.
     halfPixelOffset: 2 # Offset post-processing.
     texturePreloading: 1 # Improves performance.
+    textureInsideRT: 1 # Fixes per line drawing.
     getSkipCount: "GSC_Battlefield2" # Depth clear.
-    beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
 SLUS-29153:
   name: "Burnout Revenge [Demo]"
   region: "NTSC-U"
@@ -73016,7 +73243,7 @@ SLUS-29169:
   gameFixes:
     - BlitInternalFPSHack # Fixes internal FPS detection.
   gsHWFixes:
-    halfPixelOffset: 2 # Fixes blurriness.
+    halfPixelOffset: 5 # Fixes blurriness.
 SLUS-29170:
   name: "Total Overdose - A Gunslinger's Tale in Mexico [Demo]"
   region: "NTSC-U"
@@ -73034,8 +73261,8 @@ SLUS-29172:
     autoFlush: 1 # Post-processing.
     halfPixelOffset: 2 # Offset post-processing.
     texturePreloading: 1 # Improves performance.
+    textureInsideRT: 1 # Fixes per line drawing.
     getSkipCount: "GSC_Battlefield2" # Depth clear.
-    beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
 SLUS-29173:
   name: "The Sims 2 [Demo]"
   name-sort: "Sims 2, The [Demo]"
@@ -73060,10 +73287,9 @@ SLUS-29178:
   gsHWFixes:
     alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
     roundSprite: 1 # Fixes misaligned map.
-    skipDrawStart: 1 # Removes large black box around player car till we properly emulate it.
-    skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
     halfPixelOffset: 2 # Fixes depth of field alignment.
     nativeScaling: 1 # Fixes depth of field.
+    textureInsideRT: 1 # Fixes shadows.
 SLUS-29179:
   name: "Sonic Riders [Demo]"
   region: "NTSC-U"
@@ -73111,6 +73337,7 @@ SLUS-29191:
     vuClampMode: 0 # Fixes bump mapping issues
   gsHWFixes:
     textureInsideRT: 1 # Fixes post processing.
+    halfPixelOffset: 5 # Fixes alignment of shuffles and post processing in Hitman.
     getSkipCount: "GSC_HitmanBloodMoney"
 SLUS-29192:
   name: "Test Drive Unlimited [Public Beta Vol.1.0]"
diff --git a/bin/resources/RedumpDatabase.yaml b/bin/resources/RedumpDatabase.yaml
index d0a17169e8..020eb849b1 100644
--- a/bin/resources/RedumpDatabase.yaml
+++ b/bin/resources/RedumpDatabase.yaml
@@ -1749,7 +1749,7 @@
 - hashes:
   - md5: f95ea9eb021181b888229df60ba8effd
     size: 2159050752
-  name: Shadow the Hedgehog (Europe, Australia) (En,Fr,De,Es,It)
+  name: Shadow the Hedgehog (Europe, Australia) (En,Ja,Fr,De,Es,It)
   serial: SLES-53542
   version: '1.01'
 - hashes:
@@ -8524,7 +8524,7 @@
 - hashes:
   - md5: ce030f48dcb588682902b5a569baa24e
     size: 4677795840
-  name: 007 - Quantum of Solace (USA)
+  name: 007 - Quantum of Solace (USA) (En,Fr)
   serial: SLUS-21813
   version: '1.00'
 - hashes:
@@ -8620,7 +8620,7 @@
 - hashes:
   - md5: c15a1707d1c89728e0c596b97ba91b27
     size: 4313153536
-  name: Official PlayStation 2 Magazine Sonderausgabe 2004-3 (Germany) (En,Fr,De,Es,It)
+  name: Official PlayStation 2 Magazine - Special Edition 2004-03 (Germany) (En,Fr,De,Es,It)
   serial: SCED-52997
   version: '1.00'
 - hashes:
@@ -8854,7 +8854,7 @@
 - hashes:
   - md5: fab56e6f617b0a64ad35221341bd167c
     size: 3529965568
-  name: Rock Band - Metal Track Pack (USA)
+  name: Rock Band - Metal Track Pack (USA, Canada)
   serial: SLUS-21889
   version: '1.00'
 - hashes:
@@ -9753,7 +9753,7 @@
 - hashes:
   - md5: 63d3e8e5da0305650160bc50f46df87b
     size: 4033478656
-  name: Fight Night Round 3 (Europe) (En,Fr)
+  name: Fight Night Round 3 (Europe, Australia) (En,Fr)
   serial: SLES-53982
   version: '1.00'
 - hashes:
@@ -13331,7 +13331,7 @@
 - hashes:
   - md5: aac303724ce688c8f242245ea0f4b9e4
     size: 877953024
-  name: Tokyo Bus Guide - Kyou kara Kimi mo Untenshu (Japan)
+  name: SuperLite 2000 Vol. 5 - Tokyo Bus Guide - Kyou kara Kimi mo Untenshu (Japan)
   serial: SLPM-65032
   version: '1.04'
 - hashes:
@@ -15880,7 +15880,7 @@
 - hashes:
   - md5: 29e5cf458549ca5321dd0c12619a002b
     size: 3846504448
-  name: Bakugan - Battle Brawlers (USA)
+  name: Bakugan - Battle Brawlers (USA) (En,Fr)
   serial: SLUS-21902
   version: '1.00'
 - hashes:
@@ -20525,7 +20525,7 @@
 - hashes:
   - md5: 2e7fcee5a1333b72eef8a18c7a673e9f
     size: 8539766784
-  name: Guitar Hero - Metallica (USA)
+  name: Guitar Hero - Metallica (USA) (En,Fr)
   serial: SLUS-21843
   version: '1.00'
 - hashes:
@@ -20868,7 +20868,7 @@
 - hashes:
   - md5: 35d939b30458790cf58ddd16ef11e159
     size: 697149264
-  name: Online Start-Up Disc 4.0 - Broadband Only (USA)
+  name: Online Start-Up Disc 4.0 - Broadband Only (USA) (v1.02)
   serial: PBPX-95248
   version: '1.02'
 - hashes:
@@ -21320,8 +21320,7 @@
 - hashes:
   - md5: 4f18266ee64804fc1ba858c5d5bee759
     size: 3782836224
-  name: Official PlayStation 2 Magazine Germany Special Edition 01-2004 (Germany)
-    (En,Fr,De,Es,It)
+  name: Official PlayStation 2 Magazine - Special Edition 2004-01 (Germany) (En,Fr,De,Es,It)
   serial: SCED-52119
   version: '1.01'
 - hashes:
@@ -21764,7 +21763,7 @@
 - hashes:
   - md5: e6159c29d23cd03252e94823045b4ff8
     size: 4071424000
-  name: DJ Hero (USA)
+  name: DJ Hero (USA) (En,Fr)
   serial: SLUS-21909
   version: '1.00'
 - hashes:
@@ -22190,7 +22189,7 @@
 - hashes:
   - md5: 007f0ccc933f59b65f28c72ad227843d
     size: 4580573184
-  name: Score International Baja 1000 - World Championship Off Road Racing (Europe)
+  name: SCORE International Baja 1000 - World Championship Off Road Racing (Europe)
   serial: SLES-55295
   version: '1.00'
 - hashes:
@@ -22862,7 +22861,7 @@
 - hashes:
   - md5: cadce0add00903396577b5d53cff1929
     size: 4679565312
-  name: Marvel Super Hero Squad (USA)
+  name: Marvel Super Hero Squad (USA) (En,Fr,Es)
   serial: SLUS-21910
   version: '1.00'
 - hashes:
@@ -22946,7 +22945,7 @@
 - hashes:
   - md5: 77ae418d710142291b5d6eb5d5d904d1
     size: 3007021056
-  name: Buzz! The Schools Quiz (Europe)
+  name: Buzz! The Schools Quiz (UK) (v2.00)
   serial: SCES-54941
   version: '2.00'
 - hashes:
@@ -30411,7 +30410,7 @@
 - hashes:
   - md5: 01abdbe56de95af5b5379cf7fea1bec0
     size: 3683680256
-  name: Ratchet & Clank 2 - Gagaga! Ginga no Commando-ssu (Japan, Asia)
+  name: Ratchet & Clank 2 - Gagaga! Ginga no Commando ssu (Japan, Asia)
   serial: SCAJ-20052
   version: '1.00'
 - hashes:
@@ -32035,7 +32034,7 @@
 - hashes:
   - md5: 47e03c7b246239330d5e41efb5160fda
     size: 1328939008
-  name: Nickelodeon Bob L'eponge - Silence on Tourne! (France)
+  name: Nickelodeon Bob L'eponge - Silence on Tourne ! (France)
   serial: SLES-53495
   version: '1.00'
 - hashes:
@@ -33603,19 +33602,19 @@
 - hashes:
   - md5: ac71dddc4a60475a689fcb6f1836e607
     size: 4307582976
-  name: Buzz! The Big Quiz (Europe) (En,Fr,Nl)
+  name: Buzz! The Big Quiz (Belgium, Netherlands) (En,Fr,Nl)
   serial: SCES-53925
   version: '1.00'
 - hashes:
   - md5: 0f457023f2a436d38a0cd53599115846
     size: 4611080192
-  name: Buzz! The Mega Quiz (Europe) (En,Fr,Nl)
+  name: Buzz! The Mega Quiz (Belgium, Netherlands) (En,Fr,Nl)
   serial: SCES-54505
   version: '1.00'
 - hashes:
   - md5: 409302dffc2512d1ccd2227d17ff6bf2
     size: 4688314368
-  name: Buzz! The Pop Quiz (Europe) (En,Fr,Nl)
+  name: Buzz! The Pop Quiz (Belgium, Netherlands) (En,Fr,Nl)
   serial: SCES-55098
   version: '1.00'
 - hashes:
@@ -34577,7 +34576,7 @@
 - hashes:
   - md5: 4703eb006c9921927145c878acd7324c
     size: 3536748544
-  name: Buzz! The Sports Quiz (Europe) (En,Fr,Nl)
+  name: Buzz! The Sports Quiz (Belgium, Netherlands) (En,Fr,Nl)
   serial: SCES-54265
   version: '1.00'
 - hashes:
@@ -36547,7 +36546,7 @@
 - hashes:
   - md5: fa7523e49dc9825589504430857c5c25
     size: 564202464
-  name: LEGO Island Xtreme Stunts (USA)
+  name: Island Xtreme Stunts (USA)
   serial: SLUS-20575
   version: '1.01'
 - hashes:
@@ -38437,7 +38436,7 @@
 - hashes:
   - md5: 06553f511a16b8cc0396bab31cc910a6
     size: 2924576768
-  name: DreamWorks Madagascar - Escape 2 Africa (USA)
+  name: DreamWorks Madagascar - Escape 2 Africa (USA) (En,Fr)
   serial: SLUS-21840
   version: '1.01'
 - hashes:
@@ -39061,7 +39060,7 @@
 - hashes:
   - md5: cc5e862a633532654176096888dfacba
     size: 2679865344
-  name: PES 2011 - Pro Evolution Soccer (USA)
+  name: PES 2011 - Pro Evolution Soccer (USA) (En,Fr,Es,Pt)
   serial: SLUS-21942
   version: '1.00'
 - hashes:
@@ -39355,7 +39354,7 @@
 - hashes:
   - md5: 298ad8520c82f4edbaacb3194bc46d5c
     size: 3530391552
-  name: PES 2010 - Pro Evolution Soccer (USA)
+  name: PES 2010 - Pro Evolution Soccer (USA) (En,Fr,Es,Pt)
   serial: SLUS-21918
   version: '1.02'
 - hashes:
@@ -39421,7 +39420,7 @@
 - hashes:
   - md5: 491a3f6a39ce290de2f6dbb9ba98575f
     size: 2129297408
-  name: PES 2013 - Pro Evolution Soccer (USA)
+  name: PES 2013 - Pro Evolution Soccer (USA) (En,Fr,Es,Pt)
   serial: SLUS-21955
   version: '1.00'
 - hashes:
@@ -39433,7 +39432,7 @@
 - hashes:
   - md5: b2d139590f169442a46d21ed2f8558ab
     size: 2437316608
-  name: PES 2012 - Pro Evolution Soccer (USA)
+  name: PES 2012 - Pro Evolution Soccer (USA) (En,Fr,Es,Pt)
   serial: SLUS-21948
   version: '1.00'
 - hashes:
@@ -39511,7 +39510,7 @@
 - hashes:
   - md5: 6821bded97877694e8cf4ccf9ca64ad4
     size: 4659347456
-  name: Vitamin Z - Welcome Our New Supplement Boys (Japan) (Genteiban)
+  name: VitaminZ - Welcome Our New Supplement Boys (Japan) (Genteiban)
   serial: SLPS-25922
   version: '1.02'
 - hashes:
@@ -39770,7 +39769,7 @@
 - hashes:
   - md5: 6f2533c2ae433f1beac4f1aa3a88f4c6
     size: 4588797952
-  name: AND 1 Streetball (USA) (v1.03)
+  name: AND 1 Streetball (USA) (En,Fr,Es) (v1.03)
   serial: SLUS-21237
   version: '1.03'
 - hashes:
@@ -39902,7 +39901,7 @@
 - hashes:
   - md5: 2d3dd4cd0d8c16e97a1a887b70349658
     size: 4636672000
-  name: Score International Baja 1000 - The Official Game (USA)
+  name: SCORE International Baja 1000 - The Official Game (USA)
   serial: SLUS-21850
   version: '1.00'
 - hashes:
@@ -40463,7 +40462,7 @@
   - md5: 08a63db4f248acdc24cdaa0b9507b854
     size: 2205908992
   name: Umishou (Japan)
-  serial: SLPM-66864
+  serial: FVGK-0001
   version: '1.01'
 - hashes:
   - md5: d3b19450aea4a9688e876fa71830aa77
@@ -40745,7 +40744,7 @@
 - hashes:
   - md5: 9be1477e6c0bd67bb6aff3a02601b4a6
     size: 1534427136
-  name: Freaky Flyers (USA) (Demo)
+  name: Freaky Flyers (USA) (Demo) (Rev 1)
   serial: SLUS-29061
   version: '0.30'
 - hashes:
@@ -41497,7 +41496,7 @@
 - hashes:
   - md5: 6dc613680039ba59d20f8baa61e56fc5
     size: 739706352
-  name: Momotarou Dentetsu 11 - Black Bombee Shutsugen! no Maki (Japan)
+  name: Momotarou Dentetsu 11 - Black Bonby Shutsugen! no Maki (Japan)
   serial: SLPM-62475
   version: '1.01'
 - hashes:
@@ -44241,7 +44240,7 @@
   - md5: 34d981b3883eaeb95c82fbed14dcad26
     size: 3115188224
   name: Harukanaru Toki no Naka de 3 (Japan) (History Box)
-  serial: SLPM-66005
+  serial: SLPM-65849
   version: '1.02'
 - hashes:
   - md5: d8ecac6d03a601d4a81f1389bfe25962
@@ -45207,13 +45206,13 @@
 - hashes:
   - md5: 29a454ebd230549939654022af5db917
     size: 4107206656
-  name: Vitamin X - We are Super Supriment Boys (Japan)
+  name: VitaminX - We are Super Supriment Boys (Japan)
   serial: SLPS-25761
   version: '1.01'
 - hashes:
   - md5: 19cc959d502b7eebae156ee760731454
     size: 4659347456
-  name: Vitamin Z - Welcome Our New Supplement Boys (Japan)
+  name: VitaminZ - Welcome Our New Supplement Boys (Japan)
   serial: SLPS-25923
   version: '1.02'
 - hashes:
@@ -46244,7 +46243,7 @@
 - hashes:
   - md5: ecb21ce06339ab6b628e077f3c03690b
     size: 3962535936
-  name: Suigetsu - Mayoi Gokoro (Japan)
+  name: Suigetsu - Mayoigokoro (Japan)
   serial: SLPM-65751
   version: '1.01'
 - hashes:
@@ -47270,7 +47269,7 @@
 - hashes:
   - md5: 68634f9b74fe47e4a039ada615970ca1
     size: 541969008
-  name: Momotarou Dentetsu 15 - Godai Bombee Toujou! no Maki (Japan) (v2.00)
+  name: Momotarou Dentetsu 15 - Godai Bonby Toujou! no Maki (Japan) (v2.00)
   serial: SLPM-74104
   version: '2.00'
 - hashes:
@@ -49343,8 +49342,7 @@
 - hashes:
   - md5: 72e49d4201496dea3e0851abf58098cf
     size: 4677992448
-  name: Official PlayStation 2 Magazine Germany Special Edition 2003-01 (Germany)
-    (En,De)
+  name: Official PlayStation 2 Magazine - Special Edition 2003-01 (Germany) (En,De)
   serial: SCED-51512
   version: '1.00'
 - hashes:
@@ -49422,7 +49420,7 @@
 - hashes:
   - md5: aa26f473fc9ecf2df7fad3a9acc30351
     size: 3115188224
-  name: Harukanaru Toki no Naka de 3 (Japan) (Triple Pack)
+  name: Harukanaru Toki no Naka de 3 (Japan) (Premium Box)
   serial: SLPM-65850
   version: '1.02'
 - hashes:
@@ -51309,12 +51307,6 @@
   name: Magazine Ufficiale PlayStation 2 Demo Italia 05-2006 (Italy) (En,Fr,De,Es,It)
   serial: SCED-54180
   version: '1.00'
-- hashes:
-  - md5: 0b14951eb38e4f5f4730bcf48bf64898
-    size: 4569923584
-  name: Magazine Ufficiale PlayStation 2 Italia 05-04 (Italy) (En,Fr,De,Es,It)
-  serial: SCED-52443
-  version: '1.00'
 - hashes:
   - md5: 771bfe48ce1a10c8a638da8bedc9acf6
     size: 4175429632
@@ -51698,13 +51690,13 @@
 - hashes:
   - md5: cf45002cd37168e4a2b3a8f96c560941
     size: 3983638528
-  name: Official PlayStation 2 Magazine Germany Special 2-2005 (Germany)
+  name: Official PlayStation 2 Magazine - Special Edition 2005-02 (Germany)
   serial: SCED-53662
   version: '1.00'
 - hashes:
   - md5: 8191fa8441cd8c947ab80b9db6de0ce3
     size: 4583129088
-  name: Official PlayStation 2 Magazine Germany Special 3-2005 (Germany)
+  name: Official PlayStation 2 Magazine - Special Edition 2005-03 (Germany)
   serial: SCED-53938
   version: '1.00'
 - hashes:
@@ -51818,7 +51810,7 @@
 - hashes:
   - md5: 8e18b5399008416a7d012f2ea1bf9353
     size: 663976656
-  name: Pro Evolution Soccer 3 (Europe) (Demo 1)
+  name: Pro Evolution Soccer 3 (UK) (Demo)
   serial: SLED-51992
   version: '1.00'
 - hashes:
@@ -51950,7 +51942,7 @@
 - hashes:
   - md5: 209c4247ffb84795b23ce2cec0f090a4
     size: 3793453056
-  name: Official PlayStation 2 Magazine Germany Special Edition 2003-03 (Germany)
+  name: Official PlayStation 2 Magazine - Special Edition 2003-03 (Germany)
   serial: SCED-51551
   version: '1.00'
 - hashes:
@@ -52038,7 +52030,7 @@
 - hashes:
   - md5: e8e5b428c642c78d510cbd854c17b9cc
     size: 1616740352
-  name: Primal + The Mark of Kri + War of the Monsters (Europe) (En,Fr,De,Es,It)
+  name: Primal & The Mark of Kri & War of the Monsters (Europe) (En,Fr,De,Es,It)
   serial: SCED-51506
   version: '1.00'
 - hashes:
@@ -52350,7 +52342,7 @@
 - hashes:
   - md5: d42eed1d14cdaf8add8295116776a447
     size: 3765108736
-  name: Best PS2 Games Ever 10 (Europe)
+  name: Official PlayStation 2 Magazine-UK Special Edition - Yearbook 2002 (Europe)
   serial: SCED-51389
   version: '1.00'
 - hashes:
@@ -52637,7 +52629,7 @@
 - hashes:
   - md5: cded45ee044b5a7614644fa444a59989
     size: 4334157824
-  name: Official PlayStation 2 Magazine Germany Special Edition 2003-02 (Germany)
+  name: Official PlayStation 2 Magazine - Special Edition 2003-02 (Germany)
   serial: SCED-51549
   version: '1.01'
 - hashes:
@@ -53111,7 +53103,7 @@
 - hashes:
   - md5: f309b4b48dc775dbbde635a1ef3b662b
     size: 4522639360
-  name: Germany Special Issue 3 (Germany)
+  name: Official PlayStation 2 Magazine - Special Edition 3 (Germany)
   serial: SCED-51375
   version: '1.00'
 - hashes:
@@ -54054,7 +54046,7 @@
 - hashes:
   - md5: ac5b76bd39b0cabd1acfe4dcb08df502
     size: 1649803264
-  name: Primal + The Mark of Kri (Europe)
+  name: Primal & The Mark of Kri (Europe)
   serial: SCED-51491
   version: '1.00'
 - hashes:
@@ -54085,7 +54077,7 @@
 - hashes:
   - md5: 2475b61666f06dc2aa9ca032f15a4cde
     size: 4241293312
-  name: Official PlayStation 2 Magazine Germany Special Edition 2007-1 (Germany)
+  name: Official PlayStation 2 Magazine - Special Edition 2007-01 (Germany)
   serial: SCED-54693
   version: '1.02'
 - hashes:
@@ -54462,7 +54454,7 @@
 - hashes:
   - md5: 97a9156abd199f588d4f46e9af7ab5a7
     size: 4107206656
-  name: Vitamin X - We are Super Supriment Boys (Japan) (Genteiban)
+  name: VitaminX - We are Super Supriment Boys (Japan) (Genteiban)
   serial: SLPS-25760
   version: '1.01'
 - hashes:
@@ -54767,7 +54759,7 @@
 - hashes:
   - md5: a4b5b1d6c13c15bc1bac6fc63622c9ee
     size: 2925920256
-  name: Ever 17 - The Out of Infinity Premium Edition (Japan)
+  name: Ever 17 - The Out of Infinity - Premium Edition (Japan)
   serial: SLPM-65421
   version: '1.01'
 - hashes:
@@ -55910,7 +55902,7 @@
 - hashes:
   - md5: 05b210d50d92a418ac1e37a1fff0df8a
     size: 243996480
-  name: Giant Robo - The Animation - Chikyuu ga Seishi suru Hi (Japan)
+  name: Giant Robo - The Animation - Chikyuu ga Seishi Suru Hi (Japan)
   serial: SLPM-62526
   version: '1.02'
 - hashes:
@@ -56111,7 +56103,7 @@
 - hashes:
   - md5: 45d62f1cf862b8e6c47d373a5c55d2f2
     size: 708511776
-  name: Pro Evolution Soccer 4 (Europe) (Demo)
+  name: Pro Evolution Soccer 4 (UK) (Demo)
   serial: SLED-52873
   version: '1.02'
 - hashes:
@@ -56171,7 +56163,7 @@
 - hashes:
   - md5: 139585af1bf276d5f2e17a32def4f66d
     size: 4528504832
-  name: Official PlayStation 2 Magazine Germany Special Edition 1 (Germany)
+  name: Official PlayStation 2 Magazine - Special Edition 1 (Germany)
   serial: SCED-50780
   version: '1.10'
 - hashes:
@@ -57668,7 +57660,7 @@
 - hashes:
   - md5: 1ce4a9368f7c6c73dcd983ad5f86f3eb
     size: 718702992
-  name: MaxPlay (Europe) (Unl)
+  name: Max Play (Europe) (Unl)
   version: 1.00 (European)
 - hashes:
   - md5: 8182f27cc5a0cac14da217e45861e49e
@@ -57841,8 +57833,7 @@
 - hashes:
   - md5: 4fb718d2059a1843882a70b17922b483
     size: 4613996544
-  name: Official PlayStation 2 Magazine Germany Special Edition 2005-01 (Germany)
-    (En,De)
+  name: Official PlayStation 2 Magazine - Special Edition 2005-01 (Germany) (En,De)
   serial: SCED-53298
   version: '1.02'
 - hashes:
@@ -57854,7 +57845,7 @@
 - hashes:
   - md5: 739a2f519751c64f7291d036105c2c0d
     size: 1670316032
-  name: Buzz! Junior - Robojam (Europe) (Beta) (2007-01-12)
+  name: Buzz! Junior - RoboJam (Europe) (Beta) (2007-01-12)
   serial: SCES-54676
   version: '1.00'
 - hashes:
@@ -58392,7 +58383,7 @@
 - hashes:
   - md5: 6969a8f3623387131e2e1d49fff4c3f5
     size: 4492853248
-  name: Magical Tale - Chiicha na Mahoutsukai (Japan)
+  name: Magical Tale - Chitcha na Mahoutsukai (Japan)
   serial: SLPM-65965
   version: '1.01'
 - hashes:
@@ -59340,7 +59331,7 @@
 - hashes:
   - md5: 8d61b97a6dd45165b012b338d42e53a8
     size: 2358018048
-  name: Harry Potter and the Prisoner of Azkaban (Korea)
+  name: Harry Potter-wa Azkaban-ui Joesu (Korea)
   serial: SLKA-25172
   version: '1.01'
 - hashes:
@@ -59646,7 +59637,7 @@
 - hashes:
   - md5: 1162e6411d9e16fbefc9fd8a9e886d70
     size: 4412145664
-  name: Official PlayStation 2 Magazine Germany Winter 2006 (Germany) (En,De)
+  name: Official PlayStation 2 Magazine - Winter 2006 (Germany) (En,De)
   serial: SCED-54558
   version: '1.00'
 - hashes:
@@ -60504,7 +60495,7 @@
 - hashes:
   - md5: 78f327cd6c0f2bd6f99a299e982b9a93
     size: 1253867520
-  name: TOCA Race Driver 3 + V8 Supercars Australia 3 (Australia) (Demo)
+  name: TOCA Race Driver 3 (Australia) (Demo)
   serial: SLED-53888
   version: '1.00'
 - hashes:
@@ -60764,7 +60755,7 @@
 - hashes:
   - md5: 7e964b27119adc590228452d42c634b0
     size: 4614062080
-  name: Buzz! Hollywood Quiz (Europe) (En,Fr,Nl)
+  name: Buzz! Hollywood Quiz (Belgium, Netherlands) (En,Fr,Nl)
   serial: SCES-54854
   version: '1.00'
 - hashes:
@@ -62041,7 +62032,7 @@
 - hashes:
   - md5: dd5ccdc3e325716d7f7ed08a9836f3f0
     size: 3938189312
-  name: PlayStation 2 Revista Oficial - Portugal 9 (Portugal)
+  name: Official PlayStation 2 Magazine Demo 32 (Portugal)
   serial: SCED-51657
   version: '1.00'
 - hashes:
@@ -62487,7 +62478,7 @@
 - hashes:
   - md5: fe79ea717184a278802679ef78f6df7b
     size: 7774928896
-  name: Zhen San Guo Wu Shuang 5 Special (Taiwan)
+  name: Zhen Sanguo Wushuang 5 Special (Taiwan)
   serial: SLAJ-35007
   version: '1.00'
 - hashes:
@@ -63024,7 +63015,7 @@
 - hashes:
   - md5: 18e6281d238ccb19e8975d45e8c157f0
     size: 3816554496
-  name: Offizielle PlayStation 2 Magazin 02-2004, Das - Uncut Edition (Germany)
+  name: Official PlayStation 2 Magazine 02-2004 - Uncut Edition (Germany)
   serial: SCED-52082
   version: '1.01'
 - hashes:
@@ -63141,7 +63132,7 @@
 - hashes:
   - md5: d38ab694e14843f16af11a15d1883023
     size: 4677795840
-  name: Koi suru Otome to Shugo no Tate - The Shield of AIGIS (Japan)
+  name: Koi Suru Otome to Shugo no Tate - The Shield of AIGIS (Japan)
   serial: SLPM-55098
   version: '1.02'
 - hashes:
@@ -63554,7 +63545,7 @@
 - hashes:
   - md5: 3acdf0ae8cc67fe9e0db9f4707cb3905
     size: 2638381056
-  name: I Love Baseball - Pro Yakyuu o Koyonaku Ai suru Hitotachi e (Japan)
+  name: I Love Baseball - Pro Yakyuu o Koyonaku Ai Suru Hitotachi e (Japan)
   serial: SLPM-65633
   version: '1.04'
 - hashes:
@@ -63941,13 +63932,13 @@
 - hashes:
   - md5: 7ea2da0f39ae55794fd9fd5006b417cc
     size: 4446388224
-  name: Offizielle PlayStation 2 Magazin 09-2004, Das (Germany)
+  name: Official PlayStation 2 Magazine 09-2004 (Germany)
   serial: SCED-52089
   version: '1.02'
 - hashes:
   - md5: 11b80bd02a0a874212b014c56e44a4c5
     size: 4033347584
-  name: Offizielle PlayStation 2 Magazin 12-2003, Das (Germany)
+  name: Official PlayStation Magazine 12-2003 (Germany)
   serial: SCED-51936
   version: '1.00'
 - hashes:
@@ -64181,7 +64172,7 @@
 - hashes:
   - md5: 8990d1c3b88b04b1bbc7a78ee3e9df2f
     size: 33821760
-  name: Karat PS2-you Pro Action Replay 2 Taikenban (Japan) (Unl)
+  name: Karat PS2-you Pro Action Replay 2 Taikenban (Japan) (Unl) (Rev 1)
   version: '1.7'
 - hashes:
   - md5: 4a2754811946ef9badbbd872f541a03f
@@ -64254,7 +64245,7 @@
 - hashes:
   - md5: 0e35e8fd22fe57f8727b9764685bbc29
     size: 3871703040
-  name: Offizielle PlayStation 2 Magazin, Das - Special Edition 2 (Germany)
+  name: Official PlayStation 2 Magazine - Special Edition 2 (Germany)
   serial: SCED-51161
   version: '1.00'
 - hashes:
@@ -64563,7 +64554,7 @@
 - hashes:
   - md5: 477eb508b08f59386478908e481eb8a1
     size: 4519690240
-  name: Official PlayStation 2 Magazine - German Kids Special (Germany) (En,De)
+  name: Official PlayStation 2 Magazine - Kids Special (Germany) (En,De)
   serial: SCED-53611
   version: '1.00'
 - hashes:
@@ -64580,7 +64571,7 @@
 - hashes:
   - md5: ac9cb481855792415314e06e5c12b291
     size: 664183632
-  name: Pro Evolution Soccer 3 (Europe) (Demo 2)
+  name: Pro Evolution Soccer 3 (Europe) (Demo)
   serial: SLED-51994
   version: '1.00'
 - hashes:
@@ -65185,7 +65176,7 @@
 - hashes:
   - md5: 86af0c99c8a8566e5f9307110f339e20
     size: 364475328
-  name: Monopoly - Mezase!! Daifugou Jinsei!! (Japan)
+  name: Monopoly - Mezase!! Daifugou Jinsei!! (Japan) (v2.00)
   serial: SLPS-20281
   version: '2.00'
 - hashes:
@@ -66352,7 +66343,7 @@
 - hashes:
   - md5: ff59d561b843dbbb940c631d53294d63
     size: 1552318464
-  name: Monsterspass (Austria, Switzerland) (En,Fr,De,Es,It,Nl,Pt)
+  name: Monsterspass (Austria) (En,Fr,De,Es,It,Nl,Pt)
   serial: SCES-54704
   version: '1.00'
 - hashes:
@@ -66436,7 +66427,7 @@
 - hashes:
   - md5: 79fc6bc53ff748088a36d2f6778d0a0b
     size: 1943797760
-  name: Big! Sports Quiz, The (Austria, Switzerland)
+  name: Big! Sports Quiz, The (Austria)
   serial: SCES-54526
   version: '1.00'
 - hashes:
@@ -66803,7 +66794,7 @@
 - hashes:
   - md5: 91450691bed8af904b291c4d86c0c338
     size: 1645182976
-  name: Jungle Party (Austria, Switzerland)
+  name: Jungle Party (Austria)
   serial: SCES-54524
   version: '1.01'
 - hashes:
@@ -66934,7 +66925,7 @@
 - hashes:
   - md5: 777cd430a73b95945cee679a27446eed
     size: 2297200640
-  name: Disney-Pixar Finding Nemo (Korea)
+  name: Disney-Pixar Nemo-reul Chajaseo (Korea)
   serial: SLKA-25056
   version: '1.00'
 - hashes:
@@ -68550,7 +68541,7 @@
 - hashes:
   - md5: 5b315096f6bfc1897e52fec9c877b81d
     size: 4250206208
-  name: Offizielle PlayStation 2 Magazin 13-2003, Das - Uncut Edition (Germany)
+  name: Official PlayStation 2 Magazine 13-2003 - Uncut Edition (Germany)
   serial: SCED-51937
   version: '1.00'
 - hashes:
@@ -69278,7 +69269,7 @@
 - hashes:
   - md5: 6905874bbb6167417bac324464d70d28
     size: 541969008
-  name: Momotarou Dentetsu 15 - Godai Bombee Toujou! no Maki (Japan) (v1.01)
+  name: Momotarou Dentetsu 15 - Godai Bonby Toujou! no Maki (Japan) (v1.01)
   serial: SLPM-62702
   version: '1.01'
 - hashes:
@@ -69326,7 +69317,7 @@
 - hashes:
   - md5: 950783ce0723d41ff7aa46659a6eafbc
     size: 4492853248
-  name: Magical Tale - Chiicha na Mahoutsukai (Japan) (Shokai Genteiban)
+  name: Magical Tale - Chitcha na Mahoutsukai (Japan) (Shokai Genteiban)
   serial: SLPM-65964
   version: '1.01'
 - hashes:
@@ -69341,3 +69332,240 @@
   name: Quilt - Anata to Tsumugu Yume to Koi no Dress (Japan)
   serial: SLPM-66735
   version: '1.02'
+- hashes:
+  - md5: ad64473c57824cf607cf40a7d85cf36c
+    size: 2300313600
+  name: Guitar Hero (USA) (Demo)
+  serial: SLUS-29177
+  version: '1.00'
+- hashes:
+  - md5: 667607deb941380aa4d13db387b93077
+    size: 93254448
+  name: Codes Exclusifs (France) (Unl)
+  version: '1.00'
+- hashes:
+  - md5: 589e37362d073b8ad52670cdd5664415
+    size: 1822326784
+  name: DearS (Japan) (Genteiban)
+  serial: SLPS-25371
+  version: '1.04'
+- hashes:
+  - md5: 4afb874dc19e35051e79f7a881a584b4
+    size: 1524793344
+  name: Winning Post 6 - 2005-nendoban (Japan) (Premium Pack)
+  serial: SLPM-65893
+  version: '1.01'
+- hashes:
+  - md5: 132ce8a9e16ca7ef5a356aa111bce318
+    size: 4354473984
+  name: Jak 3 (Europe) (En,Fr,De,Es,It,Pt,Ko,Ru) (Beta) (2004-09-14)
+  serial: SCES-52460
+  version: '1.00'
+- hashes:
+  - md5: 6432d610b89d00eb1eea2ee71cf27147
+    size: 3007119360
+  name: Buzz! The Schools Quiz (UK) (v1.00)
+  serial: SCES-54941
+  version: '1.00'
+- hashes:
+  - md5: 3c47093b42a1e1a39692b220e7659ad9
+    size: 4601774080
+  name: Big! Pop Quiz, The (Austria)
+  serial: SCES-55099
+  version: '1.00'
+- hashes:
+  - md5: 859073451dbb344df7cee32703245ed5
+    size: 306380800
+  name: Freaky Flyers (USA) (Demo)
+  serial: SLUS-29051
+  version: '1.00'
+- hashes:
+  - md5: 8d987ddccb1e2ec4c068896a4182bc4c
+    size: 1542029312
+  name: Tennis no Oujisama - Smash Hit! 2 (Japan) (Shokai SP Genteiban C-Type)
+  serial: SLPM-65453
+  version: '1.01'
+- hashes:
+  - md5: b0a2a871249538d80b92e7ef837f20dd
+    size: 761692848
+  name: CD avec les Codes Action Replay Exclusivement pour le Jeu Enter the Matrix
+    (France)
+  version: 1.01 (European)
+- hashes:
+  - md5: db0c13bd5bddb659d563b4e2c0fcd5e8
+    size: 226549344
+  name: Action Replay Ultimate Cheats for Use with Grand Theft Auto - Vice City (UK)
+    (Unl)
+  version: '1.30'
+- hashes:
+  - md5: 7866eaffddb52bbf7375ab4deca20dd6
+    size: 33821760
+  name: Karat PS2-you Pro Action Replay 2 Taikenban (Japan) (Unl)
+  version: '1.7'
+- hashes:
+  - md5: 76b15475cac6977f2510ea07d9b87043
+    size: 4348444672
+  name: Official PlayStation 2 Magazine - Special Edition 2006-01 (Germany)
+  serial: SCED-54034
+  version: '1.00'
+- hashes:
+  - md5: c9f8be1699b50935c1e1989cd76bdbe1
+    size: 697118688
+  name: Online Start-Up Disc 4.0 - Broadband Only (USA) (v1.01)
+  serial: PBPX-95248
+  version: '1.01'
+- hashes:
+  - md5: d7cfe2da9a3598cb10bc61abd2657acd
+    size: 3497885696
+  name: Big! Movie Quiz, The (Austria)
+  serial: SCES-54857
+  version: '1.00'
+- hashes:
+  - md5: 875894a624cc3d7bc81311985b5eeff7
+    size: 549201408
+  name: Argus-ui Jeonsa (Korea) (Cheheompan)
+  serial: SCKA-90005
+  version: '1.00'
+- hashes:
+  - md5: 7f3b5e111ca4c77039a1641fe2785423
+    size: 3271229440
+  name: Mai-Otome HiME - Otome Butoushi!! (Japan) (Limited Edition)
+  serial: SLPS-25680
+  version: '1.01'
+- hashes:
+  - md5: 5626f8c491117a0924380c786ab7e458
+    size: 3049783296
+  name: Fire It Up Kids (Europe)
+  serial: SCED-53678
+  version: '1.00'
+- hashes:
+  - md5: 7d6503407ba1ea104753be2bfe1283e3
+    size: 2560065536
+  name: Nickelodeon SpongeBob SquarePants - Movin' with Friends (Europe) (En,Fr,De,Es)
+    (Beta) (2004-10-29)
+- hashes:
+  - md5: baf280135d74603e097a813d52e25afa
+    size: 707949648
+  name: Pro Evolution Soccer 4 (Europe) (Demo)
+  serial: SLED-52878
+  version: '1.03'
+- hashes:
+  - md5: 1fa77218061839d6ac9b39159fa46680
+    size: 1249804288
+  name: SingStar Rocks! (Europe) (Demo)
+  serial: SCED-54086
+  version: '1.00'
+- hashes:
+  - md5: 2d91ab06f6fc0f918c9389990df71a63
+    size: 1378156544
+  name: This Is Football 2004 (Belgium) (Demo)
+  serial: SCED-52321
+  version: '1.01'
+- hashes:
+  - md5: 6917a832cf75177a18c4ef4499966ba4
+    size: 3448471552
+  name: Official PlayStation 2 Magazine Demo 10 (Spain)
+  serial: SCED-50406
+- hashes:
+  - md5: e1615a414d9b561e70b395155edb7e39
+    size: 4697686016
+  name: Chaos Legion (Europe) (Demo)
+  serial: SLED-51808
+  version: '1.00'
+- hashes:
+  - md5: 670fabe932a7ad8b81f6356d162cdac6
+    size: 4569923584
+  name: Magazine Ufficiale PlayStation 2 Italia 05-04 (Italy) (En,Fr,De,Es,It)
+  serial: SCED-52443
+  version: '1.00'
+- hashes:
+  - md5: dd4dd82c735f0189b5cd91c0c5e4b327
+    size: 364472976
+  name: Monopoly - Mezase!! Daifugou Jinsei!! (Japan) (v1.04)
+  serial: SLPS-20281
+  version: '1.04'
+- hashes:
+  - md5: 2be7a399436665d532383e9e6d21f7fb
+    size: 1632665600
+  name: Musashiden II - Blademaster (Japan) (Taikenban)
+  serial: SLPM-61117
+  version: '1.00'
+- hashes:
+  - md5: 85f8dd4c84ac2fd97f4b154280c01910
+    size: 1239580672
+  name: Bratz - Rock Angelz (Denmark)
+  serial: SLES-53578
+  version: '1.00'
+- hashes:
+  - md5: 36c27c981bfdd9f311ecc36da4ad7071
+    size: 598507520
+  name: Metal Gear Solid 2 - Sons of Liberty (Europe) (En,Fr,De) (Demo)
+  serial: SLED-50782
+  version: '1.00'
+- hashes:
+  - md5: 626b946f71116a9ec455b41c0fb8aa3a
+    size: 2710274048
+  name: Bonus Demo 7 (15-16) (Europe)
+  serial: SCED-52437
+  version: '1.02'
+- hashes:
+  - md5: 2696c838c64d0f7f0c86adc5bbc1f54a
+    size: 4292870144
+  name: Buzz! The Big Quiz (Switzerland) (Fr,De,It)
+  serial: SCES-54071
+  version: '1.00'
+- hashes:
+  - md5: 865cb20ccc3b938879eb3cae955ab70c
+    size: 4598398976
+  name: Buzz! The Mega Quiz (Switzerland) (Fr,De,It)
+  serial: SCES-54506
+  version: '1.00'
+- hashes:
+  - md5: f543c17d10aa576cc4ea74622a7050ee
+    size: 750130416
+  name: Code Breaker (USA) (Unl) (v4.0)
+  version: '4.0'
+- hashes:
+  - md5: bae22925feb7587573b663cc83bc1eb3
+    size: 2719285248
+  name: Kaido Battle 2 - Chain Reaction (Korea)
+  serial: SLKA-25146
+  version: '1.02'
+- hashes:
+  - md5: 92c7a59eb4650bbc8a429970640b871b
+    size: 748700400
+  name: Time Crisis II (Europe) (Demo)
+  serial: SCED-50473
+  version: '1.01'
+- hashes:
+  - md5: fd46dd639a28f9f8ec7475f999d8b653
+    size: 2786852864
+  name: Call of Duty - World at War - Final Fronts (Korea)
+  serial: SLKA-25449
+  version: '1.00'
+- hashes:
+  - md5: 41ccada9d75b88b20adf6db41349df52
+    size: 4511367168
+  name: Shijag-ui Ilbo All Stars (Korea)
+  serial: SLKA-25152
+  version: '1.01'
+- hashes:
+  - md5: d46987283a22024d4b8e3e36c597035f
+    size: 4116643840
+  name: Fight Night Round 2 (Europe, Australia) (Demo)
+  serial: SLED-53126
+  version: '1.00'
+- hashes:
+  - md5: 22a1b12df6fae4ecd8da5bed8cd91dd6
+    size: 4192600064
+  name: SOCOM 3 - U.S. Navy SEALs (USA) (Beta) (2005-09-08)
+- hashes:
+  - md5: 3a04c1e3548d8169271336a73ae67e93
+    size: 566942544
+  name: Taz - Wanted (Europe)  (2002-01-29)
+  version: Beta
+- hashes:
+  - md5: ecb58db2de607ed68a215d052381a83b
+    size: 245814576
+  name: Taz - Wanted (Europe)  (2001-05-31)
+  version: Beta
diff --git a/bin/resources/game_controller_db.txt b/bin/resources/game_controller_db.txt
index e695cf9a5e..532e6dfbb8 100644
--- a/bin/resources/game_controller_db.txt
+++ b/bin/resources/game_controller_db.txt
@@ -193,6 +193,7 @@
 030000007d0400000640000000000000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Windows,
 03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
 03000000430b00000300000000000000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
+03000000062000001801000000000000,EMS TrioLinker Plus II,a:b0,b:b1,x:b2,y:b3,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,platform:Windows,
 03000000242f000000b7000000000000,ESM 9110,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Windows,
 03000000101c0000181c000000000000,Essential,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b4,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
 030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
@@ -610,6 +611,7 @@
 03000000921200004547000000000000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b6,x:b3,y:b4,platform:Windows,
 03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
 03000000830500006020000000000000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
+03000000632500007805000000000000,Retro Fighters Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
 0300000003040000c197000000000000,Retrode Adapter,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
 03000000bd12000013d0000000000000,Retrolink Sega Saturn Classic Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,
 03000000bd12000015d0000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
@@ -757,8 +759,8 @@
 03000000ff1100004133000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
 03000000632500002305000000000000,USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
 03000000882800000305000000000000,V5 Game Pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,x:b2,y:b3,platform:Windows,
-03000000790000001a18000000000000,Venom,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
+03000000790000001a18000000000000,Venom PS4 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000790000001b18000000000000,Venom PS4 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
 030000006f0e00000302000000000000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
 030000006f0e00000702000000000000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
 0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:a3,righty:a4,start:b4,x:b2,y:b3,platform:Windows,
@@ -1246,6 +1248,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 05000000bc2000000055000001000000,Betop AX1 BFM,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:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
 03000000bc2000006412000011010000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b30,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,
 030000006b1400000209000011010000,Bigben,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,
+03000000120c0000300e000011010000,Brook Audio Fighting Board PS3,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,
+03000000120c0000310e000011010000,Brook Audio Fighting Board PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger: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,
 03000000120c0000200e000011010000,Brook Mars 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:Linux,
 03000000120c0000210e000011010000,Brook Mars 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:a3,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
 03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
@@ -1286,7 +1290,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
 190000004b4800000010000000010000,GO-Advance Controller,a:b1,b:b0,back:b10,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,leftshoulder:b4,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b13,start:b15,x:b2,y:b3,platform:Linux,
 190000004b4800000010000001010000,GO-Advance Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b13,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b16,righttrigger:b15,start:b17,x:b2,y:b3,platform:Linux,
-190000004b4800000011000000010000,GO-Super Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b2,y:b3,platform:Linux,
+190000004b4800000011000000010000,GO-Super Gamepad,a:b0,b:b1,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b3,y:b2,platform:Linux,
 03000000f0250000c183000010010000,Goodbetterbest Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
 03000000d11800000094000011010000,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
 05000000d11800000094000000010000,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
@@ -1423,6 +1427,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 030000005e040000d102000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000005e040000dd02000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000005e040000ea02000008040000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000005e040000ea0200000f050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000005e040000e302000003020000,Microsoft Xbox One Elite,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000005e040000000b000007040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b12,paddle2:b14,paddle3:b13,paddle4:b15,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -1430,7 +1435,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
 050000005e0400008e02000030110000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000005e040000120b00000b050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-060000005e040000120b000001050000,Microsoft Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000005e040000120b000016050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000005e040000120b000017050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+060000005e040000120b000001050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
 03000000790000001c18000010010000,Mobapad Chitu HD,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
 050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
@@ -1448,6 +1455,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000006b140000010c000010010000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
 03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+05000000853200000503000000010000,Nacon MG-X Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
 0300000085320000170d000011010000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
 0300000085320000190d000011010000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
 030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -1492,7 +1500,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 030000006f0e0000b802000001010000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000006f0e0000b802000013020000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000006f0e00008501000011010000,PDP Fightpad Pro Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
 030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -1507,7 +1515,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 030000006f0e0000ef02000007640000,PDP Xbox Series Kinetic Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000d62000000540000001010000,PowerA Advantage Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+03000000d62000000540000001010000,PowerA Advantage Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 03000000d620000011a7000011010000,PowerA Core Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
 03000000dd62000015a7000011010000,PowerA Fusion Nintendo Switch Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
 03000000d620000012a7000011010000,PowerA Fusion Nintendo Switch Fight Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -1522,9 +1530,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 03000000d62000000228000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 03000000c62400001a54000001010000,PowerA Xbox One Mini Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+03000000d62000000520000050010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+03000000d62000000b20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 03000000d62000000f20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000d62000000520000050010000,PowerA Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000d62000000b20000001010000,PowerA Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
 03000000250900000017000010010000,PS/SS/N64 Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b5,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2~,righty:a3,start:b8,platform:Linux,
 03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
@@ -1582,6 +1590,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
 030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
 030000009b2800008000000020020000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
+030000009b2800008000000001010000,Raphnet Wii Classic Adapter V3,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
 03000000f8270000bf0b000011010000,Razer Kishi,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,
 030000008916000001fd000024010000,Razer Onza Classic Edition,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,
 03000000321500000204000011010000,Razer Panthera PS3,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,
@@ -1716,6 +1725,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
 03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,
 03000000790000001100000000010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,
+03000000790000001a18000011010000,Venom PS4 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000790000001b18000011010000,Venom PS4 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
 030000006f0e00000302000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
 030000006f0e00000702000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
 05000000ac0500003232000001000000,VR Box Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
@@ -1757,6 +1768,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 030000005e040000120b000009050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000005e040000120b000011050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000005e040000120b000014050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000005e040000120b000015050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
 050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
@@ -1766,13 +1779,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
 050000005e040000130b000011050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
 050000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
 050000005e040000130b000015050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+050000005e040000130b000017050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
 060000005e040000120b000007050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+060000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 060000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e040000120b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e040000120b000014050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-050000005e040000130b000017050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
-060000005e040000120b00000d050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
 050000005e040000200b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
 050000005e040000220b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
diff --git a/bin/resources/icons/flags/LICENSE b/bin/resources/icons/flags/LICENSE
new file mode 100644
index 0000000000..31e4b04f2f
--- /dev/null
+++ b/bin/resources/icons/flags/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Twitter
+
+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.
diff --git a/bin/resources/icons/flags/NTSC-B.png b/bin/resources/icons/flags/NTSC-B.png
deleted file mode 100644
index 99585b0887..0000000000
Binary files a/bin/resources/icons/flags/NTSC-B.png and /dev/null differ
diff --git a/bin/resources/icons/flags/NTSC-B.svg b/bin/resources/icons/flags/NTSC-B.svg
new file mode 100644
index 0000000000..956e39d071
--- /dev/null
+++ b/bin/resources/icons/flags/NTSC-B.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/NTSC-C.png b/bin/resources/icons/flags/NTSC-C.png
deleted file mode 100644
index effa003233..0000000000
Binary files a/bin/resources/icons/flags/NTSC-C.png and /dev/null differ
diff --git a/bin/resources/icons/flags/NTSC-C.svg b/bin/resources/icons/flags/NTSC-C.svg
new file mode 100644
index 0000000000..c10116d0a2
--- /dev/null
+++ b/bin/resources/icons/flags/NTSC-C.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/NTSC-HK.png b/bin/resources/icons/flags/NTSC-HK.png
deleted file mode 100644
index 737d180fea..0000000000
Binary files a/bin/resources/icons/flags/NTSC-HK.png and /dev/null differ
diff --git a/bin/resources/icons/flags/NTSC-HK.svg b/bin/resources/icons/flags/NTSC-HK.svg
new file mode 100644
index 0000000000..ef5ca3bcef
--- /dev/null
+++ b/bin/resources/icons/flags/NTSC-HK.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/NTSC-J.png b/bin/resources/icons/flags/NTSC-J.png
deleted file mode 100644
index f8f74b91c6..0000000000
Binary files a/bin/resources/icons/flags/NTSC-J.png and /dev/null differ
diff --git a/bin/resources/icons/flags/NTSC-J.svg b/bin/resources/icons/flags/NTSC-J.svg
new file mode 100644
index 0000000000..02986dc98b
--- /dev/null
+++ b/bin/resources/icons/flags/NTSC-J.svg
@@ -0,0 +1 @@
+
diff --git a/bin/resources/icons/flags/NTSC-K.png b/bin/resources/icons/flags/NTSC-K.png
deleted file mode 100644
index 4cc4f4a8c1..0000000000
Binary files a/bin/resources/icons/flags/NTSC-K.png and /dev/null differ
diff --git a/bin/resources/icons/flags/NTSC-K.svg b/bin/resources/icons/flags/NTSC-K.svg
new file mode 100644
index 0000000000..0f06dbb3fa
--- /dev/null
+++ b/bin/resources/icons/flags/NTSC-K.svg
@@ -0,0 +1 @@
+
diff --git a/bin/resources/icons/flags/NTSC-T.png b/bin/resources/icons/flags/NTSC-T.png
deleted file mode 100644
index 9ee09d37c1..0000000000
Binary files a/bin/resources/icons/flags/NTSC-T.png and /dev/null differ
diff --git a/bin/resources/icons/flags/NTSC-T.svg b/bin/resources/icons/flags/NTSC-T.svg
new file mode 100644
index 0000000000..4cd304e16a
--- /dev/null
+++ b/bin/resources/icons/flags/NTSC-T.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/NTSC-U.png b/bin/resources/icons/flags/NTSC-U.png
deleted file mode 100644
index 587bf92547..0000000000
Binary files a/bin/resources/icons/flags/NTSC-U.png and /dev/null differ
diff --git a/bin/resources/icons/flags/NTSC-U.svg b/bin/resources/icons/flags/NTSC-U.svg
new file mode 100644
index 0000000000..f5a7a01477
--- /dev/null
+++ b/bin/resources/icons/flags/NTSC-U.svg
@@ -0,0 +1,34 @@
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/Other.png b/bin/resources/icons/flags/Other.png
deleted file mode 100644
index 504fd9813d..0000000000
Binary files a/bin/resources/icons/flags/Other.png and /dev/null differ
diff --git a/bin/resources/icons/flags/Other.svg b/bin/resources/icons/flags/Other.svg
new file mode 100644
index 0000000000..7d32f8d108
--- /dev/null
+++ b/bin/resources/icons/flags/Other.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-A.png b/bin/resources/icons/flags/PAL-A.png
deleted file mode 100644
index 8052c63315..0000000000
Binary files a/bin/resources/icons/flags/PAL-A.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-A.svg b/bin/resources/icons/flags/PAL-A.svg
new file mode 100644
index 0000000000..989da76df5
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-A.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-AF.png b/bin/resources/icons/flags/PAL-AF.png
deleted file mode 100644
index 106ee79a9b..0000000000
Binary files a/bin/resources/icons/flags/PAL-AF.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-AF.svg b/bin/resources/icons/flags/PAL-AF.svg
new file mode 100644
index 0000000000..275c136da0
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-AF.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-AU.png b/bin/resources/icons/flags/PAL-AU.png
deleted file mode 100644
index fdf4042c25..0000000000
Binary files a/bin/resources/icons/flags/PAL-AU.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-AU.svg b/bin/resources/icons/flags/PAL-AU.svg
new file mode 100644
index 0000000000..fdfa0882f2
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-AU.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-BE.png b/bin/resources/icons/flags/PAL-BE.png
deleted file mode 100644
index 3adf04483e..0000000000
Binary files a/bin/resources/icons/flags/PAL-BE.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-BE.svg b/bin/resources/icons/flags/PAL-BE.svg
new file mode 100644
index 0000000000..e956194340
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-BE.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-E.png b/bin/resources/icons/flags/PAL-E.png
deleted file mode 100644
index a7e3a81f13..0000000000
Binary files a/bin/resources/icons/flags/PAL-E.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-E.svg b/bin/resources/icons/flags/PAL-E.svg
new file mode 100644
index 0000000000..045024a339
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-E.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-F.png b/bin/resources/icons/flags/PAL-F.png
deleted file mode 100644
index 9a8abe6bc5..0000000000
Binary files a/bin/resources/icons/flags/PAL-F.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-F.svg b/bin/resources/icons/flags/PAL-F.svg
new file mode 100644
index 0000000000..359779e7f0
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-F.svg
@@ -0,0 +1 @@
+image/svg+xml
diff --git a/bin/resources/icons/flags/PAL-FI.png b/bin/resources/icons/flags/PAL-FI.png
deleted file mode 100644
index 843f672871..0000000000
Binary files a/bin/resources/icons/flags/PAL-FI.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-FI.svg b/bin/resources/icons/flags/PAL-FI.svg
new file mode 100644
index 0000000000..e07328edd5
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-FI.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-G.png b/bin/resources/icons/flags/PAL-G.png
deleted file mode 100644
index 46b560d82e..0000000000
Binary files a/bin/resources/icons/flags/PAL-G.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-G.svg b/bin/resources/icons/flags/PAL-G.svg
new file mode 100644
index 0000000000..ef390466f7
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-G.svg
@@ -0,0 +1 @@
+image/svg+xml
diff --git a/bin/resources/icons/flags/PAL-GR.png b/bin/resources/icons/flags/PAL-GR.png
deleted file mode 100644
index b76b2f57ea..0000000000
Binary files a/bin/resources/icons/flags/PAL-GR.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-GR.svg b/bin/resources/icons/flags/PAL-GR.svg
new file mode 100644
index 0000000000..5cbe3aa7bd
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-GR.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-I.png b/bin/resources/icons/flags/PAL-I.png
deleted file mode 100644
index ef0125311e..0000000000
Binary files a/bin/resources/icons/flags/PAL-I.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-I.svg b/bin/resources/icons/flags/PAL-I.svg
new file mode 100644
index 0000000000..6c38017668
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-I.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-IN.png b/bin/resources/icons/flags/PAL-IN.png
deleted file mode 100644
index 51e7059f0c..0000000000
Binary files a/bin/resources/icons/flags/PAL-IN.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-IN.svg b/bin/resources/icons/flags/PAL-IN.svg
new file mode 100644
index 0000000000..7af1dafe43
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-IN.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-M.png b/bin/resources/icons/flags/PAL-M.png
deleted file mode 100644
index a7e3a81f13..0000000000
Binary files a/bin/resources/icons/flags/PAL-M.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-M.svg b/bin/resources/icons/flags/PAL-M.svg
new file mode 100644
index 0000000000..045024a339
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-M.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-NL.png b/bin/resources/icons/flags/PAL-NL.png
deleted file mode 100644
index ffd4390e35..0000000000
Binary files a/bin/resources/icons/flags/PAL-NL.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-NL.svg b/bin/resources/icons/flags/PAL-NL.svg
new file mode 100644
index 0000000000..65e8be9abd
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-NL.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-NO.png b/bin/resources/icons/flags/PAL-NO.png
deleted file mode 100644
index 25269b35a0..0000000000
Binary files a/bin/resources/icons/flags/PAL-NO.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-NO.svg b/bin/resources/icons/flags/PAL-NO.svg
new file mode 100644
index 0000000000..3d104a6113
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-NO.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-P.png b/bin/resources/icons/flags/PAL-P.png
deleted file mode 100644
index 97698b9c22..0000000000
Binary files a/bin/resources/icons/flags/PAL-P.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-P.svg b/bin/resources/icons/flags/PAL-P.svg
new file mode 100644
index 0000000000..c1d4a84ff2
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-P.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-PL.png b/bin/resources/icons/flags/PAL-PL.png
deleted file mode 100644
index 3b6d000a70..0000000000
Binary files a/bin/resources/icons/flags/PAL-PL.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-PL.svg b/bin/resources/icons/flags/PAL-PL.svg
new file mode 100644
index 0000000000..8169875a70
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-PL.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-R.png b/bin/resources/icons/flags/PAL-R.png
deleted file mode 100644
index 94c0d12f31..0000000000
Binary files a/bin/resources/icons/flags/PAL-R.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-R.svg b/bin/resources/icons/flags/PAL-R.svg
new file mode 100644
index 0000000000..0b6a26ff98
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-R.svg
@@ -0,0 +1 @@
+
diff --git a/bin/resources/icons/flags/PAL-S.png b/bin/resources/icons/flags/PAL-S.png
deleted file mode 100644
index 2c07dd028a..0000000000
Binary files a/bin/resources/icons/flags/PAL-S.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-S.svg b/bin/resources/icons/flags/PAL-S.svg
new file mode 100644
index 0000000000..001ff3c66a
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-S.svg
@@ -0,0 +1 @@
+
diff --git a/bin/resources/icons/flags/PAL-SC.png b/bin/resources/icons/flags/PAL-SC.png
deleted file mode 100644
index a3fd9d1c7b..0000000000
Binary files a/bin/resources/icons/flags/PAL-SC.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-SC.svg b/bin/resources/icons/flags/PAL-SC.svg
new file mode 100644
index 0000000000..444ae0a92f
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-SC.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bin/resources/icons/flags/PAL-SW.png b/bin/resources/icons/flags/PAL-SW.png
deleted file mode 100644
index 5784472255..0000000000
Binary files a/bin/resources/icons/flags/PAL-SW.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-SW.svg b/bin/resources/icons/flags/PAL-SW.svg
new file mode 100644
index 0000000000..a039dc2ded
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-SW.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-SWI.png b/bin/resources/icons/flags/PAL-SWI.png
deleted file mode 100644
index a830932d3f..0000000000
Binary files a/bin/resources/icons/flags/PAL-SWI.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-SWI.svg b/bin/resources/icons/flags/PAL-SWI.svg
new file mode 100644
index 0000000000..6181b7618c
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-SWI.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/bin/resources/icons/flags/PAL-UK.png b/bin/resources/icons/flags/PAL-UK.png
deleted file mode 100644
index e6ef417a8e..0000000000
Binary files a/bin/resources/icons/flags/PAL-UK.png and /dev/null differ
diff --git a/bin/resources/icons/flags/PAL-UK.svg b/bin/resources/icons/flags/PAL-UK.svg
new file mode 100644
index 0000000000..21b97e9fcb
--- /dev/null
+++ b/bin/resources/icons/flags/PAL-UK.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bin/resources/icons/star-0.png b/bin/resources/icons/star-0.png
deleted file mode 100644
index 5d82bf8f8a..0000000000
Binary files a/bin/resources/icons/star-0.png and /dev/null differ
diff --git a/bin/resources/icons/star-0.svg b/bin/resources/icons/star-0.svg
new file mode 100644
index 0000000000..65c0a785d1
--- /dev/null
+++ b/bin/resources/icons/star-0.svg
@@ -0,0 +1,128 @@
+
+
+
+
+  
+  
+  
+    
+    
+    
+    
+    
+  
+
diff --git a/bin/resources/icons/star-1.png b/bin/resources/icons/star-1.png
deleted file mode 100644
index 22072f3214..0000000000
Binary files a/bin/resources/icons/star-1.png and /dev/null differ
diff --git a/bin/resources/icons/star-1.svg b/bin/resources/icons/star-1.svg
new file mode 100644
index 0000000000..db2d9386ba
--- /dev/null
+++ b/bin/resources/icons/star-1.svg
@@ -0,0 +1,128 @@
+
+
+
+
+  
+  
+  
+    
+    
+    
+    
+    
+  
+
diff --git a/bin/resources/icons/star-2.png b/bin/resources/icons/star-2.png
deleted file mode 100644
index 480b9f3576..0000000000
Binary files a/bin/resources/icons/star-2.png and /dev/null differ
diff --git a/bin/resources/icons/star-2.svg b/bin/resources/icons/star-2.svg
new file mode 100644
index 0000000000..c538ca4557
--- /dev/null
+++ b/bin/resources/icons/star-2.svg
@@ -0,0 +1,128 @@
+
+
+
+
+  
+  
+  
+    
+    
+    
+    
+    
+  
+
diff --git a/bin/resources/icons/star-3.png b/bin/resources/icons/star-3.png
deleted file mode 100644
index 000e3499d0..0000000000
Binary files a/bin/resources/icons/star-3.png and /dev/null differ
diff --git a/bin/resources/icons/star-3.svg b/bin/resources/icons/star-3.svg
new file mode 100644
index 0000000000..2e85c65f18
--- /dev/null
+++ b/bin/resources/icons/star-3.svg
@@ -0,0 +1,128 @@
+
+
+
+
+  
+  
+  
+    
+    
+    
+    
+    
+  
+
diff --git a/bin/resources/icons/star-4.png b/bin/resources/icons/star-4.png
deleted file mode 100644
index 2ec1145bfe..0000000000
Binary files a/bin/resources/icons/star-4.png and /dev/null differ
diff --git a/bin/resources/icons/star-4.svg b/bin/resources/icons/star-4.svg
new file mode 100644
index 0000000000..ca0940d8f3
--- /dev/null
+++ b/bin/resources/icons/star-4.svg
@@ -0,0 +1,128 @@
+
+
+
+
+  
+  
+  
+    
+    
+    
+    
+    
+  
+
diff --git a/bin/resources/icons/star-5.png b/bin/resources/icons/star-5.png
deleted file mode 100644
index 9043b2f9fd..0000000000
Binary files a/bin/resources/icons/star-5.png and /dev/null differ
diff --git a/bin/resources/icons/star-5.svg b/bin/resources/icons/star-5.svg
new file mode 100644
index 0000000000..cd447a96b9
--- /dev/null
+++ b/bin/resources/icons/star-5.svg
@@ -0,0 +1,128 @@
+
+
+
+
+  
+  
+  
+    
+    
+    
+    
+    
+  
+
diff --git a/bin/resources/shaders/dx11/convert.fx b/bin/resources/shaders/dx11/convert.fx
index ddcd70e5ae..9771e62d4c 100644
--- a/bin/resources/shaders/dx11/convert.fx
+++ b/bin/resources/shaders/dx11/convert.fx
@@ -170,7 +170,7 @@ PS_OUTPUT ps_rta_decorrection(PS_INPUT input)
 	return output;
 }
 
-PS_OUTPUT ps_hdr_init(PS_INPUT input)
+PS_OUTPUT ps_colclip_init(PS_INPUT input)
 {
 	PS_OUTPUT output;
 	float4 value = sample_c(input.t);
@@ -178,7 +178,7 @@ PS_OUTPUT ps_hdr_init(PS_INPUT input)
 	return output;
 }
 
-PS_OUTPUT ps_hdr_resolve(PS_INPUT input)
+PS_OUTPUT ps_colclip_resolve(PS_INPUT input)
 {
 	PS_OUTPUT output;
 	float4 value = sample_c(input.t);
diff --git a/bin/resources/shaders/dx11/tfx.fx b/bin/resources/shaders/dx11/tfx.fx
index ba3b15a96f..2bd548ec60 100644
--- a/bin/resources/shaders/dx11/tfx.fx
+++ b/bin/resources/shaders/dx11/tfx.fx
@@ -55,7 +55,7 @@
 #define PS_CHANNEL_FETCH 0
 #define PS_TALES_OF_ABYSS_HLE 0
 #define PS_URBAN_CHAOS_HLE 0
-#define PS_HDR 0
+#define PS_COLCLIP_HW 0
 #define PS_RTA_CORRECTION 0
 #define PS_RTA_SRC_CORRECTION 0
 #define PS_COLCLIP 0
@@ -767,7 +767,7 @@ float4 ps_color(PS_INPUT input)
 	float4 T = sample_color(st, input.t.w);
 #endif
 
-	if (PS_SHUFFLE && !PS_SHUFFLE_SAME && !PS_READ16_SRC)
+	if (PS_SHUFFLE && !PS_SHUFFLE_SAME && !PS_READ16_SRC && !(PS_PROCESS_BA == SHUFFLE_READWRITE && PS_PROCESS_RG == SHUFFLE_READWRITE))
 	{
 		uint4 denorm_c_before = uint4(T);
 		if (PS_PROCESS_BA & SHUFFLE_READ)
@@ -799,7 +799,7 @@ void ps_fbmask(inout float4 C, float2 pos_xy)
 {
 	if (PS_FBMASK)
 	{
-		float multi = PS_HDR ? 65535.0f : 255.0f;
+		float multi = PS_COLCLIP_HW ? 65535.0f : 255.0f;
 		float4 RT = trunc(RtTexture.Load(int3(pos_xy, 0)) * multi + 0.1f);
 		C = (float4)(((uint4)C & ~FbMask) | ((uint4)RT & FbMask));
 	}
@@ -843,15 +843,17 @@ void ps_color_clamp_wrap(inout float3 C)
 			C += 7.0f; // Need to round up, not down since the shader will invert
 
 		// Standard Clamp
-		if (PS_COLCLIP == 0 && PS_HDR == 0)
+		if (PS_COLCLIP == 0 && PS_COLCLIP_HW == 0)
 			C = clamp(C, (float3)0.0f, (float3)255.0f);
 
 		// In 16 bits format, only 5 bits of color are used. It impacts shadows computation of Castlevania
 		if (PS_DST_FMT == FMT_16 && PS_DITHER != 3 && (PS_BLEND_MIX == 0 || PS_DITHER))
 			C = (float3)((int3)C & (int3)0xF8);
-		else if (PS_COLCLIP == 1 || PS_HDR == 1)
+		else if (PS_COLCLIP == 1 || PS_COLCLIP_HW == 1)
 			C = (float3)((int3)C & (int3)0xFF);
 	}
+	else if (PS_DST_FMT == FMT_16 && PS_DITHER != 3 && PS_BLEND_MIX == 0 && PS_BLEND_HW == 0)
+		C = (float3)((int3)C & (int3)0xF8);
 }
 
 void ps_blend(inout float4 Color, inout float4 As_rgba, float2 pos_xy)
@@ -896,7 +898,7 @@ void ps_blend(inout float4 Color, inout float4 As_rgba, float2 pos_xy)
 		}
 		
 		float Ad = PS_RTA_CORRECTION ? trunc(RT.a * 128.0f + 0.1f) / 128.0f : trunc(RT.a * 255.0f + 0.1f) / 128.0f;
-		float color_multi = PS_HDR ? 65535.0f : 255.0f;
+		float color_multi = PS_COLCLIP_HW ? 65535.0f : 255.0f;
 		float3 Cd = trunc(RT.rgb * color_multi + 0.1f);
 		float3 Cs = Color.rgb;
 
@@ -1084,7 +1086,7 @@ PS_OUTPUT ps_main(PS_INPUT input)
 
 	if (PS_SHUFFLE)
 	{
-		if (!PS_SHUFFLE_SAME && !PS_READ16_SRC)
+		if (!PS_SHUFFLE_SAME && !PS_READ16_SRC && !(PS_PROCESS_BA == SHUFFLE_READWRITE && PS_PROCESS_RG == SHUFFLE_READWRITE))
 		{
 			uint4 denorm_c_after = uint4(C);
 			if (PS_PROCESS_BA & SHUFFLE_READ)
@@ -1125,11 +1127,8 @@ PS_OUTPUT ps_main(PS_INPUT input)
 		{
 			if (PS_PROCESS_BA == SHUFFLE_READWRITE && PS_PROCESS_RG == SHUFFLE_READWRITE)
 			{
-				C.rb = C.br;
-				float g_temp = C.g;
-				
-				C.g = C.a;
-				C.a = g_temp;
+				C.br = C.rb;
+				C.ag = C.ga;
 			}
 			else if(PS_PROCESS_BA & SHUFFLE_READ)
 			{
@@ -1158,7 +1157,7 @@ PS_OUTPUT ps_main(PS_INPUT input)
 
 #if !PS_NO_COLOR
 	output.c0.a = PS_RTA_CORRECTION ? C.a / 128.0f : C.a / 255.0f;
-	output.c0.rgb = PS_HDR ? float3(C.rgb / 65535.0f) : C.rgb / 255.0f;
+	output.c0.rgb = PS_COLCLIP_HW ? float3(C.rgb / 65535.0f) : C.rgb / 255.0f;
 #if !PS_NO_COLOR1
 	output.c1 = alpha_blend;
 #endif
diff --git a/bin/resources/shaders/opengl/convert.glsl b/bin/resources/shaders/opengl/convert.glsl
index b4c0d52721..27320a82ce 100644
--- a/bin/resources/shaders/opengl/convert.glsl
+++ b/bin/resources/shaders/opengl/convert.glsl
@@ -348,16 +348,16 @@ void ps_rta_decorrection()
 }
 #endif
 
-#ifdef ps_hdr_init
-void ps_hdr_init()
+#ifdef ps_colclip_init
+void ps_colclip_init()
 {
 	vec4 value = sample_c();
 	SV_Target0 = vec4(round(value.rgb * 255.0f) / 65535.0f, value.a);
 }
 #endif
 
-#ifdef ps_hdr_resolve
-void ps_hdr_resolve()
+#ifdef ps_colclip_resolve
+void ps_colclip_resolve()
 {
 	vec4 value = sample_c();
 	SV_Target0 = vec4(vec3(uvec3(value.rgb * 65535.0f) & 255u) / 255.0f, value.a);
diff --git a/bin/resources/shaders/opengl/tfx_fs.glsl b/bin/resources/shaders/opengl/tfx_fs.glsl
index 47c71600cf..f290e8d5e8 100644
--- a/bin/resources/shaders/opengl/tfx_fs.glsl
+++ b/bin/resources/shaders/opengl/tfx_fs.glsl
@@ -25,7 +25,8 @@
 #define SW_AD_TO_HW (PS_BLEND_C == 1 && PS_A_MASKED)
 #define PS_PRIMID_INIT (PS_DATE == 1 || PS_DATE == 2)
 #define NEEDS_RT_EARLY (PS_TEX_IS_FB == 1 || PS_DATE >= 5)
-#define NEEDS_RT (NEEDS_RT_EARLY || (!PS_PRIMID_INIT && (PS_FBMASK || SW_BLEND_NEEDS_RT || SW_AD_TO_HW)))
+#define NEEDS_RT_FOR_AFAIL (PS_AFAIL == 3 && PS_NO_COLOR1)
+#define NEEDS_RT (NEEDS_RT_EARLY || NEEDS_RT_FOR_AFAIL || (!PS_PRIMID_INIT && (PS_FBMASK || SW_BLEND_NEEDS_RT || SW_AD_TO_HW)))
 #define NEEDS_TEX (PS_TFX != 4)
 
 layout(std140, binding = 0) uniform cb21
@@ -678,7 +679,7 @@ vec4 ps_color()
 	vec4 T = sample_color(st);
 #endif
 
-	#if PS_SHUFFLE && !PS_READ16_SRC && !PS_SHUFFLE_SAME
+	#if PS_SHUFFLE && !PS_READ16_SRC && !PS_SHUFFLE_SAME && !(PS_PROCESS_BA == SHUFFLE_READWRITE && PS_PROCESS_RG == SHUFFLE_READWRITE)
 		uvec4 denorm_c_before = uvec4(T);
 		#if (PS_PROCESS_BA & SHUFFLE_READ)
 			T.r = float((denorm_c_before.b << 3) & 0xF8u);
@@ -706,7 +707,7 @@ void ps_fbmask(inout vec4 C)
 {
 	// FIXME do I need special case for 16 bits
 #if PS_FBMASK
-	#if PS_HDR == 1
+	#if PS_COLCLIP_HW == 1
 		vec4 RT = trunc(sample_from_rt() * 65535.0f);
 	#else
 		vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
@@ -756,7 +757,7 @@ void ps_color_clamp_wrap(inout vec3 C)
 #endif
 
 	// Correct the Color value based on the output format
-#if PS_COLCLIP == 0 && PS_HDR == 0
+#if PS_COLCLIP == 0 && PS_COLCLIP_HW == 0
 	// Standard Clamp
 	C = clamp(C, vec3(0.0f), vec3(255.0f));
 #endif
@@ -770,10 +771,12 @@ void ps_color_clamp_wrap(inout vec3 C)
 #if PS_DST_FMT == FMT_16 && PS_DITHER < 3 && (PS_BLEND_MIX == 0 || PS_DITHER)
 	// In 16 bits format, only 5 bits of colors are used. It impacts shadows computation of Castlevania
 	C = vec3(ivec3(C) & ivec3(0xF8));
-#elif PS_COLCLIP == 1 || PS_HDR == 1
+#elif PS_COLCLIP == 1 || PS_COLCLIP_HW == 1
 	C = vec3(ivec3(C) & ivec3(0xFF));
 #endif
 
+#elif PS_DST_FMT == FMT_16 && PS_DITHER != 3 && PS_BLEND_MIX == 0 && PS_BLEND_HW == 0
+	C = vec3(ivec3(C) & ivec3(0xF8));
 #endif
 }
 
@@ -825,7 +828,7 @@ float As = As_rgba.a;
 	#endif
 		
 	// Let the compiler do its jobs !
-	#if PS_HDR == 1
+	#if PS_COLCLIP_HW == 1
 		vec3 Cd = trunc(RT.rgb * 65535.0f);
 	#else
 		vec3 Cd = trunc(RT.rgb * 255.0f + 0.1f);
@@ -1061,7 +1064,7 @@ void ps_main()
 
 
 #if PS_SHUFFLE
-	#if !PS_READ16_SRC && !PS_SHUFFLE_SAME
+	#if !PS_READ16_SRC && !PS_SHUFFLE_SAME && !(PS_PROCESS_BA == SHUFFLE_READWRITE && PS_PROCESS_RG == SHUFFLE_READWRITE)
 		uvec4 denorm_c_after = uvec4(C);
 		#if (PS_PROCESS_BA & SHUFFLE_READ)
 			C.b = float(((denorm_c_after.r >> 3) & 0x1Fu) | ((denorm_c_after.g << 2) & 0xE0u));
@@ -1092,11 +1095,8 @@ void ps_main()
 			C.ga = vec2(float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.x & 0x80u)));
 	#elif PS_SHUFFLE_ACROSS
 		#if(PS_PROCESS_BA == SHUFFLE_READWRITE && PS_PROCESS_RG == SHUFFLE_READWRITE)
-			C.rb = C.br;
-			float g_temp = C.g;
-			
-			C.g = C.a;
-			C.a = g_temp;
+			C.br = C.rb;
+			C.ag = C.ga;
 		#elif(PS_PROCESS_BA & SHUFFLE_READ)
 			C.rb = C.bb;
 			C.ga = C.aa;
@@ -1114,7 +1114,7 @@ void ps_main()
 
 	ps_fbmask(C);
 
-#if PS_AFAIL == 3 // RGB_ONLY
+#if PS_AFAIL == 3 && !PS_NO_COLOR1 // RGB_ONLY
 	// Use alpha blend factor to determine whether to update A.
 	alpha_blend.a = float(atst_pass);
 #endif
@@ -1125,11 +1125,15 @@ void ps_main()
 	#else
 		SV_Target0.a = C.a / 255.0f;
 	#endif
-	#if PS_HDR == 1
+	#if PS_COLCLIP_HW == 1
 		SV_Target0.rgb = vec3(C.rgb / 65535.0f);
 	#else
 		SV_Target0.rgb = C.rgb / 255.0f;
 	#endif
+	#if PS_AFAIL == 3 && !PS_NO_COLOR1 // RGB_ONLY, no dual src blend
+		if (!atst_pass)
+			SV_Target0.a = sample_from_rt().a;
+	#endif
 	#if !PS_NO_COLOR1
 		SV_Target1 = alpha_blend;
 	#endif
diff --git a/bin/resources/shaders/vulkan/convert.glsl b/bin/resources/shaders/vulkan/convert.glsl
index 7b370affc5..9a3b551dd0 100644
--- a/bin/resources/shaders/vulkan/convert.glsl
+++ b/bin/resources/shaders/vulkan/convert.glsl
@@ -148,16 +148,16 @@ void ps_rta_decorrection()
 }
 #endif
 
-#ifdef ps_hdr_init
-void ps_hdr_init()
+#ifdef ps_colclip_init
+void ps_colclip_init()
 {
 	vec4 value = sample_c(v_tex);
 	o_col0 = vec4(roundEven(value.rgb * 255.0f) / 65535.0f, value.a);
 }
 #endif
 
-#ifdef ps_hdr_resolve
-void ps_hdr_resolve()
+#ifdef ps_colclip_resolve
+void ps_colclip_resolve()
 {
 	vec4 value = sample_c(v_tex);
 	o_col0 = vec4(vec3(uvec3(value.rgb * 65535.5f) & 255u) / 255.0f, value.a);
diff --git a/bin/resources/shaders/vulkan/tfx.glsl b/bin/resources/shaders/vulkan/tfx.glsl
index 215b00bc0c..ba21b4c0b5 100644
--- a/bin/resources/shaders/vulkan/tfx.glsl
+++ b/bin/resources/shaders/vulkan/tfx.glsl
@@ -281,7 +281,7 @@ void main()
 #define PS_CHANNEL_FETCH 0
 #define PS_TALES_OF_ABYSS_HLE 0
 #define PS_URBAN_CHAOS_HLE 0
-#define PS_HDR 0
+#define PS_COLCLIP_HW 0
 #define PS_COLCLIP 0
 #define PS_BLEND_A 0
 #define PS_BLEND_B 0
@@ -299,8 +299,9 @@ void main()
 #define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
 #define SW_BLEND_NEEDS_RT (SW_BLEND && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1))
 #define SW_AD_TO_HW (PS_BLEND_C == 1 && PS_A_MASKED)
+#define AFAIL_NEEDS_RT (PS_AFAIL == 3 && PS_NO_COLOR1)
 
-#define PS_FEEDBACK_LOOP_IS_NEEDED (PS_TEX_IS_FB == 1 || PS_FBMASK || SW_BLEND_NEEDS_RT || SW_AD_TO_HW || (PS_DATE >= 5))
+#define PS_FEEDBACK_LOOP_IS_NEEDED (PS_TEX_IS_FB == 1 || AFAIL_NEEDS_RT || PS_FBMASK || SW_BLEND_NEEDS_RT || SW_AD_TO_HW || (PS_DATE >= 5))
 
 #define NEEDS_TEX (PS_TFX != 4)
 
@@ -945,7 +946,7 @@ vec4 ps_color()
 	vec4 T = sample_color(st);
 #endif
 
-	#if PS_SHUFFLE && !PS_READ16_SRC && !PS_SHUFFLE_SAME
+	#if PS_SHUFFLE && !PS_READ16_SRC && !PS_SHUFFLE_SAME && !(PS_PROCESS_BA == SHUFFLE_READWRITE && PS_PROCESS_RG == SHUFFLE_READWRITE)
 		uvec4 denorm_c_before = uvec4(T);
 		#if (PS_PROCESS_BA & SHUFFLE_READ)
 			T.r = float((denorm_c_before.b << 3) & 0xF8u);
@@ -973,7 +974,7 @@ void ps_fbmask(inout vec4 C)
 {
 	#if PS_FBMASK
 		
-		#if PS_HDR == 1
+		#if PS_COLCLIP_HW == 1
 			vec4 RT = trunc(sample_from_rt() * 65535.0f);
 		#else
 			vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
@@ -1026,7 +1027,7 @@ void ps_color_clamp_wrap(inout vec3 C)
 #endif
 
 	// Correct the Color value based on the output format
-#if PS_COLCLIP == 0 && PS_HDR == 0
+#if PS_COLCLIP == 0 && PS_COLCLIP_HW == 0
 	// Standard Clamp
 	C = clamp(C, vec3(0.0f), vec3(255.0f));
 #endif
@@ -1040,10 +1041,12 @@ void ps_color_clamp_wrap(inout vec3 C)
 #if PS_DST_FMT == FMT_16 && PS_DITHER != 3 && (PS_BLEND_MIX == 0 || PS_DITHER > 0)
 	// In 16 bits format, only 5 bits of colors are used. It impacts shadows computation of Castlevania
 	C = vec3(ivec3(C) & ivec3(0xF8));
-#elif PS_COLCLIP == 1 || PS_HDR == 1
+#elif PS_COLCLIP == 1 || PS_COLCLIP_HW == 1
 	C = vec3(ivec3(C) & ivec3(0xFF));
 #endif
 
+#elif PS_DST_FMT == FMT_16 && PS_DITHER != 3 && PS_BLEND_MIX == 0 && PS_BLEND_HW == 0
+	C = vec3(ivec3(C) & ivec3(0xF8));
 #endif
 }
 
@@ -1095,7 +1098,7 @@ void ps_blend(inout vec4 Color, inout vec4 As_rgba)
 		#endif
 
 			// Let the compiler do its jobs !
-			#if PS_HDR == 1
+			#if PS_COLCLIP_HW == 1
 			vec3 Cd = trunc(RT.rgb * 65535.0f);
 			#else
 			vec3 Cd = trunc(RT.rgb * 255.0f + 0.1f);
@@ -1329,7 +1332,7 @@ void main()
 	ps_blend(C, alpha_blend);
 
 #if PS_SHUFFLE
-		#if !PS_READ16_SRC && !PS_SHUFFLE_SAME
+		#if !PS_READ16_SRC && !PS_SHUFFLE_SAME && !(PS_PROCESS_BA == SHUFFLE_READWRITE && PS_PROCESS_RG == SHUFFLE_READWRITE)
 			uvec4 denorm_c_after = uvec4(C);
 			#if (PS_PROCESS_BA & SHUFFLE_READ)
 				C.b = float(((denorm_c_after.r >> 3) & 0x1Fu) | ((denorm_c_after.g << 2) & 0xE0u));
@@ -1340,8 +1343,6 @@ void main()
 			#endif
 		#endif
 
-		
-		
 		// Special case for 32bit input and 16bit output, shuffle used by The Godfather
 		#if PS_SHUFFLE_SAME
 			#if (PS_PROCESS_BA & SHUFFLE_READ)
@@ -1359,11 +1360,8 @@ void main()
 		// Write RB part. Mask will take care of the correct destination
 		#elif PS_SHUFFLE_ACROSS
 			#if(PS_PROCESS_BA == SHUFFLE_READWRITE && PS_PROCESS_RG == SHUFFLE_READWRITE)
-				C.rb = C.br;
-				float g_temp = C.g;
-				
-				C.g = C.a;
-				C.a = g_temp;
+				C.br = C.rb;
+				C.ag = C.ga;
 			#elif(PS_PROCESS_BA & SHUFFLE_READ)
 				C.rb = C.bb;
 				C.ga = C.aa;
@@ -1381,7 +1379,7 @@ void main()
 
 	ps_fbmask(C);
 
-	#if PS_AFAIL == 3 // RGB_ONLY
+	#if PS_AFAIL == 3 && !PS_NO_COLOR1 // RGB_ONLY
 		// Use alpha blend factor to determine whether to update A.
 		alpha_blend.a = float(atst_pass);
 	#endif
@@ -1392,7 +1390,7 @@ void main()
 		#else
 			o_col0.a = C.a / 255.0f;
 		#endif
-		#if PS_HDR == 1
+		#if PS_COLCLIP_HW == 1
 			o_col0.rgb = vec3(C.rgb / 65535.0f);
 		#else
 			o_col0.rgb = C.rgb / 255.0f;
@@ -1400,6 +1398,10 @@ void main()
 		#if !PS_NO_COLOR1
 			o_col1 = alpha_blend;
 		#endif
+		#if PS_AFAIL == 3 && PS_NO_COLOR1 // RGB_ONLY, no dual src blend
+			if (!atst_pass)
+				o_col0.a = sample_from_rt().a;
+		#endif
 	#endif
 
 	#if PS_ZCLAMP
diff --git a/cmake/SearchForStuff.cmake b/cmake/SearchForStuff.cmake
index 2e4dacefa9..01fbe240f1 100644
--- a/cmake/SearchForStuff.cmake
+++ b/cmake/SearchForStuff.cmake
@@ -105,7 +105,7 @@ disable_compiler_warnings_for_target(cubeb)
 disable_compiler_warnings_for_target(speex)
 
 # Find the Qt components that we need.
-find_package(Qt6 6.7.2 COMPONENTS CoreTools Core GuiTools Gui WidgetsTools Widgets LinguistTools REQUIRED)
+find_package(Qt6 6.7.3 COMPONENTS CoreTools Core GuiTools Gui WidgetsTools Widgets LinguistTools REQUIRED)
 
 if(WIN32)
   add_subdirectory(3rdparty/rainterface EXCLUDE_FROM_ALL)
@@ -119,6 +119,12 @@ add_subdirectory(3rdparty/ccc EXCLUDE_FROM_ALL)
 
 # The docking system for the debugger.
 find_package(KDDockWidgets-qt6 REQUIRED)
+# Add an extra include path to work around a broken include directive.
+# TODO: Remove this the next time we update KDDockWidgets.
+get_target_property(KDDOCKWIDGETS_INCLUDE_DIRECTORY KDAB::kddockwidgets INTERFACE_INCLUDE_DIRECTORIES)
+target_include_directories(KDAB::kddockwidgets INTERFACE
+	${KDDOCKWIDGETS_INCLUDE_DIRECTORY}/kddockwidgets
+)
 
 # Architecture-specific.
 if(_M_X86)
diff --git a/common/CocoaTools.h b/common/CocoaTools.h
index 1166effc4c..8da50f8a2a 100644
--- a/common/CocoaTools.h
+++ b/common/CocoaTools.h
@@ -19,6 +19,8 @@ namespace CocoaTools
 	void AddThemeChangeHandler(void* ctx, void(handler)(void* ctx));
 	/// Remove a handler previously added using AddThemeChangeHandler with the given context
 	void RemoveThemeChangeHandler(void* ctx);
+	/// Mark an NSMenu as the help menu
+	void MarkHelpMenu(void* menu);
 	/// Returns the bundle path.
 	std::optional GetBundlePath();
 	/// Get the bundle path to the actual application without any translocation fun
diff --git a/common/CocoaTools.mm b/common/CocoaTools.mm
index 71b4c91184..adbe803b80 100644
--- a/common/CocoaTools.mm
+++ b/common/CocoaTools.mm
@@ -143,6 +143,11 @@ void CocoaTools::RemoveThemeChangeHandler(void* ctx)
 	[s_themeChangeHandler removeCallback:ctx];
 }
 
+void CocoaTools::MarkHelpMenu(void* menu)
+{
+	[NSApp setHelpMenu:(__bridge NSMenu*)menu];
+}
+
 // MARK: - Sound playback
 
 bool Common::PlaySoundAsync(const char* path)
diff --git a/common/Console.cpp b/common/Console.cpp
index 8f8aa084bc..2415181bf4 100644
--- a/common/Console.cpp
+++ b/common/Console.cpp
@@ -342,7 +342,7 @@ bool Log::SetFileOutputLevel(LOGLEVEL level, std::string path)
 			if (!s_file_handle || s_file_path != path)
 			{
 				s_file_handle.reset();
-				s_file_handle = FileSystem::OpenManagedCFile(path.c_str(), "wb");
+				s_file_handle = FileSystem::OpenManagedSharedCFile(path.c_str(), "wb", FileSystem::FileShareMode::DenyWrite);
 				if (s_file_handle)
 				{
 					s_file_path = std::move(path);
diff --git a/common/Darwin/DarwinMisc.cpp b/common/Darwin/DarwinMisc.cpp
index 400c26c9b5..5f12d186f7 100644
--- a/common/Darwin/DarwinMisc.cpp
+++ b/common/Darwin/DarwinMisc.cpp
@@ -50,6 +50,27 @@ u64 GetPhysicalMemory()
 	return getmem;
 }
 
+u64 GetAvailablePhysicalMemory()
+{
+	const mach_port_t host_port = mach_host_self();
+	vm_size_t page_size;
+
+	if (host_page_size(host_port, &page_size) != KERN_SUCCESS)
+		return 0;
+
+	vm_statistics64_data_t vm_stat;
+	mach_msg_type_number_t host_size = sizeof(vm_statistics64_data_t) / sizeof(integer_t);
+
+	if (host_statistics64(host_port, HOST_VM_INFO, reinterpret_cast(&vm_stat), &host_size) != KERN_SUCCESS)
+		return 0;
+
+	const u64 free_pages = static_cast(vm_stat.free_count);
+	const u64 inactive_pages = static_cast(vm_stat.inactive_count);
+	const u64 get_available_mem = (free_pages + inactive_pages) * page_size;
+
+	return get_available_mem;
+}
+
 static mach_timebase_info_data_t s_timebase_info;
 static const u64 tickfreq = []() {
 	if (mach_timebase_info(&s_timebase_info) != KERN_SUCCESS)
diff --git a/common/HostSys.h b/common/HostSys.h
index b41581a7d1..08eb31232c 100644
--- a/common/HostSys.h
+++ b/common/HostSys.h
@@ -181,6 +181,7 @@ private:
 extern u64 GetTickFrequency();
 extern u64 GetCPUTicks();
 extern u64 GetPhysicalMemory();
+extern u64 GetAvailablePhysicalMemory();
 /// Spin for a short period of time (call while spinning waiting for a lock)
 /// Returns the approximate number of ns that passed
 extern u32 ShortSpin();
diff --git a/common/Linux/LnxMisc.cpp b/common/Linux/LnxMisc.cpp
index acefebe701..2ef073932b 100644
--- a/common/Linux/LnxMisc.cpp
+++ b/common/Linux/LnxMisc.cpp
@@ -15,6 +15,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -40,6 +41,15 @@ u64 GetPhysicalMemory()
 	return pages * getpagesize();
 }
 
+u64 GetAvailablePhysicalMemory()
+{
+	struct sysinfo info;
+	if (sysinfo(&info) != 0)
+		return 0;
+
+	return static_cast(info.freeram) * info.mem_unit;
+}
+
 u64 GetTickFrequency()
 {
 	return 1000000000; // unix measures in nanoseconds
diff --git a/common/Windows/WinMisc.cpp b/common/Windows/WinMisc.cpp
index 3cbdc201d0..b7bdb89d24 100644
--- a/common/Windows/WinMisc.cpp
+++ b/common/Windows/WinMisc.cpp
@@ -57,6 +57,14 @@ u64 GetPhysicalMemory()
 	return status.ullTotalPhys;
 }
 
+u64 GetAvailablePhysicalMemory()
+{
+	MEMORYSTATUSEX status;
+	status.dwLength = sizeof(status);
+	GlobalMemoryStatusEx(&status);
+	return status.ullAvailPhys;
+}
+
 // Calculates the Windows OS Version and processor architecture, and returns it as a
 // human-readable string. :)
 std::string GetOSVersionString()
diff --git a/common/vsprops/LinkPCSX2Deps.props b/common/vsprops/LinkPCSX2Deps.props
index 562be5a6d1..7cb1add662 100644
--- a/common/vsprops/LinkPCSX2Deps.props
+++ b/common/vsprops/LinkPCSX2Deps.props
@@ -4,13 +4,13 @@
   
     
       $(DepsLibDir);%(AdditionalLibraryDirectories)
-      %(AdditionalDependencies);freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL3.lib;zlib.lib;zstd.lib;kddockwidgets-qt62.lib
+      %(AdditionalDependencies);freetype.lib;jpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL3.lib;zlib.lib;zstd.lib;kddockwidgets-qt62.lib
    
   
   
     
     
-    
+    
     
     
     
diff --git a/common/vsprops/QtCompile.props b/common/vsprops/QtCompile.props
index 68ce622232..3ed3de883b 100644
--- a/common/vsprops/QtCompile.props
+++ b/common/vsprops/QtCompile.props
@@ -59,23 +59,37 @@
     
   
 
-  
-  
-    
-  
+  
+  
+  
   
-    
+    Condition="'@(QtUi)'!=''">
     
     
-    
-  
+    
+    
+      
+        uic %(Filename)
+        
+            "$(QtHostBinDir)uic.exe" "%(FullPath)" -o "$(QtToolOutDir)ui_%(Filename).h"
+        
+        $(QtToolOutDir)ui_%(Filename).h
+      
+    
 
-  
-    
+    
+    
+    
+      
+    
+
+    
   
 
   
@@ -88,7 +102,7 @@
   
     
     
@@ -97,7 +111,7 @@
   
 
   
-    
+    
   
   
     
diff --git a/common/vsprops/QtCompile.targets b/common/vsprops/QtCompile.targets
index 75ac29f304..ec70459f96 100644
--- a/common/vsprops/QtCompile.targets
+++ b/common/vsprops/QtCompile.targets
@@ -1,7 +1,7 @@
 
 
   
-    QtResourceClean;QtUiClean;QtMocClean;QtTsClean;$(CleanDependsOn)
+    QtResourceClean;QtMocClean;QtTsClean;$(CleanDependsOn)