Compare commits

...

117 Commits

Author SHA1 Message Date
Ty
1fd22dcc1c Windows: Make PCSX2 long path aware 2025-03-04 09:14:25 -05:00
refractionpcsx2
e3afdde981 GSDumpRunner: Fix compilation 2025-03-04 13:28:42 +00:00
lightningterror
698df49e5e Qt: Fix -Wsign-compare warnings. 2025-03-04 13:29:13 +01:00
TheLastRar
ff5c90ec5e SDLInputSource: Correct joystick types 2025-03-04 05:07:56 +01:00
TheLastRar
1e075d23b2 Input: Fix warnings 2025-03-04 05:07:56 +01:00
PCSX2 Bot
2b172903b9 [ci skip] Qt: Update Base Translation. 2025-03-04 01:04:44 +01:00
TheLastRar
4654a3ef6c FSUI: Formatting 2025-03-04 00:34:14 +01:00
Ty
9996061f74 SIO: Bump savestate warning from 1 hour to 2 hours 2025-03-03 12:19:09 -05:00
Ty
247a4c40d1 SIO: Remove a debugging include I somehow missed 2025-03-03 12:19:09 -05:00
PCSX2 Bot
1ffbdd9c08 [ci skip] PAD: Update to latest controller database. 2025-03-03 17:30:19 +01:00
TheLastRar
f67c0cbd2e Input: Fix migration of input profiles 2025-03-03 13:38:55 +01:00
PCSX2 Bot
ff7cc0867b [ci skip] Qt: Update Base Translation. 2025-03-03 01:36:07 +01:00
TheLastRar
ac1a6d3348 Deps: Update to SDL3 (#12311)
Co-authored-by: TheTechnician27 <TheTechnician27@users.noreply.github.com>
2025-03-02 18:04:19 -05:00
TellowKrinkle
582bba6c91 microVU: Accurate CLIP 2025-03-02 18:19:52 +00:00
TellowKrinkle
aaf156478e Interpreter: Accurate CLIP 2025-03-02 18:19:52 +00:00
TellowKrinkle
0539c177ab x86emitter: Add pblend 2025-03-02 18:19:52 +00:00
TellowKrinkle
fb1323b72f MicroVU: Declare constants inline 2025-03-02 18:19:52 +00:00
TellowKrinkle
dc557dd0e5 Interpreter: Merge broadcast min/max into one implementation 2025-03-02 18:19:08 +00:00
TellowKrinkle
2d0cfc9c2c Interpreter: Merge MAC ops into a few template functions 2025-03-02 18:19:08 +00:00
TellowKrinkle
625a25cd50 Interpreter: Merge broadcast ops into one implementation each 2025-03-02 18:19:08 +00:00
TellowKrinkle
b8a29d1cd8 Interpreter: Accurate FTOI
Plus some ITOF cleanup
2025-03-02 18:17:36 +00:00
TellowKrinkle
0fabdf9a01 Interpreter: Accurate ABS 2025-03-02 18:17:36 +00:00
refractionpcsx2
9c3ae795c8 COP2/Int: Propagate CLIP_FLAG writes to the VU0.clipflag variable for use in COP2
This value was being updated then COP2 running VCLIP would have the wrong original clip flag value to work from.
2025-03-02 18:17:05 +00:00
refractionpcsx2
de26226fa1 Core: Delete constant regs when flushing to interpreter 2025-03-02 18:17:05 +00:00
KamFretoZ
121920c074 FSUI: Add Themes 2025-03-02 11:48:29 -05:00
TellowKrinkle
05e19470b2 FileSystem: Don't leak on directory scan cancel
Fixes: 7587581d1f
2025-03-02 09:41:51 -05:00
TheLastRar
b6680e4aca FSUI: Formatting 2025-03-02 09:36:07 -05:00
TheLastRar
f9d70af841 FSUI: Auto detect when to use circle as confirm 2025-03-02 09:36:07 -05:00
TellowKrinkle
7587581d1f GameList: Allow recursive scans to be cancelled 2025-03-02 04:20:01 +01:00
PCSX2 Bot
8f19976c10 [ci skip] Qt: Update Base Translation. 2025-03-02 01:43:09 +01:00
GovanifY
8567d68433 VMManager: initialize PINE with config-provided slot
Sten broke it during the port to Qt...
2025-03-02 00:01:18 +01:00
Glebux
6542301566 Input/PAD: Make macro chords work 2025-03-01 14:38:00 -05:00
refractionpcsx2
a359f77cf6 GameDB/Link: Fix validation limit for Half Pixel Offset to allow new option 2025-03-01 02:01:46 +00:00
PCSX2 Bot
4c9a81f3d8 [ci skip] Qt: Update Base Translation. 2025-02-28 19:54:36 -05:00
refractionpcsx2
9234b493a3 Testing further tweaks to bring it closer to SW 2025-02-28 21:59:19 +00:00
refractionpcsx2
f84425b67c GS/HW: Add new HPO - Align to Native With Texture Offset 2025-02-28 21:59:19 +00:00
PCSX2 Bot
8a0c1874dd [ci skip] Qt: Update Base Translation. 2025-02-27 01:05:14 +01:00
Light
fa23628ae2 Qt: Allow recording on game boot 2025-02-26 17:17:39 -05:00
Loy2up
8a594e673d Debugger: Fix 8 byte searches (#12362) 2025-02-26 14:41:49 -05:00
Loy2up
92b9390c51 Debugger: Set default breakpoint size to 4 2025-02-25 19:07:19 -05:00
PCSX2 Bot
c5c5b2a7b9 [ci skip] Qt: Update Base Translation. 2025-02-26 01:06:43 +01:00
refractionpcsx2
32a9d0e48b GameDB: Also add Tekken 5 CRC to Taiko No Tatsujin 9 2025-02-25 18:22:38 +01:00
refractionpcsx2
80a961bb25 GameDB: Add Tekken 5 CRC (Yes really) To Tales of the Abyss 2025-02-25 18:22:38 +01:00
TheLastRar
d4e227286e FSUI: Correct description of the "Swap OK/Cancel" option 2025-02-25 10:00:18 -05:00
github-actions[bot]
ba705c8c24 Qt: Update Base Translation (#12354)
Co-authored-by: PCSX2 Bot <PCSX2Bot@users.noreply.github.com>
2025-02-24 19:11:57 -05:00
dependabot[bot]
b6ae4b173e CI: Update dependencies in /.github/workflows/scripts/releases/generate-release-notes (#12315)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-24 17:54:41 -05:00
TJnotJT
23a28be346 GS/UI: Rename dumping variables and UI labels to be more consistent/clear. 2025-02-24 17:53:01 -05:00
TJnotJT
a0e24dd36f UI: Add debug UI options for new dumping options. 2025-02-24 17:53:01 -05:00
TheLastRar
a2cde5e17b FSUI: Add a config option to swap OK/Cancel within BPM 2025-02-24 17:45:46 -05:00
JordanTheToaster
ecc46e9294 Deps: Update ZSTD to 1.5.7 2025-02-24 17:44:22 -05:00
dreamsyntax
20b1190d47 Achievements: Fix leaderboard timers persisting
Removes setting the leaderboard timer to active on receiving an update
event. This fixes having multiple timers stuck on the screen.
2025-02-24 14:05:03 -05:00
Silent
29b736bcf7 GameDB: Add TOCA Race Driver 3 memcard filters 2025-02-24 12:04:05 -05:00
Silent
a48bc76ca6 GameDB: Add NFS Undercover memcard filters
Checks from NFS Carbon (incl. a bugged check for MW BE)
are in the code, but unused.
2025-02-24 12:04:05 -05:00
Silent
305c01cdfa GameDB: Add NFS ProStreet memcard filters 2025-02-24 12:04:05 -05:00
Silent
88bbdf4696 GameDB: Add NFS Carbon memcard filters 2025-02-24 12:04:05 -05:00
Silent
afc11279a9 GameDB: Improve NFS Most Wanted memcard filters 2025-02-24 12:04:05 -05:00
Silent
a3fb2a84d5 GameDB: SCUS-21494 doesn't exist 2025-02-24 12:04:05 -05:00
Ty
4db23e6677 Debugger Assembler: BC1(t|f) 24 bit immediates to 16 bit immediates 2025-02-24 11:39:30 -05:00
PCSX2 Bot
5dd36a7969 [ci skip] PAD: Update to latest controller database. 2025-02-24 17:02:04 +01:00
RedPanda4552
35a3d0027e Memcard: Apply filtering when checking all possible memcard options
Prevents log being flooded with warnings when large folder memcards exceed 8 MB size
2025-02-24 16:08:00 +01:00
refractionpcsx2
02789ebd86 GS/HW: Increase Merge Sprite paving sensitivity to avoid mismerges 2025-02-23 03:33:39 +00:00
JordanTheToaster
dfd1846b93 GameDB: Various fixes 2025-02-23 01:12:43 +00:00
refractionpcsx2
872205abc6 GS/HW: Maintain scale on subsequent downscale draws 2025-02-23 01:12:07 +00:00
PCSX2 Bot
c52cebd20a [ci skip] Qt: Update Base Translation. 2025-02-22 01:04:56 +01:00
GovanifY
f449b54f87 CI: enable wayland by default 2025-02-21 12:28:28 +01:00
GovanifY
ffcb6e2f6f QT/MainWindow: disable native window rendering in wayland
This is a workaround for QTBUG-133919
2025-02-21 12:28:28 +01:00
PCSX2 Bot
5daa1aa115 [ci skip] Qt: Update Base Translation. 2025-02-21 01:09:05 +01:00
GovanifY
1dc009f752 pcsx2/SIO: correctly detect whether format status of folder mcd 2025-02-20 16:00:40 +01:00
GovanifY
009b4ff5e7 QT/Settings: ensure that a memory card is formatted before conversion 2025-02-20 16:00:40 +01:00
PCSX2 Bot
f1a947af92 [ci skip] Qt: Update Base Translation. 2025-02-19 21:00:23 -05:00
Ty Lamontagne
97c098b1ff QT: Adjust mouse grab help text 2025-02-19 11:18:17 -05:00
Ty
e252cb6643 HostSys: Implement platform Specific mouse lock osx/windows/x11 2025-02-19 11:18:17 -05:00
Gonzalosilvalde
75c0236e1e Qt: Add mouse grab/lock feature when PCSX2 is in focus 2025-02-19 11:18:17 -05:00
KamFretoZ
9c4a98bc25 Qt: Add AMOLED Theme 2025-02-19 10:34:44 -05:00
GovanifY
9cba11cde5 appimage: revert #11667 , switch back to upstream appimagetool 2025-02-19 01:44:18 +01:00
GovanifY
fac5512b04 flatpak: misc additions to the metainfo 2025-02-19 01:44:18 +01:00
GovanifY
ed9bf05971 bin: update icons to be centered 2025-02-18 20:44:43 +01:00
GovanifY
19d0f3bdc5 flatpak: add branding colors 2025-02-18 20:44:43 +01:00
GovanifY
2abe53de43 flatpak: remove wild caps in summary 2025-02-18 20:44:43 +01:00
GovanifY
37a25750d7 flatpak: update default screenshots
This fixes a few issues in our flathub review report
2025-02-18 20:44:43 +01:00
lightningterror
d3e288447f GS/HW: Cleanup gl and vk shaders.
gl: Rename fetch_rt to sample_from_rt to match vk shaders, remove old atst call.

vk: Make sure shuffle values have correct unsigned type.
2025-02-17 21:27:34 +01:00
Ziemas
4a44d2668c SDL Audio: Set app name hint 2025-02-16 16:41:51 -05:00
Ty
752b1420a3 CI: Increase flatpak cron job timeout to 3 hours instead of 1
[ci skip]
2025-02-16 16:17:11 -05:00
PCSX2 Bot
71705fc91f [ci skip] Qt: Update Base Translation. 2025-02-16 22:12:45 +01:00
Ty
645efc7520 CI: Skip macos signing on forks 2025-02-16 12:03:14 -05:00
Ty
b6ee0e5219 CI: Bump our ccache size from 100M to 500M 2025-02-16 12:03:14 -05:00
Ty
7acf32debc CI: Sign and notarize our macos binaries 2025-02-16 12:03:14 -05:00
Ty
13397f68a3 CI: Update the node version for announce-release try #2 2025-02-16 11:39:54 -05:00
Ty
79250722d6 CI: Update the node version for announce-release 2025-02-16 11:30:47 -05:00
Ty
04b8748a8f CI: Update the announce-release script to use node-fetch (#12310) 2025-02-15 15:14:28 -05:00
dependabot[bot]
2dab8053ea CI: Bump deps in announce-release (#12308)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-15 11:03:07 -05:00
refractionpcsx2
f8bab2e465 Build/VS: Fix change in latest VS 2022 update with std::chrono
For more information see: https://learn.microsoft.com/en-us/cpp/overview/what-s-new-for-visual-cpp-in-visual-studio?view=msvc-170#:~:text=Moved%20system_clock%2C%20high_resolution_clock%2C%20and%20chrono_literals%20from%20a%20commonly%20included%20internal%20header%20to%20%3Cchrono%3E.%20If%20you%20see%20compiler%20errors%20that%20types%20like%20system_clock%20or%20user%2Ddefined%20literals%20like%201729ms%20aren%27t%20recognized%2C%20include%20%3Cchrono%3E.
2025-02-14 02:40:24 +00:00
TJnotJT
46221a8500 Tools: Fix typos in GS dump runner help. 2025-02-12 17:40:49 -05:00
TJnotJT
8b0e61af8c Tools: Remove debug preprocessor check around dumping of HW renderer frames. 2025-02-12 17:40:49 -05:00
TJnotJT
2b0a78811a Tools: Add additional options for dumping in GS runner. Other formatting fixes. 2025-02-12 17:40:49 -05:00
TheTechnician27
5798cd7176 Qt: End memcard conversion progress at 100% instead of 99% 2025-02-12 17:40:17 -05:00
JordanTheToaster
5c25637381 GameDB: Knights of the Temple 2 fixes 2025-02-12 17:39:56 -05:00
TheLastRar
8316228771 iR5900: Reset manual protection counters 2025-02-12 12:12:05 -05:00
JordanTheToaster
695250155e GameDB: Even more fixes 2025-02-12 12:09:05 -05:00
PCSX2 Bot
545e606c11 [ci skip] PAD: Update to latest controller database. 2025-02-10 17:26:03 +01:00
refractionpcsx2
52771fdb17 GS/HW: Add CRC fixes for DT Carnage/Racer/Axel Impact 2025-02-10 15:06:29 +00:00
JordanTheToaster
de631a1052 PerformanceMetrics: Increase update rate
Increases update rate of OSD stats from 0.5 per poll to 0.25 seconds per poll.
2025-02-09 12:29:54 -05:00
JordanTheToaster
605398db67 GameDB: Various fixes 2025-02-09 12:29:54 -05:00
TheLastRar
407c989860 Vif: Fixes to non-volatile SSE backup and restore logic 2025-02-09 12:28:04 -05:00
lightningterror
9b4b112a97 GS/HW: Adjust max valid tex size.
Account for index 0.
2025-02-08 23:56:42 +01:00
PCSX2 Bot
865b75bcbb [ci skip] Qt: Update Base Translation. 2025-02-07 19:04:10 -05:00
Ty
795b0813cc Debugger: Only validate memory search value when needed 2025-02-07 13:40:13 -05:00
Ty
3e1f2b8b9d Debugger: Support 'unknown initial value' search types 2025-02-07 13:40:13 -05:00
Ty
1f0d6f0ac7 VMManager: Avoid use-after-move conditions 2025-02-05 10:25:24 -05:00
JordanTheToaster
4ab4f4a67c GameDB: Various fixes 2025-02-04 14:58:40 -05:00
Mrlinkwii
5dbdd5e5e4 CI : fix artifact name on linux builds 2025-02-04 14:49:36 -05:00
JordanTheToaster
f03cddf674 Deps: Update to Qt 6.8.2 on Windows and Linux 2025-02-04 12:22:17 +01:00
PCSX2 Bot
726e908a49 [ci skip] Qt: Update Base Translation. 2025-02-03 19:08:22 -05:00
Jordan
043cd673b8 3rdparty: Update ImGui to v1.91.8 (#12258) 2025-02-03 17:22:32 -05:00
KamFretoZ
f84173e5cc Qt: Add Portable Mode launch argument (#12230) 2025-02-03 17:20:32 -05:00
Jordan
bef7ae7f6c Deps: Update SDL to 2.30.12 (#12263) 2025-02-03 16:54:24 -05:00
TheTechnician27
33aed95a6c Controllers: Make restore defaults restore controller LED (#12264) 2025-02-03 16:53:55 -05:00
139 changed files with 9322 additions and 6397 deletions

View File

@@ -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 }}

View File

@@ -15,7 +15,7 @@ jobs:
uses: ./.github/workflows/linux_build_qt.yml
with:
jobName: "AppImage Build"
artifactPrefixName: "PCSX2-linux-Qt-x64-appimage-sse4"
artifactPrefixName: "PCSX2-linux-Qt-x64-appimage"
compiler: clang
cmakeflags: ""
buildAppImage: true
@@ -26,7 +26,7 @@ jobs:
uses: ./.github/workflows/linux_build_flatpak.yml
with:
jobName: "Flatpak Build"
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak-sse4"
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak"
compiler: clang
cmakeflags: ""
publish: false

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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"

View File

@@ -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

View File

@@ -19,9 +19,9 @@ LIBJPEG=9f
LIBPNG=1.6.45
LIBWEBP=1.5.0
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
SDL=SDL2-2.30.11
QT=6.8.1
ZSTD=1.5.6
SDL=SDL3-3.2.6
QT=6.8.2
ZSTD=1.5.7
SHADERC=2024.1
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
@@ -37,14 +37,14 @@ fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f $SDL.tar.gz
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
40b14562ef3bd779bc0e0418ea2ae08fa28235f8ea6e8c0cb3bce1d6ad58dcaf qtbase-everywhere-src-$QT.tar.xz
138cc2909aa98f5ff7283e36eb3936eb5e625d3ca3b4febae2ca21d8903dd237 qtimageformats-everywhere-src-$QT.tar.xz
3d0de73596e36b2daa7c48d77c4426bb091752856912fba720215f756c560dd0 qtsvg-everywhere-src-$QT.tar.xz
9d43d409be08b8681a0155a9c65114b69c9a3fc11aef6487bb7fdc5b283c432d qttools-everywhere-src-$QT.tar.xz
635a6093e99152243b807de51077485ceadd4786d4acb135b9340b2303035a4a qttranslations-everywhere-src-$QT.tar.xz
2226fbde4e2ddd12f8bf4b239c8f38fd706a54e789e63467dfddc77129eca203 qtwayland-everywhere-src-$QT.tar.xz
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
326381b7d43f07913612f291abc298ae79bd95382e2233abce982cff2b53d2c0 qttools-everywhere-src-$QT.tar.xz
d2106e8a580bfd77702c4c1840299288d344902b0e2c758ca813ea04c6d6a3d1 qttranslations-everywhere-src-$QT.tar.xz
5e46157908295f2bf924462d8c0855b0508ba338ced9e810891fefa295dc9647 qtwayland-everywhere-src-$QT.tar.xz
eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADERC.tar.gz
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz

View File

@@ -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.11.tar.gz",
"sha256": "8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f"
"url": "https://libsdl.org/release/SDL3-3.2.6.tar.gz",
"sha256": "096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a"
}
],
"cleanup": [

View File

@@ -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",
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@@ -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>

View File

@@ -40,8 +40,8 @@ fi
FREETYPE=2.13.3
HARFBUZZ=10.0.1
SDL=SDL2-2.30.11
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
8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f $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

View File

@@ -22,8 +22,8 @@ fi
FREETYPE=2.13.3
HARFBUZZ=10.0.1
SDL=SDL2-2.30.11
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
8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f $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

View File

@@ -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",

View File

@@ -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"
}
}

View File

@@ -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
}
}
}

View File

@@ -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"
}
}

