mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9a2618b7a | ||
|
|
dca0291cfb | ||
|
|
b261873471 | ||
|
|
bfd01c913a | ||
|
|
818b3fe779 | ||
|
|
66a28e4488 | ||
|
|
28e2ecf920 | ||
|
|
d3dbf53fa7 | ||
|
|
8fb2940f25 | ||
|
|
55498762f9 | ||
|
|
50baaf39d6 | ||
|
|
4743ccac8c | ||
|
|
0dc3fc6228 | ||
|
|
a7a4583c84 | ||
|
|
6b52937262 | ||
|
|
df9caf6fb8 | ||
|
|
be5f8d2e60 | ||
|
|
b0e01ca518 | ||
|
|
4e85272393 | ||
|
|
bffed9a839 | ||
|
|
7ed0c0d031 | ||
|
|
ae6e4c98f6 | ||
|
|
38cfa9912d | ||
|
|
b02318e2b6 | ||
|
|
db45263221 | ||
|
|
3fd9625f1c | ||
|
|
2978b6050d | ||
|
|
274acddcf1 | ||
|
|
8dffc85707 | ||
|
|
f799631a70 | ||
|
|
d744f0dfeb | ||
|
|
bdb8de6d3b | ||
|
|
e751f367ca | ||
|
|
13f2d87ba8 | ||
|
|
3cac2cf7c2 | ||
|
|
a67409bfc6 | ||
|
|
6a556c9968 | ||
|
|
4d93285ca2 | ||
|
|
98c35a308d | ||
|
|
7da97e6d80 | ||
|
|
edf686752a | ||
|
|
b7e17646a3 | ||
|
|
3f437e7496 | ||
|
|
7ab6c62dee | ||
|
|
2a7bf35f20 | ||
|
|
08552a83cc | ||
|
|
ee417ee4c5 | ||
|
|
869837f5f0 | ||
|
|
7ab6bac39a | ||
|
|
e388294004 | ||
|
|
bba5ef67ff | ||
|
|
83dc2de6ca | ||
|
|
f47fbda0e6 |
2
.github/workflows/macos_build.yml
vendored
2
.github/workflows/macos_build.yml
vendored
@@ -91,7 +91,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/deps
|
||||
key: ${{ inputs.os }} deps ${{ hashFiles('.github/workflows/scripts/macos/build-dependencies.sh', '.github/workflows/scripts/common/*.patch') }}
|
||||
key: ${{ inputs.os }} deps ${{ hashFiles('.github/workflows/scripts/macos/*', '.github/workflows/scripts/common/*.patch') }}
|
||||
|
||||
- name: Build Dependencies
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
|
||||
4
.github/workflows/release_cut_new.yml
vendored
4
.github/workflows/release_cut_new.yml
vendored
@@ -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@6cbd405e2c4e67a21c47fa9e383d020e4e28b836
|
||||
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090
|
||||
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@6cbd405e2c4e67a21c47fa9e383d020e4e28b836
|
||||
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090
|
||||
if: steps.tag_version.outputs.new_tag && github.event_name != 'workflow_dispatch'
|
||||
with:
|
||||
body_path: ./release-notes.md
|
||||
|
||||
18
.github/workflows/scripts/linux/appimage-qt.sh
vendored
18
.github/workflows/scripts/linux/appimage-qt.sh
vendored
@@ -50,12 +50,6 @@ declare -a MANUAL_LIBS=(
|
||||
"libfreetype.so.6"
|
||||
)
|
||||
|
||||
declare -a REMOVE_LIBS=(
|
||||
'libwayland-client.so*'
|
||||
'libwayland-cursor.so*'
|
||||
'libwayland-egl.so*'
|
||||
)
|
||||
|
||||
set -e
|
||||
|
||||
LINUXDEPLOY=./linuxdeploy-x86_64.AppImage
|
||||
@@ -130,7 +124,7 @@ echo "Running linuxdeploy to create AppDir..."
|
||||
# Interestingly, specifying the module doesn't copy the module, only the required plugins for it
|
||||
# https://github.com/linuxdeploy/linuxdeploy-plugin-qt/issues/160#issuecomment-2655543893
|
||||
EXTRA_QT_MODULES="core;gui;svg;waylandclient;waylandcompositor;widgets;xcbqpa" \
|
||||
EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so" \
|
||||
EXTRA_PLATFORM_PLUGINS="libqwayland.so" \
|
||||
DEPLOY_PLATFORM_THEMES="1" \
|
||||
QMAKE="$DEPSDIR/bin/qmake" \
|
||||
NO_STRIP="1" \
|
||||
@@ -140,16 +134,6 @@ $LINUXDEPLOY --plugin qt --appdir="$OUTDIR" --executable="$BUILDDIR/bin/pcsx2-qt
|
||||
echo "Copying resources into AppDir..."
|
||||
cp -a "$BUILDDIR/bin/resources" "$OUTDIR/usr/bin"
|
||||
|
||||
# Why do we have to manually remove these libs? Because the linuxdeploy Qt plugin
|
||||
# copies them, not the "main" linuxdeploy binary, and plugins don't inherit the
|
||||
# include list...
|
||||
for lib in "${REMOVE_LIBS[@]}"; do
|
||||
for libpath in $(find "$OUTDIR/usr/lib" -name "$lib"); do
|
||||
echo " Removing problematic library ${libpath}."
|
||||
rm -f "$libpath"
|
||||
done
|
||||
done
|
||||
|
||||
# Restore unstripped deps (for cache).
|
||||
rm -fr "$DEPSDIR"
|
||||
mv "$DEPSDIR.bak" "$DEPSDIR"
|
||||
|
||||
@@ -21,7 +21,7 @@ LIBJPEGTURBO=3.1.2
|
||||
LIBPNG=1.6.50
|
||||
LIBWEBP=1.6.0
|
||||
SDL=SDL3-3.2.24
|
||||
QT=6.9.2
|
||||
QT=6.10.0
|
||||
QTAPNG=1.3.0
|
||||
LZ4=1.10.0
|
||||
ZSTD=1.5.7
|
||||
@@ -48,12 +48,12 @@ e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWE
|
||||
687ddc0c7cb128a3ea58e159b5129252537c27ede0c32a93f11f03127f0c0165 libpng-$LIBPNG-apng.patch.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
44be9c9ecfe04129c4dea0a7e1b36ad476c9cc07c292016ac98e7b41514f2440 qtbase-everywhere-src-$QT.tar.xz
|
||||
8a023f7e2f57dedc02e2ab10c975f7cb3cccac9b8f0823c12fd6824834549139 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
d984cab8f26334aa1c15e5b8f0cd9f1b7c0c1289fe0b68c1c84ab469b75605a5 qtsvg-everywhere-src-$QT.tar.xz
|
||||
d8b7f7e8e970cc0b975205fd6d5832ea917ef3e751df69b97439c1cddd67a489 qttools-everywhere-src-$QT.tar.xz
|
||||
c73bb6281ed365c0f954f4b1b6e1b13e1b3fefd94854f46fcd9a412f641f7ed6 qttranslations-everywhere-src-$QT.tar.xz
|
||||
cad79806565568f12f9983fed69219416abcee9d5deef4abdfcf94aa2eef7781 qtwayland-everywhere-src-$QT.tar.xz
|
||||
ead4623bcb54a32257c5b3e3a5aec6d16ec96f4cda58d2e003f5a0c16f72046d qtbase-everywhere-src-$QT.tar.xz
|
||||
64450a52507c540de53616ed5e516df0e0905a99d3035ddfaa690f2b3f7c0cea qtimageformats-everywhere-src-$QT.tar.xz
|
||||
5ed2c0e04d5e73ff75c2a2ed92db5dc1788ba70f704fc2b71bc21644beda2533 qtsvg-everywhere-src-$QT.tar.xz
|
||||
d86d5098cf3e3e599f37e18df477e65908fc8f036e10ea731b3469ec4fdbd02a qttools-everywhere-src-$QT.tar.xz
|
||||
326e8253cfd0cb5745238117f297da80e30ce8f4c1db81990497bd388b026cde qttranslations-everywhere-src-$QT.tar.xz
|
||||
603f2b0a259b24bd0fb14f880d7761b1d248118a42a6870cdbe8fdda4173761f qtwayland-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
a8e4a25e5c2686fd36981e527ed05e451fcfc226bddf350f4e76181371190937 shaderc-$SHADERC.tar.gz
|
||||
9427deccbdf4bde6a269938df38c6bd75247493786a310d8d733a2c82065ef47 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
|
||||
196
.github/workflows/scripts/linux/build-dependencies-runner.sh
vendored
Executable file
196
.github/workflows/scripts/linux/build-dependencies-runner.sh
vendored
Executable file
@@ -0,0 +1,196 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Syntax: $0 <output directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPTDIR=$(realpath $(dirname "${BASH_SOURCE[0]}"))
|
||||
NPROCS="$(getconf _NPROCESSORS_ONLN)"
|
||||
INSTALLDIR="$1"
|
||||
if [ "${INSTALLDIR:0:1}" != "/" ]; then
|
||||
INSTALLDIR="$PWD/$INSTALLDIR"
|
||||
fi
|
||||
|
||||
FREETYPE=2.14.1
|
||||
HARFBUZZ=12.0.0
|
||||
LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
|
||||
LIBPNG=1.6.50
|
||||
LIBWEBP=1.6.0
|
||||
SDL=SDL3-3.2.22
|
||||
LZ4=1.10.0
|
||||
ZSTD=1.5.7
|
||||
PLUTOVG=1.3.1
|
||||
PLUTOSVG=0.0.7
|
||||
|
||||
SHADERC=2025.3
|
||||
SHADERC_GLSLANG=efd24d75bcbc55620e759f6bf42c45a32abac5f8
|
||||
SHADERC_SPIRVHEADERS=2a611a970fdbc41ac2e3e328802aed9985352dca
|
||||
SHADERC_SPIRVTOOLS=33e02568181e3312f49a3cf33df470bf96ef293a
|
||||
|
||||
mkdir -p deps-build
|
||||
cd deps-build
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
c4a398539c3e0fdc9a82dfe7824d0438cae78c1e2124e7c6ada3dfa600cdb6c8 harfbuzz-$HARFBUZZ.tar.gz
|
||||
fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.zip
|
||||
4df396518620a7aa3651443e87d1b2862e4e88cad135a8b93423e01706232307 libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
f29d00cbcee273c0a54f3f32f86bf5c595e8823a96b1d92a145aac40571ebfcc $SDL.tar.gz
|
||||
687ddc0c7cb128a3ea58e159b5129252537c27ede0c32a93f11f03127f0c0165 libpng-$LIBPNG-apng.patch.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
a8e4a25e5c2686fd36981e527ed05e451fcfc226bddf350f4e76181371190937 shaderc-$SHADERC.tar.gz
|
||||
9427deccbdf4bde6a269938df38c6bd75247493786a310d8d733a2c82065ef47 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c2225a49c3d7efa5c4f4ce4a6b42081e6ea3daca376f3353d9d7c2722d77a28a shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
44d1005880c583fc00a0fb41c839214c68214b000ea8dcb54d352732fee600ff shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
bea672eb96ee36c2cbeb911b9bac66dfe989b3ad9a9943101e00aeb2df2aefdb plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
EOF
|
||||
|
||||
curl -L \
|
||||
-o "freetype-$FREETYPE.tar.xz" "https://sourceforge.net/projects/freetype/files/freetype2/$FREETYPE/freetype-$FREETYPE.tar.xz/download" \
|
||||
-o "harfbuzz-$HARFBUZZ.tar.gz" "https://github.com/harfbuzz/harfbuzz/archive/refs/tags/$HARFBUZZ.tar.gz" \
|
||||
-O "https://github.com/ianlancetaylor/libbacktrace/archive/$LIBBACKTRACE.zip" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
|
||||
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
|
||||
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-o "plutovg-$PLUTOVG.tar.gz" "https://github.com/sammycage/plutovg/archive/v$PLUTOVG.tar.gz" \
|
||||
-o "plutosvg-$PLUTOSVG.tar.gz" "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG.tar.gz"
|
||||
|
||||
shasum -a 256 --check SHASUMS
|
||||
|
||||
echo "Building libbacktrace..."
|
||||
rm -fr "libbacktrace-$LIBBACKTRACE"
|
||||
unzip "$LIBBACKTRACE.zip"
|
||||
cd "libbacktrace-$LIBBACKTRACE"
|
||||
./configure --prefix="$INSTALLDIR"
|
||||
make
|
||||
make install
|
||||
cd ..
|
||||
|
||||
echo "Building libpng..."
|
||||
rm -fr "libpng-$LIBPNG"
|
||||
tar xf "libpng-$LIBPNG.tar.xz"
|
||||
gunzip -d -f "libpng-$LIBPNG-apng.patch.gz"
|
||||
cd "libpng-$LIBPNG"
|
||||
patch -p1 < "../libpng-$LIBPNG-apng.patch"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DBUILD_SHARED_LIBS=ON -DPNG_TESTS=OFF -DPNG_STATIC=OFF -DPNG_SHARED=ON -DPNG_TOOLS=OFF -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building LZ4..."
|
||||
rm -fr "lz4-$LZ4"
|
||||
tar xf "lz4-$LZ4.tar.gz"
|
||||
cd "lz4-$LZ4"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DLZ4_BUILD_CLI=OFF -DLZ4_BUILD_LEGACY_LZ4C=OFF -B build-dir -G Ninja build/cmake
|
||||
cmake --build build-dir --parallel
|
||||
ninja -C build-dir install
|
||||
cd ..
|
||||
|
||||
echo "Building Zstandard..."
|
||||
rm -fr "zstd-$ZSTD"
|
||||
tar xf "zstd-$ZSTD.tar.gz"
|
||||
cd "zstd-$ZSTD"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DZSTD_BUILD_SHARED=ON -DZSTD_BUILD_STATIC=OFF -DZSTD_BUILD_PROGRAMS=OFF -B build -G Ninja build/cmake
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building FreeType without HarfBuzz..."
|
||||
rm -fr "freetype-$FREETYPE"
|
||||
tar xf "freetype-$FREETYPE.tar.xz"
|
||||
cd "freetype-$FREETYPE"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DFT_REQUIRE_ZLIB=ON -DFT_REQUIRE_PNG=ON -DFT_DISABLE_BZIP2=TRUE -DFT_DISABLE_BROTLI=TRUE -DFT_DISABLE_HARFBUZZ=TRUE -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building HarfBuzz..."
|
||||
rm -fr "harfbuzz-$HARFBUZZ"
|
||||
tar xf "harfbuzz-$HARFBUZZ.tar.gz"
|
||||
cd "harfbuzz-$HARFBUZZ"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DHB_BUILD_UTILS=OFF -DHB_HAVE_FREETYPE=ON -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building WebP..."
|
||||
rm -fr "libwebp-$LIBWEBP"
|
||||
tar xf "libwebp-$LIBWEBP.tar.gz"
|
||||
cd "libwebp-$LIBWEBP"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -B build -G Ninja \
|
||||
-DWEBP_BUILD_ANIM_UTILS=OFF -DWEBP_BUILD_CWEBP=OFF -DWEBP_BUILD_DWEBP=OFF -DWEBP_BUILD_GIF2WEBP=OFF -DWEBP_BUILD_IMG2WEBP=OFF \
|
||||
-DWEBP_BUILD_VWEBP=OFF -DWEBP_BUILD_WEBPINFO=OFF -DWEBP_BUILD_WEBPMUX=OFF -DWEBP_BUILD_EXTRAS=OFF -DBUILD_SHARED_LIBS=ON
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building FreeType with HarfBuzz..."
|
||||
rm -fr "freetype-$FREETYPE"
|
||||
tar xf "freetype-$FREETYPE.tar.xz"
|
||||
cd "freetype-$FREETYPE"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DFT_REQUIRE_ZLIB=ON -DFT_REQUIRE_PNG=ON -DFT_DISABLE_BZIP2=TRUE -DFT_DISABLE_BROTLI=TRUE -DFT_REQUIRE_HARFBUZZ=TRUE -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building SDL..."
|
||||
rm -fr "$SDL"
|
||||
tar xf "$SDL.tar.gz"
|
||||
cd "$SDL"
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building PlutoVG..."
|
||||
rm -fr "plutovg-$PLUTOVG"
|
||||
tar xf "plutovg-$PLUTOVG.tar.gz"
|
||||
cd "plutovg-$PLUTOVG"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building PlutoSVG..."
|
||||
rm -fr "plutosvg-$PLUTOSVG"
|
||||
tar xf "plutosvg-$PLUTOSVG.tar.gz"
|
||||
cd "plutosvg-$PLUTOSVG"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DPLUTOSVG_ENABLE_FREETYPE=ON -DPLUTOSVG_BUILD_EXAMPLES=OFF -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building shaderc..."
|
||||
rm -fr "shaderc-$SHADERC"
|
||||
tar xf "shaderc-$SHADERC.tar.gz"
|
||||
cd "shaderc-$SHADERC"
|
||||
cd third_party
|
||||
tar xf "../../shaderc-glslang-$SHADERC_GLSLANG.tar.gz"
|
||||
mv "glslang-$SHADERC_GLSLANG" "glslang"
|
||||
tar xf "../../shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz"
|
||||
mv "SPIRV-Headers-$SHADERC_SPIRVHEADERS" "spirv-headers"
|
||||
tar xf "../../shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz"
|
||||
mv "SPIRV-Tools-$SHADERC_SPIRVTOOLS" "spirv-tools"
|
||||
cd ..
|
||||
patch -p1 < "$SCRIPTDIR/../common/shaderc-changes.patch"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DSHADERC_SKIP_TESTS=ON -DSHADERC_SKIP_EXAMPLES=ON -DSHADERC_SKIP_COPYRIGHT_CHECK=ON -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Cleaning up..."
|
||||
cd ..
|
||||
rm -r deps-build
|
||||
32
.github/workflows/scripts/macos/build-dependencies-universal.sh
vendored
Normal file → Executable file
32
.github/workflows/scripts/macos/build-dependencies-universal.sh
vendored
Normal file → Executable file
@@ -46,9 +46,9 @@ LZ4=1.10.0
|
||||
LIBPNG=1.6.50
|
||||
LIBJPEGTURBO=3.1.2
|
||||
LIBWEBP=1.6.0
|
||||
FFMPEG=6.0
|
||||
FFMPEG=8.0
|
||||
MOLTENVK=1.2.9
|
||||
QT=6.7.3
|
||||
QT=6.10.0
|
||||
QTAPNG=1.3.0
|
||||
KDDOCKWIDGETS=2.3.0
|
||||
PLUTOVG=1.3.1
|
||||
@@ -87,13 +87,13 @@ eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
687ddc0c7cb128a3ea58e159b5129252537c27ede0c32a93f11f03127f0c0165 libpng-$LIBPNG-apng.patch.gz
|
||||
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082 ffmpeg-$FFMPEG.tar.xz
|
||||
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
|
||||
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
|
||||
8ccbb9ab055205ac76632c9eeddd1ed6fc66936fc56afc2ed0fd5d9e23da3097 qtbase-everywhere-src-$QT.tar.xz
|
||||
9fd58144081654c3373768dd96ead294023830927b14fe3d3c1ef641fb324753 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
40142cb71fb1e07ad612bc361b67f5d54cd9367f9979ae6b86124a064deda06b qtsvg-everywhere-src-$QT.tar.xz
|
||||
f03bb7df619cd9ac9dba110e30b7bcab5dd88eb8bdc9cc752563b4367233203f qttools-everywhere-src-$QT.tar.xz
|
||||
dcc762acac043b9bb5e4d369b6d6f53e0ecfcf76a408fe0db5f7ef071c9d6dc8 qttranslations-everywhere-src-$QT.tar.xz
|
||||
ead4623bcb54a32257c5b3e3a5aec6d16ec96f4cda58d2e003f5a0c16f72046d qtbase-everywhere-src-$QT.tar.xz
|
||||
64450a52507c540de53616ed5e516df0e0905a99d3035ddfaa690f2b3f7c0cea qtimageformats-everywhere-src-$QT.tar.xz
|
||||
5ed2c0e04d5e73ff75c2a2ed92db5dc1788ba70f704fc2b71bc21644beda2533 qtsvg-everywhere-src-$QT.tar.xz
|
||||
d86d5098cf3e3e599f37e18df477e65908fc8f036e10ea731b3469ec4fdbd02a qttools-everywhere-src-$QT.tar.xz
|
||||
326e8253cfd0cb5745238117f297da80e30ce8f4c1db81990497bd388b026cde qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
a8e4a25e5c2686fd36981e527ed05e451fcfc226bddf350f4e76181371190937 shaderc-$SHADERC.tar.gz
|
||||
9427deccbdf4bde6a269938df38c6bd75247493786a310d8d733a2c82065ef47 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
@@ -285,6 +285,10 @@ echo "Installing Qt Base..."
|
||||
rm -fr "qtbase-everywhere-src-$QT"
|
||||
tar xf "qtbase-everywhere-src-$QT.tar.xz"
|
||||
cd "qtbase-everywhere-src-$QT"
|
||||
|
||||
# Patch Qt to support macOS 11
|
||||
patch -p1 < "$SCRIPTDIR/qt-macos11compat.patch"
|
||||
|
||||
# since we don't have a direct reference to QtSvg, it doesn't deployed directly from the main binary
|
||||
# (only indirectly from iconengines), and the libqsvg.dylib imageformat plugin does not get deployed.
|
||||
# We could run macdeployqt twice, but that's even more janky than patching it.
|
||||
@@ -320,7 +324,7 @@ tar xf "qtsvg-everywhere-src-$QT.tar.xz"
|
||||
cd "qtsvg-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL"
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DQT_GENERATE_SBOM=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -331,7 +335,7 @@ tar xf "qtimageformats-everywhere-src-$QT.tar.xz"
|
||||
cd "qtimageformats-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DFEATURE_system_webp=ON
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DQT_GENERATE_SBOM=OFF -DFEATURE_system_webp=ON
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -342,7 +346,7 @@ tar xf "qttools-everywhere-src-$QT.tar.xz"
|
||||
cd "qttools-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DQT_GENERATE_SBOM=OFF -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -371,7 +375,7 @@ tar xf "qttranslations-everywhere-src-$QT.tar.xz"
|
||||
cd "qttranslations-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL"
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DQT_GENERATE_SBOM=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -391,8 +395,8 @@ rm -fr "KDDockWidgets-$KDDOCKWIDGETS"
|
||||
tar xf "KDDockWidgets-$KDDOCKWIDGETS.tar.gz"
|
||||
cd "KDDockWidgets-$KDDOCKWIDGETS"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build
|
||||
cmake --build build --parallel
|
||||
cmake --install build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building PlutoVG..."
|
||||
|
||||
@@ -28,9 +28,9 @@ LZ4=1.10.0
|
||||
LIBPNG=1.6.50
|
||||
LIBJPEGTURBO=3.1.2
|
||||
LIBWEBP=1.6.0
|
||||
FFMPEG=6.0
|
||||
FFMPEG=8.0
|
||||
MOLTENVK=1.2.9
|
||||
QT=6.7.3
|
||||
QT=6.10.0
|
||||
QTAPNG=1.3.0
|
||||
KDDOCKWIDGETS=2.3.0
|
||||
PLUTOVG=1.3.1
|
||||
@@ -54,6 +54,7 @@ CMAKE_COMMON=(
|
||||
-DCMAKE_PREFIX_PATH="$INSTALLDIR"
|
||||
-DCMAKE_INSTALL_PREFIX="$INSTALLDIR"
|
||||
-DCMAKE_OSX_ARCHITECTURES="x86_64"
|
||||
-DCMAKE_APPLE_SILICON_PROCESSOR="x86_64"
|
||||
-DCMAKE_INSTALL_NAME_DIR='$<INSTALL_PREFIX>/lib'
|
||||
)
|
||||
|
||||
@@ -67,13 +68,13 @@ eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
687ddc0c7cb128a3ea58e159b5129252537c27ede0c32a93f11f03127f0c0165 libpng-$LIBPNG-apng.patch.gz
|
||||
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082 ffmpeg-$FFMPEG.tar.xz
|
||||
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
|
||||
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
|
||||
8ccbb9ab055205ac76632c9eeddd1ed6fc66936fc56afc2ed0fd5d9e23da3097 qtbase-everywhere-src-$QT.tar.xz
|
||||
9fd58144081654c3373768dd96ead294023830927b14fe3d3c1ef641fb324753 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
40142cb71fb1e07ad612bc361b67f5d54cd9367f9979ae6b86124a064deda06b qtsvg-everywhere-src-$QT.tar.xz
|
||||
f03bb7df619cd9ac9dba110e30b7bcab5dd88eb8bdc9cc752563b4367233203f qttools-everywhere-src-$QT.tar.xz
|
||||
dcc762acac043b9bb5e4d369b6d6f53e0ecfcf76a408fe0db5f7ef071c9d6dc8 qttranslations-everywhere-src-$QT.tar.xz
|
||||
ead4623bcb54a32257c5b3e3a5aec6d16ec96f4cda58d2e003f5a0c16f72046d qtbase-everywhere-src-$QT.tar.xz
|
||||
64450a52507c540de53616ed5e516df0e0905a99d3035ddfaa690f2b3f7c0cea qtimageformats-everywhere-src-$QT.tar.xz
|
||||
5ed2c0e04d5e73ff75c2a2ed92db5dc1788ba70f704fc2b71bc21644beda2533 qtsvg-everywhere-src-$QT.tar.xz
|
||||
d86d5098cf3e3e599f37e18df477e65908fc8f036e10ea731b3469ec4fdbd02a qttools-everywhere-src-$QT.tar.xz
|
||||
326e8253cfd0cb5745238117f297da80e30ce8f4c1db81990497bd388b026cde qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
a8e4a25e5c2686fd36981e527ed05e451fcfc226bddf350f4e76181371190937 shaderc-$SHADERC.tar.gz
|
||||
9427deccbdf4bde6a269938df38c6bd75247493786a310d8d733a2c82065ef47 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
@@ -233,26 +234,15 @@ rm -fr "qtbase-everywhere-src-$QT"
|
||||
tar xf "qtbase-everywhere-src-$QT.tar.xz"
|
||||
cd "qtbase-everywhere-src-$QT"
|
||||
|
||||
# Patch Qt to support macOS 11
|
||||
patch -p1 < "$SCRIPTDIR/qt-macos11compat.patch"
|
||||
|
||||
# since we don't have a direct reference to QtSvg, it doesn't deployed directly from the main binary
|
||||
# (only indirectly from iconengines), and the libqsvg.dylib imageformat plugin does not get deployed.
|
||||
# We could run macdeployqt twice, but that's even more janky than patching it.
|
||||
|
||||
# https://github.com/qt/qtbase/commit/7b018629c3c3ab23665bf1da00c43c1546042035
|
||||
# The QProcess default wait time of 30s may be too short in e.g. CI environments where processes may be blocked
|
||||
# for a longer time waiting for CPU or IO.
|
||||
|
||||
patch -u src/tools/macdeployqt/shared/shared.cpp <<EOF
|
||||
--- shared.cpp
|
||||
+++ shared.cpp
|
||||
@@ -152,7 +152,7 @@
|
||||
LogDebug() << " inspecting" << binaryPath;
|
||||
QProcess otool;
|
||||
otool.start("otool", QStringList() << "-L" << binaryPath);
|
||||
- otool.waitForFinished();
|
||||
+ otool.waitForFinished(-1);
|
||||
|
||||
if (otool.exitStatus() != QProcess::NormalExit || otool.exitCode() != 0) {
|
||||
LogError() << otool.readAllStandardError();
|
||||
@@ -1122,14 +1122,8 @@
|
||||
addPlugins(QStringLiteral("networkinformation"));
|
||||
}
|
||||
@@ -271,7 +261,7 @@ patch -u src/tools/macdeployqt/shared/shared.cpp <<EOF
|
||||
|
||||
// Platforminputcontext plugins if QtGui is in use
|
||||
EOF
|
||||
cmake -B build "${CMAKE_COMMON[@]}" -DFEATURE_dbus=OFF -DFEATURE_framework=OFF -DFEATURE_icu=OFF -DFEATURE_opengl=OFF -DFEATURE_sql=OFF -DFEATURE_gssapi=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON
|
||||
cmake -B build "${CMAKE_COMMON[@]}" -DCMAKE_BUILD_TYPE=MinSizeRel -DFEATURE_dbus=OFF -DFEATURE_framework=OFF -DFEATURE_icu=OFF -DFEATURE_opengl=OFF -DFEATURE_sql=OFF -DFEATURE_gssapi=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
@@ -282,7 +272,7 @@ tar xf "qtsvg-everywhere-src-$QT.tar.xz"
|
||||
cd "qtsvg-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}"
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DQT_GENERATE_SBOM=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -293,7 +283,7 @@ tar xf "qtimageformats-everywhere-src-$QT.tar.xz"
|
||||
cd "qtimageformats-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DFEATURE_system_webp=ON
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DQT_GENERATE_SBOM=OFF -DFEATURE_system_webp=ON
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -304,7 +294,7 @@ tar xf "qttools-everywhere-src-$QT.tar.xz"
|
||||
cd "qttools-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=ON -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DQT_GENERATE_SBOM=OFF -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=ON -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -333,7 +323,7 @@ tar xf "qttranslations-everywhere-src-$QT.tar.xz"
|
||||
cd "qttranslations-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}"
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DQT_GENERATE_SBOM=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
|
||||
78
.github/workflows/scripts/macos/qt-macos11compat.patch
vendored
Normal file
78
.github/workflows/scripts/macos/qt-macos11compat.patch
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
diff --git a/.cmake.conf b/.cmake.conf
|
||||
index 9a21ff42a74..d6707ba7dff 100644
|
||||
--- a/.cmake.conf
|
||||
+++ b/.cmake.conf
|
||||
@@ -51,7 +51,7 @@ set(QT_MAX_NEW_POLICY_CMAKE_VERSION_QT_APPLE "3.21")
|
||||
set(QT_SUPPORTED_MIN_MACOS_SDK_VERSION "14")
|
||||
set(QT_SUPPORTED_MAX_MACOS_SDK_VERSION "26")
|
||||
set(QT_SUPPORTED_MIN_MACOS_XCODE_VERSION "15")
|
||||
-set(QT_SUPPORTED_MIN_MACOS_VERSION "13")
|
||||
+set(QT_SUPPORTED_MIN_MACOS_VERSION "11")
|
||||
set(QT_SUPPORTED_MAX_MACOS_VERSION_TESTED "26")
|
||||
|
||||
set(QT_SUPPORTED_MIN_IOS_SDK_VERSION "17")
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index d3a14fc67eb..1553b956fe3 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -12,6 +12,10 @@ cmake_minimum_required(VERSION 3.16)
|
||||
# Get the repo version and CMake policy details
|
||||
include(.cmake.conf)
|
||||
|
||||
+if(APPLE)
|
||||
+ add_compile_options(-Werror=unguarded-availability-new)
|
||||
+endif()
|
||||
+
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtBaseHelpers.cmake)
|
||||
|
||||
qt_internal_check_if_path_has_symlinks("${CMAKE_BINARY_DIR}")
|
||||
diff --git a/src/corelib/global/qsysinfo.cpp b/src/corelib/global/qsysinfo.cpp
|
||||
index ae762c0cc6d..9171a5736b4 100644
|
||||
--- a/src/corelib/global/qsysinfo.cpp
|
||||
+++ b/src/corelib/global/qsysinfo.cpp
|
||||
@@ -1027,7 +1027,7 @@ QByteArray QSysInfo::machineUniqueId()
|
||||
{
|
||||
#if defined(Q_OS_DARWIN) && __has_include(<IOKit/IOKitLib.h>)
|
||||
char uuid[UuidStringLen + 1];
|
||||
- io_service_t service = IOServiceGetMatchingService(kIOMainPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
|
||||
+ io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
|
||||
QCFString stringRef = (CFStringRef)IORegistryEntryCreateCFProperty(service, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0);
|
||||
CFStringGetCString(stringRef, uuid, sizeof(uuid), kCFStringEncodingMacRoman);
|
||||
return QByteArray(uuid);
|
||||
diff --git a/src/corelib/kernel/qcore_mac.mm b/src/corelib/kernel/qcore_mac.mm
|
||||
index 9f27dbe694e..c023a48cad3 100644
|
||||
--- a/src/corelib/kernel/qcore_mac.mm
|
||||
+++ b/src/corelib/kernel/qcore_mac.mm
|
||||
@@ -372,7 +372,7 @@ bool qt_apple_runningWithLiquidGlass()
|
||||
return config;
|
||||
#endif
|
||||
|
||||
- QIOType<io_registry_entry_t> nvram = IORegistryEntryFromPath(kIOMainPortDefault, "IODeviceTree:/options");
|
||||
+ QIOType<io_registry_entry_t> nvram = IORegistryEntryFromPath(kIOMasterPortDefault, "IODeviceTree:/options");
|
||||
if (!nvram) {
|
||||
qWarning("Failed to locate NVRAM entry in IO registry");
|
||||
return {};
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
index 6b33d94d58c..867389e4c93 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
@@ -323,6 +323,8 @@ a normal (not maximized or full screen) top-level window.
|
||||
m_view.safeAreaInsets.bottom
|
||||
};
|
||||
|
||||
+ if (@available(macOS 12, *)) {
|
||||
+
|
||||
// The screen's safe area insets represent the distances from the screen's
|
||||
// edges at which content isn't obscured. The view's safe area margins do
|
||||
// not include the screen's insets automatically, so we need to manually
|
||||
@@ -355,6 +357,10 @@ a normal (not maximized or full screen) top-level window.
|
||||
};
|
||||
|
||||
return (screenSafeAreaMargins | viewSafeAreaMargins).toMargins();
|
||||
+
|
||||
+ } else {
|
||||
+ return viewSafeAreaMargins.toMargins();
|
||||
+ }
|
||||
}
|
||||
|
||||
void QCocoaWindow::updateSafeAreaMarginsIfNeeded()
|
||||
@@ -46,10 +46,10 @@ set FREETYPE=2.14.1
|
||||
set HARFBUZZ=12.0.0
|
||||
set LIBJPEGTURBO=3.1.2
|
||||
set LIBPNG=1650
|
||||
set SDL=SDL3-3.2.24
|
||||
set QT=6.9.2
|
||||
set LIBPNGLONG=1.6.50
|
||||
set QTMINOR=6.9
|
||||
set SDL=SDL3-3.2.24
|
||||
set QT=6.10.0
|
||||
set QTMINOR=6.10
|
||||
set QTAPNG=1.3.0
|
||||
set LZ4=1.10.0
|
||||
set WEBP=1.6.0
|
||||
@@ -72,11 +72,12 @@ call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" ca7fe2ca54a97e047f5eff236e62ae87546e862f509f0a62fc6e564ded3c6a95 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 97d59c78e40b4ddd018738d285a12afc320b57f8265a3f760353739a3619ccdb || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" f2fc6ff382c6f3af79493d0709dbd64847d0356313518f094f9096315f2fdb30 || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" af80bb671ea0f66c0036ce7041a56b0e550fc94fb88d2c77b5b6a3e33e42139b || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" d2f4c7a4a12630e879702353f944f96a5d8e764771b5a5f04163334ad61b39db || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 3e168d1b081ee3a2175fe1bd97ad03bb40fe7ce38a37e99923a19f0e7ec4d81c || goto error
|
||||
call :downloadfile "SDL-7914bdb7ea14ee5109d50df857c8dfc69a28a62d.patch" https://github.com/libsdl-org/SDL/commit/7914bdb7ea14ee5109d50df857c8dfc69a28a62d.patch 5c09a29a9cac87a85ec3b8f5a68ff0e5c6c47229f3e2282241b9c32166f26977 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" d3b5379edcace266273d789249b6d68ae9495ec1b0b562ba6d039034cd315d8e || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" ac2fe34a9f1c1451b6785474e9b1b64eb59edef6553be3d630240f16a730456d || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" c12f8bfb617e4a03da104be36f6966ba7f64bee331f0095da1a649a1149796d2 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" c6d0f0a512304ad87b20f5ff604442dd8d55769d659576ecfe5462fcd7bb9b7d || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" e6cc1ebf62cf37d81f3b86990086108518037bb383e75da327f297cc4fc1ae36 || goto error
|
||||
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
@@ -188,6 +189,7 @@ echo Building SDL...
|
||||
rmdir /S /Q "%SDL%"
|
||||
%SEVENZIP% x "%SDL%.zip" || goto error
|
||||
cd "%SDL%" || goto error
|
||||
%PATCH% -p1 < "..\SDL-7914bdb7ea14ee5109d50df857c8dfc69a28a62d.patch" || goto error
|
||||
cmake -B build %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release %FORCEPDB% -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
|
||||
@@ -46,8 +46,8 @@ set LIBJPEGTURBO=3.1.2
|
||||
set LIBPNG=1650
|
||||
set SDL=SDL3-3.2.24
|
||||
set LIBPNGLONG=1.6.50
|
||||
set QT=6.9.2
|
||||
set QTMINOR=6.9
|
||||
set QT=6.10.0
|
||||
set QTMINOR=6.10
|
||||
set QTAPNG=1.3.0
|
||||
set LZ4=1.10.0
|
||||
set WEBP=1.6.0
|
||||
@@ -70,11 +70,12 @@ call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" ca7fe2ca54a97e047f5eff236e62ae87546e862f509f0a62fc6e564ded3c6a95 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 97d59c78e40b4ddd018738d285a12afc320b57f8265a3f760353739a3619ccdb || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" f2fc6ff382c6f3af79493d0709dbd64847d0356313518f094f9096315f2fdb30 || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" af80bb671ea0f66c0036ce7041a56b0e550fc94fb88d2c77b5b6a3e33e42139b || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" d2f4c7a4a12630e879702353f944f96a5d8e764771b5a5f04163334ad61b39db || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 3e168d1b081ee3a2175fe1bd97ad03bb40fe7ce38a37e99923a19f0e7ec4d81c || goto error
|
||||
call :downloadfile "SDL-7914bdb7ea14ee5109d50df857c8dfc69a28a62d.patch" https://github.com/libsdl-org/SDL/commit/7914bdb7ea14ee5109d50df857c8dfc69a28a62d.patch 5c09a29a9cac87a85ec3b8f5a68ff0e5c6c47229f3e2282241b9c32166f26977 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" d3b5379edcace266273d789249b6d68ae9495ec1b0b562ba6d039034cd315d8e || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" ac2fe34a9f1c1451b6785474e9b1b64eb59edef6553be3d630240f16a730456d || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" c12f8bfb617e4a03da104be36f6966ba7f64bee331f0095da1a649a1149796d2 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" c6d0f0a512304ad87b20f5ff604442dd8d55769d659576ecfe5462fcd7bb9b7d || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" e6cc1ebf62cf37d81f3b86990086108518037bb383e75da327f297cc4fc1ae36 || goto error
|
||||
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
@@ -185,6 +186,7 @@ echo Building SDL...
|
||||
rmdir /S /Q "%SDL%"
|
||||
%SEVENZIP% x "%SDL%.zip" || goto error
|
||||
cd "%SDL%" || goto error
|
||||
%PATCH% -p1 < "..\SDL-7914bdb7ea14ee5109d50df857c8dfc69a28a62d.patch" || goto error
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release %FORCEPDB% -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
@@ -233,7 +235,7 @@ ninja install || goto error
|
||||
cd ..\.. || goto error
|
||||
|
||||
echo Building Qt Tools...
|
||||
rmdir /S /Q "qtimageformats-everywhere-src-%QT%"
|
||||
rmdir /S /Q "qttools-everywhere-src-%QT%"
|
||||
%SEVENZIP% x "qttools-everywhere-src-%QT%.zip" || goto error
|
||||
cd "qttools-everywhere-src-%QT%" || goto error
|
||||
mkdir build || goto error
|
||||
|
||||
2
.github/workflows/windows_deps_dispatch.yml
vendored
2
.github/workflows/windows_deps_dispatch.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dispatch to windows-dependencies repo
|
||||
uses: peter-evans/repository-dispatch@v3
|
||||
uses: peter-evans/repository-dispatch@v4
|
||||
with:
|
||||
token: ${{ secrets.DEPS_REPO_DISPATCH_ACCESS_TOKEN }}
|
||||
repository: pcsx2/pcsx2-windows-dependencies
|
||||
|
||||
187
3rdparty/fmt/ChangeLog.md
vendored
187
3rdparty/fmt/ChangeLog.md
vendored
@@ -1,3 +1,176 @@
|
||||
# 12.0.0 - 2025-09-17
|
||||
|
||||
- Optimized the default floating point formatting
|
||||
(https://github.com/fmtlib/fmt/issues/3675,
|
||||
https://github.com/fmtlib/fmt/issues/4516). In particular, formatting a
|
||||
`double` with format string compilation into a stack allocated buffer is
|
||||
more than 60% faster in version 12.0 compared to 11.2 according to
|
||||
[dtoa-benchmark](https://github.com/fmtlib/dtoa-benchmark):
|
||||
|
||||
```
|
||||
Function Time (ns) Speedup
|
||||
fmt11 34.471 1.00x
|
||||
fmt12 21.000 1.64x
|
||||
```
|
||||
|
||||
<img width="766" height="609" src="https://github.com/user-attachments/assets/d7d768ad-7543-468c-b0bb-449abf73b31b" />
|
||||
|
||||
- Added `constexpr` support to `fmt::format`. For example:
|
||||
|
||||
```c++
|
||||
#include <fmt/compile.h>
|
||||
|
||||
using namespace fmt::literals;
|
||||
std::string s = fmt::format(""_cf, 42);
|
||||
```
|
||||
|
||||
now works at compile time provided that `std::string` supports `constexpr`
|
||||
(https://github.com/fmtlib/fmt/issues/3403,
|
||||
https://github.com/fmtlib/fmt/pull/4456). Thanks @msvetkin.
|
||||
|
||||
- Added `FMT_STATIC_FORMAT` that allows formatting into a string of the exact
|
||||
required size at compile time.
|
||||
|
||||
For example:
|
||||
|
||||
```c++
|
||||
#include <fmt/compile.h>
|
||||
|
||||
constexpr auto s = FMT_STATIC_FORMAT("{}", 42);
|
||||
```
|
||||
|
||||
compiles to just
|
||||
|
||||
```s
|
||||
__ZL1s:
|
||||
.asciiz "42"
|
||||
```
|
||||
|
||||
It can be accessed as a C string with `s.c_str()` or as a string view with
|
||||
`s.str()`.
|
||||
|
||||
- Improved C++20 module support
|
||||
(https://github.com/fmtlib/fmt/pull/4451,
|
||||
https://github.com/fmtlib/fmt/pull/4459,
|
||||
https://github.com/fmtlib/fmt/pull/4476,
|
||||
https://github.com/fmtlib/fmt/pull/4488,
|
||||
https://github.com/fmtlib/fmt/issues/4491,
|
||||
https://github.com/fmtlib/fmt/pull/4495).
|
||||
Thanks @arBmind, @tkhyn, @Mishura4, @anonymouspc and @autoantwort.
|
||||
|
||||
- Switched to using estimated display width in precision. For example:
|
||||
|
||||
```c++
|
||||
fmt::print("|{:.4}|\n|1234|\n", "🐱🐱🐱");
|
||||
```
|
||||
|
||||
prints
|
||||
|
||||

|
||||
|
||||
because `🐱` has an estimated width of 2
|
||||
(https://github.com/fmtlib/fmt/issues/4272,
|
||||
https://github.com/fmtlib/fmt/pull/4443,
|
||||
https://github.com/fmtlib/fmt/pull/4475).
|
||||
Thanks @nikhilreddydev and @localspook.
|
||||
|
||||
- Fix interaction between debug presentation, precision, and width for strings
|
||||
(https://github.com/fmtlib/fmt/pull/4478). Thanks @localspook.
|
||||
|
||||
- Implemented allocator propagation on `basic_memory_buffer` move
|
||||
(https://github.com/fmtlib/fmt/issues/4487,
|
||||
https://github.com/fmtlib/fmt/pull/4490). Thanks @toprakmurat.
|
||||
|
||||
- Fixed an ambiguity between `std::reference_wrapper<T>` and `format_as`
|
||||
formatters (https://github.com/fmtlib/fmt/issues/4424,
|
||||
https://github.com/fmtlib/fmt/pull/4434). Thanks @jeremy-rifkin.
|
||||
|
||||
- Removed the following deprecated APIs:
|
||||
|
||||
- `has_formatter`: use `is_formattable` instead,
|
||||
- `basic_format_args::parse_context_type`,
|
||||
`basic_format_args::formatter_type` and similar aliases in context types,
|
||||
- wide stream overload of `fmt::printf`,
|
||||
- wide stream overloads of `fmt::print` that take text styles,
|
||||
- `is_*char` traits,
|
||||
- `fmt::localtime`.
|
||||
|
||||
- Deprecated wide overloads of `fmt::fprintf` and `fmt::sprintf`.
|
||||
|
||||
- Improved diagnostics for the incorrect usage of `fmt::ptr`
|
||||
(https://github.com/fmtlib/fmt/pull/4453). Thanks @TobiSchluter.
|
||||
|
||||
- Made handling of ANSI escape sequences more efficient
|
||||
(https://github.com/fmtlib/fmt/pull/4511,
|
||||
https://github.com/fmtlib/fmt/pull/4528).
|
||||
Thanks @localspook and @Anas-Hamdane.
|
||||
|
||||
- Fixed a buffer overflow on all emphasis flags set
|
||||
(https://github.com/fmtlib/fmt/pull/4498). Thanks @dominicpoeschko.
|
||||
|
||||
- Fixed an integer overflow for precision close to the max `int` value.
|
||||
|
||||
- Fixed compatibility with WASI (https://github.com/fmtlib/fmt/issues/4496,
|
||||
https://github.com/fmtlib/fmt/pull/4497). Thanks @whitequark.
|
||||
|
||||
- Fixed `back_insert_iterator` detection, preventing a fallback on slower path
|
||||
that handles arbitrary iterators (https://github.com/fmtlib/fmt/issues/4454).
|
||||
|
||||
- Fixed handling of invalid glibc `FILE` buffers
|
||||
(https://github.com/fmtlib/fmt/issues/4469).
|
||||
|
||||
- Added `wchar_t` support to the `std::byte` formatter
|
||||
(https://github.com/fmtlib/fmt/issues/4479,
|
||||
https://github.com/fmtlib/fmt/pull/4480). Thanks @phprus.
|
||||
|
||||
- Changed component prefix from `fmt-` to `fmt_` for compatibility with
|
||||
NSIS/CPack on Windows, e.g. `fmt-doc` changed to `fmt_doc`
|
||||
(https://github.com/fmtlib/fmt/issues/4441,
|
||||
https://github.com/fmtlib/fmt/pull/4442). Thanks @n-stein.
|
||||
|
||||
- Added the `FMT_CUSTOM_ASSERT_FAIL` macro to simplify providing a custom
|
||||
`fmt::assert_fail` implementation (https://github.com/fmtlib/fmt/pull/4505).
|
||||
Thanks @HazardyKnusperkeks.
|
||||
|
||||
- Switched to `FMT_THROW` on reporting format errors so that it can be
|
||||
overriden by users when exceptions are disabled
|
||||
(https://github.com/fmtlib/fmt/pull/4521). Thanks @HazardyKnusperkeks.
|
||||
|
||||
- Improved master project detection and disabled install targets when using
|
||||
{fmt} as a subproject by default (https://github.com/fmtlib/fmt/pull/4536).
|
||||
Thanks @crueter.
|
||||
|
||||
- Made various code improvements
|
||||
(https://github.com/fmtlib/fmt/pull/4445,
|
||||
https://github.com/fmtlib/fmt/pull/4448,
|
||||
https://github.com/fmtlib/fmt/pull/4473,
|
||||
https://github.com/fmtlib/fmt/pull/4522).
|
||||
Thanks @localspook, @tchaikov and @way4sahil.
|
||||
|
||||
- Added Conan instructions to the docs
|
||||
(https://github.com/fmtlib/fmt/pull/4537). Thanks @uilianries.
|
||||
|
||||
- Removed Bazel files to avoid issues with downstream packaging
|
||||
(https://github.com/fmtlib/fmt/pull/4530). Thanks @mering.
|
||||
|
||||
- Added more entries for generated files to `.gitignore`
|
||||
(https://github.com/fmtlib/fmt/pull/4355,
|
||||
https://github.com/fmtlib/fmt/pull/4512).
|
||||
Thanks @dinomight and @localspook.
|
||||
|
||||
- Fixed various warnings and compilation issues
|
||||
(https://github.com/fmtlib/fmt/pull/4447,
|
||||
https://github.com/fmtlib/fmt/issues/4470,
|
||||
https://github.com/fmtlib/fmt/pull/4474,
|
||||
https://github.com/fmtlib/fmt/pull/4477,
|
||||
https://github.com/fmtlib/fmt/pull/4471,
|
||||
https://github.com/fmtlib/fmt/pull/4483,
|
||||
https://github.com/fmtlib/fmt/pull/4515,
|
||||
https://github.com/fmtlib/fmt/issues/4533,
|
||||
https://github.com/fmtlib/fmt/pull/4534).
|
||||
Thanks @dodomorandi, @localspook, @remyjette, @Tomek-Stolarczyk, @Mishura4,
|
||||
@mattiasljungstrom and @FatihBAKIR.
|
||||
|
||||
# 11.2.0 - 2025-05-03
|
||||
|
||||
- Added the `s` specifier for `std::error_code`. It allows formatting an error
|
||||
@@ -56,17 +229,18 @@
|
||||
https://github.com/fmtlib/fmt/pull/4361). Thanks @dinomight.
|
||||
|
||||
- Added error reporting for duplicate named arguments
|
||||
(https://github.com/fmtlib/fmt/pull/4367). Thanks @dinomight.
|
||||
(https://github.com/fmtlib/fmt/issues/4282,
|
||||
https://github.com/fmtlib/fmt/pull/4367). Thanks @dinomight.
|
||||
|
||||
- Fixed formatting of `long` with `FMT_BUILTIN_TYPES=0`
|
||||
(https://github.com/fmtlib/fmt/issues/4375,
|
||||
https://github.com/fmtlib/fmt/issues/4394).
|
||||
|
||||
- Optimized `text_style` using bit packing
|
||||
(https://github.com/fmtlib/fmt/pull/4363). Thanks @LocalSpook.
|
||||
(https://github.com/fmtlib/fmt/pull/4363). Thanks @localspook.
|
||||
|
||||
- Added support for incomplete types (https://github.com/fmtlib/fmt/issues/3180,
|
||||
https://github.com/fmtlib/fmt/pull/4383). Thanks @LocalSpook.
|
||||
https://github.com/fmtlib/fmt/pull/4383). Thanks @localspook.
|
||||
|
||||
- Fixed a flush issue in `fmt::print` when using libstdc++
|
||||
(https://github.com/fmtlib/fmt/issues/4398).
|
||||
@@ -107,13 +281,14 @@
|
||||
`float` (https://github.com/fmtlib/fmt/issues/3649).
|
||||
|
||||
- Moved `is_compiled_string` to the public API
|
||||
(https://github.com/fmtlib/fmt/issues/4342). Thanks @SwooshyCueb.
|
||||
(https://github.com/fmtlib/fmt/issues/4335,
|
||||
https://github.com/fmtlib/fmt/issues/4342). Thanks @SwooshyCueb.
|
||||
|
||||
- Simplified implementation of `operator""_cf`
|
||||
(https://github.com/fmtlib/fmt/pull/4349). Thanks @LocalSpook.
|
||||
(https://github.com/fmtlib/fmt/pull/4349). Thanks @localspook.
|
||||
|
||||
- Fixed `__builtin_strlen` detection (https://github.com/fmtlib/fmt/pull/4329).
|
||||
Thanks @LocalSpook.
|
||||
Thanks @localspook.
|
||||
|
||||
- Fixed handling of BMI paths with the Ninja generator
|
||||
(https://github.com/fmtlib/fmt/pull/4344). Thanks @tkhyn.
|
||||
|
||||
3
3rdparty/fmt/README.md
vendored
3
3rdparty/fmt/README.md
vendored
@@ -4,8 +4,9 @@
|
||||
[](https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos)
|
||||
[](https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?\%0Acolspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\%0ASummary&q=proj%3Dfmt&can=1)
|
||||
[](https://stackoverflow.com/questions/tagged/fmt)
|
||||
[](https://www.bestpractices.dev/projects/8880)
|
||||
[](https://securityscorecards.dev/viewer/?uri=github.com/fmtlib/fmt)
|
||||
[](https://stackoverflow.com/questions/tagged/fmt)
|
||||
|
||||
**{fmt}** is an open-source formatting library providing a fast and safe
|
||||
alternative to C stdio and C++ iostreams.
|
||||
|
||||
4
3rdparty/fmt/include/fmt/args.h
vendored
4
3rdparty/fmt/include/fmt/args.h
vendored
@@ -71,7 +71,7 @@ class dynamic_arg_list {
|
||||
* It can be implicitly converted into `fmt::basic_format_args` for passing
|
||||
* into type-erased formatting functions such as `fmt::vformat`.
|
||||
*/
|
||||
template <typename Context> class dynamic_format_arg_store {
|
||||
FMT_EXPORT template <typename Context> class dynamic_format_arg_store {
|
||||
private:
|
||||
using char_type = typename Context::char_type;
|
||||
|
||||
@@ -212,7 +212,7 @@ template <typename Context> class dynamic_format_arg_store {
|
||||
}
|
||||
|
||||
/// Returns the number of elements in the store.
|
||||
size_t size() const noexcept { return data_.size(); }
|
||||
auto size() const noexcept -> size_t { return data_.size(); }
|
||||
};
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
179
3rdparty/fmt/include/fmt/base.h
vendored
179
3rdparty/fmt/include/fmt/base.h
vendored
@@ -21,7 +21,7 @@
|
||||
#endif
|
||||
|
||||
// The fmt library version in the form major * 10000 + minor * 100 + patch.
|
||||
#define FMT_VERSION 110200
|
||||
#define FMT_VERSION 120000
|
||||
|
||||
// Detect compiler versions.
|
||||
#if defined(__clang__) && !defined(__ibmxl__)
|
||||
@@ -201,14 +201,6 @@
|
||||
# define FMT_NODISCARD
|
||||
#endif
|
||||
|
||||
#ifdef FMT_DEPRECATED
|
||||
// Use the provided definition.
|
||||
#elif FMT_HAS_CPP14_ATTRIBUTE(deprecated)
|
||||
# define FMT_DEPRECATED [[deprecated]]
|
||||
#else
|
||||
# define FMT_DEPRECATED /* deprecated */
|
||||
#endif
|
||||
|
||||
#if FMT_GCC_VERSION || FMT_CLANG_VERSION
|
||||
# define FMT_VISIBILITY(value) __attribute__((visibility(value)))
|
||||
#else
|
||||
@@ -260,7 +252,7 @@ FMT_PRAGMA_CLANG(diagnostic push)
|
||||
#ifndef FMT_BEGIN_NAMESPACE
|
||||
# define FMT_BEGIN_NAMESPACE \
|
||||
namespace fmt { \
|
||||
inline namespace v11 {
|
||||
inline namespace v12 {
|
||||
# define FMT_END_NAMESPACE \
|
||||
} \
|
||||
}
|
||||
@@ -356,6 +348,9 @@ template <typename T> constexpr auto max_of(T a, T b) -> T {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
|
||||
const char* message);
|
||||
|
||||
namespace detail {
|
||||
// Suppresses "unused variable" warnings with the method described in
|
||||
// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/.
|
||||
@@ -396,7 +391,7 @@ FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
|
||||
# define FMT_ASSERT(condition, message) \
|
||||
((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \
|
||||
? (void)0 \
|
||||
: fmt::detail::assert_fail(__FILE__, __LINE__, (message)))
|
||||
: ::fmt::assert_fail(__FILE__, __LINE__, (message)))
|
||||
#endif
|
||||
|
||||
#ifdef FMT_USE_INT128
|
||||
@@ -463,12 +458,13 @@ enum { use_utf8 = !FMT_WIN32 || is_utf8_enabled };
|
||||
static_assert(!FMT_UNICODE || use_utf8,
|
||||
"Unicode support requires compiling with /utf-8");
|
||||
|
||||
template <typename T> constexpr const char* narrow(const T*) { return nullptr; }
|
||||
constexpr FMT_ALWAYS_INLINE const char* narrow(const char* s) { return s; }
|
||||
template <typename T> constexpr auto narrow(T*) -> char* { return nullptr; }
|
||||
constexpr FMT_ALWAYS_INLINE auto narrow(const char* s) -> const char* {
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, std::size_t n)
|
||||
-> int {
|
||||
FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, size_t n) -> int {
|
||||
if (!is_constant_evaluated() && sizeof(Char) == 1) return memcmp(s1, s2, n);
|
||||
for (; n != 0; ++s1, ++s2, --n) {
|
||||
if (*s1 < *s2) return -1;
|
||||
@@ -540,7 +536,7 @@ template <typename Char> class basic_string_view {
|
||||
FMT_CONSTEXPR20 basic_string_view(const Char* s) : data_(s) {
|
||||
#if FMT_HAS_BUILTIN(__builtin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION
|
||||
if (std::is_same<Char, char>::value && !detail::is_constant_evaluated()) {
|
||||
size_ = __builtin_strlen(detail::narrow(s)); // strlen is not costexpr.
|
||||
size_ = __builtin_strlen(detail::narrow(s)); // strlen is not constexpr.
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -616,19 +612,6 @@ template <typename Char> class basic_string_view {
|
||||
|
||||
using string_view = basic_string_view<char>;
|
||||
|
||||
// DEPRECATED! Will be merged with is_char and moved to detail.
|
||||
template <typename T> struct is_xchar : std::false_type {};
|
||||
template <> struct is_xchar<wchar_t> : std::true_type {};
|
||||
template <> struct is_xchar<char16_t> : std::true_type {};
|
||||
template <> struct is_xchar<char32_t> : std::true_type {};
|
||||
#ifdef __cpp_char8_t
|
||||
template <> struct is_xchar<char8_t> : std::true_type {};
|
||||
#endif
|
||||
|
||||
// Specifies if `T` is a character (code unit) type.
|
||||
template <typename T> struct is_char : is_xchar<T> {};
|
||||
template <> struct is_char<char> : std::true_type {};
|
||||
|
||||
template <typename T> class basic_appender;
|
||||
using appender = basic_appender<char>;
|
||||
|
||||
@@ -781,7 +764,7 @@ class basic_specs {
|
||||
(static_cast<unsigned>(p) << precision_shift);
|
||||
}
|
||||
|
||||
constexpr bool dynamic() const {
|
||||
constexpr auto dynamic() const -> bool {
|
||||
return (data_ & (width_mask | precision_mask)) != 0;
|
||||
}
|
||||
|
||||
@@ -921,14 +904,47 @@ template <typename Char = char> class parse_context {
|
||||
FMT_CONSTEXPR void check_dynamic_spec(int arg_id);
|
||||
};
|
||||
|
||||
#ifndef FMT_USE_LOCALE
|
||||
# define FMT_USE_LOCALE (FMT_OPTIMIZE_SIZE <= 1)
|
||||
#endif
|
||||
|
||||
// A type-erased reference to std::locale to avoid the heavy <locale> include.
|
||||
class locale_ref {
|
||||
#if FMT_USE_LOCALE
|
||||
private:
|
||||
const void* locale_; // A type-erased pointer to std::locale.
|
||||
|
||||
public:
|
||||
constexpr locale_ref() : locale_(nullptr) {}
|
||||
|
||||
template <typename Locale, FMT_ENABLE_IF(sizeof(Locale::collate) != 0)>
|
||||
locale_ref(const Locale& loc);
|
||||
|
||||
inline explicit operator bool() const noexcept { return locale_ != nullptr; }
|
||||
#endif // FMT_USE_LOCALE
|
||||
|
||||
public:
|
||||
template <typename Locale> auto get() const -> Locale;
|
||||
};
|
||||
|
||||
FMT_END_EXPORT
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Specifies if `T` is a code unit type.
|
||||
template <typename T> struct is_code_unit : std::false_type {};
|
||||
template <> struct is_code_unit<char> : std::true_type {};
|
||||
template <> struct is_code_unit<wchar_t> : std::true_type {};
|
||||
template <> struct is_code_unit<char16_t> : std::true_type {};
|
||||
template <> struct is_code_unit<char32_t> : std::true_type {};
|
||||
#ifdef __cpp_char8_t
|
||||
template <> struct is_code_unit<char8_t> : bool_constant<is_utf8_enabled> {};
|
||||
#endif
|
||||
|
||||
// Constructs fmt::basic_string_view<Char> from types implicitly convertible
|
||||
// to it, deducing Char. Explicitly convertible types such as the ones returned
|
||||
// from FMT_STRING are intentionally excluded.
|
||||
template <typename Char, FMT_ENABLE_IF(is_char<Char>::value)>
|
||||
template <typename Char, FMT_ENABLE_IF(is_code_unit<Char>::value)>
|
||||
constexpr auto to_string_view(const Char* s) -> basic_string_view<Char> {
|
||||
return s;
|
||||
}
|
||||
@@ -1057,11 +1073,11 @@ template <bool B1, bool B2, bool... Tail> constexpr auto count() -> int {
|
||||
return (B1 ? 1 : 0) + count<B2, Tail...>();
|
||||
}
|
||||
|
||||
template <typename... Args> constexpr auto count_named_args() -> int {
|
||||
return count<is_named_arg<Args>::value...>();
|
||||
template <typename... T> constexpr auto count_named_args() -> int {
|
||||
return count<is_named_arg<T>::value...>();
|
||||
}
|
||||
template <typename... Args> constexpr auto count_static_named_args() -> int {
|
||||
return count<is_static_named_arg<Args>::value...>();
|
||||
template <typename... T> constexpr auto count_static_named_args() -> int {
|
||||
return count<is_static_named_arg<T>::value...>();
|
||||
}
|
||||
|
||||
template <typename Char> struct named_arg_info {
|
||||
@@ -1069,7 +1085,7 @@ template <typename Char> struct named_arg_info {
|
||||
int id;
|
||||
};
|
||||
|
||||
// named_args is non-const to suppress a bogus -Wmaybe-uninitalized in gcc 13.
|
||||
// named_args is non-const to suppress a bogus -Wmaybe-uninitialized in gcc 13.
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR void check_for_duplicate(named_arg_info<Char>* named_args,
|
||||
int named_arg_index,
|
||||
@@ -1173,7 +1189,7 @@ template <typename Char> struct type_mapper {
|
||||
static auto map(ubitint<N>)
|
||||
-> conditional_t<N <= 64, unsigned long long, void>;
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(is_char<T>::value)>
|
||||
template <typename T, FMT_ENABLE_IF(is_code_unit<T>::value)>
|
||||
static auto map(T) -> conditional_t<
|
||||
std::is_same<T, char>::value || std::is_same<T, Char>::value, Char, void>;
|
||||
|
||||
@@ -1679,12 +1695,12 @@ template <typename... T> struct arg_pack {};
|
||||
template <typename Char, int NUM_ARGS, int NUM_NAMED_ARGS, bool DYNAMIC_NAMES>
|
||||
class format_string_checker {
|
||||
private:
|
||||
type types_[max_of(1, NUM_ARGS)];
|
||||
named_arg_info<Char> named_args_[max_of(1, NUM_NAMED_ARGS)];
|
||||
type types_[max_of<size_t>(1, NUM_ARGS)];
|
||||
named_arg_info<Char> named_args_[max_of<size_t>(1, NUM_NAMED_ARGS)];
|
||||
compile_parse_context<Char> context_;
|
||||
|
||||
using parse_func = auto (*)(parse_context<Char>&) -> const Char*;
|
||||
parse_func parse_funcs_[max_of(1, NUM_ARGS)];
|
||||
parse_func parse_funcs_[max_of<size_t>(1, NUM_ARGS)];
|
||||
|
||||
public:
|
||||
template <typename... T>
|
||||
@@ -2033,6 +2049,17 @@ struct has_back_insert_iterator_container_append<
|
||||
.append(std::declval<InputIt>(),
|
||||
std::declval<InputIt>()))>> : std::true_type {};
|
||||
|
||||
template <typename OutputIt, typename InputIt, typename = void>
|
||||
struct has_back_insert_iterator_container_insert_at_end : std::false_type {};
|
||||
|
||||
template <typename OutputIt, typename InputIt>
|
||||
struct has_back_insert_iterator_container_insert_at_end<
|
||||
OutputIt, InputIt,
|
||||
void_t<decltype(get_container(std::declval<OutputIt>())
|
||||
.insert(get_container(std::declval<OutputIt>()).end(),
|
||||
std::declval<InputIt>(),
|
||||
std::declval<InputIt>()))>> : std::true_type {};
|
||||
|
||||
// An optimized version of std::copy with the output value type (T).
|
||||
template <typename T, typename InputIt, typename OutputIt,
|
||||
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&
|
||||
@@ -2047,6 +2074,8 @@ FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
|
||||
template <typename T, typename InputIt, typename OutputIt,
|
||||
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value &&
|
||||
!has_back_insert_iterator_container_append<
|
||||
OutputIt, InputIt>::value &&
|
||||
has_back_insert_iterator_container_insert_at_end<
|
||||
OutputIt, InputIt>::value)>
|
||||
FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
|
||||
-> OutputIt {
|
||||
@@ -2056,7 +2085,11 @@ FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
|
||||
}
|
||||
|
||||
template <typename T, typename InputIt, typename OutputIt,
|
||||
FMT_ENABLE_IF(!is_back_insert_iterator<OutputIt>::value)>
|
||||
FMT_ENABLE_IF(!(is_back_insert_iterator<OutputIt>::value &&
|
||||
(has_back_insert_iterator_container_append<
|
||||
OutputIt, InputIt>::value ||
|
||||
has_back_insert_iterator_container_insert_at_end<
|
||||
OutputIt, InputIt>::value)))>
|
||||
FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
|
||||
while (begin != end) *out++ = static_cast<T>(*begin++);
|
||||
return out;
|
||||
@@ -2176,7 +2209,7 @@ template <typename Context> class value {
|
||||
static_assert(N <= 64, "unsupported _BitInt");
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(is_char<T>::value)>
|
||||
template <typename T, FMT_ENABLE_IF(is_code_unit<T>::value)>
|
||||
constexpr FMT_INLINE value(T x FMT_BUILTIN) : char_value(x) {
|
||||
static_assert(
|
||||
std::is_same<T, char>::value || std::is_same<T, char_type>::value,
|
||||
@@ -2252,7 +2285,7 @@ template <typename Context> class value {
|
||||
custom.value = const_cast<value_type*>(&x);
|
||||
#endif
|
||||
}
|
||||
custom.format = format_custom<value_type, formatter<value_type, char_type>>;
|
||||
custom.format = format_custom<value_type>;
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!has_formatter<T, char_type>())>
|
||||
@@ -2263,10 +2296,10 @@ template <typename Context> class value {
|
||||
}
|
||||
|
||||
// Formats an argument of a custom type, such as a user-defined class.
|
||||
template <typename T, typename Formatter>
|
||||
template <typename T>
|
||||
static void format_custom(void* arg, parse_context<char_type>& parse_ctx,
|
||||
Context& ctx) {
|
||||
auto f = Formatter();
|
||||
auto f = formatter<T, char_type>();
|
||||
parse_ctx.advance_to(f.parse(parse_ctx));
|
||||
using qualified_type =
|
||||
conditional_t<has_formatter<const T, char_type>(), const T, T>;
|
||||
@@ -2293,35 +2326,14 @@ struct is_output_iterator<
|
||||
enable_if_t<std::is_assignable<decltype(*std::declval<decay_t<It>&>()++),
|
||||
T>::value>> : std::true_type {};
|
||||
|
||||
#ifndef FMT_USE_LOCALE
|
||||
# define FMT_USE_LOCALE (FMT_OPTIMIZE_SIZE <= 1)
|
||||
#endif
|
||||
|
||||
// A type-erased reference to an std::locale to avoid a heavy <locale> include.
|
||||
class locale_ref {
|
||||
#if FMT_USE_LOCALE
|
||||
private:
|
||||
const void* locale_; // A type-erased pointer to std::locale.
|
||||
|
||||
public:
|
||||
constexpr locale_ref() : locale_(nullptr) {}
|
||||
template <typename Locale> locale_ref(const Locale& loc);
|
||||
|
||||
inline explicit operator bool() const noexcept { return locale_ != nullptr; }
|
||||
#endif // FMT_USE_LOCALE
|
||||
|
||||
public:
|
||||
template <typename Locale> auto get() const -> Locale;
|
||||
};
|
||||
|
||||
template <typename> constexpr auto encode_types() -> unsigned long long {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Context, typename Arg, typename... Args>
|
||||
template <typename Context, typename First, typename... T>
|
||||
constexpr auto encode_types() -> unsigned long long {
|
||||
return static_cast<unsigned>(stored_type_constant<Arg, Context>::value) |
|
||||
(encode_types<Context, Args...>() << packed_arg_bits);
|
||||
return static_cast<unsigned>(stored_type_constant<First, Context>::value) |
|
||||
(encode_types<Context, T...>() << packed_arg_bits);
|
||||
}
|
||||
|
||||
template <typename Context, typename... T, size_t NUM_ARGS = sizeof...(T)>
|
||||
@@ -2338,8 +2350,9 @@ template <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,
|
||||
unsigned long long DESC>
|
||||
struct named_arg_store {
|
||||
// args_[0].named_args points to named_args to avoid bloating format_args.
|
||||
arg_t<Context, NUM_ARGS> args[1 + NUM_ARGS];
|
||||
named_arg_info<typename Context::char_type> named_args[NUM_NAMED_ARGS];
|
||||
arg_t<Context, NUM_ARGS> args[1u + NUM_ARGS];
|
||||
named_arg_info<typename Context::char_type>
|
||||
named_args[static_cast<size_t>(NUM_NAMED_ARGS)];
|
||||
|
||||
template <typename... T>
|
||||
FMT_CONSTEXPR FMT_ALWAYS_INLINE named_arg_store(T&... values)
|
||||
@@ -2358,8 +2371,8 @@ struct named_arg_store {
|
||||
}
|
||||
|
||||
named_arg_store(const named_arg_store& rhs) = delete;
|
||||
named_arg_store& operator=(const named_arg_store& rhs) = delete;
|
||||
named_arg_store& operator=(named_arg_store&& rhs) = delete;
|
||||
auto operator=(const named_arg_store& rhs) -> named_arg_store& = delete;
|
||||
auto operator=(named_arg_store&& rhs) -> named_arg_store& = delete;
|
||||
operator const arg_t<Context, NUM_ARGS>*() const { return args + 1; }
|
||||
};
|
||||
|
||||
@@ -2372,7 +2385,7 @@ struct format_arg_store {
|
||||
// +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
|
||||
using type =
|
||||
conditional_t<NUM_NAMED_ARGS == 0,
|
||||
arg_t<Context, NUM_ARGS>[max_of(1, NUM_ARGS)],
|
||||
arg_t<Context, NUM_ARGS>[max_of<size_t>(1, NUM_ARGS)],
|
||||
named_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>>;
|
||||
type args;
|
||||
};
|
||||
@@ -2656,22 +2669,17 @@ class context {
|
||||
private:
|
||||
appender out_;
|
||||
format_args args_;
|
||||
FMT_NO_UNIQUE_ADDRESS detail::locale_ref loc_;
|
||||
FMT_NO_UNIQUE_ADDRESS locale_ref loc_;
|
||||
|
||||
public:
|
||||
/// The character type for the output.
|
||||
using char_type = char;
|
||||
|
||||
using char_type = char; ///< The character type for the output.
|
||||
using iterator = appender;
|
||||
using format_arg = basic_format_arg<context>;
|
||||
using parse_context_type FMT_DEPRECATED = parse_context<>;
|
||||
template <typename T> using formatter_type FMT_DEPRECATED = formatter<T>;
|
||||
enum { builtin_types = FMT_BUILTIN_TYPES };
|
||||
|
||||
/// Constructs a `context` object. References to the arguments are stored
|
||||
/// in the object so make sure they have appropriate lifetimes.
|
||||
FMT_CONSTEXPR context(iterator out, format_args args,
|
||||
detail::locale_ref loc = {})
|
||||
FMT_CONSTEXPR context(iterator out, format_args args, locale_ref loc = {})
|
||||
: out_(out), args_(args), loc_(loc) {}
|
||||
context(context&&) = default;
|
||||
context(const context&) = delete;
|
||||
@@ -2692,7 +2700,7 @@ class context {
|
||||
// Advances the begin iterator to `it`.
|
||||
FMT_CONSTEXPR void advance_to(iterator) {}
|
||||
|
||||
FMT_CONSTEXPR auto locale() const -> detail::locale_ref { return loc_; }
|
||||
FMT_CONSTEXPR auto locale() const -> locale_ref { return loc_; }
|
||||
};
|
||||
|
||||
template <typename Char = char> struct runtime_format_string {
|
||||
@@ -2779,9 +2787,6 @@ template <typename T, typename Char = char>
|
||||
concept formattable = is_formattable<remove_reference_t<T>, Char>::value;
|
||||
#endif
|
||||
|
||||
template <typename T, typename Char>
|
||||
using has_formatter FMT_DEPRECATED = std::is_constructible<formatter<T, Char>>;
|
||||
|
||||
// A formatter specialization for natively supported types.
|
||||
template <typename T, typename Char>
|
||||
struct formatter<T, Char,
|
||||
@@ -2978,9 +2983,9 @@ FMT_INLINE void println(format_string<T...> fmt, T&&... args) {
|
||||
return fmt::println(stdout, fmt, static_cast<T&&>(args)...);
|
||||
}
|
||||
|
||||
FMT_END_EXPORT
|
||||
FMT_PRAGMA_CLANG(diagnostic pop)
|
||||
FMT_PRAGMA_GCC(pop_options)
|
||||
FMT_END_EXPORT
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#ifdef FMT_HEADER_ONLY
|
||||
|
||||
113
3rdparty/fmt/include/fmt/chrono.h
vendored
113
3rdparty/fmt/include/fmt/chrono.h
vendored
@@ -38,6 +38,7 @@ FMT_BEGIN_NAMESPACE
|
||||
// Copyright Paul Dreik 2019
|
||||
namespace safe_duration_cast {
|
||||
|
||||
// DEPRECATED!
|
||||
template <typename To, typename From,
|
||||
FMT_ENABLE_IF(!std::is_same<From, To>::value &&
|
||||
std::numeric_limits<From>::is_signed ==
|
||||
@@ -161,17 +162,6 @@ auto safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
|
||||
int& ec) -> To {
|
||||
using From = std::chrono::duration<FromRep, FromPeriod>;
|
||||
ec = 0;
|
||||
if (std::isnan(from.count())) {
|
||||
// nan in, gives nan out. easy.
|
||||
return To{std::numeric_limits<typename To::rep>::quiet_NaN()};
|
||||
}
|
||||
// maybe we should also check if from is denormal, and decide what to do about
|
||||
// it.
|
||||
|
||||
// +-inf should be preserved.
|
||||
if (std::isinf(from.count())) {
|
||||
return To{from.count()};
|
||||
}
|
||||
|
||||
// the basic idea is that we need to convert from count() in the from type
|
||||
// to count() in the To type, by multiplying it with this:
|
||||
@@ -282,8 +272,6 @@ namespace detail {
|
||||
#define FMT_NOMACRO
|
||||
|
||||
template <typename T = void> struct null {};
|
||||
inline auto localtime_r FMT_NOMACRO(...) -> null<> { return null<>(); }
|
||||
inline auto localtime_s(...) -> null<> { return null<>(); }
|
||||
inline auto gmtime_r(...) -> null<> { return null<>(); }
|
||||
inline auto gmtime_s(...) -> null<> { return null<>(); }
|
||||
|
||||
@@ -326,7 +314,7 @@ inline auto get_classic_locale() -> const std::locale& {
|
||||
}
|
||||
|
||||
template <typename CodeUnit> struct codecvt_result {
|
||||
static constexpr const size_t max_size = 32;
|
||||
static constexpr size_t max_size = 32;
|
||||
CodeUnit buf[max_size];
|
||||
CodeUnit* end;
|
||||
};
|
||||
@@ -443,11 +431,7 @@ auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
|
||||
|
||||
using common_rep = typename std::common_type<FromRep, typename To::rep,
|
||||
decltype(factor::num)>::type;
|
||||
|
||||
int ec = 0;
|
||||
auto count = safe_duration_cast::lossless_integral_conversion<common_rep>(
|
||||
from.count(), ec);
|
||||
if (ec) throw_duration_error();
|
||||
common_rep count = from.count(); // This conversion is lossless.
|
||||
|
||||
// Multiply from.count() by factor and check for overflow.
|
||||
if (const_check(factor::num != 1)) {
|
||||
@@ -458,6 +442,7 @@ auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
|
||||
count *= factor::num;
|
||||
}
|
||||
if (const_check(factor::den != 1)) count /= factor::den;
|
||||
int ec = 0;
|
||||
auto to =
|
||||
To(safe_duration_cast::lossless_integral_conversion<typename To::rep>(
|
||||
count, ec));
|
||||
@@ -471,6 +456,8 @@ template <typename To, typename FromRep, typename FromPeriod,
|
||||
std::is_floating_point<typename To::rep>::value)>
|
||||
auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
|
||||
#if FMT_SAFE_DURATION_CAST
|
||||
// Preserve infinity and NaN.
|
||||
if (!isfinite(from.count())) return static_cast<To>(from.count());
|
||||
// Throwing version of safe_duration_cast is only available for
|
||||
// integer to integer or float to float casts.
|
||||
int ec;
|
||||
@@ -487,7 +474,7 @@ template <typename To, typename FromRep, typename FromPeriod,
|
||||
FMT_ENABLE_IF(
|
||||
!is_similar_arithmetic_type<FromRep, typename To::rep>::value)>
|
||||
auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
|
||||
// Mixed integer <-> float cast is not supported by safe_duration_cast.
|
||||
// Mixed integer <-> float cast is not supported by safe duration_cast.
|
||||
return std::chrono::duration_cast<To>(from);
|
||||
}
|
||||
|
||||
@@ -501,86 +488,10 @@ auto to_time_t(sys_time<Duration> time_point) -> std::time_t {
|
||||
.count();
|
||||
}
|
||||
|
||||
namespace tz {
|
||||
|
||||
// DEPRECATED!
|
||||
struct time_zone {
|
||||
template <typename Duration, typename LocalTime>
|
||||
auto to_sys(LocalTime) -> sys_time<Duration> {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
template <typename... T> auto current_zone(T...) -> time_zone* {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename... T> void _tzset(T...) {}
|
||||
} // namespace tz
|
||||
|
||||
// DEPRECATED!
|
||||
inline void tzset_once() {
|
||||
static bool init = []() {
|
||||
using namespace tz;
|
||||
_tzset();
|
||||
return false;
|
||||
}();
|
||||
ignore_unused(init);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
FMT_BEGIN_EXPORT
|
||||
|
||||
/**
|
||||
* Converts given time since epoch as `std::time_t` value into calendar time,
|
||||
* expressed in local time. Unlike `std::localtime`, this function is
|
||||
* thread-safe on most platforms.
|
||||
*/
|
||||
FMT_DEPRECATED inline auto localtime(std::time_t time) -> std::tm {
|
||||
struct dispatcher {
|
||||
std::time_t time_;
|
||||
std::tm tm_;
|
||||
|
||||
inline dispatcher(std::time_t t) : time_(t) {}
|
||||
|
||||
inline auto run() -> bool {
|
||||
using namespace fmt::detail;
|
||||
return handle(localtime_r(&time_, &tm_));
|
||||
}
|
||||
|
||||
inline auto handle(std::tm* tm) -> bool { return tm != nullptr; }
|
||||
|
||||
inline auto handle(detail::null<>) -> bool {
|
||||
using namespace fmt::detail;
|
||||
return fallback(localtime_s(&tm_, &time_));
|
||||
}
|
||||
|
||||
inline auto fallback(int res) -> bool { return res == 0; }
|
||||
|
||||
#if !FMT_MSC_VERSION
|
||||
inline auto fallback(detail::null<>) -> bool {
|
||||
using namespace fmt::detail;
|
||||
std::tm* tm = std::localtime(&time_);
|
||||
if (tm) tm_ = *tm;
|
||||
return tm != nullptr;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
dispatcher lt(time);
|
||||
// Too big time values may be unsupported.
|
||||
if (!lt.run()) FMT_THROW(format_error("time_t value out of range"));
|
||||
return lt.tm_;
|
||||
}
|
||||
|
||||
#if FMT_USE_LOCAL_TIME
|
||||
template <typename Duration>
|
||||
FMT_DEPRECATED auto localtime(std::chrono::local_time<Duration> time)
|
||||
-> std::tm {
|
||||
using namespace std::chrono;
|
||||
using namespace detail::tz;
|
||||
return localtime(detail::to_time_t(current_zone()->to_sys<Duration>(time)));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Converts given time since epoch as `std::time_t` value into calendar time,
|
||||
* expressed in Coordinated Universal Time (UTC). Unlike `std::gmtime`, this
|
||||
@@ -652,7 +563,7 @@ inline void write_digit2_separated(char* buf, unsigned a, unsigned b,
|
||||
// Add ASCII '0' to each digit byte and insert separators.
|
||||
digits |= 0x3030003030003030 | (usep << 16) | (usep << 40);
|
||||
|
||||
constexpr const size_t len = 8;
|
||||
constexpr size_t len = 8;
|
||||
if (const_check(is_big_endian())) {
|
||||
char tmp[len];
|
||||
std::memcpy(tmp, &digits, len);
|
||||
@@ -1000,16 +911,16 @@ template <typename T>
|
||||
struct has_tm_zone<T, void_t<decltype(T::tm_zone)>> : std::true_type {};
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(has_tm_zone<T>::value)>
|
||||
bool set_tm_zone(T& time, char* tz) {
|
||||
auto set_tm_zone(T& time, char* tz) -> bool {
|
||||
time.tm_zone = tz;
|
||||
return true;
|
||||
}
|
||||
template <typename T, FMT_ENABLE_IF(!has_tm_zone<T>::value)>
|
||||
bool set_tm_zone(T&, char*) {
|
||||
auto set_tm_zone(T&, char*) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline char* utc() {
|
||||
inline auto utc() -> char* {
|
||||
static char tz[] = "UTC";
|
||||
return tz;
|
||||
}
|
||||
@@ -2230,7 +2141,7 @@ template <typename Char> struct formatter<std::tm, Char> {
|
||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
|
||||
ctx);
|
||||
|
||||
auto loc_ref = specs.localized() ? ctx.locale() : detail::locale_ref();
|
||||
auto loc_ref = specs.localized() ? ctx.locale() : locale_ref();
|
||||
detail::get_locale loc(static_cast<bool>(loc_ref), loc_ref);
|
||||
auto w = detail::tm_writer<basic_appender<Char>, Char, Duration>(
|
||||
loc, out, tm, subsecs);
|
||||
|
||||
36
3rdparty/fmt/include/fmt/color.h
vendored
36
3rdparty/fmt/include/fmt/color.h
vendored
@@ -375,19 +375,17 @@ template <typename Char> struct ansi_color_escape {
|
||||
// 10 more.
|
||||
if (is_background) value += 10u;
|
||||
|
||||
size_t index = 0;
|
||||
buffer[index++] = static_cast<Char>('\x1b');
|
||||
buffer[index++] = static_cast<Char>('[');
|
||||
buffer[size++] = static_cast<Char>('\x1b');
|
||||
buffer[size++] = static_cast<Char>('[');
|
||||
|
||||
if (value >= 100u) {
|
||||
buffer[index++] = static_cast<Char>('1');
|
||||
buffer[size++] = static_cast<Char>('1');
|
||||
value %= 100u;
|
||||
}
|
||||
buffer[index++] = static_cast<Char>('0' + value / 10u);
|
||||
buffer[index++] = static_cast<Char>('0' + value % 10u);
|
||||
buffer[size++] = static_cast<Char>('0' + value / 10u);
|
||||
buffer[size++] = static_cast<Char>('0' + value % 10u);
|
||||
|
||||
buffer[index++] = static_cast<Char>('m');
|
||||
buffer[index++] = static_cast<Char>('\0');
|
||||
buffer[size++] = static_cast<Char>('m');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -398,7 +396,7 @@ template <typename Char> struct ansi_color_escape {
|
||||
to_esc(color.r, buffer + 7, ';');
|
||||
to_esc(color.g, buffer + 11, ';');
|
||||
to_esc(color.b, buffer + 15, 'm');
|
||||
buffer[19] = static_cast<Char>(0);
|
||||
size = 19;
|
||||
}
|
||||
FMT_CONSTEXPR ansi_color_escape(emphasis em) noexcept {
|
||||
uint8_t em_codes[num_emphases] = {};
|
||||
@@ -411,26 +409,28 @@ template <typename Char> struct ansi_color_escape {
|
||||
if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8;
|
||||
if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9;
|
||||
|
||||
size_t index = 0;
|
||||
buffer[size++] = static_cast<Char>('\x1b');
|
||||
buffer[size++] = static_cast<Char>('[');
|
||||
|
||||
for (size_t i = 0; i < num_emphases; ++i) {
|
||||
if (!em_codes[i]) continue;
|
||||
buffer[index++] = static_cast<Char>('\x1b');
|
||||
buffer[index++] = static_cast<Char>('[');
|
||||
buffer[index++] = static_cast<Char>('0' + em_codes[i]);
|
||||
buffer[index++] = static_cast<Char>('m');
|
||||
buffer[size++] = static_cast<Char>('0' + em_codes[i]);
|
||||
buffer[size++] = static_cast<Char>(';');
|
||||
}
|
||||
buffer[index++] = static_cast<Char>(0);
|
||||
|
||||
buffer[size - 1] = static_cast<Char>('m');
|
||||
}
|
||||
FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; }
|
||||
|
||||
FMT_CONSTEXPR auto begin() const noexcept -> const Char* { return buffer; }
|
||||
FMT_CONSTEXPR20 auto end() const noexcept -> const Char* {
|
||||
return buffer + basic_string_view<Char>(buffer).size();
|
||||
FMT_CONSTEXPR auto end() const noexcept -> const Char* {
|
||||
return buffer + size;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr size_t num_emphases = 8;
|
||||
Char buffer[7u + 3u * num_emphases + 1u];
|
||||
Char buffer[7u + 4u * num_emphases];
|
||||
size_t size = 0;
|
||||
|
||||
static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
|
||||
char delimiter) noexcept {
|
||||
|
||||
198
3rdparty/fmt/include/fmt/compile.h
vendored
198
3rdparty/fmt/include/fmt/compile.h
vendored
@@ -22,8 +22,6 @@ FMT_EXPORT class compiled_string {};
|
||||
template <typename S>
|
||||
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* Converts a string literal `s` into a format string that will be parsed at
|
||||
* compile time and converted into efficient formatting code. Requires C++17
|
||||
@@ -41,18 +39,40 @@ namespace detail {
|
||||
# define FMT_COMPILE(s) FMT_STRING(s)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Converts a string literal into a format string that will be parsed at
|
||||
* compile time and converted into efficient formatting code. Requires support
|
||||
* for class types in constant template parameters (a C++20 feature).
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* // Converts 42 into std::string using the most efficient method and no
|
||||
* // runtime format string processing.
|
||||
* using namespace fmt::literals;
|
||||
* std::string s = fmt::format("{}"_cf, 42);
|
||||
*/
|
||||
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||
inline namespace literals {
|
||||
template <detail::fixed_string Str> constexpr auto operator""_cf() {
|
||||
return FMT_COMPILE(Str.data);
|
||||
}
|
||||
} // namespace literals
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T, typename... Tail>
|
||||
auto first(const T& value, const Tail&...) -> const T& {
|
||||
constexpr auto first(const T& value, const Tail&...) -> const T& {
|
||||
return value;
|
||||
}
|
||||
|
||||
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
|
||||
template <typename... Args> struct type_list {};
|
||||
template <typename... T> struct type_list {};
|
||||
|
||||
// Returns a reference to the argument at index N from [first, rest...].
|
||||
template <int N, typename T, typename... Args>
|
||||
constexpr const auto& get([[maybe_unused]] const T& first,
|
||||
[[maybe_unused]] const Args&... rest) {
|
||||
constexpr auto get([[maybe_unused]] const T& first,
|
||||
[[maybe_unused]] const Args&... rest) -> const auto& {
|
||||
static_assert(N < 1 + sizeof...(Args), "index is out of bounds");
|
||||
if constexpr (N == 0)
|
||||
return first;
|
||||
@@ -84,8 +104,8 @@ FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
|
||||
}
|
||||
|
||||
template <typename Char, typename... Args>
|
||||
constexpr int get_arg_index_by_name(basic_string_view<Char> name,
|
||||
type_list<Args...>) {
|
||||
constexpr auto get_arg_index_by_name(basic_string_view<Char> name,
|
||||
type_list<Args...>) -> int {
|
||||
return get_arg_index_by_name<Args...>(name);
|
||||
}
|
||||
|
||||
@@ -105,8 +125,8 @@ template <typename Char> struct text {
|
||||
basic_string_view<Char> data;
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr OutputIt format(OutputIt out, const Args&...) const {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr auto format(OutputIt out, const T&...) const -> OutputIt {
|
||||
return write<Char>(out, data);
|
||||
}
|
||||
};
|
||||
@@ -115,8 +135,8 @@ template <typename Char>
|
||||
struct is_compiled_format<text<Char>> : std::true_type {};
|
||||
|
||||
template <typename Char>
|
||||
constexpr text<Char> make_text(basic_string_view<Char> s, size_t pos,
|
||||
size_t size) {
|
||||
constexpr auto make_text(basic_string_view<Char> s, size_t pos, size_t size)
|
||||
-> text<Char> {
|
||||
return {{&s[pos], size}};
|
||||
}
|
||||
|
||||
@@ -124,8 +144,8 @@ template <typename Char> struct code_unit {
|
||||
Char value;
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr OutputIt format(OutputIt out, const Args&...) const {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr auto format(OutputIt out, const T&...) const -> OutputIt {
|
||||
*out++ = value;
|
||||
return out;
|
||||
}
|
||||
@@ -133,7 +153,7 @@ template <typename Char> struct code_unit {
|
||||
|
||||
// This ensures that the argument type is convertible to `const T&`.
|
||||
template <typename T, int N, typename... Args>
|
||||
constexpr const T& get_arg_checked(const Args&... args) {
|
||||
constexpr auto get_arg_checked(const Args&... args) -> const T& {
|
||||
const auto& arg = detail::get<N>(args...);
|
||||
if constexpr (detail::is_named_arg<remove_cvref_t<decltype(arg)>>()) {
|
||||
return arg.value;
|
||||
@@ -146,13 +166,13 @@ template <typename Char>
|
||||
struct is_compiled_format<code_unit<Char>> : std::true_type {};
|
||||
|
||||
// A replacement field that refers to argument N.
|
||||
template <typename Char, typename T, int N> struct field {
|
||||
template <typename Char, typename V, int N> struct field {
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr OutputIt format(OutputIt out, const Args&... args) const {
|
||||
const T& arg = get_arg_checked<T, N>(args...);
|
||||
if constexpr (std::is_convertible<T, basic_string_view<Char>>::value) {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {
|
||||
const V& arg = get_arg_checked<V, N>(args...);
|
||||
if constexpr (std::is_convertible<V, basic_string_view<Char>>::value) {
|
||||
auto s = basic_string_view<Char>(arg);
|
||||
return copy<Char>(s.begin(), s.end(), out);
|
||||
} else {
|
||||
@@ -170,10 +190,10 @@ template <typename Char> struct runtime_named_field {
|
||||
basic_string_view<Char> name;
|
||||
|
||||
template <typename OutputIt, typename T>
|
||||
constexpr static bool try_format_argument(
|
||||
constexpr static auto try_format_argument(
|
||||
OutputIt& out,
|
||||
// [[maybe_unused]] due to unused-but-set-parameter warning in GCC 7,8,9
|
||||
[[maybe_unused]] basic_string_view<Char> arg_name, const T& arg) {
|
||||
[[maybe_unused]] basic_string_view<Char> arg_name, const T& arg) -> bool {
|
||||
if constexpr (is_named_arg<typename std::remove_cv<T>::type>::value) {
|
||||
if (arg_name == arg.name) {
|
||||
out = write<Char>(out, arg.value);
|
||||
@@ -183,8 +203,8 @@ template <typename Char> struct runtime_named_field {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr OutputIt format(OutputIt out, const Args&... args) const {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {
|
||||
bool found = (try_format_argument(out, name, args) || ...);
|
||||
if (!found) {
|
||||
FMT_THROW(format_error("argument with specified name is not found"));
|
||||
@@ -197,17 +217,17 @@ template <typename Char>
|
||||
struct is_compiled_format<runtime_named_field<Char>> : std::true_type {};
|
||||
|
||||
// A replacement field that refers to argument N and has format specifiers.
|
||||
template <typename Char, typename T, int N> struct spec_field {
|
||||
template <typename Char, typename V, int N> struct spec_field {
|
||||
using char_type = Char;
|
||||
formatter<T, Char> fmt;
|
||||
formatter<V, Char> fmt;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr FMT_INLINE OutputIt format(OutputIt out,
|
||||
const Args&... args) const {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr FMT_INLINE auto format(OutputIt out, const T&... args) const
|
||||
-> OutputIt {
|
||||
const auto& vargs =
|
||||
fmt::make_format_args<basic_format_context<OutputIt, Char>>(args...);
|
||||
basic_format_context<OutputIt, Char> ctx(out, vargs);
|
||||
return fmt.format(get_arg_checked<T, N>(args...), ctx);
|
||||
return fmt.format(get_arg_checked<V, N>(args...), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -219,8 +239,8 @@ template <typename L, typename R> struct concat {
|
||||
R rhs;
|
||||
using char_type = typename L::char_type;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr OutputIt format(OutputIt out, const Args&... args) const {
|
||||
template <typename OutputIt, typename... T>
|
||||
constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {
|
||||
out = lhs.format(out, args...);
|
||||
return rhs.format(out, args...);
|
||||
}
|
||||
@@ -230,14 +250,14 @@ template <typename L, typename R>
|
||||
struct is_compiled_format<concat<L, R>> : std::true_type {};
|
||||
|
||||
template <typename L, typename R>
|
||||
constexpr concat<L, R> make_concat(L lhs, R rhs) {
|
||||
constexpr auto make_concat(L lhs, R rhs) -> concat<L, R> {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
struct unknown_format {};
|
||||
|
||||
template <typename Char>
|
||||
constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) {
|
||||
constexpr auto parse_text(basic_string_view<Char> str, size_t pos) -> size_t {
|
||||
for (size_t size = str.size(); pos != size; ++pos) {
|
||||
if (str[pos] == '{' || str[pos] == '}') break;
|
||||
}
|
||||
@@ -270,8 +290,8 @@ template <typename T, typename Char> struct parse_specs_result {
|
||||
enum { manual_indexing_id = -1 };
|
||||
|
||||
template <typename T, typename Char>
|
||||
constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
|
||||
size_t pos, int next_arg_id) {
|
||||
constexpr auto parse_specs(basic_string_view<Char> str, size_t pos,
|
||||
int next_arg_id) -> parse_specs_result<T, Char> {
|
||||
str.remove_prefix(pos);
|
||||
auto ctx =
|
||||
compile_parse_context<Char>(str, max_value<int>(), nullptr, next_arg_id);
|
||||
@@ -285,16 +305,16 @@ template <typename Char> struct arg_id_handler {
|
||||
arg_id_kind kind;
|
||||
arg_ref<Char> arg_id;
|
||||
|
||||
constexpr int on_auto() {
|
||||
constexpr auto on_auto() -> int {
|
||||
FMT_ASSERT(false, "handler cannot be used with automatic indexing");
|
||||
return 0;
|
||||
}
|
||||
constexpr int on_index(int id) {
|
||||
constexpr auto on_index(int id) -> int {
|
||||
kind = arg_id_kind::index;
|
||||
arg_id = arg_ref<Char>(id);
|
||||
return 0;
|
||||
}
|
||||
constexpr int on_name(basic_string_view<Char> id) {
|
||||
constexpr auto on_name(basic_string_view<Char> id) -> int {
|
||||
kind = arg_id_kind::name;
|
||||
arg_id = arg_ref<Char>(id);
|
||||
return 0;
|
||||
@@ -433,27 +453,28 @@ FMT_BEGIN_EXPORT
|
||||
|
||||
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
|
||||
|
||||
template <typename CompiledFormat, typename... Args,
|
||||
template <typename CompiledFormat, typename... T,
|
||||
typename Char = typename CompiledFormat::char_type,
|
||||
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
|
||||
FMT_INLINE std::basic_string<Char> format(const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
FMT_INLINE FMT_CONSTEXPR_STRING auto format(const CompiledFormat& cf,
|
||||
const T&... args)
|
||||
-> std::basic_string<Char> {
|
||||
auto s = std::basic_string<Char>();
|
||||
cf.format(std::back_inserter(s), args...);
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename CompiledFormat, typename... Args,
|
||||
template <typename OutputIt, typename CompiledFormat, typename... T,
|
||||
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
|
||||
constexpr FMT_INLINE OutputIt format_to(OutputIt out, const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
constexpr FMT_INLINE auto format_to(OutputIt out, const CompiledFormat& cf,
|
||||
const T&... args) -> OutputIt {
|
||||
return cf.format(out, args...);
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
template <typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
|
||||
Args&&... args) {
|
||||
FMT_INLINE FMT_CONSTEXPR_STRING auto format(const S&, T&&... args)
|
||||
-> std::basic_string<typename S::char_type> {
|
||||
if constexpr (std::is_same<typename S::char_type, char>::value) {
|
||||
constexpr auto str = basic_string_view<typename S::char_type>(S());
|
||||
if constexpr (str.size() == 2 && str[0] == '{' && str[1] == '}') {
|
||||
@@ -466,72 +487,97 @@ FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
|
||||
}
|
||||
}
|
||||
}
|
||||
constexpr auto compiled = detail::compile<Args...>(S());
|
||||
constexpr auto compiled = detail::compile<T...>(S());
|
||||
if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
|
||||
detail::unknown_format>()) {
|
||||
return fmt::format(
|
||||
static_cast<basic_string_view<typename S::char_type>>(S()),
|
||||
std::forward<Args>(args)...);
|
||||
std::forward<T>(args)...);
|
||||
} else {
|
||||
return fmt::format(compiled, std::forward<Args>(args)...);
|
||||
return fmt::format(compiled, std::forward<T>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
template <typename OutputIt, typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) {
|
||||
constexpr auto compiled = detail::compile<Args...>(S());
|
||||
FMT_CONSTEXPR auto format_to(OutputIt out, const S&, T&&... args) -> OutputIt {
|
||||
constexpr auto compiled = detail::compile<T...>(S());
|
||||
if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
|
||||
detail::unknown_format>()) {
|
||||
return fmt::format_to(
|
||||
out, static_cast<basic_string_view<typename S::char_type>>(S()),
|
||||
std::forward<Args>(args)...);
|
||||
std::forward<T>(args)...);
|
||||
} else {
|
||||
return fmt::format_to(out, compiled, std::forward<Args>(args)...);
|
||||
return fmt::format_to(out, compiled, std::forward<T>(args)...);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
template <typename OutputIt, typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
auto format_to_n(OutputIt out, size_t n, const S& fmt, Args&&... args)
|
||||
auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args)
|
||||
-> format_to_n_result<OutputIt> {
|
||||
using traits = detail::fixed_buffer_traits;
|
||||
auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
|
||||
fmt::format_to(std::back_inserter(buf), fmt, std::forward<Args>(args)...);
|
||||
fmt::format_to(std::back_inserter(buf), fmt, std::forward<T>(args)...);
|
||||
return {buf.out(), buf.count()};
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
template <typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
FMT_CONSTEXPR20 auto formatted_size(const S& fmt, const Args&... args)
|
||||
-> size_t {
|
||||
FMT_CONSTEXPR20 auto formatted_size(const S& fmt, T&&... args) -> size_t {
|
||||
auto buf = detail::counting_buffer<>();
|
||||
fmt::format_to(appender(buf), fmt, args...);
|
||||
fmt::format_to(appender(buf), fmt, std::forward<T>(args)...);
|
||||
return buf.count();
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
template <typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
void print(std::FILE* f, const S& fmt, const Args&... args) {
|
||||
void print(std::FILE* f, const S& fmt, T&&... args) {
|
||||
auto buf = memory_buffer();
|
||||
fmt::format_to(appender(buf), fmt, args...);
|
||||
fmt::format_to(appender(buf), fmt, std::forward<T>(args)...);
|
||||
detail::print(f, {buf.data(), buf.size()});
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
template <typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
void print(const S& fmt, const Args&... args) {
|
||||
print(stdout, fmt, args...);
|
||||
void print(const S& fmt, T&&... args) {
|
||||
print(stdout, fmt, std::forward<T>(args)...);
|
||||
}
|
||||
|
||||
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||
inline namespace literals {
|
||||
template <detail::fixed_string Str> constexpr auto operator""_cf() {
|
||||
return FMT_COMPILE(Str.data);
|
||||
}
|
||||
} // namespace literals
|
||||
#endif
|
||||
template <size_t N> class static_format_result {
|
||||
private:
|
||||
char data[N];
|
||||
|
||||
public:
|
||||
template <typename S, typename... T,
|
||||
FMT_ENABLE_IF(is_compiled_string<S>::value)>
|
||||
explicit FMT_CONSTEXPR static_format_result(const S& fmt, T&&... args) {
|
||||
*fmt::format_to(data, fmt, std::forward<T>(args)...) = '\0';
|
||||
}
|
||||
|
||||
auto str() const -> fmt::string_view { return {data, N - 1}; }
|
||||
auto c_str() const -> const char* { return data; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats arguments according to the format string `fmt_str` and produces
|
||||
* a string of the exact required size at compile time. Both the format string
|
||||
* and the arguments must be compile-time expressions.
|
||||
*
|
||||
* The resulting string can be accessed as a C string via `c_str()` or as
|
||||
* a `fmt::string_view` via `str()`.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* // Produces the static string "42" at compile time.
|
||||
* static constexpr auto result = FMT_STATIC_FORMAT("{}", 42);
|
||||
* const char* s = result.c_str();
|
||||
*/
|
||||
#define FMT_STATIC_FORMAT(fmt_str, ...) \
|
||||
fmt::static_format_result< \
|
||||
fmt::formatted_size(FMT_COMPILE(fmt_str), __VA_ARGS__) + 1>( \
|
||||
FMT_COMPILE(fmt_str), __VA_ARGS__)
|
||||
|
||||
FMT_END_EXPORT
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
125
3rdparty/fmt/include/fmt/format-inl.h
vendored
125
3rdparty/fmt/include/fmt/format-inl.h
vendored
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "format.h"
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
#if FMT_USE_LOCALE && !defined(FMT_MODULE)
|
||||
# include <locale>
|
||||
#endif
|
||||
|
||||
@@ -31,14 +31,49 @@
|
||||
#endif
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
#ifndef FMT_CUSTOM_ASSERT_FAIL
|
||||
FMT_FUNC void assert_fail(const char* file, int line, const char* message) {
|
||||
// Use unchecked std::fprintf to avoid triggering another assertion when
|
||||
// writing to stderr fails.
|
||||
fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
namespace detail {
|
||||
using std::locale;
|
||||
using std::numpunct;
|
||||
using std::use_facet;
|
||||
} // namespace detail
|
||||
|
||||
template <typename Locale, enable_if_t<(sizeof(Locale::collate) != 0), int>>
|
||||
locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
|
||||
static_assert(std::is_same<Locale, std::locale>::value, "");
|
||||
}
|
||||
#else
|
||||
namespace detail {
|
||||
struct locale {};
|
||||
template <typename Char> struct numpunct {
|
||||
auto grouping() const -> std::string { return "\03"; }
|
||||
auto thousands_sep() const -> Char { return ','; }
|
||||
auto decimal_point() const -> Char { return '.'; }
|
||||
};
|
||||
template <typename Facet> Facet use_facet(locale) { return {}; }
|
||||
} // namespace detail
|
||||
#endif // FMT_USE_LOCALE
|
||||
|
||||
template <typename Locale> auto locale_ref::get() const -> Locale {
|
||||
using namespace detail;
|
||||
static_assert(std::is_same<Locale, locale>::value, "");
|
||||
#if FMT_USE_LOCALE
|
||||
if (locale_) return *static_cast<const locale*>(locale_);
|
||||
#endif
|
||||
return locale();
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
|
||||
string_view message) noexcept {
|
||||
@@ -79,33 +114,6 @@ inline void fwrite_all(const void* ptr, size_t count, FILE* stream) {
|
||||
FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
|
||||
}
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
using std::locale;
|
||||
using std::numpunct;
|
||||
using std::use_facet;
|
||||
|
||||
template <typename Locale>
|
||||
locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
|
||||
static_assert(std::is_same<Locale, locale>::value, "");
|
||||
}
|
||||
#else
|
||||
struct locale {};
|
||||
template <typename Char> struct numpunct {
|
||||
auto grouping() const -> std::string { return "\03"; }
|
||||
auto thousands_sep() const -> Char { return ','; }
|
||||
auto decimal_point() const -> Char { return '.'; }
|
||||
};
|
||||
template <typename Facet> Facet use_facet(locale) { return {}; }
|
||||
#endif // FMT_USE_LOCALE
|
||||
|
||||
template <typename Locale> auto locale_ref::get() const -> Locale {
|
||||
static_assert(std::is_same<Locale, locale>::value, "");
|
||||
#if FMT_USE_LOCALE
|
||||
if (locale_) return *static_cast<const locale*>(locale_);
|
||||
#endif
|
||||
return locale();
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char> {
|
||||
auto&& facet = use_facet<numpunct<Char>>(loc.get<locale>());
|
||||
@@ -133,14 +141,13 @@ FMT_FUNC auto write_loc(appender out, loc_value value,
|
||||
} // namespace detail
|
||||
|
||||
FMT_FUNC void report_error(const char* message) {
|
||||
#if FMT_USE_EXCEPTIONS
|
||||
// Use FMT_THROW instead of throw to avoid bogus unreachable code warnings
|
||||
// from MSVC.
|
||||
FMT_THROW(format_error(message));
|
||||
#else
|
||||
fputs(message, stderr);
|
||||
abort();
|
||||
#if FMT_MSC_VERSION || defined(__NVCC__)
|
||||
// Silence unreachable code warnings in MSVC and NVCC because these
|
||||
// are nearly impossible to fix in a generic code.
|
||||
volatile bool b = true;
|
||||
if (!b) return;
|
||||
#endif
|
||||
FMT_THROW(format_error(message));
|
||||
}
|
||||
|
||||
template <typename Locale> typename Locale::id format_facet<Locale>::id;
|
||||
@@ -174,11 +181,11 @@ inline auto operator==(basic_fp<F> x, basic_fp<F> y) -> bool {
|
||||
}
|
||||
|
||||
// Compilers should be able to optimize this into the ror instruction.
|
||||
FMT_CONSTEXPR inline auto rotr(uint32_t n, uint32_t r) noexcept -> uint32_t {
|
||||
FMT_INLINE auto rotr(uint32_t n, uint32_t r) noexcept -> uint32_t {
|
||||
r &= 31;
|
||||
return (n >> r) | (n << (32 - r));
|
||||
}
|
||||
FMT_CONSTEXPR inline auto rotr(uint64_t n, uint32_t r) noexcept -> uint64_t {
|
||||
FMT_INLINE auto rotr(uint64_t n, uint32_t r) noexcept -> uint64_t {
|
||||
r &= 63;
|
||||
return (n >> r) | (n << (64 - r));
|
||||
}
|
||||
@@ -275,7 +282,7 @@ template <> struct cache_accessor<float> {
|
||||
static auto get_cached_power(int k) noexcept -> uint64_t {
|
||||
FMT_ASSERT(k >= float_info<float>::min_k && k <= float_info<float>::max_k,
|
||||
"k is out of range");
|
||||
static constexpr const uint64_t pow10_significands[] = {
|
||||
static constexpr uint64_t pow10_significands[] = {
|
||||
0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f,
|
||||
0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb,
|
||||
0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28,
|
||||
@@ -370,7 +377,7 @@ template <> struct cache_accessor<double> {
|
||||
FMT_ASSERT(k >= float_info<double>::min_k && k <= float_info<double>::max_k,
|
||||
"k is out of range");
|
||||
|
||||
static constexpr const uint128_fallback pow10_significands[] = {
|
||||
static constexpr uint128_fallback pow10_significands[] = {
|
||||
#if FMT_USE_FULL_CACHE_DRAGONBOX
|
||||
{0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b},
|
||||
{0x9faacf3df73609b1, 0x77b191618c54e9ad},
|
||||
@@ -1037,7 +1044,7 @@ template <> struct cache_accessor<double> {
|
||||
#if FMT_USE_FULL_CACHE_DRAGONBOX
|
||||
return pow10_significands[k - float_info<double>::min_k];
|
||||
#else
|
||||
static constexpr const uint64_t powers_of_5_64[] = {
|
||||
static constexpr uint64_t powers_of_5_64[] = {
|
||||
0x0000000000000001, 0x0000000000000005, 0x0000000000000019,
|
||||
0x000000000000007d, 0x0000000000000271, 0x0000000000000c35,
|
||||
0x0000000000003d09, 0x000000000001312d, 0x000000000005f5e1,
|
||||
@@ -1149,8 +1156,8 @@ auto is_left_endpoint_integer_shorter_interval(int exponent) noexcept -> bool {
|
||||
exponent <= case_shorter_interval_left_endpoint_upper_threshold;
|
||||
}
|
||||
|
||||
// Remove trailing zeros from n and return the number of zeros removed (float)
|
||||
FMT_INLINE int remove_trailing_zeros(uint32_t& n, int s = 0) noexcept {
|
||||
// Remove trailing zeros from n and return the number of zeros removed (float).
|
||||
FMT_INLINE auto remove_trailing_zeros(uint32_t& n, int s = 0) noexcept -> int {
|
||||
FMT_ASSERT(n != 0, "");
|
||||
// Modular inverse of 5 (mod 2^32): (mod_inv_5 * 5) mod 2^32 = 1.
|
||||
constexpr uint32_t mod_inv_5 = 0xcccccccd;
|
||||
@@ -1170,22 +1177,19 @@ FMT_INLINE int remove_trailing_zeros(uint32_t& n, int s = 0) noexcept {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Removes trailing zeros and returns the number of zeros removed (double)
|
||||
FMT_INLINE int remove_trailing_zeros(uint64_t& n) noexcept {
|
||||
// Removes trailing zeros and returns the number of zeros removed (double).
|
||||
FMT_INLINE auto remove_trailing_zeros(uint64_t& n) noexcept -> int {
|
||||
FMT_ASSERT(n != 0, "");
|
||||
|
||||
// This magic number is ceil(2^90 / 10^8).
|
||||
constexpr uint64_t magic_number = 12379400392853802749ull;
|
||||
auto nm = umul128(n, magic_number);
|
||||
|
||||
// Is n is divisible by 10^8?
|
||||
if ((nm.high() & ((1ull << (90 - 64)) - 1)) == 0 && nm.low() < magic_number) {
|
||||
constexpr uint32_t ten_pow_8 = 100000000u;
|
||||
if ((n % ten_pow_8) == 0) {
|
||||
// If yes, work with the quotient...
|
||||
auto n32 = static_cast<uint32_t>(nm.high() >> (90 - 64));
|
||||
auto n32 = static_cast<uint32_t>(n / ten_pow_8);
|
||||
// ... and use the 32 bit variant of the function
|
||||
int s = remove_trailing_zeros(n32, 8);
|
||||
int num_zeros = remove_trailing_zeros(n32, 8);
|
||||
n = n32;
|
||||
return s;
|
||||
return num_zeros;
|
||||
}
|
||||
|
||||
// If n is not divisible by 10^8, work with n itself.
|
||||
@@ -1210,7 +1214,7 @@ FMT_INLINE int remove_trailing_zeros(uint64_t& n) noexcept {
|
||||
|
||||
// The main algorithm for shorter interval case
|
||||
template <typename T>
|
||||
FMT_INLINE decimal_fp<T> shorter_interval_case(int exponent) noexcept {
|
||||
FMT_INLINE auto shorter_interval_case(int exponent) noexcept -> decimal_fp<T> {
|
||||
decimal_fp<T> ret_value;
|
||||
// Compute k and beta
|
||||
const int minus_k = floor_log10_pow2_minus_log10_4_over_3(exponent);
|
||||
@@ -1454,8 +1458,8 @@ FMT_FUNC void vformat_to(buffer<char>& buf, string_view fmt, format_args args,
|
||||
auto out = appender(buf);
|
||||
if (fmt.size() == 2 && equal2(fmt.data(), "{}"))
|
||||
return args.get(0).visit(default_arg_formatter<char>{out});
|
||||
parse_format_string(
|
||||
fmt, format_handler<char>{parse_context<char>(fmt), {out, args, loc}});
|
||||
parse_format_string(fmt,
|
||||
format_handler<>{parse_context<>(fmt), {out, args, loc}});
|
||||
}
|
||||
|
||||
template <typename T> struct span {
|
||||
@@ -1546,10 +1550,11 @@ template <typename F> class glibc_file : public file_base<F> {
|
||||
|
||||
void advance_write_buffer(size_t size) { this->file_->_IO_write_ptr += size; }
|
||||
|
||||
bool needs_flush() const {
|
||||
auto needs_flush() const -> bool {
|
||||
if ((this->file_->_flags & line_buffered) == 0) return false;
|
||||
char* end = this->file_->_IO_write_end;
|
||||
return memchr(end, '\n', to_unsigned(this->file_->_IO_write_ptr - end));
|
||||
auto size = max_of<ptrdiff_t>(this->file_->_IO_write_ptr - end, 0);
|
||||
return memchr(end, '\n', static_cast<size_t>(size));
|
||||
}
|
||||
|
||||
void flush() { fflush_unlocked(this->file_); }
|
||||
@@ -1573,7 +1578,7 @@ template <typename F> class apple_file : public file_base<F> {
|
||||
void init_buffer() {
|
||||
if (this->file_->_p) return;
|
||||
// Force buffer initialization by placing and removing a char in a buffer.
|
||||
putc_unlocked(0, this->file_);
|
||||
if (!FMT_CLANG_ANALYZER) putc_unlocked(0, this->file_);
|
||||
--this->file_->_p;
|
||||
++this->file_->_w;
|
||||
}
|
||||
@@ -1594,7 +1599,7 @@ template <typename F> class apple_file : public file_base<F> {
|
||||
this->file_->_w -= size;
|
||||
}
|
||||
|
||||
bool needs_flush() const {
|
||||
auto needs_flush() const -> bool {
|
||||
if ((this->file_->_flags & line_buffered) == 0) return false;
|
||||
return memchr(this->file_->_p + this->file_->_w, '\n',
|
||||
to_unsigned(-this->file_->_w));
|
||||
|
||||
819
3rdparty/fmt/include/fmt/format.h
vendored
819
3rdparty/fmt/include/fmt/format.h
vendored
File diff suppressed because it is too large
Load Diff
3
3rdparty/fmt/include/fmt/os.h
vendored
3
3rdparty/fmt/include/fmt/os.h
vendored
@@ -29,7 +29,8 @@
|
||||
# if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \
|
||||
defined(__linux__)) && \
|
||||
(!defined(WINAPI_FAMILY) || \
|
||||
(WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
|
||||
(WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)) && \
|
||||
!defined(__wasm__)
|
||||
# include <fcntl.h> // for O_RDONLY
|
||||
# define FMT_USE_FCNTL 1
|
||||
# else
|
||||
|
||||
4
3rdparty/fmt/include/fmt/ostream.h
vendored
4
3rdparty/fmt/include/fmt/ostream.h
vendored
@@ -33,8 +33,8 @@
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
// Generate a unique explicit instantion in every translation unit using a tag
|
||||
// type in an anonymous namespace.
|
||||
// Generate a unique explicit instantiation in every translation unit using a
|
||||
// tag type in an anonymous namespace.
|
||||
namespace {
|
||||
struct file_access_tag {};
|
||||
} // namespace
|
||||
|
||||
59
3rdparty/fmt/include/fmt/printf.h
vendored
59
3rdparty/fmt/include/fmt/printf.h
vendored
@@ -9,7 +9,7 @@
|
||||
#define FMT_PRINTF_H_
|
||||
|
||||
#ifndef FMT_MODULE
|
||||
# include <algorithm> // std::max
|
||||
# include <algorithm> // std::find
|
||||
# include <limits> // std::numeric_limits
|
||||
#endif
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
FMT_BEGIN_NAMESPACE
|
||||
FMT_BEGIN_EXPORT
|
||||
|
||||
template <typename T> struct printf_formatter {
|
||||
printf_formatter() = delete;
|
||||
};
|
||||
|
||||
template <typename Char> class basic_printf_context {
|
||||
private:
|
||||
basic_appender<Char> out_;
|
||||
@@ -33,8 +29,6 @@ template <typename Char> class basic_printf_context {
|
||||
|
||||
public:
|
||||
using char_type = Char;
|
||||
using parse_context_type = parse_context<Char>;
|
||||
template <typename T> using formatter_type = printf_formatter<T>;
|
||||
enum { builtin_types = 1 };
|
||||
|
||||
/// Constructs a `printf_context` object. References to the arguments are
|
||||
@@ -46,7 +40,7 @@ template <typename Char> class basic_printf_context {
|
||||
auto out() -> basic_appender<Char> { return out_; }
|
||||
void advance_to(basic_appender<Char>) {}
|
||||
|
||||
auto locale() -> detail::locale_ref { return {}; }
|
||||
auto locale() -> locale_ref { return {}; }
|
||||
|
||||
auto arg(int id) const -> basic_format_arg<basic_printf_context> {
|
||||
return args_.get(id);
|
||||
@@ -74,10 +68,9 @@ inline auto find<false, char>(const char* first, const char* last, char value,
|
||||
|
||||
// Checks if a value fits in int - used to avoid warnings about comparing
|
||||
// signed and unsigned integers.
|
||||
template <bool IsSigned> struct int_checker {
|
||||
template <bool IS_SIGNED> struct int_checker {
|
||||
template <typename T> static auto fits_in_int(T value) -> bool {
|
||||
unsigned max = to_unsigned(max_value<int>());
|
||||
return value <= max;
|
||||
return value <= to_unsigned(max_value<int>());
|
||||
}
|
||||
inline static auto fits_in_int(bool) -> bool { return true; }
|
||||
};
|
||||
@@ -95,7 +88,7 @@ struct printf_precision_handler {
|
||||
auto operator()(T value) -> int {
|
||||
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
|
||||
report_error("number is too big");
|
||||
return (std::max)(static_cast<int>(value), 0);
|
||||
return max_of(static_cast<int>(value), 0);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
@@ -410,7 +403,9 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
arg_index = parse_ctx.next_arg_id();
|
||||
else
|
||||
parse_ctx.check_arg_id(--arg_index);
|
||||
return detail::get_arg(context, arg_index);
|
||||
auto arg = context.arg(arg_index);
|
||||
if (!arg) report_error("argument not found");
|
||||
return arg;
|
||||
};
|
||||
|
||||
const Char* start = parse_ctx.begin();
|
||||
@@ -571,15 +566,19 @@ inline auto vsprintf(basic_string_view<Char> fmt,
|
||||
*
|
||||
* std::string message = fmt::sprintf("The answer is %d", 42);
|
||||
*/
|
||||
template <typename S, typename... T, typename Char = detail::char_t<S>>
|
||||
inline auto sprintf(const S& fmt, const T&... args) -> std::basic_string<Char> {
|
||||
return vsprintf(detail::to_string_view(fmt),
|
||||
fmt::make_format_args<basic_printf_context<Char>>(args...));
|
||||
template <typename... T>
|
||||
inline auto sprintf(string_view fmt, const T&... args) -> std::string {
|
||||
return vsprintf(fmt, make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED auto sprintf(basic_string_view<wchar_t> fmt, const T&... args)
|
||||
-> std::wstring {
|
||||
return vsprintf(fmt, make_printf_args<wchar_t>(args...));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline auto vfprintf(std::FILE* f, basic_string_view<Char> fmt,
|
||||
typename vprintf_args<Char>::type args) -> int {
|
||||
auto vfprintf(std::FILE* f, basic_string_view<Char> fmt,
|
||||
typename vprintf_args<Char>::type args) -> int {
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
detail::vprintf(buf, fmt, args);
|
||||
size_t size = buf.size();
|
||||
@@ -596,17 +595,14 @@ inline auto vfprintf(std::FILE* f, basic_string_view<Char> fmt,
|
||||
*
|
||||
* fmt::fprintf(stderr, "Don't %s!", "panic");
|
||||
*/
|
||||
template <typename S, typename... T, typename Char = detail::char_t<S>>
|
||||
inline auto fprintf(std::FILE* f, const S& fmt, const T&... args) -> int {
|
||||
return vfprintf(f, detail::to_string_view(fmt),
|
||||
make_printf_args<Char>(args...));
|
||||
template <typename... T>
|
||||
inline auto fprintf(std::FILE* f, string_view fmt, const T&... args) -> int {
|
||||
return vfprintf(f, fmt, make_printf_args(args...));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_DEPRECATED inline auto vprintf(basic_string_view<Char> fmt,
|
||||
typename vprintf_args<Char>::type args)
|
||||
-> int {
|
||||
return vfprintf(stdout, fmt, args);
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED auto fprintf(std::FILE* f, basic_string_view<wchar_t> fmt,
|
||||
const T&... args) -> int {
|
||||
return vfprintf(f, fmt, make_printf_args<wchar_t>(args...));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -621,11 +617,6 @@ template <typename... T>
|
||||
inline auto printf(string_view fmt, const T&... args) -> int {
|
||||
return vfprintf(stdout, fmt, make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED inline auto printf(basic_string_view<wchar_t> fmt,
|
||||
const T&... args) -> int {
|
||||
return vfprintf(stdout, fmt, make_printf_args<wchar_t>(args...));
|
||||
}
|
||||
|
||||
FMT_END_EXPORT
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
48
3rdparty/fmt/include/fmt/ranges.h
vendored
48
3rdparty/fmt/include/fmt/ranges.h
vendored
@@ -11,7 +11,6 @@
|
||||
#ifndef FMT_MODULE
|
||||
# include <initializer_list>
|
||||
# include <iterator>
|
||||
# include <string>
|
||||
# include <tuple>
|
||||
# include <type_traits>
|
||||
# include <utility>
|
||||
@@ -31,7 +30,7 @@ template <typename T> class is_map {
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
@@ -40,17 +39,16 @@ template <typename T> class is_set {
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value && !is_map<T>::value;
|
||||
};
|
||||
|
||||
// C array overload
|
||||
template <typename T, std::size_t N>
|
||||
template <typename T, size_t N>
|
||||
auto range_begin(const T (&arr)[N]) -> const T* {
|
||||
return arr;
|
||||
}
|
||||
template <typename T, std::size_t N>
|
||||
auto range_end(const T (&arr)[N]) -> const T* {
|
||||
template <typename T, size_t N> auto range_end(const T (&arr)[N]) -> const T* {
|
||||
return arr + N;
|
||||
}
|
||||
|
||||
@@ -120,7 +118,7 @@ template <typename T> class is_tuple_like_ {
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
@@ -154,7 +152,7 @@ using tuple_index_sequence = make_index_sequence<std::tuple_size<T>::value>;
|
||||
template <typename T, typename C, bool = is_tuple_like_<T>::value>
|
||||
class is_tuple_formattable_ {
|
||||
public:
|
||||
static constexpr const bool value = false;
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
template <typename T, typename C> class is_tuple_formattable_<T, C, true> {
|
||||
template <size_t... Is>
|
||||
@@ -170,7 +168,7 @@ template <typename T, typename C> class is_tuple_formattable_<T, C, true> {
|
||||
C>::value)...>{}));
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
decltype(check(tuple_index_sequence<T>{}))::value;
|
||||
};
|
||||
|
||||
@@ -208,7 +206,7 @@ template <typename Char, typename... T>
|
||||
using result_t = std::tuple<formatter<remove_cvref_t<T>, Char>...>;
|
||||
|
||||
using std::get;
|
||||
template <typename Tuple, typename Char, std::size_t... Is>
|
||||
template <typename Tuple, typename Char, size_t... Is>
|
||||
auto get_formatters(index_sequence<Is...>)
|
||||
-> result_t<Char, decltype(get<Is>(std::declval<Tuple>()))...>;
|
||||
} // namespace tuple
|
||||
@@ -219,7 +217,7 @@ template <typename R> struct range_reference_type_impl {
|
||||
using type = decltype(*detail::range_begin(std::declval<R&>()));
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N> struct range_reference_type_impl<T[N]> {
|
||||
template <typename T, size_t N> struct range_reference_type_impl<T[N]> {
|
||||
using type = T&;
|
||||
};
|
||||
|
||||
@@ -281,14 +279,15 @@ template <typename FormatContext> struct format_tuple_element {
|
||||
|
||||
} // namespace detail
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T> struct is_tuple_like {
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value;
|
||||
};
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename C> struct is_tuple_formattable {
|
||||
static constexpr const bool value =
|
||||
detail::is_tuple_formattable_<T, C>::value;
|
||||
static constexpr bool value = detail::is_tuple_formattable_<T, C>::value;
|
||||
};
|
||||
|
||||
template <typename Tuple, typename Char>
|
||||
@@ -343,8 +342,9 @@ struct formatter<Tuple, Char,
|
||||
}
|
||||
};
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename Char> struct is_range {
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
detail::is_range_<T>::value && !detail::has_to_string_view<T>::value;
|
||||
};
|
||||
|
||||
@@ -368,6 +368,7 @@ template <typename P1, typename... Pn>
|
||||
struct conjunction<P1, Pn...>
|
||||
: conditional_t<bool(P1::value), conjunction<Pn...>, P1> {};
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename Char, typename Enable = void>
|
||||
struct range_formatter;
|
||||
|
||||
@@ -670,7 +671,8 @@ struct formatter<join_view<It, Sentinel, Char>, Char> {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename Tuple> struct tuple_join_view : detail::view {
|
||||
FMT_EXPORT
|
||||
template <typename Tuple, typename Char> struct tuple_join_view : detail::view {
|
||||
const Tuple& tuple;
|
||||
basic_string_view<Char> sep;
|
||||
|
||||
@@ -685,15 +687,15 @@ template <typename Char, typename Tuple> struct tuple_join_view : detail::view {
|
||||
# define FMT_TUPLE_JOIN_SPECIFIERS 0
|
||||
#endif
|
||||
|
||||
template <typename Char, typename Tuple>
|
||||
struct formatter<tuple_join_view<Char, Tuple>, Char,
|
||||
template <typename Tuple, typename Char>
|
||||
struct formatter<tuple_join_view<Tuple, Char>, Char,
|
||||
enable_if_t<is_tuple_like<Tuple>::value>> {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return do_parse(ctx, std::tuple_size<Tuple>());
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const tuple_join_view<Char, Tuple>& value,
|
||||
auto format(const tuple_join_view<Tuple, Char>& value,
|
||||
FormatContext& ctx) const -> typename FormatContext::iterator {
|
||||
return do_format(value, ctx, std::tuple_size<Tuple>());
|
||||
}
|
||||
@@ -725,14 +727,14 @@ struct formatter<tuple_join_view<Char, Tuple>, Char,
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto do_format(const tuple_join_view<Char, Tuple>&, FormatContext& ctx,
|
||||
auto do_format(const tuple_join_view<Tuple, Char>&, FormatContext& ctx,
|
||||
std::integral_constant<size_t, 0>) const ->
|
||||
typename FormatContext::iterator {
|
||||
return ctx.out();
|
||||
}
|
||||
|
||||
template <typename FormatContext, size_t N>
|
||||
auto do_format(const tuple_join_view<Char, Tuple>& value, FormatContext& ctx,
|
||||
auto do_format(const tuple_join_view<Tuple, Char>& value, FormatContext& ctx,
|
||||
std::integral_constant<size_t, N>) const ->
|
||||
typename FormatContext::iterator {
|
||||
using std::get;
|
||||
@@ -754,7 +756,7 @@ template <typename T> class is_container_adaptor_like {
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
static constexpr bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
@@ -825,7 +827,7 @@ auto join(Range&& r, string_view sep)
|
||||
*/
|
||||
template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
|
||||
FMT_CONSTEXPR auto join(const Tuple& tuple, string_view sep)
|
||||
-> tuple_join_view<char, Tuple> {
|
||||
-> tuple_join_view<Tuple, char> {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
|
||||
425
3rdparty/fmt/include/fmt/std.h
vendored
425
3rdparty/fmt/include/fmt/std.h
vendored
@@ -15,15 +15,13 @@
|
||||
# include <atomic>
|
||||
# include <bitset>
|
||||
# include <complex>
|
||||
# include <cstdlib>
|
||||
# include <exception>
|
||||
# include <functional>
|
||||
# include <functional> // std::reference_wrapper
|
||||
# include <memory>
|
||||
# include <thread>
|
||||
# include <type_traits>
|
||||
# include <typeinfo>
|
||||
# include <utility>
|
||||
# include <vector>
|
||||
# include <typeinfo> // std::type_info
|
||||
# include <utility> // std::make_index_sequence
|
||||
|
||||
// Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC.
|
||||
# if FMT_CPLUSPLUS >= 201703L
|
||||
@@ -62,27 +60,26 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// For older Xcode versions, __cpp_lib_xxx flags are inaccurately defined.
|
||||
#ifndef FMT_CPP_LIB_FILESYSTEM
|
||||
# ifdef __cpp_lib_filesystem
|
||||
# define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem
|
||||
# else
|
||||
# define FMT_CPP_LIB_FILESYSTEM 0
|
||||
# endif
|
||||
#ifdef FMT_CPP_LIB_FILESYSTEM
|
||||
// Use the provided definition.
|
||||
#elif defined(__cpp_lib_filesystem)
|
||||
# define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem
|
||||
#else
|
||||
# define FMT_CPP_LIB_FILESYSTEM 0
|
||||
#endif
|
||||
|
||||
#ifndef FMT_CPP_LIB_VARIANT
|
||||
# ifdef __cpp_lib_variant
|
||||
# define FMT_CPP_LIB_VARIANT __cpp_lib_variant
|
||||
# else
|
||||
# define FMT_CPP_LIB_VARIANT 0
|
||||
# endif
|
||||
#ifdef FMT_CPP_LIB_VARIANT
|
||||
// Use the provided definition.
|
||||
#elif defined(__cpp_lib_variant)
|
||||
# define FMT_CPP_LIB_VARIANT __cpp_lib_variant
|
||||
#else
|
||||
# define FMT_CPP_LIB_VARIANT 0
|
||||
#endif
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
#if FMT_CPP_LIB_FILESYSTEM
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Char, typename PathChar>
|
||||
auto get_path_string(const std::filesystem::path& p,
|
||||
@@ -111,8 +108,168 @@ void write_escaped_path(basic_memory_buffer<Char>& quoted,
|
||||
}
|
||||
}
|
||||
|
||||
#endif // FMT_CPP_LIB_FILESYSTEM
|
||||
|
||||
#if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT
|
||||
template <typename Char, typename OutputIt, typename T>
|
||||
auto write_escaped_alternative(OutputIt out, const T& v) -> OutputIt {
|
||||
if constexpr (has_to_string_view<T>::value)
|
||||
return write_escaped_string<Char>(out, detail::to_string_view(v));
|
||||
if constexpr (std::is_same_v<T, Char>) return write_escaped_char(out, v);
|
||||
return write<Char>(out, v);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FMT_CPP_LIB_VARIANT
|
||||
|
||||
template <typename> struct is_variant_like_ : std::false_type {};
|
||||
template <typename... Types>
|
||||
struct is_variant_like_<std::variant<Types...>> : std::true_type {};
|
||||
|
||||
template <typename Variant, typename Char> class is_variant_formattable {
|
||||
template <size_t... Is>
|
||||
static auto check(std::index_sequence<Is...>) -> std::conjunction<
|
||||
is_formattable<std::variant_alternative_t<Is, Variant>, Char>...>;
|
||||
|
||||
public:
|
||||
static constexpr bool value = decltype(check(
|
||||
std::make_index_sequence<std::variant_size<Variant>::value>()))::value;
|
||||
};
|
||||
|
||||
#endif // FMT_CPP_LIB_VARIANT
|
||||
|
||||
#if FMT_USE_RTTI
|
||||
|
||||
template <typename OutputIt>
|
||||
auto write_demangled_name(OutputIt out, const std::type_info& ti) -> OutputIt {
|
||||
# ifdef FMT_HAS_ABI_CXA_DEMANGLE
|
||||
int status = 0;
|
||||
size_t size = 0;
|
||||
std::unique_ptr<char, void (*)(void*)> demangled_name_ptr(
|
||||
abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
|
||||
|
||||
string_view demangled_name_view;
|
||||
if (demangled_name_ptr) {
|
||||
demangled_name_view = demangled_name_ptr.get();
|
||||
|
||||
// Normalization of stdlib inline namespace names.
|
||||
// libc++ inline namespaces.
|
||||
// std::__1::* -> std::*
|
||||
// std::__1::__fs::* -> std::*
|
||||
// libstdc++ inline namespaces.
|
||||
// std::__cxx11::* -> std::*
|
||||
// std::filesystem::__cxx11::* -> std::filesystem::*
|
||||
if (demangled_name_view.starts_with("std::")) {
|
||||
char* begin = demangled_name_ptr.get();
|
||||
char* to = begin + 5; // std::
|
||||
for (char *from = to, *end = begin + demangled_name_view.size();
|
||||
from < end;) {
|
||||
// This is safe, because demangled_name is NUL-terminated.
|
||||
if (from[0] == '_' && from[1] == '_') {
|
||||
char* next = from + 1;
|
||||
while (next < end && *next != ':') next++;
|
||||
if (next[0] == ':' && next[1] == ':') {
|
||||
from = next + 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*to++ = *from++;
|
||||
}
|
||||
demangled_name_view = {begin, detail::to_unsigned(to - begin)};
|
||||
}
|
||||
} else {
|
||||
demangled_name_view = string_view(ti.name());
|
||||
}
|
||||
return detail::write_bytes<char>(out, demangled_name_view);
|
||||
# elif FMT_MSC_VERSION
|
||||
const string_view demangled_name(ti.name());
|
||||
for (size_t i = 0; i < demangled_name.size(); ++i) {
|
||||
auto sub = demangled_name;
|
||||
sub.remove_prefix(i);
|
||||
if (sub.starts_with("enum ")) {
|
||||
i += 4;
|
||||
continue;
|
||||
}
|
||||
if (sub.starts_with("class ") || sub.starts_with("union ")) {
|
||||
i += 5;
|
||||
continue;
|
||||
}
|
||||
if (sub.starts_with("struct ")) {
|
||||
i += 6;
|
||||
continue;
|
||||
}
|
||||
if (*sub.begin() != ' ') *out++ = *sub.begin();
|
||||
}
|
||||
return out;
|
||||
# else
|
||||
return detail::write_bytes<char>(out, string_view(ti.name()));
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif // FMT_USE_RTTI
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct has_flip : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_flip<T, void_t<decltype(std::declval<T>().flip())>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T> struct is_bit_reference_like {
|
||||
static constexpr bool value = std::is_convertible<T, bool>::value &&
|
||||
std::is_nothrow_assignable<T, bool>::value &&
|
||||
has_flip<T>::value;
|
||||
};
|
||||
|
||||
// Workaround for libc++ incompatibility with C++ standard.
|
||||
// According to the Standard, `bitset::operator[] const` returns bool.
|
||||
#if defined(_LIBCPP_VERSION) && !defined(FMT_IMPORT_STD)
|
||||
template <typename C>
|
||||
struct is_bit_reference_like<std::__bit_const_reference<C>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct has_format_as : std::false_type {};
|
||||
template <typename T>
|
||||
struct has_format_as<T, void_t<decltype(format_as(std::declval<const T&>()))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct has_format_as_member : std::false_type {};
|
||||
template <typename T>
|
||||
struct has_format_as_member<
|
||||
T, void_t<decltype(formatter<T>::format_as(std::declval<const T&>()))>>
|
||||
: std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename Deleter>
|
||||
auto ptr(const std::unique_ptr<T, Deleter>& p) -> const void* {
|
||||
return p.get();
|
||||
}
|
||||
template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
|
||||
return p.get();
|
||||
}
|
||||
|
||||
#if FMT_CPP_LIB_FILESYSTEM
|
||||
|
||||
class path : public std::filesystem::path {
|
||||
public:
|
||||
auto display_string() const -> std::string {
|
||||
const std::filesystem::path& base = *this;
|
||||
return fmt::format(FMT_STRING("{}"), base);
|
||||
}
|
||||
auto system_string() const -> std::string { return string(); }
|
||||
|
||||
auto generic_display_string() const -> std::string {
|
||||
const std::filesystem::path& base = *this;
|
||||
return fmt::format(FMT_STRING("{:g}"), base);
|
||||
}
|
||||
auto generic_system_string() const -> std::string { return generic_string(); }
|
||||
};
|
||||
|
||||
template <typename Char> struct formatter<std::filesystem::path, Char> {
|
||||
private:
|
||||
format_specs specs_;
|
||||
@@ -162,39 +319,20 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
|
||||
}
|
||||
};
|
||||
|
||||
class path : public std::filesystem::path {
|
||||
public:
|
||||
auto display_string() const -> std::string {
|
||||
const std::filesystem::path& base = *this;
|
||||
return fmt::format(FMT_STRING("{}"), base);
|
||||
}
|
||||
auto system_string() const -> std::string { return string(); }
|
||||
|
||||
auto generic_display_string() const -> std::string {
|
||||
const std::filesystem::path& base = *this;
|
||||
return fmt::format(FMT_STRING("{:g}"), base);
|
||||
}
|
||||
auto generic_system_string() const -> std::string { return generic_string(); }
|
||||
};
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
#endif // FMT_CPP_LIB_FILESYSTEM
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template <std::size_t N, typename Char>
|
||||
template <size_t N, typename Char>
|
||||
struct formatter<std::bitset<N>, Char>
|
||||
: nested_formatter<basic_string_view<Char>, Char> {
|
||||
private:
|
||||
// Functor because C++11 doesn't support generic lambdas.
|
||||
// This is a functor because C++11 doesn't support generic lambdas.
|
||||
struct writer {
|
||||
const std::bitset<N>& bs;
|
||||
|
||||
template <typename OutputIt>
|
||||
FMT_CONSTEXPR auto operator()(OutputIt out) -> OutputIt {
|
||||
for (auto pos = N; pos > 0; --pos) {
|
||||
for (auto pos = N; pos > 0; --pos)
|
||||
out = detail::write<Char>(out, bs[pos - 1] ? Char('1') : Char('0'));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
@@ -209,10 +347,8 @@ struct formatter<std::bitset<N>, Char>
|
||||
|
||||
template <typename Char>
|
||||
struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#ifdef __cpp_lib_optional
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template <typename T, typename Char>
|
||||
struct formatter<std::optional<T>, Char,
|
||||
std::enable_if_t<is_formattable<T, Char>::value>> {
|
||||
@@ -251,30 +387,9 @@ struct formatter<std::optional<T>, Char,
|
||||
return detail::write(out, ')');
|
||||
}
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
#endif // __cpp_lib_optional
|
||||
|
||||
#if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
template <typename Char, typename OutputIt, typename T>
|
||||
auto write_escaped_alternative(OutputIt out, const T& v) -> OutputIt {
|
||||
if constexpr (has_to_string_view<T>::value)
|
||||
return write_escaped_string<Char>(out, detail::to_string_view(v));
|
||||
if constexpr (std::is_same_v<T, Char>) return write_escaped_char(out, v);
|
||||
return write<Char>(out, v);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
#ifdef __cpp_lib_expected
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
template <typename T, typename E, typename Char>
|
||||
struct formatter<std::expected<T, E>, Char,
|
||||
std::enable_if_t<(std::is_void<T>::value ||
|
||||
@@ -301,11 +416,9 @@ struct formatter<std::expected<T, E>, Char,
|
||||
return out;
|
||||
}
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
#endif // __cpp_lib_expected
|
||||
|
||||
#ifdef __cpp_lib_source_location
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template <> struct formatter<std::source_location> {
|
||||
FMT_CONSTEXPR auto parse(parse_context<>& ctx) { return ctx.begin(); }
|
||||
|
||||
@@ -323,42 +436,12 @@ template <> struct formatter<std::source_location> {
|
||||
return out;
|
||||
}
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
#if FMT_CPP_LIB_VARIANT
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
using variant_index_sequence =
|
||||
std::make_index_sequence<std::variant_size<T>::value>;
|
||||
|
||||
template <typename> struct is_variant_like_ : std::false_type {};
|
||||
template <typename... Types>
|
||||
struct is_variant_like_<std::variant<Types...>> : std::true_type {};
|
||||
|
||||
// formattable element check.
|
||||
template <typename T, typename C> class is_variant_formattable_ {
|
||||
template <std::size_t... Is>
|
||||
static std::conjunction<
|
||||
is_formattable<std::variant_alternative_t<Is, T>, C>...>
|
||||
check(std::index_sequence<Is...>);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
decltype(check(variant_index_sequence<T>{}))::value;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T> struct is_variant_like {
|
||||
static constexpr const bool value = detail::is_variant_like_<T>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename C> struct is_variant_formattable {
|
||||
static constexpr const bool value =
|
||||
detail::is_variant_formattable_<T, C>::value;
|
||||
static constexpr bool value = detail::is_variant_like_<T>::value;
|
||||
};
|
||||
|
||||
template <typename Char> struct formatter<std::monostate, Char> {
|
||||
@@ -374,10 +457,10 @@ template <typename Char> struct formatter<std::monostate, Char> {
|
||||
};
|
||||
|
||||
template <typename Variant, typename Char>
|
||||
struct formatter<
|
||||
Variant, Char,
|
||||
std::enable_if_t<std::conjunction_v<
|
||||
is_variant_like<Variant>, is_variant_formattable<Variant, Char>>>> {
|
||||
struct formatter<Variant, Char,
|
||||
std::enable_if_t<std::conjunction_v<
|
||||
is_variant_like<Variant>,
|
||||
detail::is_variant_formattable<Variant, Char>>>> {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return ctx.begin();
|
||||
}
|
||||
@@ -402,10 +485,9 @@ struct formatter<
|
||||
return out;
|
||||
}
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_CPP_LIB_VARIANT
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template <> struct formatter<std::error_code> {
|
||||
private:
|
||||
format_specs specs_;
|
||||
@@ -459,101 +541,29 @@ template <> struct formatter<std::error_code> {
|
||||
};
|
||||
|
||||
#if FMT_USE_RTTI
|
||||
namespace detail {
|
||||
|
||||
template <typename Char, typename OutputIt>
|
||||
auto write_demangled_name(OutputIt out, const std::type_info& ti) -> OutputIt {
|
||||
# ifdef FMT_HAS_ABI_CXA_DEMANGLE
|
||||
int status = 0;
|
||||
std::size_t size = 0;
|
||||
std::unique_ptr<char, void (*)(void*)> demangled_name_ptr(
|
||||
abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
|
||||
|
||||
string_view demangled_name_view;
|
||||
if (demangled_name_ptr) {
|
||||
demangled_name_view = demangled_name_ptr.get();
|
||||
|
||||
// Normalization of stdlib inline namespace names.
|
||||
// libc++ inline namespaces.
|
||||
// std::__1::* -> std::*
|
||||
// std::__1::__fs::* -> std::*
|
||||
// libstdc++ inline namespaces.
|
||||
// std::__cxx11::* -> std::*
|
||||
// std::filesystem::__cxx11::* -> std::filesystem::*
|
||||
if (demangled_name_view.starts_with("std::")) {
|
||||
char* begin = demangled_name_ptr.get();
|
||||
char* to = begin + 5; // std::
|
||||
for (char *from = to, *end = begin + demangled_name_view.size();
|
||||
from < end;) {
|
||||
// This is safe, because demangled_name is NUL-terminated.
|
||||
if (from[0] == '_' && from[1] == '_') {
|
||||
char* next = from + 1;
|
||||
while (next < end && *next != ':') next++;
|
||||
if (next[0] == ':' && next[1] == ':') {
|
||||
from = next + 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*to++ = *from++;
|
||||
}
|
||||
demangled_name_view = {begin, detail::to_unsigned(to - begin)};
|
||||
}
|
||||
} else {
|
||||
demangled_name_view = string_view(ti.name());
|
||||
}
|
||||
return detail::write_bytes<Char>(out, demangled_name_view);
|
||||
# elif FMT_MSC_VERSION
|
||||
const string_view demangled_name(ti.name());
|
||||
for (std::size_t i = 0; i < demangled_name.size(); ++i) {
|
||||
auto sub = demangled_name;
|
||||
sub.remove_prefix(i);
|
||||
if (sub.starts_with("enum ")) {
|
||||
i += 4;
|
||||
continue;
|
||||
}
|
||||
if (sub.starts_with("class ") || sub.starts_with("union ")) {
|
||||
i += 5;
|
||||
continue;
|
||||
}
|
||||
if (sub.starts_with("struct ")) {
|
||||
i += 6;
|
||||
continue;
|
||||
}
|
||||
if (*sub.begin() != ' ') *out++ = *sub.begin();
|
||||
}
|
||||
return out;
|
||||
# else
|
||||
return detail::write_bytes<Char>(out, string_view(ti.name()));
|
||||
# endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Char>
|
||||
struct formatter<std::type_info, Char // DEPRECATED! Mixing code unit types.
|
||||
> {
|
||||
template <> struct formatter<std::type_info> {
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
auto format(const std::type_info& ti, Context& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
return detail::write_demangled_name<Char>(ctx.out(), ti);
|
||||
return detail::write_demangled_name(ctx.out(), ti);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#endif // FMT_USE_RTTI
|
||||
|
||||
template <typename T, typename Char>
|
||||
template <typename T>
|
||||
struct formatter<
|
||||
T, Char, // DEPRECATED! Mixing code unit types.
|
||||
T, char,
|
||||
typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {
|
||||
private:
|
||||
bool with_typename_ = false;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
|
||||
auto it = ctx.begin();
|
||||
auto end = ctx.end();
|
||||
if (it == end || *it == '}') return it;
|
||||
@@ -570,43 +580,15 @@ struct formatter<
|
||||
auto out = ctx.out();
|
||||
#if FMT_USE_RTTI
|
||||
if (with_typename_) {
|
||||
out = detail::write_demangled_name<Char>(out, typeid(ex));
|
||||
out = detail::write_demangled_name(out, typeid(ex));
|
||||
*out++ = ':';
|
||||
*out++ = ' ';
|
||||
}
|
||||
#endif
|
||||
return detail::write_bytes<Char>(out, string_view(ex.what()));
|
||||
return detail::write_bytes<char>(out, string_view(ex.what()));
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct has_flip : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_flip<T, void_t<decltype(std::declval<T>().flip())>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T> struct is_bit_reference_like {
|
||||
static constexpr const bool value =
|
||||
std::is_convertible<T, bool>::value &&
|
||||
std::is_nothrow_assignable<T, bool>::value && has_flip<T>::value;
|
||||
};
|
||||
|
||||
#ifdef _LIBCPP_VERSION
|
||||
|
||||
// Workaround for libc++ incompatibility with C++ standard.
|
||||
// According to the Standard, `bitset::operator[] const` returns bool.
|
||||
template <typename C>
|
||||
struct is_bit_reference_like<std::__bit_const_reference<C>> {
|
||||
static constexpr const bool value = true;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// We can't use std::vector<bool, Allocator>::reference and
|
||||
// std::bitset<N>::reference because the compiler can't deduce Allocator and N
|
||||
// in partial specialization.
|
||||
@@ -621,14 +603,6 @@ struct formatter<BitRef, Char,
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Deleter>
|
||||
auto ptr(const std::unique_ptr<T, Deleter>& p) -> const void* {
|
||||
return p.get();
|
||||
}
|
||||
template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
|
||||
return p.get();
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
struct formatter<std::atomic<T>, Char,
|
||||
enable_if_t<is_formattable<T, Char>::value>>
|
||||
@@ -715,7 +689,11 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
|
||||
|
||||
template <typename T, typename Char>
|
||||
struct formatter<std::reference_wrapper<T>, Char,
|
||||
enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value>>
|
||||
// Guard against format_as because reference_wrapper is
|
||||
// implicitly convertible to T&.
|
||||
enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value &&
|
||||
!detail::has_format_as<T>::value &&
|
||||
!detail::has_format_as_member<T>::value>>
|
||||
: formatter<remove_cvref_t<T>, Char> {
|
||||
template <typename FormatContext>
|
||||
auto format(std::reference_wrapper<T> ref, FormatContext& ctx) const
|
||||
@@ -725,4 +703,5 @@ struct formatter<std::reference_wrapper<T>, Char,
|
||||
};
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_STD_H_
|
||||
|
||||
73
3rdparty/fmt/include/fmt/xchar.h
vendored
73
3rdparty/fmt/include/fmt/xchar.h
vendored
@@ -55,6 +55,16 @@ inline auto write_loc(basic_appender<wchar_t> out, loc_value value,
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
|
||||
basic_format_args<buffered_context<Char>> args,
|
||||
locale_ref loc = {}) {
|
||||
static_assert(!std::is_same<Char, char>::value, "");
|
||||
auto out = basic_appender<Char>(buf);
|
||||
parse_format_string(
|
||||
fmt, format_handler<Char>{parse_context<Char>(fmt), {out, args, loc}});
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
FMT_BEGIN_EXPORT
|
||||
@@ -112,10 +122,6 @@ inline auto runtime(wstring_view s) -> runtime_format_string<wchar_t> {
|
||||
return {{s}};
|
||||
}
|
||||
|
||||
#ifdef __cpp_char8_t
|
||||
template <> struct is_char<char8_t> : bool_constant<detail::is_utf8_enabled> {};
|
||||
#endif
|
||||
|
||||
template <typename... T>
|
||||
constexpr auto make_wformat_args(T&... args)
|
||||
-> decltype(fmt::make_format_args<wformat_context>(args...)) {
|
||||
@@ -151,13 +157,13 @@ auto join(std::initializer_list<T> list, wstring_view sep)
|
||||
|
||||
template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
|
||||
auto join(const Tuple& tuple, basic_string_view<wchar_t> sep)
|
||||
-> tuple_join_view<wchar_t, Tuple> {
|
||||
-> tuple_join_view<Tuple, wchar_t> {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
|
||||
auto vformat(basic_string_view<Char> fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
basic_format_args<buffered_context<Char>> args)
|
||||
-> std::basic_string<Char> {
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
detail::vformat_to(buf, fmt, args);
|
||||
@@ -187,24 +193,20 @@ auto format(const S& fmt, T&&... args) -> std::basic_string<Char> {
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
}
|
||||
|
||||
template <typename Locale, typename S,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat(const Locale& loc, const S& fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
template <typename S, typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat(locale_ref loc, const S& fmt,
|
||||
basic_format_args<buffered_context<Char>> args)
|
||||
-> std::basic_string<Char> {
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
detail::vformat_to(buf, detail::to_string_view(fmt), args,
|
||||
detail::locale_ref(loc));
|
||||
detail::vformat_to(buf, detail::to_string_view(fmt), args, loc);
|
||||
return {buf.data(), buf.size()};
|
||||
}
|
||||
|
||||
template <typename Locale, typename S, typename... T,
|
||||
template <typename S, typename... T,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto format(const Locale& loc, const S& fmt, T&&... args)
|
||||
FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
|
||||
inline auto format(locale_ref loc, const S& fmt, T&&... args)
|
||||
-> std::basic_string<Char> {
|
||||
return vformat(loc, detail::to_string_view(fmt),
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
@@ -215,7 +217,7 @@ template <typename OutputIt, typename S,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
auto vformat_to(OutputIt out, const S& fmt,
|
||||
typename detail::vformat_args<Char>::type args) -> OutputIt {
|
||||
basic_format_args<buffered_context<Char>> args) -> OutputIt {
|
||||
auto&& buf = detail::get_buffer<Char>(out);
|
||||
detail::vformat_to(buf, detail::to_string_view(fmt), args);
|
||||
return detail::get_iterator(buf, out);
|
||||
@@ -231,27 +233,24 @@ inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt {
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
}
|
||||
|
||||
template <typename Locale, typename S, typename OutputIt, typename... Args,
|
||||
template <typename S, typename OutputIt, typename... Args,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||
detail::is_locale<Locale>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat_to(OutputIt out, const Locale& loc, const S& fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat_to(OutputIt out, locale_ref loc, const S& fmt,
|
||||
basic_format_args<buffered_context<Char>> args)
|
||||
-> OutputIt {
|
||||
auto&& buf = detail::get_buffer<Char>(out);
|
||||
vformat_to(buf, detail::to_string_view(fmt), args, detail::locale_ref(loc));
|
||||
vformat_to(buf, detail::to_string_view(fmt), args, loc);
|
||||
return detail::get_iterator(buf, out);
|
||||
}
|
||||
|
||||
template <typename Locale, typename OutputIt, typename S, typename... T,
|
||||
template <typename OutputIt, typename S, typename... T,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
bool enable = detail::is_output_iterator<OutputIt, Char>::value &&
|
||||
detail::is_locale<Locale>::value &&
|
||||
detail::is_exotic_char<Char>::value>
|
||||
inline auto format_to(OutputIt out, const Locale& loc, const S& fmt,
|
||||
T&&... args) ->
|
||||
typename std::enable_if<enable, OutputIt>::type {
|
||||
inline auto format_to(OutputIt out, locale_ref loc, const S& fmt, T&&... args)
|
||||
-> typename std::enable_if<enable, OutputIt>::type {
|
||||
return vformat_to(out, loc, detail::to_string_view(fmt),
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
}
|
||||
@@ -260,7 +259,7 @@ template <typename OutputIt, typename Char, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat_to_n(OutputIt out, size_t n, basic_string_view<Char> fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
basic_format_args<buffered_context<Char>> args)
|
||||
-> format_to_n_result<OutputIt> {
|
||||
using traits = detail::fixed_buffer_traits;
|
||||
auto buf = detail::iterator_buffer<OutputIt, Char, traits>(out, n);
|
||||
@@ -331,18 +330,6 @@ inline auto format(text_style ts, wformat_string<T...> fmt, T&&... args)
|
||||
return fmt::vformat(ts, fmt, fmt::make_wformat_args(args...));
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED void print(std::FILE* f, text_style ts, wformat_string<T...> fmt,
|
||||
const T&... args) {
|
||||
vprint(f, ts, fmt, fmt::make_wformat_args(args...));
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED void print(text_style ts, wformat_string<T...> fmt,
|
||||
const T&... args) {
|
||||
return print(stdout, ts, fmt, args...);
|
||||
}
|
||||
|
||||
inline void vprint(std::wostream& os, wstring_view fmt, wformat_args args) {
|
||||
auto buffer = basic_memory_buffer<wchar_t>();
|
||||
detail::vformat_to(buffer, fmt, args);
|
||||
|
||||
2
3rdparty/fmt/src/fmt.cc
vendored
2
3rdparty/fmt/src/fmt.cc
vendored
@@ -50,6 +50,8 @@ module;
|
||||
# include <limits.h>
|
||||
# include <stdint.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <time.h>
|
||||
#endif
|
||||
#include <cerrno>
|
||||
|
||||
17
3rdparty/fmt/src/format.cc
vendored
17
3rdparty/fmt/src/format.cc
vendored
@@ -8,6 +8,12 @@
|
||||
#include "fmt/format-inl.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
template FMT_API locale_ref::locale_ref(const std::locale& loc);
|
||||
template FMT_API auto locale_ref::get<std::locale>() const -> std::locale;
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
template FMT_API auto dragonbox::to_decimal(float x) noexcept
|
||||
@@ -15,12 +21,6 @@ template FMT_API auto dragonbox::to_decimal(float x) noexcept
|
||||
template FMT_API auto dragonbox::to_decimal(double x) noexcept
|
||||
-> dragonbox::decimal_fp<double>;
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
// DEPRECATED! locale_ref in the detail namespace
|
||||
template FMT_API locale_ref::locale_ref(const std::locale& loc);
|
||||
template FMT_API auto locale_ref::get<std::locale>() const -> std::locale;
|
||||
#endif
|
||||
|
||||
// Explicit instantiations for char.
|
||||
|
||||
template FMT_API auto thousands_sep_impl(locale_ref)
|
||||
@@ -30,16 +30,13 @@ template FMT_API auto decimal_point_impl(locale_ref) -> char;
|
||||
// DEPRECATED!
|
||||
template FMT_API void buffer<char>::append(const char*, const char*);
|
||||
|
||||
// DEPRECATED!
|
||||
template FMT_API void vformat_to(buffer<char>&, string_view,
|
||||
typename vformat_args<>::type, locale_ref);
|
||||
|
||||
// Explicit instantiations for wchar_t.
|
||||
|
||||
template FMT_API auto thousands_sep_impl(locale_ref)
|
||||
-> thousands_sep_result<wchar_t>;
|
||||
template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
|
||||
|
||||
// DEPRECATED!
|
||||
template FMT_API void buffer<wchar_t>::append(const wchar_t*, const wchar_t*);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
20
3rdparty/fmt/src/os.cc
vendored
20
3rdparty/fmt/src/os.cc
vendored
@@ -66,14 +66,14 @@ using rwresult = int;
|
||||
|
||||
// On Windows the count argument to read and write is unsigned, so convert
|
||||
// it from size_t preventing integer overflow.
|
||||
inline unsigned convert_rwcount(std::size_t count) {
|
||||
inline unsigned convert_rwcount(size_t count) {
|
||||
return count <= UINT_MAX ? static_cast<unsigned>(count) : UINT_MAX;
|
||||
}
|
||||
#elif FMT_USE_FCNTL
|
||||
// Return type of read and write functions.
|
||||
using rwresult = ssize_t;
|
||||
|
||||
inline std::size_t convert_rwcount(std::size_t count) { return count; }
|
||||
inline auto convert_rwcount(size_t count) -> size_t { return count; }
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
@@ -185,7 +185,7 @@ void buffered_file::close() {
|
||||
FMT_THROW(system_error(errno, FMT_STRING("cannot close file")));
|
||||
}
|
||||
|
||||
int buffered_file::descriptor() const {
|
||||
auto buffered_file::descriptor() const -> int {
|
||||
#ifdef FMT_HAS_SYSTEM
|
||||
// fileno is a macro on OpenBSD.
|
||||
# ifdef fileno
|
||||
@@ -240,7 +240,7 @@ void file::close() {
|
||||
FMT_THROW(system_error(errno, FMT_STRING("cannot close file")));
|
||||
}
|
||||
|
||||
long long file::size() const {
|
||||
auto file::size() const -> long long {
|
||||
# ifdef _WIN32
|
||||
// Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT
|
||||
// is less than 0x0500 as is the case with some default MinGW builds.
|
||||
@@ -251,7 +251,7 @@ long long file::size() const {
|
||||
if (size_lower == INVALID_FILE_SIZE) {
|
||||
DWORD error = GetLastError();
|
||||
if (error != NO_ERROR)
|
||||
FMT_THROW(windows_error(GetLastError(), "cannot get file size"));
|
||||
FMT_THROW(windows_error(error, "cannot get file size"));
|
||||
}
|
||||
unsigned long long long_size = size_upper;
|
||||
return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;
|
||||
@@ -266,7 +266,7 @@ long long file::size() const {
|
||||
# endif
|
||||
}
|
||||
|
||||
std::size_t file::read(void* buffer, std::size_t count) {
|
||||
auto file::read(void* buffer, size_t count) -> size_t {
|
||||
rwresult result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
|
||||
if (result < 0)
|
||||
@@ -274,7 +274,7 @@ std::size_t file::read(void* buffer, std::size_t count) {
|
||||
return detail::to_unsigned(result);
|
||||
}
|
||||
|
||||
std::size_t file::write(const void* buffer, std::size_t count) {
|
||||
auto file::write(const void* buffer, size_t count) -> size_t {
|
||||
rwresult result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
|
||||
if (result < 0)
|
||||
@@ -282,7 +282,7 @@ std::size_t file::write(const void* buffer, std::size_t count) {
|
||||
return detail::to_unsigned(result);
|
||||
}
|
||||
|
||||
file file::dup(int fd) {
|
||||
auto file::dup(int fd) -> file {
|
||||
// Don't retry as dup doesn't return EINTR.
|
||||
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
|
||||
int new_fd = FMT_POSIX_CALL(dup(fd));
|
||||
@@ -308,7 +308,7 @@ void file::dup2(int fd, std::error_code& ec) noexcept {
|
||||
if (result == -1) ec = std::error_code(errno, std::generic_category());
|
||||
}
|
||||
|
||||
buffered_file file::fdopen(const char* mode) {
|
||||
auto file::fdopen(const char* mode) -> buffered_file {
|
||||
// Don't retry as fdopen doesn't return EINTR.
|
||||
# if defined(__MINGW32__) && defined(_POSIX_)
|
||||
FILE* f = ::fdopen(fd_, mode);
|
||||
@@ -355,7 +355,7 @@ pipe::pipe() {
|
||||
}
|
||||
|
||||
# if !defined(__MSDOS__)
|
||||
long getpagesize() {
|
||||
auto getpagesize() -> long {
|
||||
# ifdef _WIN32
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
|
||||
16
3rdparty/rcheevos/CHANGELOG.md
vendored
16
3rdparty/rcheevos/CHANGELOG.md
vendored
@@ -1,3 +1,19 @@
|
||||
# v12.1.0
|
||||
* add rc_client_get_user_subset_summary
|
||||
* add validation warning for using MeasuredIf without Measured
|
||||
* add validation warning for using ResetIf without hit targets
|
||||
* add rapi function for update_rich_presence
|
||||
* add gap to RC_CONSOLE_WII memory map to make it easier to convert pointers
|
||||
* improve range validation logic
|
||||
* fix error Remembering float value
|
||||
* fix MeasuredIf evaluation in rich presence
|
||||
* fix parsing of code notes with addresses above 0x7FFFFFFF
|
||||
* fix double evaluation of rich presence parameters
|
||||
* fix validation of SubSource chain
|
||||
* fix error if rc_client_allow_background_memory_reads called before calling rc_client_begin_load_raintegration
|
||||
* fix memory corruption when mixing legacy and new-format macros in rich presence
|
||||
* fix invalid pointer reference when iterator gets cloned
|
||||
|
||||
# v12.0.0
|
||||
* rc_client changes
|
||||
* add RC_CLIENT_EVENT_SUBSET_COMPLETED event
|
||||
|
||||
2
3rdparty/rcheevos/src/rc_client.c
vendored
2
3rdparty/rcheevos/src/rc_client.c
vendored
@@ -5880,7 +5880,7 @@ void rc_client_do_frame(rc_client_t* client)
|
||||
|
||||
richpresence = client->game->runtime.richpresence;
|
||||
if (richpresence && richpresence->richpresence)
|
||||
rc_update_richpresence(richpresence->richpresence, client->state.legacy_peek, client, NULL);
|
||||
rc_update_richpresence_internal(richpresence->richpresence, client->state.legacy_peek, client);
|
||||
|
||||
rc_mutex_unlock(&client->state.mutex);
|
||||
|
||||
|
||||
@@ -223,6 +223,8 @@ static void rc_client_init_raintegration(rc_client_t* client,
|
||||
external_client->set_encore_mode_enabled(rc_client_get_encore_mode_enabled(client));
|
||||
if (external_client->set_spectator_mode_enabled)
|
||||
external_client->set_spectator_mode_enabled(rc_client_get_spectator_mode_enabled(client));
|
||||
if (external_client->set_allow_background_memory_reads)
|
||||
external_client->set_allow_background_memory_reads(client->state.allow_background_memory_reads);
|
||||
|
||||
/* attach the external client and call the callback */
|
||||
client->state.external_client = external_client;
|
||||
|
||||
2
3rdparty/rcheevos/src/rc_version.h
vendored
2
3rdparty/rcheevos/src/rc_version.h
vendored
@@ -8,7 +8,7 @@
|
||||
RC_BEGIN_C_DECLS
|
||||
|
||||
#define RCHEEVOS_VERSION_MAJOR 12
|
||||
#define RCHEEVOS_VERSION_MINOR 0
|
||||
#define RCHEEVOS_VERSION_MINOR 1
|
||||
#define RCHEEVOS_VERSION_PATCH 0
|
||||
|
||||
#define RCHEEVOS_MAKE_VERSION(major, minor, patch) (major * 1000000 + minor * 1000 + patch)
|
||||
|
||||
4
3rdparty/rcheevos/src/rcheevos/condset.c
vendored
4
3rdparty/rcheevos/src/rcheevos/condset.c
vendored
@@ -607,8 +607,8 @@ static void rc_condset_evaluate_or_next(rc_condition_t* condition, rc_eval_state
|
||||
eval_state->or_next = rc_condset_evaluate_condition_no_add_hits(condition, eval_state);
|
||||
}
|
||||
|
||||
static void rc_test_condset_internal(rc_condition_t* condition, uint32_t num_conditions,
|
||||
rc_eval_state_t* eval_state, int can_short_circuit) {
|
||||
void rc_test_condset_internal(rc_condition_t* condition, uint32_t num_conditions,
|
||||
rc_eval_state_t* eval_state, int can_short_circuit) {
|
||||
const rc_condition_t* condition_end = condition + num_conditions;
|
||||
for (; condition < condition_end; ++condition) {
|
||||
switch (condition->type) {
|
||||
|
||||
2
3rdparty/rcheevos/src/rcheevos/rc_internal.h
vendored
2
3rdparty/rcheevos/src/rcheevos/rc_internal.h
vendored
@@ -311,6 +311,7 @@ rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse);
|
||||
int rc_test_condset(rc_condset_t* self, rc_eval_state_t* eval_state);
|
||||
void rc_reset_condset(rc_condset_t* self);
|
||||
rc_condition_t* rc_condset_get_conditions(rc_condset_t* self);
|
||||
void rc_test_condset_internal(rc_condition_t* condition, uint32_t num_conditions, rc_eval_state_t* eval_state, int can_short_circuit);
|
||||
|
||||
enum {
|
||||
RC_PROCESSING_COMPARE_DEFAULT = 0,
|
||||
@@ -379,6 +380,7 @@ int rc_lboard_state_active(int state);
|
||||
void rc_parse_richpresence_internal(rc_richpresence_t* self, const char* script, rc_parse_state_t* parse);
|
||||
rc_memrefs_t* rc_richpresence_get_memrefs(rc_richpresence_t* self);
|
||||
void rc_reset_richpresence_triggers(rc_richpresence_t* self);
|
||||
void rc_update_richpresence_internal(rc_richpresence_t* richpresence, rc_peek_t peek, void* peek_ud);
|
||||
|
||||
int rc_validate_memrefs(const rc_memrefs_t* memrefs, char result[], const size_t result_size, uint32_t max_address);
|
||||
int rc_validate_memrefs_for_console(const rc_memrefs_t* memrefs, char result[], const size_t result_size, uint32_t console_id);
|
||||
|
||||
156
3rdparty/rcheevos/src/rcheevos/rc_validate.c
vendored
156
3rdparty/rcheevos/src/rcheevos/rc_validate.c
vendored
@@ -133,79 +133,93 @@ static uint32_t rc_max_value(const rc_operand_t* operand)
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t rc_scale_value(uint32_t value, uint8_t oper, const rc_operand_t* operand)
|
||||
static void rc_combine_ranges(uint32_t* min_val, uint32_t* max_val, uint8_t oper, uint32_t oper_min_val, uint32_t oper_max_val)
|
||||
{
|
||||
switch (oper) {
|
||||
case RC_OPERATOR_MULT:
|
||||
{
|
||||
unsigned long long scaled = ((unsigned long long)value) * rc_max_value(operand);
|
||||
if (scaled > 0xFFFFFFFF)
|
||||
return 0xFFFFFFFF;
|
||||
unsigned long long scaled = ((unsigned long long)*min_val) * oper_min_val;
|
||||
*min_val = (scaled > 0xFFFFFFFF) ? 0xFFFFFFFF : (uint32_t)scaled;
|
||||
|
||||
return (uint32_t)scaled;
|
||||
scaled = ((unsigned long long)*max_val) * oper_max_val;
|
||||
*max_val = (scaled > 0xFFFFFFFF) ? 0xFFFFFFFF : (uint32_t)scaled;
|
||||
break;
|
||||
}
|
||||
|
||||
case RC_OPERATOR_DIV:
|
||||
{
|
||||
const uint32_t min_val = (operand->type == RC_OPERAND_CONST) ? operand->value.num : 1;
|
||||
return value / min_val;
|
||||
}
|
||||
*min_val = (oper_max_val == 0) ? *min_val : (*min_val / oper_max_val);
|
||||
*max_val = (oper_min_val == 0) ? *max_val : (*max_val / oper_min_val);
|
||||
break;
|
||||
|
||||
case RC_OPERATOR_AND:
|
||||
return rc_max_value(operand);
|
||||
*min_val = 0;
|
||||
*max_val &= oper_max_val;
|
||||
break;
|
||||
|
||||
case RC_OPERATOR_XOR:
|
||||
return value | rc_max_value(operand);
|
||||
*min_val = 0;
|
||||
*max_val |= oper_max_val;
|
||||
break;
|
||||
|
||||
case RC_OPERATOR_MOD:
|
||||
{
|
||||
const uint32_t divisor = (operand->type == RC_OPERAND_CONST) ? operand->value.num : 1;
|
||||
return (divisor >= value) ? (divisor - 1) : value;
|
||||
}
|
||||
*min_val = 0;
|
||||
*max_val = (*max_val >= oper_max_val) ? oper_max_val - 1 : *max_val;
|
||||
break;
|
||||
|
||||
case RC_OPERATOR_ADD:
|
||||
{
|
||||
unsigned long scaled = ((unsigned long)value) + rc_max_value(operand);
|
||||
if (scaled > 0xFFFFFFFF)
|
||||
return 0xFFFFFFFF;
|
||||
if (*min_val > *max_val) { /* underflow occurred */
|
||||
*max_val += oper_max_val;
|
||||
}
|
||||
else {
|
||||
unsigned long scaled = ((unsigned long)*max_val) + oper_max_val;
|
||||
*max_val = (scaled > 0xFFFFFFFF) ? 0xFFFFFFFF : (uint32_t)scaled;
|
||||
}
|
||||
|
||||
return (uint32_t)scaled;
|
||||
}
|
||||
*min_val += oper_min_val;
|
||||
break;
|
||||
|
||||
case RC_OPERATOR_SUB:
|
||||
{
|
||||
const uint32_t op_max = (operand->type == RC_OPERAND_CONST) ? operand->value.num : 0;
|
||||
if (value >= op_max)
|
||||
return value - op_max;
|
||||
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
*min_val -= oper_max_val;
|
||||
*max_val -= oper_min_val;
|
||||
break;
|
||||
|
||||
case RC_OPERATOR_SUB_PARENT:
|
||||
{
|
||||
const uint32_t op_max = (operand->type == RC_OPERAND_CONST) ? operand->value.num : rc_max_value(operand);
|
||||
if (op_max > value)
|
||||
return op_max - value;
|
||||
|
||||
return 0xFFFFFFFF;
|
||||
uint32_t temp = oper_min_val - *max_val;
|
||||
*max_val = oper_max_val - *min_val;
|
||||
*min_val = temp;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t rc_max_chain_value(const rc_operand_t* operand)
|
||||
static void rc_chain_get_value_range(const rc_operand_t* operand, uint32_t* min_val, uint32_t* max_val)
|
||||
{
|
||||
if (rc_operand_is_memref(operand) && operand->value.memref->value.memref_type == RC_MEMREF_TYPE_MODIFIED_MEMREF) {
|
||||
const rc_modified_memref_t* modified_memref = (const rc_modified_memref_t*)operand->value.memref;
|
||||
if (modified_memref->modifier_type != RC_OPERATOR_INDIRECT_READ) {
|
||||
const uint32_t op_max = rc_max_chain_value(&modified_memref->parent);
|
||||
return rc_scale_value(op_max, modified_memref->modifier_type, &modified_memref->modifier);
|
||||
if (modified_memref->modifier_type == RC_OPERATOR_DIV &&
|
||||
rc_operand_is_memref(&modified_memref->modifier) &&
|
||||
rc_operands_are_equal(&modified_memref->modifier, &modified_memref->parent)) {
|
||||
/* division by self can only return 0 or 1. */
|
||||
*min_val = 0;
|
||||
*max_val = 1;
|
||||
}
|
||||
else {
|
||||
uint32_t modifier_min_val, modifier_max_val;
|
||||
rc_chain_get_value_range(&modified_memref->parent, min_val, max_val);
|
||||
rc_chain_get_value_range(&modified_memref->modifier, &modifier_min_val, &modifier_max_val);
|
||||
rc_combine_ranges(min_val, max_val, modified_memref->modifier_type, modifier_min_val, modifier_max_val);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return rc_max_value(operand);
|
||||
*min_val = (operand->type == RC_OPERAND_CONST) ? operand->value.num : 0;
|
||||
*max_val = rc_max_value(operand);
|
||||
}
|
||||
|
||||
static int rc_validate_get_condition_index(const rc_condset_t* condset, const rc_condition_t* condition)
|
||||
@@ -291,7 +305,7 @@ static int rc_validate_range(uint32_t min_val, uint32_t max_val, char oper, uint
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int rc_validate_condset_internal(const rc_condset_t* condset, char result[], const size_t result_size, uint32_t console_id, uint32_t max_address)
|
||||
static int rc_validate_condset_internal(const rc_condset_t* condset, char result[], const size_t result_size, uint32_t console_id, uint32_t max_address, int has_hits)
|
||||
{
|
||||
const rc_condition_t* cond;
|
||||
char buffer[128];
|
||||
@@ -299,6 +313,8 @@ static int rc_validate_condset_internal(const rc_condset_t* condset, char result
|
||||
int in_add_hits = 0;
|
||||
int in_add_address = 0;
|
||||
int is_combining = 0;
|
||||
int has_measured = 0;
|
||||
int measuredif_index = -1;
|
||||
|
||||
if (!condset) {
|
||||
*result = '\0';
|
||||
@@ -383,6 +399,10 @@ static int rc_validate_condset_internal(const rc_condset_t* condset, char result
|
||||
is_combining = 0;
|
||||
break;
|
||||
}
|
||||
if (!has_hits) {
|
||||
snprintf(result, result_size, "Condition %d: No captured hits to reset", index);
|
||||
return 0;
|
||||
}
|
||||
if (cond->required_hits == 1) {
|
||||
snprintf(result, result_size, "Condition %d: Hit target of 1 is redundant on ResetIf", index);
|
||||
return 0;
|
||||
@@ -398,6 +418,10 @@ static int rc_validate_condset_internal(const rc_condset_t* condset, char result
|
||||
in_add_hits = 0;
|
||||
}
|
||||
|
||||
has_measured |= (cond->type == RC_CONDITION_MEASURED);
|
||||
if (cond->type == RC_CONDITION_MEASURED_IF && measuredif_index == -1)
|
||||
measuredif_index = index;
|
||||
|
||||
is_combining = 0;
|
||||
break;
|
||||
}
|
||||
@@ -424,10 +448,16 @@ static int rc_validate_condset_internal(const rc_condset_t* condset, char result
|
||||
const size_t prefix_length = snprintf(result, result_size, "Condition %d: ", index);
|
||||
const rc_operand_t* operand2 = &cond->operand2;
|
||||
uint8_t oper = cond->oper;
|
||||
uint32_t max = rc_max_chain_value(operand1);
|
||||
uint32_t min, max;
|
||||
uint32_t max_val = rc_max_value(operand2);
|
||||
uint32_t min_val;
|
||||
|
||||
rc_chain_get_value_range(operand1, &min, &max);
|
||||
if (min > max) { /* underflow */
|
||||
min = 0;
|
||||
max = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
if (!is_memref1) {
|
||||
/* pretend constant was on right side */
|
||||
operand2 = operand1;
|
||||
@@ -477,6 +507,7 @@ static int rc_validate_condset_internal(const rc_condset_t* condset, char result
|
||||
break;
|
||||
}
|
||||
|
||||
/* min_val and max_val are the range allowed by operand2. max is the upper value from operand1. */
|
||||
if (!rc_validate_range(min_val, max_val, oper, max, result + prefix_length, result_size - prefix_length))
|
||||
return 0;
|
||||
}
|
||||
@@ -487,19 +518,48 @@ static int rc_validate_condset_internal(const rc_condset_t* condset, char result
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (measuredif_index != -1 && !has_measured) {
|
||||
snprintf(result, result_size, "Condition %d: MeasuredIf without Measured", measuredif_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*result = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int rc_condset_has_hittargets(const rc_condset_t* condset)
|
||||
{
|
||||
if (condset->num_hittarget_conditions > 0)
|
||||
return 1;
|
||||
|
||||
/* pause and reset conditions may have hittargets and won't be classified as hittarget conditions.
|
||||
* measured conditions may also have hittargets.
|
||||
*/
|
||||
if (condset->num_pause_conditions || condset->num_reset_conditions || condset->num_measured_conditions) {
|
||||
const rc_condition_t* condition = rc_condset_get_conditions((rc_condset_t*)condset);
|
||||
/* ASSERT: don't need to add num_hittarget_conditions because it must be 0 per earlier check */
|
||||
const rc_condition_t* stop = condition + condset->num_pause_conditions
|
||||
+ condset->num_reset_conditions + condset->num_measured_conditions;
|
||||
for (; condition < stop; ++condition) {
|
||||
if (condition->required_hits)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rc_validate_condset(const rc_condset_t* condset, char result[], const size_t result_size, uint32_t max_address)
|
||||
{
|
||||
return rc_validate_condset_internal(condset, result, result_size, 0, max_address);
|
||||
int has_hits = rc_condset_has_hittargets(condset);
|
||||
return rc_validate_condset_internal(condset, result, result_size, 0, max_address, has_hits);
|
||||
}
|
||||
|
||||
int rc_validate_condset_for_console(const rc_condset_t* condset, char result[], const size_t result_size, uint32_t console_id)
|
||||
{
|
||||
const uint32_t max_address = rc_console_max_address(console_id);
|
||||
return rc_validate_condset_internal(condset, result, result_size, console_id, max_address);
|
||||
int has_hits = rc_condset_has_hittargets(condset);
|
||||
return rc_validate_condset_internal(condset, result, result_size, console_id, max_address, has_hits);
|
||||
}
|
||||
|
||||
static int rc_validate_is_combining_condition(const rc_condition_t* condition)
|
||||
@@ -845,7 +905,7 @@ static int rc_validate_conflicting_conditions(const rc_condset_t* conditions, co
|
||||
switch (compare_condition->type)
|
||||
{
|
||||
case RC_CONDITION_PAUSE_IF:
|
||||
if (conditions != compare_conditions)
|
||||
if (conditions != compare_conditions) /* PauseIf only affects conditions in same group */
|
||||
break;
|
||||
/* fallthrough */
|
||||
case RC_CONDITION_RESET_IF:
|
||||
@@ -955,10 +1015,10 @@ static int rc_validate_trigger_internal(const rc_trigger_t* trigger, char result
|
||||
{
|
||||
const rc_condset_t* alt;
|
||||
int index;
|
||||
int has_hits = (trigger->requirement && trigger->requirement->num_hittarget_conditions > 0);
|
||||
int has_hits = trigger->requirement && rc_condset_has_hittargets(trigger->requirement);
|
||||
if (!has_hits) {
|
||||
for (alt = trigger->alternative; alt; alt = alt->next) {
|
||||
if (alt->num_hittarget_conditions > 0) {
|
||||
if (rc_condset_has_hittargets(alt)) {
|
||||
has_hits = 1;
|
||||
break;
|
||||
}
|
||||
@@ -966,14 +1026,14 @@ static int rc_validate_trigger_internal(const rc_trigger_t* trigger, char result
|
||||
}
|
||||
|
||||
if (!trigger->alternative) {
|
||||
if (!rc_validate_condset_internal(trigger->requirement, result, result_size, console_id, max_address))
|
||||
if (!rc_validate_condset_internal(trigger->requirement, result, result_size, console_id, max_address, has_hits))
|
||||
return 0;
|
||||
|
||||
return rc_validate_conflicting_conditions(trigger->requirement, trigger->requirement, has_hits, "", "", result, result_size);
|
||||
}
|
||||
|
||||
snprintf(result, result_size, "Core ");
|
||||
if (!rc_validate_condset_internal(trigger->requirement, result + 5, result_size - 5, console_id, max_address))
|
||||
if (!rc_validate_condset_internal(trigger->requirement, result + 5, result_size - 5, console_id, max_address, has_hits))
|
||||
return 0;
|
||||
|
||||
/* compare core to itself */
|
||||
@@ -984,7 +1044,7 @@ static int rc_validate_trigger_internal(const rc_trigger_t* trigger, char result
|
||||
for (alt = trigger->alternative; alt; alt = alt->next, ++index) {
|
||||
char altname[16];
|
||||
const size_t prefix_length = snprintf(result, result_size, "Alt%d ", index);
|
||||
if (!rc_validate_condset_internal(alt, result + prefix_length, result_size - prefix_length, console_id, max_address))
|
||||
if (!rc_validate_condset_internal(alt, result + prefix_length, result_size - prefix_length, console_id, max_address, has_hits))
|
||||
return 0;
|
||||
|
||||
/* compare alt to itself */
|
||||
|
||||
@@ -723,14 +723,19 @@ rc_memrefs_t* rc_richpresence_get_memrefs(rc_richpresence_t* self) {
|
||||
}
|
||||
|
||||
void rc_update_richpresence(rc_richpresence_t* richpresence, rc_peek_t peek, void* peek_ud, void* unused_L) {
|
||||
rc_richpresence_display_t* display;
|
||||
(void)unused_L;
|
||||
|
||||
rc_update_richpresence_memrefs(richpresence, peek, peek_ud);
|
||||
rc_update_values(richpresence->values, peek, peek_ud);
|
||||
rc_update_richpresence_internal(richpresence, peek, peek_ud);
|
||||
}
|
||||
|
||||
void rc_update_richpresence_internal(rc_richpresence_t* richpresence, rc_peek_t peek, void* peek_ud) {
|
||||
rc_richpresence_display_t* display;
|
||||
|
||||
for (display = richpresence->first_display; display; display = display->next) {
|
||||
if (display->has_required_hits)
|
||||
rc_test_trigger(&display->trigger, peek, peek_ud, unused_L);
|
||||
rc_test_trigger(&display->trigger, peek, peek_ud, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,10 @@ add_subdirectory(common)
|
||||
|
||||
# make pcsx2
|
||||
add_subdirectory(pcsx2)
|
||||
add_subdirectory(pcsx2-qt)
|
||||
|
||||
if(ENABLE_QT_UI)
|
||||
add_subdirectory(pcsx2-qt)
|
||||
endif()
|
||||
|
||||
# Updater is Windows only for now.
|
||||
if (WIN32)
|
||||
@@ -62,9 +65,6 @@ endif()
|
||||
|
||||
# gsrunner
|
||||
if(ENABLE_GSRUNNER)
|
||||
if (NOT WIN32 AND NOT APPLE)
|
||||
message(WARNING "GSRunner is only supported on Windows and macOS and may not build on your system")
|
||||
endif()
|
||||
add_subdirectory(pcsx2-gsrunner)
|
||||
else()
|
||||
add_subdirectory(pcsx2-gsrunner EXCLUDE_FROM_ALL)
|
||||
|
||||
@@ -413,6 +413,7 @@ PAPX-90504:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
PAPX-90505:
|
||||
name: "2002 夏のオススメソフト おためしDisc"
|
||||
@@ -446,6 +447,7 @@ PAPX-90508:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
PAPX-90511:
|
||||
name: "SIREN [体験版]"
|
||||
@@ -466,6 +468,7 @@ PAPX-90512:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
PAPX-90514:
|
||||
name: "冬のオススメソフト おためしDISC"
|
||||
@@ -522,12 +525,15 @@ PAPX-90523:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
PAPX-90524:
|
||||
name: "ワイルドアームズ ザ フィフスヴァンガード [体験版]"
|
||||
name-sort: "わいるどあーむず ざ ふぃふすゔぁんがーど [たいけんばん]"
|
||||
name-en: "Wild Arms - The Vth Vanguard [Trial]"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
vu1ClampMode: 3 # Fixes SPS on shell worm enemies.
|
||||
gsHWFixes:
|
||||
roundSprite: 1 # Fixes font sizes and lines in UI.
|
||||
textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
|
||||
@@ -1101,6 +1107,7 @@ PCPX-96634:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
PCPX-96635:
|
||||
name: "プレプレ2 VOLUME.8"
|
||||
@@ -1143,6 +1150,7 @@ PCPX-96649:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
PCPX-96653:
|
||||
name: "ラチェット&クランク3 突撃!ガラクチック★レンジャーズ [店頭体験版]"
|
||||
@@ -2419,6 +2427,7 @@ SCAJ-20179:
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
bilinearUpscale: 2 # Fixes off axis texture corruption in some areas.
|
||||
SCAJ-20180:
|
||||
name: "Xenosaga Episode III - Also Sprach Zarathustra [Disc 2 of 2]"
|
||||
region: "NTSC-Unk"
|
||||
@@ -2427,6 +2436,7 @@ SCAJ-20180:
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
bilinearUpscale: 2 # Fixes off axis texture corruption in some areas.
|
||||
SCAJ-20181:
|
||||
name: "Minna no Tennis"
|
||||
region: "NTSC-Unk"
|
||||
@@ -2442,6 +2452,8 @@ SCAJ-20183:
|
||||
name-sort: "わいるどあーむず ざ ふぃふすゔぁんがーど"
|
||||
name-en: "Wild Arms - The Vth Vanguard"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
vu1ClampMode: 3 # Fixes SPS on shell worm enemies.
|
||||
gsHWFixes:
|
||||
roundSprite: 1 # Fixes font sizes and lines in UI.
|
||||
textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
|
||||
@@ -3231,6 +3243,7 @@ SCED-51352:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
SCED-51359:
|
||||
name: "Official PlayStation 2 Magazine Demo 27"
|
||||
@@ -3820,6 +3833,7 @@ SCED-52578:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
SCED-52580:
|
||||
name: "Magazine Ufficiale PlayStation 2 Italia 06/04"
|
||||
@@ -3836,6 +3850,7 @@ SCED-52681:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
SCED-52687:
|
||||
name: "Formula One 04 [Demo]"
|
||||
@@ -4019,7 +4034,7 @@ SCED-52952:
|
||||
cpuSpriteRenderBW: 4 # Fixes character and water textures.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
autoFlush: 2 # Fixes lighting.
|
||||
halfPixelOffset: 4 # Aligns post-processing.
|
||||
halfPixelOffset: 5 # Aligns post-processing and fixes desert tiles.
|
||||
nativeScaling: 2 # Fixes lighting effects due to upscaling.
|
||||
SCED-52969:
|
||||
name: "EyeToy - Play 2"
|
||||
@@ -5745,7 +5760,7 @@ SCES-52460:
|
||||
cpuSpriteRenderBW: 4 # Fixes character and water textures.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
autoFlush: 2 # Fixes lighting.
|
||||
halfPixelOffset: 4 # Aligns post-processing.
|
||||
halfPixelOffset: 5 # Aligns post-processing and fixes desert tiles.
|
||||
nativeScaling: 2 # Fixes lighting effects due to upscaling.
|
||||
SCES-52529:
|
||||
name: "Sly 2 - Band of Thieves"
|
||||
@@ -7386,7 +7401,7 @@ SCKA-20040:
|
||||
cpuSpriteRenderBW: 4 # Fixes character and water textures.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
autoFlush: 2 # Fixes lighting.
|
||||
halfPixelOffset: 4 # Aligns post-processing.
|
||||
halfPixelOffset: 5 # Aligns post-processing and fixes desert tiles.
|
||||
nativeScaling: 2 # Fixes lighting effects due to upscaling.
|
||||
SCKA-20041:
|
||||
name: "아이토이 - 플레이 2"
|
||||
@@ -8283,6 +8298,7 @@ SCPM-85301:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
SCPM-85302:
|
||||
name: "みんなのGOLF オンライン"
|
||||
@@ -8302,6 +8318,7 @@ SCPM-85304:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
SCPN-60101:
|
||||
name: "PlayStation BB Navigator - Version 0.10 [Prerelease] [Disc 1]"
|
||||
@@ -9553,6 +9570,8 @@ SCPS-15118:
|
||||
name-sort: "わいるどあーむず ざ ふぃふすゔぁんがーど"
|
||||
name-en: "Wild ARMs - The Vth Vanguard"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
vu1ClampMode: 3 # Fixes SPS on shell worm enemies.
|
||||
gsHWFixes:
|
||||
roundSprite: 1 # Fixes font sizes and lines in UI.
|
||||
textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
|
||||
@@ -10263,6 +10282,8 @@ SCPS-19333:
|
||||
name-sort: "わいるどあーむず ざ ふぃふすゔぁんがーど [PlayStation2 the Best]"
|
||||
name-en: "Wild ARMs - The Vth Vanguard [PlayStation2 the Best]"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
vu1ClampMode: 3 # Fixes SPS on shell worm enemies.
|
||||
gsHWFixes:
|
||||
roundSprite: 1 # Fixes font sizes and lines in UI.
|
||||
textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
|
||||
@@ -11798,7 +11819,7 @@ SCUS-97330:
|
||||
cpuSpriteRenderBW: 4 # Fixes character and water textures.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
autoFlush: 2 # Fixes lighting.
|
||||
halfPixelOffset: 4 # Aligns post-processing.
|
||||
halfPixelOffset: 5 # Aligns post-processing and fixes desert tiles.
|
||||
nativeScaling: 2 # Fixes lighting effects due to upscaling.
|
||||
SCUS-97331:
|
||||
name: "Official U.S. PlayStation Magazine Demo Disc 078"
|
||||
@@ -11976,6 +11997,7 @@ SCUS-97384:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
SCUS-97392:
|
||||
name: "NBA '06 featuring The Life Vol.1 [Demo]"
|
||||
@@ -12082,7 +12104,7 @@ SCUS-97412:
|
||||
cpuSpriteRenderBW: 4 # Fixes character and water textures.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
autoFlush: 2 # Fixes lighting.
|
||||
halfPixelOffset: 4 # Aligns post-processing.
|
||||
halfPixelOffset: 5 # Aligns post-processing and fixes desert tiles.
|
||||
nativeScaling: 2 # Fixes lighting effects due to upscaling.
|
||||
SCUS-97413:
|
||||
name: "Ratchet & Clank - Up Your Arsenal [Public Beta v1.0]"
|
||||
@@ -12188,6 +12210,7 @@ SCUS-97436:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
memcardFilters:
|
||||
- "SCUS-97328"
|
||||
@@ -12410,6 +12433,7 @@ SCUS-97483:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves banding in car showcase as well as car brightness and sheen.
|
||||
halfPixelOffset: 4 # Fixes weird edge shadows and depth bleed which happens on the edge as well.
|
||||
autoFlush: 1 # Helps lens flare and sun occlusion somewhat but doesn't full fix it.
|
||||
getSkipCount: "GSC_PolyphonyDigitalGames" # Fixes post-processing.
|
||||
SCUS-97484:
|
||||
name: "Sly 3 - Honor Among Thieves [E3 Demo]"
|
||||
@@ -12620,7 +12644,7 @@ SCUS-97516:
|
||||
cpuSpriteRenderBW: 4 # Fixes character and water textures.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
autoFlush: 2 # Fixes lighting.
|
||||
halfPixelOffset: 4 # Aligns post-processing.
|
||||
halfPixelOffset: 5 # Aligns post-processing and fixes desert tiles.
|
||||
nativeScaling: 2 # Fixes lighting effects due to upscaling.
|
||||
SCUS-97517:
|
||||
name: "Killzone [Greatest Hits]"
|
||||
@@ -13064,6 +13088,8 @@ SLAJ-25008:
|
||||
SLAJ-25011:
|
||||
name: "Shin Sangoku Musou 3"
|
||||
region: "NTSC-Unk"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLAJ-25012:
|
||||
name: "Final Fantasy X-2"
|
||||
region: "NTSC-Unk"
|
||||
@@ -13326,7 +13352,7 @@ SLAJ-25078:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Improves lighting on buildings and objects.
|
||||
autoFlush: 2 # Properly diffuses light instead of strips of light.
|
||||
halfPixelOffset: 4 # Mostly aligns post-processing.
|
||||
halfPixelOffset: 5 # Mostly aligns post-processing.
|
||||
nativeScaling: 2 # Improves post-processing smoothness.
|
||||
getSkipCount: "GSC_BlackAndBurnoutSky"
|
||||
beforeDraw: "OI_BurnoutGames"
|
||||
@@ -14133,7 +14159,7 @@ SLED-53937:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Improves lighting on buildings and objects.
|
||||
autoFlush: 2 # Properly diffuses light instead of strips of light.
|
||||
halfPixelOffset: 4 # Mostly aligns post-processing.
|
||||
halfPixelOffset: 5 # Mostly aligns post-processing.
|
||||
nativeScaling: 2 # Improves post-processing smoothness.
|
||||
getSkipCount: "GSC_BlackAndBurnoutSky"
|
||||
beforeDraw: "OI_BurnoutGames"
|
||||
@@ -15493,6 +15519,8 @@ SLES-50510:
|
||||
SLES-50511:
|
||||
name: "G-Surfers"
|
||||
region: "PAL-M3"
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2 # Improves character portraits.
|
||||
SLES-50512:
|
||||
name: "Bass Strike"
|
||||
region: "PAL-E"
|
||||
@@ -18201,18 +18229,28 @@ SLES-51660:
|
||||
SLES-51661:
|
||||
name: "Dynasty Warriors 4"
|
||||
region: "PAL-E"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLES-51662:
|
||||
name: "Dynasty Warriors 4"
|
||||
region: "PAL-F"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLES-51663:
|
||||
name: "Dynasty Warriors 4"
|
||||
region: "PAL-G"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLES-51664:
|
||||
name: "Dynasty Warriors 4"
|
||||
region: "PAL-I"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLES-51665:
|
||||
name: "Dynasty Warriors 4"
|
||||
region: "PAL-S"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLES-51666:
|
||||
name: "Piglet - El Gran Juego de Disney"
|
||||
name-en: "Piglet's Big Game"
|
||||
@@ -21613,21 +21651,29 @@ SLES-52909:
|
||||
region: "PAL-E-G"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes graphical corruption.
|
||||
gsHWFixes:
|
||||
mipmap: 0 # Currently totally breaks player uniform rendering if mipmapping is enabled.
|
||||
SLES-52910:
|
||||
name: "UEFA Champions League 2005"
|
||||
region: "PAL-F-G"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes graphical corruption.
|
||||
gsHWFixes:
|
||||
mipmap: 0 # Currently totally breaks player uniform rendering if mipmapping is enabled.
|
||||
SLES-52911:
|
||||
name: "UEFA Champions League 2005"
|
||||
region: "PAL-I-S"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes graphical corruption.
|
||||
gsHWFixes:
|
||||
mipmap: 0 # Currently totally breaks player uniform rendering if mipmapping is enabled.
|
||||
SLES-52912:
|
||||
name: "UEFA Champions League 2005"
|
||||
region: "PAL-E-DU"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes graphical corruption.
|
||||
gsHWFixes:
|
||||
mipmap: 0 # Currently totally breaks player uniform rendering if mipmapping is enabled.
|
||||
SLES-52913:
|
||||
name: "Suikoden IV"
|
||||
region: "PAL-M5"
|
||||
@@ -24797,7 +24843,7 @@ SLES-53886:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Improves lighting on buildings and objects.
|
||||
autoFlush: 2 # Properly diffuses light instead of strips of light.
|
||||
halfPixelOffset: 4 # Mostly aligns post-processing.
|
||||
halfPixelOffset: 5 # Mostly aligns post-processing.
|
||||
nativeScaling: 2 # Improves post-processing smoothness.
|
||||
getSkipCount: "GSC_BlackAndBurnoutSky"
|
||||
beforeDraw: "OI_BurnoutGames"
|
||||
@@ -25234,7 +25280,7 @@ SLES-54030:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Improves lighting on buildings and objects.
|
||||
autoFlush: 2 # Properly diffuses light instead of strips of light.
|
||||
halfPixelOffset: 4 # Mostly aligns post-processing.
|
||||
halfPixelOffset: 5 # Mostly aligns post-processing.
|
||||
nativeScaling: 2 # Improves post-processing smoothness.
|
||||
getSkipCount: "GSC_BlackAndBurnoutSky"
|
||||
beforeDraw: "OI_BurnoutGames"
|
||||
@@ -26934,8 +26980,10 @@ SLES-54569:
|
||||
region: "PAL-E"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 1 # Needed to remove part of red box.
|
||||
roundSprite: 2 # Fully remove red box when upscaling .
|
||||
halfPixelOffset: 5 # Aligns bloom outlines.
|
||||
nativeScaling: 2 # Softens and aligns bloom outlines.
|
||||
cpuSpriteRenderBW: 4 # Fixes bloom softness.
|
||||
cpuSpriteRenderLevel: 1 # Needed for above.
|
||||
gameFixes:
|
||||
- XGKickHack # Fixes blank textures.
|
||||
SLES-54579:
|
||||
@@ -27342,6 +27390,8 @@ SLES-54713:
|
||||
SLES-54714:
|
||||
name: "Tony Hawk's Downhill Jam"
|
||||
region: "PAL-E"
|
||||
speedHacks:
|
||||
mtvu: 0 # Fixes tutorial crashing.
|
||||
roundModes:
|
||||
vu1RoundMode: 0 # Crashes without.
|
||||
gsHWFixes:
|
||||
@@ -27352,6 +27402,8 @@ SLES-54714:
|
||||
SLES-54715:
|
||||
name: "Tony Hawk's Downhill Jam"
|
||||
region: "PAL-M4"
|
||||
speedHacks:
|
||||
mtvu: 0 # Fixes tutorial crashing.
|
||||
roundModes:
|
||||
vu1RoundMode: 0 # Crashes without.
|
||||
gsHWFixes:
|
||||
@@ -28187,11 +28239,15 @@ SLES-54964:
|
||||
SLES-54971:
|
||||
name: "Hot Wheels - Beat That!"
|
||||
region: "PAL-M4"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes various car physics issues.
|
||||
gsHWFixes:
|
||||
roundSprite: 1 # Fixes font artifacts.
|
||||
SLES-54972:
|
||||
name: "Wild Arms 5"
|
||||
region: "PAL-M3"
|
||||
clampModes:
|
||||
vu1ClampMode: 3 # Fixes SPS on shell worm enemies.
|
||||
gsHWFixes:
|
||||
roundSprite: 1 # Fixes font sizes and lines in UI.
|
||||
textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
|
||||
@@ -29709,7 +29765,7 @@ SLES-55421:
|
||||
region: "PAL-SWI"
|
||||
SLES-55428:
|
||||
name: "Disney Bolt"
|
||||
region: "PAL-M4"
|
||||
region: "PAL-SC"
|
||||
SLES-55429:
|
||||
name: "Disney Bolt"
|
||||
region: "PAL-M3"
|
||||
@@ -31075,6 +31131,8 @@ SLKA-25050:
|
||||
name: "진・삼국무쌍 3" # Undumped on ReDump as of 2025-08-28
|
||||
name-en: "Jin Samguk Mussang 3"
|
||||
region: "NTSC-K"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLKA-25051:
|
||||
name: "클락 타워 3"
|
||||
name-en: "Clock Tower 3"
|
||||
@@ -36567,6 +36625,7 @@ SLPM-61147:
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
bilinearUpscale: 2 # Fixes off axis texture corruption in some areas.
|
||||
SLPM-61148:
|
||||
name: "グローランサーⅤ ジェネレーションズ [体験版]"
|
||||
name-sort: "ぐろーらんさー5 じぇねれーしょんず [たいけんばん]"
|
||||
@@ -42239,6 +42298,8 @@ SLPM-65248:
|
||||
name-sort: "しんさんごくむそう3"
|
||||
name-en: "Shin Sangoku Musou 3"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLPM-65249:
|
||||
name: "CHAOS LEGION"
|
||||
name-sort: "かおす れぎおん"
|
||||
@@ -48850,7 +48911,7 @@ SLPM-66354:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Improves lighting on buildings and objects.
|
||||
autoFlush: 2 # Properly diffuses light instead of strips of light.
|
||||
halfPixelOffset: 4 # Mostly aligns post-processing.
|
||||
halfPixelOffset: 5 # Mostly aligns post-processing.
|
||||
nativeScaling: 2 # Improves post-processing smoothness.
|
||||
getSkipCount: "GSC_BlackAndBurnoutSky"
|
||||
beforeDraw: "OI_BurnoutGames"
|
||||
@@ -49916,6 +49977,8 @@ SLPM-66522:
|
||||
name-sort: "しんさんごくむそう3 [こーえーていばんしりーず]"
|
||||
name-en: "Shin Sangoku Musou 3 [KOEI Selection]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLPM-66523:
|
||||
name: "三國志Ⅸ with パワーアップキット [KOEI The Best]"
|
||||
name-sort: "さんごくし 9 with ぱわーあっぷきっと [KOEI The Best]"
|
||||
@@ -51196,7 +51259,7 @@ SLPM-66731:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Improves lighting on buildings and objects.
|
||||
autoFlush: 2 # Properly diffuses light instead of strips of light.
|
||||
halfPixelOffset: 4 # Mostly aligns post-processing.
|
||||
halfPixelOffset: 5 # Mostly aligns post-processing.
|
||||
nativeScaling: 2 # Improves post-processing smoothness.
|
||||
getSkipCount: "GSC_BlackAndBurnoutSky"
|
||||
beforeDraw: "OI_BurnoutGames"
|
||||
@@ -52549,7 +52612,7 @@ SLPM-66961:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Improves lighting on buildings and objects.
|
||||
autoFlush: 2 # Properly diffuses light instead of strips of light.
|
||||
halfPixelOffset: 4 # Mostly aligns post-processing.
|
||||
halfPixelOffset: 5 # Mostly aligns post-processing.
|
||||
nativeScaling: 2 # Improves post-processing smoothness.
|
||||
getSkipCount: "GSC_BlackAndBurnoutSky"
|
||||
beforeDraw: "OI_BurnoutGames"
|
||||
@@ -53488,16 +53551,22 @@ SLPM-74215:
|
||||
name-sort: "しんさんごくむそう3 [PlayStation2 the Best]"
|
||||
name-en: "Shin Sangoku Musou 3 [PlayStation2 the Best]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLPM-74216:
|
||||
name: "真・三國無双3 猛将伝 [PlayStation2 the Best]"
|
||||
name-sort: "しんさんごくむそう3 もうしょうでん [PlayStation2 the Best]"
|
||||
name-en: "Shin Sangoku Musou 3 - Moushouden [PlayStation2 the Best]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLPM-74217:
|
||||
name: "真・三國無双3 [PlayStation2 the Best] [メガパック]"
|
||||
name-sort: "しんさんごくむそう3 [PlayStation2 the Best] [めがぱっく]"
|
||||
name-en: "Shin Sangoku Musou 3 [PlayStation2 the Best] [Mega Pack]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLPM-74218:
|
||||
name: "シャイニング・ティアーズ [PlayStation2 the Best]"
|
||||
name-sort: "しゃいにんぐ・てぃあーず [PlayStation2 the Best]"
|
||||
@@ -56428,8 +56497,10 @@ SLPS-20466:
|
||||
name-en: "Simple 2000 Series Vol.101 - The OneeChanpon - OneeChan 2 Special Edition"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 1 # Needed to remove part of red box.
|
||||
roundSprite: 2 # Fully remove red box when upscaling .
|
||||
halfPixelOffset: 5 # Aligns bloom outlines.
|
||||
nativeScaling: 2 # Softens and aligns bloom outlines.
|
||||
cpuSpriteRenderBW: 4 # Fixes bloom softness.
|
||||
cpuSpriteRenderLevel: 1 # Needed for above.
|
||||
gameFixes:
|
||||
- XGKickHack # Fixes blank textures.
|
||||
SLPS-20467:
|
||||
@@ -60515,6 +60586,7 @@ SLPS-25640:
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
bilinearUpscale: 2 # Fixes off axis texture corruption in some areas.
|
||||
memcardFilters: # Allows import of Xenosaga II save data.
|
||||
- "SLPS-25640"
|
||||
- "SLPS-25368"
|
||||
@@ -60529,6 +60601,7 @@ SLPS-25641:
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
bilinearUpscale: 2 # Fixes off axis texture corruption in some areas.
|
||||
memcardFilters:
|
||||
- "SLPS-25640"
|
||||
- "SLPS-25368"
|
||||
@@ -66415,9 +66488,11 @@ SLUS-20591:
|
||||
halfPixelOffset: 4 # Aligns post effects.
|
||||
nativeScaling: 2 # Fixes post-processing and lighting smoothness and position.
|
||||
SLUS-20592:
|
||||
name: "HyperSonic Xtreme - HSX"
|
||||
name: "HSX - HyperSonic - Xtreme"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2 # Improves character portraits.
|
||||
SLUS-20593:
|
||||
name: "Magic Pengel - The Quest for Color"
|
||||
region: "NTSC-U"
|
||||
@@ -66741,6 +66816,8 @@ SLUS-20653:
|
||||
name: "Dynasty Warriors 4"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes missing graphics.
|
||||
SLUS-20655:
|
||||
name: "The Hobbit - The Prelude to the Lord of the Rings"
|
||||
name-sort: "Hobbit, The - The Prelude to the Lord of the Rings"
|
||||
@@ -67500,6 +67577,8 @@ SLUS-20789:
|
||||
name: "Jeopardy!"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes menus.
|
||||
SLUS-20790:
|
||||
name: "Wheel of Fortune"
|
||||
region: "NTSC-U"
|
||||
@@ -71245,7 +71324,7 @@ SLUS-21376:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Improves lighting on buildings and objects.
|
||||
autoFlush: 2 # Properly diffuses light instead of strips of light.
|
||||
halfPixelOffset: 4 # Mostly aligns post-processing.
|
||||
halfPixelOffset: 5 # Mostly aligns post-processing.
|
||||
nativeScaling: 2 # Improves post-processing smoothness.
|
||||
getSkipCount: "GSC_BlackAndBurnoutSky"
|
||||
beforeDraw: "OI_BurnoutGames"
|
||||
@@ -71346,6 +71425,7 @@ SLUS-21389:
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
bilinearUpscale: 2 # Fixes off axis texture corruption in some areas.
|
||||
memcardFilters: # Allows import of Xenosaga II save data.
|
||||
- "SLUS-21389"
|
||||
- "SLUS-20892"
|
||||
@@ -71516,6 +71596,7 @@ SLUS-21417:
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
bilinearUpscale: 2 # Fixes off axis texture corruption in some areas.
|
||||
memcardFilters:
|
||||
- "SLUS-21389"
|
||||
- "SLUS-20892"
|
||||
@@ -71794,6 +71875,8 @@ SLUS-21456:
|
||||
name: "Tony Hawk's Downhill Jam"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
speedHacks:
|
||||
mtvu: 0 # Fixes tutorial crashing.
|
||||
roundModes:
|
||||
vu1RoundMode: 0 # Crashes without.
|
||||
gsHWFixes:
|
||||
@@ -72562,6 +72645,8 @@ SLUS-21615:
|
||||
name: "Wild ARMs 5"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
clampModes:
|
||||
vu1ClampMode: 3 # Fixes SPS on shell worm enemies.
|
||||
gsHWFixes:
|
||||
roundSprite: 1 # Fixes font sizes and lines in UI.
|
||||
textureInsideRT: 1 # Fixes sepia-tone flashback sequences.
|
||||
@@ -72657,6 +72742,8 @@ SLUS-21628:
|
||||
name: "Hot Wheels - Beat That!"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes various car physics issues.
|
||||
gsHWFixes:
|
||||
roundSprite: 1 # Fixes font artifacts.
|
||||
SLUS-21629:
|
||||
@@ -75317,7 +75404,7 @@ SLUS-29180:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Improves lighting on buildings and objects.
|
||||
autoFlush: 2 # Properly diffuses light instead of strips of light.
|
||||
halfPixelOffset: 4 # Mostly aligns post-processing.
|
||||
halfPixelOffset: 5 # Mostly aligns post-processing.
|
||||
nativeScaling: 2 # Improves post-processing smoothness.
|
||||
getSkipCount: "GSC_BlackAndBurnoutSky"
|
||||
beforeDraw: "OI_BurnoutGames"
|
||||
|
||||
@@ -1197,7 +1197,7 @@ PS_OUTPUT ps_main(PS_INPUT input)
|
||||
#if !PS_NO_COLOR1
|
||||
output.c1 = alpha_blend;
|
||||
#endif
|
||||
#if PS_AFAIL == 3 && !PS_NO_COLOR1 // RGB_ONLY, no dual src blend
|
||||
#if PS_AFAIL == 3 && PS_NO_COLOR1 // RGB_ONLY, no dual src blend
|
||||
if (!atst_pass)
|
||||
{
|
||||
float RTa = NEEDS_RT_FOR_AFAIL ? RtTexture.Load(int3(input.p.xy, 0)).a : 0.0f;
|
||||
|
||||
@@ -1134,7 +1134,7 @@ void ps_main()
|
||||
#else
|
||||
SV_Target0.rgb = C.rgb / 255.0f;
|
||||
#endif
|
||||
#if PS_AFAIL == 3 && !PS_NO_COLOR1 // RGB_ONLY, no dual src blend
|
||||
#if PS_AFAIL == 3 && PS_NO_COLOR1 // RGB_ONLY, no dual src blend
|
||||
if (!atst_pass)
|
||||
SV_Target0.a = sample_from_rt().a;
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,7 @@ include(GNUInstallDirs)
|
||||
# Misc option
|
||||
#-------------------------------------------------------------------------------
|
||||
option(ENABLE_TESTS "Enables building the unit tests" ON)
|
||||
option(ENABLE_QT_UI "Enables building the PCSX2 Qt interface." ON)
|
||||
option(ENABLE_GSRUNNER "Enables building the GSRunner by default. It can still be built with `make pcsx2-gsrunner` otherwise." OFF)
|
||||
option(LTO_PCSX2_CORE "Enable LTO/IPO/LTCG on the subset of pcsx2 that benefits most from it but not anything else")
|
||||
option(USE_VTUNE "Plug VTUNE to profile GS JIT.")
|
||||
|
||||
@@ -107,10 +107,19 @@ disable_compiler_warnings_for_target(cubeb)
|
||||
disable_compiler_warnings_for_target(speex)
|
||||
|
||||
# Find the Qt components that we need.
|
||||
find_package(Qt6 6.7.3 COMPONENTS CoreTools Core GuiTools Gui WidgetsTools Widgets LinguistTools REQUIRED)
|
||||
if(ENABLE_QT_UI)
|
||||
find_package(Qt6 6.7.3 COMPONENTS CoreTools Core GuiTools Gui WidgetsTools Widgets LinguistTools REQUIRED)
|
||||
endif()
|
||||
|
||||
if (Qt6_VERSION VERSION_GREATER_EQUAL 6.10.0)
|
||||
find_package(Qt6 COMPONENTS CorePrivate GuiPrivate WidgetsPrivate REQUIRED)
|
||||
endif()
|
||||
|
||||
# The docking system for the debugger.
|
||||
find_package(KDDockWidgets-qt6 2.3.0 REQUIRED)
|
||||
|
||||
if(WIN32)
|
||||
add_subdirectory(3rdparty/rainterface EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(3rdparty/rainterface EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
# Demangler for the debugger.
|
||||
@@ -119,15 +128,6 @@ add_subdirectory(3rdparty/demangler EXCLUDE_FROM_ALL)
|
||||
# Symbol table parser.
|
||||
add_subdirectory(3rdparty/ccc EXCLUDE_FROM_ALL)
|
||||
|
||||
# The docking system for the debugger.
|
||||
find_package(KDDockWidgets-qt6 2.0.0 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)
|
||||
add_subdirectory(3rdparty/zydis EXCLUDE_FROM_ALL)
|
||||
|
||||
@@ -47,6 +47,14 @@
|
||||
|
||||
#include "svnrev.h"
|
||||
|
||||
// Down here because X11 has a lot of defines that can conflict
|
||||
#if defined(__linux__)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <sys/select.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace GSRunner
|
||||
{
|
||||
static void InitializeConsole();
|
||||
@@ -1086,4 +1094,118 @@ void GSRunner::StopPlatformMessagePump()
|
||||
CocoaTools::StopMainThreadEventLoop();
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
static Display* s_display = nullptr;
|
||||
static Window s_window = None;
|
||||
static WindowInfo s_wi;
|
||||
static std::atomic<bool> s_shutdown_requested{false};
|
||||
|
||||
bool GSRunner::CreatePlatformWindow()
|
||||
{
|
||||
pxAssertRel(!s_display && s_window == None, "Tried to create window when there already was one!");
|
||||
|
||||
s_display = XOpenDisplay(nullptr);
|
||||
if (!s_display)
|
||||
{
|
||||
Console.Error("Failed to open X11 display");
|
||||
return false;
|
||||
}
|
||||
|
||||
int screen = DefaultScreen(s_display);
|
||||
Window root = RootWindow(s_display, screen);
|
||||
|
||||
s_window = XCreateSimpleWindow(s_display, root, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 1,
|
||||
BlackPixel(s_display, screen), WhitePixel(s_display, screen));
|
||||
|
||||
if (s_window == None)
|
||||
{
|
||||
Console.Error("Failed to create X11 window");
|
||||
XCloseDisplay(s_display);
|
||||
s_display = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
XStoreName(s_display, s_window, "PCSX2 GS Runner");
|
||||
XSelectInput(s_display, s_window, StructureNotifyMask);
|
||||
XMapWindow(s_display, s_window);
|
||||
|
||||
s_wi.type = WindowInfo::Type::X11;
|
||||
s_wi.display_connection = s_display;
|
||||
s_wi.window_handle = reinterpret_cast<void*>(s_window);
|
||||
s_wi.surface_width = WINDOW_WIDTH;
|
||||
s_wi.surface_height = WINDOW_HEIGHT;
|
||||
s_wi.surface_scale = 1.0f;
|
||||
|
||||
XFlush(s_display);
|
||||
PumpPlatformMessages();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GSRunner::DestroyPlatformWindow()
|
||||
{
|
||||
if (s_display && s_window != None)
|
||||
{
|
||||
XDestroyWindow(s_display, s_window);
|
||||
s_window = None;
|
||||
}
|
||||
|
||||
if (s_display)
|
||||
{
|
||||
XCloseDisplay(s_display);
|
||||
s_display = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<WindowInfo> GSRunner::GetPlatformWindowInfo()
|
||||
{
|
||||
WindowInfo wi;
|
||||
if (s_display && s_window != None)
|
||||
wi = s_wi;
|
||||
else
|
||||
wi.type = WindowInfo::Type::Surfaceless;
|
||||
return wi;
|
||||
}
|
||||
|
||||
void GSRunner::PumpPlatformMessages(bool forever)
|
||||
{
|
||||
if (!s_display)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
while (XPending(s_display) > 0)
|
||||
{
|
||||
XEvent event;
|
||||
XNextEvent(s_display, &event);
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case ConfigureNotify:
|
||||
{
|
||||
const XConfigureEvent& configure = event.xconfigure;
|
||||
s_wi.surface_width = static_cast<u32>(configure.width);
|
||||
s_wi.surface_height = static_cast<u32>(configure.height);
|
||||
break;
|
||||
}
|
||||
case DestroyNotify:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (s_shutdown_requested.load())
|
||||
return;
|
||||
|
||||
if (forever)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
} while (forever && !s_shutdown_requested.load());
|
||||
}
|
||||
|
||||
void GSRunner::StopPlatformMessagePump()
|
||||
{
|
||||
s_shutdown_requested.store(true);
|
||||
}
|
||||
#endif // _WIN32 / __APPLE__
|
||||
|
||||
@@ -73,7 +73,6 @@ def run_regression_test(runner, dumpdir, renderer, upscale, renderhacks, paralle
|
||||
#print("Running '%s'" % (" ".join(args)))
|
||||
subprocess.run(args, env=environ, stdin=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL, creationflags=creationflags)
|
||||
|
||||
|
||||
def run_regression_tests(runner, gsdir, dumpdir, renderer, upscale, renderhacks, parallel=1):
|
||||
paths = glob.glob(gsdir + "/*.*", recursive=True)
|
||||
gamepaths = list(filter(lambda x: get_gs_name(x) is not None, paths))
|
||||
@@ -104,12 +103,12 @@ def run_regression_tests(runner, gsdir, dumpdir, renderer, upscale, renderhacks,
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Generate frame dump images for regression tests")
|
||||
parser.add_argument("-runner", action="store", required=True, help="Path to PCSX2 GS runner")
|
||||
parser.add_argument("-gsdir", action="store", required=True, help="Directory containing GS dumps")
|
||||
parser.add_argument("-dumpdir", action="store", required=True, help="Base directory to dump frames to")
|
||||
parser.add_argument("-renderer", action="store", required=False, help="Renderer to use")
|
||||
parser.add_argument("-runner", action="store", required=True, type=str.strip, help="Path to PCSX2 GS runner")
|
||||
parser.add_argument("-gsdir", action="store", required=True, type=str.strip, help="Directory containing GS dumps")
|
||||
parser.add_argument("-dumpdir", action="store", required=True, type=str.strip, help="Base directory to dump frames to")
|
||||
parser.add_argument("-renderer", action="store", required=False, type=str.strip, help="Renderer to use")
|
||||
parser.add_argument("-upscale", action="store", type=float, default=1, help="Upscaling multiplier to use")
|
||||
parser.add_argument("-renderhacks", action="store", required=False, help="Enable HW Rendering hacks")
|
||||
parser.add_argument("-renderhacks", action="store", required=False, type=str.strip, help="Enable HW Rendering hacks")
|
||||
parser.add_argument("-parallel", action="store", type=int, default=1, help="Number of processes to run")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -281,6 +281,7 @@ target_link_libraries(pcsx2-qt PRIVATE
|
||||
PCSX2
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::GuiPrivate
|
||||
Qt6::Widgets
|
||||
KDAB::kddockwidgets
|
||||
)
|
||||
|
||||
@@ -50,6 +50,8 @@ void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32
|
||||
const s32 charWidth = painter.fontMetrics().averageCharWidth();
|
||||
const s32 x = charWidth; // Left padding
|
||||
const s32 y = rowHeight;
|
||||
const s32 displayTypeWidth = MemoryViewTypeWidth[static_cast<s32>(displayType)];
|
||||
const s32 displayTypeVisualWidth = MemoryViewTypeVisualWidth[static_cast<s32>(displayType)];
|
||||
rowVisible = (height / rowHeight);
|
||||
rowCount = rowVisible + 1;
|
||||
|
||||
@@ -69,23 +71,32 @@ void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32
|
||||
const u32 currentRowAddress = startAddress + (i * 0x10);
|
||||
s32 valX = valuexAxis;
|
||||
segmentXAxis[0] = valX;
|
||||
for (int j = 0; j < 16 / static_cast<s32>(displayType); j++)
|
||||
for (int j = 0; j < 16 / displayTypeWidth; j++)
|
||||
{
|
||||
valX += charWidth;
|
||||
const u32 thisSegmentsStart = currentRowAddress + (j * static_cast<s32>(displayType));
|
||||
const u32 thisSegmentsStart = currentRowAddress + (j * displayTypeWidth);
|
||||
|
||||
segmentXAxis[j] = valX;
|
||||
|
||||
bool penDefault = false;
|
||||
if ((selectedAddress & ~0xF) == currentRowAddress)
|
||||
{
|
||||
if (selectedAddress >= thisSegmentsStart && selectedAddress < (thisSegmentsStart + static_cast<s32>(displayType)))
|
||||
if (selectedAddress >= thisSegmentsStart && selectedAddress < (thisSegmentsStart + displayTypeWidth))
|
||||
{ // If the current byte and row we are drawing is selected
|
||||
if (!selectedText)
|
||||
{
|
||||
s32 charsIntoSegment = ((selectedAddress - thisSegmentsStart) * 2) + ((selectedNibbleHI ? 0 : 1) ^ littleEndian);
|
||||
s32 charsIntoSegment = 0;
|
||||
if (displayType == MemoryViewType::FLOAT)
|
||||
{
|
||||
charsIntoSegment = selectedIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
charsIntoSegment = ((selectedAddress - thisSegmentsStart) * 2) + ((selectedNibbleHI ? 0 : 1) ^ littleEndian);
|
||||
}
|
||||
|
||||
if (littleEndian)
|
||||
charsIntoSegment = (static_cast<s32>(displayType) * 2) - charsIntoSegment - 1;
|
||||
charsIntoSegment = displayTypeVisualWidth - charsIntoSegment - 1;
|
||||
painter.setPen(QColor::fromRgb(205, 165, 0)); // SELECTED NIBBLE LINE COLOUR
|
||||
const QPoint lineStart(valX + (charsIntoSegment * charWidth) + 1, y + (rowHeight * i));
|
||||
painter.drawLine(lineStart, lineStart + QPoint(charWidth - 3, 0));
|
||||
@@ -139,8 +150,19 @@ void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32
|
||||
painter.drawText(valX, y + (rowHeight * i), valid ? FilledQStringFromValue(val, 16) : "????????????????");
|
||||
break;
|
||||
}
|
||||
case MemoryViewType::FLOAT:
|
||||
{
|
||||
const u32 intVal = convertEndian<u32>(cpu.read32(thisSegmentsStart, valid));
|
||||
float val = 0.0;
|
||||
std::memcpy(&val, &intVal, sizeof(val));
|
||||
if (penDefault && val == 0.0)
|
||||
painter.setPen(QColor::fromRgb(145, 145, 155)); // ZERO BYTE COLOUR
|
||||
QString floatStr = QString::number(val, 'g');
|
||||
painter.drawText(valX, y + (rowHeight * i), valid ? QString("%1").arg(floatStr, displayTypeVisualWidth) : "??????????????");
|
||||
break;
|
||||
}
|
||||
}
|
||||
valX += charWidth * 2 * static_cast<s32>(displayType);
|
||||
valX += charWidth * displayTypeVisualWidth;
|
||||
}
|
||||
|
||||
// valX is our new X position after the hex values
|
||||
@@ -183,7 +205,9 @@ void MemoryViewTable::SelectAt(QPoint pos)
|
||||
const u32 selectedRow = (pos.y() - 2) / (rowHeight);
|
||||
const s32 x = pos.x();
|
||||
const s32 avgSegmentWidth = segmentXAxis[1] - segmentXAxis[0];
|
||||
const u32 nibbleWidth = (avgSegmentWidth / (2 * (s32)displayType));
|
||||
const s32 displayTypeWidth = MemoryViewTypeWidth[static_cast<s32>(displayType)];
|
||||
const s32 displayTypeVisualWidth = MemoryViewTypeVisualWidth[static_cast<s32>(displayType)];
|
||||
const u32 nibbleWidth = (avgSegmentWidth / displayTypeVisualWidth);
|
||||
selectedAddress = (selectedRow * 0x10) + startAddress;
|
||||
|
||||
if (x <= segmentXAxis[0])
|
||||
@@ -191,7 +215,7 @@ void MemoryViewTable::SelectAt(QPoint pos)
|
||||
// The user clicked before the first segment
|
||||
selectedText = false;
|
||||
if (littleEndian)
|
||||
selectedAddress += static_cast<s32>(displayType) - 1;
|
||||
selectedAddress += displayTypeWidth - 1;
|
||||
selectedNibbleHI = true;
|
||||
}
|
||||
else if (x > valuexAxis && x < textXAxis)
|
||||
@@ -200,13 +224,23 @@ void MemoryViewTable::SelectAt(QPoint pos)
|
||||
// The user clicked inside of the hexadecimal area
|
||||
for (s32 i = 0; i < 16; i++)
|
||||
{
|
||||
if (i == ((16 / static_cast<s32>(displayType)) - 1) || (x >= segmentXAxis[i] && x < (segmentXAxis[i + 1])))
|
||||
if (i == ((16 / displayTypeWidth) - 1) || (x >= segmentXAxis[i] && x < (segmentXAxis[i + 1])))
|
||||
{
|
||||
u32 indexInSegment = (x - segmentXAxis[i]) / nibbleWidth;
|
||||
if (littleEndian)
|
||||
indexInSegment = (static_cast<s32>(displayType) * 2) - indexInSegment - 1;
|
||||
selectedAddress = selectedAddress + i * static_cast<s32>(displayType) + (indexInSegment / 2);
|
||||
selectedNibbleHI = littleEndian ? indexInSegment & 1 : !(indexInSegment & 1);
|
||||
indexInSegment = displayTypeVisualWidth - indexInSegment - 1;
|
||||
selectedIndex = indexInSegment;
|
||||
if (displayType == MemoryViewType::FLOAT)
|
||||
{
|
||||
// Selecting float always points to starting address of float
|
||||
selectedAddress = selectedAddress + i * displayTypeWidth;
|
||||
selectedNibbleHI = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedAddress = selectedAddress + i * displayTypeWidth + (indexInSegment / 2);
|
||||
selectedNibbleHI = littleEndian ? indexInSegment & 1 : !(indexInSegment & 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -236,6 +270,9 @@ u128 MemoryViewTable::GetSelectedSegment(DebugInterface& cpu)
|
||||
case MemoryViewType::DWORD:
|
||||
val._u64[0] = convertEndian(cpu.read64(selectedAddress & ~7));
|
||||
break;
|
||||
case MemoryViewType::FLOAT:
|
||||
val.lo = convertEndian(cpu.read32(selectedAddress & ~3));
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
@@ -260,36 +297,111 @@ void MemoryViewTable::InsertIntoSelectedHexView(u8 value, DebugInterface& cpu)
|
||||
});
|
||||
}
|
||||
|
||||
bool MemoryViewTable::InsertFloatIntoSelectedHexView(DebugInterface& cpu)
|
||||
{
|
||||
// Get currently selected float as string
|
||||
const u32 currentIntVal = GetSelectedSegment(cpu).lo;
|
||||
float currentFloatVal = 0;
|
||||
std::memcpy(¤tFloatVal, ¤tIntVal, sizeof(currentFloatVal));
|
||||
const QString currentfloatStr = QString("%1").arg(QString::number(currentFloatVal, 'g'), 14).trimmed();
|
||||
|
||||
// Prompt user to enter a new float value
|
||||
bool isValidInput = false;
|
||||
QString newFloatStr = QInputDialog::getText(parent, tr("Input New Float"), "",
|
||||
QLineEdit::Normal, currentfloatStr, &isValidInput);
|
||||
if (!isValidInput)
|
||||
return false;
|
||||
|
||||
// Convert string into float value
|
||||
bool isValidFloat = false;
|
||||
const float newFloatVal = newFloatStr.toFloat(&isValidFloat);
|
||||
if (!isValidFloat)
|
||||
{
|
||||
QMessageBox::warning(parent, tr("Input Error"), tr("Invalid float value"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write new float value back to memory
|
||||
u32 newIntVal = 0;
|
||||
std::memcpy(&newIntVal, &newFloatVal, sizeof(newIntVal));
|
||||
newIntVal = convertEndian(newIntVal);
|
||||
|
||||
const QPointer<MemoryViewTable> table(this);
|
||||
Host::RunOnCPUThread([table, address = selectedAddress, &cpu, val = newIntVal] {
|
||||
cpu.write32(address, val);
|
||||
|
||||
QtHost::RunOnUIThread([table] {
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
table->parent->update();
|
||||
});
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MemoryViewTable::InsertAtCurrentSelection(const QString& text, DebugInterface& cpu)
|
||||
{
|
||||
if (!cpu.isValidAddress(selectedAddress))
|
||||
return;
|
||||
|
||||
// If pasting into the hex view, also decode the input as hex bytes.
|
||||
// This approach prevents one from pasting on a nibble boundary, but that is almost always
|
||||
// user error, and we don't have an undo function in this view, so best to stay conservative.
|
||||
QByteArray input = selectedText ? text.toUtf8() : QByteArray::fromHex(text.toUtf8());
|
||||
|
||||
const QPointer<MemoryViewTable> table(this);
|
||||
const MemoryViewType display_type = displayType;
|
||||
const bool little_endian = littleEndian;
|
||||
Host::RunOnCPUThread([table, address = selectedAddress, &cpu, input, display_type, little_endian] {
|
||||
u32 currAddr = address;
|
||||
for (int i = 0; i < input.size(); i++)
|
||||
if (displayType == MemoryViewType::FLOAT)
|
||||
{
|
||||
// Convert string into float value
|
||||
bool isValidFloat = false;
|
||||
const float newFloatVal = text.toFloat(&isValidFloat);
|
||||
if (!isValidFloat)
|
||||
{
|
||||
cpu.write8(currAddr, input[i]);
|
||||
currAddr = nextAddress(currAddr, address, display_type, little_endian);
|
||||
QMessageBox::warning(parent, tr("Input Error"), tr("Invalid float value"));
|
||||
return;
|
||||
}
|
||||
|
||||
u32 end_address = address + input.size();
|
||||
QtHost::RunOnUIThread([table, end_address] {
|
||||
if (!table)
|
||||
return;
|
||||
// Write new float value back to memory
|
||||
u32 newIntVal = 0;
|
||||
std::memcpy(&newIntVal, &newFloatVal, sizeof(newIntVal));
|
||||
newIntVal = convertEndian(newIntVal);
|
||||
|
||||
table->UpdateSelectedAddress(end_address);
|
||||
table->parent->update();
|
||||
const QPointer<MemoryViewTable> table(this);
|
||||
Host::RunOnCPUThread([table, address = selectedAddress, &cpu, val = newIntVal] {
|
||||
cpu.write32(address, val);
|
||||
|
||||
QtHost::RunOnUIThread([table] {
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
table->parent->update();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// If pasting into the hex view, also decode the input as hex bytes.
|
||||
// This approach prevents one from pasting on a nibble boundary, but that is almost always
|
||||
// user error, and we don't have an undo function in this view, so best to stay conservative.
|
||||
QByteArray input = selectedText ? text.toUtf8() : QByteArray::fromHex(text.toUtf8());
|
||||
|
||||
const QPointer<MemoryViewTable> table(this);
|
||||
const MemoryViewType display_type = displayType;
|
||||
const bool little_endian = littleEndian;
|
||||
Host::RunOnCPUThread([table, address = selectedAddress, &cpu, input, display_type, little_endian] {
|
||||
u32 currAddr = address;
|
||||
for (int i = 0; i < input.size(); i++)
|
||||
{
|
||||
cpu.write8(currAddr, input[i]);
|
||||
currAddr = nextAddress(currAddr, address, display_type, little_endian);
|
||||
}
|
||||
|
||||
u32 end_address = address + input.size();
|
||||
QtHost::RunOnUIThread([table, end_address] {
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
table->UpdateSelectedAddress(end_address);
|
||||
table->parent->update();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
u32 MemoryViewTable::nextAddress(u32 addr, u32 selected_address, MemoryViewType display_type, bool little_endian)
|
||||
@@ -300,8 +412,8 @@ u32 MemoryViewTable::nextAddress(u32 addr, u32 selected_address, MemoryViewType
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selected_address % static_cast<s32>(display_type) == 0)
|
||||
return addr + (static_cast<s32>(display_type) * 2 - 1);
|
||||
if (selected_address % MemoryViewTypeWidth[static_cast<s32>(display_type)] == 0)
|
||||
return addr + (MemoryViewTypeWidth[static_cast<s32>(display_type)] * 2 - 1);
|
||||
else
|
||||
return addr - 1;
|
||||
}
|
||||
@@ -317,7 +429,7 @@ u32 MemoryViewTable::prevAddress(u32 addr, u32 selected_address, MemoryViewType
|
||||
{
|
||||
// It works
|
||||
if ((addr & (static_cast<u32>(display_type) - 1)) == (static_cast<u32>(display_type) - 1))
|
||||
return addr - (static_cast<s32>(display_type) * 2 - 1);
|
||||
return addr - (MemoryViewTypeWidth[static_cast<s32>(display_type)] * 2 - 1);
|
||||
else
|
||||
return selected_address + 1;
|
||||
}
|
||||
@@ -325,39 +437,104 @@ u32 MemoryViewTable::prevAddress(u32 addr, u32 selected_address, MemoryViewType
|
||||
|
||||
void MemoryViewTable::ForwardSelection()
|
||||
{
|
||||
if (!littleEndian)
|
||||
if (displayType == MemoryViewType::FLOAT)
|
||||
{
|
||||
if ((selectedNibbleHI = !selectedNibbleHI))
|
||||
UpdateSelectedAddress(selectedAddress + 1);
|
||||
if (!littleEndian)
|
||||
{
|
||||
// Bump to next address if selection is at end of current float segment
|
||||
if (selectedIndex >= MemoryViewTypeVisualWidth[static_cast<s32>(MemoryViewType::FLOAT)] - 1)
|
||||
{
|
||||
UpdateSelectedAddress(selectedAddress + 4);
|
||||
selectedIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedIndex++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectedIndex <= 0)
|
||||
{
|
||||
UpdateSelectedAddress(selectedAddress + 4);
|
||||
selectedIndex = MemoryViewTypeVisualWidth[static_cast<s32>(MemoryViewType::FLOAT)] - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((selectedNibbleHI = !selectedNibbleHI))
|
||||
if (!littleEndian)
|
||||
{
|
||||
if (selectedAddress % static_cast<s32>(displayType) == 0)
|
||||
UpdateSelectedAddress(selectedAddress + (static_cast<s32>(displayType) * 2 - 1));
|
||||
else
|
||||
UpdateSelectedAddress(selectedAddress - 1);
|
||||
if ((selectedNibbleHI = !selectedNibbleHI))
|
||||
UpdateSelectedAddress(selectedAddress + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((selectedNibbleHI = !selectedNibbleHI))
|
||||
{
|
||||
if (selectedAddress % MemoryViewTypeWidth[static_cast<s32>(displayType)] == 0)
|
||||
UpdateSelectedAddress(selectedAddress + (MemoryViewTypeVisualWidth[static_cast<s32>(displayType)] - 1));
|
||||
else
|
||||
UpdateSelectedAddress(selectedAddress - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryViewTable::BackwardSelection()
|
||||
{
|
||||
if (!littleEndian)
|
||||
const s32 displayTypeWidth = MemoryViewTypeWidth[static_cast<s32>(displayType)];
|
||||
const s32 displayTypeVisualWidth = MemoryViewTypeVisualWidth[static_cast<s32>(displayType)];
|
||||
|
||||
if (displayType == MemoryViewType::FLOAT)
|
||||
{
|
||||
if (!(selectedNibbleHI = !selectedNibbleHI))
|
||||
UpdateSelectedAddress(selectedAddress - 1);
|
||||
if (!littleEndian)
|
||||
{
|
||||
// Bump to previous address if selection is at beginning of current float segment
|
||||
if (selectedIndex <= 0)
|
||||
{
|
||||
UpdateSelectedAddress(selectedAddress - 4);
|
||||
selectedIndex = displayTypeVisualWidth - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedIndex--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectedIndex >= displayTypeVisualWidth - 1)
|
||||
{
|
||||
UpdateSelectedAddress(selectedAddress - 4);
|
||||
selectedIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(selectedNibbleHI = !selectedNibbleHI))
|
||||
if (!littleEndian)
|
||||
{
|
||||
// It works
|
||||
if ((selectedAddress & (static_cast<u32>(displayType) - 1)) == (static_cast<u32>(displayType) - 1))
|
||||
UpdateSelectedAddress(selectedAddress - (static_cast<s32>(displayType) * 2 - 1));
|
||||
else
|
||||
UpdateSelectedAddress(selectedAddress + 1);
|
||||
if (!(selectedNibbleHI = !selectedNibbleHI))
|
||||
UpdateSelectedAddress(selectedAddress - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(selectedNibbleHI = !selectedNibbleHI))
|
||||
{
|
||||
// It works
|
||||
if ((selectedAddress & (static_cast<u32>(displayTypeWidth) - 1)) == (static_cast<u32>(displayTypeWidth) - 1))
|
||||
UpdateSelectedAddress(selectedAddress - (displayTypeVisualWidth - 1));
|
||||
else
|
||||
UpdateSelectedAddress(selectedAddress + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -430,12 +607,15 @@ bool MemoryViewTable::KeyPress(int key, QChar keychar, DebugInterface& cpu)
|
||||
|
||||
if (keyCharIsText)
|
||||
{
|
||||
// Check if key pressed is hex before insertion (QString conversion fails otherwise)
|
||||
const u8 keyPressed = static_cast<u8>(QString(QChar(key)).toInt(&pressHandled, 16));
|
||||
if (pressHandled)
|
||||
if (displayType != MemoryViewType::FLOAT)
|
||||
{
|
||||
InsertIntoSelectedHexView(keyPressed, cpu);
|
||||
ForwardSelection();
|
||||
// Check if key pressed is hex before insertion (QString conversion fails otherwise)
|
||||
const u8 keyPressed = static_cast<u8>(QString(QChar(key)).toInt(&pressHandled, 16));
|
||||
if (pressHandled)
|
||||
{
|
||||
InsertIntoSelectedHexView(keyPressed, cpu);
|
||||
ForwardSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,6 +635,13 @@ bool MemoryViewTable::KeyPress(int key, QChar keychar, DebugInterface& cpu)
|
||||
BackwardSelection();
|
||||
pressHandled = true;
|
||||
break;
|
||||
case Qt::Key::Key_Return:
|
||||
case Qt::Key::Key_Enter:
|
||||
if (displayType == MemoryViewType::FLOAT)
|
||||
{
|
||||
pressHandled = InsertFloatIntoSelectedHexView(cpu);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -549,7 +736,8 @@ bool MemoryView::fromJson(const JsonValueWrapper& json)
|
||||
if (type == MemoryViewType::BYTE ||
|
||||
type == MemoryViewType::BYTEHW ||
|
||||
type == MemoryViewType::WORD ||
|
||||
type == MemoryViewType::DWORD)
|
||||
type == MemoryViewType::DWORD ||
|
||||
type == MemoryViewType::FLOAT)
|
||||
m_table.SetViewType(type);
|
||||
}
|
||||
|
||||
@@ -647,6 +835,12 @@ void MemoryView::openContextMenu(QPoint pos)
|
||||
connect(dword_action, &QAction::triggered, this, [this]() { m_table.SetViewType(MemoryViewType::DWORD); });
|
||||
view_type_group->addAction(dword_action);
|
||||
|
||||
QAction* float_action = menu->addAction(tr("Show as float"));
|
||||
float_action->setCheckable(true);
|
||||
float_action->setChecked(current_view_type == MemoryViewType::FLOAT);
|
||||
connect(float_action, &QAction::triggered, this, [this]() { m_table.SetViewType(MemoryViewType::FLOAT); });
|
||||
view_type_group->addAction(float_action);
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
createEventActions<DebuggerEvents::AddToSavedAddresses>(menu, [this]() {
|
||||
@@ -655,9 +849,16 @@ void MemoryView::openContextMenu(QPoint pos)
|
||||
return std::optional(event);
|
||||
});
|
||||
|
||||
connect(menu->addAction(tr("Copy Byte")), &QAction::triggered, this, &MemoryView::contextCopyByte);
|
||||
QAction* copy_byte_action = menu->addAction(tr("Copy Byte"));
|
||||
copy_byte_action->setEnabled(current_view_type != MemoryViewType::FLOAT);
|
||||
connect(copy_byte_action, &QAction::triggered, this, &MemoryView::contextCopyByte);
|
||||
|
||||
connect(menu->addAction(tr("Copy Segment")), &QAction::triggered, this, &MemoryView::contextCopySegment);
|
||||
connect(menu->addAction(tr("Copy Character")), &QAction::triggered, this, &MemoryView::contextCopyCharacter);
|
||||
|
||||
QAction* copy_char_action = menu->addAction(tr("Copy Character"));
|
||||
copy_char_action->setEnabled(current_view_type != MemoryViewType::FLOAT);
|
||||
connect(copy_char_action, &QAction::triggered, this, &MemoryView::contextCopyCharacter);
|
||||
|
||||
connect(menu->addAction(tr("Paste")), &QAction::triggered, this, &MemoryView::contextPaste);
|
||||
|
||||
menu->popup(this->mapToGlobal(pos));
|
||||
@@ -673,7 +874,17 @@ void MemoryView::contextCopyByte()
|
||||
|
||||
void MemoryView::contextCopySegment()
|
||||
{
|
||||
QApplication::clipboard()->setText(QString::number(m_table.GetSelectedSegment(cpu()).lo, 16).toUpper());
|
||||
if (m_table.GetViewType() == MemoryViewType::FLOAT)
|
||||
{
|
||||
u32 intVal = m_table.GetSelectedSegment(cpu()).lo;
|
||||
float val = 0;
|
||||
std::memcpy(&val, &intVal, sizeof(val));
|
||||
QApplication::clipboard()->setText(QString::number(val, 'g'));
|
||||
}
|
||||
else
|
||||
{
|
||||
QApplication::clipboard()->setText(QString::number(m_table.GetSelectedSegment(cpu()).lo, 16).toUpper());
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryView::contextCopyCharacter()
|
||||
|
||||
@@ -20,10 +20,27 @@
|
||||
|
||||
enum class MemoryViewType
|
||||
{
|
||||
BYTE = 1,
|
||||
BYTEHW = 2,
|
||||
WORD = 4,
|
||||
DWORD = 8,
|
||||
BYTE = 0,
|
||||
BYTEHW = 1,
|
||||
WORD = 2,
|
||||
DWORD = 3,
|
||||
FLOAT = 4,
|
||||
};
|
||||
|
||||
const s32 MemoryViewTypeWidth[] = {
|
||||
1, // BYTE
|
||||
2, // BYTEHW
|
||||
4, // WORD
|
||||
8, // DWORD
|
||||
4, // FLOAT
|
||||
};
|
||||
|
||||
const s32 MemoryViewTypeVisualWidth[] = {
|
||||
2, // BYTE
|
||||
4, // BYTEHW
|
||||
8, // WORD
|
||||
16, // DWORD
|
||||
14, // FLOAT
|
||||
};
|
||||
|
||||
class MemoryViewTable : public QObject
|
||||
@@ -48,6 +65,7 @@ private:
|
||||
bool selectedNibbleHI = false;
|
||||
|
||||
void InsertIntoSelectedHexView(u8 value, DebugInterface& cpu);
|
||||
bool InsertFloatIntoSelectedHexView(DebugInterface& cpu);
|
||||
|
||||
template <class T>
|
||||
T convertEndian(T in)
|
||||
@@ -73,6 +91,7 @@ public:
|
||||
|
||||
u32 startAddress;
|
||||
u32 selectedAddress;
|
||||
s32 selectedIndex;
|
||||
|
||||
void UpdateStartAddress(u32 start);
|
||||
void UpdateSelectedAddress(u32 selected, bool page = false);
|
||||
|
||||
@@ -131,6 +131,10 @@ namespace
|
||||
// Fetch icon pixmap
|
||||
const QRect r = option.rect;
|
||||
const QPixmap pix = qvariant_cast<QPixmap>(index.data(Qt::DecorationRole));
|
||||
|
||||
if (pix.isNull())
|
||||
return;
|
||||
|
||||
const int pix_width = static_cast<int>(pix.width() / pix.devicePixelRatio());
|
||||
const int pix_height = static_cast<int>(pix.height() / pix.devicePixelRatio());
|
||||
|
||||
|
||||
@@ -1162,12 +1162,20 @@ bool MainWindow::shouldAbortForMemcardBusy(const VMLock& lock)
|
||||
{
|
||||
if (MemcardBusy::IsBusy() && !GSDumpReplayer::IsReplayingDump())
|
||||
{
|
||||
const QMessageBox::StandardButton res = QMessageBox::critical(
|
||||
lock.getDialogParent(),
|
||||
tr("WARNING: Memory Card Busy"),
|
||||
tr("WARNING: Your memory card is still writing data. Shutting down now <b>WILL IRREVERSIBLY DESTROY YOUR MEMORY CARD.</b> It is strongly recommended to resume your game and let it finish writing to your memory card.<br><br>Do you wish to shutdown anyways and <b>IRREVERSIBLY DESTROY YOUR MEMORY CARD?</b>"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||
QMessageBox msgbox(lock.getDialogParent());
|
||||
msgbox.setIcon(QMessageBox::Warning);
|
||||
msgbox.setWindowTitle(tr("WARNING: Memory Card Busy"));
|
||||
msgbox.setWindowIcon(QtHost::GetAppIcon());
|
||||
msgbox.setWindowModality(Qt::WindowModal);
|
||||
msgbox.setTextFormat(Qt::RichText);
|
||||
msgbox.setText(tr("Your memory card is still saving data."));
|
||||
msgbox.setInformativeText(tr("WARNING: Shutting down now can <b>IRREVERSIBLY CORRUPT YOUR MEMORY CARD.</b><br><br>"
|
||||
"You are strongly advised to select 'No' and let the save finish.<br><br>"
|
||||
"Do you want to shutdown anyway and <b>IRREVERSIBLY CORRUPT YOUR MEMORY CARD</b>?"));
|
||||
msgbox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgbox.setDefaultButton(QMessageBox::No);
|
||||
|
||||
if (res != QMessageBox::Yes)
|
||||
if (msgbox.exec() != QMessageBox::Yes)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -879,38 +879,6 @@ void EmuThread::endCapture()
|
||||
MTGS::RunOnGSThread(&GSEndCapture);
|
||||
}
|
||||
|
||||
void EmuThread::setAudioOutputVolume(int volume, int fast_forward_volume)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "setAudioOutputVolume", Qt::QueuedConnection, Q_ARG(int, volume),
|
||||
Q_ARG(int, fast_forward_volume));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
EmuConfig.SPU2.OutputVolume = static_cast<u32>(volume);
|
||||
EmuConfig.SPU2.FastForwardVolume = static_cast<u32>(fast_forward_volume);
|
||||
SPU2::SetOutputVolume(SPU2::GetResetVolume());
|
||||
}
|
||||
|
||||
void EmuThread::setAudioOutputMuted(bool muted)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "setAudioOutputMuted", Qt::QueuedConnection, Q_ARG(bool, muted));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
EmuConfig.SPU2.OutputMuted = muted;
|
||||
SPU2::SetOutputVolume(SPU2::GetResetVolume());
|
||||
}
|
||||
|
||||
std::optional<WindowInfo> EmuThread::acquireRenderWindow(bool recreate_window)
|
||||
{
|
||||
// Check if we're wanting to get exclusive fullscreen. This should be safe to read, since we're going to be calling from the GS thread.
|
||||
|
||||
@@ -112,8 +112,6 @@ public Q_SLOTS:
|
||||
void queueSnapshot(quint32 gsdump_frames);
|
||||
void beginCapture(const QString& path);
|
||||
void endCapture();
|
||||
void setAudioOutputVolume(int volume, int fast_forward_volume);
|
||||
void setAudioOutputMuted(bool muted);
|
||||
|
||||
Q_SIGNALS:
|
||||
bool messageConfirmed(const QString& title, const QString& message);
|
||||
|
||||
@@ -73,21 +73,21 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* settings_dialog, QWidge
|
||||
// for per-game, just use the normal path, since it needs to re-read/apply
|
||||
if (!dialog()->isPerGameSettings())
|
||||
{
|
||||
m_ui.volume->setValue(dialog()->getEffectiveIntValue("SPU2/Output", "OutputVolume", 100));
|
||||
m_ui.standardVolume->setValue(dialog()->getEffectiveIntValue("SPU2/Output", "StandardVolume", 100));
|
||||
m_ui.fastForwardVolume->setValue(dialog()->getEffectiveIntValue("SPU2/Output", "FastForwardVolume", 100));
|
||||
m_ui.muted->setChecked(dialog()->getEffectiveBoolValue("SPU2/Output", "OutputMuted", false));
|
||||
connect(m_ui.volume, &QSlider::valueChanged, this, &AudioSettingsWidget::onOutputVolumeChanged);
|
||||
connect(m_ui.standardVolume, &QSlider::valueChanged, this, &AudioSettingsWidget::onStandardVolumeChanged);
|
||||
connect(m_ui.fastForwardVolume, &QSlider::valueChanged, this, &AudioSettingsWidget::onFastForwardVolumeChanged);
|
||||
connect(m_ui.muted, &QCheckBox::checkStateChanged, this, &AudioSettingsWidget::onOutputMutedChanged);
|
||||
updateVolumeLabel();
|
||||
}
|
||||
else
|
||||
{
|
||||
SettingWidgetBinder::BindWidgetAndLabelToIntSetting(sif, m_ui.volume, m_ui.volumeLabel, tr("%"), "SPU2/Output", "OutputVolume", 100);
|
||||
SettingWidgetBinder::BindWidgetAndLabelToIntSetting(sif, m_ui.standardVolume, m_ui.standardVolumeLabel, tr("%"), "SPU2/Output", "StandardVolume", 100);
|
||||
SettingWidgetBinder::BindWidgetAndLabelToIntSetting(sif, m_ui.fastForwardVolume, m_ui.fastForwardVolumeLabel, tr("%"), "SPU2/Output", "FastForwardVolume", 100);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.muted, "SPU2/Output", "OutputMuted", false);
|
||||
}
|
||||
connect(m_ui.resetVolume, &QToolButton::clicked, this, [this]() { resetVolume(false); });
|
||||
connect(m_ui.resetStandardVolume, &QToolButton::clicked, this, [this]() { resetVolume(false); });
|
||||
connect(m_ui.resetFastForwardVolume, &QToolButton::clicked, this, [this]() { resetVolume(true); });
|
||||
|
||||
dialog()->registerWidgetHelp(
|
||||
@@ -103,8 +103,8 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* settings_dialog, QWidge
|
||||
m_ui.outputLatencyMS, tr("Output Latency"), tr("%1 ms").arg(AudioStreamParameters::DEFAULT_OUTPUT_LATENCY_MS),
|
||||
tr("Determines the latency from the buffer to the host audio output. This can be set lower than the target latency "
|
||||
"to reduce audio delay."));
|
||||
dialog()->registerWidgetHelp(m_ui.volume, tr("Output Volume"), "100%",
|
||||
tr("Controls the volume of the audio played on the host."));
|
||||
dialog()->registerWidgetHelp(m_ui.standardVolume, tr("Standard Volume"), "100%",
|
||||
tr("Controls the volume of the audio played on the host at normal speed."));
|
||||
dialog()->registerWidgetHelp(m_ui.fastForwardVolume, tr("Fast Forward Volume"), "100%",
|
||||
tr("Controls the volume of the audio played on the host when fast forwarding."));
|
||||
dialog()->registerWidgetHelp(m_ui.muted, tr("Mute All Sound"), tr("Unchecked"),
|
||||
@@ -118,9 +118,9 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* settings_dialog, QWidge
|
||||
tr("When running outside of 100% speed, adjusts the tempo on audio instead of dropping frames. Produces much nicer fast-forward/slowdown audio."));
|
||||
dialog()->registerWidgetHelp(m_ui.stretchSettings, tr("Stretch Settings"), tr("N/A"),
|
||||
tr("These settings fine-tune the behavior of the SoundTouch audio time stretcher when running outside of 100% speed."));
|
||||
dialog()->registerWidgetHelp(m_ui.resetVolume, tr("Reset Volume"), tr("N/A"),
|
||||
dialog()->isPerGameSettings() ? tr("Resets output volume back to the global/inherited setting.") :
|
||||
tr("Resets output volume back to the default."));
|
||||
dialog()->registerWidgetHelp(m_ui.resetStandardVolume, tr("Reset Standard Volume"), tr("N/A"),
|
||||
dialog()->isPerGameSettings() ? tr("Resets standard volume back to the global/inherited setting.") :
|
||||
tr("Resets standard volume back to the default."));
|
||||
dialog()->registerWidgetHelp(m_ui.resetFastForwardVolume, tr("Reset Fast Forward Volume"), tr("N/A"),
|
||||
dialog()->isPerGameSettings() ? tr("Resets fast forward volume back to the global/inherited setting.") :
|
||||
tr("Resets fast forward volume back to the default."));
|
||||
@@ -292,7 +292,7 @@ void AudioSettingsWidget::updateLatencyLabel()
|
||||
|
||||
void AudioSettingsWidget::updateVolumeLabel()
|
||||
{
|
||||
m_ui.volumeLabel->setText(tr("%1%").arg(m_ui.volume->value()));
|
||||
m_ui.standardVolumeLabel->setText(tr("%1%").arg(m_ui.standardVolume->value()));
|
||||
m_ui.fastForwardVolumeLabel->setText(tr("%1%").arg(m_ui.fastForwardVolume->value()));
|
||||
}
|
||||
|
||||
@@ -303,18 +303,18 @@ void AudioSettingsWidget::onMinimalOutputLatencyChanged()
|
||||
updateLatencyLabel();
|
||||
}
|
||||
|
||||
void AudioSettingsWidget::onOutputVolumeChanged(int new_value)
|
||||
void AudioSettingsWidget::onStandardVolumeChanged(const int new_value)
|
||||
{
|
||||
// only called for base settings
|
||||
pxAssert(!dialog()->isPerGameSettings());
|
||||
Host::SetBaseIntSettingValue("SPU2/Output", "OutputVolume", new_value);
|
||||
Host::SetBaseIntSettingValue("SPU2/Output", "StandardVolume", new_value);
|
||||
Host::CommitBaseSettingChanges();
|
||||
g_emu_thread->applySettings();
|
||||
|
||||
updateVolumeLabel();
|
||||
}
|
||||
|
||||
void AudioSettingsWidget::onFastForwardVolumeChanged(int new_value)
|
||||
void AudioSettingsWidget::onFastForwardVolumeChanged(const int new_value)
|
||||
{
|
||||
// only called for base settings
|
||||
pxAssert(!dialog()->isPerGameSettings());
|
||||
@@ -325,7 +325,7 @@ void AudioSettingsWidget::onFastForwardVolumeChanged(int new_value)
|
||||
updateVolumeLabel();
|
||||
}
|
||||
|
||||
void AudioSettingsWidget::onOutputMutedChanged(int new_state)
|
||||
void AudioSettingsWidget::onOutputMutedChanged(const int new_state)
|
||||
{
|
||||
// only called for base settings
|
||||
pxAssert(!dialog()->isPerGameSettings());
|
||||
@@ -478,11 +478,11 @@ void AudioSettingsWidget::onStretchSettingsClicked()
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void AudioSettingsWidget::resetVolume(bool fast_forward)
|
||||
void AudioSettingsWidget::resetVolume(const bool fast_forward)
|
||||
{
|
||||
const char* key = fast_forward ? "FastForwardVolume" : "OutputVolume";
|
||||
QSlider* const slider = fast_forward ? m_ui.fastForwardVolume : m_ui.volume;
|
||||
QLabel* const label = fast_forward ? m_ui.fastForwardVolumeLabel : m_ui.volumeLabel;
|
||||
const char* key = fast_forward ? "FastForwardVolume" : "StandardVolume";
|
||||
QSlider* const slider = fast_forward ? m_ui.fastForwardVolume : m_ui.standardVolume;
|
||||
QLabel* const label = fast_forward ? m_ui.fastForwardVolumeLabel : m_ui.standardVolumeLabel;
|
||||
|
||||
if (dialog()->isPerGameSettings())
|
||||
{
|
||||
|
||||
@@ -27,9 +27,9 @@ private Q_SLOTS:
|
||||
void updateLatencyLabel();
|
||||
void updateVolumeLabel();
|
||||
void onMinimalOutputLatencyChanged();
|
||||
void onOutputVolumeChanged(int new_value);
|
||||
void onFastForwardVolumeChanged(int new_value);
|
||||
void onOutputMutedChanged(int new_state);
|
||||
void onStandardVolumeChanged(const int new_value);
|
||||
void onFastForwardVolumeChanged(const int new_value);
|
||||
void onOutputMutedChanged(const int new_state);
|
||||
|
||||
void onExpansionSettingsClicked();
|
||||
void onStretchSettingsClicked();
|
||||
@@ -38,7 +38,7 @@ private:
|
||||
AudioBackend getEffectiveBackend() const;
|
||||
AudioExpansionMode getEffectiveExpansionMode() const;
|
||||
u32 getEffectiveExpansionBlockSize() const;
|
||||
void resetVolume(bool fast_forward);
|
||||
void resetVolume(const bool fast_forward);
|
||||
|
||||
Ui::AudioSettingsWidget m_ui;
|
||||
u32 m_output_device_latency = 0;
|
||||
|
||||
@@ -219,14 +219,14 @@
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Output Volume:</string>
|
||||
<string>Standard Volume:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSlider" name="volume">
|
||||
<widget class="QSlider" name="standardVolume">
|
||||
<property name="maximum">
|
||||
<number>200</number>
|
||||
</property>
|
||||
@@ -245,7 +245,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="volumeLabel">
|
||||
<widget class="QLabel" name="standardVolumeLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -261,9 +261,9 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="resetVolume">
|
||||
<widget class="QToolButton" name="resetStandardVolume">
|
||||
<property name="toolTip">
|
||||
<string>Reset Volume</string>
|
||||
<string>Reset Standard Volume</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="restart-line"/>
|
||||
|
||||
@@ -71,15 +71,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
|
||||
setupTab(m_capture, tr("Media Capture"));
|
||||
m_advanced_tab = setupTab(m_advanced, tr("Advanced"));
|
||||
|
||||
#ifndef PCSX2_DEVBUILD
|
||||
if (!dialog()->isPerGameSettings())
|
||||
{
|
||||
// We removed hardware fixes from global settings, but people in the past did set this stuff globally.
|
||||
// So, just reset it all. We can remove this code at some point in the future.
|
||||
resetManualHardwareFixes();
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Display Settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -548,9 +539,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
|
||||
|
||||
dialog()->registerWidgetHelp(m_hw.blending, tr("Blending Accuracy"), tr("Basic (Recommended)"),
|
||||
tr("Control the accuracy level of the GS blending unit emulation.<br> "
|
||||
"The higher the setting, the more blending is emulated in the shader accurately, and the higher the speed penalty will "
|
||||
"be.<br> "
|
||||
"Note that Direct3D 12's blending is reduced in capability compared to OpenGL/Vulkan/Direct3D 11."));
|
||||
"The higher the setting, the more blending is emulated in the shader accurately, and the higher the speed penalty will be."));
|
||||
|
||||
dialog()->registerWidgetHelp(m_advanced.texturePreloading, tr("Texture Preloading"), tr("Full (Hash Cache)"),
|
||||
tr("Uploads entire textures at once instead of in small pieces, avoiding redundant uploads when possible. "
|
||||
@@ -1115,7 +1104,7 @@ void GraphicsSettingsWidget::updateRendererDependentOptions()
|
||||
const bool is_software = (type == GSRendererType::SW);
|
||||
const bool is_auto = (type == GSRendererType::Auto);
|
||||
const bool is_vk = (type == GSRendererType::VK);
|
||||
const bool is_disable_barriers = (type == GSRendererType::DX12 || type == GSRendererType::Metal || type == GSRendererType::SW);
|
||||
const bool is_disable_barriers = (type == GSRendererType::Metal || type == GSRendererType::SW);
|
||||
const bool hw_fixes = (is_hardware && m_hw.enableHWFixes && m_hw.enableHWFixes->checkState() == Qt::Checked);
|
||||
|
||||
QWidget* prev_tab;
|
||||
@@ -1317,58 +1306,3 @@ void GraphicsSettingsWidget::onUpscaleMultiplierChanged()
|
||||
dialog()->setFloatSettingValue("EmuCore/GS", "upscale_multiplier",
|
||||
data.isValid() ? std::optional<float>(data.toFloat()) : std::optional<float>());
|
||||
}
|
||||
|
||||
void GraphicsSettingsWidget::resetManualHardwareFixes()
|
||||
{
|
||||
bool changed = false;
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
SettingsInterface* const si = Host::Internal::GetBaseSettingsLayer();
|
||||
|
||||
auto check_bool = [&](const char* section, const char* key, bool expected) {
|
||||
if (si->GetBoolValue(section, key, expected) != expected)
|
||||
{
|
||||
si->SetBoolValue(section, key, expected);
|
||||
changed = true;
|
||||
}
|
||||
};
|
||||
auto check_int = [&](const char* section, const char* key, s32 expected) {
|
||||
if (si->GetIntValue(section, key, expected) != expected)
|
||||
{
|
||||
si->SetIntValue(section, key, expected);
|
||||
changed = true;
|
||||
}
|
||||
};
|
||||
|
||||
check_bool("EmuCore/GS", "UserHacks", false);
|
||||
|
||||
check_int("EmuCore/GS", "UserHacks_CPUSpriteRenderBW", 0);
|
||||
check_int("EmuCore/GS", "UserHacks_CPUCLUTRender", 0);
|
||||
check_int("EmuCore/GS", "UserHacks_GPUTargetCLUTMode", 0);
|
||||
check_int("EmuCore/GS", "UserHacks_SkipDraw_Start", 0);
|
||||
check_int("EmuCore/GS", "UserHacks_SkipDraw_End", 0);
|
||||
check_bool("EmuCore/GS", "UserHacks_AutoFlush", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_CPU_FB_Conversion", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_DisableDepthSupport", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_Disable_Safe_Features", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_DisableRenderFixes", false);
|
||||
check_bool("EmuCore/GS", "preload_frame_with_gs_data", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
|
||||
check_int("EmuCore/GS", "UserHacks_TextureInsideRt", static_cast<int>(GSTextureInRtMode::Disabled));
|
||||
check_bool("EmuCore/GS", "UserHacks_ReadTCOnClose", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_EstimateTextureRegion", false);
|
||||
check_bool("EmuCore/GS", "paltex", false);
|
||||
check_int("EmuCore/GS", "UserHacks_HalfPixelOffset", 0);
|
||||
check_int("EmuCore/GS", "UserHacks_native_scaling", static_cast<int>(GSNativeScaling::Off));
|
||||
check_int("EmuCore/GS", "UserHacks_round_sprite_offset", 0);
|
||||
check_int("EmuCore/GS", "UserHacks_TCOffsetX", 0);
|
||||
check_int("EmuCore/GS", "UserHacks_TCOffsetY", 0);
|
||||
check_bool("EmuCore/GS", "UserHacks_align_sprite_X", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_merge_pp_sprite", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_ForceEvenSpritePosition", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_BilinearHack", false);
|
||||
}
|
||||
|
||||
if (changed)
|
||||
Host::CommitBaseSettingChanges();
|
||||
}
|
||||
|
||||
@@ -60,7 +60,6 @@ private:
|
||||
GSRendererType getEffectiveRenderer() const;
|
||||
void updateRendererDependentOptions();
|
||||
void populateUpscaleMultipliers(u32 max_upscale_multiplier);
|
||||
void resetManualHardwareFixes();
|
||||
|
||||
Ui::GraphicsSettingsHeader m_header;
|
||||
Ui::GraphicsDisplaySettingsTab m_display;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1028,7 +1028,7 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
|
||||
|
||||
if (const std::string_view badge_name = info->badge_name; !badge_name.empty())
|
||||
{
|
||||
s_game_icon = Path::Combine(s_image_directory, fmt::format("game_{}.png", info->id));
|
||||
s_game_icon = Path::Combine(s_image_directory, fmt::format("game_{}.png", badge_name));
|
||||
if (!s_game_icon.empty() && !s_game_icon_url.empty() && !FileSystem::FileExists(s_game_icon.c_str()))
|
||||
DownloadImage(s_game_icon_url, s_game_icon);
|
||||
}
|
||||
@@ -1633,16 +1633,16 @@ void Achievements::SaveState(SaveStateBase& writer)
|
||||
|
||||
std::string Achievements::GetAchievementBadgePath(const rc_client_achievement_t* achievement, int state)
|
||||
{
|
||||
static constexpr std::array<const char*, NUM_RC_CLIENT_ACHIEVEMENT_STATES> s_achievement_state_strings = {
|
||||
{"inactive", "active", "unlocked", "disabled"}};
|
||||
|
||||
std::string path;
|
||||
|
||||
if (achievement->badge_name[0] == 0)
|
||||
const std::string_view badge_name(achievement->badge_name);
|
||||
if (badge_name.empty())
|
||||
return path;
|
||||
|
||||
const std::string_view suffix = state == RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED ? "" : "_lock";
|
||||
|
||||
path = Path::Combine(s_image_directory,
|
||||
TinyString::from_format("achievement_{}_{}_{}.png", s_game_id, achievement->id, s_achievement_state_strings[state]));
|
||||
TinyString::from_format("achievement_{}{}.png", badge_name, suffix));
|
||||
|
||||
if (!FileSystem::FileExists(path.c_str()))
|
||||
{
|
||||
|
||||
@@ -942,7 +942,7 @@ struct Pcsx2Config
|
||||
VisualDebugEnabled : 1;
|
||||
BITFIELD_END
|
||||
|
||||
u32 OutputVolume = 100;
|
||||
u32 StandardVolume = 100;
|
||||
u32 FastForwardVolume = 100;
|
||||
bool OutputMuted = false;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user