Compare commits
91 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4654a3ef6c | ||
|
|
9996061f74 | ||
|
|
247a4c40d1 | ||
|
|
1ffbdd9c08 | ||
|
|
f67c0cbd2e | ||
|
|
ff7cc0867b | ||
|
|
ac1a6d3348 | ||
|
|
582bba6c91 | ||
|
|
aaf156478e | ||
|
|
0539c177ab | ||
|
|
fb1323b72f | ||
|
|
dc557dd0e5 | ||
|
|
2d0cfc9c2c | ||
|
|
625a25cd50 | ||
|
|
b8a29d1cd8 | ||
|
|
0fabdf9a01 | ||
|
|
9c3ae795c8 | ||
|
|
de26226fa1 | ||
|
|
121920c074 | ||
|
|
05e19470b2 | ||
|
|
b6680e4aca | ||
|
|
f9d70af841 | ||
|
|
7587581d1f | ||
|
|
8f19976c10 | ||
|
|
8567d68433 | ||
|
|
6542301566 | ||
|
|
a359f77cf6 | ||
|
|
4c9a81f3d8 | ||
|
|
9234b493a3 | ||
|
|
f84425b67c | ||
|
|
8a0c1874dd | ||
|
|
fa23628ae2 | ||
|
|
8a594e673d | ||
|
|
92b9390c51 | ||
|
|
c5c5b2a7b9 | ||
|
|
32a9d0e48b | ||
|
|
80a961bb25 | ||
|
|
d4e227286e | ||
|
|
ba705c8c24 | ||
|
|
b6ae4b173e | ||
|
|
23a28be346 | ||
|
|
a0e24dd36f | ||
|
|
a2cde5e17b | ||
|
|
ecc46e9294 | ||
|
|
20b1190d47 | ||
|
|
29b736bcf7 | ||
|
|
a48bc76ca6 | ||
|
|
305c01cdfa | ||
|
|
88bbdf4696 | ||
|
|
afc11279a9 | ||
|
|
a3fb2a84d5 | ||
|
|
4db23e6677 | ||
|
|
5dd36a7969 | ||
|
|
35a3d0027e | ||
|
|
02789ebd86 | ||
|
|
dfd1846b93 | ||
|
|
872205abc6 | ||
|
|
c52cebd20a | ||
|
|
f449b54f87 | ||
|
|
ffcb6e2f6f | ||
|
|
5daa1aa115 | ||
|
|
1dc009f752 | ||
|
|
009b4ff5e7 | ||
|
|
f1a947af92 | ||
|
|
97c098b1ff | ||
|
|
e252cb6643 | ||
|
|
75c0236e1e | ||
|
|
9c4a98bc25 | ||
|
|
9cba11cde5 | ||
|
|
fac5512b04 | ||
|
|
ed9bf05971 | ||
|
|
19d0f3bdc5 | ||
|
|
2abe53de43 | ||
|
|
37a25750d7 | ||
|
|
d3e288447f | ||
|
|
4a44d2668c | ||
|
|
752b1420a3 | ||
|
|
71705fc91f | ||
|
|
645efc7520 | ||
|
|
b6ee0e5219 | ||
|
|
7acf32debc | ||
|
|
13397f68a3 | ||
|
|
79250722d6 | ||
|
|
04b8748a8f | ||
|
|
2dab8053ea | ||
|
|
f8bab2e465 | ||
|
|
46221a8500 | ||
|
|
8b0e61af8c | ||
|
|
2b0a78811a | ||
|
|
5798cd7176 | ||
|
|
5c25637381 |
1
.github/workflows/cron_publish_flatpak.yml
vendored
@@ -10,6 +10,7 @@ jobs:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Check if release is needed"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 180
|
||||
outputs:
|
||||
PCSX2_RELEASE: ${{ steps.getinfo.outputs.PCSX2_RELEASE }}
|
||||
FLATHUB_RELEASE: ${{ steps.getinfo.outputs.FLATHUB_RELEASE }}
|
||||
|
||||
2
.github/workflows/linux_build_qt.yml
vendored
@@ -55,7 +55,7 @@ jobs:
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_COMPRESS: true
|
||||
CCACHE_COMPRESSLEVEL: 9
|
||||
CCACHE_MAXSIZE: 100M
|
||||
CCACHE_MAXSIZE: 500M
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
|
||||
42
.github/workflows/macos_build.yml
vendored
@@ -25,6 +25,10 @@ on:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
sign_and_notarize:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
build_macos:
|
||||
@@ -38,7 +42,9 @@ jobs:
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_COMPRESS: true
|
||||
CCACHE_COMPRESSLEVEL: 9
|
||||
CCACHE_MAXSIZE: 100M
|
||||
CCACHE_MAXSIZE: 500M
|
||||
# Only way to use a secret in an if statement
|
||||
SIGN_KEY: ${{ secrets.APPLE_SIGN_P12_B64 }}
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
@@ -143,6 +149,38 @@ jobs:
|
||||
run: make -j$(getconf _NPROCESSORS_ONLN) unittests
|
||||
|
||||
- name: Prepare Build Artifacts
|
||||
run: |
|
||||
mv build/pcsx2*/PCSX2.app PCSX2.app
|
||||
|
||||
- name: Pull the Signing Keys and Notarization Credentials
|
||||
if: ${{ inputs.sign_and_notarize == true && env.SIGN_KEY }}
|
||||
run: |
|
||||
echo "${{ secrets.APPLE_SIGN_P12_B64 }}" | base64 -d > cert.p12
|
||||
echo "${{ secrets.APPLE_APPSTORECONNECT_CFG }}" | base64 -d > key.json
|
||||
|
||||
- name: Sign the Application
|
||||
if: ${{ inputs.sign_and_notarize == true && env.SIGN_KEY }}
|
||||
uses: indygreg/apple-code-sign-action@v1.1
|
||||
with:
|
||||
input_path: 'PCSX2.app'
|
||||
p12_file: cert.p12
|
||||
p12_password: "${{ secrets.APPLE_SIGN_P12_PASS }}"
|
||||
sign_args: |
|
||||
--for-notarization
|
||||
--code-signature-flags=runtime
|
||||
--entitlements-xml-file=pcsx2/Resources/PCSX2.entitlements
|
||||
notarize: true
|
||||
# max_wait_seconds is only present on my fork located at F0bes/apple-code-sign-action@demo4
|
||||
# If we are timing out we should switch to the newest upstream (if I get it upstreamed)
|
||||
# or use my fork.
|
||||
# max_wait_seconds: '2000'
|
||||
staple: true
|
||||
# Generated using rcodesign
|
||||
# Despite what the docs say, I found that this file is required and I had 0 luck
|
||||
# passing the issuer id, key, etc through arguments.
|
||||
app_store_connect_api_key_json_file: 'key.json'
|
||||
|
||||
- name: Zip Build Artifacts
|
||||
run: |
|
||||
TAG="$(git tag --points-at HEAD)"
|
||||
if [ -z "$TAG" ]; then
|
||||
@@ -150,7 +188,7 @@ jobs:
|
||||
else
|
||||
APPNAME="PCSX2-$TAG"
|
||||
fi
|
||||
mv build/pcsx2*/PCSX2.app "$APPNAME.app"
|
||||
mv PCSX2.app "$APPNAME.app"
|
||||
tar --options xz:compression-level=9 -cvJf "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" "$APPNAME.app"
|
||||
mkdir ci-artifacts
|
||||
cp "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" ci-artifacts/macOS.tar.xz
|
||||
|
||||
1
.github/workflows/macos_build_matrix.yml
vendored
@@ -16,4 +16,5 @@ jobs:
|
||||
with:
|
||||
jobName: "MacOS Build"
|
||||
artifactPrefixName: "PCSX2-macos-Qt"
|
||||
sign_and_notarize: true # If we find that notarization takes a long time we should disable that on PR builds
|
||||
secrets: inherit
|
||||
|
||||
3
.github/workflows/release_cut_new.yml
vendored
@@ -148,6 +148,7 @@ jobs:
|
||||
artifactPrefixName: "PCSX2-macos-Qt"
|
||||
fetchTags: true
|
||||
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
|
||||
sign_and_notarize: true
|
||||
secrets: inherit
|
||||
|
||||
# Upload the Artifacts
|
||||
@@ -204,7 +205,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 22
|
||||
|
||||
- name: Announce Release
|
||||
env:
|
||||
|
||||
25
.github/workflows/scripts/linux/appimage-qt.sh
vendored
@@ -63,9 +63,9 @@ declare -a REMOVE_LIBS=(
|
||||
|
||||
set -e
|
||||
|
||||
LINUXDEPLOY=./linuxdeploy-x86_64
|
||||
LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64
|
||||
APPIMAGETOOL=./appimagetool-x86_64
|
||||
LINUXDEPLOY=./linuxdeploy-x86_64.AppImage
|
||||
LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
APPIMAGETOOL=./appimagetool-x86_64.AppImage
|
||||
PATCHELF=patchelf
|
||||
|
||||
if [ ! -f "$LINUXDEPLOY" ]; then
|
||||
@@ -78,11 +78,8 @@ if [ ! -f "$LINUXDEPLOY_PLUGIN_QT" ]; then
|
||||
chmod +x "$LINUXDEPLOY_PLUGIN_QT"
|
||||
fi
|
||||
|
||||
# Using go-appimage
|
||||
# Backported from https://github.com/stenzek/duckstation/pull/3251
|
||||
if [ ! -f "$APPIMAGETOOL" ]; then
|
||||
APPIMAGETOOLURL=$(wget -q https://api.github.com/repos/probonopd/go-appimage/releases -O - | sed 's/[()",{} ]/\n/g' | grep -o 'https.*continuous.*tool.*86_64.*mage$' | head -1)
|
||||
"$PCSX2DIR/tools/retry.sh" wget -O "$APPIMAGETOOL" "$APPIMAGETOOLURL"
|
||||
"$PCSX2DIR/tools/retry.sh" wget -O "$APPIMAGETOOL" https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
chmod +x "$APPIMAGETOOL"
|
||||
fi
|
||||
|
||||
@@ -190,17 +187,6 @@ echo "Generating AppStream metainfo..."
|
||||
mkdir -p "$OUTDIR/usr/share/metainfo"
|
||||
"$SCRIPTDIR/generate-metainfo.sh" "$OUTDIR/usr/share/metainfo/net.pcsx2.PCSX2.appdata.xml"
|
||||
|
||||
# Copy in AppRun hooks.
|
||||
# Unfortunately linuxdeploy is a bit lame and doesn't let us provide our own AppRun hooks, instead
|
||||
# they have to come from plugins.. and screw writing one of those just to disable Wayland.
|
||||
echo "Copying AppRun hooks..."
|
||||
mkdir -p "$OUTDIR/apprun-hooks"
|
||||
for hookpath in "$SCRIPTDIR/apprun-hooks"/*; do
|
||||
hookname=$(basename "$hookpath")
|
||||
cp -v "$hookpath" "$OUTDIR/apprun-hooks/$hookname"
|
||||
sed -i -e 's/exec /source "$this_dir"\/apprun-hooks\/"'"$hookname"'"\nexec /' "$OUTDIR/AppRun"
|
||||
done
|
||||
|
||||
echo "Generating AppImage..."
|
||||
GIT_VERSION=$(git tag --points-at HEAD)
|
||||
|
||||
@@ -213,5 +199,4 @@ if [[ "${GIT_VERSION}" == "" ]]; then
|
||||
fi
|
||||
|
||||
rm -f "$NAME.AppImage"
|
||||
ARCH=x86_64 VERSION="${GIT_VERSION}" "$APPIMAGETOOL" -s "$OUTDIR" && mv ./*.AppImage "$NAME.AppImage"
|
||||
|
||||
$APPIMAGETOOL -v "$OUTDIR" "$NAME.AppImage"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
if [[ -z "$I_WANT_A_BROKEN_WAYLAND_UI" ]]; then
|
||||
echo "Forcing X11 instead of Wayland, due to various protocol limitations"
|
||||
echo "and Qt issues. If you want to use Wayland, launch PCSX2 with"
|
||||
echo "I_WANT_A_BROKEN_WAYLAND_UI=YES set."
|
||||
export QT_QPA_PLATFORM=xcb
|
||||
else
|
||||
echo "Wayland is not being disabled. Do not complain when things break."
|
||||
fi
|
||||
|
||||
@@ -19,9 +19,9 @@ LIBJPEG=9f
|
||||
LIBPNG=1.6.45
|
||||
LIBWEBP=1.5.0
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
SDL=SDL2-2.30.12
|
||||
SDL=SDL3-3.2.6
|
||||
QT=6.8.2
|
||||
ZSTD=1.5.6
|
||||
ZSTD=1.5.7
|
||||
|
||||
SHADERC=2024.1
|
||||
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
|
||||
@@ -37,8 +37,8 @@ fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
ac356ea55e8b9dd0b2d1fa27da40ef7e238267ccf9324704850d5d47375b48ea $SDL.tar.gz
|
||||
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
|
||||
096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
012043ce6d411e6e8a91fdc4e05e6bedcfa10fcb1347d3c33908f7fdd10dfe05 qtbase-everywhere-src-$QT.tar.xz
|
||||
d2a1bbb84707b8a0aec29227b170be00f04383fbf2361943596d09e7e443c8e1 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
aa2579f21ca66d19cbcf31d87e9067e07932635d36869c8239d4decd0a9dc1fa qtsvg-everywhere-src-$QT.tar.xz
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "sdl2",
|
||||
"name": "sdl3",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
@@ -14,8 +14,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://libsdl.org/release/SDL2-2.30.12.tar.gz",
|
||||
"sha256": "ac356ea55e8b9dd0b2d1fa27da40ef7e238267ccf9324704850d5d47375b48ea"
|
||||
"url": "https://libsdl.org/release/SDL3-3.2.6.tar.gz",
|
||||
"sha256": "096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
@@ -19,14 +19,14 @@
|
||||
"--device=all",
|
||||
"--share=network",
|
||||
"--share=ipc",
|
||||
"--socket=x11",
|
||||
"--socket=wayland",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=pulseaudio",
|
||||
"--talk-name=org.freedesktop.ScreenSaver",
|
||||
"--env=QT_QPA_PLATFORM=xcb"
|
||||
"--talk-name=org.freedesktop.ScreenSaver"
|
||||
],
|
||||
"modules": [
|
||||
"modules/10-libpcap.json",
|
||||
"modules/20-sdl2.json",
|
||||
"modules/20-sdl3.json",
|
||||
"modules/21-libbacktrace.json",
|
||||
"modules/22-shaderc.json",
|
||||
{
|
||||
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 2.3 MiB |
@@ -6,17 +6,21 @@
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0+</project_license>
|
||||
<name>PCSX2</name>
|
||||
<developer_name>PCSX2</developer_name>
|
||||
<summary>PlayStation 2 Emulator</summary>
|
||||
<developer id="net.pcsx2">
|
||||
<name>PCSX2 Team</name>
|
||||
</developer>
|
||||
<summary>PlayStation 2 emulator</summary>
|
||||
<description>
|
||||
<p>PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a combination of MIPS CPU Interpreters, Recompilers, and a Virtual Machine which manages hardware states and PS2 system memory. This allows you to play PS2 games on your PC, with many additional features and benefits.</p>
|
||||
<p>PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not affiliated in any way with Sony Interactive Entertainment.</p>
|
||||
</description>
|
||||
<url type="homepage">https://pcsx2.net/</url>
|
||||
<url type="vcs-browser">https://github.com/PCSX2/pcsx2</url>
|
||||
<url type="bugtracker">https://github.com/PCSX2/pcsx2/issues</url>
|
||||
<url type="donation">https://github.com/sponsors/PCSX2</url>
|
||||
<url type="faq">https://pcsx2.net/docs/</url>
|
||||
<url type="help">https://pcsx2.net/discord</url>
|
||||
<url type="contribute">https://github.com/PCSX2/pcsx2/blob/master/.github/CONTRIBUTING.md</url>
|
||||
<url type="translate">https://crowdin.com/project/pcsx2-emulator</url>
|
||||
<url type="contact">https://mastodon.social/@PCSX2</url>
|
||||
<screenshots>
|
||||
@@ -37,6 +41,26 @@
|
||||
</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<categories>
|
||||
<category>Game</category>
|
||||
<category>Emulator</category>
|
||||
</categories>
|
||||
<branding>
|
||||
<color type="primary" scheme_preference="light">#3584e4</color>
|
||||
<color type="primary" scheme_preference="dark">#241f31</color>
|
||||
</branding>
|
||||
<supports>
|
||||
<control>keyboard</control>
|
||||
<control>pointing</control>
|
||||
<internet>offline-only</internet>
|
||||
</supports>
|
||||
<recommends>
|
||||
<control>gamepad</control>
|
||||
<memory>8192</memory>
|
||||
</recommends>
|
||||
<requires>
|
||||
<display_length compare="ge">768</display_length>
|
||||
</requires>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<update_contact>pcsx2_AT_pcsx2.net</update_contact>
|
||||
<releases>
|
||||
|
||||
@@ -40,8 +40,8 @@ fi
|
||||
|
||||
FREETYPE=2.13.3
|
||||
HARFBUZZ=10.0.1
|
||||
SDL=SDL2-2.30.12
|
||||
ZSTD=1.5.6
|
||||
SDL=SDL3-3.2.6
|
||||
ZSTD=1.5.7
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
LIBPNG=1.6.45
|
||||
LIBJPEG=9f
|
||||
@@ -76,8 +76,8 @@ CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
|
||||
cat > SHASUMS <<EOF
|
||||
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
|
||||
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
|
||||
ac356ea55e8b9dd0b2d1fa27da40ef7e238267ccf9324704850d5d47375b48ea $SDL.tar.gz
|
||||
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
|
||||
096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
|
||||
|
||||
@@ -22,8 +22,8 @@ fi
|
||||
|
||||
FREETYPE=2.13.3
|
||||
HARFBUZZ=10.0.1
|
||||
SDL=SDL2-2.30.12
|
||||
ZSTD=1.5.6
|
||||
SDL=SDL3-3.2.6
|
||||
ZSTD=1.5.7
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
LIBPNG=1.6.45
|
||||
LIBJPEG=9f
|
||||
@@ -56,8 +56,8 @@ CMAKE_COMMON=(
|
||||
cat > SHASUMS <<EOF
|
||||
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
|
||||
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
|
||||
ac356ea55e8b9dd0b2d1fa27da40ef7e238267ccf9324704850d5d47375b48ea $SDL.tar.gz
|
||||
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
|
||||
096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
|
||||
|
||||
640
.github/workflows/scripts/releases/announce-release/package-lock.json
generated
vendored
@@ -10,8 +10,8 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"@octokit/plugin-throttling": "^9.4.0",
|
||||
"@octokit/rest": "^21.1.1",
|
||||
"discord.js": "^13.2.0"
|
||||
}
|
||||
},
|
||||
@@ -61,45 +61,102 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
|
||||
"integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
|
||||
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz",
|
||||
"integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/auth-token": "^5.0.0",
|
||||
"@octokit/graphql": "^8.1.2",
|
||||
"@octokit/request": "^9.2.1",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"before-after-hook": "^3.0.2",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/core/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"version": "10.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
|
||||
"integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/types": "^13.6.2",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/endpoint/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz",
|
||||
"integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/request": "^9.2.2",
|
||||
"@octokit/types": "^13.8.0",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/graphql/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
@@ -108,28 +165,75 @@
|
||||
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "2.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
|
||||
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
|
||||
"version": "11.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.2.tgz",
|
||||
"integrity": "sha512-BXJ7XPCTDXFF+wxcg/zscfgw2O/iDPtNSkwwR1W1W5c4Mb3zav/M2XvxQ23nVmKj7jpweB4g8viMeCQdm7LMVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.33.0"
|
||||
"@octokit/types": "^13.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-request-log": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-5.3.1.tgz",
|
||||
"integrity": "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=3"
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
|
||||
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
|
||||
"version": "13.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.1.tgz",
|
||||
"integrity": "sha512-o8uOBdsyR+WR8MK9Cco8dCgvG13H1RlM1nWnK/W7TEACQBFux/vPREgKucxUfuDQ5yi1T3hGf4C5ZmZXAERgwQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.33.0",
|
||||
"deprecation": "^2.3.1"
|
||||
"@octokit/types": "^13.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-retry": {
|
||||
@@ -142,49 +246,107 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.7.0.tgz",
|
||||
"integrity": "sha512-qrKT1Yl/KuwGSC6/oHpLBot3ooC9rq0/ryDYBCpkRtoj+R8T47xTMDT6Tk2CxWopFota/8Pi/2SqArqwC0JPow==",
|
||||
"version": "9.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.4.0.tgz",
|
||||
"integrity": "sha512-IOlXxXhZA4Z3m0EEYtrrACkuHiArHLZ3CvqWwOez/pURNqRuwfoFlTPbN5Muf28pzFuztxPyiUiNwz8KctdZaQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.1",
|
||||
"@octokit/types": "^13.7.0",
|
||||
"bottleneck": "^2.15.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": "^3.5.0"
|
||||
"@octokit/core": "^6.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
|
||||
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
|
||||
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/endpoint": "^10.1.3",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"fast-content-type-parse": "^2.0.0",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"version": "6.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
|
||||
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
"@octokit/types": "^13.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest": {
|
||||
"version": "18.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
|
||||
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
|
||||
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@octokit/plugin-paginate-rest": "^2.16.8",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
|
||||
"@octokit/core": "^6.1.4",
|
||||
"@octokit/plugin-paginate-rest": "^11.4.2",
|
||||
"@octokit/plugin-request-log": "^5.3.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
@@ -234,9 +396,10 @@
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
|
||||
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/bottleneck": {
|
||||
"version": "2.19.5",
|
||||
@@ -270,11 +433,6 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"node_modules/discord-api-types": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz",
|
||||
@@ -316,6 +474,22 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-content-type-parse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
|
||||
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-obj": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
|
||||
@@ -324,14 +498,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
@@ -375,14 +541,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/ow": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz",
|
||||
@@ -429,9 +587,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/vali-date": {
|
||||
"version": "1.0.0",
|
||||
@@ -455,11 +614,6 @@
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||
@@ -517,45 +671,86 @@
|
||||
}
|
||||
},
|
||||
"@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
|
||||
"integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw=="
|
||||
},
|
||||
"@octokit/core": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
|
||||
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz",
|
||||
"integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==",
|
||||
"requires": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/auth-token": "^5.0.0",
|
||||
"@octokit/graphql": "^8.1.2",
|
||||
"@octokit/request": "^9.2.1",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"before-after-hook": "^3.0.2",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"version": "10.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
|
||||
"integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/types": "^13.6.2",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz",
|
||||
"integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==",
|
||||
"requires": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/request": "^9.2.2",
|
||||
"@octokit/types": "^13.8.0",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
@@ -564,26 +759,55 @@
|
||||
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
"version": "2.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
|
||||
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
|
||||
"version": "11.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.2.tgz",
|
||||
"integrity": "sha512-BXJ7XPCTDXFF+wxcg/zscfgw2O/iDPtNSkwwR1W1W5c4Mb3zav/M2XvxQ23nVmKj7jpweB4g8viMeCQdm7LMVA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0"
|
||||
"@octokit/types": "^13.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-request-log": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-5.3.1.tgz",
|
||||
"integrity": "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==",
|
||||
"requires": {}
|
||||
},
|
||||
"@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
|
||||
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
|
||||
"version": "13.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.1.tgz",
|
||||
"integrity": "sha512-o8uOBdsyR+WR8MK9Cco8dCgvG13H1RlM1nWnK/W7TEACQBFux/vPREgKucxUfuDQ5yi1T3hGf4C5ZmZXAERgwQ==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0",
|
||||
"deprecation": "^2.3.1"
|
||||
"@octokit/types": "^13.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-retry": {
|
||||
@@ -596,46 +820,88 @@
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-throttling": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.7.0.tgz",
|
||||
"integrity": "sha512-qrKT1Yl/KuwGSC6/oHpLBot3ooC9rq0/ryDYBCpkRtoj+R8T47xTMDT6Tk2CxWopFota/8Pi/2SqArqwC0JPow==",
|
||||
"version": "9.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.4.0.tgz",
|
||||
"integrity": "sha512-IOlXxXhZA4Z3m0EEYtrrACkuHiArHLZ3CvqWwOez/pURNqRuwfoFlTPbN5Muf28pzFuztxPyiUiNwz8KctdZaQ==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.1",
|
||||
"@octokit/types": "^13.7.0",
|
||||
"bottleneck": "^2.15.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
|
||||
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
|
||||
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
|
||||
"requires": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/endpoint": "^10.1.3",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"fast-content-type-parse": "^2.0.0",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"version": "6.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
|
||||
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
"@octokit/types": "^13.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/rest": {
|
||||
"version": "18.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
|
||||
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
|
||||
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
|
||||
"requires": {
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@octokit/plugin-paginate-rest": "^2.16.8",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
|
||||
"@octokit/core": "^6.1.4",
|
||||
"@octokit/plugin-paginate-rest": "^11.4.2",
|
||||
"@octokit/plugin-request-log": "^5.3.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
@@ -675,9 +941,9 @@
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
|
||||
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="
|
||||
},
|
||||
"bottleneck": {
|
||||
"version": "2.19.5",
|
||||
@@ -702,11 +968,6 @@
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"discord-api-types": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz",
|
||||
@@ -735,16 +996,16 @@
|
||||
"is-obj": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"fast-content-type-parse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
|
||||
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q=="
|
||||
},
|
||||
"is-obj": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
|
||||
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
},
|
||||
"lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
@@ -771,14 +1032,6 @@
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"ow": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz",
|
||||
@@ -813,9 +1066,9 @@
|
||||
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="
|
||||
},
|
||||
"universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="
|
||||
},
|
||||
"vali-date": {
|
||||
"version": "1.0.0",
|
||||
@@ -836,11 +1089,6 @@
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"ws": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"@octokit/plugin-throttling": "^9.4.0",
|
||||
"@octokit/rest": "^21.1.1",
|
||||
"discord.js": "^13.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
337
.github/workflows/scripts/releases/generate-release-notes/package-lock.json
generated
vendored
@@ -1,22 +1,33 @@
|
||||
{
|
||||
"name": "generate-release-notes",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": {
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^21.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"@octokit/core": {
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
|
||||
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.0",
|
||||
@@ -26,76 +37,60 @@
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/graphql": {
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz",
|
||||
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
"version": "2.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
|
||||
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-request-log": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA=="
|
||||
},
|
||||
"@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
|
||||
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0",
|
||||
"deprecation": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-retry": {
|
||||
"node_modules/@octokit/plugin-retry": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
|
||||
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"bottleneck": "^2.15.3"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-throttling": {
|
||||
"node_modules/@octokit/plugin-throttling": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.5.2.tgz",
|
||||
"integrity": "sha512-Eu7kfJxU8vmHqWGNszWpg+GVp2tnAfax3XQV5CkYPEE69C+KvInJXW9WajgSeW+cxYe0UVdouzCtcreGNuJo7A==",
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.1",
|
||||
"bottleneck": "^2.15.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
|
||||
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
@@ -104,99 +99,295 @@
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"@octokit/rest": {
|
||||
"version": "18.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
|
||||
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
|
||||
"requires": {
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@octokit/plugin-paginate-rest": "^2.16.8",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
|
||||
"node_modules/@octokit/rest": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
|
||||
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^6.1.4",
|
||||
"@octokit/plugin-paginate-rest": "^11.4.2",
|
||||
"@octokit/plugin-request-log": "^5.3.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/auth-token": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
|
||||
"integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/core": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz",
|
||||
"integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^5.0.0",
|
||||
"@octokit/graphql": "^8.1.2",
|
||||
"@octokit/request": "^9.2.1",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"before-after-hook": "^3.0.2",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/endpoint": {
|
||||
"version": "10.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
|
||||
"integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.6.2",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/graphql": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz",
|
||||
"integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^9.2.2",
|
||||
"@octokit/types": "^13.8.0",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "11.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.2.tgz",
|
||||
"integrity": "sha512-BXJ7XPCTDXFF+wxcg/zscfgw2O/iDPtNSkwwR1W1W5c4Mb3zav/M2XvxQ23nVmKj7jpweB4g8viMeCQdm7LMVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-5.3.1.tgz",
|
||||
"integrity": "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "13.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.1.tgz",
|
||||
"integrity": "sha512-o8uOBdsyR+WR8MK9Cco8dCgvG13H1RlM1nWnK/W7TEACQBFux/vPREgKucxUfuDQ5yi1T3hGf4C5ZmZXAERgwQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/request": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
|
||||
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^10.1.3",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"fast-content-type-parse": "^2.0.0",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/request-error": {
|
||||
"version": "6.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
|
||||
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/before-after-hook": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
|
||||
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/universal-user-agent": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "6.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
|
||||
"integrity": "sha512-0zffZ048M0UhthyPXQHLz4038Ak46nMWZXkzlXvXB/M/L1jYPBceq4iZj4qjKVrvveaJrrgKdJ9+3yUuITfcCw==",
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^11.1.0"
|
||||
}
|
||||
},
|
||||
"before-after-hook": {
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==",
|
||||
"peer": true
|
||||
},
|
||||
"bottleneck": {
|
||||
"node_modules/bottleneck": {
|
||||
"version": "2.19.5",
|
||||
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
|
||||
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
|
||||
},
|
||||
"deprecation": {
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
|
||||
"peer": true
|
||||
},
|
||||
"is-plain-object": {
|
||||
"node_modules/fast-content-type-parse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
|
||||
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"tr46": {
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
|
||||
"peer": true
|
||||
},
|
||||
"universal-user-agent": {
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==",
|
||||
"peer": true
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
|
||||
"peer": true
|
||||
},
|
||||
"whatwg-url": {
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^18.12.0"
|
||||
"@octokit/rest": "^21.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,11 +49,11 @@ set LIBPNG=1645
|
||||
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
set QT=6.8.2
|
||||
set QTMINOR=6.8
|
||||
set SDL=SDL2-2.30.12
|
||||
set SDL=SDL3-3.2.6
|
||||
set WEBP=1.5.0
|
||||
set ZLIB=1.3.1
|
||||
set ZLIBSHORT=131
|
||||
set ZSTD=1.5.6
|
||||
set ZSTD=1.5.7
|
||||
|
||||
set SHADERC=2024.1
|
||||
set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
|
||||
@@ -66,15 +66,14 @@ call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lp
|
||||
call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" aa2808d0f2dc6b383c6689bf6d166e2de62db4d58be989e4b052acb31df0fba3 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 665e5aa2a613affe099a38d61257ecc5ef4bf38b109d915147aa8b005399d68a || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 3b1c3b46e416d36931efd34663122d7f51b550c87f74de2d38249516fe7d8be5 || goto error
|
||||
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 8df152f4969b308546306c074628de761f0b80265de7de534e3822fab22d7535 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error
|
||||
@@ -159,7 +158,6 @@ echo Building Zstandard...
|
||||
rmdir /S /Q "zstd-%ZSTD%"
|
||||
%SEVENZIP% x "-x^!zstd-%ZSTD%\tests\cli-tests\bin" "zstd-%ZSTD%.zip" || goto error
|
||||
cd "zstd-%ZSTD%"
|
||||
%PATCH% -p1 < "..\zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" || goto error
|
||||
cmake %ARM64TOOLCHAIN% -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 || goto error
|
||||
ninja -C build install || goto error
|
||||
@@ -181,7 +179,7 @@ cd "%SDL%" || 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
|
||||
copy build\SDL2.pdb "%INSTALLDIR%\bin" || goto error
|
||||
copy build\SDL3.pdb "%INSTALLDIR%\bin" || goto error
|
||||
cd .. || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
|
||||
@@ -47,11 +47,11 @@ set LIBPNG=1645
|
||||
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
set QT=6.8.2
|
||||
set QTMINOR=6.8
|
||||
set SDL=SDL2-2.30.12
|
||||
set SDL=SDL3-3.2.6
|
||||
set WEBP=1.5.0
|
||||
set ZLIB=1.3.1
|
||||
set ZLIBSHORT=131
|
||||
set ZSTD=1.5.6
|
||||
set ZSTD=1.5.7
|
||||
|
||||
set SHADERC=2024.1
|
||||
set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
|
||||
@@ -64,15 +64,14 @@ call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lp
|
||||
call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" aa2808d0f2dc6b383c6689bf6d166e2de62db4d58be989e4b052acb31df0fba3 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 665e5aa2a613affe099a38d61257ecc5ef4bf38b109d915147aa8b005399d68a || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 3b1c3b46e416d36931efd34663122d7f51b550c87f74de2d38249516fe7d8be5 || goto error
|
||||
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 8df152f4969b308546306c074628de761f0b80265de7de534e3822fab22d7535 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error
|
||||
@@ -156,7 +155,6 @@ echo Building Zstandard...
|
||||
rmdir /S /Q "zstd-%ZSTD%"
|
||||
%SEVENZIP% x "-x^!zstd-%ZSTD%\tests\cli-tests\bin" "zstd-%ZSTD%.zip" || goto error
|
||||
cd "zstd-%ZSTD%"
|
||||
%PATCH% -p1 < "..\zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" || goto error
|
||||
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 || goto error
|
||||
ninja -C build install || goto error
|
||||
@@ -178,7 +176,7 @@ cd "%SDL%" || 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
|
||||
copy build\SDL2.pdb "%INSTALLDIR%\bin" || goto error
|
||||
copy build\SDL3.pdb "%INSTALLDIR%\bin" || goto error
|
||||
cd .. || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
|
||||
@@ -1270,6 +1270,7 @@ SCAJ-10015:
|
||||
region: "NTSC-Unk"
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SCAJ-20001:
|
||||
name: "Ratchet & Clank"
|
||||
region: "NTSC-Unk"
|
||||
@@ -2015,7 +2016,6 @@ SCAJ-20132:
|
||||
eeClampMode: 2 # Fixes wrong color on some characters and breakable objects.
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 1 # Fixes ghosting characters.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SCAJ-20133:
|
||||
name: "Kagero 2 - Dark Illusion"
|
||||
@@ -2237,6 +2237,7 @@ SCAJ-20163:
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting.
|
||||
autoFlush: 2 # Fixes post lighting.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SCAJ-20164:
|
||||
name: "Kingdom Hearts II"
|
||||
region: "NTSC-Unk"
|
||||
@@ -10418,15 +10419,6 @@ SCUS-21295:
|
||||
recommendedBlendingLevel: 3 # Fixes water and grass textures.
|
||||
halfPixelOffset: 4 # Mostly aligns post processing.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SCUS-21494:
|
||||
name: "Need for Speed - Carbon Collector's Edition"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes game hang after opening intro.
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes blurriness.
|
||||
roundSprite: 2 # Fixes blurriness.
|
||||
SCUS-90174:
|
||||
name: "Disney/Pixar Toy Story 3 [PlayStation 2 Bundle]"
|
||||
region: "NTSC-U"
|
||||
@@ -12805,9 +12797,7 @@ SLAJ-25075:
|
||||
- "SLAJ-25075"
|
||||
- "SLPM-66232"
|
||||
- "SLPM-66562"
|
||||
- "SLPM-65766"
|
||||
- "SLPM-66051"
|
||||
- "SLPM-66960"
|
||||
- "SLAJ-25054" # Underground 2 save grants extra money.
|
||||
SLAJ-25076:
|
||||
name: "Harry Potter and the Goblet of Fire"
|
||||
region: "NTSC-Unk"
|
||||
@@ -12879,6 +12869,13 @@ SLAJ-25091:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLAJ-25091"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLAJ-25075"
|
||||
- "SLPM-66232"
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLAJ-25054"
|
||||
SLAJ-25092:
|
||||
name: "Shin Sangoku Musou 4 [PlayStation2 the Best]"
|
||||
region: "NTSC-Unk"
|
||||
@@ -13630,7 +13627,7 @@ SLED-53954:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLED-53977:
|
||||
name: "Dragon Quest - The Journey of the Cursed King"
|
||||
region: "PAL-E"
|
||||
@@ -15351,7 +15348,6 @@ SLES-50723:
|
||||
name: "TOCA Race Driver"
|
||||
region: "PAL-M3"
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes lighting.
|
||||
halfPixelOffset: 1 # Fixes vertical lines
|
||||
SLES-50725:
|
||||
name: "V-Rally 3"
|
||||
@@ -15449,7 +15445,6 @@ SLES-50767:
|
||||
name: "V8 Supercars Australia - Race Driver"
|
||||
region: "PAL-A"
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes lighting.
|
||||
halfPixelOffset: 1 # Fixes vertical lines
|
||||
SLES-50768:
|
||||
name: "Rally Championship"
|
||||
@@ -15616,13 +15611,11 @@ SLES-50816:
|
||||
region: "PAL-M3"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes lighting.
|
||||
halfPixelOffset: 1 # Fixes vertical lines
|
||||
SLES-50818:
|
||||
name: "Pro Race Driver"
|
||||
region: "PAL-I"
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes lighting.
|
||||
halfPixelOffset: 1 # Fixes vertical lines
|
||||
SLES-50820:
|
||||
name: "Micro Machines"
|
||||
@@ -18283,7 +18276,7 @@ SLES-51914:
|
||||
- "SLES-51914"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Mostly aligns post processing.
|
||||
nativeScaling: 2 # Fixes post processing smoothness and position.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
disablePartialInvalidation: 1 # Fixes textureless graphics ingame.
|
||||
bilinearUpscale: 2 # Gets rid of center vertical line when upscaling.
|
||||
SLES-51915:
|
||||
@@ -20081,7 +20074,7 @@ SLES-52636:
|
||||
autoFlush: 1 # Fixes incorrect colors.
|
||||
alignSprite: 1 # Fixes vertical lines such as in FMVs.
|
||||
SLES-52637:
|
||||
name: "TOCA Racer Driver 2"
|
||||
name: "TOCA Race Driver 2"
|
||||
region: "PAL-M5"
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes lighting and vertical lines, also works with normal vertex.
|
||||
@@ -21524,6 +21517,9 @@ SLES-53087:
|
||||
skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
|
||||
halfPixelOffset: 2 # Fixes depth of field alignment.
|
||||
nativeScaling: 1 # Fixes depth of field.
|
||||
memcardFilters:
|
||||
- "SLES-53087"
|
||||
- "SLES-52637" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
|
||||
SLES-53088:
|
||||
name: "DTM Race Driver 3"
|
||||
region: "PAL-M5"
|
||||
@@ -21534,6 +21530,9 @@ SLES-53088:
|
||||
skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
|
||||
halfPixelOffset: 2 # Fixes depth of field alignment.
|
||||
nativeScaling: 1 # Fixes depth of field.
|
||||
memcardFilters:
|
||||
- "SLES-53088"
|
||||
- "SLES-52638" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
|
||||
SLES-53089:
|
||||
name: "V8 Supercars Australia 3"
|
||||
region: "PAL-E"
|
||||
@@ -21544,6 +21543,9 @@ SLES-53089:
|
||||
skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
|
||||
halfPixelOffset: 2 # Fixes depth of field alignment.
|
||||
nativeScaling: 1 # Fixes depth of field.
|
||||
memcardFilters:
|
||||
- "SLES-53089"
|
||||
- "SLES-52639" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
|
||||
SLES-53090:
|
||||
name: "Circuit Blasters"
|
||||
region: "PAL-M5"
|
||||
@@ -22913,7 +22915,7 @@ SLES-53556:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLES-53557:
|
||||
name: "Need for Speed - Most Wanted"
|
||||
region: "PAL-E"
|
||||
@@ -22923,12 +22925,12 @@ SLES-53557:
|
||||
halfPixelOffset: 2 # Fixes blurriness.
|
||||
cpuCLUTRender: 1 # Final colour adjustment LUT.
|
||||
gpuTargetCLUT: 1 # Fixes sun penetrating bridges (along with HPO special).
|
||||
memcardFilters: # Reads Underground 2 save for extra money.
|
||||
memcardFilters:
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857"
|
||||
- "SLES-52725"
|
||||
- "SLES-52725" # Underground 2 save grants extra money.
|
||||
SLES-53558:
|
||||
name: "Need for Speed - Most Wanted"
|
||||
region: "PAL-M8"
|
||||
@@ -22942,7 +22944,7 @@ SLES-53558:
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857"
|
||||
- "SLES-52725"
|
||||
- "SLES-52725" # Underground 2 save grants extra money.
|
||||
SLES-53559:
|
||||
name: "Need for Speed - Most Wanted"
|
||||
region: "PAL-M7"
|
||||
@@ -22956,7 +22958,7 @@ SLES-53559:
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857"
|
||||
- "SLES-52725"
|
||||
- "SLES-52725" # Underground 2 save grants extra money.
|
||||
SLES-53560:
|
||||
name: "Sonic Riders"
|
||||
region: "PAL-M5"
|
||||
@@ -23209,6 +23211,9 @@ SLES-53645:
|
||||
name: "Knights of the Temple II"
|
||||
region: "PAL-M5"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Improves shadow quality.
|
||||
autoFlush: 1 # Fixes light leaking and fire bloom intensity.
|
||||
SLES-53646:
|
||||
name: "World Racing 2"
|
||||
region: "PAL-M5"
|
||||
@@ -23700,7 +23705,6 @@ SLES-53794:
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Fix effects upscaling.
|
||||
nativeScaling: 2 # Fixes post effects.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SLES-53796:
|
||||
name: "FIFA Street 2"
|
||||
@@ -23892,7 +23896,7 @@ SLES-53857:
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857"
|
||||
- "SLES-52725"
|
||||
- "SLES-52725" # Underground 2 save grants extra money.
|
||||
SLES-53860:
|
||||
name: "Dynasty Warriors 5 - Xtreme Legends"
|
||||
region: "PAL-E"
|
||||
@@ -24382,7 +24386,7 @@ SLES-54027:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLES-54030:
|
||||
name: "Black"
|
||||
region: "PAL-E"
|
||||
@@ -25138,7 +25142,7 @@ SLES-54317:
|
||||
region: "PAL-M5"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes alignment on fire effects.
|
||||
halfPixelOffset: 4 # Fixes alignment on fire effects.
|
||||
SLES-54319:
|
||||
name: "Biker Mice from Mars"
|
||||
region: "PAL-M5"
|
||||
@@ -25156,6 +25160,18 @@ SLES-54321:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-54321"
|
||||
- "SLES-54322"
|
||||
- "SLES-54323"
|
||||
- "SLES-54324"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-54322:
|
||||
name: "Need for Speed - Carbon"
|
||||
region: "PAL-M8"
|
||||
@@ -25164,6 +25180,18 @@ SLES-54322:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-54321"
|
||||
- "SLES-54322"
|
||||
- "SLES-54323"
|
||||
- "SLES-54324"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-54323:
|
||||
name: "Need for Speed - Carbon"
|
||||
region: "PAL-I-S"
|
||||
@@ -25172,6 +25200,18 @@ SLES-54323:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-54321"
|
||||
- "SLES-54322"
|
||||
- "SLES-54323"
|
||||
- "SLES-54324"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-54324:
|
||||
name: "Need for Speed - Carbon"
|
||||
region: "PAL-R"
|
||||
@@ -25180,6 +25220,18 @@ SLES-54324:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-54321"
|
||||
- "SLES-54322"
|
||||
- "SLES-54323"
|
||||
- "SLES-54324"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-54326:
|
||||
name: "Raceway - Drag Stock Racing"
|
||||
region: "PAL-E"
|
||||
@@ -25454,6 +25506,17 @@ SLES-54402:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-54402"
|
||||
- "SLES-54492"
|
||||
- "SLES-54493"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-54410:
|
||||
name: "Monster Trux Arenas - Special Edition"
|
||||
region: "PAL-Unk"
|
||||
@@ -25710,7 +25773,6 @@ SLES-54483:
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes car reflections.
|
||||
mergeSprite: 1 # Fixes bluriness.
|
||||
halfPixelOffset: 4 # Fixes bluriness.
|
||||
nativeScaling: 2 # Fixes post lighting.
|
||||
autoFlush: 1 # Fixes post alignment.
|
||||
@@ -25751,6 +25813,17 @@ SLES-54492:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-54402"
|
||||
- "SLES-54492"
|
||||
- "SLES-54493"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-54493:
|
||||
name: "Need for Speed - Carbon [Collector's Edition]"
|
||||
region: "PAL-F-G"
|
||||
@@ -25759,6 +25832,17 @@ SLES-54493:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-54402"
|
||||
- "SLES-54492"
|
||||
- "SLES-54493"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-54494:
|
||||
name: "Little Britain - The Video Game"
|
||||
region: "PAL-E"
|
||||
@@ -27322,26 +27406,132 @@ SLES-55002:
|
||||
region: "PAL-E"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-55002"
|
||||
- "SLES-55003"
|
||||
- "SLES-55004"
|
||||
- "SLES-55005"
|
||||
- "SLES-55006"
|
||||
# Carbon save grants extra money.
|
||||
- "SLES-54321"
|
||||
- "SLES-54322"
|
||||
- "SLES-54323"
|
||||
- "SLES-54324"
|
||||
- "SLES-54402"
|
||||
- "SLES-54492"
|
||||
- "SLES-54493"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-55003:
|
||||
name: "Need for Speed - ProStreet"
|
||||
region: "PAL-F-G"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-55002"
|
||||
- "SLES-55003"
|
||||
- "SLES-55004"
|
||||
- "SLES-55005"
|
||||
- "SLES-55006"
|
||||
# Carbon save grants extra money.
|
||||
- "SLES-54321"
|
||||
- "SLES-54322"
|
||||
- "SLES-54323"
|
||||
- "SLES-54324"
|
||||
- "SLES-54402"
|
||||
- "SLES-54492"
|
||||
- "SLES-54493"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-55004:
|
||||
name: "Need for Speed - ProStreet"
|
||||
region: "PAL-I-S"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-55002"
|
||||
- "SLES-55003"
|
||||
- "SLES-55004"
|
||||
- "SLES-55005"
|
||||
- "SLES-55006"
|
||||
# Carbon save grants extra money.
|
||||
- "SLES-54321"
|
||||
- "SLES-54322"
|
||||
- "SLES-54323"
|
||||
- "SLES-54324"
|
||||
- "SLES-54402"
|
||||
- "SLES-54492"
|
||||
- "SLES-54493"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-55005:
|
||||
name: "Need for Speed - ProStreet"
|
||||
region: "PAL-M8"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-55002"
|
||||
- "SLES-55003"
|
||||
- "SLES-55004"
|
||||
- "SLES-55005"
|
||||
- "SLES-55006"
|
||||
# Carbon save grants extra money.
|
||||
- "SLES-54321"
|
||||
- "SLES-54322"
|
||||
- "SLES-54323"
|
||||
- "SLES-54324"
|
||||
- "SLES-54402"
|
||||
- "SLES-54492"
|
||||
- "SLES-54493"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-55006:
|
||||
name: "Need for Speed - ProStreet"
|
||||
region: "PAL-R"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLES-55002"
|
||||
- "SLES-55003"
|
||||
- "SLES-55004"
|
||||
- "SLES-55005"
|
||||
- "SLES-55006"
|
||||
# Carbon save grants extra money. Detection is bugged by default, can be fixed with a patch.
|
||||
- "SLES-54321"
|
||||
- "SLES-54322"
|
||||
- "SLES-54323"
|
||||
- "SLES-54324"
|
||||
- "SLES-54402"
|
||||
- "SLES-54492"
|
||||
- "SLES-54493"
|
||||
# Most Wanted save grants extra money. Detection is bugged by default, can be fixed with a patch.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857"
|
||||
- "SLUS-21267" # Original wrong Most Wanted serial.
|
||||
# UG2 saves can be detected, but the code is unused.
|
||||
- "SLES-52725"
|
||||
SLES-55007:
|
||||
name: "Boogie"
|
||||
region: "PAL-M7"
|
||||
@@ -28286,6 +28476,18 @@ SLES-55349:
|
||||
gpuTargetCLUT: 1 # Fixes sun penetration.
|
||||
nativeScaling: 2 # Fixes post alignment.
|
||||
getSkipCount: "GSC_NFSUndercover"
|
||||
memcardFilters:
|
||||
- "SLES-55349"
|
||||
- "SLES-55350"
|
||||
- "SLES-55351"
|
||||
- "SLES-55352"
|
||||
- "SLES-55353"
|
||||
# Checks from Carbon are left in the code, unused.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857"
|
||||
- "SLES-52725"
|
||||
SLES-55350:
|
||||
name: "Need for Speed - Undercover"
|
||||
region: "PAL-F-G"
|
||||
@@ -28296,6 +28498,18 @@ SLES-55350:
|
||||
gpuTargetCLUT: 1 # Fixes sun penetration.
|
||||
nativeScaling: 2 # Fixes post alignment.
|
||||
getSkipCount: "GSC_NFSUndercover"
|
||||
memcardFilters:
|
||||
- "SLES-55349"
|
||||
- "SLES-55350"
|
||||
- "SLES-55351"
|
||||
- "SLES-55352"
|
||||
- "SLES-55353"
|
||||
# Checks from Carbon are left in the code, unused.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857"
|
||||
- "SLES-52725"
|
||||
SLES-55351:
|
||||
name: "Need for Speed - Undercover"
|
||||
region: "PAL-I-S"
|
||||
@@ -28306,6 +28520,18 @@ SLES-55351:
|
||||
gpuTargetCLUT: 1 # Fixes sun penetration.
|
||||
nativeScaling: 2 # Fixes post alignment.
|
||||
getSkipCount: "GSC_NFSUndercover"
|
||||
memcardFilters:
|
||||
- "SLES-55349"
|
||||
- "SLES-55350"
|
||||
- "SLES-55351"
|
||||
- "SLES-55352"
|
||||
- "SLES-55353"
|
||||
# Checks from Carbon are left in the code, unused.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857"
|
||||
- "SLES-52725"
|
||||
SLES-55352:
|
||||
name: "Need for Speed - Undercover"
|
||||
region: "PAL-SC"
|
||||
@@ -28317,6 +28543,18 @@ SLES-55352:
|
||||
gpuTargetCLUT: 1 # Fixes sun penetration.
|
||||
nativeScaling: 2 # Fixes post alignment.
|
||||
getSkipCount: "GSC_NFSUndercover"
|
||||
memcardFilters:
|
||||
- "SLES-55349"
|
||||
- "SLES-55350"
|
||||
- "SLES-55351"
|
||||
- "SLES-55352"
|
||||
- "SLES-55353"
|
||||
# Checks from Carbon are left in the code, unused.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857"
|
||||
- "SLES-52725"
|
||||
SLES-55353:
|
||||
name: "Need for Speed - Undercover"
|
||||
region: "PAL-M6"
|
||||
@@ -28327,6 +28565,18 @@ SLES-55353:
|
||||
gpuTargetCLUT: 1 # Fixes sun penetration.
|
||||
nativeScaling: 2 # Fixes post alignment.
|
||||
getSkipCount: "GSC_NFSUndercover"
|
||||
memcardFilters:
|
||||
- "SLES-55349"
|
||||
- "SLES-55350"
|
||||
- "SLES-55351"
|
||||
- "SLES-55352"
|
||||
- "SLES-55353"
|
||||
# Checks from Carbon are left in the code, unused.
|
||||
- "SLES-53557"
|
||||
- "SLES-53558"
|
||||
- "SLES-53559"
|
||||
- "SLES-53857"
|
||||
- "SLES-52725"
|
||||
SLES-55354:
|
||||
name: "Shin Megami Tensei - Persona 3 FES"
|
||||
region: "PAL-E"
|
||||
@@ -29910,7 +30160,7 @@ SLKA-25093:
|
||||
- "SLKA-25093"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Mostly aligns post processing.
|
||||
nativeScaling: 2 # Fixes post processing smoothness and position.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
disablePartialInvalidation: 1 # Fixes textureless graphics ingame.
|
||||
bilinearUpscale: 2 # Gets rid of center vertical line when upscaling.
|
||||
SLKA-25095:
|
||||
@@ -30258,6 +30508,11 @@ SLKA-25185:
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes blurriness.
|
||||
roundSprite: 2 # Fixes blurriness.
|
||||
memcardFilters:
|
||||
- "SLKA-25185"
|
||||
- "SLKA-25334" # Most Wanted save grants extra money.
|
||||
- "SLAJ-25075" # Original wrong Black Edition serial.
|
||||
- "SLKA-25241" # UG2 saves can be detected, but the code is unused.
|
||||
SLKA-25186:
|
||||
name: "The King of Fighters - Maximum Impact [Limited Edition]"
|
||||
name-sort: "King of Fighters, The - Maximum Impact [Limited Edition]"
|
||||
@@ -30944,6 +31199,9 @@ SLKA-25334:
|
||||
halfPixelOffset: 2 # Fixes blurriness.
|
||||
cpuCLUTRender: 1 # Final colour adjustment LUT.
|
||||
gpuTargetCLUT: 1 # Fixes sun penetrating bridges (along with HPO special).
|
||||
memcardFilters:
|
||||
- "SLKA-25334"
|
||||
- "SLKA-25241" # Underground 2 save grants extra money.
|
||||
SLKA-25335:
|
||||
name: "Shadow the Hedgehog"
|
||||
region: "NTSC-K"
|
||||
@@ -30983,7 +31241,7 @@ SLKA-25341:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLKA-25342:
|
||||
name: "Ryu ga Gotoku"
|
||||
region: "NTSC-K"
|
||||
@@ -31305,6 +31563,11 @@ SLKA-25411:
|
||||
region: "NTSC-K"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLKA-25411"
|
||||
- "SLKA-25185" # Carbon save grants extra money.
|
||||
- "SLKA-25334" # Most Wanted save grants extra money.
|
||||
- "SLKA-25241" # UG2 saves can be detected, but the code is unused.
|
||||
SLKA-25412:
|
||||
name: "Sengoku Basara 2 - Heroes"
|
||||
region: "NTSC-K"
|
||||
@@ -31421,6 +31684,13 @@ SLKA-25446:
|
||||
recommendedBlendingLevel: 3 # Improves car reflections.
|
||||
halfPixelOffset: 2 # Fixes blurriness.
|
||||
getSkipCount: "GSC_NFSUndercover"
|
||||
memcardFilters:
|
||||
- "SLKA-25446"
|
||||
# Checks from Carbon are left in the code, unused.
|
||||
- "SLKA-25185"
|
||||
- "SLKA-25334"
|
||||
- "SLAJ-25075"
|
||||
- "SLKA-25241"
|
||||
SLKA-25447:
|
||||
name: "FIFA 09"
|
||||
region: "NTSC-K"
|
||||
@@ -31616,6 +31886,9 @@ SLPM-55003:
|
||||
halfPixelOffset: 2 # Fixes blurriness.
|
||||
cpuCLUTRender: 1 # Final colour adjustment LUT.
|
||||
gpuTargetCLUT: 1 # Fixes sun penetrating bridges (along with HPO special).
|
||||
memcardFilters:
|
||||
- "SLPM-55003"
|
||||
- "SLPM-65766" # Underground 2 save grants extra money.
|
||||
SLPM-55004:
|
||||
name: "バーンアウト リベンジ [EA:SY! 1980]"
|
||||
name-sort: "ばーんあうと りべんじ [EA:SY! 1980])"
|
||||
@@ -31869,6 +32142,9 @@ SLPM-55046:
|
||||
skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
|
||||
halfPixelOffset: 2 # Fixes depth of field alignment.
|
||||
nativeScaling: 1 # Fixes depth of field.
|
||||
memcardFilters:
|
||||
- "SLPM-55046"
|
||||
- "SLPM-66498" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
|
||||
SLPM-55047:
|
||||
name: "Sugar+Spice! ~あの子のステキな何もかも~"
|
||||
name-sort: "しゅがーすぱいす あのこのすてきななにもかも"
|
||||
@@ -31943,6 +32219,13 @@ SLPM-55061:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLPM-55061"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLPM-66232"
|
||||
- "SLPM-66562"
|
||||
- "SLAJ-25075" # Original wrong Black Edition serial.
|
||||
- "SLPM-65766" # UG2 saves can be detected, but the code is unused.
|
||||
SLPM-55062:
|
||||
name: "実況パワフルメジャーリーグ 3"
|
||||
name-sort: "じっきょうぱわふるめじゃーりーぐ 3"
|
||||
@@ -32045,7 +32328,6 @@ SLPM-55081:
|
||||
eeClampMode: 2 # Fixes wrong color on some characters and breakable objects.
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 1 # Fixes ghosting characters.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SLPM-55082:
|
||||
name: "真・三國無双5 Special [ディスク 1]"
|
||||
@@ -32261,6 +32543,13 @@ SLPM-55127:
|
||||
gpuTargetCLUT: 1 # Fixes sun penetration.
|
||||
nativeScaling: 2 # Fixes post alignment.
|
||||
getSkipCount: "GSC_NFSUndercover"
|
||||
memcardFilters:
|
||||
- "SLPM-55127"
|
||||
# Checks from Carbon are left in the code, unused.
|
||||
- "SLPM-66232"
|
||||
- "SLPM-66562"
|
||||
- "SLAJ-25075"
|
||||
- "SLPM-65766"
|
||||
SLPM-55128:
|
||||
name: "ラグビー08 [英語版] [EA:SY! 1980]"
|
||||
name-sort: "らぐびー08 [えいごばん] [EA:SY! 1980]"
|
||||
@@ -32398,6 +32687,16 @@ SLPM-55151:
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLPM-55151"
|
||||
# Carbon save grants extra money.
|
||||
- "SLPM-55061"
|
||||
- "SLPM-66617"
|
||||
- "SLPM-66869"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLPM-66232"
|
||||
- "SLPM-66562"
|
||||
- "SLPM-65766" # UG2 saves can be detected, but the code is unused.
|
||||
SLPM-55152:
|
||||
name: "スロッターUPコア11 巨人の星Ⅳ 青春群像編"
|
||||
name-sort: "すろったーUPこあ11 きょじんのほし4 せいしゅんぐんぞうへん"
|
||||
@@ -32839,6 +33138,13 @@ SLPM-55244:
|
||||
gpuTargetCLUT: 1 # Fixes sun penetration.
|
||||
nativeScaling: 2 # Fixes post alignment.
|
||||
getSkipCount: "GSC_NFSUndercover"
|
||||
memcardFilters:
|
||||
- "SLPM-55244"
|
||||
# Checks from Carbon are left in the code, unused.
|
||||
- "SLPM-66232"
|
||||
- "SLPM-66562"
|
||||
- "SLAJ-25075"
|
||||
- "SLPM-65766"
|
||||
SLPM-55245:
|
||||
name: "ひまわり -Pebble in the Sky-"
|
||||
name-sort: "ひまわり -Pebble in the Sky-"
|
||||
@@ -34507,7 +34813,6 @@ SLPM-61120:
|
||||
eeClampMode: 2 # Fixes wrong color on some characters and breakable objects.
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 1 # Fixes ghosting characters.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SLPM-61121:
|
||||
name: "KAIDO ~峠の伝説~ [体験版]"
|
||||
@@ -41211,7 +41516,7 @@ SLPM-65413:
|
||||
- "SLPM-65413"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Mostly aligns post processing.
|
||||
nativeScaling: 2 # Fixes post processing smoothness and position.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
disablePartialInvalidation: 1 # Fixes textureless graphics ingame.
|
||||
bilinearUpscale: 2 # Gets rid of center vertical line when upscaling.
|
||||
SLPM-65414:
|
||||
@@ -44544,7 +44849,6 @@ SLPM-65999:
|
||||
eeClampMode: 2 # Fixes wrong color on some characters and breakable objects.
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 1 # Fixes ghosting characters.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SLPM-66000:
|
||||
name: "コンフリクトデルタⅡ ~湾岸戦争1991~"
|
||||
@@ -46060,7 +46364,8 @@ SLPM-66232:
|
||||
- "SLAJ-25075"
|
||||
- "SLPM-66232"
|
||||
- "SLPM-66562"
|
||||
- "SLPM-65766"
|
||||
- "SLPM-65766" # Underground 2 save grants extra money.
|
||||
# Unconfirmed UG2 serials.
|
||||
- "SLPM-66051"
|
||||
- "SLPM-66960"
|
||||
SLPM-66233:
|
||||
@@ -48091,7 +48396,8 @@ SLPM-66562:
|
||||
- "SLAJ-25075"
|
||||
- "SLPM-66232"
|
||||
- "SLPM-66562"
|
||||
- "SLPM-65766"
|
||||
- "SLPM-65766" # Underground 2 save grants extra money.
|
||||
# Unconfirmed UG2 serials.
|
||||
- "SLPM-66051"
|
||||
- "SLPM-66960"
|
||||
SLPM-66563:
|
||||
@@ -48132,7 +48438,7 @@ SLPM-66567:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLPM-66568:
|
||||
name: "ブラザー イン アームズ ロード トゥ ヒル サーティ [UBISOFT BEST]"
|
||||
name-sort: "ぶらざー いん あーむず ろーど とぅ ひる さーてぃ [UBISOFT BEST]"
|
||||
@@ -48440,6 +48746,13 @@ SLPM-66617:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLPM-66617"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLPM-66232"
|
||||
- "SLPM-66562"
|
||||
- "SLAJ-25075" # Original wrong Black Edition serial.
|
||||
- "SLPM-65766" # UG2 saves can be detected, but the code is unused.
|
||||
SLPM-66618:
|
||||
name: "夢見師 [初回限定版]"
|
||||
name-sort: "ゆめみし [しょかいげんていばん]"
|
||||
@@ -49968,6 +50281,13 @@ SLPM-66869:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLPM-66869"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLPM-66232"
|
||||
- "SLPM-66562"
|
||||
- "SLAJ-25075" # Original wrong Black Edition serial.
|
||||
- "SLPM-65766" # UG2 saves can be detected, but the code is unused.
|
||||
SLPM-66870:
|
||||
name: "星色のおくりもの [初回スペシャル限定版]"
|
||||
name-sort: "ほしいろのおくりもの [しょかいすぺしゃるげんていばん]"
|
||||
@@ -50036,6 +50356,9 @@ SLPM-66881:
|
||||
skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
|
||||
halfPixelOffset: 2 # Fixes depth of field alignment.
|
||||
nativeScaling: 1 # Fixes depth of field.
|
||||
memcardFilters:
|
||||
- "SLPM-66881"
|
||||
- "SLPM-66498" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
|
||||
SLPM-66882:
|
||||
name: "はかれなはーと ~君がために輝きを~ [限定版・サントラボイスCD付]"
|
||||
name-sort: "はかれなはーと きみがためにかがやきを [げんていばん さんとらぼいすCDつき]"
|
||||
@@ -50316,6 +50639,16 @@ SLPM-66932:
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLPM-66932"
|
||||
# Carbon save grants extra money.
|
||||
- "SLPM-55061"
|
||||
- "SLPM-66617"
|
||||
- "SLPM-66869"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLPM-66232"
|
||||
- "SLPM-66562"
|
||||
- "SLPM-65766" # UG2 saves can be detected, but the code is unused.
|
||||
SLPM-66933:
|
||||
name: "君が主で執事が俺で~お仕え日記~ [初回限定版]"
|
||||
name-sort: "きみがあるじでしつじがおれで おつかえにっき [しょかいげんていばん]"
|
||||
@@ -54356,6 +54689,7 @@ SLPS-20485:
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SLPS-20486:
|
||||
name: "太鼓の達人 ドカッ!と大盛り七代目 [ソフト単体]"
|
||||
name-sort: "たいこのたつじん どかっ!とおおもりななだいめ [そふとたんたい]"
|
||||
@@ -54363,6 +54697,7 @@ SLPS-20486:
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SLPS-20487:
|
||||
name: "パチスロキング! 科学忍者隊ガッチャマン"
|
||||
name-sort: "ぱちすろきんぐ! かがくにんじゃたいがっちゃまん"
|
||||
@@ -57940,6 +58275,7 @@ SLPS-25586:
|
||||
halfPixelOffset: 4 # Fixes post positioning.
|
||||
nativeScaling: 1 # Fixes post effects.
|
||||
autoFlush: 2 # Fixes post lighting.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SLPS-25587:
|
||||
name: "シュガシュガルーン 恋もおしゃれもピックアップ!"
|
||||
name-sort: "しゅがしゅがるーん こいもおしゃれもぴっくあっぷ!"
|
||||
@@ -60973,6 +61309,7 @@ SLPS-73252:
|
||||
halfPixelOffset: 4 # Fixes post positioning.
|
||||
nativeScaling: 1 # Fixes post effects.
|
||||
autoFlush: 2 # Fixes post lighting.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SLPS-73253:
|
||||
name: "るろうに剣心-明治剣客浪漫譚- 炎上!京都輪廻 [PlayStation2 the Best]"
|
||||
name-sort: "るろうにけんしん めいじけんかくろまんたん えんじょう きょうとりんね [PlayStation2 the Best]"
|
||||
@@ -62647,7 +62984,6 @@ SLUS-20329:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes lighting.
|
||||
halfPixelOffset: 1 # Fixes vertical lines
|
||||
SLUS-20330:
|
||||
name: "NBA 2K2 - Sega Sports"
|
||||
@@ -64553,7 +64889,7 @@ SLUS-20694:
|
||||
- "SLUS-20710"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Mostly aligns post processing.
|
||||
nativeScaling: 2 # Fixes post processing smoothness and position.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
disablePartialInvalidation: 1 # Fixes textureless graphics ingame.
|
||||
bilinearUpscale: 2 # Gets rid of center vertical line when upscaling.
|
||||
SLUS-20695:
|
||||
@@ -67348,6 +67684,9 @@ SLUS-21182:
|
||||
skipDrawEnd: 1 # Removes large black box around player car till we properly emulate it.
|
||||
halfPixelOffset: 2 # Fixes depth of field alignment.
|
||||
nativeScaling: 1 # Fixes depth of field.
|
||||
memcardFilters:
|
||||
- "SLUS-21182"
|
||||
- "SLUS-21039" # Race Driver 2 save unlocks 'Class A 4WD Track Challenge' in career early.
|
||||
SLUS-21183:
|
||||
name: "Teen Titans"
|
||||
region: "NTSC-U"
|
||||
@@ -67866,6 +68205,9 @@ SLUS-21257:
|
||||
halfPixelOffset: 2 # Fixes blurriness.
|
||||
cpuCLUTRender: 1 # Final colour adjustment LUT.
|
||||
gpuTargetCLUT: 1 # Fixes sun penetrating bridges (along with HPO special).
|
||||
memcardFilters:
|
||||
- "SLUS-21257"
|
||||
- "SLUS-21065" # Underground 2 save grants extra money.
|
||||
SLUS-21258:
|
||||
name: ".hack//G.U. Vol.1 - Rebirth"
|
||||
region: "NTSC-U"
|
||||
@@ -67952,7 +68294,7 @@ SLUS-21267:
|
||||
memcardFilters:
|
||||
- "SLUS-21267"
|
||||
- "SLUS-21351"
|
||||
- "SLUS-21065"
|
||||
- "SLUS-21065" # Underground 2 save grants extra money.
|
||||
SLUS-21268:
|
||||
name: "24 - The Game"
|
||||
region: "NTSC-U"
|
||||
@@ -67985,7 +68327,7 @@ SLUS-21271:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLUS-21272:
|
||||
name: "Super Monkey Ball Adventure"
|
||||
region: "NTSC-U"
|
||||
@@ -68241,7 +68583,7 @@ SLUS-21306:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes alignment on fire effects.
|
||||
halfPixelOffset: 4 # Fixes alignment on fire effects.
|
||||
SLUS-21307:
|
||||
name: "Ice Age 2 - The Meltdown"
|
||||
region: "NTSC-U"
|
||||
@@ -68541,7 +68883,7 @@ SLUS-21351:
|
||||
memcardFilters:
|
||||
- "SLUS-21267"
|
||||
- "SLUS-21351"
|
||||
- "SLUS-21065"
|
||||
- "SLUS-21065" # Underground 2 save grants extra money.
|
||||
SLUS-21352:
|
||||
name: "Dai Senryaku VII Exceed"
|
||||
region: "NTSC-U"
|
||||
@@ -68703,7 +69045,6 @@ SLUS-21373:
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Fix effects upscaling.
|
||||
nativeScaling: 2 # Fixes post effects.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SLUS-21374:
|
||||
name: "Marvel - Ultimate Alliance"
|
||||
@@ -68802,6 +69143,7 @@ SLUS-21386:
|
||||
halfPixelOffset: 4 # Fixes post positioning.
|
||||
nativeScaling: 1 # Fixes post effects.
|
||||
autoFlush: 2 # Fixes post lighting.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SLUS-21387:
|
||||
name: "Warship Gunner 2"
|
||||
region: "NTSC-U"
|
||||
@@ -68883,7 +69225,7 @@ SLUS-21399:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLUS-21400:
|
||||
name: "Monster House"
|
||||
region: "NTSC-U"
|
||||
@@ -69209,7 +69551,6 @@ SLUS-21449:
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes car reflections.
|
||||
mergeSprite: 1 # Fixes bluriness.
|
||||
halfPixelOffset: 4 # Fixes bluriness.
|
||||
nativeScaling: 2 # Fixes post lighting.
|
||||
autoFlush: 1 # Fixes post alignment.
|
||||
@@ -69485,14 +69826,29 @@ SLUS-21493:
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLUS-21493"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLUS-21267"
|
||||
- "SLUS-21351" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
- "SLAJ-25075" # Original wrong Black Edition serial.
|
||||
- "SLUS-21065" # UG2 saves can be detected, but the code is unused.
|
||||
SLUS-21494:
|
||||
name: "Need for Speed - Carbon [Collector's Edition]"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes game hang after opening intro.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 3 # Fixes car headlights.
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLUS-21494"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLUS-21267"
|
||||
- "SLUS-21351" # Black Edition detection is bugged by default, can be fixed with a patch.
|
||||
- "SLAJ-25075" # Original wrong Black Edition serial.
|
||||
- "SLUS-21065" # UG2 saves can be detected, but the code is unused.
|
||||
SLUS-21495:
|
||||
name: "Sudoku, Carol Vorderman's"
|
||||
region: "NTSC-U"
|
||||
@@ -70250,6 +70606,15 @@ SLUS-21658:
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes depth line.
|
||||
memcardFilters:
|
||||
- "SLUS-21658"
|
||||
# Carbon save grants extra money.
|
||||
- "SLUS-21493"
|
||||
- "SLUS-21494"
|
||||
# Most Wanted save grants extra money.
|
||||
- "SLUS-21267"
|
||||
- "SLUS-21351"
|
||||
- "SLUS-21065" # UG2 saves can be detected, but the code is unused.
|
||||
SLUS-21660:
|
||||
name: "Disney Princess - Enchanted Journey"
|
||||
region: "NTSC-U"
|
||||
@@ -71028,6 +71393,13 @@ SLUS-21801:
|
||||
gpuTargetCLUT: 1 # Fixes sun penetration.
|
||||
nativeScaling: 2 # Fixes post alignment.
|
||||
getSkipCount: "GSC_NFSUndercover"
|
||||
memcardFilters:
|
||||
- "SLUS-21801"
|
||||
# Checks from Carbon are left in the code, unused.
|
||||
- "SLUS-21267"
|
||||
- "SLUS-21351"
|
||||
- "SLAJ-25075"
|
||||
- "SLUS-21065"
|
||||
SLUS-21802:
|
||||
name: "Naked Brothers Band - The Video Game"
|
||||
region: "NTSC-U"
|
||||
@@ -72684,7 +73056,7 @@ SLUS-29185:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLUS-29188:
|
||||
name: "Steambot Chronicles [Regular Demo]"
|
||||
region: "NTSC-U"
|
||||
|
||||
@@ -480,6 +480,7 @@
|
||||
030000008916000000fd000000000000,Onza TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||
03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
||||
0300000009120000072f000000000000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:-a2,leftx:a0,lefty:a1,righttrigger:-a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,
|
||||
03000000120c0000f60e000000000000,P4 Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||
@@ -665,7 +666,7 @@
|
||||
03000000952e00002577000000000000,Scuf PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
||||
03000000a30c00002500000000000000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Windows,
|
||||
03000000a30c00002400000000000000,Sega Mega Drive Mini 6B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
|
||||
03000000d804000086e6000000000000,Sega Multi Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
|
||||
03000000d804000086e6000000000000,Sega Multi Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:a2,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
|
||||
0300000000050000289b000000000000,Sega Saturn Adapter,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
|
||||
0300000000f000000800000000000000,Sega Saturn Controller,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b7,righttrigger:b3,start:b0,x:b5,y:b6,platform:Windows,
|
||||
03000000730700000601000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
|
||||
@@ -967,6 +968,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000380700008433000000010000,Mad Catz PS3 Fightstick TE S Plus,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000380700005082000000010000,Mad Catz PS4 Fightpad Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000380700008483000000010000,Mad Catz PS4 Fightstick TE S Plus,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
||||
0300000049190000020400001b010000,Manba One,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
03000000790000000600000007010000,Marvo GT-004,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||
030000008f0e00001330000011010000,Mayflash Controller Adapter,a:b2,b:b4,back:b16,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b12,lefttrigger:b16,leftx:a0,lefty:a2,rightshoulder:b14,rightx:a6~,righty:a4,start:b18,x:b0,y:b6,platform:Mac OS X,
|
||||
03000000790000004318000000010000,Mayflash GameCube Adapter,a:b4,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,
|
||||
@@ -998,7 +1000,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000550900001472000025050000,NVIDIA Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,
|
||||
030000004b120000014d000000010000,Nyko Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000790000001c18000000010000,PB Tails Choc,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
030000006f0e00000901000002010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||
03000000d620000011a7000000020000,PowerA Core Plus Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||
@@ -1070,6 +1071,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000e40a00000307000001000000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Mac OS X,
|
||||
03000000e40a00000207000001000000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Mac OS X,
|
||||
03000000790000001c18000000010000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
03000000790000001c18000003100000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
03000000591c00002400000021000000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000591c00002600000021000000,THEGamepad,a:b2,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Mac OS X,
|
||||
@@ -1519,6 +1521,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000c62400001a54000001010000,PowerA Xbox One Mini Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
03000000d62000000f20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
03000000d62000000520000050010000,PowerA Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
03000000d62000000b20000001010000,PowerA Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000250900000017000010010000,PS/SS/N64 Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b5,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2~,righty:a3,start:b8,platform:Linux,
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 91 KiB |
@@ -111,7 +111,7 @@ layout(binding = 3) uniform sampler2D img_prim_min;
|
||||
//layout(pixel_center_integer) in vec4 gl_FragCoord;
|
||||
#endif
|
||||
|
||||
vec4 fetch_rt()
|
||||
vec4 sample_from_rt()
|
||||
{
|
||||
#if !NEEDS_RT
|
||||
return vec4(0.0);
|
||||
@@ -127,7 +127,7 @@ vec4 fetch_rt()
|
||||
vec4 sample_c(vec2 uv)
|
||||
{
|
||||
#if PS_TEX_IS_FB == 1
|
||||
return fetch_rt();
|
||||
return sample_from_rt();
|
||||
#elif PS_REGION_RECT
|
||||
return texelFetch(TextureSampler, ivec2(uv), 0);
|
||||
#else
|
||||
@@ -312,7 +312,7 @@ int fetch_raw_depth()
|
||||
float multiplier = exp2(32.0f);
|
||||
|
||||
#if PS_TEX_IS_FB == 1
|
||||
return int(fetch_rt().r * multiplier);
|
||||
return int(sample_from_rt().r * multiplier);
|
||||
#else
|
||||
return int(texelFetch(TextureSampler, ivec2(gl_FragCoord.xy), 0).r * multiplier);
|
||||
#endif
|
||||
@@ -321,7 +321,7 @@ int fetch_raw_depth()
|
||||
vec4 fetch_raw_color()
|
||||
{
|
||||
#if PS_TEX_IS_FB == 1
|
||||
return fetch_rt();
|
||||
return sample_from_rt();
|
||||
#else
|
||||
return texelFetch(TextureSampler, ivec2(gl_FragCoord.xy), 0);
|
||||
#endif
|
||||
@@ -697,8 +697,6 @@ vec4 ps_color()
|
||||
|
||||
vec4 C = tfx(T, PSin.c);
|
||||
|
||||
atst(C);
|
||||
|
||||
fog(C, PSin.t_float.z);
|
||||
|
||||
return C;
|
||||
@@ -709,9 +707,9 @@ void ps_fbmask(inout vec4 C)
|
||||
// FIXME do I need special case for 16 bits
|
||||
#if PS_FBMASK
|
||||
#if PS_HDR == 1
|
||||
vec4 RT = trunc(fetch_rt() * 65535.0f);
|
||||
vec4 RT = trunc(sample_from_rt() * 65535.0f);
|
||||
#else
|
||||
vec4 RT = trunc(fetch_rt() * 255.0f + 0.1f);
|
||||
vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
|
||||
#endif
|
||||
C = vec4((uvec4(C) & ~FbMask) | (uvec4(RT) & FbMask));
|
||||
#endif
|
||||
@@ -799,7 +797,7 @@ float As = As_rgba.a;
|
||||
#endif
|
||||
|
||||
#if SW_BLEND_NEEDS_RT
|
||||
vec4 RT = fetch_rt();
|
||||
vec4 RT = sample_from_rt();
|
||||
#else
|
||||
// Not used, but we define it to make the selection below simpler.
|
||||
vec4 RT = vec4(0.0f);
|
||||
@@ -974,9 +972,9 @@ void ps_main()
|
||||
|
||||
#if PS_WRITE_RG == 1
|
||||
// Pseudo 16 bits access.
|
||||
float rt_a = fetch_rt().g;
|
||||
float rt_a = sample_from_rt().g;
|
||||
#else
|
||||
float rt_a = fetch_rt().a;
|
||||
float rt_a = sample_from_rt().a;
|
||||
#endif
|
||||
|
||||
#if (PS_DATE & 3) == 1
|
||||
@@ -1028,9 +1026,9 @@ void ps_main()
|
||||
|
||||
#if SW_AD_TO_HW
|
||||
#if PS_RTA_CORRECTION
|
||||
vec4 RT = trunc(fetch_rt() * 128.0f + 0.1f);
|
||||
vec4 RT = trunc(sample_from_rt() * 128.0f + 0.1f);
|
||||
#else
|
||||
vec4 RT = trunc(fetch_rt() * 255.0f + 0.1f);
|
||||
vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
|
||||
#endif
|
||||
|
||||
vec4 alpha_blend = vec4(RT.a / 128.0f);
|
||||
|
||||
@@ -954,7 +954,7 @@ vec4 ps_color()
|
||||
T.a = float(denorm_c_before.a & 0x80u);
|
||||
#else
|
||||
T.r = float((denorm_c_before.r << 3) & 0xF8u);
|
||||
T.g = float(((denorm_c_before.r >> 2) & 0x38) | ((denorm_c_before.g << 6) & 0xC0u));
|
||||
T.g = float(((denorm_c_before.r >> 2) & 0x38u) | ((denorm_c_before.g << 6) & 0xC0u));
|
||||
T.b = float((denorm_c_before.g << 1) & 0xF8u);
|
||||
T.a = float(denorm_c_before.g & 0x80u);
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,7 @@ find_package(ZLIB REQUIRED) # v1.3, but Mac uses the SDK version.
|
||||
find_package(Zstd 1.5.5 REQUIRED)
|
||||
find_package(LZ4 REQUIRED)
|
||||
find_package(WebP REQUIRED) # v1.3.2, spews an error on Linux because no pkg-config.
|
||||
find_package(SDL2 2.30.4 REQUIRED)
|
||||
find_package(SDL3 3.2.6 REQUIRED)
|
||||
find_package(Freetype 2.11.1 REQUIRED)
|
||||
|
||||
if(USE_VULKAN)
|
||||
|
||||
@@ -168,6 +168,7 @@ else()
|
||||
${DBUS_LINK_LIBRARIES}
|
||||
X11::X11
|
||||
X11::Xrandr
|
||||
X11::Xi
|
||||
)
|
||||
if(USE_BACKTRACE)
|
||||
target_compile_definitions(common PRIVATE "HAS_LIBBACKTRACE=1")
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <mach/task.h>
|
||||
#include <mach/vm_map.h>
|
||||
#include <mutex>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||
|
||||
// Darwin (OSX) is a bit different from Linux when requesting properties of
|
||||
@@ -127,6 +128,69 @@ bool Common::InhibitScreensaver(bool inhibit)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Common::SetMousePosition(int x, int y)
|
||||
{
|
||||
// Little bit ugly but;
|
||||
// Creating mouse move events and posting them wasn't very reliable.
|
||||
// Calling CGWarpMouseCursorPosition without CGAssociateMouseAndMouseCursorPosition(false)
|
||||
// ends up with the cursor feeling "sticky".
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
CGWarpMouseCursorPosition(CGPointMake(x, y));
|
||||
CGAssociateMouseAndMouseCursorPosition(true); // The default state
|
||||
return;
|
||||
}
|
||||
|
||||
CFMachPortRef mouseEventTap = nullptr;
|
||||
CFRunLoopSourceRef mouseRunLoopSource = nullptr;
|
||||
|
||||
static std::function<void(int, int)> fnMouseMoveCb;
|
||||
CGEventRef mouseMoveCallback(CGEventTapProxy, CGEventType type, CGEventRef event, void* arg)
|
||||
{
|
||||
if (type == kCGEventMouseMoved)
|
||||
{
|
||||
const CGPoint location = CGEventGetLocation(event);
|
||||
fnMouseMoveCb(location.x, location.y);
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
bool Common::AttachMousePositionCb(std::function<void(int, int)> cb)
|
||||
{
|
||||
if (!AXIsProcessTrusted())
|
||||
{
|
||||
Console.Warning("Process isn't trusted with accessibility permissions. Mouse tracking will not work!");
|
||||
}
|
||||
|
||||
fnMouseMoveCb = cb;
|
||||
mouseEventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault,
|
||||
CGEventMaskBit(kCGEventMouseMoved), mouseMoveCallback, nullptr);
|
||||
if (!mouseEventTap)
|
||||
{
|
||||
Console.Warning("Unable to create mouse moved event tap. Mouse tracking will not work!");
|
||||
return false;
|
||||
}
|
||||
|
||||
mouseRunLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, mouseEventTap, 0);
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), mouseRunLoopSource, kCFRunLoopCommonModes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Common::DetachMousePositionCb()
|
||||
{
|
||||
if (mouseRunLoopSource)
|
||||
{
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), mouseRunLoopSource, kCFRunLoopCommonModes);
|
||||
CFRelease(mouseRunLoopSource);
|
||||
}
|
||||
if (mouseEventTap)
|
||||
{
|
||||
CFRelease(mouseEventTap);
|
||||
}
|
||||
mouseRunLoopSource = nullptr;
|
||||
mouseEventTap = nullptr;
|
||||
}
|
||||
|
||||
void Threading::Sleep(int ms)
|
||||
{
|
||||
usleep(1000 * ms);
|
||||
|
||||
@@ -1354,8 +1354,11 @@ static u32 TranslateWin32Attributes(u32 Win32Attributes)
|
||||
}
|
||||
|
||||
static u32 RecursiveFindFiles(const char* origin_path, const char* parent_path, const char* path, const char* pattern,
|
||||
u32 flags, FileSystem::FindResultsArray* results, std::vector<std::string>& visited)
|
||||
u32 flags, FileSystem::FindResultsArray* results, std::vector<std::string>& visited, ProgressCallback* cancel)
|
||||
{
|
||||
if (cancel && cancel->IsCancelled())
|
||||
return 0;
|
||||
|
||||
std::string search_dir;
|
||||
if (path)
|
||||
{
|
||||
@@ -1427,11 +1430,11 @@ static u32 RecursiveFindFiles(const char* origin_path, const char* parent_path,
|
||||
if (parent_path)
|
||||
{
|
||||
const std::string recurse_dir = fmt::format("{}\\{}", parent_path, path);
|
||||
nFiles += RecursiveFindFiles(origin_path, recurse_dir.c_str(), utf8_filename.c_str(), pattern, flags, results, visited);
|
||||
nFiles += RecursiveFindFiles(origin_path, recurse_dir.c_str(), utf8_filename.c_str(), pattern, flags, results, visited, cancel);
|
||||
}
|
||||
else
|
||||
{
|
||||
nFiles += RecursiveFindFiles(origin_path, path, utf8_filename.c_str(), pattern, flags, results, visited);
|
||||
nFiles += RecursiveFindFiles(origin_path, path, utf8_filename.c_str(), pattern, flags, results, visited, cancel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1494,7 +1497,7 @@ static u32 RecursiveFindFiles(const char* origin_path, const char* parent_path,
|
||||
return nFiles;
|
||||
}
|
||||
|
||||
bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results)
|
||||
bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results, ProgressCallback* cancel)
|
||||
{
|
||||
// has a path
|
||||
if (path[0] == '\0')
|
||||
@@ -1514,7 +1517,7 @@ bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, Fin
|
||||
}
|
||||
|
||||
// enter the recursive function
|
||||
if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited) == 0)
|
||||
if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited, cancel) == 0)
|
||||
return false;
|
||||
|
||||
if (flags & FILESYSTEM_FIND_SORT_BY_NAME)
|
||||
@@ -2046,8 +2049,11 @@ bool FileSystem::DeleteSymbolicLink(const char* path, Error* error)
|
||||
static_assert(sizeof(off_t) == sizeof(s64));
|
||||
|
||||
static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, const char* Path, const char* Pattern,
|
||||
u32 Flags, FileSystem::FindResultsArray* pResults, std::vector<std::string>& visited)
|
||||
u32 Flags, FileSystem::FindResultsArray* pResults, std::vector<std::string>& visited, ProgressCallback* cancel)
|
||||
{
|
||||
if (cancel && cancel->IsCancelled())
|
||||
return 0;
|
||||
|
||||
std::string tempStr;
|
||||
if (Path)
|
||||
{
|
||||
@@ -2118,11 +2124,11 @@ static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, co
|
||||
if (ParentPath)
|
||||
{
|
||||
const std::string recursive_dir = fmt::format("{}/{}", ParentPath, Path);
|
||||
nFiles += RecursiveFindFiles(OriginPath, recursive_dir.c_str(), pDirEnt->d_name, Pattern, Flags, pResults, visited);
|
||||
nFiles += RecursiveFindFiles(OriginPath, recursive_dir.c_str(), pDirEnt->d_name, Pattern, Flags, pResults, visited, cancel);
|
||||
}
|
||||
else
|
||||
{
|
||||
nFiles += RecursiveFindFiles(OriginPath, Path, pDirEnt->d_name, Pattern, Flags, pResults, visited);
|
||||
nFiles += RecursiveFindFiles(OriginPath, Path, pDirEnt->d_name, Pattern, Flags, pResults, visited, cancel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2177,7 +2183,7 @@ static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, co
|
||||
return nFiles;
|
||||
}
|
||||
|
||||
bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results)
|
||||
bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results, ProgressCallback* cancel)
|
||||
{
|
||||
// has a path
|
||||
if (path[0] == '\0')
|
||||
@@ -2197,7 +2203,7 @@ bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, Fin
|
||||
}
|
||||
|
||||
// enter the recursive function
|
||||
if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited) == 0)
|
||||
if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited, cancel) == 0)
|
||||
return false;
|
||||
|
||||
if (flags & FILESYSTEM_FIND_SORT_BY_NAME)
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace FileSystem
|
||||
std::vector<std::string> GetRootDirectoryList();
|
||||
|
||||
/// Search for files
|
||||
bool FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results);
|
||||
bool FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results, ProgressCallback* cancel = nullptr);
|
||||
|
||||
/// Stat file
|
||||
bool StatFile(const char* path, struct stat* st);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "common/Pcsx2Defs.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -198,4 +199,8 @@ namespace Common
|
||||
/// Abstracts platform-specific code for asynchronously playing a sound.
|
||||
/// On Windows, this will use PlaySound(). On Linux, it will shell out to aplay. On MacOS, it uses NSSound.
|
||||
bool PlaySoundAsync(const char* path);
|
||||
|
||||
void SetMousePosition(int x, int y);
|
||||
bool AttachMousePositionCb(std::function<void(int,int)> cb);
|
||||
void DetachMousePositionCb();
|
||||
} // namespace Common
|
||||
|
||||
@@ -13,17 +13,20 @@
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <optional>
|
||||
#include <dbus/dbus.h>
|
||||
#include <spawn.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <dbus/dbus.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <ctype.h>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
|
||||
// Returns 0 on failure (not supported by the operating system).
|
||||
u64 GetPhysicalMemory()
|
||||
@@ -177,6 +180,111 @@ bool Common::InhibitScreensaver(bool inhibit)
|
||||
return SetScreensaverInhibitDBus(inhibit, "PCSX2", "PCSX2 VM is running.");
|
||||
}
|
||||
|
||||
void Common::SetMousePosition(int x, int y)
|
||||
{
|
||||
Display* display = XOpenDisplay(nullptr);
|
||||
if (!display)
|
||||
return;
|
||||
|
||||
Window root = DefaultRootWindow(display);
|
||||
XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);
|
||||
XFlush(display);
|
||||
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
|
||||
static std::function<void(int, int)> fnMouseMoveCb;
|
||||
static std::atomic<bool> trackingMouse = false;
|
||||
static std::thread mouseThread;
|
||||
|
||||
void mouseEventLoop()
|
||||
{
|
||||
Threading::SetNameOfCurrentThread("X11 Mouse Thread");
|
||||
Display* display = XOpenDisplay(nullptr);
|
||||
if (!display)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int opcode, eventcode, error;
|
||||
if (!XQueryExtension(display, "XInputExtension", &opcode, &eventcode, &error))
|
||||
{
|
||||
XCloseDisplay(display);
|
||||
return;
|
||||
}
|
||||
|
||||
const Window root = DefaultRootWindow(display);
|
||||
XIEventMask evmask;
|
||||
unsigned char mask[(XI_LASTEVENT + 7) / 8] = {0};
|
||||
|
||||
evmask.deviceid = XIAllDevices;
|
||||
evmask.mask_len = sizeof(mask);
|
||||
evmask.mask = mask;
|
||||
XISetMask(mask, XI_RawMotion);
|
||||
|
||||
XISelectEvents(display, root, &evmask, 1);
|
||||
XSync(display, False);
|
||||
|
||||
XEvent event;
|
||||
while (trackingMouse)
|
||||
{
|
||||
// XNextEvent is blocking, this is a zombie process risk if no events arrive
|
||||
// while we are trying to shutdown.
|
||||
// https://nrk.neocities.org/articles/x11-timeout-with-xsyncalarm might be
|
||||
// a better solution than using XPending.
|
||||
if (!XPending(display))
|
||||
{
|
||||
Threading::Sleep(1);
|
||||
Threading::SpinWait();
|
||||
continue;
|
||||
}
|
||||
|
||||
XNextEvent(display, &event);
|
||||
if (event.xcookie.type == GenericEvent &&
|
||||
event.xcookie.extension == opcode &&
|
||||
XGetEventData(display, &event.xcookie))
|
||||
{
|
||||
XIRawEvent* raw_event = reinterpret_cast<XIRawEvent*>(event.xcookie.data);
|
||||
if (raw_event->evtype == XI_RawMotion)
|
||||
{
|
||||
Window w;
|
||||
int root_x, root_y, win_x, win_y;
|
||||
unsigned int mask;
|
||||
XQueryPointer(display, root, &w, &w, &root_x, &root_y, &win_x, &win_y, &mask);
|
||||
|
||||
if (fnMouseMoveCb)
|
||||
fnMouseMoveCb(root_x, root_y);
|
||||
}
|
||||
XFreeEventData(display, &event.xcookie);
|
||||
}
|
||||
}
|
||||
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
|
||||
bool Common::AttachMousePositionCb(std::function<void(int, int)> cb)
|
||||
{
|
||||
fnMouseMoveCb = cb;
|
||||
|
||||
if (trackingMouse)
|
||||
return true;
|
||||
|
||||
trackingMouse = true;
|
||||
mouseThread = std::thread(mouseEventLoop);
|
||||
mouseThread.detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Common::DetachMousePositionCb()
|
||||
{
|
||||
trackingMouse = false;
|
||||
fnMouseMoveCb = nullptr;
|
||||
if (mouseThread.joinable())
|
||||
{
|
||||
mouseThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
bool Common::PlaySoundAsync(const char* path)
|
||||
{
|
||||
#ifdef __linux__
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "common/Console.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/HostSys.h"
|
||||
#include "common/RedtapeWindows.h"
|
||||
@@ -86,6 +87,61 @@ bool Common::InhibitScreensaver(bool inhibit)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Common::SetMousePosition(int x, int y)
|
||||
{
|
||||
SetCursorPos(x, y);
|
||||
}
|
||||
|
||||
/*
|
||||
static HHOOK mouseHook = nullptr;
|
||||
static std::function<void(int, int)> fnMouseMoveCb;
|
||||
LRESULT CALLBACK Mousecb(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (nCode >= 0 && wParam == WM_MOUSEMOVE)
|
||||
{
|
||||
MSLLHOOKSTRUCT* mouse = (MSLLHOOKSTRUCT*)lParam;
|
||||
fnMouseMoveCb(mouse->pt.x, mouse->pt.y);
|
||||
}
|
||||
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
|
||||
}
|
||||
*/
|
||||
|
||||
// This (and the above) works, but is not recommended on Windows and is only here for consistency.
|
||||
// Defer to using raw input instead.
|
||||
bool Common::AttachMousePositionCb(std::function<void(int, int)> cb)
|
||||
{
|
||||
/*
|
||||
if (mouseHook)
|
||||
Common::DetachMousePositionCb();
|
||||
|
||||
fnMouseMoveCb = cb;
|
||||
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, Mousecb, GetModuleHandle(NULL), 0);
|
||||
if (!mouseHook)
|
||||
{
|
||||
Console.Warning("Failed to set mouse hook: %d", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(PCSX2_DEBUG) || defined(PCSX2_DEVBUILD)
|
||||
static bool warned = false;
|
||||
if (!warned)
|
||||
{
|
||||
Console.Warning("Mouse hooks are enabled, and this isn't a release build! Using a debugger, or loading symbols, _will_ stall the hook and cause global mouse lag.");
|
||||
warned = true;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
void Common::DetachMousePositionCb()
|
||||
{
|
||||
/*
|
||||
UnhookWindowsHookEx(mouseHook);
|
||||
mouseHook = nullptr;
|
||||
*/
|
||||
}
|
||||
|
||||
bool Common::PlaySoundAsync(const char* path)
|
||||
{
|
||||
const std::wstring wpath = FileSystem::GetWin32Path(path);
|
||||
|
||||
@@ -119,6 +119,12 @@ namespace x86Emitter
|
||||
xImplSimd_DestRegSSE VPD;
|
||||
};
|
||||
|
||||
struct xImplSimd_PBlend
|
||||
{
|
||||
xImplSimd_DestRegImmSSE W;
|
||||
xImplSimd_DestRegSSE VB;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xImplSimd_PMove
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
@@ -500,6 +500,7 @@ namespace x86Emitter
|
||||
extern const xImplSimd_MovHL_RtoR xMOVLH;
|
||||
extern const xImplSimd_MovHL_RtoR xMOVHL;
|
||||
|
||||
extern const xImplSimd_PBlend xPBLEND;
|
||||
extern const xImplSimd_Blend xBLEND;
|
||||
extern const xImplSimd_PMove xPMOVSX;
|
||||
extern const xImplSimd_PMove xPMOVZX;
|
||||
|
||||
@@ -556,12 +556,18 @@ namespace x86Emitter
|
||||
const xImplSimd_MovHL_RtoR xMOVLH = {0x16};
|
||||
const xImplSimd_MovHL_RtoR xMOVHL = {0x12};
|
||||
|
||||
const xImplSimd_PBlend xPBLEND =
|
||||
{
|
||||
{0x66, 0x0e3a}, // W
|
||||
{0x66, 0x1038}, // VB
|
||||
};
|
||||
|
||||
const xImplSimd_Blend xBLEND =
|
||||
{
|
||||
{0x66, 0x0c3a}, // PS
|
||||
{0x66, 0x0d3a}, // PD
|
||||
{0x66, 0x1438}, // VPS
|
||||
{0x66, 0x1538}, // VPD
|
||||
{
|
||||
{0x66, 0x0c3a}, // PS
|
||||
{0x66, 0x0d3a}, // PD
|
||||
{0x66, 0x1438}, // VPS
|
||||
{0x66, 0x1538}, // VPD
|
||||
};
|
||||
|
||||
const xImplSimd_PMove xPMOVSX = {0x2038};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL2.lib;zlib.lib;zstd.lib</AdditionalDependencies>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL3.lib;zlib.lib;zstd.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
@@ -15,7 +15,7 @@
|
||||
<DepsDLLs Include="$(DepsBinDir)libsharpyuv.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)libwebp.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)lz4.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)SDL2.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)SDL3.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)shaderc_shared.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)zlib1.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)zstd.dll" />
|
||||
|
||||
@@ -174,6 +174,14 @@ std::unique_ptr<ProgressCallback> Host::CreateHostProgressCallback()
|
||||
return ProgressCallback::CreateNullProgressCallback();
|
||||
}
|
||||
|
||||
void Host::ReportInfoAsync(const std::string_view title, const std::string_view message)
|
||||
{
|
||||
if (!title.empty() && !message.empty())
|
||||
INFO_LOG("ReportInfoAsync: {}: {}", title, message);
|
||||
else if (!message.empty())
|
||||
INFO_LOG("ReportInfoAsync: {}", message);
|
||||
}
|
||||
|
||||
void Host::ReportErrorAsync(const std::string_view title, const std::string_view message)
|
||||
{
|
||||
if (!title.empty() && !message.empty())
|
||||
@@ -246,7 +254,7 @@ void Host::BeginPresentFrame()
|
||||
GSJoinSnapshotThreads();
|
||||
|
||||
// queue dumping of this frame
|
||||
std::string dump_path(fmt::format("{}_frame{}.png", s_output_prefix, s_dump_frame_number));
|
||||
std::string dump_path(fmt::format("{}_frame{:05}.png", s_output_prefix, s_dump_frame_number));
|
||||
GSQueueSnapshot(dump_path);
|
||||
}
|
||||
|
||||
@@ -443,8 +451,17 @@ static void PrintCommandLineHelp(const char* progname)
|
||||
std::fprintf(stderr, " -help: Displays this information and exits.\n");
|
||||
std::fprintf(stderr, " -version: Displays version information and exits.\n");
|
||||
std::fprintf(stderr, " -dumpdir <dir>: Frame dump directory (will be dumped as filename_frameN.png).\n");
|
||||
std::fprintf(stderr, " -dump [rt|tex|z|f|a|i]: Enabling dumping of render target, texture, z buffer, frame, "
|
||||
"alphas, and info (context, vertices), respectively, per draw. Generates lots of data.\n");
|
||||
std::fprintf(stderr, " -dumprange N[,L,B]: Start dumping from draw N (base 0), stops after L draws, and only "
|
||||
"those draws that are multiples of B (intersection of -dumprange and -dumprangef used)."
|
||||
"Defaults to 0,-1,1 (all draws). Only used if -dump used.\n");
|
||||
std::fprintf(stderr, " -dumprangef NF[,LF,BF]: Start dumping from frame NF (base 0), stops after LF frames, "
|
||||
"and only those frames that are multiples of BF (intersection of -dumprange and -dumprangef used).\n"
|
||||
"Defaults to 0,-1,1 (all frames). Only used if -dump is used.\n");
|
||||
std::fprintf(stderr, " -loop <count>: Loops dump playback N times. Defaults to 1. 0 will loop infinitely.\n");
|
||||
std::fprintf(stderr, " -renderer <renderer>: Sets the graphics renderer. Defaults to Auto.\n");
|
||||
std::fprintf(stderr, " -swthreads <threads>: Sets the number of threads for the software renderer.\n");
|
||||
std::fprintf(stderr, " -window: Forces a window to be displayed.\n");
|
||||
std::fprintf(stderr, " -surfaceless: Disables showing a window.\n");
|
||||
std::fprintf(stderr, " -logfile <filename>: Writes emu log to filename.\n");
|
||||
@@ -465,6 +482,7 @@ void GSRunner::InitializeConsole()
|
||||
|
||||
bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& params)
|
||||
{
|
||||
std::string dumpdir; // Save from argument -dumpdir for creating sub-directories
|
||||
bool no_more_args = false;
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
@@ -485,7 +503,7 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-dumpdir"))
|
||||
{
|
||||
s_output_prefix = StringUtil::StripWhitespace(argv[++i]);
|
||||
dumpdir = s_output_prefix = StringUtil::StripWhitespace(argv[++i]);
|
||||
if (s_output_prefix.empty())
|
||||
{
|
||||
Console.Error("Invalid dump directory specified.");
|
||||
@@ -500,6 +518,86 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-dump"))
|
||||
{
|
||||
std::string str(argv[++i]);
|
||||
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "dump", true);
|
||||
|
||||
if (str.find("rt") != std::string::npos)
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveRT", true);
|
||||
if (str.find("f") != std::string::npos)
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveFrame", true);
|
||||
if (str.find("tex") != std::string::npos)
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveTexture", true);
|
||||
if (str.find("z") != std::string::npos)
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveDepth", true);
|
||||
if (str.find("a") != std::string::npos)
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveAlpha", true);
|
||||
if (str.find("i") != std::string::npos)
|
||||
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveInfo", true);
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-dumprange"))
|
||||
{
|
||||
std::string str(argv[++i]);
|
||||
|
||||
std::vector<std::string_view> split = StringUtil::SplitString(str, ',');
|
||||
int start = 0;
|
||||
int num = -1;
|
||||
int by = 1;
|
||||
if (split.size() > 0)
|
||||
{
|
||||
start = StringUtil::FromChars<int>(split[0]).value_or(0);
|
||||
}
|
||||
if (split.size() > 1)
|
||||
{
|
||||
num = StringUtil::FromChars<int>(split[1]).value_or(-1);
|
||||
}
|
||||
if (split.size() > 2)
|
||||
{
|
||||
by = std::max(1, StringUtil::FromChars<int>(split[2]).value_or(1));
|
||||
}
|
||||
s_settings_interface.SetIntValue("EmuCore/GS", "SaveDrawStart", start);
|
||||
s_settings_interface.SetIntValue("EmuCore/GS", "SaveDrawCount", num);
|
||||
s_settings_interface.SetIntValue("EmuCore/GS", "SaveDrawBy", by);
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-dumprangef"))
|
||||
{
|
||||
std::string str(argv[++i]);
|
||||
|
||||
std::vector<std::string_view> split = StringUtil::SplitString(str, ',');
|
||||
int start = 0;
|
||||
int num = -1;
|
||||
int by = 1;
|
||||
if (split.size() > 0)
|
||||
{
|
||||
start = StringUtil::FromChars<int>(split[0]).value_or(0);
|
||||
}
|
||||
if (split.size() > 1)
|
||||
{
|
||||
num = StringUtil::FromChars<int>(split[1]).value_or(-1);
|
||||
}
|
||||
if (split.size() > 2)
|
||||
{
|
||||
by = std::max(1, StringUtil::FromChars<int>(split[2]).value_or(1));
|
||||
}
|
||||
s_settings_interface.SetIntValue("EmuCore/GS", "SaveFrameStart", start);
|
||||
s_settings_interface.SetIntValue("EmuCore/GS", "SaveFrameCount", num);
|
||||
s_settings_interface.SetIntValue("EmuCore/GS", "SaveFrameBy", by);
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-dumpdirhw"))
|
||||
{
|
||||
s_settings_interface.SetStringValue("EmuCore/GS", "HWDumpDirectory", argv[++i]);
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-dumpdirsw"))
|
||||
{
|
||||
s_settings_interface.SetStringValue("EmuCore/GS", "SWDumpDirectory", argv[++i]);
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-loop"))
|
||||
{
|
||||
s_loop_count = StringUtil::FromChars<s32>(argv[++i]).value_or(0);
|
||||
@@ -543,6 +641,19 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa
|
||||
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", static_cast<int>(type));
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-swthreads"))
|
||||
{
|
||||
const int swthreads = StringUtil::FromChars<int>(argv[++i]).value_or(0);
|
||||
if (swthreads < 0)
|
||||
{
|
||||
Console.WriteLn("Invalid number of software threads");
|
||||
return false;
|
||||
}
|
||||
|
||||
Console.WriteLn(fmt::format("Setting number of software threads to {}", swthreads));
|
||||
s_settings_interface.SetIntValue("EmuCore/GS", "SWExtraThreads", swthreads);
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-renderhacks"))
|
||||
{
|
||||
std::string str(argv[++i]);
|
||||
@@ -643,6 +754,18 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_settings_interface.GetBoolValue("EmuCore/GS", "dump") && !dumpdir.empty())
|
||||
{
|
||||
if (s_settings_interface.GetStringValue("EmuCore/GS", "HWDumpDirectory").empty())
|
||||
s_settings_interface.SetStringValue("EmuCore/GS", "HWDumpDirectory", dumpdir.c_str());
|
||||
if (s_settings_interface.GetStringValue("EmuCore/GS", "SWDumpDirectory").empty())
|
||||
s_settings_interface.SetStringValue("EmuCore/GS", "SWDumpDirectory", dumpdir.c_str());
|
||||
|
||||
// Disable saving frames with SaveSnapshotToMemory()
|
||||
// Instead we save more "raw" snapshots when using -dump.
|
||||
s_output_prefix = "";
|
||||
}
|
||||
|
||||
// set up the frame dump directory
|
||||
if (!s_output_prefix.empty())
|
||||
{
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
<string>4</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -453,7 +453,7 @@ std::vector<SearchResult> startWorker(DebugInterface* cpu, const SearchType type
|
||||
isSigned ? searchWorker<s32>(cpu, searchResults, type, comparison, start, end, value.toInt(nullptr, base)) : searchWorker<u32>(cpu, searchResults, type, comparison, start, end, value.toUInt(nullptr, base));
|
||||
break;
|
||||
case SearchType::Int64Type:
|
||||
isSigned ? searchWorker<s64>(cpu, searchResults, type, comparison, start, end, value.toLong(nullptr, base)) : searchWorker<s64>(cpu, searchResults, type, comparison, start, end, value.toULongLong(nullptr, base));
|
||||
isSigned ? searchWorker<s64>(cpu, searchResults, type, comparison, start, end, value.toLongLong(nullptr, base)) : searchWorker<u64>(cpu, searchResults, type, comparison, start, end, value.toULongLong(nullptr, base));
|
||||
break;
|
||||
case SearchType::FloatType:
|
||||
searchWorker<float>(cpu, searchResults, type, comparison, start, end, value.toFloat());
|
||||
|
||||
@@ -99,11 +99,23 @@ static QString s_current_disc_serial;
|
||||
static quint32 s_current_disc_crc;
|
||||
static quint32 s_current_running_crc;
|
||||
|
||||
static bool s_record_on_start = false;
|
||||
static QString s_path_to_recording_for_record_on_start;
|
||||
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
pxAssert(!g_main_window);
|
||||
g_main_window = this;
|
||||
|
||||
// Native window rendering is broken in wayland.
|
||||
// Let's work around it by disabling it for every widget besides
|
||||
// DisplayWidget.
|
||||
// Additionally, alien widget rendering is much more performant, so we
|
||||
// should have a nice responsiveness boost in our UI :)
|
||||
// QTBUG-133919, reported upstream by govanify
|
||||
QGuiApplication::setAttribute(Qt::AA_NativeWindows, false);
|
||||
QGuiApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
s_use_central_widget = DisplayContainer::isRunningOnWayland();
|
||||
#endif
|
||||
@@ -115,6 +127,8 @@ MainWindow::~MainWindow()
|
||||
cancelGameListRefresh();
|
||||
destroySubWindows();
|
||||
|
||||
Common::DetachMousePositionCb();
|
||||
|
||||
// we compare here, since recreate destroys the window later
|
||||
if (g_main_window == this)
|
||||
g_main_window = nullptr;
|
||||
@@ -150,6 +164,9 @@ void MainWindow::initialize()
|
||||
#ifdef _WIN32
|
||||
registerForDeviceNotifications();
|
||||
#endif
|
||||
|
||||
if (Host::GetBoolSettingValue("EmuCore", "EnableMouseLock", false))
|
||||
setupMouseMoveHandler();
|
||||
}
|
||||
|
||||
// TODO: Figure out how to set this in the .ui file
|
||||
@@ -724,7 +741,48 @@ void MainWindow::updateAdvancedSettingsVisibility()
|
||||
void MainWindow::onVideoCaptureToggled(bool checked)
|
||||
{
|
||||
if (!s_vm_valid)
|
||||
{
|
||||
if (!s_record_on_start)
|
||||
{
|
||||
QMessageBox msgbox(this);
|
||||
msgbox.setIcon(QMessageBox::Question);
|
||||
msgbox.setWindowIcon(QtHost::GetAppIcon());
|
||||
msgbox.setWindowTitle(tr("Record On Boot"));
|
||||
msgbox.setWindowModality(Qt::WindowModal);
|
||||
msgbox.setText(tr("Did you want to start recording on boot?"));
|
||||
msgbox.addButton(QMessageBox::Yes);
|
||||
msgbox.addButton(QMessageBox::No);
|
||||
msgbox.setDefaultButton(QMessageBox::Yes);
|
||||
if (msgbox.exec() == QMessageBox::Yes)
|
||||
{
|
||||
const QString container(QString::fromStdString(
|
||||
Host::GetStringSettingValue("EmuCore/GS", "CaptureContainer", Pcsx2Config::GSOptions::DEFAULT_CAPTURE_CONTAINER)));
|
||||
const QString filter(tr("%1 Files (*.%2)").arg(container.toUpper()).arg(container));
|
||||
|
||||
QString temp(QStringLiteral("%1.%2").arg(QString::fromStdString(GSGetBaseVideoFilename())).arg(container));
|
||||
temp = QDir::toNativeSeparators(QFileDialog::getSaveFileName(this, tr("Video Capture"), temp, filter));
|
||||
s_path_to_recording_for_record_on_start = temp;
|
||||
if (s_path_to_recording_for_record_on_start.isEmpty())
|
||||
return;
|
||||
s_record_on_start = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox msgbox(this);
|
||||
msgbox.setIcon(QMessageBox::Question);
|
||||
msgbox.setWindowIcon(QtHost::GetAppIcon());
|
||||
msgbox.setWindowTitle(tr("Record On Boot"));
|
||||
msgbox.setWindowModality(Qt::WindowModal);
|
||||
msgbox.setText(tr("Did you want to cancel recording on boot?"));
|
||||
msgbox.addButton(QMessageBox::Yes);
|
||||
msgbox.addButton(QMessageBox::No);
|
||||
msgbox.setDefaultButton(QMessageBox::Yes);
|
||||
if (msgbox.exec() == QMessageBox::Yes)
|
||||
s_record_on_start = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset the checked state, we'll get updated by the GS thread.
|
||||
QSignalBlocker sb(m_ui.actionVideoCapture);
|
||||
@@ -736,16 +794,26 @@ void MainWindow::onVideoCaptureToggled(bool checked)
|
||||
return;
|
||||
}
|
||||
|
||||
const QString container(QString::fromStdString(
|
||||
Host::GetStringSettingValue("EmuCore/GS", "CaptureContainer", Pcsx2Config::GSOptions::DEFAULT_CAPTURE_CONTAINER)));
|
||||
const QString filter(tr("%1 Files (*.%2)").arg(container.toUpper()).arg(container));
|
||||
if (s_record_on_start && !s_path_to_recording_for_record_on_start.isEmpty())
|
||||
{
|
||||
// We can't start recording immediately, this is called before full GS init (specifically the fps amount)
|
||||
// and GSCapture ends up unhappy.
|
||||
// TODO: Pass some sort of flag or callback to the GS thread to start recording on frame 0.
|
||||
Host::AddOSDMessage(tr("Recording will start in a moment").toStdString(), 3.0f);
|
||||
QTimer::singleShot(2000, []() { g_emu_thread->beginCapture(s_path_to_recording_for_record_on_start); });
|
||||
}
|
||||
else
|
||||
{
|
||||
const QString container(QString::fromStdString(
|
||||
Host::GetStringSettingValue("EmuCore/GS", "CaptureContainer", Pcsx2Config::GSOptions::DEFAULT_CAPTURE_CONTAINER)));
|
||||
const QString filter(tr("%1 Files (*.%2)").arg(container.toUpper()).arg(container));
|
||||
|
||||
QString path(QStringLiteral("%1.%2").arg(QString::fromStdString(GSGetBaseVideoFilename())).arg(container));
|
||||
path = QDir::toNativeSeparators(QFileDialog::getSaveFileName(this, tr("Video Capture"), path, filter));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
g_emu_thread->beginCapture(path);
|
||||
QString path(QStringLiteral("%1.%2").arg(QString::fromStdString(GSGetBaseVideoFilename())).arg(container));
|
||||
path = QDir::toNativeSeparators(QFileDialog::getSaveFileName(this, tr("Video Capture"), path, filter));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
g_emu_thread->beginCapture(path);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onCaptureStarted(const QString& filename)
|
||||
@@ -890,8 +958,6 @@ void MainWindow::updateEmulationActions(bool starting, bool running, bool stoppi
|
||||
m_ui.actionToolbarSaveState->setEnabled(running);
|
||||
|
||||
m_ui.actionViewGameProperties->setEnabled(running);
|
||||
|
||||
m_ui.actionVideoCapture->setEnabled(running);
|
||||
if (!running && m_ui.actionVideoCapture->isChecked())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.actionVideoCapture);
|
||||
@@ -1071,6 +1137,21 @@ bool MainWindow::shouldHideMainWindow() const
|
||||
QtHost::InNoGUIMode();
|
||||
}
|
||||
|
||||
bool MainWindow::shouldMouseLock() const
|
||||
{
|
||||
if (!s_vm_valid || s_vm_paused)
|
||||
return false;
|
||||
|
||||
if (!Host::GetBoolSettingValue("EmuCore", "EnableMouseLock", false))
|
||||
return false;
|
||||
|
||||
bool windowsHidden = (!m_debugger_window || m_debugger_window->isHidden()) &&
|
||||
(!m_controller_settings_window || m_controller_settings_window->isHidden()) &&
|
||||
(!m_settings_window || m_settings_window->isHidden());
|
||||
|
||||
return windowsHidden && (isActiveWindow() || isRenderingFullscreen());
|
||||
}
|
||||
|
||||
bool MainWindow::shouldAbortForMemcardBusy(const VMLock& lock)
|
||||
{
|
||||
if (MemcardBusy::IsBusy() && !GSDumpReplayer::IsReplayingDump())
|
||||
@@ -1140,6 +1221,11 @@ void MainWindow::cancelGameListRefresh()
|
||||
m_game_list_widget->cancelRefresh();
|
||||
}
|
||||
|
||||
void MainWindow::reportInfo(const QString& title, const QString& message)
|
||||
{
|
||||
QMessageBox::information(this, title, message);
|
||||
}
|
||||
|
||||
void MainWindow::reportError(const QString& title, const QString& message)
|
||||
{
|
||||
QMessageBox::critical(this, title, message);
|
||||
@@ -1962,6 +2048,11 @@ void MainWindow::onVMStarted()
|
||||
updateWindowTitle();
|
||||
updateStatusBarWidgetVisibility();
|
||||
updateInputRecordingActions(true);
|
||||
if (s_record_on_start)
|
||||
{
|
||||
m_ui.actionVideoCapture->setChecked(true);
|
||||
s_record_on_start = false;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onVMPaused()
|
||||
@@ -2234,6 +2325,15 @@ void MainWindow::registerForDeviceNotifications()
|
||||
DEV_BROADCAST_DEVICEINTERFACE_W filter = {sizeof(DEV_BROADCAST_DEVICEINTERFACE_W), DBT_DEVTYP_DEVICEINTERFACE};
|
||||
m_device_notification_handle =
|
||||
RegisterDeviceNotificationW((HANDLE)winId(), &filter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
|
||||
|
||||
// Set up the raw input device for mouse grabbing
|
||||
RAWINPUTDEVICE rid;
|
||||
rid.usUsagePage = 0x01; // Generic desktop controls
|
||||
rid.usUsage = 0x02; // Mouse
|
||||
rid.dwFlags = RIDEV_INPUTSINK;
|
||||
rid.hwndTarget = (HWND)winId();
|
||||
|
||||
RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2262,6 +2362,26 @@ bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr
|
||||
*result = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg->message == WM_INPUT)
|
||||
{
|
||||
UINT dwSize = 40;
|
||||
static BYTE lpb[40];
|
||||
if (GetRawInputData((HRAWINPUT)msg->lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)))
|
||||
{
|
||||
const RAWINPUT* raw = (RAWINPUT*)lpb;
|
||||
if (raw->header.dwType == RIM_TYPEMOUSE)
|
||||
{
|
||||
const RAWMOUSE& mouse = raw->data.mouse;
|
||||
if (mouse.usFlags == MOUSE_MOVE_ABSOLUTE || mouse.usFlags == MOUSE_MOVE_RELATIVE)
|
||||
{
|
||||
POINT cursorPos;
|
||||
GetCursorPos(&cursorPos);
|
||||
checkMousePosition(cursorPos.x, cursorPos.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QMainWindow::nativeEvent(eventType, message, result);
|
||||
@@ -2541,6 +2661,53 @@ QWidget* MainWindow::getDisplayContainer() const
|
||||
return (m_display_container ? static_cast<QWidget*>(m_display_container) : static_cast<QWidget*>(m_display_widget));
|
||||
}
|
||||
|
||||
void MainWindow::setupMouseMoveHandler()
|
||||
{
|
||||
auto mouse_cb_fn = [](int x, int y)
|
||||
{
|
||||
if(g_main_window)
|
||||
g_main_window->checkMousePosition(x, y);
|
||||
};
|
||||
|
||||
if(!Common::AttachMousePositionCb(mouse_cb_fn))
|
||||
{
|
||||
Console.Warning("Unable to setup mouse position cb!");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void MainWindow::checkMousePosition(int x, int y)
|
||||
{
|
||||
if (!shouldMouseLock())
|
||||
return;
|
||||
|
||||
const QPoint globalCursorPos = {x, y};
|
||||
QRect windowBounds = isRenderingFullscreen() ? screen()->geometry() : geometry();
|
||||
if (windowBounds.contains(globalCursorPos))
|
||||
return;
|
||||
|
||||
Common::SetMousePosition(
|
||||
std::clamp(globalCursorPos.x(), windowBounds.left(), windowBounds.right()),
|
||||
std::clamp(globalCursorPos.y(), windowBounds.top(), windowBounds.bottom()));
|
||||
|
||||
/*
|
||||
Provided below is how we would handle this if we were using low level hooks (What is used in Common::AttachMouseCb)
|
||||
We currently use rawmouse on Windows, so Common::SetMousePosition called directly works fine.
|
||||
*/
|
||||
#if 0
|
||||
// We are currently in a low level hook. SetCursorPos here (what is in Common::SetMousePosition) will not work!
|
||||
// Let's (a)buse Qt's event loop to dispatch the call at a later time, outside of the hook.
|
||||
QMetaObject::invokeMethod(
|
||||
this, [=]() {
|
||||
Common::SetMousePosition(
|
||||
std::clamp(globalCursorPos.x(), windowBounds.left(), windowBounds.right()),
|
||||
std::clamp(globalCursorPos.y(), windowBounds.top(), windowBounds.bottom()));
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::saveDisplayWindowGeometryToConfig()
|
||||
{
|
||||
QWidget* container = getDisplayContainer();
|
||||
|
||||
@@ -104,11 +104,12 @@ public:
|
||||
void rescanFile(const std::string& path);
|
||||
|
||||
void openDebugger();
|
||||
|
||||
void checkMousePosition(int x, int y);
|
||||
public Q_SLOTS:
|
||||
void checkForUpdates(bool display_message, bool force_check);
|
||||
void refreshGameList(bool invalidate_cache);
|
||||
void cancelGameListRefresh();
|
||||
void reportInfo(const QString& title, const QString& message);
|
||||
void reportError(const QString& title, const QString& message);
|
||||
bool confirmMessage(const QString& title, const QString& message);
|
||||
void onStatusMessage(const QString& message);
|
||||
@@ -128,7 +129,7 @@ private Q_SLOTS:
|
||||
void mouseModeRequested(bool relative_mode, bool hide_cursor);
|
||||
void releaseRenderWindow();
|
||||
void focusDisplayWidget();
|
||||
|
||||
void setupMouseMoveHandler();
|
||||
void onGameListRefreshComplete();
|
||||
void onGameListRefreshProgress(const QString& status, int current, int total);
|
||||
void onGameListSelectionChanged();
|
||||
@@ -182,7 +183,6 @@ private Q_SLOTS:
|
||||
void onInputRecPlayActionTriggered();
|
||||
void onInputRecStopActionTriggered();
|
||||
void onInputRecOpenViewer();
|
||||
|
||||
void onVMStarting();
|
||||
void onVMStarted();
|
||||
void onVMPaused();
|
||||
@@ -240,6 +240,7 @@ private:
|
||||
bool isRenderingToMain() const;
|
||||
bool shouldHideMouseCursor() const;
|
||||
bool shouldHideMainWindow() const;
|
||||
bool shouldMouseLock() const;
|
||||
void switchToGameListView();
|
||||
void switchToEmulationView();
|
||||
|
||||
|
||||
@@ -1612,6 +1612,18 @@ bool QtHost::DownloadFile(QWidget* parent, const QString& title, std::string url
|
||||
return true;
|
||||
}
|
||||
|
||||
void Host::ReportInfoAsync(const std::string_view title, const std::string_view message)
|
||||
{
|
||||
if (!title.empty() && !message.empty())
|
||||
INFO_LOG("ReportInfoAsync: {}: {}", title, message);
|
||||
else if (!message.empty())
|
||||
INFO_LOG("ReportInfoAsync: {}", message);
|
||||
|
||||
QMetaObject::invokeMethod(g_main_window, "reportInfo", Qt::QueuedConnection,
|
||||
Q_ARG(const QString&, title.empty() ? QString() : QString::fromUtf8(title.data(), title.size())),
|
||||
Q_ARG(const QString&, message.empty() ? QString() : QString::fromUtf8(message.data(), message.size())));
|
||||
}
|
||||
|
||||
void Host::ReportErrorAsync(const std::string_view title, const std::string_view message)
|
||||
{
|
||||
if (!title.empty() && !message.empty())
|
||||
|
||||
@@ -19,7 +19,7 @@ ControllerGlobalSettingsWidget::ControllerGlobalSettingsWidget(QWidget* parent,
|
||||
SettingsInterface* sif = dialog->getProfileSettingsInterface();
|
||||
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLSource, "InputSources", "SDL", true);
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLEnhancedMode, "InputSources", "SDLControllerEnhancedMode", false);
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLEnhancedMode, "InputSources", "SDLControllerEnhancedMode", true);
|
||||
connect(m_ui.enableSDLSource, &QCheckBox::checkStateChanged, this, &ControllerGlobalSettingsWidget::updateSDLOptionsEnabled);
|
||||
connect(m_ui.ledSettings, &QToolButton::clicked, this, &ControllerGlobalSettingsWidget::ledSettingsClicked);
|
||||
|
||||
@@ -146,7 +146,7 @@ ControllerLEDSettingsDialog::ControllerLEDSettingsDialog(QWidget* parent, Contro
|
||||
|
||||
SettingsInterface* sif = dialog->getProfileSettingsInterface();
|
||||
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLPS5PlayerLED, "InputSources", "SDLPS5PlayerLED", false);
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLPS5PlayerLED, "InputSources", "SDLPS5PlayerLED", true);
|
||||
connect(m_ui.buttonBox->button(QDialogButtonBox::Close), &QPushButton::clicked, this, &QDialog::accept);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,19 +44,23 @@ DebugSettingsWidget::DebugSettingsWidget(SettingsWindow* dialog, QWidget* parent
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GS Settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.dumpGSDraws, "EmuCore/GS", "dump", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveRT, "EmuCore/GS", "save", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveFrame, "EmuCore/GS", "savef", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveTexture, "EmuCore/GS", "savet", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveDepth, "EmuCore/GS", "savez", false);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.startDraw, "EmuCore/GS", "saven", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.dumpCount, "EmuCore/GS", "savel", 5000);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.dumpGSData, "EmuCore/GS", "DumpGSData", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveRT, "EmuCore/GS", "SaveRT", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveFrame, "EmuCore/GS", "SaveFrame", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveTexture, "EmuCore/GS", "SaveTexture", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveDepth, "EmuCore/GS", "SaveDepth", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveAlpha, "EmuCore/GS", "SaveAlpha", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveInfo, "EmuCore/GS", "SaveInfo", false);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.saveDrawStart, "EmuCore/GS", "SaveDrawStart", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.saveDrawCount, "EmuCore/GS", "SaveDrawCount", 5000);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.saveFrameStart, "EmuCore/GS", "SaveFrameStart", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.saveFrameCount, "EmuCore/GS", "SaveFrameCount", 999999);
|
||||
SettingWidgetBinder::BindWidgetToFolderSetting(
|
||||
sif, m_ui.hwDumpDirectory, m_ui.hwDumpBrowse, m_ui.hwDumpOpen, nullptr, "EmuCore/GS", "HWDumpDirectory", std::string(), false);
|
||||
SettingWidgetBinder::BindWidgetToFolderSetting(
|
||||
sif, m_ui.swDumpDirectory, m_ui.swDumpBrowse, m_ui.swDumpOpen, nullptr, "EmuCore/GS", "SWDumpDirectory", std::string(), false);
|
||||
|
||||
connect(m_ui.dumpGSDraws, &QCheckBox::checkStateChanged, this, &DebugSettingsWidget::onDrawDumpingChanged);
|
||||
connect(m_ui.dumpGSData, &QCheckBox::checkStateChanged, this, &DebugSettingsWidget::onDrawDumpingChanged);
|
||||
onDrawDumpingChanged();
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
@@ -146,13 +150,17 @@ DebugSettingsWidget::~DebugSettingsWidget() = default;
|
||||
|
||||
void DebugSettingsWidget::onDrawDumpingChanged()
|
||||
{
|
||||
const bool enabled = m_dialog->getEffectiveBoolValue("EmuCore/GS", "dump", false);
|
||||
const bool enabled = m_dialog->getEffectiveBoolValue("EmuCore/GS", "DumpGSData", false);
|
||||
m_ui.saveRT->setEnabled(enabled);
|
||||
m_ui.saveFrame->setEnabled(enabled);
|
||||
m_ui.saveTexture->setEnabled(enabled);
|
||||
m_ui.saveDepth->setEnabled(enabled);
|
||||
m_ui.startDraw->setEnabled(enabled);
|
||||
m_ui.dumpCount->setEnabled(enabled);
|
||||
m_ui.saveAlpha->setEnabled(enabled);
|
||||
m_ui.saveInfo->setEnabled(enabled);
|
||||
m_ui.saveDrawStart->setEnabled(enabled);
|
||||
m_ui.saveDrawCount->setEnabled(enabled);
|
||||
m_ui.saveFrameStart->setEnabled(enabled);
|
||||
m_ui.saveFrameCount->setEnabled(enabled);
|
||||
m_ui.hwDumpDirectory->setEnabled(enabled);
|
||||
m_ui.hwDumpBrowse->setEnabled(enabled);
|
||||
m_ui.hwDumpOpen->setEnabled(enabled);
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="dumpGSDraws">
|
||||
<widget class="QCheckBox" name="dumpGSData">
|
||||
<property name="text">
|
||||
<string>Dump GS Draws</string>
|
||||
</property>
|
||||
@@ -195,17 +195,31 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="saveAlpha">
|
||||
<property name="text">
|
||||
<string>Save Alpha</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="saveInfo">
|
||||
<property name="text">
|
||||
<string>Save Info</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<widget class="QLabel" name="label_1">
|
||||
<property name="text">
|
||||
<string>Start Draw Number:</string>
|
||||
<string>Save Draw Start:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="startDraw">
|
||||
<widget class="QSpinBox" name="saveDrawStart">
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
@@ -214,12 +228,12 @@
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Draw Dump Count:</string>
|
||||
<string>Save Draw Count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="dumpCount">
|
||||
<widget class="QSpinBox" name="saveDrawCount">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
@@ -231,39 +245,49 @@
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Hardware Dump Directory:</string>
|
||||
<string>Save Frame Start:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="saveFrameStart">
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Software Dump Directory:</string>
|
||||
<string>Save Frame Count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0,0">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="swDumpDirectory"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="swDumpBrowse">
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="swDumpOpen">
|
||||
<property name="text">
|
||||
<string>Open...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QSpinBox" name="saveFrameCount">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Hardware Dump Directory:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Software Dump Directory:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="hwDumpDirectory"/>
|
||||
@@ -284,6 +308,27 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0,0">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="swDumpDirectory"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="swDumpBrowse">
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="swDumpOpen">
|
||||
<property name="text">
|
||||
<string>Open...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -1055,7 +1055,12 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Align To Native</string>
|
||||
<string>Align to Native</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Align to Native - with Texture Offset</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
#include <bit>
|
||||
|
||||
InputBindingDialog::InputBindingDialog(SettingsInterface* sif, InputBindingInfo::Type bind_type, std::string section_name,
|
||||
std::string key_name, std::vector<std::string> bindings, QWidget* parent)
|
||||
std::string key_name, std::vector<std::string> bindings_settings, std::vector<std::string> bindings_ui, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_sif(sif)
|
||||
, m_bind_type(bind_type)
|
||||
, m_section_name(std::move(section_name))
|
||||
, m_key_name(std::move(key_name))
|
||||
, m_bindings(std::move(bindings))
|
||||
, m_bindings_settings(std::move(bindings_settings))
|
||||
, m_bindings_ui(std::move(bindings_ui))
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
m_ui.title->setText(tr("Bindings for %1 %2").arg(QString::fromStdString(m_section_name)).arg(QString::fromStdString(m_key_name)));
|
||||
@@ -32,6 +33,8 @@ InputBindingDialog::InputBindingDialog(SettingsInterface* sif, InputBindingInfo:
|
||||
connect(m_ui.removeBinding, &QPushButton::clicked, this, &InputBindingDialog::onRemoveBindingButtonClicked);
|
||||
connect(m_ui.clearBindings, &QPushButton::clicked, this, &InputBindingDialog::onClearBindingsButtonClicked);
|
||||
connect(m_ui.buttonBox, &QDialogButtonBox::rejected, [this]() { done(0); });
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceConnected, this, &InputBindingDialog::onInputDeviceConnected);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceDisconnected, this, &InputBindingDialog::onInputDeviceDisconnected);
|
||||
updateList();
|
||||
|
||||
// Only show the sensitivity controls for binds where it's applicable.
|
||||
@@ -210,11 +213,17 @@ void InputBindingDialog::addNewBinding()
|
||||
const std::string new_binding(InputManager::ConvertInputBindingKeysToString(m_bind_type, m_new_bindings.data(), m_new_bindings.size()));
|
||||
if (!new_binding.empty())
|
||||
{
|
||||
if (std::find(m_bindings.begin(), m_bindings.end(), new_binding) != m_bindings.end())
|
||||
if (std::find(m_bindings_settings.begin(), m_bindings_settings.end(), new_binding) != m_bindings_settings.end())
|
||||
return;
|
||||
|
||||
m_ui.bindingList->addItem(QString::fromStdString(new_binding));
|
||||
m_bindings.push_back(std::move(new_binding));
|
||||
m_bindings_settings.push_back(std::move(new_binding));
|
||||
|
||||
SmallString new_binding_temp{std::string_view{new_binding}};
|
||||
InputManager::PrettifyInputBinding(new_binding_temp, false);
|
||||
std::string new_binding_ui{new_binding_temp};
|
||||
|
||||
m_bindings_ui.push_back(new_binding_ui);
|
||||
m_ui.bindingList->addItem(QString::fromStdString(new_binding_ui));
|
||||
saveListToSettings();
|
||||
}
|
||||
}
|
||||
@@ -230,17 +239,19 @@ void InputBindingDialog::onAddBindingButtonClicked()
|
||||
void InputBindingDialog::onRemoveBindingButtonClicked()
|
||||
{
|
||||
const int row = m_ui.bindingList->currentRow();
|
||||
if (row < 0 || static_cast<size_t>(row) >= m_bindings.size())
|
||||
if (row < 0 || static_cast<size_t>(row) >= m_bindings_ui.size())
|
||||
return;
|
||||
|
||||
m_bindings.erase(m_bindings.begin() + row);
|
||||
m_bindings_settings.erase(m_bindings_settings.begin() + row);
|
||||
m_bindings_ui.erase(m_bindings_ui.begin() + row);
|
||||
delete m_ui.bindingList->takeItem(row);
|
||||
saveListToSettings();
|
||||
}
|
||||
|
||||
void InputBindingDialog::onClearBindingsButtonClicked()
|
||||
{
|
||||
m_bindings.clear();
|
||||
m_bindings_settings.clear();
|
||||
m_bindings_ui.clear();
|
||||
m_ui.bindingList->clear();
|
||||
saveListToSettings();
|
||||
}
|
||||
@@ -248,7 +259,7 @@ void InputBindingDialog::onClearBindingsButtonClicked()
|
||||
void InputBindingDialog::updateList()
|
||||
{
|
||||
m_ui.bindingList->clear();
|
||||
for (const std::string& binding : m_bindings)
|
||||
for (const std::string& binding : m_bindings_ui)
|
||||
m_ui.bindingList->addItem(QString::fromStdString(binding));
|
||||
}
|
||||
|
||||
@@ -256,8 +267,8 @@ void InputBindingDialog::saveListToSettings()
|
||||
{
|
||||
if (m_sif)
|
||||
{
|
||||
if (!m_bindings.empty())
|
||||
m_sif->SetStringList(m_section_name.c_str(), m_key_name.c_str(), m_bindings);
|
||||
if (!m_bindings_settings.empty())
|
||||
m_sif->SetStringList(m_section_name.c_str(), m_key_name.c_str(), m_bindings_settings);
|
||||
else
|
||||
m_sif->DeleteValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
m_sif->Save();
|
||||
@@ -265,8 +276,8 @@ void InputBindingDialog::saveListToSettings()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_bindings.empty())
|
||||
Host::SetBaseStringListSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_bindings);
|
||||
if (!m_bindings_settings.empty())
|
||||
Host::SetBaseStringListSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_bindings_settings);
|
||||
else
|
||||
Host::RemoveBaseSettingValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
Host::CommitBaseSettingChanges();
|
||||
@@ -337,6 +348,16 @@ void InputBindingDialog::onDeadzoneChanged(int value)
|
||||
m_ui.deadzoneValue->setText(tr("%1%").arg(value));
|
||||
}
|
||||
|
||||
void InputBindingDialog::onInputDeviceConnected(const QString& identifier, const QString& device_name)
|
||||
{
|
||||
ReloadBindNames();
|
||||
}
|
||||
|
||||
void InputBindingDialog::onInputDeviceDisconnected(const QString& identifier)
|
||||
{
|
||||
ReloadBindNames();
|
||||
}
|
||||
|
||||
void InputBindingDialog::hookInputManager()
|
||||
{
|
||||
InputManager::SetHook([this](InputBindingKey key, float value) {
|
||||
@@ -349,3 +370,17 @@ void InputBindingDialog::unhookInputManager()
|
||||
{
|
||||
InputManager::RemoveHook();
|
||||
}
|
||||
|
||||
void InputBindingDialog::ReloadBindNames()
|
||||
{
|
||||
m_bindings_ui.clear();
|
||||
m_bindings_ui.reserve(m_bindings_settings.size());
|
||||
for (int i = 0; i < m_bindings_settings.size(); i++)
|
||||
{
|
||||
SmallString binding{std::string_view{m_bindings_settings[i]}};
|
||||
InputManager::PrettifyInputBinding(binding, false);
|
||||
m_bindings_ui.push_back(std::string{binding});
|
||||
}
|
||||
|
||||
updateList();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class InputBindingDialog : public QDialog
|
||||
|
||||
public:
|
||||
InputBindingDialog(SettingsInterface* sif, InputBindingInfo::Type bind_type, std::string section_name, std::string key_name,
|
||||
std::vector<std::string> bindings, QWidget* parent);
|
||||
std::vector<std::string> bindings_settings, std::vector<std::string> bindings_ui, QWidget* parent);
|
||||
~InputBindingDialog();
|
||||
|
||||
protected Q_SLOTS:
|
||||
@@ -35,6 +35,9 @@ protected Q_SLOTS:
|
||||
void onSensitivityChanged(int value);
|
||||
void onDeadzoneChanged(int value);
|
||||
|
||||
void onInputDeviceConnected(const QString& identifier, const QString& device_name);
|
||||
void onInputDeviceDisconnected(const QString& identifier);
|
||||
|
||||
protected:
|
||||
enum : u32
|
||||
{
|
||||
@@ -55,13 +58,16 @@ protected:
|
||||
void hookInputManager();
|
||||
void unhookInputManager();
|
||||
|
||||
void ReloadBindNames();
|
||||
|
||||
Ui::InputBindingDialog m_ui;
|
||||
|
||||
SettingsInterface* m_sif;
|
||||
InputBindingInfo::Type m_bind_type;
|
||||
std::string m_section_name;
|
||||
std::string m_key_name;
|
||||
std::vector<std::string> m_bindings;
|
||||
std::vector<std::string> m_bindings_settings;
|
||||
std::vector<std::string> m_bindings_ui;
|
||||
std::vector<InputBindingKey> m_new_bindings;
|
||||
std::vector<std::pair<InputBindingKey, std::pair<float, float>>> m_value_ranges;
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ InputBindingWidget::InputBindingWidget(QWidget* parent)
|
||||
: QPushButton(parent)
|
||||
{
|
||||
connect(this, &QPushButton::clicked, this, &InputBindingWidget::onClicked);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceConnected, this, &InputBindingWidget::onInputDeviceConnected);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceDisconnected, this, &InputBindingWidget::onInputDeviceDisconnected);
|
||||
}
|
||||
|
||||
InputBindingWidget::InputBindingWidget(
|
||||
@@ -33,6 +35,8 @@ InputBindingWidget::InputBindingWidget(
|
||||
setMaximumWidth(225);
|
||||
|
||||
connect(this, &QPushButton::clicked, this, &InputBindingWidget::onClicked);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceConnected, this, &InputBindingWidget::onInputDeviceConnected);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceDisconnected, this, &InputBindingWidget::onInputDeviceDisconnected);
|
||||
|
||||
initialize(sif, bind_type, std::move(section_name), std::move(key_name));
|
||||
}
|
||||
@@ -62,20 +66,20 @@ void InputBindingWidget::updateText()
|
||||
const QString binding_tip(tr("\n\nLeft click to assign a new button\nShift + left click for additional bindings"));
|
||||
const QString binding_clear_tip(tr("\nRight click to clear binding"));
|
||||
|
||||
if (m_bindings.empty())
|
||||
if (m_bindings_ui.empty())
|
||||
{
|
||||
setText(QString());
|
||||
|
||||
setToolTip(tr("No bindings registered") + binding_tip);
|
||||
}
|
||||
else if (m_bindings.size() > 1)
|
||||
else if (m_bindings_ui.size() > 1)
|
||||
{
|
||||
setText(tr("%n bindings", "", static_cast<int>(m_bindings.size())));
|
||||
setText(tr("%n bindings", "", static_cast<int>(m_bindings_ui.size())));
|
||||
|
||||
// keep the full thing for the tooltip
|
||||
std::stringstream ss;
|
||||
bool first = true;
|
||||
for (const std::string& binding : m_bindings)
|
||||
for (const std::string& binding : m_bindings_ui)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
@@ -87,7 +91,7 @@ void InputBindingWidget::updateText()
|
||||
}
|
||||
else
|
||||
{
|
||||
QString binding_text(QString::fromStdString(m_bindings[0]));
|
||||
QString binding_text(QString::fromStdString(m_bindings_ui[0]));
|
||||
setToolTip(binding_text + binding_tip + binding_clear_tip);
|
||||
|
||||
// fix up accelerators, and if it's too long, ellipsise it
|
||||
@@ -232,13 +236,12 @@ void InputBindingWidget::setNewBinding()
|
||||
}
|
||||
}
|
||||
|
||||
m_bindings.clear();
|
||||
m_bindings.push_back(std::move(new_binding));
|
||||
m_bindings_ui.clear();
|
||||
m_bindings_ui.push_back(std::move(new_binding));
|
||||
}
|
||||
|
||||
void InputBindingWidget::clearBinding()
|
||||
{
|
||||
m_bindings.clear();
|
||||
if (m_sif)
|
||||
{
|
||||
m_sif->DeleteValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
@@ -256,14 +259,24 @@ void InputBindingWidget::clearBinding()
|
||||
|
||||
void InputBindingWidget::reloadBinding()
|
||||
{
|
||||
m_bindings = m_sif ? m_sif->GetStringList(m_section_name.c_str(), m_key_name.c_str()) :
|
||||
Host::GetBaseStringListSetting(m_section_name.c_str(), m_key_name.c_str());
|
||||
m_bindings_settings = m_sif ? m_sif->GetStringList(m_section_name.c_str(), m_key_name.c_str()) :
|
||||
Host::GetBaseStringListSetting(m_section_name.c_str(), m_key_name.c_str());
|
||||
|
||||
m_bindings_ui.clear();
|
||||
m_bindings_ui.reserve(m_bindings_settings.size());
|
||||
for (int i = 0; i < m_bindings_settings.size(); i++)
|
||||
{
|
||||
SmallString binding{std::string_view{m_bindings_settings[i]}};
|
||||
InputManager::PrettifyInputBinding(binding, false);
|
||||
m_bindings_ui.push_back(std::string{binding});
|
||||
}
|
||||
|
||||
updateText();
|
||||
}
|
||||
|
||||
void InputBindingWidget::onClicked()
|
||||
{
|
||||
if (m_bindings.size() > 1)
|
||||
if (m_bindings_ui.size() > 1)
|
||||
{
|
||||
openDialog();
|
||||
return;
|
||||
@@ -376,6 +389,16 @@ void InputBindingWidget::inputManagerHookCallback(InputBindingKey key, float val
|
||||
}
|
||||
}
|
||||
|
||||
void InputBindingWidget::onInputDeviceConnected(const QString& identifier, const QString& device_name)
|
||||
{
|
||||
reloadBinding();
|
||||
}
|
||||
|
||||
void InputBindingWidget::onInputDeviceDisconnected(const QString& identifier)
|
||||
{
|
||||
reloadBinding();
|
||||
}
|
||||
|
||||
void InputBindingWidget::hookInputManager()
|
||||
{
|
||||
InputManager::SetHook([this](InputBindingKey key, float value) {
|
||||
@@ -391,7 +414,7 @@ void InputBindingWidget::unhookInputManager()
|
||||
|
||||
void InputBindingWidget::openDialog()
|
||||
{
|
||||
InputBindingDialog binding_dialog(m_sif, m_bind_type, m_section_name, m_key_name, m_bindings, QtUtils::GetRootWidget(this));
|
||||
InputBindingDialog binding_dialog(m_sif, m_bind_type, m_section_name, m_key_name, m_bindings_settings, m_bindings_ui, QtUtils::GetRootWidget(this));
|
||||
binding_dialog.exec();
|
||||
reloadBinding();
|
||||
}
|
||||
@@ -422,6 +445,12 @@ void InputVibrationBindingWidget::setKey(ControllerSettingsWindow* dialog, std::
|
||||
m_section_name = std::move(section_name);
|
||||
m_key_name = std::move(key_name);
|
||||
m_binding = Host::GetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
|
||||
SmallString binding{std::string_view{m_binding}};
|
||||
|
||||
if (InputManager::PrettifyInputBinding(binding, false))
|
||||
m_binding = binding;
|
||||
|
||||
setText(QString::fromStdString(m_binding));
|
||||
}
|
||||
|
||||
@@ -440,12 +469,22 @@ void InputVibrationBindingWidget::onClicked()
|
||||
|
||||
const QString full_key(QStringLiteral("%1/%2").arg(QString::fromStdString(m_section_name)).arg(QString::fromStdString(m_key_name)));
|
||||
const QString current(QString::fromStdString(m_binding));
|
||||
QStringList input_options(m_dialog->getVibrationMotors());
|
||||
if (!current.isEmpty() && input_options.indexOf(current) < 0)
|
||||
QStringList input_setting_options(m_dialog->getVibrationMotors());
|
||||
QStringList input_ui_options;
|
||||
input_ui_options.reserve(input_setting_options.count());
|
||||
|
||||
for (QString motor : input_setting_options)
|
||||
{
|
||||
input_options.append(current);
|
||||
SmallStringBase motor_ui(motor.toStdString());
|
||||
InputManager::PrettifyInputBinding(motor_ui, false);
|
||||
input_ui_options.push_back(QString(motor_ui));
|
||||
}
|
||||
else if (input_options.isEmpty())
|
||||
|
||||
if (!current.isEmpty() && input_ui_options.indexOf(current) < 0)
|
||||
{
|
||||
input_setting_options.append(current);
|
||||
}
|
||||
else if (input_setting_options.isEmpty())
|
||||
{
|
||||
QMessageBox::critical(QtUtils::GetRootWidget(this), tr("Error"), tr("No devices with vibration motors were detected."));
|
||||
return;
|
||||
@@ -457,16 +496,25 @@ void InputVibrationBindingWidget::onClicked()
|
||||
input_dialog.setInputMode(QInputDialog::TextInput);
|
||||
input_dialog.setOptions(QInputDialog::UseListViewForComboBoxItems);
|
||||
input_dialog.setComboBoxEditable(false);
|
||||
input_dialog.setComboBoxItems(std::move(input_options));
|
||||
input_dialog.setComboBoxItems(std::move(input_ui_options));
|
||||
input_dialog.setTextValue(current);
|
||||
if (input_dialog.exec() == 0)
|
||||
return;
|
||||
|
||||
const QString new_value(input_dialog.textValue());
|
||||
m_binding = new_value.toStdString();
|
||||
Host::SetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_binding.c_str());
|
||||
Host::CommitBaseSettingChanges();
|
||||
setText(new_value);
|
||||
// If a controller is unplugged, we won't have the setting string to save
|
||||
// Skip saving if selected is an existing bind from an unplugged controller
|
||||
const int selected = input_setting_options.indexOf(input_dialog.textValue());
|
||||
if (selected >= 0)
|
||||
{
|
||||
// Update config
|
||||
const std::string new_setting_value(input_setting_options[selected].toStdString());
|
||||
Host::SetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str(), new_setting_value.c_str());
|
||||
Host::CommitBaseSettingChanges();
|
||||
// Update ui
|
||||
const QString new_ui_value(input_dialog.textValue());
|
||||
m_binding = new_ui_value.toStdString();
|
||||
setText(new_ui_value);
|
||||
}
|
||||
}
|
||||
|
||||
void InputVibrationBindingWidget::mouseReleaseEvent(QMouseEvent* e)
|
||||
|
||||
@@ -39,6 +39,9 @@ protected Q_SLOTS:
|
||||
void onInputListenTimerTimeout();
|
||||
void inputManagerHookCallback(InputBindingKey key, float value);
|
||||
|
||||
void onInputDeviceConnected(const QString& identifier, const QString& device_name);
|
||||
void onInputDeviceDisconnected(const QString& identifier);
|
||||
|
||||
protected:
|
||||
enum : u32
|
||||
{
|
||||
@@ -65,7 +68,8 @@ protected:
|
||||
InputBindingInfo::Type m_bind_type = InputBindingInfo::Type::Unknown;
|
||||
std::string m_section_name;
|
||||
std::string m_key_name;
|
||||
std::vector<std::string> m_bindings;
|
||||
std::vector<std::string> m_bindings_settings;
|
||||
std::vector<std::string> m_bindings_ui;
|
||||
std::vector<InputBindingKey> m_new_bindings;
|
||||
std::vector<std::pair<InputBindingKey, std::pair<float, float>>> m_value_ranges;
|
||||
QTimer* m_input_listen_timer = nullptr;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "InterfaceSettingsWidget.h"
|
||||
#include "AutoUpdaterDialog.h"
|
||||
#include "Common.h"
|
||||
#include "MainWindow.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsWindow.h"
|
||||
@@ -36,6 +37,8 @@ const char* InterfaceSettingsWidget::THEME_NAMES[] = {
|
||||
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Cobalt Sky (Blue) [Dark]"),
|
||||
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "AMOLED (Black) [Dark]"),
|
||||
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Ruby (Black/Red) [Dark]"),
|
||||
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Sapphire (Black/Blue) [Dark]"),
|
||||
@@ -61,6 +64,7 @@ const char* InterfaceSettingsWidget::THEME_VALUES[] = {
|
||||
"ScarletDevilRed",
|
||||
"VioletAngelPurple",
|
||||
"CobaltSky",
|
||||
"AMOLED",
|
||||
"Ruby",
|
||||
"Sapphire",
|
||||
"Emerald",
|
||||
@@ -80,6 +84,13 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* dialog, QWidget
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pauseOnControllerDisconnection, "UI", "PauseOnControllerDisconnection", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.discordPresence, "EmuCore", "EnableDiscordPresence", false);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.mouseLock, "EmuCore", "EnableMouseLock", false);
|
||||
connect(m_ui.mouseLock, &QCheckBox::checkStateChanged, [](Qt::CheckState state) {
|
||||
if (state == Qt::Checked)
|
||||
Common::AttachMousePositionCb([](int x, int y) { g_main_window->checkMousePosition(x, y); });
|
||||
else
|
||||
Common::DetachMousePositionCb();
|
||||
});
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.startFullscreen, "UI", "StartFullscreen", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.doubleClickTogglesFullscreen, "UI", "DoubleClickTogglesFullscreen",
|
||||
true);
|
||||
@@ -161,6 +172,9 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* dialog, QWidget
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.discordPresence, tr("Enable Discord Presence"), tr("Unchecked"),
|
||||
tr("Shows the game you are currently playing as part of your profile in Discord."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.mouseLock, tr("Enable Mouse Lock"), tr("Unchecked"),
|
||||
tr("Locks the mouse cursor to the windows when PCSX2 is in focus and all other windows are closed.<br><b>Unavailable on Linux Wayland.</b><br><b>Requires accessibility permissions on macOS.</b>"));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.doubleClickTogglesFullscreen, tr("Double-Click Toggles Fullscreen"), tr("Checked"),
|
||||
tr("Allows switching in and out of fullscreen mode by double-clicking the game window."));
|
||||
|
||||
@@ -50,6 +50,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="mouseLock">
|
||||
<property name="text">
|
||||
<string>Enable Mouse Lock</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="pauseOnStart">
|
||||
<property name="text">
|
||||
|
||||
@@ -121,7 +121,7 @@ bool MemoryCardConvertWorker::ConvertToFolder(const std::string& srcFileName, co
|
||||
// Set progress bar to the literal number of bytes in the memcard.
|
||||
// Plus two because there is a lag period after the Save calls complete
|
||||
// where the progress bar stalls out; this lets us stop the progress bar
|
||||
// just shy of 50 and 100% so it seems like its still doing some work.
|
||||
// just shy of 50 and 100% so it seems like it's still doing some work.
|
||||
this->SetProgressRange((sourceBuffer.size() * 2) + 2);
|
||||
this->SetProgressValue(0);
|
||||
|
||||
@@ -161,5 +161,7 @@ bool MemoryCardConvertWorker::ConvertToFolder(const std::string& srcFileName, co
|
||||
this->IncrementProgressValue();
|
||||
}
|
||||
|
||||
this->IncrementProgressValue();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -183,6 +183,14 @@ QString MemoryCardSettingsWidget::getSelectedCard() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool MemoryCardSettingsWidget::isSelectedCardFormatted() const
|
||||
{
|
||||
const QList<QTreeWidgetItem*> selection(m_ui.cardList->selectedItems());
|
||||
if (!selection.empty())
|
||||
return selection[0]->data(0, Qt::UserRole).toBool();
|
||||
return false;
|
||||
}
|
||||
|
||||
void MemoryCardSettingsWidget::updateCardActions()
|
||||
{
|
||||
QString selectedCard = getSelectedCard();
|
||||
@@ -263,6 +271,12 @@ void MemoryCardSettingsWidget::convertCard()
|
||||
if (selectedCard.isEmpty())
|
||||
return;
|
||||
|
||||
if (!isSelectedCardFormatted())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Cannot convert an unformatted memory card."));
|
||||
return;
|
||||
}
|
||||
|
||||
MemoryCardConvertDialog dialog(QtUtils::GetRootWidget(this), selectedCard);
|
||||
|
||||
if (dialog.IsSetup() && dialog.exec() == QDialog::Accepted)
|
||||
@@ -442,6 +456,10 @@ void MemoryCardListWidget::refresh(SettingsWindow* dialog)
|
||||
item->setText(1, getSizeSummary(mcd));
|
||||
item->setText(2, mcd.formatted ? tr("Yes") : tr("No"));
|
||||
item->setText(3, mtime.toString(QLocale::system().dateTimeFormat(QLocale::ShortFormat)));
|
||||
|
||||
// store formatted metadata
|
||||
item->setData(0, Qt::UserRole, mcd.formatted);
|
||||
|
||||
addTopLevelItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ private:
|
||||
void createCard();
|
||||
|
||||
QString getSelectedCard() const;
|
||||
bool isSelectedCardFormatted() const;
|
||||
void updateCardActions();
|
||||
void deleteCard();
|
||||
void renameCard();
|
||||
|
||||
@@ -280,7 +280,7 @@ void QtHost::SetStyleFromSettings()
|
||||
pizzaPalette.setColor(QPalette::Link, highlight.darker());
|
||||
pizzaPalette.setColor(QPalette::Highlight, highlight);
|
||||
pizzaPalette.setColor(QPalette::HighlightedText, Qt::white);
|
||||
|
||||
|
||||
pizzaPalette.setColor(QPalette::Active, QPalette::Button, extr);
|
||||
pizzaPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray.darker());
|
||||
pizzaPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray.darker());
|
||||
@@ -428,6 +428,42 @@ void QtHost::SetStyleFromSettings()
|
||||
qApp->setPalette(cobaltSkyPalette);
|
||||
qApp->setStyleSheet(QString());
|
||||
}
|
||||
else if (theme == "AMOLED")
|
||||
{
|
||||
// Custom palette by KamFretoZ, A pure concentrated darkness
|
||||
// of a theme designed for maximum eye comfort and benefits
|
||||
// OLED screens.
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
|
||||
const QColor black(0, 0, 0);
|
||||
const QColor gray(25, 25, 25);
|
||||
const QColor lighterGray(75, 75, 75);
|
||||
const QColor blue(198, 238, 255);
|
||||
|
||||
QPalette AMOLEDPalette;
|
||||
AMOLEDPalette.setColor(QPalette::Window, black);
|
||||
AMOLEDPalette.setColor(QPalette::WindowText, Qt::white);
|
||||
AMOLEDPalette.setColor(QPalette::Base, gray);
|
||||
AMOLEDPalette.setColor(QPalette::AlternateBase, black);
|
||||
AMOLEDPalette.setColor(QPalette::ToolTipBase, gray);
|
||||
AMOLEDPalette.setColor(QPalette::ToolTipText, Qt::white);
|
||||
AMOLEDPalette.setColor(QPalette::Text, Qt::white);
|
||||
AMOLEDPalette.setColor(QPalette::Button, gray);
|
||||
AMOLEDPalette.setColor(QPalette::ButtonText, Qt::white);
|
||||
AMOLEDPalette.setColor(QPalette::Link, blue);
|
||||
AMOLEDPalette.setColor(QPalette::Highlight, lighterGray);
|
||||
AMOLEDPalette.setColor(QPalette::HighlightedText, Qt::white);
|
||||
AMOLEDPalette.setColor(QPalette::PlaceholderText, QColor(Qt::white).darker());
|
||||
|
||||
AMOLEDPalette.setColor(QPalette::Active, QPalette::Button, gray);
|
||||
AMOLEDPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(Qt::white).darker());
|
||||
AMOLEDPalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(Qt::white).darker());
|
||||
AMOLEDPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(Qt::white).darker());
|
||||
AMOLEDPalette.setColor(QPalette::Disabled, QPalette::Light, QColor(Qt::white).darker());
|
||||
|
||||
qApp->setPalette(AMOLEDPalette);
|
||||
qApp->setStyleSheet(QString());
|
||||
}
|
||||
else if (theme == "Ruby")
|
||||
{
|
||||
// Custom palette by Daisouji, Black as main color and Red as complimentary.
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "common/SmallString.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/ImGui/FullscreenUI.h"
|
||||
#include "pcsx2/ImGui/ImGuiManager.h"
|
||||
#include "pcsx2/MTGS.h"
|
||||
|
||||
@@ -191,6 +192,13 @@ void QtHost::InstallTranslator(QWidget* dialog_parent)
|
||||
}
|
||||
|
||||
UpdateGlyphRangesAndClearCache(dialog_parent, language.toStdString());
|
||||
|
||||
if (FullscreenUI::IsInitialized())
|
||||
{
|
||||
MTGS::RunOnGSThread([]() mutable {
|
||||
FullscreenUI::LocaleChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const char* QtHost::GetDefaultLanguage()
|
||||
@@ -220,6 +228,12 @@ std::string Host::TranslatePluralToString(const char* context, const char* msg,
|
||||
return qApp->translate(context, msg, disambiguation, count).toStdString();
|
||||
}
|
||||
|
||||
bool Host::LocaleCircleConfirm()
|
||||
{
|
||||
QLocale& loc = QtHost::s_current_locale;
|
||||
return (loc.language() == QLocale::Japanese) || (loc.language() == QLocale::Chinese) || (loc.language() == QLocale::Korean);
|
||||
}
|
||||
|
||||
std::vector<std::pair<QString, QString>> QtHost::GetAvailableLanguageList()
|
||||
{
|
||||
return {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DepsIncludeDir)\SDL2</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DepsIncludeDir)\SDL3</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\fmt\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\lzma\include</AdditionalIncludeDirectories>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 6.1 KiB |
@@ -1268,7 +1268,6 @@ void Achievements::HandleLeaderboardTrackerUpdateEvent(const rc_client_event_t*
|
||||
"Achievements: Updating leaderboard tracker: %u: %s", event->leaderboard_tracker->id, event->leaderboard_tracker->display);
|
||||
|
||||
it->text = event->leaderboard_tracker->display;
|
||||
it->active = true;
|
||||
}
|
||||
|
||||
void Achievements::HandleAchievementChallengeIndicatorShowEvent(const rc_client_event_t* event)
|
||||
|
||||
@@ -1146,7 +1146,7 @@ target_link_libraries(PCSX2_FLAGS INTERFACE
|
||||
discord-rpc
|
||||
simpleini
|
||||
freesurround
|
||||
SDL2::SDL2
|
||||
SDL3::SDL3
|
||||
ZLIB::ZLIB
|
||||
LZ4::LZ4
|
||||
SoundTouch::SoundTouch
|
||||
@@ -1282,7 +1282,7 @@ function(setup_main_executable target)
|
||||
|
||||
# Copy dependency libraries.
|
||||
set(DEPS_BINDIR "${CMAKE_SOURCE_DIR}/deps/bin")
|
||||
set(DEPS_TO_COPY freetype.dll harfbuzz.dll libjpeg.dll libpng16.dll libsharpyuv.dll libwebp.dll lz4.dll SDL2.dll shaderc_shared.dll zlib1.dll zstd.dll)
|
||||
set(DEPS_TO_COPY freetype.dll harfbuzz.dll libjpeg.dll libpng16.dll libsharpyuv.dll libwebp.dll lz4.dll SDL3.dll shaderc_shared.dll zlib1.dll zstd.dll)
|
||||
foreach(DEP_TO_COPY ${DEPS_TO_COPY})
|
||||
install(FILES "${DEPS_BINDIR}/${DEP_TO_COPY}" DESTINATION "${CMAKE_SOURCE_DIR}/bin")
|
||||
endforeach()
|
||||
@@ -1347,6 +1347,7 @@ function(setup_main_executable target)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
MACOSX_BUNDLE true
|
||||
MACOSX_BUNDLE_INFO_PLIST "${PCSX2_SOURCE_DIR}/Resources/Info.plist.in"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${PCSX2_SOURCE_DIR}/Resources/PCSX2.entitlements"
|
||||
OUTPUT_NAME PCSX2
|
||||
# Fixes complaints when Xcode tries to sign for running locally about MoltenVK not being signed
|
||||
XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS --deep
|
||||
|
||||
@@ -440,6 +440,7 @@ enum class GSHalfPixelOffset : u8
|
||||
Special,
|
||||
SpecialAggressive,
|
||||
Native,
|
||||
NativeWTexOffset,
|
||||
MaxCount
|
||||
};
|
||||
|
||||
@@ -745,6 +746,8 @@ struct Pcsx2Config
|
||||
SaveFrame : 1,
|
||||
SaveTexture : 1,
|
||||
SaveDepth : 1,
|
||||
SaveAlpha : 1,
|
||||
SaveInfo : 1,
|
||||
DumpReplaceableTextures : 1,
|
||||
DumpReplaceableMipmaps : 1,
|
||||
DumpTexturesWithFMVActive : 1,
|
||||
@@ -820,8 +823,12 @@ struct Pcsx2Config
|
||||
u16 SWExtraThreads = 2;
|
||||
u16 SWExtraThreadsHeight = 4;
|
||||
|
||||
int SaveN = 0;
|
||||
int SaveL = 5000;
|
||||
int SaveDrawStart = 0;
|
||||
int SaveDrawCount = 5000;
|
||||
int SaveDrawBy = 1;
|
||||
int SaveFrameStart = 0;
|
||||
int SaveFrameCount = -1;
|
||||
int SaveFrameBy = 1;
|
||||
|
||||
s8 ExclusiveFullscreenControl = -1;
|
||||
GSScreenshotSize ScreenshotSize = GSScreenshotSize::WindowResolution;
|
||||
@@ -865,6 +872,9 @@ struct Pcsx2Config
|
||||
|
||||
bool operator==(const GSOptions& right) const;
|
||||
bool operator!=(const GSOptions& right) const;
|
||||
|
||||
// Should we dump this draw/frame?
|
||||
bool ShouldDump(int draw, int frame) const;
|
||||
};
|
||||
|
||||
struct SPU2Options
|
||||
|
||||
@@ -599,7 +599,11 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
}
|
||||
}
|
||||
|
||||
if (valueStack.size() != 1) return false;
|
||||
if (valueStack.size() != 1)
|
||||
{
|
||||
error = TRANSLATE("ExpressionParser", "Invalid expression (Too many constants?)");
|
||||
return false;
|
||||
}
|
||||
dest = valueStack[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -637,14 +637,14 @@ bool CMipsInstruction::Validate()
|
||||
immediate.value = (immediate.value >> 2) & 0x3FFFFFF;
|
||||
} else if (Opcode.flags & MO_IPCR) // relative 16 bit value
|
||||
{
|
||||
int num = (immediate.value-RamPos-4);
|
||||
const int num = (immediate.value-RamPos-4) >> 2;
|
||||
|
||||
if (num > 0x20000 || num < (-0x20000))
|
||||
if (num > std::numeric_limits<short>::max() || num < std::numeric_limits<short>::min())
|
||||
{
|
||||
Logger::queueError(Logger::Error,L"Branch target %08X out of range",immediate.value);
|
||||
return false;
|
||||
}
|
||||
immediate.value = num >> 2;
|
||||
immediate.value = num;
|
||||
}
|
||||
|
||||
int immediateBits = getImmediateBits(immediateType);
|
||||
|
||||
@@ -596,10 +596,10 @@ const tMipsOpcode MipsOpcodes[] = {
|
||||
// 10 | --- | --- | --- | --- | --- | --- | --- | --- | 10..17
|
||||
// 11 | --- | --- | --- | --- | --- | --- | --- | --- | 18..1F
|
||||
// hi |-------|-------|-------|-------|-------|-------|-------|-------|
|
||||
{ "bc1f", "I", MIPS_COP1BC(0x00), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
|
||||
{ "bc1t", "I", MIPS_COP1BC(0x01), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
|
||||
{ "bc1fl", "I", MIPS_COP1BC(0x02), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
|
||||
{ "bc1tl", "I", MIPS_COP1BC(0x03), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
|
||||
{ "bc1f", "i", MIPS_COP1BC(0x00), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
|
||||
{ "bc1t", "i", MIPS_COP1BC(0x01), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
|
||||
{ "bc1fl", "i", MIPS_COP1BC(0x02), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
|
||||
{ "bc1tl", "i", MIPS_COP1BC(0x03), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
|
||||
|
||||
// 31---------21------------------------------------------5--------0
|
||||
// |= COP1S | | function|
|
||||
|
||||
@@ -179,7 +179,7 @@ The clamp modes are also numerically based.
|
||||
* bilinearUpscale [`0` or `1` or `2`] {Automatic, Force Bilinear, Force Nearest} Default: Automatic
|
||||
* skipDrawStart [Value between `0` to `10000`] {0-10000} Default: Off (`0`)
|
||||
* skipDrawEnd [Value between `0` to `10000`] {0-10000} Default: Off (`0`)
|
||||
* halfPixelOffset [`0` or `1` or `2` or `3` or `4`] {Off, Normal Vertex, Special (Texture), Special (Texture Aggressive), Align to Native} Default: Off (`0`)
|
||||
* halfPixelOffset [`0` or `1` or `2` or `3` or `4` or `5`] {Off, Normal Vertex, Special (Texture), Special (Texture Aggressive), Align to Native, Align to Native with Texture Offsets} Default: Off (`0`)
|
||||
* nativeScaling [`0` or `1` or `2`] {Normal, Aggressive or Off} Default: Normal (`0`)
|
||||
* nativePaletteDraw [`0` or `1`] {Off, On} Default: Off (`0`)
|
||||
* roundSprite [`0` or `1` or `2`] {Off, Half or Full} Default: Off (`0`)
|
||||
|
||||
@@ -237,7 +237,7 @@
|
||||
"halfPixelOffset": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 4
|
||||
"maximum": 5
|
||||
},
|
||||
"nativeScaling": {
|
||||
"type": "integer",
|
||||
|
||||
@@ -203,16 +203,15 @@ void GSDrawingContext::Dump(const std::string& filename)
|
||||
"\tTBW:%u\n"
|
||||
"\tPSM:0x%x\n"
|
||||
"\tTW:%u\n"
|
||||
"\tTH:%u\n"
|
||||
"\tTCC:%u\n"
|
||||
"\tTFX:%u\n"
|
||||
"\tCBP:0x%x\n"
|
||||
"\tCPSM:0x%x\n"
|
||||
"\tCSM:%u\n"
|
||||
"\tCSA:%u\n"
|
||||
"\tCLD:%u\n"
|
||||
"\tTH:%u\n",
|
||||
TEX0.TBP0, TEX0.TBW, TEX0.PSM, TEX0.TW, TEX0.TCC, TEX0.TFX, TEX0.CBP, TEX0.CPSM, TEX0.CSM, TEX0.CSA, TEX0.CLD,
|
||||
static_cast<uint32_t>(TEX0.TH));
|
||||
"\tCLD:%u\n\n",
|
||||
TEX0.TBP0, TEX0.TBW, TEX0.PSM, TEX0.TW, static_cast<uint32_t>(TEX0.TH), TEX0.TCC, TEX0.TFX, TEX0.CBP, TEX0.CPSM, TEX0.CSM, TEX0.CSA, TEX0.CLD);
|
||||
|
||||
fprintf(fp,
|
||||
"TEX1\n"
|
||||
|
||||
@@ -87,7 +87,6 @@ public:
|
||||
|
||||
fprintf(fp, "SCANMSK\n"
|
||||
"\tMSK:%u\n\n"
|
||||
"\n"
|
||||
, SCANMSK.MSK);
|
||||
|
||||
fprintf(fp, "TEXA\n"
|
||||
|
||||
@@ -662,11 +662,7 @@ void GSLocalMemory::SaveBMP(const std::string& fn, u32 bp, u32 bw, u32 psm, int
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
GSPng::Save(GSPng::RGB_A_PNG, fn, static_cast<u8*>(bits), w, h, pitch, GSConfig.PNGCompressionLevel, false);
|
||||
#else
|
||||
GSPng::Save(GSPng::RGB_PNG, fn, static_cast<u8*>(bits), w, h, pitch, GSConfig.PNGCompressionLevel, false);
|
||||
#endif
|
||||
GSPng::Save((IsDevBuild || GSConfig.SaveAlpha) ? GSPng::RGB_A_PNG : GSPng::RGB_PNG, fn, static_cast<u8*>(bits), w, h, pitch, GSConfig.PNGCompressionLevel, false);
|
||||
|
||||
_aligned_free(bits);
|
||||
}
|
||||
|
||||
@@ -443,7 +443,7 @@ void GSState::DumpVertices(const std::string& filename)
|
||||
file << std::fixed << std::setprecision(4);
|
||||
for (u32 i = 0; i < count; ++i)
|
||||
{
|
||||
file << "\t" << "v" << i << ": ";
|
||||
file << "\t" << std::dec << "v" << i << ": ";
|
||||
GSVertex v = buffer[m_index.buff[i]];
|
||||
|
||||
const float x = (v.XYZ.X - (int)m_context->XYOFFSET.OFX) / 16.0f;
|
||||
@@ -461,7 +461,7 @@ void GSState::DumpVertices(const std::string& filename)
|
||||
file << std::fixed << std::setprecision(6);
|
||||
for (u32 i = 0; i < count; ++i)
|
||||
{
|
||||
file << "\t" << "v" << i << ": ";
|
||||
file << "\t" << std::dec << "v" << i << ": ";
|
||||
GSVertex v = buffer[m_index.buff[i]];
|
||||
|
||||
file << std::setfill('0') << std::setw(3) << unsigned(v.RGBAQ.R) << DEL;
|
||||
@@ -479,7 +479,7 @@ void GSState::DumpVertices(const std::string& filename)
|
||||
file << "TEXTURE COORDS (" << qualifier << ")" << std::endl;;
|
||||
for (u32 i = 0; i < count; ++i)
|
||||
{
|
||||
file << "\t" << "v" << i << ": ";
|
||||
file << "\t" << "v" << std::dec << i << ": ";
|
||||
const GSVertex v = buffer[m_index.buff[i]];
|
||||
|
||||
// note
|
||||
@@ -1994,7 +1994,7 @@ void GSState::InitReadFIFO(u8* mem, int len)
|
||||
// Read the image all in one go.
|
||||
m_mem.ReadImageX(m_tr.x, m_tr.y, m_tr.buff, m_tr.total, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG);
|
||||
|
||||
if (GSConfig.DumpGSData && GSConfig.SaveRT && s_n >= GSConfig.SaveN)
|
||||
if (GSConfig.SaveRT && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
const std::string s(GetDrawDumpPath(
|
||||
"%05d_read_%05x_%d_%d_%d_%d_%d_%d.bmp",
|
||||
@@ -2742,7 +2742,7 @@ int GSState::Defrost(const freezeData* fd)
|
||||
m_mem.m_clut.Reset();
|
||||
(PRIM->CTXT == 0) ? ApplyTEX0<0>(m_context->TEX0) : ApplyTEX0<1>(m_context->TEX0);
|
||||
|
||||
g_perfmon.SetFrame(5000);
|
||||
g_perfmon.SetFrame(0);
|
||||
|
||||
ResetPCRTC();
|
||||
|
||||
|
||||
@@ -546,9 +546,9 @@ void GSRenderer::EndPresentFrame()
|
||||
|
||||
void GSRenderer::VSync(u32 field, bool registers_written, bool idle_frame)
|
||||
{
|
||||
if (GSConfig.DumpGSData && s_n >= GSConfig.SaveN)
|
||||
if (GSConfig.SaveInfo && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
DumpGSPrivRegs(*m_regs, GetDrawDumpPath("vsync_%05d_f%lld_gs_reg.txt", s_n, g_perfmon.GetFrame()));
|
||||
DumpGSPrivRegs(*m_regs, GetDrawDumpPath("%05d_f%05lld_vsync_gs_reg.txt", s_n, g_perfmon.GetFrame()));
|
||||
}
|
||||
|
||||
const int fb_sprite_blits = g_perfmon.GetDisplayFramebufferSpriteBlits();
|
||||
|
||||
@@ -35,11 +35,8 @@ bool GSTexture::Save(const std::string& fn)
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
GSPng::Format format = GSPng::RGB_A_PNG;
|
||||
#else
|
||||
GSPng::Format format = GSPng::RGB_PNG;
|
||||
#endif
|
||||
GSPng::Format format = (IsDevBuild || GSConfig.SaveAlpha) ? GSPng::RGB_A_PNG : GSPng::RGB_PNG;
|
||||
|
||||
switch (m_format)
|
||||
{
|
||||
case Format::UNorm8:
|
||||
|
||||
@@ -212,10 +212,8 @@ bool GSHwHack::GSC_Tekken5(GSRendererHW& r, int& skip)
|
||||
{
|
||||
if (skip == 0)
|
||||
{
|
||||
if (r.IsPossibleChannelShuffle())
|
||||
if (r.IsPossibleChannelShuffle() && (RTBP0 & 31))
|
||||
{
|
||||
pxAssertMsg((RTBP0 & 31) == 0, "TEX0 should be page aligned");
|
||||
|
||||
GSVertex* v = &r.m_vertex.buff[0];
|
||||
|
||||
// Make sure we're detecting the right effect.
|
||||
|
||||
@@ -178,15 +178,10 @@ GSTexture* GSRendererHW::GetOutput(int i, float& scale, int& y_offset)
|
||||
GL_CACHE("Frame y offset %d pixels, unit %d", y_offset, i);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_OGL_DEBUG
|
||||
if (GSConfig.DumpGSData)
|
||||
if (GSConfig.SaveFrame && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
if (GSConfig.SaveFrame && s_n >= GSConfig.SaveN)
|
||||
{
|
||||
t->Save(GetDrawDumpPath("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, static_cast<int>(TEX0.TBP0), psm_str(TEX0.PSM)));
|
||||
}
|
||||
t->Save(GetDrawDumpPath("%05d_f%05lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, static_cast<int>(TEX0.TBP0), psm_str(TEX0.PSM)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return t;
|
||||
@@ -210,10 +205,8 @@ GSTexture* GSRendererHW::GetFeedbackOutput(float& scale)
|
||||
GSTexture* t = rt->m_texture;
|
||||
scale = rt->m_scale;
|
||||
|
||||
#ifdef ENABLE_OGL_DEBUG
|
||||
if (GSConfig.DumpGSData && GSConfig.SaveFrame && s_n >= GSConfig.SaveN)
|
||||
t->Save(GetDrawDumpPath("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), 3, static_cast<int>(TEX0.TBP0), psm_str(TEX0.PSM)));
|
||||
#endif
|
||||
if (GSConfig.SaveFrame && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
t->Save(GetDrawDumpPath("%05d_f%05lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), 3, static_cast<int>(TEX0.TBP0), psm_str(TEX0.PSM)));
|
||||
|
||||
return t;
|
||||
}
|
||||
@@ -739,7 +732,7 @@ void GSRendererHW::ConvertSpriteTextureShuffle(u32& process_rg, u32& process_ba,
|
||||
GSVector4 GSRendererHW::RealignTargetTextureCoordinate(const GSTextureCache::Source* tex)
|
||||
{
|
||||
if (GSConfig.UserHacks_HalfPixelOffset <= GSHalfPixelOffset::Normal ||
|
||||
GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::Native ||
|
||||
GSConfig.UserHacks_HalfPixelOffset >= GSHalfPixelOffset::Native ||
|
||||
GetUpscaleMultiplier() == 1.0f || m_downscale_source || tex->GetScale() == 1.0f)
|
||||
{
|
||||
return GSVector4(0.0f);
|
||||
@@ -833,20 +826,34 @@ void GSRendererHW::MergeSprite(GSTextureCache::Source* tex)
|
||||
// Tested on Tekken 5.
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
bool is_paving = true;
|
||||
bool is_paving_h = true;
|
||||
bool is_paving_v = true;
|
||||
// SSE optimization: shuffle m[1] to have (4*32 bits) X, Y, U, V
|
||||
const int first_dpX = v[1].XYZ.X - v[0].XYZ.X;
|
||||
const int first_dpU = v[1].U - v[0].U;
|
||||
const int first_dpY = v[1].XYZ.Y - v[0].XYZ.Y;
|
||||
const int first_dpV = v[1].V - v[0].V;
|
||||
for (u32 i = 0; i < m_vertex.next; i += 2)
|
||||
{
|
||||
const int dpX = v[i + 1].XYZ.X - v[i].XYZ.X;
|
||||
const int dpU = v[i + 1].U - v[i].U;
|
||||
|
||||
const int dpY = v[i + 1].XYZ.Y - v[i].XYZ.Y;
|
||||
const int dpV = v[i + 1].V - v[i].V;
|
||||
if (dpX != first_dpX || dpU != first_dpU)
|
||||
{
|
||||
is_paving = false;
|
||||
break;
|
||||
is_paving_h = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (dpY != first_dpY || dpV != first_dpV)
|
||||
{
|
||||
is_paving_v = false;
|
||||
}
|
||||
|
||||
if (!is_paving_h && !is_paving_v)
|
||||
break;
|
||||
}
|
||||
is_paving = is_paving_h || is_paving_v;
|
||||
#if 0
|
||||
const GSVector4 delta_p = m_vt.m_max.p - m_vt.m_min.p;
|
||||
const GSVector4 delta_t = m_vt.m_max.t - m_vt.m_min.t;
|
||||
@@ -857,20 +864,92 @@ void GSRendererHW::MergeSprite(GSTextureCache::Source* tex)
|
||||
if (is_paving)
|
||||
{
|
||||
// Replace all sprite with a single fullscreen sprite.
|
||||
u32 unique_verts = 2;
|
||||
GSVertex* s = &m_vertex.buff[0];
|
||||
if (is_paving_h)
|
||||
{
|
||||
s[0].XYZ.X = static_cast<u16>((16.0f * m_vt.m_min.p.x) + m_context->XYOFFSET.OFX);
|
||||
s[1].XYZ.X = static_cast<u16>((16.0f * m_vt.m_max.p.x) + m_context->XYOFFSET.OFX);
|
||||
|
||||
s[0].XYZ.X = static_cast<u16>((16.0f * m_vt.m_min.p.x) + m_context->XYOFFSET.OFX);
|
||||
s[1].XYZ.X = static_cast<u16>((16.0f * m_vt.m_max.p.x) + m_context->XYOFFSET.OFX);
|
||||
s[0].XYZ.Y = static_cast<u16>((16.0f * m_vt.m_min.p.y) + m_context->XYOFFSET.OFY);
|
||||
s[1].XYZ.Y = static_cast<u16>((16.0f * m_vt.m_max.p.y) + m_context->XYOFFSET.OFY);
|
||||
s[0].U = static_cast<u16>(16.0f * m_vt.m_min.t.x);
|
||||
s[1].U = static_cast<u16>(16.0f * m_vt.m_max.t.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 2; i < (m_vertex.tail & ~1); i++)
|
||||
{
|
||||
bool unique_found = false;
|
||||
|
||||
s[0].U = static_cast<u16>(16.0f * m_vt.m_min.t.x);
|
||||
s[0].V = static_cast<u16>(16.0f * m_vt.m_min.t.y);
|
||||
s[1].U = static_cast<u16>(16.0f * m_vt.m_max.t.x);
|
||||
s[1].V = static_cast<u16>(16.0f * m_vt.m_max.t.y);
|
||||
for (u32 j = i & 1; j < unique_verts; i += 2)
|
||||
{
|
||||
if (s[i].XYZ.X != s[j].XYZ.X)
|
||||
{
|
||||
unique_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unique_found)
|
||||
{
|
||||
unique_verts += 2;
|
||||
s[unique_verts - 2].XYZ.X = s[i & ~1].XYZ.X;
|
||||
s[unique_verts - 1].XYZ.X = s[i | 1].XYZ.X;
|
||||
s[unique_verts - 2].U = s[i & ~1].U;
|
||||
s[unique_verts - 1].U = s[i | 1].U;
|
||||
|
||||
m_vertex.head = m_vertex.tail = m_vertex.next = 2;
|
||||
m_index.tail = 2;
|
||||
s[unique_verts - 2].XYZ.Y = static_cast<u16>((16.0f * m_vt.m_min.p.y) + m_context->XYOFFSET.OFY);
|
||||
s[unique_verts - 1].XYZ.Y = static_cast<u16>((16.0f * m_vt.m_max.p.y) + m_context->XYOFFSET.OFY);
|
||||
|
||||
s[unique_verts - 2].V = static_cast<u16>(16.0f * m_vt.m_min.t.y);
|
||||
s[unique_verts - 1].V = static_cast<u16>(16.0f * m_vt.m_max.t.y);
|
||||
|
||||
i |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_paving_v)
|
||||
{
|
||||
s[0].XYZ.Y = static_cast<u16>((16.0f * m_vt.m_min.p.y) + m_context->XYOFFSET.OFY);
|
||||
s[1].XYZ.Y = static_cast<u16>((16.0f * m_vt.m_max.p.y) + m_context->XYOFFSET.OFY);
|
||||
|
||||
s[0].V = static_cast<u16>(16.0f * m_vt.m_min.t.y);
|
||||
s[1].V = static_cast<u16>(16.0f * m_vt.m_max.t.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 2; i < (m_vertex.tail & ~1); i++)
|
||||
{
|
||||
bool unique_found = false;
|
||||
|
||||
for (u32 j = i & 1; j < unique_verts; i+=2)
|
||||
{
|
||||
if (s[i].XYZ.Y != s[j].XYZ.Y)
|
||||
{
|
||||
unique_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unique_found)
|
||||
{
|
||||
unique_verts += 2;
|
||||
s[unique_verts - 2].XYZ.Y = s[i & ~1].XYZ.Y;
|
||||
s[unique_verts - 1].XYZ.Y = s[i | 1].XYZ.Y;
|
||||
s[unique_verts - 2].V = s[i & ~1].V;
|
||||
s[unique_verts - 1].V = s[i | 1].V;
|
||||
|
||||
s[unique_verts - 2].XYZ.X = static_cast<u16>((16.0f * m_vt.m_min.p.x) + m_context->XYOFFSET.OFX);
|
||||
s[unique_verts - 1].XYZ.X = static_cast<u16>((16.0f * m_vt.m_max.p.x) + m_context->XYOFFSET.OFX);
|
||||
|
||||
s[unique_verts - 2].U = static_cast<u16>(16.0f * m_vt.m_min.t.x);
|
||||
s[unique_verts - 1].U = static_cast<u16>(16.0f * m_vt.m_max.t.x);
|
||||
|
||||
i |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_vertex.head = m_vertex.tail = m_vertex.next = unique_verts;
|
||||
m_index.tail = unique_verts;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1999,7 +2078,7 @@ void GSRendererHW::RoundSpriteOffset()
|
||||
|
||||
void GSRendererHW::Draw()
|
||||
{
|
||||
if (GSConfig.DumpGSData && (s_n >= GSConfig.SaveN))
|
||||
if (GSConfig.SaveInfo && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
std::string s;
|
||||
|
||||
@@ -2757,7 +2836,7 @@ void GSRendererHW::Draw()
|
||||
|
||||
// Preserve downscaled target when copying directly from a downscaled target, or it's a normal draw using a downscaled target. Clears that are drawing to the target can also preserve size.
|
||||
// Of course if this size is different (in width) or this is a shuffle happening, this will be bypassed.
|
||||
const bool preserve_downscale_draw = scale_draw < 0 || (scale_draw == 0 && ((src && src->m_from_target && src->m_from_target->m_downscaled) || is_possible_mem_clear == ClearType::ClearWithDraw));
|
||||
const bool preserve_downscale_draw = std::abs(scale_draw) == 1 || (scale_draw == 0 && ((src && src->m_from_target && src->m_from_target->m_downscaled) || is_possible_mem_clear == ClearType::ClearWithDraw));
|
||||
|
||||
rt = g_texture_cache->LookupTarget(FRAME_TEX0, t_size, ((src && src->m_scale != 1) && GSConfig.UserHacks_NativeScaling == GSNativeScaling::Normal && !possible_shuffle) ? GetTextureScaleFactor() : target_scale, GSTextureCache::RenderTarget, true,
|
||||
fm, false, force_preload, preserve_rt_rgb, preserve_rt_alpha, unclamped_draw_rect, possible_shuffle, is_possible_mem_clear && FRAME_TEX0.TBP0 != m_cached_ctx.ZBUF.Block(), GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && preserve_downscale_draw && is_possible_mem_clear != ClearType::NormalClear);
|
||||
@@ -3308,15 +3387,15 @@ void GSRendererHW::Draw()
|
||||
src->m_texture = src->m_from_target->m_texture;
|
||||
}
|
||||
|
||||
if (GSConfig.DumpGSData)
|
||||
if (GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
const u64 frame = g_perfmon.GetFrame();
|
||||
|
||||
std::string s;
|
||||
|
||||
if (GSConfig.SaveTexture && s_n >= GSConfig.SaveN && src)
|
||||
if (GSConfig.SaveTexture && src)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%lld_itex_%05x_%s_%d%d_%02x_%02x_%02x_%02x.dds",
|
||||
s = GetDrawDumpPath("%05d_f%05lld_itex_%05x_%s_%d%d_%02x_%02x_%02x_%02x.dds",
|
||||
s_n, frame, static_cast<int>(m_cached_ctx.TEX0.TBP0), psm_str(m_cached_ctx.TEX0.PSM),
|
||||
static_cast<int>(m_cached_ctx.CLAMP.WMS), static_cast<int>(m_cached_ctx.CLAMP.WMT),
|
||||
static_cast<int>(m_cached_ctx.CLAMP.MINU), static_cast<int>(m_cached_ctx.CLAMP.MAXU),
|
||||
@@ -3326,23 +3405,23 @@ void GSRendererHW::Draw()
|
||||
|
||||
if (src->m_palette)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%lld_itpx_%05x_%s.dds", s_n, frame, m_cached_ctx.TEX0.CBP, psm_str(m_cached_ctx.TEX0.CPSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_itpx_%05x_%s.dds", s_n, frame, m_cached_ctx.TEX0.CBP, psm_str(m_cached_ctx.TEX0.CPSM));
|
||||
|
||||
src->m_palette->Save(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (rt && GSConfig.SaveRT && s_n >= GSConfig.SaveN)
|
||||
if (rt && GSConfig.SaveRT)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, m_cached_ctx.FRAME.Block(), psm_str(m_cached_ctx.FRAME.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_rt0_%05x_%s.bmp", s_n, frame, m_cached_ctx.FRAME.Block(), psm_str(m_cached_ctx.FRAME.PSM));
|
||||
|
||||
if (rt->m_texture)
|
||||
rt->m_texture->Save(s);
|
||||
}
|
||||
|
||||
if (ds && GSConfig.SaveDepth && s_n >= GSConfig.SaveN)
|
||||
if (ds && GSConfig.SaveDepth)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, m_cached_ctx.ZBUF.Block(), psm_str(m_cached_ctx.ZBUF.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_rz0_%05x_%s.bmp", s_n, frame, m_cached_ctx.ZBUF.Block(), psm_str(m_cached_ctx.ZBUF.PSM));
|
||||
|
||||
if (ds->m_texture)
|
||||
ds->m_texture->Save(s);
|
||||
@@ -3457,10 +3536,7 @@ void GSRendererHW::Draw()
|
||||
GSTextureCache::RenderTarget, m_cached_ctx.ZBUF.Block(), m_cached_ctx.ZBUF.PSM, zm);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
if (GSConfig.DumpGSData)
|
||||
if (GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
const bool writeback_HDR_texture = g_gs_device->GetHDRTexture() != nullptr;
|
||||
if (writeback_HDR_texture)
|
||||
@@ -3474,24 +3550,19 @@ void GSRendererHW::Draw()
|
||||
|
||||
std::string s;
|
||||
|
||||
if (rt && GSConfig.SaveRT && s_n >= GSConfig.SaveN)
|
||||
if (rt && GSConfig.SaveRT)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%lld_rt1_%05x_(%05x)_%s.bmp", s_n, frame, m_cached_ctx.FRAME.Block(), rt->m_TEX0.TBP0, psm_str(m_cached_ctx.FRAME.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_rt1_%05x_%s.bmp", s_n, frame, m_cached_ctx.FRAME.Block(), psm_str(m_cached_ctx.FRAME.PSM));
|
||||
|
||||
rt->m_texture->Save(s);
|
||||
}
|
||||
|
||||
if (ds && GSConfig.SaveDepth && s_n >= GSConfig.SaveN)
|
||||
if (ds && GSConfig.SaveDepth)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%lld_rz1_%05x_(%05x)_%s.bmp", s_n, frame, m_cached_ctx.ZBUF.Block(), ds->m_TEX0.TBP0, psm_str(m_cached_ctx.ZBUF.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_rz1_%05x_%s.bmp", s_n, frame, m_cached_ctx.ZBUF.Block(), psm_str(m_cached_ctx.ZBUF.PSM));
|
||||
|
||||
ds->m_texture->Save(s);
|
||||
}
|
||||
|
||||
if (GSConfig.SaveL > 0 && (s_n - GSConfig.SaveN) > GSConfig.SaveL)
|
||||
{
|
||||
GSConfig.DumpGSData = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (rt)
|
||||
@@ -5089,6 +5160,26 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
|
||||
|
||||
const GSVector4 half_pixel = RealignTargetTextureCoordinate(tex);
|
||||
m_conf.cb_vs.texture_offset = GSVector2(half_pixel.x, half_pixel.y);
|
||||
|
||||
// Can be seen with the cabin part of the ship in God of War, offsets are required when using FST.
|
||||
// ST uses a normalized position so doesn't need an offset here, will break Bionicle Heroes.
|
||||
if (GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::NativeWTexOffset)
|
||||
{
|
||||
if (!m_downscale_source && tex->m_scale > 1.0f)
|
||||
{
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
if (PRIM->FST)
|
||||
{
|
||||
const int x1_frac = ((v[1].XYZ.X - m_context->XYOFFSET.OFX) & 0xf);
|
||||
const int y1_frac = ((v[1].XYZ.Y - m_context->XYOFFSET.OFY) & 0xf);
|
||||
|
||||
if (!(x1_frac & 8))
|
||||
m_conf.cb_vs.texture_offset.x = 6.0f + (0.25f * tex->m_scale);
|
||||
if (!(y1_frac & 8))
|
||||
m_conf.cb_vs.texture_offset.y = 6.0f + (0.25f * tex->m_scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tex->m_target)
|
||||
{
|
||||
@@ -5140,6 +5231,33 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
|
||||
const GSVector4 half_pixel = RealignTargetTextureCoordinate(tex);
|
||||
m_conf.cb_vs.texture_offset = GSVector2(half_pixel.x, half_pixel.y);
|
||||
|
||||
if (GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::NativeWTexOffset)
|
||||
{
|
||||
if (!m_downscale_source && tex->m_scale > 1.0f)
|
||||
{
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
if (PRIM->FST)
|
||||
{
|
||||
const int x1_frac = ((v[1].XYZ.X - m_context->XYOFFSET.OFX) & 0xf);
|
||||
const int y1_frac = ((v[1].XYZ.Y - m_context->XYOFFSET.OFY) & 0xf);
|
||||
|
||||
if (!(x1_frac & 8))
|
||||
m_conf.cb_vs.texture_offset.x = 6.0f + (0.25f * tex->m_scale);
|
||||
if (!(y1_frac & 8))
|
||||
m_conf.cb_vs.texture_offset.y = 6.0f + (0.25f * tex->m_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float tw = static_cast<float>(1 << m_cached_ctx.TEX0.TW);
|
||||
const float th = static_cast<float>(1 << m_cached_ctx.TEX0.TH);
|
||||
const float q = v[0].RGBAQ.Q;
|
||||
|
||||
m_conf.cb_vs.texture_offset.x = 0.5f * q / tw;
|
||||
m_conf.cb_vs.texture_offset.y = 0.5f * q / th;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_vt.m_primclass == GS_SPRITE_CLASS && GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].pal > 0 && m_index.tail >= 4)
|
||||
{
|
||||
HandleManualDeswizzle();
|
||||
@@ -5469,7 +5587,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
|
||||
// When using native HPO, the top-left column/row of pixels are often not drawn. Clamp these away to avoid sampling black,
|
||||
// causing bleeding into the edges of the downsampled texture.
|
||||
const u32 downsample_factor = static_cast<u32>(src_target->GetScale());
|
||||
const GSVector2i clamp_min = (GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native) ?
|
||||
const GSVector2i clamp_min = (GSConfig.UserHacks_HalfPixelOffset < GSHalfPixelOffset::Native) ?
|
||||
GSVector2i(0, 0) :
|
||||
GSVector2i(downsample_factor, downsample_factor);
|
||||
GSVector4i copy_rect = tmm.coverage;
|
||||
@@ -6201,7 +6319,8 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
||||
float sx, sy, ox2, oy2;
|
||||
const float ox = static_cast<float>(static_cast<int>(m_context->XYOFFSET.OFX));
|
||||
const float oy = static_cast<float>(static_cast<int>(m_context->XYOFFSET.OFY));
|
||||
if (GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native && rtscale > 1.0f)
|
||||
|
||||
if ((GSConfig.UserHacks_HalfPixelOffset < GSHalfPixelOffset::Native || m_channel_shuffle) && rtscale > 1.0f)
|
||||
{
|
||||
sx = 2.0f * rtscale / (rtsize.x << 4);
|
||||
sy = 2.0f * rtscale / (rtsize.y << 4);
|
||||
@@ -6230,8 +6349,31 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
||||
const int unscaled_y = rt_or_ds ? rt_or_ds->GetUnscaledHeight() : 0;
|
||||
sx = 2.0f / (unscaled_x << 4);
|
||||
sy = 2.0f / (unscaled_y << 4);
|
||||
ox2 = -1.0f / unscaled_x;
|
||||
oy2 = -1.0f / unscaled_y;
|
||||
|
||||
if (GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::NativeWTexOffset)
|
||||
{
|
||||
ox2 = (-1.0f / (unscaled_x * rtscale));
|
||||
oy2 = (-1.0f / (unscaled_y * rtscale));
|
||||
|
||||
// Having the vertex negatively offset is a common thing for copying sprites but this causes problems when upscaling, so we need to further adjust the offset.
|
||||
// This kinda screws things up when using ST, so let's not.
|
||||
if (m_vt.m_primclass == GS_SPRITE_CLASS && rtscale > 1.0f && (!tex || PRIM->FST))
|
||||
{
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
const int x1_frac = ((v[1].XYZ.X - m_context->XYOFFSET.OFX) & 0xf);
|
||||
const int y1_frac = ((v[1].XYZ.Y - m_context->XYOFFSET.OFY) & 0xf);
|
||||
if (x1_frac & 8)
|
||||
ox2 *= 1.0f + ((static_cast<float>(16 - x1_frac) / 8.0f) * rtscale);
|
||||
|
||||
if (y1_frac & 8)
|
||||
oy2 *= 1.0f + ((static_cast<float>(16 - y1_frac) / 8.0f) * rtscale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ox2 = -1.0f / unscaled_x;
|
||||
oy2 = -1.0f / unscaled_y;
|
||||
}
|
||||
}
|
||||
|
||||
m_conf.cb_vs.vertex_scale = GSVector2(sx, sy);
|
||||
|
||||
@@ -2132,8 +2132,8 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
// And invalidate the target, we're drawing over it so we don't care what's there.
|
||||
// We can't do this when upscaling, because of the vertex offset, the top/left rows often aren't drawn.
|
||||
GL_INS("TC: Invalidating%s target %s[%x] because it's completely overwritten.", to_string(type),
|
||||
(scale > 1.0f && GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::Native) ? "[clearing] " : "", dst->m_TEX0.TBP0);
|
||||
if (scale > 1.0f && GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native)
|
||||
(scale > 1.0f && GSConfig.UserHacks_HalfPixelOffset >= GSHalfPixelOffset::Native) ? "[clearing] " : "", dst->m_TEX0.TBP0);
|
||||
if (scale > 1.0f && GSConfig.UserHacks_HalfPixelOffset < GSHalfPixelOffset::Native)
|
||||
{
|
||||
if (dst->m_type == RenderTarget)
|
||||
g_gs_device->ClearRenderTarget(dst->m_texture, 0);
|
||||
|
||||
@@ -179,12 +179,9 @@ GSTexture* GSRendererSW::GetOutput(int i, float& scale, int& y_offset)
|
||||
|
||||
m_texture[index]->Update(out_r, m_output, pitch);
|
||||
|
||||
if (GSConfig.DumpGSData)
|
||||
if (GSConfig.SaveFrame && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
if (GSConfig.SaveFrame && s_n >= GSConfig.SaveN)
|
||||
{
|
||||
m_texture[index]->Save(GetDrawDumpPath("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, (int)curFramebuffer.Block(), psm_str(curFramebuffer.PSM)));
|
||||
}
|
||||
m_texture[index]->Save(GetDrawDumpPath("%05d_f%05lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, (int)curFramebuffer.Block(), psm_str(curFramebuffer.PSM)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,22 +309,19 @@ void GSRendererSW::Draw()
|
||||
{
|
||||
const GSDrawingContext* context = m_context;
|
||||
|
||||
if (GSConfig.DumpGSData)
|
||||
if (GSConfig.SaveInfo && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
std::string s;
|
||||
|
||||
if (s_n >= GSConfig.SaveN)
|
||||
{
|
||||
// Dump Register state
|
||||
s = GetDrawDumpPath("%05d_context.txt", s_n);
|
||||
// Dump Register state
|
||||
s = GetDrawDumpPath("%05d_context.txt", s_n);
|
||||
|
||||
m_draw_env->Dump(s);
|
||||
m_context->Dump(s);
|
||||
m_draw_env->Dump(s);
|
||||
m_context->Dump(s);
|
||||
|
||||
// Dump vertices
|
||||
s = GetDrawDumpPath("%05d_vertex.txt", s_n);
|
||||
DumpVertices(s);
|
||||
}
|
||||
// Dump vertices
|
||||
s = GetDrawDumpPath("%05d_vertex.txt", s_n);
|
||||
DumpVertices(s);
|
||||
}
|
||||
|
||||
auto data = m_vertex_heap.make_shared<SharedData>().cast<GSRasterizerData>();
|
||||
@@ -431,9 +425,7 @@ void GSRendererSW::Draw()
|
||||
|
||||
sd->UsePages(fb_pages, m_context->offset.fb.psm(), zb_pages, m_context->offset.zb.psm());
|
||||
|
||||
//
|
||||
|
||||
if (GSConfig.DumpGSData)
|
||||
if (GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
Sync(2);
|
||||
|
||||
@@ -444,36 +436,36 @@ void GSRendererSW::Draw()
|
||||
// It will breaks the few games that really uses 16 bits RT
|
||||
bool texture_shuffle = ((context->FRAME.PSM & 0x2) && ((context->TEX0.PSM & 3) == 2) && (m_vt.m_primclass == GS_SPRITE_CLASS));
|
||||
|
||||
if (GSConfig.SaveTexture && s_n >= GSConfig.SaveN && PRIM->TME)
|
||||
if (GSConfig.SaveTexture && PRIM->TME)
|
||||
{
|
||||
if (texture_shuffle)
|
||||
{
|
||||
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
|
||||
s = GetDrawDumpPath("%05d_f%lld_itexraw_%05x_32bits.bmp", s_n, frame, (int)m_context->TEX0.TBP0);
|
||||
s = GetDrawDumpPath("%05d_f%05lld_itexraw_%05x_32bits.bmp", s_n, frame, (int)m_context->TEX0.TBP0);
|
||||
m_mem.SaveBMP(s, m_context->TEX0.TBP0, m_context->TEX0.TBW, 0, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH);
|
||||
}
|
||||
|
||||
s = GetDrawDumpPath("%05d_f%lld_itexraw_%05x_%s.bmp", s_n, frame, (int)m_context->TEX0.TBP0, psm_str(m_context->TEX0.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_itexraw_%05x_%s.bmp", s_n, frame, (int)m_context->TEX0.TBP0, psm_str(m_context->TEX0.PSM));
|
||||
m_mem.SaveBMP(s, m_context->TEX0.TBP0, m_context->TEX0.TBW, m_context->TEX0.PSM, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH);
|
||||
}
|
||||
|
||||
if (GSConfig.SaveRT && s_n >= GSConfig.SaveN)
|
||||
if (GSConfig.SaveRT)
|
||||
{
|
||||
|
||||
if (texture_shuffle)
|
||||
{
|
||||
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
|
||||
s = GetDrawDumpPath("%05d_f%lld_rt0_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
|
||||
s = GetDrawDumpPath("%05d_f%05lld_rt0_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
|
||||
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, r.z, r.w);
|
||||
}
|
||||
|
||||
s = GetDrawDumpPath("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_rt0_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
|
||||
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, r.z, r.w);
|
||||
}
|
||||
|
||||
if (GSConfig.SaveDepth && s_n >= GSConfig.SaveN)
|
||||
if (GSConfig.SaveDepth)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_rz0_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
|
||||
|
||||
m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, r.z, r.w);
|
||||
}
|
||||
@@ -482,30 +474,25 @@ void GSRendererSW::Draw()
|
||||
|
||||
Sync(3);
|
||||
|
||||
if (GSConfig.SaveRT && s_n >= GSConfig.SaveN)
|
||||
if (GSConfig.SaveRT)
|
||||
{
|
||||
if (texture_shuffle)
|
||||
{
|
||||
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
|
||||
s = GetDrawDumpPath("%05d_f%lld_rt1_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
|
||||
s = GetDrawDumpPath("%05d_f%05lld_rt1_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
|
||||
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, r.z, r.w);
|
||||
}
|
||||
|
||||
s = GetDrawDumpPath("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_rt1_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
|
||||
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, r.z, r.w);
|
||||
}
|
||||
|
||||
if (GSConfig.SaveDepth && s_n >= GSConfig.SaveN)
|
||||
if (GSConfig.SaveDepth)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%lld_rz1_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_rz1_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
|
||||
|
||||
m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, r.z, r.w);
|
||||
}
|
||||
|
||||
if (GSConfig.SaveL > 0 && (s_n - GSConfig.SaveN) > GSConfig.SaveL)
|
||||
{
|
||||
GSConfig.DumpGSData = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -585,14 +572,14 @@ void GSRendererSW::Sync(int reason)
|
||||
|
||||
if (GSConfig.SaveRT)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%lld_rt1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_rt1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
|
||||
|
||||
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, PCRTCDisplays.GetFramebufferRect(-1).width(), 512);
|
||||
}
|
||||
|
||||
if (GSConfig.SaveDepth)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%lld_zb1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_zb1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
|
||||
|
||||
m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, PCRTCDisplays.GetFramebufferRect(-1).width(), 512);
|
||||
}
|
||||
@@ -1546,30 +1533,25 @@ void GSRendererSW::SharedData::UpdateSource()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
if (GSConfig.DumpGSData)
|
||||
if (GSConfig.SaveTexture && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
const u64 frame = g_perfmon.GetFrame();
|
||||
|
||||
std::string s;
|
||||
|
||||
if (GSConfig.SaveTexture && g_gs_renderer->s_n >= GSConfig.SaveN)
|
||||
for (size_t i = 0; m_tex[i].t; i++)
|
||||
{
|
||||
for (size_t i = 0; m_tex[i].t; i++)
|
||||
{
|
||||
const GIFRegTEX0& TEX0 = g_gs_renderer->GetTex0Layer(i);
|
||||
const GIFRegTEX0& TEX0 = g_gs_renderer->GetTex0Layer(i);
|
||||
|
||||
s = GetDrawDumpPath("%05d_f%lld_itex%d_%05x_%s.bmp", g_gs_renderer->s_n, frame, i, TEX0.TBP0, psm_str(TEX0.PSM));
|
||||
s = GetDrawDumpPath("%05d_f%05lld_itex%d_%05x_%s.bmp", g_gs_renderer->s_n, frame, i, TEX0.TBP0, psm_str(TEX0.PSM));
|
||||
|
||||
m_tex[i].t->Save(s);
|
||||
}
|
||||
m_tex[i].t->Save(s);
|
||||
}
|
||||
|
||||
if (global.clut)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%lld_itexp_%05x_%s.bmp", g_gs_renderer->s_n, frame, (int)g_gs_renderer->m_context->TEX0.CBP, psm_str(g_gs_renderer->m_context->TEX0.CPSM));
|
||||
GSPng::Save(IsDevBuild ? GSPng::RGB_A_PNG : GSPng::RGB_PNG, s, reinterpret_cast<const u8*>(global.clut), 256, 1, sizeof(u32) * 256, GSConfig.PNGCompressionLevel, false);
|
||||
}
|
||||
if (global.clut)
|
||||
{
|
||||
s = GetDrawDumpPath("%05d_f%05lld_itexp_%05x_%s.bmp", g_gs_renderer->s_n, frame, (int)g_gs_renderer->m_context->TEX0.CBP, psm_str(g_gs_renderer->m_context->TEX0.CPSM));
|
||||
GSPng::Save((IsDevBuild || GSConfig.SaveAlpha) ? GSPng::RGB_A_PNG : GSPng::RGB_PNG, s, reinterpret_cast<const u8*>(global.clut), 256, 1, sizeof(u32) * 256, GSConfig.PNGCompressionLevel, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ bool GSTextureCacheSW::Texture::Save(const std::string& fn) const
|
||||
const u32 w = 1 << m_TEX0.TW;
|
||||
const u32 h = 1 << m_TEX0.TH;
|
||||
|
||||
constexpr GSPng::Format format = IsDevBuild ? GSPng::RGB_A_PNG : GSPng::RGB_PNG;
|
||||
const GSPng::Format format = (IsDevBuild || GSConfig.SaveAlpha) ? GSPng::RGB_A_PNG : GSPng::RGB_PNG;
|
||||
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[m_TEX0.PSM];
|
||||
const u8* RESTRICT src = (u8*)m_buff;
|
||||
const u32 src_pitch = 1u << (m_tw + (psm.pal == 0 ? 2 : 0));
|
||||
|
||||
@@ -593,15 +593,14 @@ void GameList::ScanDirectory(const char* path, bool recursive, bool only_cache,
|
||||
progress->PushState();
|
||||
progress->SetStatusText(fmt::format(
|
||||
recursive ? TRANSLATE_FS("GameList", "Scanning directory {} (recursively)...") :
|
||||
TRANSLATE_FS("GameList", "Scanning directory {}..."),
|
||||
path)
|
||||
.c_str());
|
||||
TRANSLATE_FS("GameList", "Scanning directory {}..."),
|
||||
path).c_str());
|
||||
|
||||
FileSystem::FindResultsArray files;
|
||||
FileSystem::FindFiles(path, "*",
|
||||
recursive ? (FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RECURSIVE) :
|
||||
(FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES),
|
||||
&files);
|
||||
(FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES),
|
||||
&files, progress);
|
||||
|
||||
u32 files_scanned = 0;
|
||||
progress->SetProgressRange(static_cast<u32>(files.size()));
|
||||
|
||||
@@ -138,6 +138,15 @@ void Host::ClearTranslationCache()
|
||||
s_translation_string_mutex.unlock();
|
||||
}
|
||||
|
||||
void Host::ReportFormattedInfoAsync(const std::string_view title, const char* format, ...)
|
||||
{
|
||||
std::va_list ap;
|
||||
va_start(ap, format);
|
||||
std::string message(StringUtil::StdStringFromFormatV(format, ap));
|
||||
va_end(ap);
|
||||
ReportInfoAsync(title, message);
|
||||
}
|
||||
|
||||
void Host::ReportFormattedErrorAsync(const std::string_view title, const char* format, ...)
|
||||
{
|
||||
std::va_list ap;
|
||||
|
||||
@@ -55,6 +55,10 @@ namespace Host
|
||||
void RemoveKeyedOSDMessage(std::string key);
|
||||
void ClearOSDMessages();
|
||||
|
||||
/// Displays an asynchronous error on the UI thread, i.e. doesn't block the caller.
|
||||
void ReportInfoAsync(const std::string_view title, const std::string_view message);
|
||||
void ReportFormattedInfoAsync(const std::string_view title, const char* format, ...);
|
||||
|
||||
/// Displays an asynchronous error on the UI thread, i.e. doesn't block the caller.
|
||||
void ReportErrorAsync(const std::string_view title, const std::string_view message);
|
||||
void ReportFormattedErrorAsync(const std::string_view title, const char* format, ...);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "common/Console.h"
|
||||
#include "common/Error.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -23,11 +23,11 @@ namespace
|
||||
void CloseDevice();
|
||||
|
||||
protected:
|
||||
__fi bool IsOpen() const { return (m_device_id != 0); }
|
||||
__fi bool IsOpen() const { return (m_stream != nullptr); }
|
||||
|
||||
static void AudioCallback(void* userdata, uint8_t* stream, int len);
|
||||
static void AudioCallback(void* userdata, SDL_AudioStream* stream, int additional_amount, int total_amount);
|
||||
|
||||
u32 m_device_id = 0;
|
||||
SDL_AudioStream* m_stream = nullptr;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
@@ -37,8 +37,11 @@ static bool InitializeSDLAudio(Error* error)
|
||||
if (initialized)
|
||||
return true;
|
||||
|
||||
// Set the name that shows up in the audio mixers on some platforms
|
||||
SDL_SetHint("SDL_AUDIO_DEVICE_APP_NAME", "PCSX2");
|
||||
|
||||
// May as well keep it alive until the process exits.
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0)
|
||||
if (!SDL_InitSubSystem(SDL_INIT_AUDIO))
|
||||
{
|
||||
Error::SetStringFmt(error, "SDL_InitSubSystem(SDL_INIT_AUDIO) failed: {}", SDL_GetError());
|
||||
return false;
|
||||
@@ -99,27 +102,24 @@ bool SDLAudioStream::OpenDevice(bool stretch_enabled, Error* error)
|
||||
READ_CHANNEL_REAR_LEFT, READ_CHANNEL_REAR_RIGHT>,
|
||||
}};
|
||||
|
||||
SDL_AudioSpec spec = {};
|
||||
spec.freq = m_sample_rate;
|
||||
spec.channels = m_output_channels;
|
||||
spec.format = AUDIO_S16;
|
||||
spec.samples = static_cast<Uint16>(GetBufferSizeForMS(
|
||||
m_sample_rate, (m_parameters.minimal_output_latency) ? m_parameters.buffer_ms : m_parameters.output_latency_ms));
|
||||
spec.callback = AudioCallback;
|
||||
spec.userdata = static_cast<void*>(this);
|
||||
uint samples = GetBufferSizeForMS(
|
||||
m_sample_rate, (m_parameters.minimal_output_latency) ? m_parameters.buffer_ms : m_parameters.output_latency_ms);
|
||||
|
||||
SDL_SetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES, fmt::format("{}", samples).c_str());
|
||||
|
||||
const SDL_AudioSpec spec = {SDL_AUDIO_S16LE, m_output_channels, static_cast<int>(m_sample_rate)};
|
||||
m_stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, AudioCallback, static_cast<void*>(this));
|
||||
|
||||
SDL_AudioSpec obtained_spec = {};
|
||||
m_device_id = SDL_OpenAudioDevice(nullptr, 0, &spec, &obtained_spec, SDL_AUDIO_ALLOW_SAMPLES_CHANGE);
|
||||
if (m_device_id == 0)
|
||||
{
|
||||
Error::SetStringFmt(error, "SDL_OpenAudioDevice() failed: {}", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
int obtained_samples = 0;
|
||||
|
||||
DEV_LOG("Requested {} frame buffer, got {} frame buffer", spec.samples, obtained_spec.samples);
|
||||
if (SDL_GetAudioDeviceFormat(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &obtained_spec, &obtained_samples))
|
||||
DEV_LOG("Requested {} frame buffer, got {} frame buffer", samples, obtained_samples);
|
||||
else
|
||||
DEV_LOG("SDL_GetAudioDeviceFormat() failed {}", SDL_GetError());
|
||||
|
||||
BaseInitialize(sample_readers[static_cast<size_t>(m_parameters.expansion_mode)], stretch_enabled);
|
||||
SDL_PauseAudioDevice(m_device_id, 0);
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(m_stream));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -129,20 +129,33 @@ void SDLAudioStream::SetPaused(bool paused)
|
||||
if (m_paused == paused)
|
||||
return;
|
||||
|
||||
SDL_PauseAudioDevice(m_device_id, paused ? 1 : 0);
|
||||
if (paused)
|
||||
SDL_PauseAudioDevice(SDL_GetAudioStreamDevice(m_stream));
|
||||
else
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(m_stream));
|
||||
|
||||
m_paused = paused;
|
||||
}
|
||||
|
||||
void SDLAudioStream::CloseDevice()
|
||||
{
|
||||
SDL_CloseAudioDevice(m_device_id);
|
||||
m_device_id = 0;
|
||||
SDL_DestroyAudioStream(m_stream);
|
||||
m_stream = nullptr;
|
||||
}
|
||||
|
||||
void SDLAudioStream::AudioCallback(void* userdata, uint8_t* stream, int len)
|
||||
void SDLAudioStream::AudioCallback(void* userdata, SDL_AudioStream* stream, int additional_amount, int total_amount)
|
||||
{
|
||||
SDLAudioStream* const this_ptr = static_cast<SDLAudioStream*>(userdata);
|
||||
const u32 num_frames = len / sizeof(SampleType) / this_ptr->m_output_channels;
|
||||
if (additional_amount > 0)
|
||||
{
|
||||
SDLAudioStream* const this_ptr = static_cast<SDLAudioStream*>(userdata);
|
||||
|
||||
this_ptr->ReadFrames(reinterpret_cast<SampleType*>(stream), num_frames);
|
||||
const u32 num_frames = additional_amount / sizeof(SampleType) / this_ptr->m_output_channels;
|
||||
SampleType* buffer = SDL_stack_alloc(SampleType, additional_amount / sizeof(SampleType));
|
||||
if (buffer)
|
||||
{
|
||||
this_ptr->ReadFrames(buffer, num_frames);
|
||||
SDL_PutAudioStreamData(stream, buffer, additional_amount);
|
||||
SDL_stack_free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,6 +237,7 @@ namespace FullscreenUI
|
||||
static void DrawAboutWindow();
|
||||
static void OpenAboutWindow();
|
||||
static void GetStandardSelectionFooterText(SmallStringBase& dest, bool back_instead_of_cancel);
|
||||
static void ApplyConfirmSetting(const SettingsInterface* bsi = nullptr);
|
||||
|
||||
static MainWindowType s_current_main_window = MainWindowType::None;
|
||||
static PauseSubMenu s_current_pause_submenu = PauseSubMenu::None;
|
||||
@@ -504,18 +505,23 @@ void FullscreenUI::GetStandardSelectionFooterText(SmallStringBase& dest, bool ba
|
||||
{
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
ImGuiFullscreen::CreateFooterTextString(
|
||||
dest,
|
||||
std::array{std::make_pair(ICON_PF_DPAD_UP_DOWN, FSUI_VSTR("Change Selection")),
|
||||
std::make_pair(ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_BUTTON_CIRCLE, back_instead_of_cancel ? FSUI_VSTR("Back") : FSUI_VSTR("Cancel"))});
|
||||
std::array{
|
||||
std::make_pair(ICON_PF_DPAD_UP_DOWN, FSUI_VSTR("Change Selection")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, back_instead_of_cancel ? FSUI_VSTR("Back") : FSUI_VSTR("Cancel")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiFullscreen::CreateFooterTextString(
|
||||
dest, std::array{std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, FSUI_VSTR("Change Selection")),
|
||||
dest, std::array{
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, FSUI_VSTR("Change Selection")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_ESC, back_instead_of_cancel ? FSUI_VSTR("Back") : FSUI_VSTR("Cancel"))});
|
||||
std::make_pair(ICON_PF_ESC, back_instead_of_cancel ? FSUI_VSTR("Back") : FSUI_VSTR("Cancel")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,19 +541,25 @@ void ImGuiFullscreen::GetFileSelectorHelpText(SmallStringBase& dest)
|
||||
{
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
ImGuiFullscreen::CreateFooterTextString(
|
||||
dest, std::array{std::make_pair(ICON_PF_DPAD_UP_DOWN, FSUI_VSTR("Change Selection")),
|
||||
dest, std::array{
|
||||
std::make_pair(ICON_PF_DPAD_UP_DOWN, FSUI_VSTR("Change Selection")),
|
||||
std::make_pair(ICON_PF_BUTTON_TRIANGLE, FSUI_VSTR("Parent Directory")),
|
||||
std::make_pair(ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Cancel"))});
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Cancel")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiFullscreen::CreateFooterTextString(
|
||||
dest,
|
||||
std::array{std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, FSUI_VSTR("Change Selection")),
|
||||
std::array{
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, FSUI_VSTR("Change Selection")),
|
||||
std::make_pair(ICON_PF_BACKSPACE, FSUI_VSTR("Parent Directory")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")), std::make_pair(ICON_PF_ESC, FSUI_VSTR("Cancel"))});
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Cancel")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,18 +567,81 @@ void ImGuiFullscreen::GetInputDialogHelpText(SmallStringBase& dest)
|
||||
{
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
CreateFooterTextString(dest, std::array{std::make_pair(ICON_PF_KEYBOARD, FSUI_VSTR("Enter Value")),
|
||||
std::make_pair(ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Cancel"))});
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
CreateFooterTextString(dest, std::array{
|
||||
std::make_pair(ICON_PF_KEYBOARD, FSUI_VSTR("Enter Value")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Cancel")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateFooterTextString(dest, std::array{std::make_pair(ICON_PF_KEYBOARD, FSUI_VSTR("Enter Value")),
|
||||
CreateFooterTextString(dest, std::array{
|
||||
std::make_pair(ICON_PF_KEYBOARD, FSUI_VSTR("Enter Value")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Cancel"))});
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Cancel")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void FullscreenUI::ApplyConfirmSetting(const SettingsInterface* bsi)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
SmallString swap_mode;
|
||||
if (bsi)
|
||||
swap_mode = bsi->GetSmallStringValue("UI", "SwapOKFullscreenUI", "auto");
|
||||
else
|
||||
swap_mode = Host::GetBaseSmallStringSettingValue("UI", "SwapOKFullscreenUI", "auto");
|
||||
|
||||
if (swap_mode == "true")
|
||||
io.ConfigNavSwapGamepadButtons = true;
|
||||
else if (swap_mode == "false")
|
||||
io.ConfigNavSwapGamepadButtons = false;
|
||||
else if (swap_mode == "auto")
|
||||
{
|
||||
// Check language
|
||||
if (Host::LocaleCircleConfirm())
|
||||
{
|
||||
io.ConfigNavSwapGamepadButtons = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check BIOS
|
||||
SmallString bios_selection;
|
||||
if (bsi)
|
||||
bios_selection = bsi->GetSmallStringValue("Filenames", "BIOS", "");
|
||||
else
|
||||
bios_selection = Host::GetBaseSmallStringSettingValue("Filenames", "BIOS", "");
|
||||
|
||||
if (bios_selection != "")
|
||||
{
|
||||
u32 bios_version, bios_region;
|
||||
std::string bios_description, bios_zone;
|
||||
if (IsBIOS(Path::Combine(EmuFolders::Bios, bios_selection).c_str(), bios_version, bios_description, bios_region, bios_zone))
|
||||
{
|
||||
// Japan, Asia, China
|
||||
if (bios_region == 0 || bios_region == 4 || bios_region == 6)
|
||||
{
|
||||
io.ConfigNavSwapGamepadButtons = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// X is confirm
|
||||
io.ConfigNavSwapGamepadButtons = false;
|
||||
return;
|
||||
}
|
||||
// Invalid setting
|
||||
else
|
||||
io.ConfigNavSwapGamepadButtons = false;
|
||||
}
|
||||
|
||||
void FullscreenUI::LocaleChanged()
|
||||
{
|
||||
ApplyConfirmSetting();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Main
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -579,8 +654,9 @@ bool FullscreenUI::Initialize()
|
||||
if (s_tried_to_initialize)
|
||||
return false;
|
||||
|
||||
ImGuiFullscreen::SetTheme(Host::GetBaseBoolSettingValue("UI", "UseLightFullscreenUITheme", false));
|
||||
ImGuiFullscreen::SetTheme(Host::GetBaseStringSettingValue("UI", "FullscreenUITheme", "Dark"));
|
||||
ImGuiFullscreen::UpdateLayoutScale();
|
||||
ApplyConfirmSetting();
|
||||
|
||||
if (!ImGuiManager::AddFullscreenFontsIfMissing() || !ImGuiFullscreen::Initialize("fullscreenui/placeholder.png") || !LoadResources())
|
||||
{
|
||||
@@ -632,6 +708,8 @@ void FullscreenUI::CheckForConfigChanges(const Pcsx2Config& old_config)
|
||||
if (!IsInitialized())
|
||||
return;
|
||||
|
||||
ImGuiFullscreen::SetTheme(Host::GetBaseStringSettingValue("UI", "FullscreenUITheme", "Dark"));
|
||||
|
||||
// If achievements got disabled, we might have the menu open...
|
||||
// That means we're going to be reaching achievement state.
|
||||
if (old_config.Achievements.Enabled && !EmuConfig.Achievements.Enabled)
|
||||
@@ -645,6 +723,13 @@ void FullscreenUI::CheckForConfigChanges(const Pcsx2Config& old_config)
|
||||
});
|
||||
MTGS::WaitGS(false, false, false);
|
||||
}
|
||||
|
||||
if (old_config.FullpathToBios() != EmuConfig.FullpathToBios())
|
||||
{
|
||||
MTGS::RunOnGSThread([]() {
|
||||
ApplyConfirmSetting();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void FullscreenUI::OnVMStarted()
|
||||
@@ -1306,13 +1391,14 @@ void FullscreenUI::DrawLandingWindow()
|
||||
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_SELECT_SHARE, FSUI_VSTR("About")),
|
||||
std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, FSUI_VSTR("Navigate")),
|
||||
std::make_pair(ICON_PF_BUTTON_TRIANGLE, FSUI_VSTR("Game List")),
|
||||
std::make_pair(ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Toggle Fullscreen")),
|
||||
std::make_pair(ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Exit"))
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Exit")),
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -1323,7 +1409,7 @@ void FullscreenUI::DrawLandingWindow()
|
||||
std::make_pair(ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, FSUI_VSTR("Navigate")),
|
||||
std::make_pair(ICON_PF_SPACE, FSUI_VSTR("Game List")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Exit"))
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Exit")),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1378,17 +1464,22 @@ void FullscreenUI::DrawStartGameWindow()
|
||||
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
SetFullscreenFooterText(std::array{std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, FSUI_VSTR("Navigate")),
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, FSUI_VSTR("Navigate")),
|
||||
std::make_pair(ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Load Global State")),
|
||||
std::make_pair(ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back"))});
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFullscreenFooterText(std::array{std::make_pair(ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, FSUI_VSTR("Navigate")),
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, FSUI_VSTR("Navigate")),
|
||||
std::make_pair(ICON_PF_F1, FSUI_VSTR("Load Global State")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Back"))});
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Back")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1430,19 +1521,20 @@ void FullscreenUI::DrawExitWindow()
|
||||
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, FSUI_VSTR("Navigate")),
|
||||
std::make_pair(ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back"))}
|
||||
);
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, FSUI_VSTR("Navigate")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Back"))}
|
||||
);
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Back")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1518,7 +1610,9 @@ void FullscreenUI::DrawInputBindingButton(
|
||||
return;
|
||||
|
||||
if (oneline)
|
||||
InputManager::PrettifyInputBinding(value);
|
||||
InputManager::PrettifyInputBinding(value, true);
|
||||
else
|
||||
InputManager::PrettifyInputBinding(value, false);
|
||||
|
||||
if (show_type)
|
||||
{
|
||||
@@ -3008,11 +3102,13 @@ void FullscreenUI::DrawSettingsWindow()
|
||||
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, FSUI_VSTR("Change Page")),
|
||||
std::make_pair(ICON_PF_DPAD_UP_DOWN, FSUI_VSTR("Navigate")),
|
||||
std::make_pair(ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back"))});
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3020,7 +3116,8 @@ void FullscreenUI::DrawSettingsWindow()
|
||||
std::make_pair(ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, FSUI_VSTR("Change Page")),
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, FSUI_VSTR("Navigate")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Back"))});
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Back")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3139,17 +3236,50 @@ void FullscreenUI::DrawSummarySettingsPage()
|
||||
|
||||
void FullscreenUI::DrawInterfaceSettingsPage()
|
||||
{
|
||||
static constexpr const char* s_theme_name[] = {
|
||||
FSUI_NSTR("Dark"),
|
||||
FSUI_NSTR("Light"),
|
||||
FSUI_NSTR("Grey Matter"),
|
||||
FSUI_NSTR("Untouched Lagoon"),
|
||||
FSUI_NSTR("Baby Pastel"),
|
||||
FSUI_NSTR("Pizza Time!"),
|
||||
FSUI_NSTR("PCSX2 Blue"),
|
||||
FSUI_NSTR("Scarlet Devil"),
|
||||
FSUI_NSTR("Violet Angel"),
|
||||
FSUI_NSTR("Cobalt Sky"),
|
||||
FSUI_NSTR("AMOLED"),
|
||||
};
|
||||
|
||||
static constexpr const char* s_theme_value[] = {
|
||||
"Dark",
|
||||
"Light",
|
||||
"GreyMatter",
|
||||
"UntouchedLagoon",
|
||||
"BabyPastel",
|
||||
"PizzaBrown",
|
||||
"PCSX2Blue",
|
||||
"ScarletDevil",
|
||||
"VioletAngel",
|
||||
"CobaltSky",
|
||||
"AMOLED",
|
||||
};
|
||||
|
||||
SettingsInterface* bsi = GetEditingSettingsInterface();
|
||||
|
||||
BeginMenuButtons();
|
||||
|
||||
MenuHeading(FSUI_CSTR("Behaviour"));
|
||||
MenuHeading(FSUI_CSTR("Appearance"));
|
||||
DrawStringListSetting(bsi, FSUI_ICONSTR(ICON_FA_PAINT_BRUSH, "Theme"),
|
||||
FSUI_CSTR("Selects the color style to be used for Big Picture Mode."),
|
||||
"UI", "FullscreenUITheme", "Dark", s_theme_name, s_theme_value, std::size(s_theme_name), true);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_INFO_CIRCLE, "Use Save State Selector"),
|
||||
FSUI_CSTR("Show a save state selector UI when switching slots instead of showing a notification bubble."),
|
||||
"EmuCore", "UseSavestateSelector", true);
|
||||
|
||||
MenuHeading(FSUI_CSTR("Behaviour"));
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_PF_SNOOZE, "Inhibit Screensaver"),
|
||||
FSUI_CSTR("Prevents the screen saver from activating and the host from sleeping while emulation is running."), "EmuCore",
|
||||
"InhibitScreensaver", true);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_USER_CIRCLE, "Enable Discord Presence"),
|
||||
FSUI_CSTR("Shows the game you are currently playing as part of your profile on Discord."), "UI", "DiscordPresence", false);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_PAUSE, "Pause On Start"), FSUI_CSTR("Pauses the emulator when a game is started."), "UI",
|
||||
"StartPaused", false);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_EYE, "Pause On Focus Loss"),
|
||||
@@ -3169,15 +3299,56 @@ void FullscreenUI::DrawInterfaceSettingsPage()
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_ARCHIVE, "Create Save State Backups"),
|
||||
FSUI_CSTR("Creates a backup copy of a save state if it already exists when the save is created. The backup copy has a .backup suffix"),
|
||||
"EmuCore", "BackupSavestate", true);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_INFO_CIRCLE, "Use Save State Selector"),
|
||||
FSUI_CSTR("Show a save state selector UI when switching slots instead of showing a notification bubble."),
|
||||
"EmuCore", "UseSavestateSelector", true);
|
||||
if (DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_LIGHTBULB, "Use Light Theme"),
|
||||
FSUI_CSTR("Uses a light coloured theme instead of the default dark theme."), "UI", "UseLightFullscreenUITheme", false))
|
||||
// DrawStringListSetting dosn't have a callback for applying settings
|
||||
const SmallString swap_mode = bsi->GetSmallStringValue("UI", "SwapOKFullscreenUI", "auto");
|
||||
static constexpr const char* swap_names[] = {
|
||||
FSUI_NSTR("Automatic"),
|
||||
FSUI_NSTR("Enabled"),
|
||||
FSUI_NSTR("Disabled"),
|
||||
};
|
||||
static constexpr const char* swap_values[] = {
|
||||
"auto",
|
||||
"true",
|
||||
"false",
|
||||
};
|
||||
size_t swap_index = std::size(swap_values);
|
||||
for (size_t i = 0; i < std::size(swap_values); i++)
|
||||
{
|
||||
ImGuiFullscreen::SetTheme(bsi->GetBoolValue("UI", "UseLightFullscreenUITheme", false));
|
||||
if (swap_mode == swap_values[i])
|
||||
{
|
||||
swap_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SmallStackString<256> swap_summery;
|
||||
swap_summery.format(FSUI_FSTR("Uses {} as confirm when using a controller"), ICON_PF_BUTTON_CIRCLE);
|
||||
if (MenuButtonWithValue(FSUI_ICONSTR(ICON_FA_GAMEPAD, "Swap OK/Cancel in Big Picture Mode"), swap_summery.c_str(),
|
||||
(swap_index < std::size(swap_values)) ? Host::TranslateToCString(TR_CONTEXT, swap_names[swap_index]) : FSUI_CSTR("Unknown")))
|
||||
{
|
||||
ImGuiFullscreen::ChoiceDialogOptions cd_options;
|
||||
cd_options.reserve(std::size(swap_values));
|
||||
for (size_t i = 0; i < std::size(swap_values); i++)
|
||||
cd_options.emplace_back(Host::TranslateToString(TR_CONTEXT, swap_names[i]), i == static_cast<size_t>(swap_index));
|
||||
|
||||
OpenChoiceDialog(FSUI_ICONSTR(ICON_FA_GAMEPAD, "Swap OK/Cancel in Big Picture Mode"), false, std::move(cd_options), [](s32 index, const std::string& title, bool checked) {
|
||||
if (index >= 0)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
SettingsInterface* bsi = GetEditingSettingsInterface(false);
|
||||
bsi->SetStringValue("UI", "SwapOKFullscreenUI", swap_values[index]);
|
||||
SetSettingsChanged(bsi);
|
||||
ApplyConfirmSetting(bsi);
|
||||
}
|
||||
|
||||
CloseChoiceDialog();
|
||||
});
|
||||
}
|
||||
|
||||
MenuHeading(FSUI_CSTR("Integration"));
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_USER_CIRCLE, "Enable Discord Presence"),
|
||||
FSUI_CSTR("Shows the game you are currently playing as part of your profile on Discord."), "UI", "DiscordPresence", false);
|
||||
|
||||
MenuHeading(FSUI_CSTR("Game Display"));
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_TV, "Start Fullscreen"),
|
||||
FSUI_CSTR("Automatically switches to fullscreen mode when a game is started."), "UI", "StartFullscreen", false);
|
||||
@@ -3291,6 +3462,7 @@ void FullscreenUI::DrawBIOSSettingsPage()
|
||||
SettingsInterface* bsi = GetEditingSettingsInterface(game_settings);
|
||||
bsi->SetStringValue("Filenames", "BIOS", values[index].c_str());
|
||||
SetSettingsChanged(bsi);
|
||||
ApplyConfirmSetting(bsi);
|
||||
CloseChoiceDialog();
|
||||
});
|
||||
}
|
||||
@@ -3809,7 +3981,8 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
|
||||
FSUI_NSTR("Normal (Vertex)"),
|
||||
FSUI_NSTR("Special (Texture)"),
|
||||
FSUI_NSTR("Special (Texture - Aggressive)"),
|
||||
FSUI_NSTR("Align To Native"),
|
||||
FSUI_NSTR("Align to Native"),
|
||||
FSUI_NSTR("Align to Native - with Texture Offset"),
|
||||
};
|
||||
static constexpr const char* s_native_scaling_options[] = {
|
||||
FSUI_NSTR("Normal (Default)"),
|
||||
@@ -3977,8 +4150,8 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
|
||||
static constexpr const char* s_gsdump_compression[] = {
|
||||
FSUI_NSTR("Uncompressed"),
|
||||
FSUI_NSTR("LZMA (xz)"),
|
||||
FSUI_NSTR("Zstandard (zst)")
|
||||
};
|
||||
FSUI_NSTR("Zstandard (zst)"),
|
||||
};
|
||||
|
||||
if (show_advanced_settings)
|
||||
{
|
||||
@@ -4314,11 +4487,11 @@ void FullscreenUI::DrawControllerSettingsPage()
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_COG, "Enable SDL Input Source"),
|
||||
FSUI_CSTR("The SDL input source supports most controllers."), "InputSources", "SDL", true, true, false);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_WIFI, "SDL DualShock 4 / DualSense Enhanced Mode"),
|
||||
FSUI_CSTR("Provides vibration and LED control support over Bluetooth."), "InputSources", "SDLControllerEnhancedMode", false,
|
||||
FSUI_CSTR("Provides vibration and LED control support over Bluetooth."), "InputSources", "SDLControllerEnhancedMode", true,
|
||||
bsi->GetBoolValue("InputSources", "SDL", true), false);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_LIGHTBULB, "SDL DualSense Player LED"),
|
||||
FSUI_CSTR("Enable/Disable the Player LED on DualSense controllers."), "InputSources", "SDLPS5PlayerLED", false,
|
||||
bsi->GetBoolValue("InputSources", "SDLControllerEnhancedMode", true), false);
|
||||
FSUI_CSTR("Enable/Disable the Player LED on DualSense controllers."), "InputSources", "SDLPS5PlayerLED", true,
|
||||
bsi->GetBoolValue("InputSources", "SDLControllerEnhancedMode", true), true);
|
||||
#ifdef _WIN32
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_COG, "SDL Raw Input"), FSUI_CSTR("Allow SDL to use raw access to input devices."),
|
||||
"InputSources", "SDLRawInput", false, bsi->GetBoolValue("InputSources", "SDL", true), false);
|
||||
@@ -4768,14 +4941,14 @@ void FullscreenUI::DrawAdvancedSettingsPage()
|
||||
FSUI_NSTR("Uncompressed"),
|
||||
FSUI_NSTR("Deflate64"),
|
||||
FSUI_NSTR("Zstandard"),
|
||||
FSUI_NSTR("LZMA2")
|
||||
FSUI_NSTR("LZMA2"),
|
||||
};
|
||||
|
||||
static constexpr const char* s_savestate_compression_ratio[] = {
|
||||
FSUI_NSTR("Low (Fast)"),
|
||||
FSUI_NSTR("Medium (Recommended)"),
|
||||
FSUI_NSTR("High"),
|
||||
FSUI_NSTR("Very High (Slow, Not Recommended)")
|
||||
FSUI_NSTR("Very High (Slow, Not Recommended)"),
|
||||
};
|
||||
|
||||
if (show_advanced_settings)
|
||||
@@ -5252,15 +5425,20 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
|
||||
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
SetFullscreenFooterText(std::array{std::make_pair(ICON_PF_DPAD_UP_DOWN, FSUI_VSTR("Change Selection")),
|
||||
std::make_pair(ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Return To Game"))});
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_DPAD_UP_DOWN, FSUI_VSTR("Change Selection")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Return To Game")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, FSUI_VSTR("Change Selection")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")), std::make_pair(ICON_PF_ESC, FSUI_VSTR("Return To Game"))});
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Return To Game")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5685,18 +5863,22 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
|
||||
{
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_DPAD, FSUI_VSTR("Select State")),
|
||||
std::make_pair(ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Options")),
|
||||
std::make_pair(ICON_PF_BUTTON_CROSS, FSUI_VSTR("Load/Save State")),
|
||||
std::make_pair(ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Cancel"))});
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Load/Save State")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Cancel")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, FSUI_VSTR("Select State")),
|
||||
std::make_pair(ICON_PF_F1, FSUI_VSTR("Options")), std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Load/Save State")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Cancel"))});
|
||||
std::make_pair(ICON_PF_F1, FSUI_VSTR("Options")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Load/Save State")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Cancel")),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5980,21 +6162,26 @@ void FullscreenUI::DrawGameListWindow()
|
||||
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_DPAD, FSUI_VSTR("Select Game")),
|
||||
std::make_pair(ICON_PF_START, FSUI_VSTR("Settings")),
|
||||
std::make_pair(ICON_PF_BUTTON_TRIANGLE, FSUI_VSTR("Change View")),
|
||||
std::make_pair(ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Launch Options")),
|
||||
std::make_pair(ICON_PF_BUTTON_CROSS, FSUI_VSTR("Start Game")),
|
||||
std::make_pair(ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back"))});
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Start Game")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, FSUI_VSTR("Select Game")),
|
||||
std::make_pair(ICON_PF_F1, FSUI_VSTR("Change View")), std::make_pair(ICON_PF_F2, FSUI_VSTR("Settings")),
|
||||
std::make_pair(ICON_PF_F3, FSUI_VSTR("Launch Options")), std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Start Game")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Back"))});
|
||||
std::make_pair(ICON_PF_F1, FSUI_VSTR("Change View")),
|
||||
std::make_pair(ICON_PF_F2, FSUI_VSTR("Settings")),
|
||||
std::make_pair(ICON_PF_F3, FSUI_VSTR("Launch Options")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Start Game")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Back")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6966,9 +7153,11 @@ TRANSLATE_NOOP("FullscreenUI", "Input Profile");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Options");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Copies the current global settings to this game.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Clears all settings set for this game.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Appearance");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Selects the color style to be used for Big Picture Mode.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Show a save state selector UI when switching slots instead of showing a notification bubble.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Behaviour");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Prevents the screen saver from activating and the host from sleeping while emulation is running.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Shows the game you are currently playing as part of your profile on Discord.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Pauses the emulator when a game is started.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Pauses the emulator when you minimize the window or switch to another application, and unpauses when you switch back.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Pauses the emulator when a controller with bindings is disconnected.");
|
||||
@@ -6976,8 +7165,8 @@ TRANSLATE_NOOP("FullscreenUI", "Pauses the emulator when you open the quick menu
|
||||
TRANSLATE_NOOP("FullscreenUI", "Determines whether a prompt will be displayed to confirm shutting down the emulator/game when the hotkey is pressed.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Automatically saves the emulator state when powering down or exiting. You can then resume directly from where you left off next time.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Creates a backup copy of a save state if it already exists when the save is created. The backup copy has a .backup suffix");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Show a save state selector UI when switching slots instead of showing a notification bubble.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Uses a light coloured theme instead of the default dark theme.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Integration");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Shows the game you are currently playing as part of your profile on Discord.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game Display");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Automatically switches to fullscreen mode when a game is started.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Switches between full screen and windowed when the window is double-clicked.");
|
||||
@@ -7384,6 +7573,7 @@ TRANSLATE_NOOP("FullscreenUI", "Automatic mapping completed for {}.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Automatic mapping failed for {}.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game settings initialized with global settings for '{}'.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game settings have been cleared for '{}'.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Uses {} as confirm when using a controller");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Slot {}");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{} (Current)");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{} (Folder)");
|
||||
@@ -7428,6 +7618,19 @@ TRANSLATE_NOOP("FullscreenUI", "Folder Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Advanced Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Patches");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Cheats");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Dark");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Light");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Grey Matter");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Untouched Lagoon");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Baby Pastel");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Pizza Time!");
|
||||
TRANSLATE_NOOP("FullscreenUI", "PCSX2 Blue");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Scarlet Devil");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Violet Angel");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Cobalt Sky");
|
||||
TRANSLATE_NOOP("FullscreenUI", "AMOLED");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Enabled");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disabled");
|
||||
TRANSLATE_NOOP("FullscreenUI", "2% [1 FPS (NTSC) / 1 FPS (PAL)]");
|
||||
TRANSLATE_NOOP("FullscreenUI", "10% [6 FPS (NTSC) / 5 FPS (PAL)]");
|
||||
TRANSLATE_NOOP("FullscreenUI", "25% [15 FPS (NTSC) / 12 FPS (PAL)]");
|
||||
@@ -7550,13 +7753,13 @@ TRANSLATE_NOOP("FullscreenUI", "Sprites/Triangles");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Blended Sprites/Triangles");
|
||||
TRANSLATE_NOOP("FullscreenUI", "1 (Normal)");
|
||||
TRANSLATE_NOOP("FullscreenUI", "2 (Aggressive)");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disabled");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Inside Target");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Merge Targets");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Normal (Vertex)");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Special (Texture)");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Special (Texture - Aggressive)");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Align To Native");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Align to Native");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Align to Native - with Texture Offset");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Aggressive");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Half");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Force Bilinear");
|
||||
@@ -7630,8 +7833,9 @@ TRANSLATE_NOOP("FullscreenUI", "Select Disc Path");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Cannot show details for games which were not scanned in the game list.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Copy Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Clear Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Theme");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Use Save State Selector");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Inhibit Screensaver");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Enable Discord Presence");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Pause On Start");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Pause On Focus Loss");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Pause On Controller Disconnection");
|
||||
@@ -7639,8 +7843,8 @@ TRANSLATE_NOOP("FullscreenUI", "Pause On Menu");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Confirm Shutdown");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Save State On Shutdown");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Create Save State Backups");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Use Save State Selector");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Use Light Theme");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Swap OK/Cancel in Big Picture Mode");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Enable Discord Presence");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Start Fullscreen");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Double-Click Toggles Fullscreen");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Hide Cursor In Fullscreen");
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace FullscreenUI
|
||||
void ReturnToPreviousWindow();
|
||||
void ReturnToMainWindow();
|
||||
void SetStandardSelectionFooterText(bool back_instead_of_cancel);
|
||||
void LocaleChanged();
|
||||
|
||||
void Shutdown(bool clear_state);
|
||||
void Render();
|
||||
@@ -51,4 +52,7 @@ namespace Host
|
||||
|
||||
void OnCoverDownloaderOpenRequested();
|
||||
void OnCreateMemoryCardOpenRequested();
|
||||
|
||||
/// Did Playstation in the currently selected locale use circle as confirm
|
||||
bool LocaleCircleConfirm();
|
||||
} // namespace Host
|
||||
|
||||
@@ -86,7 +86,6 @@ namespace ImGuiFullscreen
|
||||
static u32 s_menu_button_index = 0;
|
||||
static u32 s_close_button_state = 0;
|
||||
static FocusResetType s_focus_reset_queued = FocusResetType::None;
|
||||
static bool s_light_theme = false;
|
||||
|
||||
static LRUCache<std::string, std::shared_ptr<GSTexture>> s_texture_cache(128, true);
|
||||
static std::shared_ptr<GSTexture> s_placeholder_texture;
|
||||
@@ -2668,10 +2667,10 @@ void ImGuiFullscreen::DrawNotifications(ImVec2& position, float spacing)
|
||||
ImFont* const title_font = ImGuiFullscreen::g_large_font;
|
||||
ImFont* const text_font = ImGuiFullscreen::g_medium_font;
|
||||
|
||||
const u32 toast_background_color = s_light_theme ? IM_COL32(241, 241, 241, 255) : IM_COL32(0x21, 0x21, 0x21, 255);
|
||||
const u32 toast_border_color = s_light_theme ? IM_COL32(0x88, 0x88, 0x88, 255) : IM_COL32(0x48, 0x48, 0x48, 255);
|
||||
const u32 toast_title_color = s_light_theme ? IM_COL32(1, 1, 1, 255) : IM_COL32(0xff, 0xff, 0xff, 255);
|
||||
const u32 toast_text_color = s_light_theme ? IM_COL32(0, 0, 0, 255) : IM_COL32(0xff, 0xff, 0xff, 255);
|
||||
const u32 toast_background_color = IM_COL32(0x21, 0x21, 0x21, 255);
|
||||
const u32 toast_border_color = IM_COL32(0x48, 0x48, 0x48, 255);
|
||||
const u32 toast_title_color = IM_COL32(0xff, 0xff, 0xff, 255);
|
||||
const u32 toast_text_color = IM_COL32(0xff, 0xff, 0xff, 255);
|
||||
|
||||
for (u32 index = 0; index < static_cast<u32>(s_notifications.size());)
|
||||
{
|
||||
@@ -2839,13 +2838,10 @@ void ImGuiFullscreen::DrawToast()
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiFullscreen::SetTheme(bool light)
|
||||
void ImGuiFullscreen::SetTheme(std::string_view theme)
|
||||
{
|
||||
s_light_theme = light;
|
||||
|
||||
if (!light)
|
||||
if (theme == "Dark")
|
||||
{
|
||||
// dark
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x212121, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
@@ -2863,9 +2859,8 @@ void ImGuiFullscreen::SetTheme(bool light)
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x002171, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else
|
||||
else if (theme == "Light")
|
||||
{
|
||||
// light
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0xc8c8c8, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xe1e2e1, 0xff);
|
||||
@@ -2883,4 +2878,175 @@ void ImGuiFullscreen::SetTheme(bool light)
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0xc0cfff, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
}
|
||||
else if (theme == "AMOLED")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0x0c0c0c, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x212121, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x0a0a0a, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xb5b5b5, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x8d8d8d, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0x191919, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x474747, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else if (theme == "CobaltSky")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x2b3760, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0x3b54ac, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x2b3760, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x202e5a, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xb5b5b5, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x222c4d, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x8d8d8d, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0x245dda, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x3a3d7b, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else if (theme == "GreyMatter")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x353944, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0x484d57, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x212121, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x292d35, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xb5b5b5, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x212121, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x8d8d8d, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0x191919, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x2a2e36, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else if (theme == "UntouchedLagoon")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x9db1bb, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0x1b7f7f, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x488c8c, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0xa2c2bc, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xadcfc8, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x488c8c, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x4b4b4b, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0x2a5151, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x475055, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
}
|
||||
else if (theme == "BabyPastel")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0xf1d9ee, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xe05885, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0xe05885, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0xeba0b9, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0xffaec9, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xe05885, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0xc3859a, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x4b4b4b, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0xeba0b9, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0xe05885, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0xdc6c68, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0xab5451, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
}
|
||||
else if (theme == "PizzaBrown")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0xd9c9ba, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0xaa5a36, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0xefad42, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0xe9bb93, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xf9e7ac, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0xefad42, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x4b4b4b, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0xaf1c2f, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0xab5451, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
}
|
||||
else if (theme == "ScarletDevil")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x782c44, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0xa73e5f, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x88475d, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x4f2c44, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xb5b5b5, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x632438, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0xc80000, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x8a334e, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else if (theme == "VioletAngel")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x6e1e7d, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0x862c9c, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0x862c9c, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x502657, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x321846, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0x9833d6, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x70269e, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0xe200cb, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0xff00e6, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x561d79, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else if (theme == "PCSX2Blue")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x819af0, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0x89a5ff, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0xfefffe, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0xb4cffe, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x92b6fe, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0x89a5ff, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x7c8ef3, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x4b4b4b, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x92b6fe, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0x0c53c5, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x819af0, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace ImGuiFullscreen
|
||||
/// Initializes, setting up any state.
|
||||
bool Initialize(const char* placeholder_image_path);
|
||||
|
||||
void SetTheme(bool light);
|
||||
void SetTheme(std::string_view theme);
|
||||
void SetFonts(ImFont* standard_font, ImFont* medium_font, ImFont* large_font);
|
||||
bool UpdateLayoutScale();
|
||||
|
||||
|
||||
@@ -489,7 +489,7 @@ bool ImGuiManager::AddIconFonts(float size)
|
||||
{
|
||||
// clang-format off
|
||||
static constexpr ImWchar range_fa[] = { 0xe06f,0xe06f,0xf002,0xf002,0xf005,0xf005,0xf007,0xf007,0xf00c,0xf00e,0xf011,0xf011,0xf013,0xf013,0xf017,0xf017,0xf019,0xf019,0xf021,0xf023,0xf025,0xf028,0xf02b,0xf02b,0xf02e,0xf02e,0xf030,0xf030,0xf03a,0xf03a,0xf03d,0xf03e,0xf04b,0xf04c,0xf04e,0xf04e,0xf050,0xf050,0xf052,0xf052,0xf05a,0xf05a,0xf05e,0xf05e,0xf063,0xf063,0xf067,0xf067,0xf06a,0xf06a,0xf06e,0xf06e,0xf071,0xf071,0xf077,0xf078,0xf07b,0xf07c,0xf084,0xf084,0xf091,0xf091,0xf0ac,0xf0ad,0xf0b0,0xf0b0,0xf0c5,0xf0c5,0xf0c7,0xf0c8,0xf0cb,0xf0cb,0xf0d0,0xf0d0,0xf0dc,0xf0dc,0xf0e2,0xf0e2,0xf0eb,0xf0eb,0xf0f3,0xf0f3,0xf0fe,0xf0fe,0xf11b,0xf11c,0xf120,0xf121,0xf129,0xf12a,0xf140,0xf140,0xf14a,0xf14a,0xf15b,0xf15b,0xf15d,0xf15d,0xf187,0xf188,0xf191,0xf192,0xf1b3,0xf1b3,0xf1de,0xf1de,0xf1e6,0xf1e6,0xf1ea,0xf1eb,0xf1f8,0xf1f8,0xf1fc,0xf1fc,0xf21e,0xf21e,0xf245,0xf245,0xf26c,0xf26c,0xf279,0xf279,0xf2bd,0xf2bd,0xf2db,0xf2db,0xf2f2,0xf2f2,0xf302,0xf302,0xf3c1,0xf3c1,0xf3fd,0xf3fd,0xf410,0xf410,0xf462,0xf462,0xf466,0xf466,0xf4e2,0xf4e2,0xf51f,0xf51f,0xf545,0xf545,0xf54c,0xf54c,0xf553,0xf553,0xf56d,0xf56d,0xf5a2,0xf5a2,0xf65d,0xf65e,0xf6a9,0xf6a9,0xf70e,0xf70e,0xf756,0xf756,0xf780,0xf780,0xf794,0xf794,0xf815,0xf815,0xf84c,0xf84c,0xf8cc,0xf8cc,0x0,0x0 };
|
||||
static constexpr ImWchar range_pf[] = { 0x2198,0x2199,0x219e,0x21a3,0x21b0,0x21b3,0x21ba,0x21c3,0x21ce,0x21ce,0x21d0,0x21d4,0x21dc,0x21dd,0x21e0,0x21e3,0x21f3,0x21f3,0x21f7,0x21f8,0x21fa,0x21fb,0x221a,0x221a,0x227a,0x227d,0x22bf,0x22c8,0x2349,0x2349,0x235a,0x235e,0x2360,0x2361,0x2364,0x2367,0x237a,0x237b,0x237d,0x237d,0x237f,0x237f,0x23b2,0x23b5,0x23cc,0x23cc,0x23f4,0x23f7,0x2427,0x243a,0x243d,0x243d,0x2443,0x2443,0x2460,0x246b,0x248f,0x248f,0x24f5,0x24fd,0x24ff,0x24ff,0x2605,0x2605,0x2699,0x2699,0x278a,0x278e,0xe001,0xe001,0xff21,0xff3a,0x0,0x0 };
|
||||
static constexpr ImWchar range_pf[] = { 0x2198,0x2199,0x219e,0x21a7,0x21b0,0x21b3,0x21ba,0x21c3,0x21ce,0x21ce,0x21d0,0x21d4,0x21dc,0x21dd,0x21e0,0x21e3,0x21e6,0x21e8,0x21f3,0x21f3,0x21f7,0x21f8,0x21fa,0x21fb,0x2206,0x2208,0x221a,0x221a,0x227a,0x227d,0x22bf,0x22c8,0x2349,0x2349,0x235a,0x235e,0x2360,0x2361,0x2364,0x2367,0x237a,0x237b,0x237d,0x237d,0x237f,0x237f,0x23b2,0x23b5,0x23cc,0x23cc,0x23f4,0x23f7,0x2427,0x243a,0x243d,0x243d,0x2443,0x2443,0x2460,0x246b,0x248f,0x248f,0x24f5,0x24fd,0x24ff,0x24ff,0x2605,0x2605,0x2699,0x2699,0x278a,0x278e,0xe000,0xe001,0xff21,0xff3a,0x0,0x0 };
|
||||
// clang-format on
|
||||
|
||||
{
|
||||
|
||||
@@ -45,6 +45,17 @@ std::string DInputSource::GetDeviceIdentifier(u32 index)
|
||||
return fmt::format("DInput-{}", index);
|
||||
}
|
||||
|
||||
static constexpr const char* s_dinput_axis_names[] = {
|
||||
"X Axis",
|
||||
"Y Axis",
|
||||
"Z Axis",
|
||||
"Z Rotation",
|
||||
"X Rotation",
|
||||
"Y Rotation",
|
||||
"Slider 1",
|
||||
"Slider 2",
|
||||
};
|
||||
|
||||
static constexpr std::array<const char*, DInputSource::NUM_HAT_DIRECTIONS> s_hat_directions = {{"Up", "Down", "Left", "Right"}};
|
||||
|
||||
bool DInputSource::Initialize(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock)
|
||||
@@ -150,6 +161,15 @@ void DInputSource::Shutdown()
|
||||
GetDeviceIdentifier(index));
|
||||
m_controllers.pop_back();
|
||||
}
|
||||
|
||||
m_toplevel_window = nullptr;
|
||||
m_dinput.reset();
|
||||
m_dinput_module.reset();
|
||||
}
|
||||
|
||||
bool DInputSource::IsInitialized()
|
||||
{
|
||||
return m_toplevel_window;
|
||||
}
|
||||
|
||||
bool DInputSource::AddDevice(ControllerData& cd, const std::string& name)
|
||||
@@ -379,7 +399,7 @@ std::optional<InputBindingKey> DInputSource::ParseKeyString(const std::string_vi
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
TinyString DInputSource::ConvertKeyToString(InputBindingKey key)
|
||||
TinyString DInputSource::ConvertKeyToString(InputBindingKey key, bool display, bool migration)
|
||||
{
|
||||
TinyString ret;
|
||||
|
||||
@@ -387,18 +407,33 @@ TinyString DInputSource::ConvertKeyToString(InputBindingKey key)
|
||||
{
|
||||
if (key.source_subtype == InputSubclass::ControllerAxis)
|
||||
{
|
||||
const char* modifier = (key.modifier == InputModifier::FullAxis ? "Full" : (key.modifier == InputModifier::Negate ? "-" : "+"));
|
||||
ret.format("DInput-{}/{}Axis{}{}", u32(key.source_index), modifier, u32(key.data), (key.invert && !ShouldIgnoreInversion()) ? "~" : "");
|
||||
const char* modifier = (key.modifier == InputModifier::FullAxis ? (display ? "Full " : "Full") : (key.modifier == InputModifier::Negate ? "-" : "+"));
|
||||
if (display)
|
||||
{
|
||||
if (key.data < std::size(s_dinput_axis_names))
|
||||
ret.format("DInput-{} {}{}{}", u32(key.source_index), modifier, s_dinput_axis_names[key.data], key.invert ? "~" : "");
|
||||
else
|
||||
ret.format("DInput-{} {}Axis {}{}", u32(key.source_index), modifier, u32(key.data) + 1, key.invert ? "~" : "");
|
||||
}
|
||||
else
|
||||
ret.format("DInput-{}/{}Axis{}{}", u32(key.source_index), modifier, u32(key.data), (key.invert && (migration || !ShouldIgnoreInversion())) ? "~" : "");
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::ControllerButton && key.data >= MAX_NUM_BUTTONS)
|
||||
{
|
||||
// Note, hats currently get mapped to buttons
|
||||
const u32 hat_num = (key.data - MAX_NUM_BUTTONS) / NUM_HAT_DIRECTIONS;
|
||||
const u32 hat_dir = (key.data - MAX_NUM_BUTTONS) % NUM_HAT_DIRECTIONS;
|
||||
ret.format("DInput-{}/Hat{}{}", u32(key.source_index), hat_num, s_hat_directions[hat_dir]);
|
||||
if (display)
|
||||
ret.format("DInput-{} Hat {} {}", u32(key.source_index), hat_num + 1, s_hat_directions[hat_dir]);
|
||||
else
|
||||
ret.format("DInput-{}/Hat{}{}", u32(key.source_index), hat_num, s_hat_directions[hat_dir]);
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::ControllerButton)
|
||||
{
|
||||
ret.format("DInput-{}/Button{}", u32(key.source_index), u32(key.data));
|
||||
if (display)
|
||||
ret.format("DInput-{} Button {}", u32(key.source_index), u32(key.data) + 1);
|
||||
else
|
||||
ret.format("DInput-{}/Button{}", u32(key.source_index), u32(key.data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
||||
bool ReloadDevices() override;
|
||||
void Shutdown() override;
|
||||
bool IsInitialized() override;
|
||||
|
||||
void PollEvents() override;
|
||||
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
||||
@@ -47,7 +48,7 @@ public:
|
||||
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
||||
|
||||
std::optional<InputBindingKey> ParseKeyString(const std::string_view device, const std::string_view binding) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key, bool display = false, bool migration = false) override;
|
||||
TinyString ConvertKeyToIcon(InputBindingKey key) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "SIO/Sio.h"
|
||||
#include "USB/USB.h"
|
||||
#include "VMManager.h"
|
||||
#include "LayeredSettingsInterface.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
@@ -92,19 +93,23 @@ namespace InputManager
|
||||
static std::optional<InputBindingKey> ParseHostKeyboardKey(const std::string_view source, const std::string_view sub_binding);
|
||||
static std::optional<InputBindingKey> ParsePointerKey(const std::string_view source, const std::string_view sub_binding);
|
||||
|
||||
static std::vector<std::string_view> SplitChord(const std::string_view binding);
|
||||
static TinyString ConvertKeyboardKeyToString(InputBindingKey key, bool display = false);
|
||||
static TinyString ConvertPointerKeyToString(InputBindingKey key, bool display = false);
|
||||
|
||||
static bool SplitBinding(const std::string_view binding, std::string_view* source, std::string_view* sub_binding);
|
||||
static void PrettifyInputBindingPart(const std::string_view binding, SmallString& ret, bool& changed);
|
||||
static void AddBinding(const std::string_view binding, const InputEventHandler& handler);
|
||||
static void AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler);
|
||||
static void PrettifyInputBindingPart(const std::string_view binding, SmallString& ret, bool& changed, bool use_icons);
|
||||
static std::shared_ptr<InputBinding> AddBinding(const std::string_view binding, const InputEventHandler& handler);
|
||||
// Will also apply SDL2-SDL3 migrations and update the provided section & key
|
||||
static void AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler,
|
||||
InputBindingInfo::Type binding_type, SettingsInterface& si, const char* section, const char* key, bool is_profile);
|
||||
static bool ParseBindingAndGetSource(const std::string_view binding, InputBindingKey* key, InputSource** source);
|
||||
|
||||
static bool IsAxisHandler(const InputEventHandler& handler);
|
||||
static float ApplySingleBindingScale(float sensitivity, float deadzone, float value);
|
||||
|
||||
static void AddHotkeyBindings(SettingsInterface& si);
|
||||
static void AddPadBindings(SettingsInterface& si, u32 pad);
|
||||
static void AddUSBBindings(SettingsInterface& si, u32 port);
|
||||
static void AddHotkeyBindings(SettingsInterface& si, bool is_profile);
|
||||
static void AddPadBindings(SettingsInterface& si, u32 pad, bool is_profile);
|
||||
static void AddUSBBindings(SettingsInterface& si, u32 port, bool is_profile);
|
||||
static void UpdateContinuedVibration();
|
||||
static void GenerateRelativeMouseEvents();
|
||||
|
||||
@@ -143,9 +148,12 @@ static const HotkeyInfo* const s_hotkey_list[] = {g_common_hotkeys, g_gs_hotkeys
|
||||
// Tracking host mouse movement and turning into relative events
|
||||
// 4 axes: pointer left/right, wheel vertical/horizontal. Last/Next/Normalized.
|
||||
// ------------------------------------------------------------------------
|
||||
static constexpr const std::array<const char*, static_cast<u8>(InputPointerAxis::Count)> s_pointer_axis_names = {
|
||||
static constexpr const std::array<const char*, static_cast<u8>(InputPointerAxis::Count)> s_pointer_axis_setting_names = {
|
||||
{"X", "Y", "WheelX", "WheelY"}};
|
||||
static constexpr const std::array<const char*, 3> s_pointer_button_names = {{"LeftButton", "RightButton", "MiddleButton"}};
|
||||
static constexpr const std::array<const char*, static_cast<u8>(InputPointerAxis::Count)> s_pointer_axis_names = {
|
||||
{"X", "Y", "Wheel X", "Wheel Y"}};
|
||||
static constexpr const std::array<const char*, 3> s_pointer_button_setting_names = {{"LeftButton", "RightButton", "MiddleButton"}};
|
||||
static constexpr const std::array<const char*, 3> s_pointer_button_names = {{"Left Button", "Right Button", "Middle Button"}};
|
||||
|
||||
struct PointerAxisState
|
||||
{
|
||||
@@ -233,7 +241,7 @@ std::optional<InputBindingKey> InputManager::ParseInputBindingKey(const std::str
|
||||
{
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
{
|
||||
std::optional<InputBindingKey> key = s_input_sources[i]->ParseKeyString(source, sub_binding);
|
||||
if (key.has_value())
|
||||
@@ -253,7 +261,7 @@ bool InputManager::ParseBindingAndGetSource(const std::string_view binding, Inpu
|
||||
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
{
|
||||
std::optional<InputBindingKey> parsed_key = s_input_sources[i]->ParseKeyString(source_string, sub_binding);
|
||||
if (parsed_key.has_value())
|
||||
@@ -268,7 +276,62 @@ bool InputManager::ParseBindingAndGetSource(const std::string_view binding, Inpu
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string InputManager::ConvertInputBindingKeyToString(InputBindingInfo::Type binding_type, InputBindingKey key)
|
||||
TinyString InputManager::ConvertKeyboardKeyToString(InputBindingKey key, bool display)
|
||||
{
|
||||
TinyString ret;
|
||||
|
||||
if (key.source_type == InputSourceType::Keyboard)
|
||||
{
|
||||
const std::optional<std::string> str(ConvertHostKeyboardCodeToString(key.data));
|
||||
if (str.has_value() && !str->empty())
|
||||
if (display)
|
||||
// Keyboard keys arn't spaced out for display yet
|
||||
ret.format("Keyboard {}", str->c_str());
|
||||
else
|
||||
ret.format("Keyboard/{}", str->c_str());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
TinyString InputManager::ConvertPointerKeyToString(InputBindingKey key, bool display)
|
||||
{
|
||||
TinyString ret;
|
||||
|
||||
if (key.source_type == InputSourceType::Pointer)
|
||||
{
|
||||
if (key.source_subtype == InputSubclass::PointerButton)
|
||||
{
|
||||
if (display)
|
||||
{
|
||||
if (key.data < s_pointer_button_setting_names.size())
|
||||
ret.format("Pointer-{} {}", u32{key.source_index}, s_pointer_button_names[key.data]);
|
||||
else
|
||||
ret.format("Pointer-{} Button{}", u32{key.source_index}, key.data + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key.data < s_pointer_button_setting_names.size())
|
||||
ret.format("Pointer-{}/{}", u32{key.source_index}, s_pointer_button_setting_names[key.data]);
|
||||
else
|
||||
ret.format("Pointer-{}/Button{}", u32{key.source_index}, key.data);
|
||||
}
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::PointerAxis)
|
||||
{
|
||||
if (display)
|
||||
ret.format("Pointer-{} {}{:c}", u32{key.source_index}, s_pointer_axis_setting_names[key.data],
|
||||
key.modifier == InputModifier::Negate ? '-' : '+');
|
||||
else
|
||||
ret.format("Pointer-{}/{}{:c}", u32{key.source_index}, s_pointer_axis_setting_names[key.data],
|
||||
key.modifier == InputModifier::Negate ? '-' : '+');
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string InputManager::ConvertInputBindingKeyToString(InputBindingInfo::Type binding_type, InputBindingKey key, bool migration)
|
||||
{
|
||||
if (binding_type == InputBindingInfo::Type::Pointer || binding_type == InputBindingInfo::Type::Device)
|
||||
{
|
||||
@@ -295,48 +358,35 @@ std::string InputManager::ConvertInputBindingKeyToString(InputBindingInfo::Type
|
||||
{
|
||||
if (key.source_type == InputSourceType::Keyboard)
|
||||
{
|
||||
const std::optional<std::string> str(ConvertHostKeyboardCodeToString(key.data));
|
||||
if (str.has_value() && !str->empty())
|
||||
return fmt::format("Keyboard/{}", str->c_str());
|
||||
return std::string(ConvertKeyboardKeyToString(key));
|
||||
}
|
||||
else if (key.source_type == InputSourceType::Pointer)
|
||||
{
|
||||
if (key.source_subtype == InputSubclass::PointerButton)
|
||||
{
|
||||
if (key.data < s_pointer_button_names.size())
|
||||
return fmt::format("Pointer-{}/{}", u32{key.source_index}, s_pointer_button_names[key.data]);
|
||||
else
|
||||
return fmt::format("Pointer-{}/Button{}", u32{key.source_index}, key.data);
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::PointerAxis)
|
||||
{
|
||||
return fmt::format("Pointer-{}/{}{:c}", u32{key.source_index}, s_pointer_axis_names[key.data],
|
||||
key.modifier == InputModifier::Negate ? '-' : '+');
|
||||
}
|
||||
return std::string(ConvertPointerKeyToString(key));
|
||||
}
|
||||
else if (key.source_type < InputSourceType::Count && s_input_sources[static_cast<u32>(key.source_type)])
|
||||
{
|
||||
return std::string(s_input_sources[static_cast<u32>(key.source_type)]->ConvertKeyToString(key));
|
||||
return std::string(s_input_sources[static_cast<u32>(key.source_type)]->ConvertKeyToString(key, false, migration));
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string InputManager::ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type, const InputBindingKey* keys, size_t num_keys)
|
||||
std::string InputManager::ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type, const InputBindingKey* keys, size_t num_keys, bool migration)
|
||||
{
|
||||
// can't have a chord of devices/pointers
|
||||
if (binding_type == InputBindingInfo::Type::Pointer || binding_type == InputBindingInfo::Type::Device)
|
||||
{
|
||||
// so only take the first
|
||||
if (num_keys > 0)
|
||||
return ConvertInputBindingKeyToString(binding_type, keys[0]);
|
||||
return ConvertInputBindingKeyToString(binding_type, keys[0], migration);
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
for (size_t i = 0; i < num_keys; i++)
|
||||
{
|
||||
const std::string keystr(ConvertInputBindingKeyToString(binding_type, keys[i]));
|
||||
const std::string keystr(ConvertInputBindingKeyToString(binding_type, keys[i], migration));
|
||||
if (keystr.empty())
|
||||
return std::string();
|
||||
|
||||
@@ -349,7 +399,7 @@ std::string InputManager::ConvertInputBindingKeysToString(InputBindingInfo::Type
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
|
||||
bool InputManager::PrettifyInputBinding(SmallStringBase& binding, bool use_icons)
|
||||
{
|
||||
if (binding.empty())
|
||||
return false;
|
||||
@@ -370,7 +420,7 @@ bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
|
||||
{
|
||||
if (!ret.empty())
|
||||
ret.append(" + ");
|
||||
PrettifyInputBindingPart(part, ret, changed);
|
||||
PrettifyInputBindingPart(part, ret, changed, use_icons);
|
||||
}
|
||||
}
|
||||
last = next + 1;
|
||||
@@ -382,7 +432,7 @@ bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
|
||||
{
|
||||
if (!ret.empty())
|
||||
ret.append(" + ");
|
||||
PrettifyInputBindingPart(part, ret, changed);
|
||||
PrettifyInputBindingPart(part, ret, changed, use_icons);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,7 +442,7 @@ bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
|
||||
return changed;
|
||||
}
|
||||
|
||||
void InputManager::PrettifyInputBindingPart(const std::string_view binding, SmallString& ret, bool& changed)
|
||||
void InputManager::PrettifyInputBindingPart(const std::string_view binding, SmallString& ret, bool& changed, bool use_icons)
|
||||
{
|
||||
std::string_view source, sub_binding;
|
||||
if (!SplitBinding(binding, &source, &sub_binding))
|
||||
@@ -402,12 +452,30 @@ void InputManager::PrettifyInputBindingPart(const std::string_view binding, Smal
|
||||
if (source.starts_with("Keyboard"))
|
||||
{
|
||||
std::optional<InputBindingKey> key = ParseHostKeyboardKey(source, sub_binding);
|
||||
const char* icon = key.has_value() ? ConvertHostKeyboardCodeToIcon(key->data) : nullptr;
|
||||
if (icon)
|
||||
if (key.has_value())
|
||||
{
|
||||
ret.append(icon);
|
||||
changed = true;
|
||||
return;
|
||||
if (use_icons)
|
||||
{
|
||||
const char* icon = ConvertHostKeyboardCodeToIcon(key->data);
|
||||
if (icon)
|
||||
{
|
||||
ret.append(icon);
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.append(ConvertKeyboardKeyToString(key.value(), true));
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.append(ConvertKeyboardKeyToString(key.value(), true));
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (source.starts_with("Pointer"))
|
||||
@@ -415,7 +483,7 @@ void InputManager::PrettifyInputBindingPart(const std::string_view binding, Smal
|
||||
const std::optional<InputBindingKey> key = ParsePointerKey(source, sub_binding);
|
||||
if (key.has_value())
|
||||
{
|
||||
if (key->source_subtype == InputSubclass::PointerButton)
|
||||
if (use_icons && key->source_subtype == InputSubclass::PointerButton)
|
||||
{
|
||||
static constexpr const char* button_icons[] = {
|
||||
ICON_PF_MOUSE_BUTTON_1,
|
||||
@@ -425,32 +493,41 @@ void InputManager::PrettifyInputBindingPart(const std::string_view binding, Smal
|
||||
ICON_PF_MOUSE_BUTTON_5,
|
||||
};
|
||||
if (key->data < std::size(button_icons))
|
||||
{
|
||||
ret.append(button_icons[key->data]);
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
ret.append(ConvertPointerKeyToString(key.value(), true));
|
||||
}
|
||||
else
|
||||
ret.append(ConvertPointerKeyToString(key.value(), true));
|
||||
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
// We call ConvertKeyToIcon/String() even on disabled sources
|
||||
// This ensures consistant appearance between enabled and disabled sources
|
||||
if (s_input_sources[i])
|
||||
{
|
||||
std::optional<InputBindingKey> key = s_input_sources[i]->ParseKeyString(source, sub_binding);
|
||||
if (key.has_value())
|
||||
{
|
||||
const TinyString icon = s_input_sources[i]->ConvertKeyToIcon(key.value());
|
||||
if (!icon.empty())
|
||||
if (use_icons)
|
||||
{
|
||||
ret.append(icon);
|
||||
changed = true;
|
||||
return;
|
||||
const TinyString icon = s_input_sources[i]->ConvertKeyToIcon(key.value());
|
||||
if (!icon.empty())
|
||||
ret.append(icon);
|
||||
else
|
||||
ret.append(s_input_sources[i]->ConvertKeyToString(key.value(), true));
|
||||
}
|
||||
else
|
||||
ret.append(s_input_sources[i]->ConvertKeyToString(key.value(), true));
|
||||
|
||||
break;
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -460,7 +537,7 @@ void InputManager::PrettifyInputBindingPart(const std::string_view binding, Smal
|
||||
}
|
||||
|
||||
|
||||
void InputManager::AddBinding(const std::string_view binding, const InputEventHandler& handler)
|
||||
std::shared_ptr<InputBinding> InputManager::AddBinding(const std::string_view binding, const InputEventHandler& handler)
|
||||
{
|
||||
std::shared_ptr<InputBinding> ibinding;
|
||||
const std::vector<std::string_view> chord_bindings(SplitChord(binding));
|
||||
@@ -494,17 +571,74 @@ void InputManager::AddBinding(const std::string_view binding, const InputEventHa
|
||||
}
|
||||
|
||||
if (!ibinding)
|
||||
return;
|
||||
return nullptr;
|
||||
|
||||
// plop it in the input map for all the keys
|
||||
for (u32 i = 0; i < ibinding->num_keys; i++)
|
||||
s_binding_map.emplace(ibinding->keys[i].MaskDirection(), ibinding);
|
||||
|
||||
return ibinding;
|
||||
}
|
||||
|
||||
void InputManager::AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler)
|
||||
void InputManager::AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler,
|
||||
InputBindingInfo::Type binding_type, SettingsInterface& si, const char* section, const char* key, bool is_profile)
|
||||
{
|
||||
std::vector<std::shared_ptr<InputBinding>> ibindings;
|
||||
|
||||
bool migrate = false;
|
||||
for (const std::string& binding : bindings)
|
||||
AddBinding(binding, handler);
|
||||
{
|
||||
std::shared_ptr<InputBinding> ibinding = AddBinding(binding, handler);
|
||||
ibindings.push_back(ibinding);
|
||||
|
||||
if (ibinding)
|
||||
{
|
||||
// Check for SDL2-3 migrations
|
||||
for (u32 i = 0; i < ibinding->num_keys; i++)
|
||||
{
|
||||
if (ibinding->keys[i].needs_migration)
|
||||
migrate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save migrations
|
||||
if (migrate)
|
||||
{
|
||||
std::vector<std::string> new_bindings;
|
||||
new_bindings.reserve(bindings.size());
|
||||
|
||||
for (int i = 0; i < bindings.size(); i++)
|
||||
{
|
||||
if (ibindings[i])
|
||||
new_bindings.push_back(ConvertInputBindingKeysToString(binding_type, ibindings[i]->keys, ibindings[i]->num_keys, true));
|
||||
else
|
||||
// Retain invalid bindings as is
|
||||
new_bindings.push_back(bindings[i]);
|
||||
}
|
||||
|
||||
if (is_profile)
|
||||
{
|
||||
// INISettingsInterface, can just update directly
|
||||
si.SetStringList(section, key, new_bindings);
|
||||
si.Save();
|
||||
}
|
||||
else
|
||||
{
|
||||
// LayeredSettingsInterface, Need to find which layer our binding came from
|
||||
LayeredSettingsInterface& lsi = static_cast<LayeredSettingsInterface&>(si);
|
||||
for (int i = 0; i < LayeredSettingsInterface::NUM_LAYERS; i++)
|
||||
{
|
||||
SettingsInterface* layer = lsi.GetLayer(static_cast<LayeredSettingsInterface::Layer>(i));
|
||||
if (layer && layer->GetStringList(section, key) == bindings)
|
||||
{
|
||||
// Layer found, update settings
|
||||
layer->SetStringList(section, key, new_bindings);
|
||||
layer->Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@@ -632,14 +766,14 @@ std::optional<InputBindingKey> InputManager::ParsePointerKey(const std::string_v
|
||||
return key;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < s_pointer_axis_names.size(); i++)
|
||||
for (u32 i = 0; i < s_pointer_axis_setting_names.size(); i++)
|
||||
{
|
||||
if (sub_binding.starts_with(s_pointer_axis_names[i]))
|
||||
if (sub_binding.starts_with(s_pointer_axis_setting_names[i]))
|
||||
{
|
||||
key.source_subtype = InputSubclass::PointerAxis;
|
||||
key.data = i;
|
||||
|
||||
const std::string_view dir_part(sub_binding.substr(std::strlen(s_pointer_axis_names[i])));
|
||||
const std::string_view dir_part(sub_binding.substr(std::strlen(s_pointer_axis_setting_names[i])));
|
||||
if (dir_part == "+")
|
||||
key.modifier = InputModifier::None;
|
||||
else if (dir_part == "-")
|
||||
@@ -651,9 +785,9 @@ std::optional<InputBindingKey> InputManager::ParsePointerKey(const std::string_v
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < s_pointer_button_names.size(); i++)
|
||||
for (u32 i = 0; i < s_pointer_button_setting_names.size(); i++)
|
||||
{
|
||||
if (sub_binding == s_pointer_button_names[i])
|
||||
if (sub_binding == s_pointer_button_setting_names[i])
|
||||
{
|
||||
key.source_subtype = InputSubclass::PointerButton;
|
||||
key.data = i;
|
||||
@@ -702,7 +836,7 @@ std::vector<const HotkeyInfo*> InputManager::GetHotkeyList()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void InputManager::AddHotkeyBindings(SettingsInterface& si)
|
||||
void InputManager::AddHotkeyBindings(SettingsInterface& si, bool is_profile)
|
||||
{
|
||||
for (const HotkeyInfo* hotkey_list : s_hotkey_list)
|
||||
{
|
||||
@@ -712,12 +846,12 @@ void InputManager::AddHotkeyBindings(SettingsInterface& si)
|
||||
if (bindings.empty())
|
||||
continue;
|
||||
|
||||
AddBindings(bindings, InputButtonEventHandler{hotkey->handler});
|
||||
AddBindings(bindings, InputButtonEventHandler{hotkey->handler}, InputBindingInfo::Type::Button, si, "Hotkeys", hotkey->name, is_profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index)
|
||||
void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index, bool is_profile)
|
||||
{
|
||||
const Pad::ControllerType type = EmuConfig.Pad.Ports[pad_index].Type;
|
||||
|
||||
@@ -752,9 +886,10 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index)
|
||||
const float sensitivity = si.GetFloatValue(section.c_str(), fmt::format("{}Scale", bi.name).c_str(), 1.0f);
|
||||
const float deadzone = si.GetFloatValue(section.c_str(), fmt::format("{}Deadzone", bi.name).c_str(), 0.0f);
|
||||
AddBindings(
|
||||
bindings, InputAxisEventHandler{[pad_index, bind_index = bi.bind_index, sensitivity, deadzone](float value) {
|
||||
bindings, InputAxisEventHandler{[pad_index, bind_index = bi.bind_index, sensitivity, deadzone](InputBindingKey key, float value) {
|
||||
Pad::SetControllerState(pad_index, bind_index, ApplySingleBindingScale(sensitivity, deadzone, value));
|
||||
}});
|
||||
}},
|
||||
bi.bind_type, si, section.c_str(), bi.name, is_profile);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -772,10 +907,12 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index)
|
||||
if (!bindings.empty())
|
||||
{
|
||||
const float deadzone = si.GetFloatValue(section.c_str(), fmt::format("Macro{}Deadzone", macro_button_index + 1).c_str(), 0.0f);
|
||||
AddBindings(bindings, InputAxisEventHandler{[pad_index, macro_button_index, deadzone](float value) {
|
||||
const bool state = (value > deadzone);
|
||||
Pad::SetMacroButtonState(pad_index, macro_button_index, state);
|
||||
}});
|
||||
AddBindings(
|
||||
bindings, InputAxisEventHandler{[pad_index, macro_button_index, deadzone](InputBindingKey key, float value) {
|
||||
const bool state = (value > deadzone);
|
||||
Pad::SetMacroButtonState(key, pad_index, macro_button_index, state);
|
||||
}},
|
||||
InputBindingInfo::Type::Macro, si, section.c_str(), fmt::format("Macro{}", macro_button_index + 1).c_str(), is_profile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -812,7 +949,7 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index)
|
||||
}
|
||||
}
|
||||
|
||||
void InputManager::AddUSBBindings(SettingsInterface& si, u32 port)
|
||||
void InputManager::AddUSBBindings(SettingsInterface& si, u32 port, bool is_profile)
|
||||
{
|
||||
const std::string device(USB::GetConfigDevice(si, port));
|
||||
if (device.empty() || device == "None")
|
||||
@@ -836,9 +973,11 @@ void InputManager::AddUSBBindings(SettingsInterface& si, u32 port)
|
||||
{
|
||||
const float sensitivity = si.GetFloatValue(section.c_str(), fmt::format("{}Scale", bi.name).c_str(), 1.0f);
|
||||
const float deadzone = si.GetFloatValue(section.c_str(), fmt::format("{}Deadzone", bi.name).c_str(), 0.0f);
|
||||
AddBindings(bindings, InputAxisEventHandler{[port, bind_index = bi.bind_index, sensitivity, deadzone](float value) {
|
||||
USB::SetDeviceBindValue(port, bind_index, ApplySingleBindingScale(sensitivity, deadzone, value));
|
||||
}});
|
||||
AddBindings(
|
||||
bindings, InputAxisEventHandler{[port, bind_index = bi.bind_index, sensitivity, deadzone](InputBindingKey key, float value) {
|
||||
USB::SetDeviceBindValue(port, bind_index, ApplySingleBindingScale(sensitivity, deadzone, value));
|
||||
}},
|
||||
bi.bind_type, si, section.c_str(), bind_name.c_str(), is_profile);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -977,7 +1116,7 @@ bool InputManager::ProcessEvent(InputBindingKey key, float value, bool skip_butt
|
||||
if (IsAxisHandler(binding->handler))
|
||||
{
|
||||
if (value_to_pass >= 0.0f && (!skip_button_handlers || value_to_pass == 0.0f))
|
||||
std::get<InputAxisEventHandler>(binding->handler)(value_to_pass);
|
||||
std::get<InputAxisEventHandler>(binding->handler)(key, value_to_pass);
|
||||
}
|
||||
else if (binding->num_keys >= min_num_keys)
|
||||
{
|
||||
@@ -1056,7 +1195,7 @@ void InputManager::ClearBindStateFromSource(InputBindingKey key)
|
||||
if (binding->keys[i].MaskDirection() != match_key)
|
||||
continue;
|
||||
|
||||
std::get<InputAxisEventHandler>(binding->handler)(0.0f);
|
||||
std::get<InputAxisEventHandler>(binding->handler)(key, 0.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1392,7 +1531,7 @@ bool InputManager::DoEventHook(InputBindingKey key, float value)
|
||||
// Binding Updater
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
void InputManager::ReloadBindings(SettingsInterface& si, SettingsInterface& binding_si, SettingsInterface& hotkey_binding_si)
|
||||
void InputManager::ReloadBindings(SettingsInterface& si, SettingsInterface& binding_si, SettingsInterface& hotkey_binding_si, bool is_binding_profile, bool is_hotkey_profile)
|
||||
{
|
||||
PauseVibration();
|
||||
|
||||
@@ -1404,28 +1543,28 @@ void InputManager::ReloadBindings(SettingsInterface& si, SettingsInterface& bind
|
||||
s_pointer_move_callbacks.clear();
|
||||
|
||||
// Hotkeys use the base configuration, except if the custom hotkeys option is enabled.
|
||||
AddHotkeyBindings(hotkey_binding_si);
|
||||
AddHotkeyBindings(hotkey_binding_si, is_hotkey_profile);
|
||||
|
||||
// If there's an input profile, we load pad bindings from it alone, rather than
|
||||
// falling back to the base configuration.
|
||||
for (u32 pad = 0; pad < Pad::NUM_CONTROLLER_PORTS; pad++)
|
||||
AddPadBindings(binding_si, pad);
|
||||
AddPadBindings(binding_si, pad, is_binding_profile);
|
||||
|
||||
constexpr float ui_ctrl_range = 100.0f;
|
||||
constexpr float pointer_sensitivity = 0.05f;
|
||||
for (u32 axis = 0; axis <= static_cast<u32>(InputPointerAxis::Y); axis++)
|
||||
{
|
||||
s_pointer_axis_speed[axis] = si.GetFloatValue("Pad", fmt::format("Pointer{}Speed", s_pointer_axis_names[axis]).c_str(), 40.0f) /
|
||||
s_pointer_axis_speed[axis] = si.GetFloatValue("Pad", fmt::format("Pointer{}Speed", s_pointer_axis_setting_names[axis]).c_str(), 40.0f) /
|
||||
ui_ctrl_range * pointer_sensitivity;
|
||||
s_pointer_axis_dead_zone[axis] = std::min(
|
||||
si.GetFloatValue("Pad", fmt::format("Pointer{}DeadZone", s_pointer_axis_names[axis]).c_str(), 20.0f) / ui_ctrl_range, 1.0f);
|
||||
si.GetFloatValue("Pad", fmt::format("Pointer{}DeadZone", s_pointer_axis_setting_names[axis]).c_str(), 20.0f) / ui_ctrl_range, 1.0f);
|
||||
s_pointer_axis_range[axis] = 1.0f - s_pointer_axis_dead_zone[axis];
|
||||
}
|
||||
s_pointer_inertia = si.GetFloatValue("Pad", "PointerInertia", 10.0f) / ui_ctrl_range;
|
||||
s_pointer_pos = {};
|
||||
|
||||
for (u32 port = 0; port < USB::NUM_PORTS; port++)
|
||||
AddUSBBindings(binding_si, port);
|
||||
AddUSBBindings(binding_si, port, is_binding_profile);
|
||||
|
||||
UpdateHostMouseMode();
|
||||
}
|
||||
@@ -1462,7 +1601,7 @@ bool InputManager::ReloadDevices()
|
||||
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
changed |= s_input_sources[i]->ReloadDevices();
|
||||
}
|
||||
|
||||
@@ -1473,11 +1612,11 @@ void InputManager::CloseSources()
|
||||
{
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
{
|
||||
s_input_sources[i]->Shutdown();
|
||||
s_input_sources[i].reset();
|
||||
}
|
||||
s_input_sources[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1485,7 +1624,7 @@ void InputManager::PollSources()
|
||||
{
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
s_input_sources[i]->PollEvents();
|
||||
}
|
||||
|
||||
@@ -1505,7 +1644,7 @@ std::vector<std::pair<std::string, std::string>> InputManager::EnumerateDevices(
|
||||
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
{
|
||||
std::vector<std::pair<std::string, std::string>> devs(s_input_sources[i]->EnumerateDevices());
|
||||
if (ret.empty())
|
||||
@@ -1524,7 +1663,7 @@ std::vector<InputBindingKey> InputManager::EnumerateMotors()
|
||||
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
{
|
||||
std::vector<InputBindingKey> devs(s_input_sources[i]->EnumerateMotors());
|
||||
if (ret.empty())
|
||||
@@ -1584,7 +1723,7 @@ InputManager::GenericInputBindingMapping InputManager::GetGenericBindingMapping(
|
||||
{
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i] && s_input_sources[i]->GetGenericBindingMapping(device, &mapping))
|
||||
if (s_input_sources[i]->IsInitialized() && s_input_sources[i]->GetGenericBindingMapping(device, &mapping))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1600,34 +1739,34 @@ bool InputManager::IsInputSourceEnabled(SettingsInterface& si, InputSourceType t
|
||||
template <typename T>
|
||||
void InputManager::UpdateInputSourceState(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock, InputSourceType type)
|
||||
{
|
||||
if (!s_input_sources[static_cast<u32>(type)])
|
||||
{
|
||||
std::unique_ptr<InputSource> source = std::make_unique<T>();
|
||||
if (!source->Initialize(si, settings_lock))
|
||||
Console.Error("(InputManager) Source '%s' failed to initialize.", InputSourceToString(type));
|
||||
|
||||
s_input_sources[static_cast<u32>(type)] = std::move(source);
|
||||
}
|
||||
|
||||
const bool enabled = IsInputSourceEnabled(si, type);
|
||||
if (enabled)
|
||||
{
|
||||
if (s_input_sources[static_cast<u32>(type)])
|
||||
if (s_input_sources[static_cast<u32>(type)]->IsInitialized())
|
||||
{
|
||||
s_input_sources[static_cast<u32>(type)]->UpdateSettings(si, settings_lock);
|
||||
}
|
||||
else
|
||||
else if (!s_input_sources[static_cast<u32>(type)]->Initialize(si, settings_lock))
|
||||
{
|
||||
std::unique_ptr<InputSource> source = std::make_unique<T>();
|
||||
if (!source->Initialize(si, settings_lock))
|
||||
{
|
||||
Console.Error("(InputManager) Source '%s' failed to initialize.", InputSourceToString(type));
|
||||
return;
|
||||
}
|
||||
|
||||
s_input_sources[static_cast<u32>(type)] = std::move(source);
|
||||
Console.Error("(InputManager) Source '%s' failed to initialize.", InputSourceToString(type));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_input_sources[static_cast<u32>(type)])
|
||||
if (s_input_sources[static_cast<u32>(type)]->IsInitialized())
|
||||
{
|
||||
settings_lock.unlock();
|
||||
s_input_sources[static_cast<u32>(type)]->Shutdown();
|
||||
settings_lock.lock();
|
||||
|
||||
s_input_sources[static_cast<u32>(type)].reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,8 @@ union InputBindingKey
|
||||
InputSubclass source_subtype : 3; ///< if 1, binding is for an axis and not a button (used for controllers)
|
||||
InputModifier modifier : 2;
|
||||
u32 invert : 1; ///< if 1, value is inverted prior to being sent to the sink
|
||||
u32 unused : 14;
|
||||
u32 needs_migration : 1; //< Used for SDL2-3 Migration, binding should be saved to complete migration
|
||||
u32 unused : 13;
|
||||
u32 data;
|
||||
};
|
||||
|
||||
@@ -80,6 +81,7 @@ union InputBindingKey
|
||||
r.bits = bits;
|
||||
r.modifier = InputModifier::None;
|
||||
r.invert = 0;
|
||||
r.needs_migration = false;
|
||||
return r;
|
||||
}
|
||||
};
|
||||
@@ -95,7 +97,7 @@ struct InputBindingKeyHash
|
||||
using InputButtonEventHandler = std::function<void(s32 value)>;
|
||||
|
||||
/// Callback types for a normalized event. Usually used for pads.
|
||||
using InputAxisEventHandler = std::function<void(float value)>;
|
||||
using InputAxisEventHandler = std::function<void(InputBindingKey key, float value)>;
|
||||
|
||||
/// Input monitoring for external access.
|
||||
struct InputInterceptHook
|
||||
@@ -203,13 +205,16 @@ namespace InputManager
|
||||
std::optional<InputBindingKey> ParseInputBindingKey(const std::string_view binding);
|
||||
|
||||
/// Converts a input key to a string.
|
||||
std::string ConvertInputBindingKeyToString(InputBindingInfo::Type binding_type, InputBindingKey key);
|
||||
std::string ConvertInputBindingKeyToString(InputBindingInfo::Type binding_type, InputBindingKey key, bool migration = false);
|
||||
|
||||
/// Converts a chord of binding keys to a string.
|
||||
std::string ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type, const InputBindingKey* keys, size_t num_keys);
|
||||
std::string ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type, const InputBindingKey* keys, size_t num_keys, bool migration = false);
|
||||
|
||||
/// Represents a binding with icon fonts, if available.
|
||||
bool PrettifyInputBinding(SmallStringBase& binding);
|
||||
bool PrettifyInputBinding(SmallStringBase& binding, bool use_icons = true);
|
||||
|
||||
/// Splits a chord into individual bindings.
|
||||
std::vector<std::string_view> SplitChord(const std::string_view binding);
|
||||
|
||||
/// Returns a list of all hotkeys.
|
||||
std::vector<const HotkeyInfo*> GetHotkeyList();
|
||||
@@ -228,7 +233,7 @@ namespace InputManager
|
||||
bool IsInputSourceEnabled(SettingsInterface& si, InputSourceType type);
|
||||
|
||||
/// Re-parses the config and registers all hotkey and pad bindings.
|
||||
void ReloadBindings(SettingsInterface& si, SettingsInterface& binding_si, SettingsInterface& hotkey_binding_si);
|
||||
void ReloadBindings(SettingsInterface& si, SettingsInterface& binding_si, SettingsInterface& hotkey_binding_si, bool is_binding_profile, bool is_hotkey_profile);
|
||||
|
||||
/// Re-parses the sources part of the config and initializes any backends.
|
||||
void ReloadSources(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock);
|
||||
|
||||
@@ -24,11 +24,13 @@ public:
|
||||
virtual void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) = 0;
|
||||
virtual bool ReloadDevices() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual bool IsInitialized() = 0;
|
||||
|
||||
virtual void PollEvents() = 0;
|
||||
|
||||
/// InputBinding functions can be called while uninitialized
|
||||
virtual std::optional<InputBindingKey> ParseKeyString(const std::string_view device, const std::string_view binding) = 0;
|
||||
virtual TinyString ConvertKeyToString(InputBindingKey key) = 0;
|
||||
virtual TinyString ConvertKeyToString(InputBindingKey key, bool display = false, bool migration = false) = 0;
|
||||
virtual TinyString ConvertKeyToIcon(InputBindingKey key) = 0;
|
||||
|
||||
/// Enumerates available devices. Returns a pair of the prefix (e.g. SDL-0) and the device name.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "Input/InputSource.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
||||
bool ReloadDevices() override;
|
||||
void Shutdown() override;
|
||||
bool IsInitialized() override;
|
||||
|
||||
void PollEvents() override;
|
||||
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
||||
@@ -35,7 +36,7 @@ public:
|
||||
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
||||
|
||||
std::optional<InputBindingKey> ParseKeyString(const std::string_view device, const std::string_view binding) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key, bool display = false, bool migration = false) override;
|
||||
TinyString ConvertKeyToIcon(InputBindingKey key) override;
|
||||
|
||||
bool ProcessSDLEvent(const SDL_Event* event);
|
||||
@@ -50,17 +51,17 @@ private:
|
||||
struct ControllerData
|
||||
{
|
||||
SDL_Haptic* haptic;
|
||||
SDL_GameController* game_controller;
|
||||
SDL_Gamepad* gamepad;
|
||||
SDL_Joystick* joystick;
|
||||
u16 rumble_intensity[2];
|
||||
int haptic_left_right_effect;
|
||||
int joystick_id;
|
||||
SDL_JoystickID joystick_id;
|
||||
int player_id;
|
||||
bool use_game_controller_rumble;
|
||||
bool use_gamepad_rumble;
|
||||
|
||||
// Used to disable Joystick controls that are used in GameController inputs so we don't get double events
|
||||
std::vector<bool> joy_button_used_in_gc;
|
||||
std::vector<bool> joy_axis_used_in_gc;
|
||||
// Used to disable Joystick controls that are used in Gamepad inputs so we don't get double events
|
||||
std::vector<bool> joy_button_used_in_pad;
|
||||
std::vector<bool> joy_axis_used_in_pad;
|
||||
|
||||
// Track last hat state so we can send "unpressed" events.
|
||||
std::vector<u8> last_hat_state;
|
||||
@@ -77,10 +78,10 @@ private:
|
||||
ControllerDataVector::iterator GetControllerDataForPlayerId(int id);
|
||||
int GetFreePlayerId() const;
|
||||
|
||||
bool OpenDevice(int index, bool is_gamecontroller);
|
||||
bool OpenDevice(int index, bool is_gamepad);
|
||||
bool CloseDevice(int joystick_index);
|
||||
bool HandleControllerAxisEvent(const SDL_ControllerAxisEvent* ev);
|
||||
bool HandleControllerButtonEvent(const SDL_ControllerButtonEvent* ev);
|
||||
bool HandleGamepadAxisEvent(const SDL_GamepadAxisEvent* ev);
|
||||
bool HandleGamepadButtonEvent(const SDL_GamepadButtonEvent* ev);
|
||||
bool HandleJoystickAxisEvent(const SDL_JoyAxisEvent* ev);
|
||||
bool HandleJoystickButtonEvent(const SDL_JoyButtonEvent* ev);
|
||||
bool HandleJoystickHatEvent(const SDL_JoyHatEvent* ev);
|
||||
@@ -88,13 +89,22 @@ private:
|
||||
|
||||
ControllerDataVector m_controllers;
|
||||
|
||||
// ConvertKeyToString and ConvertKeyToIcon can inspect the
|
||||
// currently connected gamepad to provide matching labels
|
||||
// ParseKeyString can also inspect the gamepad for migrations
|
||||
// Those functions can be called on the main thread, while
|
||||
// gamepad addition/removal is done on the CPU thread
|
||||
std::mutex m_controllers_key_mutex;
|
||||
|
||||
std::vector<u32> m_gamepads_needing_migration;
|
||||
|
||||
std::array<u32, MAX_LED_COLORS> m_led_colors{};
|
||||
std::vector<std::pair<std::string, std::string>> m_sdl_hints;
|
||||
|
||||
bool m_sdl_subsystem_initialized = false;
|
||||
bool m_controller_enhanced_mode = false;
|
||||
bool m_controller_raw_mode = false;
|
||||
bool m_controller_ps5_player_led = false;
|
||||
bool m_enable_enhanced_reports = false;
|
||||
bool m_use_raw_input = false;
|
||||
bool m_enable_ps5_player_leds = false;
|
||||
|
||||
#ifdef __APPLE__
|
||||
bool m_enable_iokit_driver = false;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
static const char* s_axis_names[XInputSource::NUM_AXES] = {
|
||||
static const char* s_axis_setting_names[XInputSource::NUM_AXES] = {
|
||||
"LeftX", // AXIS_LEFTX
|
||||
"LeftY", // AXIS_LEFTY
|
||||
"RightX", // AXIS_RIGHTX
|
||||
@@ -22,6 +22,14 @@ static const char* s_axis_names[XInputSource::NUM_AXES] = {
|
||||
"LeftTrigger", // AXIS_TRIGGERLEFT
|
||||
"RightTrigger", // AXIS_TRIGGERRIGHT
|
||||
};
|
||||
static const char* s_axis_names[XInputSource::NUM_AXES] = {
|
||||
"Left X", // AXIS_LEFTX
|
||||
"Left Y", // AXIS_LEFTY
|
||||
"Right X", // AXIS_RIGHTX
|
||||
"Right Y", // AXIS_RIGHTY
|
||||
"Left Trigger", // AXIS_TRIGGERLEFT
|
||||
"Right Trigger", // AXIS_TRIGGERRIGHT
|
||||
};
|
||||
static constexpr const char* s_axis_icons[][2] = {
|
||||
{ICON_PF_LEFT_ANALOG_LEFT, ICON_PF_LEFT_ANALOG_RIGHT}, // AXIS_LEFTX
|
||||
{ICON_PF_LEFT_ANALOG_UP, ICON_PF_LEFT_ANALOG_DOWN}, // AXIS_LEFTY
|
||||
@@ -39,7 +47,7 @@ static const GenericInputBinding s_xinput_generic_binding_axis_mapping[][2] = {
|
||||
{GenericInputBinding::Unknown, GenericInputBinding::R2}, // AXIS_TRIGGERRIGHT
|
||||
};
|
||||
|
||||
static const char* s_button_names[XInputSource::NUM_BUTTONS] = {
|
||||
static const char* s_button_setting_names[XInputSource::NUM_BUTTONS] = {
|
||||
"DPadUp", // XINPUT_GAMEPAD_DPAD_UP
|
||||
"DPadDown", // XINPUT_GAMEPAD_DPAD_DOWN
|
||||
"DPadLeft", // XINPUT_GAMEPAD_DPAD_LEFT
|
||||
@@ -56,6 +64,24 @@ static const char* s_button_names[XInputSource::NUM_BUTTONS] = {
|
||||
"Y", // XINPUT_GAMEPAD_Y
|
||||
"Guide", // XINPUT_GAMEPAD_GUIDE
|
||||
};
|
||||
static const char* s_button_names[XInputSource::NUM_BUTTONS] = {
|
||||
"D-Pad Up", // XINPUT_GAMEPAD_DPAD_UP
|
||||
"D-Pad Down", // XINPUT_GAMEPAD_DPAD_DOWN
|
||||
"D-Pad Left", // XINPUT_GAMEPAD_DPAD_LEFT
|
||||
"D-Pad Right", // XINPUT_GAMEPAD_DPAD_RIGHT
|
||||
"Start", // XINPUT_GAMEPAD_START
|
||||
"Back", // XINPUT_GAMEPAD_BACK
|
||||
"Left Stick", // XINPUT_GAMEPAD_LEFT_THUMB
|
||||
"Right Stick", // XINPUT_GAMEPAD_RIGHT_THUMB
|
||||
"Left Shoulder", // XINPUT_GAMEPAD_LEFT_SHOULDER
|
||||
"Right Shoulder", // XINPUT_GAMEPAD_RIGHT_SHOULDER
|
||||
"A", // XINPUT_GAMEPAD_A
|
||||
"B", // XINPUT_GAMEPAD_B
|
||||
"X", // XINPUT_GAMEPAD_X
|
||||
"Y", // XINPUT_GAMEPAD_Y
|
||||
"Guide", // XINPUT_GAMEPAD_GUIDE
|
||||
};
|
||||
|
||||
static const u16 s_button_masks[XInputSource::NUM_BUTTONS] = {
|
||||
XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT, XINPUT_GAMEPAD_START,
|
||||
XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB, XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER,
|
||||
@@ -133,6 +159,8 @@ bool XInputSource::Initialize(SettingsInterface& si, std::unique_lock<std::mutex
|
||||
if (!m_xinput_get_state || !m_xinput_set_state || !m_xinput_get_capabilities)
|
||||
{
|
||||
Console.Error("Failed to get XInput function pointers.");
|
||||
FreeLibrary(m_xinput_module);
|
||||
m_xinput_module = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -196,6 +224,11 @@ void XInputSource::Shutdown()
|
||||
m_xinput_get_extended = nullptr;
|
||||
}
|
||||
|
||||
bool XInputSource::IsInitialized()
|
||||
{
|
||||
return m_xinput_module;
|
||||
}
|
||||
|
||||
void XInputSource::PollEvents()
|
||||
{
|
||||
for (u32 i = 0; i < NUM_CONTROLLERS; i++)
|
||||
@@ -287,9 +320,9 @@ std::optional<InputBindingKey> XInputSource::ParseKeyString(const std::string_vi
|
||||
{
|
||||
// likely an axis
|
||||
const std::string_view axis_name(binding.substr(1));
|
||||
for (u32 i = 0; i < std::size(s_axis_names); i++)
|
||||
for (u32 i = 0; i < std::size(s_axis_setting_names); i++)
|
||||
{
|
||||
if (axis_name == s_axis_names[i])
|
||||
if (axis_name == s_axis_setting_names[i])
|
||||
{
|
||||
// found an axis!
|
||||
key.source_subtype = InputSubclass::ControllerAxis;
|
||||
@@ -302,9 +335,9 @@ std::optional<InputBindingKey> XInputSource::ParseKeyString(const std::string_vi
|
||||
else
|
||||
{
|
||||
// must be a button
|
||||
for (u32 i = 0; i < std::size(s_button_names); i++)
|
||||
for (u32 i = 0; i < std::size(s_button_setting_names); i++)
|
||||
{
|
||||
if (binding == s_button_names[i])
|
||||
if (binding == s_button_setting_names[i])
|
||||
{
|
||||
key.source_subtype = InputSubclass::ControllerButton;
|
||||
key.data = i;
|
||||
@@ -317,24 +350,33 @@ std::optional<InputBindingKey> XInputSource::ParseKeyString(const std::string_vi
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
TinyString XInputSource::ConvertKeyToString(InputBindingKey key)
|
||||
TinyString XInputSource::ConvertKeyToString(InputBindingKey key, bool display, bool migration)
|
||||
{
|
||||
TinyString ret;
|
||||
|
||||
if (key.source_type == InputSourceType::XInput)
|
||||
{
|
||||
if (key.source_subtype == InputSubclass::ControllerAxis && key.data < std::size(s_axis_names))
|
||||
if (key.source_subtype == InputSubclass::ControllerAxis && key.data < std::size(s_axis_setting_names))
|
||||
{
|
||||
const char modifier = key.modifier == InputModifier::Negate ? '-' : '+';
|
||||
ret.format("XInput-{}/{}{}", static_cast<u32>(key.source_index), modifier, s_axis_names[key.data]);
|
||||
if (display)
|
||||
ret.format("XInput-{} {}{}", static_cast<u32>(key.source_index), modifier, s_axis_names[key.data]);
|
||||
else
|
||||
ret.format("XInput-{}/{}{}", static_cast<u32>(key.source_index), modifier, s_axis_setting_names[key.data]);
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::ControllerButton && key.data < std::size(s_button_names))
|
||||
else if (key.source_subtype == InputSubclass::ControllerButton && key.data < std::size(s_button_setting_names))
|
||||
{
|
||||
ret.format("XInput-{}/{}", static_cast<u32>(key.source_index), s_button_names[key.data]);
|
||||
if (display)
|
||||
ret.format("XInput-{} {}", static_cast<u32>(key.source_index), s_button_names[key.data]);
|
||||
else
|
||||
ret.format("XInput-{}/{}", static_cast<u32>(key.source_index), s_button_setting_names[key.data]);
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::ControllerMotor)
|
||||
{
|
||||
ret.format("XInput-{}/{}Motor", static_cast<u32>(key.source_index), key.data ? "Large" : "Small");
|
||||
if (display)
|
||||
ret.format("XInput-{} {} Motor", static_cast<u32>(key.source_index), key.data ? "Large" : "Small");
|
||||
else
|
||||
ret.format("XInput-{}/{}Motor", static_cast<u32>(key.source_index), key.data ? "Large" : "Small");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,16 +446,16 @@ bool XInputSource::GetGenericBindingMapping(const std::string_view device, Input
|
||||
const GenericInputBinding negative = s_xinput_generic_binding_axis_mapping[i][0];
|
||||
const GenericInputBinding positive = s_xinput_generic_binding_axis_mapping[i][1];
|
||||
if (negative != GenericInputBinding::Unknown)
|
||||
mapping->emplace_back(negative, fmt::format("XInput-{}/-{}", pid, s_axis_names[i]));
|
||||
mapping->emplace_back(negative, fmt::format("XInput-{}/-{}", pid, s_axis_setting_names[i]));
|
||||
|
||||
if (positive != GenericInputBinding::Unknown)
|
||||
mapping->emplace_back(positive, fmt::format("XInput-{}/+{}", pid, s_axis_names[i]));
|
||||
mapping->emplace_back(positive, fmt::format("XInput-{}/+{}", pid, s_axis_setting_names[i]));
|
||||
}
|
||||
for (u32 i = 0; i < std::size(s_xinput_generic_binding_button_mapping); i++)
|
||||
{
|
||||
const GenericInputBinding binding = s_xinput_generic_binding_button_mapping[i];
|
||||
if (binding != GenericInputBinding::Unknown)
|
||||
mapping->emplace_back(binding, fmt::format("XInput-{}/{}", pid, s_button_names[i]));
|
||||
mapping->emplace_back(binding, fmt::format("XInput-{}/{}", pid, s_button_setting_names[i]));
|
||||
}
|
||||
|
||||
if (m_controllers[pid].has_small_motor)
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
||||
bool ReloadDevices() override;
|
||||
void Shutdown() override;
|
||||
bool IsInitialized() override;
|
||||
|
||||
void PollEvents() override;
|
||||
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
||||
@@ -84,7 +85,7 @@ public:
|
||||
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
||||
|
||||
std::optional<InputBindingKey> ParseKeyString(const std::string_view device, const std::string_view binding) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key, bool display = false, bool migration = false) override;
|
||||
TinyString ConvertKeyToIcon(InputBindingKey key) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -838,8 +838,12 @@ bool Pcsx2Config::GSOptions::OptionsAreEqual(const GSOptions& right) const
|
||||
OpEqu(ShadeBoost_Contrast) &&
|
||||
OpEqu(ShadeBoost_Saturation) &&
|
||||
OpEqu(PNGCompressionLevel) &&
|
||||
OpEqu(SaveN) &&
|
||||
OpEqu(SaveL) &&
|
||||
OpEqu(SaveDrawStart) &&
|
||||
OpEqu(SaveDrawCount) &&
|
||||
OpEqu(SaveDrawBy) &&
|
||||
OpEqu(SaveFrameStart) &&
|
||||
OpEqu(SaveFrameCount) &&
|
||||
OpEqu(SaveFrameBy) &&
|
||||
|
||||
OpEqu(ExclusiveFullscreenControl) &&
|
||||
OpEqu(ScreenshotSize) &&
|
||||
@@ -961,11 +965,13 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
|
||||
SettingsWrapBitBoolEx(UserHacks_EstimateTextureRegion, "UserHacks_EstimateTextureRegion");
|
||||
SettingsWrapBitBoolEx(FXAA, "fxaa");
|
||||
SettingsWrapBitBool(ShadeBoost);
|
||||
SettingsWrapBitBoolEx(DumpGSData, "dump");
|
||||
SettingsWrapBitBoolEx(SaveRT, "save");
|
||||
SettingsWrapBitBoolEx(SaveFrame, "savef");
|
||||
SettingsWrapBitBoolEx(SaveTexture, "savet");
|
||||
SettingsWrapBitBoolEx(SaveDepth, "savez");
|
||||
SettingsWrapBitBoolEx(DumpGSData, "DumpGSData");
|
||||
SettingsWrapBitBoolEx(SaveRT, "SaveRT");
|
||||
SettingsWrapBitBoolEx(SaveFrame, "SaveFrame");
|
||||
SettingsWrapBitBoolEx(SaveTexture, "SaveTexture");
|
||||
SettingsWrapBitBoolEx(SaveDepth, "SaveDepth");
|
||||
SettingsWrapBitBoolEx(SaveAlpha, "SaveAlpha");
|
||||
SettingsWrapBitBoolEx(SaveInfo, "SaveInfo");
|
||||
SettingsWrapBitBool(DumpReplaceableTextures);
|
||||
SettingsWrapBitBool(DumpReplaceableMipmaps);
|
||||
SettingsWrapBitBool(DumpTexturesWithFMVActive);
|
||||
@@ -1024,8 +1030,12 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
|
||||
SettingsWrapBitfield(ShadeBoost_Saturation);
|
||||
SettingsWrapBitfield(ExclusiveFullscreenControl);
|
||||
SettingsWrapBitfieldEx(PNGCompressionLevel, "png_compression_level");
|
||||
SettingsWrapBitfieldEx(SaveN, "saven");
|
||||
SettingsWrapBitfieldEx(SaveL, "savel");
|
||||
SettingsWrapBitfieldEx(SaveDrawStart, "SaveDrawStart");
|
||||
SettingsWrapBitfieldEx(SaveDrawCount, "SaveDrawCount");
|
||||
SettingsWrapBitfieldEx(SaveDrawBy, "SaveDrawBy");
|
||||
SettingsWrapBitfieldEx(SaveFrameStart, "SaveFrameStart");
|
||||
SettingsWrapBitfieldEx(SaveFrameCount, "SaveFrameCount");
|
||||
SettingsWrapBitfieldEx(SaveFrameBy, "SaveFrameBy");
|
||||
|
||||
SettingsWrapEntryEx(CaptureContainer, "CaptureContainer");
|
||||
SettingsWrapEntryEx(VideoCaptureCodec, "VideoCaptureCodec");
|
||||
@@ -1110,6 +1120,15 @@ bool Pcsx2Config::GSOptions::UseHardwareRenderer() const
|
||||
return (Renderer != GSRendererType::Null && Renderer != GSRendererType::SW);
|
||||
}
|
||||
|
||||
bool Pcsx2Config::GSOptions::ShouldDump(int draw, int frame) const
|
||||
{
|
||||
int drawOffset = draw - SaveDrawStart;
|
||||
int frameOffset = frame - SaveFrameStart;
|
||||
return DumpGSData &&
|
||||
(drawOffset >= 0) && ((SaveDrawCount < 0) || (drawOffset < SaveDrawCount)) && (drawOffset % SaveDrawBy == 0) &&
|
||||
(frameOffset >= 0) && ((SaveFrameCount < 0) || (frameOffset < SaveFrameCount)) && (frameOffset % SaveFrameBy == 0);
|
||||
}
|
||||
|
||||
static constexpr const std::array s_spu2_sync_mode_names = {
|
||||
"Disabled",
|
||||
"TimeStretch",
|
||||
|
||||