View File

@@ -47,13 +47,13 @@ set HARFBUZZ=10.0.1
set LIBJPEG=9f
set LIBPNG=1645
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
set QT=6.8.1
set QT=6.8.2
set QTMINOR=6.8
set SDL=SDL2-2.30.11
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" a0b3e7ac5f708042683ff0f22e069bdf75563540c615f9854ecc9bc8913e2488 || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" e22d997bd15b795a176c8da62c8c1da0a674eb534e02f7c01ca507bf11bce0c3 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 247a0a58039275a5a4fb499a600a90f66dc6e00321bb6f86a9b8d8020344d853 || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 57bd332e5550ff70a852560c591b786b6ba587c5e41cb5ef91038d82db137ab9 || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" c65a89140f5d68137ffec67d631ec97002fb37077d9b4eb4ee45cbec39b1c38a || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 30a8e7773e1f274557e049a97f158b808f344247da03ae5240e4956c81d51cd5 || 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 (

View File

@@ -45,13 +45,13 @@ set HARFBUZZ=10.0.1
set LIBJPEG=9f
set LIBPNG=1645
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
set QT=6.8.1
set QT=6.8.2
set QTMINOR=6.8
set SDL=SDL2-2.30.11
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" a0b3e7ac5f708042683ff0f22e069bdf75563540c615f9854ecc9bc8913e2488 || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" e22d997bd15b795a176c8da62c8c1da0a674eb534e02f7c01ca507bf11bce0c3 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 247a0a58039275a5a4fb499a600a90f66dc6e00321bb6f86a9b8d8020344d853 || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 57bd332e5550ff70a852560c591b786b6ba587c5e41cb5ef91038d82db137ab9 || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" c65a89140f5d68137ffec67d631ec97002fb37077d9b4eb4ee45cbec39b1c38a || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 30a8e7773e1f274557e049a97f158b808f344247da03ae5240e4956c81d51cd5 || 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 (

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.7
// dear imgui, v1.91.8
// (headers)
// Help:
@@ -28,8 +28,8 @@
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.91.7"
#define IMGUI_VERSION_NUM 19170
#define IMGUI_VERSION "1.91.8"
#define IMGUI_VERSION_NUM 19180
#define IMGUI_HAS_TABLE
/*
@@ -158,7 +158,7 @@ typedef unsigned int ImU32; // 32-bit unsigned integer (often used to st
typedef signed long long ImS64; // 64-bit signed integer
typedef unsigned long long ImU64; // 64-bit unsigned integer
// Forward declarations
// Forward declarations: ImDrawList, ImFontAtlas layer
struct ImDrawChannel; // Temporary storage to output draw commands out of order, used by ImDrawListSplitter and ImDrawList::ChannelsSplit()
struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call, unless it is a callback)
struct ImDrawData; // All draw command lists required to render the frame + pos/size coordinates to use for the projection matrix.
@@ -173,6 +173,8 @@ struct ImFontConfig; // Configuration data when adding a font or
struct ImFontGlyph; // A single font glyph (code point + coordinates within in ImFontAtlas + offset)
struct ImFontGlyphRangesBuilder; // Helper to build glyph ranges from text/string data
struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 (*OBSOLETE* please avoid using)
// Forward declarations: ImGui layer
struct ImGuiContext; // Dear ImGui context (opaque structure, unless including imgui_internal.h)
struct ImGuiIO; // Main configuration and I/O between your application and ImGui (also see: ImGuiPlatformIO)
struct ImGuiInputTextCallbackData; // Shared state of InputText() when using custom ImGuiInputTextCallback (rare/advanced use)
@@ -1009,6 +1011,7 @@ namespace ImGui
IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down). Same as GetMouseClickedCount() == 1.
IMGUI_API bool IsMouseReleased(ImGuiMouseButton button); // did mouse button released? (went from Down to !Down)
IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? Same as GetMouseClickedCount() == 2. (note that a double-click will also report IsMouseClicked() == true)
IMGUI_API bool IsMouseReleasedWithDelay(ImGuiMouseButton button, float delay); // delayed mouse release (use very sparingly!). Generally used with 'delay >= io.MouseDoubleClickTime' + combined with a 'io.MouseClickedLastCount==1' test. This is a very rarely used UI idiom, but some apps use this: e.g. MS Explorer single click on an icon to rename.
IMGUI_API int GetMouseClickedCount(ImGuiMouseButton button); // return the number of successive mouse-clicks at the time where a click happen (otherwise 0).
IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available
@@ -1751,10 +1754,16 @@ enum ImGuiColorEditFlags_
ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.
ImGuiColorEditFlags_NoBorder = 1 << 10, // // ColorButton: disable border (which is enforced by default)
// Alpha preview
// - Prior to 1.91.8 (2025/01/21): alpha was made opaque in the preview by default using old name ImGuiColorEditFlags_AlphaPreview.
// - We now display the preview as transparent by default. You can use ImGuiColorEditFlags_AlphaOpaque to use old behavior.
// - The new flags may be combined better and allow finer controls.
ImGuiColorEditFlags_AlphaOpaque = 1 << 11, // // ColorEdit, ColorPicker, ColorButton: disable alpha in the preview,. Contrary to _NoAlpha it may still be edited when calling ColorEdit4()/ColorPicker4(). For ColorButton() this does the same as _NoAlpha.
ImGuiColorEditFlags_AlphaNoBg = 1 << 12, // // ColorEdit, ColorPicker, ColorButton: disable rendering a checkerboard background behind transparent color.
ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 13, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half transparent preview.
// User Options (right-click on widget to change some of them).
ImGuiColorEditFlags_AlphaBar = 1 << 16, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
ImGuiColorEditFlags_AlphaPreview = 1 << 17, // // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque.
ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 18, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque.
ImGuiColorEditFlags_HDR = 1 << 19, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well).
ImGuiColorEditFlags_DisplayRGB = 1 << 20, // [Display] // ColorEdit: override _display_ type among RGB/HSV/Hex. ColorPicker: select any combination using one or more of RGB/HSV/Hex.
ImGuiColorEditFlags_DisplayHSV = 1 << 21, // [Display] // "
@@ -1771,12 +1780,16 @@ enum ImGuiColorEditFlags_
ImGuiColorEditFlags_DefaultOptions_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_PickerHueBar,
// [Internal] Masks
ImGuiColorEditFlags_AlphaMask_ = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaOpaque | ImGuiColorEditFlags_AlphaNoBg | ImGuiColorEditFlags_AlphaPreviewHalf,
ImGuiColorEditFlags_DisplayMask_ = ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex,
ImGuiColorEditFlags_DataTypeMask_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_Float,
ImGuiColorEditFlags_PickerMask_ = ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_PickerHueBar,
ImGuiColorEditFlags_InputMask_ = ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_InputHSV,
// Obsolete names
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiColorEditFlags_AlphaPreview = 0, // [Removed in 1.91.8] This is the default now. Will display a checkerboard unless ImGuiColorEditFlags_AlphaNoBg is set.
#endif
//ImGuiColorEditFlags_RGB = ImGuiColorEditFlags_DisplayRGB, ImGuiColorEditFlags_HSV = ImGuiColorEditFlags_DisplayHSV, ImGuiColorEditFlags_HEX = ImGuiColorEditFlags_DisplayHex // [renamed in 1.69]
};
@@ -2403,6 +2416,7 @@ struct ImGuiIO
ImU16 MouseClickedCount[5]; // == 0 (not clicked), == 1 (same as MouseClicked[]), == 2 (double-clicked), == 3 (triple-clicked) etc. when going from !Down to Down
ImU16 MouseClickedLastCount[5]; // Count successive number of clicks. Stays valid after mouse release. Reset after another click is done.
bool MouseReleased[5]; // Mouse button went from Down to !Down
double MouseReleasedTime[5]; // Time of last released (rarely used! but useful to handle delayed single-click when trying to disambiguate them from double-click).
bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds.
bool MouseDownOwnedUnlessPopupClose[5]; // Track if button was clicked inside a dear imgui window.
bool MouseWheelRequestAxisSwap; // On a non-Mac system, holding SHIFT requests WheelY to perform the equivalent of a WheelX event. On a Mac system this is already enforced by the system.
@@ -2923,7 +2937,7 @@ struct ImGuiSelectionExternalStorage
// The maximum line width to bake anti-aliased textures for. Build atlas with ImFontAtlasFlags_NoBakedLines to disable baking.
#ifndef IM_DRAWLIST_TEX_LINES_WIDTH_MAX
#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (63)
#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (32)
#endif
// ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h]
@@ -2997,7 +3011,6 @@ struct ImDrawChannel
ImVector<ImDrawIdx> _IdxBuffer;
};
// Split/Merge functions are used to split the draw list into different layers which can be drawn into out of order.
// This is used by the Columns/Tables API, so items of each column can be batched together in a same draw call.
struct ImDrawListSplitter
@@ -3232,26 +3245,27 @@ struct ImDrawData
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFontGlyphRangesBuilder, ImFont)
//-----------------------------------------------------------------------------
// A font input/source (we may rename this to ImFontSource in the future)
struct ImFontConfig
{
void* FontData; // // TTF/OTF data
int FontDataSize; // // TTF/OTF data size
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
int FontNo; // 0 // Index of font within TTF/OTF file
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
int OversampleH; // 2 // Rasterize at higher quality for sub-pixel positioning. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
int OversampleV; // 1 // Rasterize at higher quality for sub-pixel positioning. This is not really useful as we don't use sub-pixel positions on the Y axis.
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
bool PixelSnapH; // false // Align every glyph AdvanceX to pixel boundaries. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
int FontNo; // 0 // Index of font within TTF/OTF file
int OversampleH; // 0 (2) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1 or 2 depending on size. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
int OversampleV; // 0 (1) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1. This is not really useful as we don't use sub-pixel positions on the Y axis.
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs when rendered: essentially add to glyph->AdvanceX. Only X axis is supported for now.
ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input.
const ImWchar* GlyphRanges; // NULL // THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list).
float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future.
float RasterizerDensity; // 1.0f // DPI scale for rasterization, not altering other font metrics: make it easy to swap between e.g. a 100% and a 400% fonts for a zooming display. IMPORTANT: If you increase this it is expected that you increase font scale accordingly, otherwise quality may look lowered.
ImWchar EllipsisChar; // 0 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
ImWchar EllipsisChar; // 0 // Explicitly specify Unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
// [Internal]
char Name[40]; // Name (strictly to ease debugging)
@@ -3341,8 +3355,8 @@ struct ImFontAtlas
IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_data_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp.
IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter.
IMGUI_API void ClearInputData(); // Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts.
IMGUI_API void ClearFonts(); // Clear input+output font data (same as ClearInputData() + glyphs storage, UV coordinates).
IMGUI_API void ClearTexData(); // Clear output texture data (CPU side). Saves RAM once the texture has been copied to graphics memory.
IMGUI_API void ClearFonts(); // Clear output font data (glyphs storage, UV coordinates).
IMGUI_API void Clear(); // Clear all input and output.
// Build atlas, retrieve pixel data.
@@ -3375,7 +3389,7 @@ struct ImFontAtlas
IMGUI_API const ImWchar* GetGlyphRangesVietnamese(); // Default + Vietnamese characters
//-------------------------------------------
// [BETA] Custom Rectangles/Glyphs API
// [ALPHA] Custom Rectangles/Glyphs API
//-------------------------------------------
// You can request arbitrary rectangles to be packed into the atlas, for your own purposes.
@@ -3401,11 +3415,11 @@ struct ImFontAtlas
ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure.
int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
int TexGlyphPadding; // FIXME: Should be called "TexPackPadding". Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0 (will also need to set AntiAliasedLinesUseTex = false).
bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert.
void* UserData; // Store your own atlas related user-data (if e.g. you have multiple font atlas).
// [Internal]
// NB: Access texture data via GetTexData*() calls! Which will setup a default font for you.
bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert.
bool TexReady; // Set when texture was built matching current font input
bool TexPixelsUseColors; // Tell whether our texture data is known to use colors (rather than just alpha channel), in order to help backend select a format.
unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight
@@ -3437,39 +3451,39 @@ struct ImFontAtlas
struct ImFont
{
// [Internal] Members: Hot ~20/24 bytes (for CalcTextSize)
ImVector<float> IndexAdvanceX; // 12-16 // out // // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this info, and are often bottleneck in large UI).
ImVector<float> IndexAdvanceX; // 12-16 // out // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this info, and are often bottleneck in large UI).
float FallbackAdvanceX; // 4 // out // = FallbackGlyph->AdvanceX
float FontSize; // 4 // in // // Height of characters/line, set during loading (don't change after loading)
float FontSize; // 4 // in // Height of characters/line, set during loading (don't change after loading)
// [Internal] Members: Hot ~28/40 bytes (for RenderText loop)
ImVector<ImWchar> IndexLookup; // 12-16 // out // // Sparse. Index glyphs by Unicode code-point.
ImVector<ImFontGlyph> Glyphs; // 12-16 // out // // All glyphs.
ImVector<ImU16> IndexLookup; // 12-16 // out // Sparse. Index glyphs by Unicode code-point.
ImVector<ImFontGlyph> Glyphs; // 12-16 // out // All glyphs.
const ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar)
// [Internal] Members: Cold ~32/40 bytes
// Conceptually ConfigData[] is the list of font sources merged to create this font.
ImFontAtlas* ContainerAtlas; // 4-8 // out // // What we has been loaded into
const ImFontConfig* ConfigData; // 4-8 // in // // Pointer within ContainerAtlas->ConfigData to ConfigDataCount instances
short ConfigDataCount; // 2 // in // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont.
ImFontAtlas* ContainerAtlas; // 4-8 // out // What we has been loaded into
const ImFontConfig* ConfigData; // 4-8 // in // Pointer within ContainerAtlas->ConfigData to ConfigDataCount instances
short ConfigDataCount; // 2 // in // Number of ImFontConfig involved in creating this font. Usually 1, or >1 when merging multiple font sources into one ImFont.
short EllipsisCharCount; // 1 // out // 1 or 3
ImWchar EllipsisChar; // 2-4 // out // = '...'/'.'// Character used for ellipsis rendering.
ImWchar FallbackChar; // 2-4 // out // = FFFD/'?' // Character used if a glyph isn't found.
float EllipsisWidth; // 4 // out // Width
float EllipsisCharStep; // 4 // out // Step between characters when EllipsisCount > 0
ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...').
ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?')
float EllipsisWidth; // 4 // out // Total ellipsis Width
float EllipsisCharStep; // 4 // out // Step between characters when EllipsisCount > 0
float Scale; // 4 // in // Base font scale (1.0f), multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
float Ascent, Descent; // 4+4 // out // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] (unscaled)
int MetricsTotalSurface;// 4 // out // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
bool DirtyLookupTables; // 1 // out //
float Scale; // 4 // in // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
float Ascent, Descent; // 4+4 // out // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] (unscaled)
int MetricsTotalSurface;// 4 // out // // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
ImU8 Used4kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/4096/8]; // 2 bytes if ImWchar=ImWchar16, 34 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/8192/8]; // 1 bytes if ImWchar=ImWchar16, 16 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
// Methods
IMGUI_API ImFont();
IMGUI_API ~ImFont();
IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c);
IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c);
float GetCharAdvance(ImWchar c) { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; }
bool IsLoaded() const { return ContainerAtlas != NULL; }
const char* GetDebugName() const { return ConfigData ? ConfigData->Name : "<unknown>"; }
float GetCharAdvance(ImWchar c) { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; }
bool IsLoaded() const { return ContainerAtlas != NULL; }
const char* GetDebugName() const { return ConfigData ? ConfigData->Name : "<unknown>"; }
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.7
// dear imgui, v1.91.8
// (internal structures/api)
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
@@ -130,10 +130,17 @@ Index of this file:
// [SECTION] Forward declarations
//-----------------------------------------------------------------------------
// Utilities
// (other types which are not forwarded declared are: ImBitArray<>, ImSpan<>, ImSpanAllocator<>, ImPool<>, ImChunkStream<>)
struct ImBitVector; // Store 1-bit per value
struct ImRect; // An axis-aligned rectangle (2 points)
struct ImGuiTextIndex; // Maintain a line index for a text buffer.
// ImDrawList/ImFontAtlas
struct ImDrawDataBuilder; // Helper to build a ImDrawData instance
struct ImDrawListSharedData; // Data shared between all ImDrawList instances
// ImGui
struct ImGuiBoxSelectState; // Box-selection state (currently used by multi-selection, could potentially be used by others)
struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it
struct ImGuiContext; // Main Dear ImGui context
@@ -222,7 +229,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
#endif
// Debug Logging for ShowDebugLogWindow(). This is designed for relatively rare events so please don't spam.
#define IMGUI_DEBUG_LOG_ERROR(...) do { ImGuiContext& g2 = *GImGui; if (g2.DebugLogFlags & ImGuiDebugLogFlags_EventError) IMGUI_DEBUG_LOG(__VA_ARGS__); else g2.DebugLogSkippedErrors++; } while (0)
#define IMGUI_DEBUG_LOG_ERROR(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventError) IMGUI_DEBUG_LOG(__VA_ARGS__); else g.DebugLogSkippedErrors++; } while (0)
#define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
@@ -462,7 +469,7 @@ static inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * (T)t); }
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
template<typename T> static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
@@ -736,6 +743,7 @@ struct ImGuiTextIndex
// Helper: ImGuiStorage
IMGUI_API ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key);
//-----------------------------------------------------------------------------
// [SECTION] ImDrawList support
//-----------------------------------------------------------------------------
@@ -2448,6 +2456,8 @@ struct IMGUI_API ImGuiWindowTempData
ImGuiLayoutType LayoutType;
ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin()
ImU32 ModalDimBgColor;
ImGuiItemStatusFlags WindowItemStatusFlags;
ImGuiItemStatusFlags ChildItemStatusFlags;
// Local parameters stacks
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
@@ -2543,6 +2553,8 @@ struct IMGUI_API ImGuiWindow
ImGuiStorage StateStorage;
ImVector<ImGuiOldColumns> ColumnsStorage;
float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
float FontWindowScaleParents;
float FontRefSize; // This is a copy of window->CalcFontSize() at the time of Begin(), trying to phase out CalcFontSize() especially as it may be called on non-current window.
int SettingsOffset; // Offset into SettingsWindows[] (offsets are always valid as we only grow the array from the back)
ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
@@ -2577,7 +2589,7 @@ public:
// We don't use g.FontSize because the window may be != g.CurrentWindow.
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
float CalcFontSize() const { ImGuiContext& g = *Ctx; float scale = g.FontBaseSize * FontWindowScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; }
float CalcFontSize() const { ImGuiContext& g = *Ctx; return g.FontBaseSize * FontWindowScale * FontWindowScaleParents; }
ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight)); }
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight; return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight); }
};
@@ -2600,6 +2612,8 @@ enum ImGuiTabItemFlagsPrivate_
ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing,
ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout)
ImGuiTabItemFlags_Button = 1 << 21, // Used by TabItemButton, change the tab item behavior to mimic a button
ImGuiTabItemFlags_Invisible = 1 << 22, // To reserve space e.g. with ImGuiTabItemFlags_Leading
//ImGuiTabItemFlags_Unsorted = 1 << 23, // [Docking] Trailing tabs with the _Unsorted flag will be sorted based on the DockOrder of their Window.
};
// Storage for one active tab item (sizeof() 40 bytes)
@@ -2863,6 +2877,7 @@ struct IMGUI_API ImGuiTable
ImGuiTableDrawChannelIdx DummyDrawChannel; // Redirect non-visible columns here.
ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing across columns after the freezing line. Index within DrawSplitter.Channels[]
ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen;
ImS8 NavLayer; // ImGuiNavLayer at the time of BeginTable().
bool IsLayoutLocked; // Set by TableUpdateLayout() which is called when beginning the first row.
bool IsInsideRow; // Set when inside TableBeginRow()/TableEndRow().
bool IsInitializing;
@@ -3004,6 +3019,7 @@ namespace ImGui
// Fonts, drawing
IMGUI_API void SetCurrentFont(ImFont* font);
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
IMGUI_API void PushPasswordFont();
inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { IM_UNUSED(window); return GetForegroundDrawList(); } // This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'docking' branches.
IMGUI_API ImDrawList* GetBackgroundDrawList(ImGuiViewport* viewport); // get background draw list for the given viewport. this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents.
IMGUI_API ImDrawList* GetForegroundDrawList(ImGuiViewport* viewport); // get foreground draw list for the given viewport. this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents.
@@ -3085,7 +3101,7 @@ namespace ImGui
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags);
IMGUI_API bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags = 0);
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id);
IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags item_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h);
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
IMGUI_API void PushMultiItemsWidths(int components, float width_full);
@@ -3366,6 +3382,7 @@ namespace ImGui
IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, ImVec2 mouse_pos);
IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar);
IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window);
IMGUI_API void TabItemSpacing(const char* str_id, ImGuiTabItemFlags flags, float width);
IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button_or_unsaved_marker);
IMGUI_API ImVec2 TabItemCalcSize(ImGuiWindow* window);
IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col);
@@ -3561,6 +3578,7 @@ IMGUI_API void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas,
IMGUI_API void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value);
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
IMGUI_API void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* cfg, int* out_oversample_h, int* out_oversample_v);
//-----------------------------------------------------------------------------
// [SECTION] Test Engine specific hooks (imgui_test_engine)

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.7
// dear imgui, v1.91.8
// (main code and documentation)
// Help:
@@ -430,6 +430,9 @@ CODE
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2025/01/22 (1.91.8) - removed ImGuiColorEditFlags_AlphaPreview (made value 0): it is now the default behavior.
prior to 1.91.8: alpha was made opaque in the preview by default _unless_ using ImGuiColorEditFlags_AlphaPreview. We now display the preview as transparent by default. You can use ImGuiColorEditFlags_AlphaOpaque to use old behavior.
the new flags (ImGuiColorEditFlags_AlphaOpaque, ImGuiColorEditFlags_AlphaNoBg + existing ImGuiColorEditFlags_AlphaPreviewHalf) may be combined better and allow finer controls:
- 2025/01/14 (1.91.7) - renamed ImGuiTreeNodeFlags_SpanTextWidth to ImGuiTreeNodeFlags_SpanLabelWidth for consistency with other names. Kept redirection enum (will obsolete). (#6937)
- 2024/11/27 (1.91.6) - changed CRC32 table from CRC32-adler to CRC32c polynomial in order to be compatible with the result of SSE 4.2 instructions.
As a result, old .ini data may be partially lost (docking and tables information particularly).
@@ -1253,6 +1256,7 @@ static void RenderWindowTitleBarContents(ImGuiWindow* window, const
static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col);
static void RenderDimmedBackgrounds();
static void SetLastItemDataForWindow(ImGuiWindow* window, const ImRect& rect);
static void SetLastItemDataForChildWindowItem(ImGuiWindow* window, const ImRect& rect);
// Viewports
const ImGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbitrary constant instead of e.g. ImHashStr("ViewportDefault", 0); so it's easier to spot in the debugger. The exact value doesn't matter.
@@ -1334,11 +1338,11 @@ ImGuiStyle::ImGuiStyle()
GrabMinSize = 12.0f; // Minimum width/height of a grab box for slider/scrollbar
GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
TabRounding = 5.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
TabBorderSize = 0.0f; // Thickness of border around tabs.
TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected.
TabBarBorderSize = 1.0f; // Thickness of tab-bar separator, which takes on the tab active color to denote focus.
TabBarOverlineSize = 2.0f; // Thickness of tab-bar overline, which highlights the selected tab-bar.
TabBarOverlineSize = 1.0f; // Thickness of tab-bar overline, which highlights the selected tab-bar.
TableAngledHeadersAngle = 35.0f * (IM_PI / 180.0f); // Angle of angled headers (supported values range from -50 degrees to +50 degrees).
TableAngledHeadersTextAlign = ImVec2(0.5f,0.0f);// Alignment of angled headers within the cell
ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
@@ -4276,7 +4280,8 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* ctx, const char* name) : DrawListInst(NUL
SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
LastFrameActive = -1;
LastTimeActive = -1.0f;
FontWindowScale = 1.0f;
FontRefSize = 0.0f;
FontWindowScale = FontWindowScaleParents = 1.0f;
SettingsOffset = -1;
DrawList = &DrawListInst;
DrawList->_OwnerName = Name;
@@ -4691,15 +4696,27 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id)
// This is also inlined in ItemAdd()
// Note: if ImGuiItemStatusFlags_HasDisplayRect is set, user needs to set g.LastItemData.DisplayRect.
void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags item_flags, const ImRect& item_rect)
void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags item_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect)
{
ImGuiContext& g = *GImGui;
g.LastItemData.ID = item_id;
g.LastItemData.ItemFlags = in_flags;
g.LastItemData.StatusFlags = item_flags;
g.LastItemData.ItemFlags = item_flags;
g.LastItemData.StatusFlags = status_flags;
g.LastItemData.Rect = g.LastItemData.NavRect = item_rect;
}
static void ImGui::SetLastItemDataForWindow(ImGuiWindow* window, const ImRect& rect)
{
ImGuiContext& g = *GImGui;
SetLastItemData(window->MoveId, g.CurrentItemFlags, window->DC.WindowItemStatusFlags, rect);
}
static void ImGui::SetLastItemDataForChildWindowItem(ImGuiWindow* window, const ImRect& rect)
{
ImGuiContext& g = *GImGui;
SetLastItemData(window->ChildId, g.CurrentItemFlags, window->DC.ChildItemStatusFlags, rect);
}
float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x)
{
if (wrap_pos_x < 0.0f)
@@ -5086,6 +5103,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
}
// Called once a frame. Followed by SetCurrentFont() which sets up the remaining data.
// FIXME-VIEWPORT: the concept of a single ClipRectFullscreen is not ideal!
static void SetupDrawListSharedData()
{
ImGuiContext& g = *GImGui;
@@ -6152,7 +6170,14 @@ void ImGui::EndChild()
}
if (g.HoveredWindow == child_window)
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
child_window->DC.ChildItemStatusFlags = g.LastItemData.StatusFlags;
//SetLastItemDataForChildWindowItem(child_window, child_window->Rect()); // Not needed, effectively done by ItemAdd()
}
else
{
SetLastItemDataForChildWindowItem(child_window, child_window->Rect());
}
g.WithinEndChildID = backup_within_end_child_id;
g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
}
@@ -6707,7 +6732,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar))
{
float y = window->Pos.y + window->TitleBarHeight - 1;
window->DrawList->AddLine(ImVec2(window->Pos.x + border_size, y), ImVec2(window->Pos.x + window->Size.x - border_size, y), border_col, g.Style.FrameBorderSize);
window->DrawList->AddLine(ImVec2(window->Pos.x + border_size * 0.5f, y), ImVec2(window->Pos.x + window->Size.x - border_size * 0.5f, y), border_col, g.Style.FrameBorderSize);
}
}
@@ -6767,9 +6792,9 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
{
ImRect menu_bar_rect = window->MenuBarRect();
menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them.
window->DrawList->AddRectFilled(menu_bar_rect.Min + ImVec2(window_border_size, 0), menu_bar_rect.Max - ImVec2(window_border_size, 0), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawFlags_RoundCornersTop);
window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawFlags_RoundCornersTop);
if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y)
window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
window->DrawList->AddLine(menu_bar_rect.GetBL() + ImVec2(window_border_size * 0.5f, 0.0f), menu_bar_rect.GetBR() - ImVec2(window_border_size * 0.5f, 0.0f), GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
}
// Scrollbars
@@ -6788,9 +6813,10 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
continue;
const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n];
const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPosN);
window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, resize_grip_draw_size) : ImVec2(resize_grip_draw_size, window_border_size)));
window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(resize_grip_draw_size, window_border_size) : ImVec2(window_border_size, resize_grip_draw_size)));
window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12);
const float border_inner = IM_ROUND(window_border_size * 0.5f);
window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(border_inner, resize_grip_draw_size) : ImVec2(resize_grip_draw_size, border_inner)));
window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(resize_grip_draw_size, border_inner) : ImVec2(border_inner, resize_grip_draw_size)));
window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + border_inner), corner.y + grip.InnerDir.y * (window_rounding + border_inner)), window_rounding, grip.AngleMin12, grip.AngleMax12);
window->DrawList->PathFillConvex(col);
}
}
@@ -7036,6 +7062,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// There's little point to expose a flag to set this: because the interesting cases won't be using parent_window_in_stack,
// e.g. linking a tool window in a standalone viewport to a document window, regardless of their Begin() stack parenting. (#6798)
window->ParentWindowForFocusRoute = (flags & ImGuiWindowFlags_ChildWindow) ? parent_window_in_stack : NULL;
// Inherent SetWindowFontScale() from parent until we fix this system...
window->FontWindowScaleParents = parent_window ? parent_window->FontWindowScaleParents * parent_window->FontWindowScale : 1.0f;
}
// Add to focus scope stack
@@ -7197,6 +7226,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
window->TitleBarHeight = (flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : g.FontSize + g.Style.FramePadding.y * 2.0f;
window->MenuBarHeight = (flags & ImGuiWindowFlags_MenuBar) ? window->DC.MenuBarOffset.y + g.FontSize + g.Style.FramePadding.y * 2.0f : 0.0f;
window->FontRefSize = g.FontSize; // Lock this to discourage calling window->CalcFontSize() outside of current window.
// Depending on condition we use previous or current window size to compare against contents size to decide if a scrollbar should be visible.
// Those flags will be altered further down in the function depending on more conditions.
@@ -7602,6 +7632,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin().
// This is useful to allow creating context menus on title bar only, etc.
window->DC.WindowItemStatusFlags = ImGuiItemStatusFlags_None;
window->DC.WindowItemStatusFlags |= IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0;
SetLastItemDataForWindow(window, title_bar_rect);
// [DEBUG]
@@ -7707,12 +7739,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
return !window->SkipItems;
}
static void ImGui::SetLastItemDataForWindow(ImGuiWindow* window, const ImRect& rect)
{
ImGuiContext& g = *GImGui;
SetLastItemData(window->MoveId, g.CurrentItemFlags, IsMouseHoveringRect(rect.Min, rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, rect);
}
void ImGui::End()
{
ImGuiContext& g = *GImGui;
@@ -9204,6 +9230,17 @@ bool ImGui::IsMouseReleased(ImGuiMouseButton button, ImGuiID owner_id)
return g.IO.MouseReleased[button] && TestKeyOwner(MouseButtonToKey(button), owner_id); // Should be same as IsKeyReleased(MouseButtonToKey(button), owner_id)
}
// Use if you absolutely need to distinguish single-click from double-click by introducing a delay.
// Generally use with 'delay >= io.MouseDoubleClickTime' + combined with a 'io.MouseClickedLastCount == 1' test.
// This is a very rarely used UI idiom, but some apps use this: e.g. MS Explorer single click on an icon to rename.
bool ImGui::IsMouseReleasedWithDelay(ImGuiMouseButton button, float delay)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
const float time_since_release = (float)(g.Time - g.IO.MouseReleasedTime[button]);
return !IsMouseDown(button) && (time_since_release - g.IO.DeltaTime < delay) && (time_since_release >= delay);
}
bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button)
{
ImGuiContext& g = *GImGui;
@@ -9477,6 +9514,8 @@ static void ImGui::UpdateMouseInputs()
io.MouseClicked[i] = io.MouseDown[i] && io.MouseDownDuration[i] < 0.0f;
io.MouseClickedCount[i] = 0; // Will be filled below
io.MouseReleased[i] = !io.MouseDown[i] && io.MouseDownDuration[i] >= 0.0f;
if (io.MouseReleased[i])
io.MouseReleasedTime[i] = g.Time;
io.MouseDownDurationPrev[i] = io.MouseDownDuration[i];
io.MouseDownDuration[i] = io.MouseDown[i] ? (io.MouseDownDuration[i] < 0.0f ? 0.0f : io.MouseDownDuration[i] + io.DeltaTime) : -1.0f;
if (io.MouseClicked[i])
@@ -9645,7 +9684,7 @@ void ImGui::UpdateMouseWheel()
{
LockWheelingWindow(window, wheel.x);
float max_step = window->InnerRect.GetWidth() * 0.67f;
float scroll_step = ImTrunc(ImMin(2 * window->CalcFontSize(), max_step));
float scroll_step = ImTrunc(ImMin(2 * window->FontRefSize, max_step));
SetScrollX(window, window->Scroll.x - wheel.x * scroll_step);
g.WheelingWindowScrolledFrame = g.FrameCount;
}
@@ -9653,7 +9692,7 @@ void ImGui::UpdateMouseWheel()
{
LockWheelingWindow(window, wheel.y);
float max_step = window->InnerRect.GetHeight() * 0.67f;
float scroll_step = ImTrunc(ImMin(5 * window->CalcFontSize(), max_step));
float scroll_step = ImTrunc(ImMin(5 * window->FontRefSize, max_step));
SetScrollY(window, window->Scroll.y - wheel.y * scroll_step);
g.WheelingWindowScrolledFrame = g.FrameCount;
}
@@ -10262,6 +10301,11 @@ void ImGui::ErrorRecoveryTryToRecoverWindowState(const ImGuiErrorRecoveryStat
IM_ASSERT_USER_ERROR(0, "Missing EndMultiSelect()");
EndMultiSelect();
}
if (window->DC.MenuBarAppending) //-V1044
{
IM_ASSERT_USER_ERROR(0, "Missing EndMenuBar()");
EndMenuBar();
}
while (window->DC.TreeDepth > state_in->SizeOfTreeStack) //-V1044
{
IM_ASSERT_USER_ERROR(0, "Missing TreePop()");
@@ -12983,7 +13027,7 @@ static void ImGui::NavUpdate()
{
// *Fallback* manual-scroll with Nav directional keys when window has no navigable item
ImGuiWindow* window = g.NavWindow;
const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
const float scroll_speed = IM_ROUND(window->FontRefSize * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
const ImGuiDir move_dir = g.NavMoveDir;
if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavWindowHasScrollY && move_dir != ImGuiDir_None)
{
@@ -13173,8 +13217,8 @@ void ImGui::NavUpdateCreateMoveRequest()
if ((clamp_x || clamp_y) && !inner_rect_rel.Contains(window->NavRectRel[g.NavLayer]))
{
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel for gamepad move\n");
float pad_x = ImMin(inner_rect_rel.GetWidth(), window->CalcFontSize() * 0.5f);
float pad_y = ImMin(inner_rect_rel.GetHeight(), window->CalcFontSize() * 0.5f); // Terrible approximation for the intent of starting navigation from first fully visible item
float pad_x = ImMin(inner_rect_rel.GetWidth(), window->FontRefSize * 0.5f);
float pad_y = ImMin(inner_rect_rel.GetHeight(), window->FontRefSize * 0.5f); // Terrible approximation for the intent of starting navigation from first fully visible item
inner_rect_rel.Min.x = clamp_x ? (inner_rect_rel.Min.x + pad_x) : -FLT_MAX;
inner_rect_rel.Max.x = clamp_x ? (inner_rect_rel.Max.x - pad_x) : +FLT_MAX;
inner_rect_rel.Min.y = clamp_y ? (inner_rect_rel.Min.y + pad_y) : -FLT_MAX;
@@ -13432,7 +13476,7 @@ static float ImGui::NavUpdatePageUpPageDown()
else
{
ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight());
const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->FontRefSize * 1.0f + nav_rect_rel.GetHeight());
float nav_scoring_rect_offset_y = 0.0f;
if (IsKeyPressed(ImGuiKey_PageUp, true))
{
@@ -13813,12 +13857,12 @@ void ImGui::NavUpdateWindowingOverlay()
return;
if (g.NavWindowingListWindow == NULL)
g.NavWindowingListWindow = FindWindowByName("###NavWindowingList");
g.NavWindowingListWindow = FindWindowByName("###NavWindowingOverlay");
const ImGuiViewport* viewport = GetMainViewport();
SetNextWindowSizeConstraints(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y * 0.20f), ImVec2(FLT_MAX, FLT_MAX));
SetNextWindowPos(viewport->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f);
Begin("###NavWindowingList", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings);
Begin("###NavWindowingOverlay", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings);
if (g.ContextName[0] != 0)
SeparatorText(g.ContextName);
for (int n = g.WindowsFocusOrder.Size - 1; n >= 0; n--)
@@ -16128,18 +16172,24 @@ void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, co
// [DEBUG] Display details for a single font, called by ShowStyleEditor().
void ImGui::DebugNodeFont(ImFont* font)
{
bool opened = TreeNode(font, "Font: \"%s\"\n%.2f px, %d glyphs, %d file(s)",
bool opened = TreeNode(font, "Font: \"%s\": %.2f px, %d glyphs, %d sources(s)",
font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size, font->ConfigDataCount);
SameLine();
if (SmallButton("Set as default"))
GetIO().FontDefault = font;
if (!opened)
return;
// Display preview text
if (!opened)
Indent();
Indent();
PushFont(font);
Text("The quick brown fox jumps over the lazy dog");
PopFont();
if (!opened)
{
Unindent();
Unindent();
return;
}
if (SmallButton("Set as default"))
GetIO().FontDefault = font;
// Display details
SetNextItemWidth(GetFontSize() * 8);
@@ -16158,62 +16208,69 @@ void ImGui::DebugNodeFont(ImFont* font)
Text("Texture Area: about %d px ~%dx%d px", font->MetricsTotalSurface, surface_sqrt, surface_sqrt);
for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
if (font->ConfigData)
if (const ImFontConfig* cfg = &font->ConfigData[config_i])
BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d, Offset: (%.1f,%.1f)",
config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH, cfg->GlyphOffset.x, cfg->GlyphOffset.y);
{
const ImFontConfig* cfg = &font->ConfigData[config_i];
int oversample_h, oversample_v;
ImFontAtlasBuildGetOversampleFactors(cfg, &oversample_h, &oversample_v);
BulletText("Input %d: \'%s\', Oversample: (%d=>%d,%d=>%d), PixelSnapH: %d, Offset: (%.1f,%.1f)",
config_i, cfg->Name, cfg->OversampleH, oversample_h, cfg->OversampleV, oversample_v, cfg->PixelSnapH, cfg->GlyphOffset.x, cfg->GlyphOffset.y);
}
// Display all glyphs of the fonts in separate pages of 256 characters
if (TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size))
{
ImDrawList* draw_list = GetWindowDrawList();
const ImU32 glyph_col = GetColorU32(ImGuiCol_Text);
const float cell_size = font->FontSize * 1;
const float cell_spacing = GetStyle().ItemSpacing.y;
for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256)
if (TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size))
{
// Skip ahead if a large bunch of glyphs are not present in the font (test in chunks of 4k)
// This is only a small optimization to reduce the number of iterations when IM_UNICODE_MAX_CODEPOINT
// is large // (if ImWchar==ImWchar32 we will do at least about 272 queries here)
if (!(base & 4095) && font->IsGlyphRangeUnused(base, base + 4095))
ImDrawList* draw_list = GetWindowDrawList();
const ImU32 glyph_col = GetColorU32(ImGuiCol_Text);
const float cell_size = font->FontSize * 1;
const float cell_spacing = GetStyle().ItemSpacing.y;
for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256)
{
base += 4096 - 256;
continue;
}
int count = 0;
for (unsigned int n = 0; n < 256; n++)
if (font->FindGlyphNoFallback((ImWchar)(base + n)))
count++;
if (count <= 0)
continue;
if (!TreeNode((void*)(intptr_t)base, "U+%04X..U+%04X (%d %s)", base, base + 255, count, count > 1 ? "glyphs" : "glyph"))
continue;
// Draw a 16x16 grid of glyphs
ImVec2 base_pos = GetCursorScreenPos();
for (unsigned int n = 0; n < 256; n++)
{
// We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions
// available here and thus cannot easily generate a zero-terminated UTF-8 encoded string.
ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size + cell_spacing), base_pos.y + (n / 16) * (cell_size + cell_spacing));
ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size);
const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base + n));
draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50));
if (!glyph)
continue;
font->RenderChar(draw_list, cell_size, cell_p1, glyph_col, (ImWchar)(base + n));
if (IsMouseHoveringRect(cell_p1, cell_p2) && BeginTooltip())
// Skip ahead if a large bunch of glyphs are not present in the font (test in chunks of 4k)
// This is only a small optimization to reduce the number of iterations when IM_UNICODE_MAX_CODEPOINT
// is large // (if ImWchar==ImWchar32 we will do at least about 272 queries here)
if (!(base & 8191) && font->IsGlyphRangeUnused(base, base + 8191))
{
DebugNodeFontGlyph(font, glyph);
EndTooltip();
base += 8192 - 256;
continue;
}
int count = 0;
for (unsigned int n = 0; n < 256; n++)
if (font->FindGlyphNoFallback((ImWchar)(base + n)))
count++;
if (count <= 0)
continue;
if (!TreeNode((void*)(intptr_t)base, "U+%04X..U+%04X (%d %s)", base, base + 255, count, count > 1 ? "glyphs" : "glyph"))
continue;
// Draw a 16x16 grid of glyphs
ImVec2 base_pos = GetCursorScreenPos();
for (unsigned int n = 0; n < 256; n++)
{
// We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions
// available here and thus cannot easily generate a zero-terminated UTF-8 encoded string.
ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size + cell_spacing), base_pos.y + (n / 16) * (cell_size + cell_spacing));
ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size);
const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base + n));
draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50));
if (!glyph)
continue;
font->RenderChar(draw_list, cell_size, cell_p1, glyph_col, (ImWchar)(base + n));
if (IsMouseHoveringRect(cell_p1, cell_p2) && BeginTooltip())
{
DebugNodeFontGlyph(font, glyph);
EndTooltip();
}
}
Dummy(ImVec2((cell_size + cell_spacing) * 16, (cell_size + cell_spacing) * 16));
TreePop();
}
Dummy(ImVec2((cell_size + cell_spacing) * 16, (cell_size + cell_spacing) * 16));
TreePop();
}
TreePop();
}
TreePop();
Unindent();
}
void ImGui::DebugNodeFontGlyph(ImFont*, const ImFontGlyph* glyph)

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.7
// dear imgui, v1.91.8
// (demo code)
// Help:
@@ -2117,19 +2117,16 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
if (ImGui::TreeNode("Color/Picker Widgets"))
{
static ImVec4 color = ImVec4(114.0f / 255.0f, 144.0f / 255.0f, 154.0f / 255.0f, 200.0f / 255.0f);
static ImGuiColorEditFlags base_flags = ImGuiColorEditFlags_None;
static bool alpha_preview = true;
static bool alpha_half_preview = false;
static bool drag_and_drop = true;
static bool options_menu = true;
static bool hdr = false;
ImGui::SeparatorText("Options");
ImGui::Checkbox("With Alpha Preview", &alpha_preview);
ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview);
ImGui::Checkbox("With Drag and Drop", &drag_and_drop);
ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options.");
ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.");
ImGuiColorEditFlags misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (drag_and_drop ? 0 : ImGuiColorEditFlags_NoDragDrop) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions);
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoAlpha", &base_flags, ImGuiColorEditFlags_NoAlpha);
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaOpaque", &base_flags, ImGuiColorEditFlags_AlphaOpaque);
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaNoBg", &base_flags, ImGuiColorEditFlags_AlphaNoBg);
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaPreviewHalf", &base_flags, ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoDragDrop", &base_flags, ImGuiColorEditFlags_NoDragDrop);
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoOptions", &base_flags, ImGuiColorEditFlags_NoOptions); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options.");
ImGui::CheckboxFlags("ImGuiColorEditFlags_HDR", &base_flags, ImGuiColorEditFlags_HDR); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.");
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit");
ImGui::SeparatorText("Inline color editor");
@@ -2137,15 +2134,15 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
ImGui::SameLine(); HelpMarker(
"Click on the color square to open a color picker.\n"
"CTRL+click on individual component to input value.\n");
ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags);
ImGui::ColorEdit3("MyColor##1", (float*)&color, base_flags);
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (HSV, with Alpha)");
ImGui::Text("Color widget HSV with Alpha:");
ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_DisplayHSV | misc_flags);
ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_DisplayHSV | base_flags);
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (float display)");
ImGui::Text("Color widget with Float Display:");
ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags);
ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | base_flags);
IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with Picker)");
ImGui::Text("Color button with Picker:");
@@ -2153,7 +2150,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
"With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\n"
"With the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only "
"be used for the tooltip and picker popup.");
ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags);
ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | base_flags);
IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with custom Picker popup)");
ImGui::Text("Color button with Custom Picker Popup:");
@@ -2173,7 +2170,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
}
static ImVec4 backup_color;
bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags);
bool open_popup = ImGui::ColorButton("MyColor##3b", color, base_flags);
ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
open_popup |= ImGui::Button("Palette");
if (open_popup)
@@ -2185,7 +2182,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
{
ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!");
ImGui::Separator();
ImGui::ColorPicker4("##picker", (float*)&color, misc_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview);
ImGui::ColorPicker4("##picker", (float*)&color, base_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview);
ImGui::SameLine();
ImGui::BeginGroup(); // Lock X position
@@ -2227,40 +2224,42 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
ImGui::Text("Color button only:");
static bool no_border = false;
ImGui::Checkbox("ImGuiColorEditFlags_NoBorder", &no_border);
ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80, 80));
ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, base_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80, 80));
IMGUI_DEMO_MARKER("Widgets/Color/ColorPicker");
ImGui::SeparatorText("Color picker");
static bool alpha = true;
static bool alpha_bar = true;
static bool side_preview = true;
static bool ref_color = false;
static ImVec4 ref_color_v(1.0f, 0.0f, 1.0f, 0.5f);
static int display_mode = 0;
static int picker_mode = 0;
ImGui::Checkbox("With Alpha", &alpha);
ImGui::Checkbox("With Alpha Bar", &alpha_bar);
ImGui::Checkbox("With Side Preview", &side_preview);
if (side_preview)
static int display_mode = 0;
static ImGuiColorEditFlags color_picker_flags = ImGuiColorEditFlags_AlphaBar;
ImGui::PushID("Color picker");
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoAlpha", &color_picker_flags, ImGuiColorEditFlags_NoAlpha);
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaBar", &color_picker_flags, ImGuiColorEditFlags_AlphaBar);
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoSidePreview", &color_picker_flags, ImGuiColorEditFlags_NoSidePreview);
if (color_picker_flags & ImGuiColorEditFlags_NoSidePreview)
{
ImGui::SameLine();
ImGui::Checkbox("With Ref Color", &ref_color);
if (ref_color)
{
ImGui::SameLine();
ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags);
ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | base_flags);
}
}
ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0None\0RGB Only\0HSV Only\0Hex Only\0");
ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0ImGuiColorEditFlags_PickerHueBar\0ImGuiColorEditFlags_PickerHueWheel\0");
ImGui::SameLine(); HelpMarker("When not specified explicitly, user can right-click the picker to change mode.");
ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0ImGuiColorEditFlags_NoInputs\0ImGuiColorEditFlags_DisplayRGB\0ImGuiColorEditFlags_DisplayHSV\0ImGuiColorEditFlags_DisplayHex\0");
ImGui::SameLine(); HelpMarker(
"ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, "
"but the user can change it with a right-click on those inputs.\n\nColorPicker defaults to displaying RGB+HSV+Hex "
"if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions().");
ImGui::SameLine(); HelpMarker("When not specified explicitly (Auto/Current mode), user can right-click the picker to change mode.");
ImGuiColorEditFlags flags = misc_flags;
if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4()
if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar;
if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview;
ImGuiColorEditFlags flags = base_flags | color_picker_flags;
if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar;
if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel;
if (display_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; // Disable all RGB/HSV/Hex displays
@@ -2289,6 +2288,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
ImGui::SameLine();
ImGui::SetNextItemWidth(w);
ImGui::ColorPicker3("##MyColor##6", (float*)&color, ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoAlpha);
ImGui::PopID();
// HSV encoded support (to avoid RGB<>HSV round trips and singularities when S==0 or V==0)
static ImVec4 color_hsv(0.23f, 1.0f, 1.0f, 1.0f); // Stored as HSV!
@@ -7408,6 +7408,8 @@ static void ShowDemoWindowInputs()
ImGui::Text("Mouse down:");
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDown(i)) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); }
ImGui::Text("Mouse wheel: %.1f", io.MouseWheel);
ImGui::Text("Mouse clicked count:");
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseClickedCount[i] > 0) { ImGui::SameLine(); ImGui::Text("b%d: %d", i, io.MouseClickedCount[i]); }
// We iterate both legacy native range and named ImGuiKey ranges. This is a little unusual/odd but this allows
// displaying the data for old/new backends.
@@ -7966,7 +7968,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f");
ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f");
ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f, 2.0f, "%.0f");
ImGui::SliderFloat("TabBarOverlineSize", &style.TabBarOverlineSize, 0.0f, 2.0f, "%.0f");
ImGui::SliderFloat("TabBarOverlineSize", &style.TabBarOverlineSize, 0.0f, 3.0f, "%.0f");
ImGui::SameLine(); HelpMarker("Overline is only drawn over the selected tab when ImGuiTabBarFlags_DrawSelectedOverline is set.");
ImGui::SeparatorText("Rounding");
@@ -8046,9 +8048,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
static ImGuiColorEditFlags alpha_flags = 0;
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine();
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_AlphaPreview)) { alpha_flags = ImGuiColorEditFlags_AlphaPreview; } ImGui::SameLine();
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine();
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_AlphaOpaque)) { alpha_flags = ImGuiColorEditFlags_AlphaOpaque; } ImGui::SameLine();
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine();
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine();
HelpMarker(
"In the color list:\n"
"Left-click on color square to open color picker,\n"

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.7
// dear imgui, v1.91.8
// (drawing and font code)
/*
@@ -1669,8 +1669,7 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
// Accept null ranges
if (text_begin == text_end || text_begin[0] == 0)
return;
if (text_end == NULL)
text_end = text_begin + strlen(text_begin);
// No need to strlen() here: font->RenderText() will do it and may early out.
// Pull default font/size from the shared ImDrawListSharedData instance
if (font == NULL)
@@ -1693,7 +1692,7 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
{
AddText(NULL, 0.0f, pos, col, text_begin, text_end);
AddText(_Data->Font, _Data->FontSize, pos, col, text_begin, text_end);
}
void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col)
@@ -2375,8 +2374,8 @@ ImFontConfig::ImFontConfig()
{
memset(this, 0, sizeof(*this));
FontDataOwnedByAtlas = true;
OversampleH = 2;
OversampleV = 1;
OversampleH = 0; // Auto == 1 or 2 depending on size
OversampleV = 0; // Auto == 1
GlyphMaxAdvanceX = FLT_MAX;
RasterizerMultiply = 1.0f;
RasterizerDensity = 1.0f;
@@ -2521,6 +2520,7 @@ void ImFontAtlas::ClearTexData()
void ImFontAtlas::ClearFonts()
{
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
ClearInputData();
Fonts.clear_delete();
TexReady = false;
}
@@ -2573,8 +2573,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
IM_ASSERT(font_cfg->FontData != NULL && font_cfg->FontDataSize > 0);
IM_ASSERT(font_cfg->SizePixels > 0.0f && "Is ImFontConfig struct correctly initialized?");
IM_ASSERT(font_cfg->OversampleH > 0 && font_cfg->OversampleV > 0 && "Is ImFontConfig struct correctly initialized?");
IM_ASSERT(font_cfg->RasterizerDensity > 0.0f);
IM_ASSERT(font_cfg->RasterizerDensity > 0.0f && "Is ImFontConfig struct correctly initialized?");
// Create new font
if (!font_cfg->MergeMode)
@@ -2820,6 +2819,13 @@ void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsig
*data = table[*data];
}
void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* cfg, int* out_oversample_h, int* out_oversample_v)
{
// Automatically disable horizontal oversampling over size 36
*out_oversample_h = (cfg->OversampleH != 0) ? cfg->OversampleH : (cfg->SizePixels * cfg->RasterizerDensity > 36.0f || cfg->PixelSnapH) ? 1 : 2;
*out_oversample_v = (cfg->OversampleV != 0) ? cfg->OversampleV : 1;
}
#ifdef IMGUI_ENABLE_STB_TRUETYPE
// Temporary data for one source font (multiple source fonts can be merged into one destination ImFont)
// (C++03 doesn't allow instancing ImVector<> with function-local types so we declare the type here.)
@@ -2985,15 +2991,19 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
buf_rects_out_n += src_tmp.GlyphsCount;
buf_packedchars_out_n += src_tmp.GlyphsCount;
// Convert our ranges in the format stb_truetype wants
// Automatic selection of oversampling parameters
ImFontConfig& cfg = atlas->ConfigData[src_i];
int oversample_h, oversample_v;
ImFontAtlasBuildGetOversampleFactors(&cfg, &oversample_h, &oversample_v);
// Convert our ranges in the format stb_truetype wants
src_tmp.PackRange.font_size = cfg.SizePixels * cfg.RasterizerDensity;
src_tmp.PackRange.first_unicode_codepoint_in_range = 0;
src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data;
src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size;
src_tmp.PackRange.chardata_for_range = src_tmp.PackedChars;
src_tmp.PackRange.h_oversample = (unsigned char)cfg.OversampleH;
src_tmp.PackRange.v_oversample = (unsigned char)cfg.OversampleV;
src_tmp.PackRange.h_oversample = (unsigned char)oversample_h;
src_tmp.PackRange.v_oversample = (unsigned char)oversample_v;
// Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects)
const float scale = (cfg.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels * cfg.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels * cfg.RasterizerDensity);
@@ -3002,9 +3012,9 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
int x0, y0, x1, y1;
const int glyph_index_in_font = stbtt_FindGlyphIndex(&src_tmp.FontInfo, src_tmp.GlyphsList[glyph_i]);
IM_ASSERT(glyph_index_in_font != 0);
stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * cfg.OversampleH, scale * cfg.OversampleV, 0, 0, &x0, &y0, &x1, &y1);
src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + pack_padding + cfg.OversampleH - 1);
src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + pack_padding + cfg.OversampleV - 1);
stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * oversample_h, scale * oversample_v, 0, 0, &x0, &y0, &x1, &y1);
src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + pack_padding + oversample_h - 1);
src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + pack_padding + oversample_v - 1);
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
}
}
@@ -3689,7 +3699,7 @@ ImFont::ImFont()
Scale = 1.0f;
Ascent = Descent = 0.0f;
MetricsTotalSurface = 0;
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
}
ImFont::~ImFont()
@@ -3709,7 +3719,7 @@ void ImFont::ClearOutputData()
DirtyLookupTables = true;
Ascent = Descent = 0.0f;
MetricsTotalSurface = 0;
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
}
static ImWchar FindFirstExistingGlyph(ImFont* font, const ImWchar* candidate_chars, int candidate_chars_count)
@@ -3732,17 +3742,17 @@ void ImFont::BuildLookupTable()
IndexAdvanceX.clear();
IndexLookup.clear();
DirtyLookupTables = false;
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
GrowIndex(max_codepoint + 1);
for (int i = 0; i < Glyphs.Size; i++)
{
int codepoint = (int)Glyphs[i].Codepoint;
IndexAdvanceX[codepoint] = Glyphs[i].AdvanceX;
IndexLookup[codepoint] = (ImWchar)i;
IndexLookup[codepoint] = (ImU16)i;
// Mark 4K page as used
const int page_n = codepoint / 4096;
Used4kPagesMap[page_n >> 3] |= 1 << (page_n & 7);
const int page_n = codepoint / 8192;
Used8kPagesMap[page_n >> 3] |= 1 << (page_n & 7);
}
// Create a glyph to handle TAB
@@ -3756,7 +3766,7 @@ void ImFont::BuildLookupTable()
tab_glyph.Codepoint = '\t';
tab_glyph.AdvanceX *= IM_TABSIZE;
IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX;
IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size - 1);
IndexLookup[(int)tab_glyph.Codepoint] = (ImU16)(Glyphs.Size - 1);
}
// Mark special glyphs as not visible (note that AddGlyph already mark as non-visible glyphs with zero-size polygons)
@@ -3804,15 +3814,15 @@ void ImFont::BuildLookupTable()
}
}
// API is designed this way to avoid exposing the 4K page size
// API is designed this way to avoid exposing the 8K page size
// e.g. use with IsGlyphRangeUnused(0, 255)
bool ImFont::IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last)
{
unsigned int page_begin = (c_begin / 4096);
unsigned int page_last = (c_last / 4096);
unsigned int page_begin = (c_begin / 8192);
unsigned int page_last = (c_last / 8192);
for (unsigned int page_n = page_begin; page_n <= page_last; page_n++)
if ((page_n >> 3) < sizeof(Used4kPagesMap))
if (Used4kPagesMap[page_n >> 3] & (1 << (page_n & 7)))
if ((page_n >> 3) < sizeof(Used8kPagesMap))
if (Used8kPagesMap[page_n >> 3] & (1 << (page_n & 7)))
return false;
return true;
}
@@ -3829,7 +3839,7 @@ void ImFont::GrowIndex(int new_size)
if (new_size <= IndexLookup.Size)
return;
IndexAdvanceX.resize(new_size, -1.0f);
IndexLookup.resize(new_size, (ImWchar)-1);
IndexLookup.resize(new_size, (ImU16)-1);
}
// x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero.
@@ -3872,6 +3882,7 @@ void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, floa
glyph.U1 = u1;
glyph.V1 = v1;
glyph.AdvanceX = advance_x;
IM_ASSERT(Glyphs.Size < 0xFFFF); // IndexLookup[] hold 16-bit values and -1 is reserved.
// Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
// We use (U1-U0)*TexWidth instead of X1-X0 to account for oversampling.
@@ -3885,13 +3896,13 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function.
unsigned int index_size = (unsigned int)IndexLookup.Size;
if (dst < index_size && IndexLookup.Data[dst] == (ImWchar)-1 && !overwrite_dst) // 'dst' already exists
if (dst < index_size && IndexLookup.Data[dst] == (ImU16)-1 && !overwrite_dst) // 'dst' already exists
return;
if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op
return;
GrowIndex(dst + 1);
IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (ImWchar)-1;
IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (ImU16)-1;
IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f;
}
@@ -3900,8 +3911,8 @@ const ImFontGlyph* ImFont::FindGlyph(ImWchar c)
{
if (c >= (size_t)IndexLookup.Size)
return FallbackGlyph;
const ImWchar i = IndexLookup.Data[c];
if (i == (ImWchar)-1)
const ImU16 i = IndexLookup.Data[c];
if (i == (ImU16)-1)
return FallbackGlyph;
return &Glyphs.Data[i];
}
@@ -3910,8 +3921,8 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c)
{
if (c >= (size_t)IndexLookup.Size)
return NULL;
const ImWchar i = IndexLookup.Data[c];
if (i == (ImWchar)-1)
const ImU16 i = IndexLookup.Data[c];
if (i == (ImU16)-1)
return NULL;
return &Glyphs.Data[i];
}
@@ -4125,15 +4136,15 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip)
{
if (!text_end)
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
// Align to be pixel perfect
float x = IM_TRUNC(pos.x);
float y = IM_TRUNC(pos.y);
if (y > clip_rect.w)
return;
if (!text_end)
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
const float scale = size / FontSize;
const float line_height = FontSize * scale;
const float origin_x = x;

View File

@@ -33,7 +33,7 @@
// - For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
// - The default dear imgui styles will be impacted by this change (alpha values will need tweaking).
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
// FIXME: cfg.OversampleH, OversampleV are not supported, but generally not necessary with this rasterizer because Hinting makes everything look better.
#include "imgui.h"
#ifndef IMGUI_DISABLE
@@ -104,6 +104,9 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_
// Code
//-------------------------------------------------------------------------
#define FT_CEIL(X) (((X + 63) & -64) / 64) // From SDL_ttf: Handy routines for converting from fixed point
#define FT_SCALEFACTOR 64.0f
namespace
{
// Glyph metrics:
@@ -182,9 +185,6 @@ namespace
float InvRasterizationDensity;
};
// From SDL_ttf: Handy routines for converting from fixed point
#define FT_CEIL(X) (((X + 63) & -64) / 64)
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags)
{
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
@@ -316,7 +316,7 @@ namespace
out_glyph_info->Height = (int)ft_bitmap->rows;
out_glyph_info->OffsetX = Face->glyph->bitmap_left;
out_glyph_info->OffsetY = -Face->glyph->bitmap_top;
out_glyph_info->AdvanceX = (float)FT_CEIL(slot->advance.x);
out_glyph_info->AdvanceX = (float)slot->advance.x / FT_SCALEFACTOR;
out_glyph_info->IsColored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA);
return ft_bitmap;

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.7
// dear imgui, v1.91.8
// (tables and columns code)
/*
@@ -374,6 +374,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->ColumnsCount = columns_count;
table->IsLayoutLocked = false;
table->InnerWidth = inner_width;
table->NavLayer = (ImS8)outer_window->DC.NavLayerCurrent;
temp_data->UserOuterSize = outer_size;
// Instance data (for instance 0, TableID == TableInstanceID)
@@ -1050,7 +1051,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
const int column_n = table->DisplayOrderToIndex[order_n];
ImGuiTableColumn* column = &table->Columns[column_n];
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); // Use Count NOT request so Header line changes layer when frozen
// Initial nav layer: using FreezeRowsCount, NOT FreezeRowsRequest, so Header line changes layer when frozen
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : (ImGuiNavLayer)table->NavLayer);
if (offset_x_frozen && table->FreezeColumnsCount == visible_n)
{
@@ -1493,7 +1495,7 @@ void ImGui::EndTable()
if (inner_window != outer_window)
{
short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask;
inner_window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main; // So empty table don't appear to navigate differently.
inner_window->DC.NavLayersActiveMask |= 1 << table->NavLayer; // So empty table don't appear to navigate differently.
g.CurrentTable = NULL; // To avoid error recovery recursing
EndChild();
g.CurrentTable = table;
@@ -2032,7 +2034,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
if (unfreeze_rows_request)
{
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
table->Columns[column_n].NavLayerCurrent = ImGuiNavLayer_Main;
table->Columns[column_n].NavLayerCurrent = table->NavLayer;
const float y0 = ImMax(table->RowPosY2 + 1, table->InnerClipRect.Min.y);
table_instance->LastFrozenHeight = y0 - table->OuterRect.Min.y;

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.7
// dear imgui, v1.91.8
// (widgets code)
/*
@@ -909,15 +909,17 @@ ImGuiID ImGui::GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis)
// Return scrollbar rectangle, must only be called for corresponding axis if window->ScrollbarX/Y is set.
ImRect ImGui::GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis)
{
ImGuiContext& g = *GImGui;
const ImRect outer_rect = window->Rect();
const ImRect inner_rect = window->InnerRect;
const float border_size = window->WindowBorderSize;
const float scrollbar_size = window->ScrollbarSizes[axis ^ 1]; // (ScrollbarSizes.x = width of Y scrollbar; ScrollbarSizes.y = height of X scrollbar)
IM_ASSERT(scrollbar_size > 0.0f);
const float border_size = IM_ROUND(window->WindowBorderSize * 0.5f);
const float border_top = (window->Flags & ImGuiWindowFlags_MenuBar) ? IM_ROUND(g.Style.FrameBorderSize * 0.5f) : 0.0f;
if (axis == ImGuiAxis_X)
return ImRect(inner_rect.Min.x, ImMax(outer_rect.Min.y, outer_rect.Max.y - border_size - scrollbar_size), inner_rect.Max.x - border_size, outer_rect.Max.y - border_size);
return ImRect(inner_rect.Min.x + border_size, ImMax(outer_rect.Min.y + border_size, outer_rect.Max.y - border_size - scrollbar_size), inner_rect.Max.x - border_size, outer_rect.Max.y - border_size);
else
return ImRect(ImMax(outer_rect.Min.x, outer_rect.Max.x - border_size - scrollbar_size), inner_rect.Min.y, outer_rect.Max.x - border_size, inner_rect.Max.y - border_size);
return ImRect(ImMax(outer_rect.Min.x, outer_rect.Max.x - border_size - scrollbar_size), inner_rect.Min.y + border_top, outer_rect.Max.x - border_size, inner_rect.Max.y - border_size);
}
void ImGui::Scrollbar(ImGuiAxis axis)
@@ -4244,6 +4246,23 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
BufTextLen += new_text_len;
}
void ImGui::PushPasswordFont()
{
ImGuiContext& g = *GImGui;
ImFont* in_font = g.Font;
ImFont* out_font = &g.InputTextPasswordFont;
const ImFontGlyph* glyph = in_font->FindGlyph('*');
out_font->FontSize = in_font->FontSize;
out_font->Scale = in_font->Scale;
out_font->Ascent = in_font->Ascent;
out_font->Descent = in_font->Descent;
out_font->ContainerAtlas = in_font->ContainerAtlas;
out_font->FallbackGlyph = glyph;
out_font->FallbackAdvanceX = glyph->AdvanceX;
IM_ASSERT(out_font->Glyphs.Size == 0 && out_font->IndexAdvanceX.Size == 0 && out_font->IndexLookup.Size == 0);
PushFont(out_font);
}
// Return false to discard a character.
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard)
{
@@ -4654,19 +4673,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Password pushes a temporary font with only a fallback glyph
if (is_password && !is_displaying_hint)
{
const ImFontGlyph* glyph = g.Font->FindGlyph('*');
ImFont* password_font = &g.InputTextPasswordFont;
password_font->FontSize = g.Font->FontSize;
password_font->Scale = g.Font->Scale;
password_font->Ascent = g.Font->Ascent;
password_font->Descent = g.Font->Descent;
password_font->ContainerAtlas = g.Font->ContainerAtlas;
password_font->FallbackGlyph = glyph;
password_font->FallbackAdvanceX = glyph->AdvanceX;
IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexAdvanceX.empty() && password_font->IndexLookup.empty());
PushFont(password_font);
}
PushPasswordFont();
// Process mouse inputs and character inputs
if (g.ActiveId == id)
@@ -5902,7 +5909,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
if ((flags & ImGuiColorEditFlags_NoLabel))
Text("Current");
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf | ImGuiColorEditFlags_NoTooltip;
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaMask_ | ImGuiColorEditFlags_NoTooltip;
ColorButton("##current", col_v4, (flags & sub_flags_to_forward), ImVec2(square_sz * 3, square_sz * 2));
if (ref_col != NULL)
{
@@ -5942,7 +5949,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
if ((flags & ImGuiColorEditFlags_NoInputs) == 0)
{
PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x);
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf;
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaMask_ | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoSmallPreview;
ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker;
if (flags & ImGuiColorEditFlags_DisplayRGB || (flags & ImGuiColorEditFlags_DisplayMask_) == 0)
if (ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_DisplayRGB))
@@ -6118,8 +6125,8 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held);
if (flags & ImGuiColorEditFlags_NoAlpha)
flags &= ~(ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf);
if (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaOpaque))
flags &= ~(ImGuiColorEditFlags_AlphaNoBg | ImGuiColorEditFlags_AlphaPreviewHalf);
ImVec4 col_rgb = col;
if (flags & ImGuiColorEditFlags_InputHSV)
@@ -6138,14 +6145,17 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
{
float mid_x = IM_ROUND((bb_inner.Min.x + bb_inner.Max.x) * 0.5f);
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawFlags_RoundCornersRight);
if ((flags & ImGuiColorEditFlags_AlphaNoBg) == 0)
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawFlags_RoundCornersRight);
else
window->DrawList->AddRectFilled(ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), rounding, ImDrawFlags_RoundCornersRight);
window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawFlags_RoundCornersLeft);
}
else
{
// Because GetColorU32() multiplies by the global style Alpha and we don't want to display a checkerboard if the source code had no alpha
ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaPreview) ? col_rgb : col_rgb_without_alpha;
if (col_source.w < 1.0f)
ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaOpaque) ? col_rgb_without_alpha : col_rgb;
if (col_source.w < 1.0f && (flags & ImGuiColorEditFlags_AlphaNoBg) == 0)
RenderColorRectWithAlphaCheckerboard(window->DrawList, bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding);
else
window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding);
@@ -6175,7 +6185,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
// Tooltip
if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered && IsItemHovered(ImGuiHoveredFlags_ForTooltip))
ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf));
ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_AlphaMask_));
return pressed;
}
@@ -6216,7 +6226,8 @@ void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags
ImVec2 sz(g.FontSize * 3 + g.Style.FramePadding.y * 2, g.FontSize * 3 + g.Style.FramePadding.y * 2);
ImVec4 cf(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]);
int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]);
ColorButton("##preview", cf, (flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)) | ImGuiColorEditFlags_NoTooltip, sz);
ImGuiColorEditFlags flags_to_forward = ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_AlphaMask_;
ColorButton("##preview", cf, (flags & flags_to_forward) | ImGuiColorEditFlags_NoTooltip, sz);
SameLine();
if ((flags & ImGuiColorEditFlags_InputRGB) || !(flags & ImGuiColorEditFlags_InputMask_))
{
@@ -6937,13 +6948,9 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth))
size.x = ImMax(label_size.x, max_x - min_x);
// Text stays at the submission position, but bounding box may be extended on both sides
const ImVec2 text_min = pos;
const ImVec2 text_max(min_x + size.x, pos.y + size.y);
// Selectables are meant to be tightly packed together with no click-gap, so we extend their box to cover spacing between selectable.
// FIXME: Not part of layout so not included in clipper calculation, but ItemSize currently doesn't allow offsetting CursorPos.
ImRect bb(min_x, pos.y, text_max.x, text_max.y);
ImRect bb(min_x, pos.y, min_x + size.x, pos.y + size.y);
if ((flags & ImGuiSelectableFlags_NoPadWithHalfSpacing) == 0)
{
const float spacing_x = span_all_columns ? 0.0f : style.ItemSpacing.x;
@@ -7079,8 +7086,9 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
PopColumnsBackground();
}
// Text stays at the submission position. Alignment/clipping extents ignore SpanAllColumns.
if (is_visible)
RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb);
RenderTextClipped(pos, ImVec2(window->WorkRect.Max.x, pos.y + size.y), label, NULL, &label_size, style.SelectableTextAlign, &bb);
// Automatically close popups
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_NoAutoClosePopups) && (g.LastItemData.ItemFlags & ImGuiItemFlags_AutoClosePopups))
@@ -8622,12 +8630,13 @@ bool ImGui::BeginMenuBar()
IM_ASSERT(!window->DC.MenuBarAppending);
BeginGroup(); // Backup position on layer 0 // FIXME: Misleading to use a group for that backup/restore
PushID("##menubar");
PushID("##MenuBar");
// We don't clip with current window clipping rectangle as it is already set to the area below. However we clip with window full rect.
// We remove 1 worth of rounding to Max.x to that text in long menus and small windows don't tend to display over the lower-right rounded area, which looks particularly glitchy.
const float border_top = ImMax(window->WindowBorderSize * 0.5f - window->TitleBarHeight, 0.0f);
ImRect bar_rect = window->MenuBarRect();
ImRect clip_rect(IM_ROUND(bar_rect.Min.x + window->WindowBorderSize), IM_ROUND(bar_rect.Min.y + window->WindowBorderSize), IM_ROUND(ImMax(bar_rect.Min.x, bar_rect.Max.x - ImMax(window->WindowRounding, window->WindowBorderSize))), IM_ROUND(bar_rect.Max.y));
ImRect clip_rect(IM_ROUND(bar_rect.Min.x + window->WindowBorderSize * 0.5f), IM_ROUND(bar_rect.Min.y + border_top), IM_ROUND(ImMax(bar_rect.Min.x, bar_rect.Max.x - ImMax(window->WindowRounding, window->WindowBorderSize * 0.5f))), IM_ROUND(bar_rect.Max.y));
clip_rect.ClipWith(window->OuterRectClipped);
PushClipRect(clip_rect.Min, clip_rect.Max, false);
@@ -8648,6 +8657,10 @@ void ImGui::EndMenuBar()
return;
ImGuiContext& g = *GImGui;
IM_MSVC_WARNING_SUPPRESS(6011); // Static Analysis false positive "warning C6011: Dereferencing NULL pointer 'window'"
IM_ASSERT(window->Flags & ImGuiWindowFlags_MenuBar);
IM_ASSERT(window->DC.MenuBarAppending);
// Nav: When a move request within one of our child menu failed, capture the request to navigate among our siblings.
if (NavMoveRequestButNoResultYet() && (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) && (g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
{
@@ -8674,9 +8687,6 @@ void ImGui::EndMenuBar()
}
}
IM_MSVC_WARNING_SUPPRESS(6011); // Static Analysis false positive "warning C6011: Dereferencing NULL pointer 'window'"
IM_ASSERT(window->Flags & ImGuiWindowFlags_MenuBar);
IM_ASSERT(window->DC.MenuBarAppending);
PopClipRect();
PopID();
window->DC.MenuBarOffset.x = window->DC.CursorPos.x - window->Pos.x; // Save horizontal position so next append can reuse it. This is kinda equivalent to a per-layer CursorPos.
@@ -8745,22 +8755,33 @@ bool ImGui::BeginMainMenuBar()
float height = GetFrameHeight();
bool is_open = BeginViewportSideBar("##MainMenuBar", viewport, ImGuiDir_Up, height, window_flags);
g.NextWindowData.MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f);
if (is_open)
BeginMenuBar();
else
if (!is_open)
{
End();
return false;
}
// Temporarily disable _NoSavedSettings, in the off-chance that tables or child windows submitted within the menu-bar may want to use settings. (#8356)
g.CurrentWindow->Flags &= ~ImGuiWindowFlags_NoSavedSettings;
BeginMenuBar();
return is_open;
}
void ImGui::EndMainMenuBar()
{
ImGuiContext& g = *GImGui;
if (!g.CurrentWindow->DC.MenuBarAppending)
{
IM_ASSERT_USER_ERROR(0, "Calling EndMainMenuBar() not from a menu-bar!"); // Not technically testing that it is the main menu bar
return;
}
EndMenuBar();
g.CurrentWindow->Flags |= ImGuiWindowFlags_NoSavedSettings; // Restore _NoSavedSettings (#8356)
// When the user has left the menu layer (typically: closed menus through activation of an item), we restore focus to the previous window
// FIXME: With this strategy we won't be able to restore a NULL focus.
ImGuiContext& g = *GImGui;
if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest)
if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest && g.ActiveId == 0)
FocusTopMostWindowUnderOne(g.NavWindow, NULL, NULL, ImGuiFocusRequestFlags_UnlessBelowModal | ImGuiFocusRequestFlags_RestoreFocusedChild);
End();
@@ -9921,7 +9942,7 @@ bool ImGui::BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags f
IM_ASSERT_USER_ERROR(tab_bar, "Needs to be called between BeginTabBar() and EndTabBar()!");
return false;
}
IM_ASSERT(!(flags & ImGuiTabItemFlags_Button)); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
IM_ASSERT((flags & ImGuiTabItemFlags_Button) == 0); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL);
if (ret && !(flags & ImGuiTabItemFlags_NoPushId))
@@ -9967,6 +9988,23 @@ bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags)
return TabItemEx(tab_bar, label, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, NULL);
}
void ImGui::TabItemSpacing(const char* str_id, ImGuiTabItemFlags flags, float width)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
if (window->SkipItems)
return;
ImGuiTabBar* tab_bar = g.CurrentTabBar;
if (tab_bar == NULL)
{
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
return;
}
SetNextItemWidth(width);
TabItemEx(tab_bar, str_id, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder | ImGuiTabItemFlags_Invisible, NULL);
}
bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window)
{
// Layout whole tab bar if not already done
@@ -10112,8 +10150,11 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowOverlap);
if (g.DragDropActive)
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
bool hovered, held, pressed;
if (flags & ImGuiTabItemFlags_Invisible)
hovered = held = pressed = false;
else
pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
if (pressed && !is_tab_button)
TabBarQueueFocus(tab_bar, tab);
@@ -10145,36 +10186,59 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
#endif
// Render tab shape
ImDrawList* display_draw_list = window->DrawList;
const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabSelected : ImGuiCol_TabDimmedSelected) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabDimmed));
TabItemBackground(display_draw_list, bb, flags, tab_col);
if (tab_contents_visible && (tab_bar->Flags & ImGuiTabBarFlags_DrawSelectedOverline) && style.TabBarOverlineSize > 0.0f)
const bool is_visible = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible) && !(flags & ImGuiTabItemFlags_Invisible);
if (is_visible)
{
float x_offset = IM_TRUNC(0.4f * style.TabRounding);
if (x_offset < 2.0f * g.CurrentDpiScale)
x_offset = 0.0f;
float y_offset = 1.0f * g.CurrentDpiScale;
display_draw_list->AddLine(bb.GetTL() + ImVec2(x_offset, y_offset), bb.GetTR() + ImVec2(-x_offset, y_offset), GetColorU32(tab_bar_focused ? ImGuiCol_TabSelectedOverline : ImGuiCol_TabDimmedSelectedOverline), style.TabBarOverlineSize);
}
RenderNavCursor(bb, id);
ImDrawList* display_draw_list = window->DrawList;
const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabSelected : ImGuiCol_TabDimmedSelected) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabDimmed));
TabItemBackground(display_draw_list, bb, flags, tab_col);
if (tab_contents_visible && (tab_bar->Flags & ImGuiTabBarFlags_DrawSelectedOverline) && style.TabBarOverlineSize > 0.0f)
{
// Might be moved to TabItemBackground() ?
ImVec2 tl = bb.GetTL() + ImVec2(0, 1.0f * g.CurrentDpiScale);
ImVec2 tr = bb.GetTR() + ImVec2(0, 1.0f * g.CurrentDpiScale);
ImU32 overline_col = GetColorU32(tab_bar_focused ? ImGuiCol_TabSelectedOverline : ImGuiCol_TabDimmedSelectedOverline);
if (style.TabRounding > 0.0f)
{
float rounding = style.TabRounding;
display_draw_list->PathArcToFast(tl + ImVec2(+rounding, +rounding), rounding, 7, 9);
display_draw_list->PathArcToFast(tr + ImVec2(-rounding, +rounding), rounding, 9, 11);
display_draw_list->PathStroke(overline_col, 0, style.TabBarOverlineSize);
}
else
{
display_draw_list->AddLine(tl - ImVec2(0.5f, 0.5f), tr - ImVec2(0.5f, 0.5f), overline_col, style.TabBarOverlineSize);
}
}
RenderNavCursor(bb, id);
// Select with right mouse button. This is so the common idiom for context menu automatically highlight the current widget.
const bool hovered_unblocked = IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup);
if (tab_bar->SelectedTabId != tab->ID && hovered_unblocked && (IsMouseClicked(1) || IsMouseReleased(1)) && !is_tab_button)
TabBarQueueFocus(tab_bar, tab);
// Select with right mouse button. This is so the common idiom for context menu automatically highlight the current widget.
const bool hovered_unblocked = IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup);
if (tab_bar->SelectedTabId != tab->ID && hovered_unblocked && (IsMouseClicked(1) || IsMouseReleased(1)) && !is_tab_button)
TabBarQueueFocus(tab_bar, tab);
if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)
flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)
flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
// Render tab label, process close button
const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, id) : 0;
bool just_closed;
bool text_clipped;
TabItemLabelAndCloseButton(display_draw_list, bb, tab_just_unsaved ? (flags & ~ImGuiTabItemFlags_UnsavedDocument) : flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped);
if (just_closed && p_open != NULL)
{
*p_open = false;
TabBarCloseTab(tab_bar, tab);
// Render tab label, process close button
const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, id) : 0;
bool just_closed;
bool text_clipped;
TabItemLabelAndCloseButton(display_draw_list, bb, tab_just_unsaved ? (flags & ~ImGuiTabItemFlags_UnsavedDocument) : flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped);
if (just_closed && p_open != NULL)
{
*p_open = false;
TabBarCloseTab(tab_bar, tab);
}
// Tooltip
// (Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer-> seems ok)
// (We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar, which g.HoveredId ignores)
// FIXME: This is a mess.
// FIXME: We may want disabled tab to still display the tooltip?
if (text_clipped && g.HoveredId == id && !held)
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
}
// Restore main window position so user can draw there
@@ -10182,15 +10246,6 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
PopClipRect();
window->DC.CursorPos = backup_main_cursor_pos;
// Tooltip
// (Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer-> seems ok)
// (We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar, which g.HoveredId ignores)
// FIXME: This is a mess.
// FIXME: We may want disabled tab to still display the tooltip?
if (text_clipped && g.HoveredId == id && !held)
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected
if (is_tab_button)
return pressed;

File diff suppressed because it is too large Load Diff

View File

@@ -446,7 +446,6 @@
03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
03000000091200004488000000000000,MUSIA PlayStation 2 Input Display,a:b0,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:b11,rightx:a2,righty:a3,start:b5,x:b1,y:b3,platform:Windows,
03000000f70600000100000000000000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Windows,
030000006f0e00001311000000000000,N64 Controller,+rightx:b10,+righty:b3,-rightx:b0,-righty:b11,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,platform:Windows,
030000006b140000010c000000000000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000006b1400001106000000000000,Nacon Revolution 3 PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
0300000085320000170d000000000000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
@@ -481,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,
@@ -637,6 +637,7 @@
030000000d0f0000ad00000000000000,RX Gamepad,a:b0,b:b4,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,rightshoulder:b6,start:b9,x:b2,y:b1,platform:Windows,
030000008916000000fe000000000000,Sabertooth,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,
03000000c6240000045d000000000000,Sabertooth,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,
030000006f0e00001311000000000000,Saffun Controller,a:b2,b:b3,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:b1,y:b0,platform:Windows,
03000000a30600001af5000000000000,Saitek Cyborg,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:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000a306000023f6000000000000,Saitek Cyborg,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:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000300f00001201000000000000,Saitek Dual Analog,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform: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,
@@ -1441,7 +1443,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000f70600000100000000010000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Linux,
030000006f0e00001311000011010000,N64 Controller,+rightx:b10,+righty:b3,-rightx:b0,-righty:b11,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,platform:Linux,
030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006b140000010c000010010000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -1497,11 +1498,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e00000901000011010000,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:Linux,
030000006f0e00002f01000011010000,PDP Wired 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:Linux,
03000000ad1b000004f9000000010000,PDP Xbox 360 Versus Fighting,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000f102000000000000,PDP Xbox Atomic,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,
030000006f0e0000a802000023020000,PDP Xbox One Controller,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:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000006f0e0000a702000023020000,PDP Xbox One Raven Black,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,
030000006f0e0000d802000006640000,PDP Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000ef02000007640000,PDP Xbox Series Kinetic Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000f102000000000000,PDP Xbox Atomic,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000000540000001010000,PowerA Advantage Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -1520,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,
@@ -1611,6 +1613,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e00001e01000011010000,Rock Candy 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:Linux,
03000000c6240000fefa000000010000,Rock Candy Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,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,
030000006f0e00001311000011010000,Saffun Controller,a:b2,b:b3,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:b1,y:b0,platform:Linux,
03000000a306000023f6000011010000,Saitek Cyborg PlayStation 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:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,
03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 91 KiB

View File

@@ -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);

View File

@@ -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

View File

@@ -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)

View File

@@ -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")

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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

View File

@@ -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__

View File

@@ -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);

View File

@@ -119,6 +119,12 @@ namespace x86Emitter
xImplSimd_DestRegSSE VPD;
};
struct xImplSimd_PBlend
{
xImplSimd_DestRegImmSSE W;
xImplSimd_DestRegSSE VB;
};
// --------------------------------------------------------------------------------------
// xImplSimd_PMove
// --------------------------------------------------------------------------------------

View File

@@ -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;

View File

@@ -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};

View File

@@ -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" />

View File

@@ -169,11 +169,25 @@ void Host::SetDefaultUISettings(SettingsInterface& si)
// nothing
}
bool Host::LocaleCircleConfirm()
{
// not running any UI, so no settings requests will come in
return false;
}
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 +260,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 +457,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 +488,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 +509,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 +524,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 +647,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 +760,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())
{

View File

@@ -212,7 +212,7 @@
</size>
</property>
<property name="text">
<string>1</string>
<string>4</string>
</property>
</widget>
</item>

View File

@@ -40,6 +40,7 @@ MemorySearchWidget::MemorySearchWidget(QWidget* parent)
connect(m_ui.listSearchResults->verticalScrollBar(), &QScrollBar::valueChanged, this, &MemorySearchWidget::onSearchResultsListScroll);
connect(m_ui.listSearchResults, &QListView::customContextMenuRequested, this, &MemorySearchWidget::onListSearchResultsContextMenu);
connect(m_ui.cmbSearchType, &QComboBox::currentIndexChanged, this, &MemorySearchWidget::onSearchTypeChanged);
connect(m_ui.cmbSearchComparison, &QComboBox::currentIndexChanged, this, &MemorySearchWidget::onSearchComparisonChanged);
// Ensures we don't retrigger the load results function unintentionally
m_resultsLoadTimer.setInterval(100);
@@ -249,7 +250,6 @@ bool handleSearchComparison(SearchComparison searchComparison, u32 searchAddress
}
case SearchComparison::IncreasedBy:
{
const T priorValue = priorResult->getValue<T>();
const T expectedIncrease = searchValue + priorValue;
return memoryValueComparator(SearchComparison::Equals, readValue, expectedIncrease);
@@ -282,6 +282,10 @@ bool handleSearchComparison(SearchComparison searchComparison, u32 searchAddress
const T expectedDecrease = priorValue - searchValue;
return memoryValueComparator(SearchComparison::Equals, readValue, expectedIncrease) || memoryValueComparator(SearchComparison::Equals, readValue, expectedDecrease);
}
case SearchComparison::UnknownValue:
{
return true;
}
default:
Console.Error("Debugger: Unknown type when doing memory search!");
return false;
@@ -449,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());
@@ -506,63 +510,69 @@ void MemorySearchWidget::onSearchButtonClicked()
const bool isFilterSearch = sender() == m_ui.btnFilterSearch;
unsigned long long value;
switch (searchType)
if(searchComparison != SearchComparison::UnknownValue)
{
case SearchType::ByteType:
case SearchType::Int16Type:
case SearchType::Int32Type:
case SearchType::Int64Type:
value = searchValue.toULongLong(&ok, searchHex ? 16 : 10);
break;
case SearchType::FloatType:
case SearchType::DoubleType:
searchValue.toDouble(&ok);
break;
case SearchType::StringType:
ok = !searchValue.isEmpty();
break;
case SearchType::ArrayType:
ok = !searchValue.trimmed().isEmpty();
break;
}
if(doesSearchComparisonTakeInput(searchComparison))
{
switch (searchType)
{
case SearchType::ByteType:
case SearchType::Int16Type:
case SearchType::Int32Type:
case SearchType::Int64Type:
value = searchValue.toULongLong(&ok, searchHex ? 16 : 10);
break;
case SearchType::FloatType:
case SearchType::DoubleType:
searchValue.toDouble(&ok);
break;
case SearchType::StringType:
ok = !searchValue.isEmpty();
break;
case SearchType::ArrayType:
ok = !searchValue.trimmed().isEmpty();
break;
}
if (!ok)
{
QMessageBox::critical(this, tr("Debugger"), tr("Invalid search value"));
return;
}
if (!ok)
{
QMessageBox::critical(this, tr("Debugger"), tr("Invalid search value"));
return;
}
switch (searchType)
{
case SearchType::ArrayType:
case SearchType::StringType:
case SearchType::DoubleType:
case SearchType::FloatType:
break;
case SearchType::Int64Type:
if (value <= std::numeric_limits<unsigned long long>::max())
break;
case SearchType::Int32Type:
if (value <= std::numeric_limits<unsigned long>::max())
break;
case SearchType::Int16Type:
if (value <= std::numeric_limits<unsigned short>::max())
break;
case SearchType::ByteType:
if (value <= std::numeric_limits<unsigned char>::max())
break;
default:
QMessageBox::critical(this, tr("Debugger"), tr("Value is larger than type"));
switch (searchType)
{
case SearchType::ArrayType:
case SearchType::StringType:
case SearchType::DoubleType:
case SearchType::FloatType:
break;
case SearchType::Int64Type:
if (value <= std::numeric_limits<unsigned long long>::max())
break;
case SearchType::Int32Type:
if (value <= std::numeric_limits<unsigned long>::max())
break;
case SearchType::Int16Type:
if (value <= std::numeric_limits<unsigned short>::max())
break;
case SearchType::ByteType:
if (value <= std::numeric_limits<unsigned char>::max())
break;
default:
QMessageBox::critical(this, tr("Debugger"), tr("Value is larger than type"));
return;
}
}
if (!isFilterSearch && (searchComparison == SearchComparison::Changed || searchComparison == SearchComparison::ChangedBy
|| searchComparison == SearchComparison::Decreased || searchComparison == SearchComparison::DecreasedBy
|| searchComparison == SearchComparison::Increased || searchComparison == SearchComparison::IncreasedBy
|| searchComparison == SearchComparison::NotChanged))
{
QMessageBox::critical(this, tr("Debugger"), tr("This search comparison can only be used with filter searches."));
return;
}
if (!isFilterSearch && (searchComparison == SearchComparison::Changed || searchComparison == SearchComparison::ChangedBy
|| searchComparison == SearchComparison::Decreased || searchComparison == SearchComparison::DecreasedBy
|| searchComparison == SearchComparison::Increased || searchComparison == SearchComparison::IncreasedBy
|| searchComparison == SearchComparison::NotChanged))
{
QMessageBox::critical(this, tr("Debugger"), tr("This search comparison can only be used with filter searches."));
return;
}
}
QFutureWatcher<std::vector<SearchResult>>* workerWatcher = new QFutureWatcher<std::vector<SearchResult>>();
@@ -637,6 +647,23 @@ SearchComparison MemorySearchWidget::getCurrentSearchComparison()
return m_searchComparisonLabelMap.labelToEnum(m_ui.cmbSearchComparison->currentText());
}
bool MemorySearchWidget::doesSearchComparisonTakeInput(const SearchComparison comparison)
{
switch (comparison) {
case SearchComparison::Equals:
case SearchComparison::NotEquals:
case SearchComparison::GreaterThan:
case SearchComparison::GreaterThanOrEqual:
case SearchComparison::LessThan:
case SearchComparison::LessThanOrEqual:
case SearchComparison::IncreasedBy:
case SearchComparison::DecreasedBy:
return true;
default:
return false;
}
}
void MemorySearchWidget::onSearchTypeChanged(int newIndex)
{
if (newIndex < 4)
@@ -654,6 +681,11 @@ void MemorySearchWidget::onSearchTypeChanged(int newIndex)
updateSearchComparisonSelections();
}
void MemorySearchWidget::onSearchComparisonChanged(int newValue)
{
m_ui.txtSearchValue->setEnabled(getCurrentSearchComparison() != SearchComparison::UnknownValue);
}
void MemorySearchWidget::updateSearchComparisonSelections()
{
const QString selectedComparisonLabel = m_ui.cmbSearchComparison->currentText();
@@ -704,5 +736,11 @@ std::vector<SearchComparison> MemorySearchWidget::getValidSearchComparisonsForSt
comparisons.push_back(SearchComparison::ChangedBy);
comparisons.push_back(SearchComparison::NotChanged);
}
if(!hasResults)
{
comparisons.push_back(SearchComparison::UnknownValue);
}
return comparisons;
}

View File

@@ -48,6 +48,7 @@ public:
Changed,
ChangedBy,
NotChanged,
UnknownValue,
Invalid
};
@@ -69,6 +70,7 @@ public:
insert(SearchComparison::Changed, tr("Changed"));
insert(SearchComparison::ChangedBy, tr("Changed By"));
insert(SearchComparison::NotChanged, tr("Not Changed"));
insert(SearchComparison::UnknownValue, tr("Unknown Initial Value"));
insert(SearchComparison::Invalid, "");
}
SearchComparison labelToEnum(QString comparisonLabel)
@@ -120,6 +122,7 @@ public slots:
void onSearchButtonClicked();
void onSearchResultsListScroll(u32 value);
void onSearchTypeChanged(int newIndex);
void onSearchComparisonChanged(int newIndex);
void loadSearchResults();
void contextSearchResultGoToDisassembly();
void contextRemoveSearchResult();
@@ -146,4 +149,5 @@ private:
std::vector<SearchComparison> getValidSearchComparisonsForState(SearchType type, std::vector<SearchResult> &existingResults);
SearchType getCurrentSearchType();
SearchComparison getCurrentSearchComparison();
bool doesSearchComparisonTakeInput(SearchComparison comparison);
};

View File

@@ -148,6 +148,11 @@
<string>Less Than Or Equal</string>
</property>
</item>
<item>
<property name="text">
<string>Unknown Initial Value</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">

View File

@@ -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();

View File

@@ -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();

View File

@@ -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())
@@ -2040,6 +2052,7 @@ void QtHost::PrintCommandLineHelp(const std::string_view progname)
std::fprintf(stderr, " -version: Displays version information and exits.\n");
std::fprintf(stderr, " -batch: Enables batch mode (exits after shutting down).\n");
std::fprintf(stderr, " -nogui: Hides main window while running (implies batch mode).\n");
std::fprintf(stderr, " -portable: Force enable portable mode to store data in local PCSX2 path instead of the default configuration path.\n");
std::fprintf(stderr, " -elf <file>: Overrides the boot ELF with the specified filename.\n");
std::fprintf(stderr, " -gameargs <string>: passes the specified quoted space-delimited string of launch arguments.\n");
std::fprintf(stderr, " -disc <path>: Uses the specified host DVD drive as a source.\n");
@@ -2111,6 +2124,11 @@ bool QtHost::ParseCommandLineOptions(const QStringList& args, std::shared_ptr<VM
s_nogui_mode = true;
continue;
}
else if (CHECK_ARG(QStringLiteral("-portable")))
{
EmuConfig.IsPortableMode = true;
continue;
}
else if (CHECK_ARG(QStringLiteral("-fastboot")))
{
AutoBoot(autoboot)->fast_boot = true;

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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>

View File

@@ -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>

View File

@@ -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 (size_t 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();
}

View File

@@ -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;

View File

@@ -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 (size_t 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)

View File

@@ -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;

View File

@@ -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."));

View File

@@ -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">

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -97,6 +97,7 @@ private:
void createCard();
QString getSelectedCard() const;
bool isSelectedCardFormatted() const;
void updateCardActions();
void deleteCard();
void renameCard();

View File

@@ -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.

View File

@@ -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 {

File diff suppressed because it is too large Load Diff

View File

@@ -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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -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)

View File

@@ -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

View File

@@ -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
@@ -1328,6 +1338,7 @@ struct Pcsx2Config
std::string CurrentIRX;
std::string CurrentGameArgs;
AspectRatioType CurrentAspectRatio = AspectRatioType::RAuto4_3_3_2;
bool IsPortableMode = false;
Pcsx2Config();
void LoadSave(SettingsWrapper& wrap);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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|

View File

@@ -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`)

View File

@@ -237,7 +237,7 @@
"halfPixelOffset": {
"type": "integer",
"minimum": 0,
"maximum": 4
"maximum": 5
},
"nativeScaling": {
"type": "integer",

View File

@@ -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"

View File

@@ -87,7 +87,6 @@ public:
fprintf(fp, "SCANMSK\n"
"\tMSK:%u\n\n"
"\n"
, SCANMSK.MSK);
fprintf(fp, "TEXA\n"

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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:

View File

@@ -154,14 +154,66 @@ bool GSHwHack::GSC_SFEX3(GSRendererHW& r, int& skip)
return true;
}
bool GSHwHack::GSC_DTGames(GSRendererHW& r, int& skip)
{
if (skip == 0)
{
// The game does a shuffle based on the result of a copy from the depth buffer, which ends up looking bizzare so PCSX2 doesn't know how to deal with it.
// What they're actually doing is copying the red/green channel of the result (kind of a shadow stencil) to the alpha channel.
// The further problem to this is the limitation of alpha we can save on an RT as they copy in 255, so I can cheese it here pretending it's RTA'd
if (RTME && RFPSM == PSMCT32 && RTBP0 == RFBP && RTPSM == PSMCT16 && RTEST.ATE && RTEST.ATST == ATST_NEVER && RTEST.AFAIL == AFAIL_FB_ONLY && RFBMSK == 0xFFFFFF)
{
GSTextureCache::Target* rt = g_texture_cache->LookupTarget(GIFRegTEX0::Create(RTBP0, RFBW, RFPSM),
GSVector2i(1, 1), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget);
if (!rt)
return false;
// Clear down the alpha first.
GSHWDrawConfig& clear = r.BeginHLEHardwareDraw(
rt->GetTexture(), nullptr, rt->GetScale(), nullptr, rt->GetScale(), rt->GetUnscaledRect());
clear.colormask.wrgba = 0;
clear.colormask.wa = 1;
r.EndHLEHardwareDraw(false);
// Shuffle the green channel in to alpha.
GSHWDrawConfig& config = r.BeginHLEHardwareDraw(
rt->GetTexture(), nullptr, rt->GetScale(), rt->GetTexture(), rt->GetScale(), rt->GetUnscaledRect());
config.ps.shuffle = 1;
config.ps.dst_fmt = GSLocalMemory::PSM_FMT_32;
config.ps.write_rg = 0;
config.ps.shuffle_same = 0;
config.ps.real16src = 0;
config.ps.shuffle_across = 1;
config.ps.process_rg = r.SHUFFLE_READ;
config.ps.process_ba = r.SHUFFLE_WRITE;
config.colormask.wrgba = 0;
config.colormask.wa = 1;
config.ps.rta_correction = 1;
config.ps.tfx = TFX_DECAL;
config.ps.tcc = true;
r.EndHLEHardwareDraw(true);
rt->m_alpha_min = 0;
rt->m_alpha_max = 255;
skip = 69;
}
}
else
{
if (RTPSM != PSMCT16)
skip = 0;
}
return true;
}
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.
@@ -1471,6 +1523,7 @@ const GSHwHack::Entry<GSRendererHW::GSC_Ptr> GSHwHack::s_get_skip_count_function
CRC_F(GSC_SakuraWarsSoLongMyLove),
CRC_F(GSC_Simple2000Vol114),
CRC_F(GSC_SFEX3),
CRC_F(GSC_DTGames),
CRC_F(GSC_TalesOfLegendia),
CRC_F(GSC_TalesofSymphonia),
CRC_F(GSC_UrbanReign),

View File

@@ -11,6 +11,7 @@ public:
static bool GSC_Manhunt2(GSRendererHW& r, int& skip);
static bool GSC_SacredBlaze(GSRendererHW& r, int& skip);
static bool GSC_SFEX3(GSRendererHW& r, int& skip);
static bool GSC_DTGames(GSRendererHW& r, int& skip);
static bool GSC_Tekken5(GSRendererHW& r, int& skip);
static bool GSC_BurnoutGames(GSRendererHW& r, int& skip);
static bool GSC_BlackAndBurnoutSky(GSRendererHW& r, int& skip);

View File

@@ -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;
}
@@ -554,7 +547,7 @@ void GSRendererHW::ConvertSpriteTextureShuffle(u32& process_rg, u32& process_ba,
}
else
{
if ((floor(m_vt.m_max.p.y) <= rt->m_valid.w) && ((floor(m_vt.m_max.p.x) > (m_cached_ctx.FRAME.FBW * 64)) || (rt->m_TEX0.TBW != m_cached_ctx.FRAME.FBW)))
if (((m_r.width() + 8) & ~(GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.x - 1)) != GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.x && (floor(m_vt.m_max.p.y) <= rt->m_valid.w) && ((floor(m_vt.m_max.p.x) > (m_cached_ctx.FRAME.FBW * 64)) || (rt->m_TEX0.TBW < m_cached_ctx.FRAME.FBW)))
{
half_bottom_vert = false;
half_bottom_uv = false;
@@ -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;
}
}
}
@@ -952,7 +1031,7 @@ GSVector2i GSRendererHW::GetValidSize(const GSTextureCache::Source* tex)
// Make sure sizes are within max limit of 2048,
// this shouldn't happen but if it does it needs to be addressed,
// clamp the size so at least it doesn't cause a crash.
constexpr int valid_max_size = 2048;
constexpr int valid_max_size = 2047;
if ((width > valid_max_size) || (height > valid_max_size))
{
Console.Warning("Warning: GetValidSize out of bounds, X:%d Y:%d", width, height);
@@ -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);

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -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));

View File

@@ -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()));

View File

@@ -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;

View File

@@ -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, ...);

View File

@@ -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);
}
}
}

View File

@@ -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");

View File

@@ -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

View File

@@ -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);
}
}

Some files were not shown because too many files have changed in this diff Show More