mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4654a3ef6c | ||
|
|
9996061f74 | ||
|
|
247a4c40d1 | ||
|
|
1ffbdd9c08 | ||
|
|
f67c0cbd2e | ||
|
|
ff7cc0867b | ||
|
|
ac1a6d3348 | ||
|
|
582bba6c91 | ||
|
|
aaf156478e | ||
|
|
0539c177ab | ||
|
|
fb1323b72f | ||
|
|
dc557dd0e5 | ||
|
|
2d0cfc9c2c | ||
|
|
625a25cd50 | ||
|
|
b8a29d1cd8 | ||
|
|
0fabdf9a01 | ||
|
|
9c3ae795c8 | ||
|
|
de26226fa1 | ||
|
|
121920c074 |
@@ -19,7 +19,7 @@ LIBJPEG=9f
|
||||
LIBPNG=1.6.45
|
||||
LIBWEBP=1.5.0
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
SDL=SDL2-2.30.12
|
||||
SDL=SDL3-3.2.6
|
||||
QT=6.8.2
|
||||
ZSTD=1.5.7
|
||||
|
||||
@@ -37,7 +37,7 @@ fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
ac356ea55e8b9dd0b2d1fa27da40ef7e238267ccf9324704850d5d47375b48ea $SDL.tar.gz
|
||||
096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
012043ce6d411e6e8a91fdc4e05e6bedcfa10fcb1347d3c33908f7fdd10dfe05 qtbase-everywhere-src-$QT.tar.xz
|
||||
d2a1bbb84707b8a0aec29227b170be00f04383fbf2361943596d09e7e443c8e1 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "sdl2",
|
||||
"name": "sdl3",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
@@ -14,8 +14,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://libsdl.org/release/SDL2-2.30.12.tar.gz",
|
||||
"sha256": "ac356ea55e8b9dd0b2d1fa27da40ef7e238267ccf9324704850d5d47375b48ea"
|
||||
"url": "https://libsdl.org/release/SDL3-3.2.6.tar.gz",
|
||||
"sha256": "096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
@@ -26,7 +26,7 @@
|
||||
],
|
||||
"modules": [
|
||||
"modules/10-libpcap.json",
|
||||
"modules/20-sdl2.json",
|
||||
"modules/20-sdl3.json",
|
||||
"modules/21-libbacktrace.json",
|
||||
"modules/22-shaderc.json",
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ fi
|
||||
|
||||
FREETYPE=2.13.3
|
||||
HARFBUZZ=10.0.1
|
||||
SDL=SDL2-2.30.12
|
||||
SDL=SDL3-3.2.6
|
||||
ZSTD=1.5.7
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
LIBPNG=1.6.45
|
||||
@@ -76,7 +76,7 @@ CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
|
||||
cat > SHASUMS <<EOF
|
||||
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
|
||||
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
|
||||
ac356ea55e8b9dd0b2d1fa27da40ef7e238267ccf9324704850d5d47375b48ea $SDL.tar.gz
|
||||
096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
|
||||
@@ -22,7 +22,7 @@ fi
|
||||
|
||||
FREETYPE=2.13.3
|
||||
HARFBUZZ=10.0.1
|
||||
SDL=SDL2-2.30.12
|
||||
SDL=SDL3-3.2.6
|
||||
ZSTD=1.5.7
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
LIBPNG=1.6.45
|
||||
@@ -56,7 +56,7 @@ CMAKE_COMMON=(
|
||||
cat > SHASUMS <<EOF
|
||||
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
|
||||
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
|
||||
ac356ea55e8b9dd0b2d1fa27da40ef7e238267ccf9324704850d5d47375b48ea $SDL.tar.gz
|
||||
096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
|
||||
@@ -49,7 +49,7 @@ set LIBPNG=1645
|
||||
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
set QT=6.8.2
|
||||
set QTMINOR=6.8
|
||||
set SDL=SDL2-2.30.12
|
||||
set SDL=SDL3-3.2.6
|
||||
set WEBP=1.5.0
|
||||
set ZLIB=1.3.1
|
||||
set ZLIBSHORT=131
|
||||
@@ -66,7 +66,7 @@ call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lp
|
||||
call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" aa2808d0f2dc6b383c6689bf6d166e2de62db4d58be989e4b052acb31df0fba3 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 665e5aa2a613affe099a38d61257ecc5ef4bf38b109d915147aa8b005399d68a || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
|
||||
@@ -179,7 +179,7 @@ cd "%SDL%" || goto error
|
||||
cmake -B build %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release %FORCEPDB% -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
copy build\SDL2.pdb "%INSTALLDIR%\bin" || goto error
|
||||
copy build\SDL3.pdb "%INSTALLDIR%\bin" || goto error
|
||||
cd .. || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
|
||||
@@ -47,7 +47,7 @@ set LIBPNG=1645
|
||||
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
set QT=6.8.2
|
||||
set QTMINOR=6.8
|
||||
set SDL=SDL2-2.30.12
|
||||
set SDL=SDL3-3.2.6
|
||||
set WEBP=1.5.0
|
||||
set ZLIB=1.3.1
|
||||
set ZLIBSHORT=131
|
||||
@@ -64,7 +64,7 @@ call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lp
|
||||
call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" aa2808d0f2dc6b383c6689bf6d166e2de62db4d58be989e4b052acb31df0fba3 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 665e5aa2a613affe099a38d61257ecc5ef4bf38b109d915147aa8b005399d68a || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
|
||||
@@ -176,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 (
|
||||
|
||||
@@ -479,8 +479,8 @@
|
||||
030000008916000001fd000000000000,Onza CE,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:a3,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||
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,
|
||||
0300000009120000072f000000000000,OrangeFox86 DreamPicoPort,a:b0,b:b1,x:b3,y:b4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,dpdown:h0.4,leftx:a0,lefty:a1,lefttrigger:-a2,righttrigger:-a5,start:b11,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,
|
||||
@@ -1000,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,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,
|
||||
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,
|
||||
@@ -1072,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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -119,6 +119,12 @@ namespace x86Emitter
|
||||
xImplSimd_DestRegSSE VPD;
|
||||
};
|
||||
|
||||
struct xImplSimd_PBlend
|
||||
{
|
||||
xImplSimd_DestRegImmSSE W;
|
||||
xImplSimd_DestRegSSE VB;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xImplSimd_PMove
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
@@ -500,6 +500,7 @@ namespace x86Emitter
|
||||
extern const xImplSimd_MovHL_RtoR xMOVLH;
|
||||
extern const xImplSimd_MovHL_RtoR xMOVHL;
|
||||
|
||||
extern const xImplSimd_PBlend xPBLEND;
|
||||
extern const xImplSimd_Blend xBLEND;
|
||||
extern const xImplSimd_PMove xPMOVSX;
|
||||
extern const xImplSimd_PMove xPMOVZX;
|
||||
|
||||
@@ -556,12 +556,18 @@ namespace x86Emitter
|
||||
const xImplSimd_MovHL_RtoR xMOVLH = {0x16};
|
||||
const xImplSimd_MovHL_RtoR xMOVHL = {0x12};
|
||||
|
||||
const xImplSimd_PBlend xPBLEND =
|
||||
{
|
||||
{0x66, 0x0e3a}, // W
|
||||
{0x66, 0x1038}, // VB
|
||||
};
|
||||
|
||||
const xImplSimd_Blend xBLEND =
|
||||
{
|
||||
{0x66, 0x0c3a}, // PS
|
||||
{0x66, 0x0d3a}, // PD
|
||||
{0x66, 0x1438}, // VPS
|
||||
{0x66, 0x1538}, // VPD
|
||||
{
|
||||
{0x66, 0x0c3a}, // PS
|
||||
{0x66, 0x0d3a}, // PD
|
||||
{0x66, 0x1438}, // VPS
|
||||
{0x66, 0x1538}, // VPD
|
||||
};
|
||||
|
||||
const xImplSimd_PMove xPMOVSX = {0x2038};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL2.lib;zlib.lib;zstd.lib</AdditionalDependencies>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL3.lib;zlib.lib;zstd.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
@@ -15,7 +15,7 @@
|
||||
<DepsDLLs Include="$(DepsBinDir)libsharpyuv.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)libwebp.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)lz4.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)SDL2.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)SDL3.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)shaderc_shared.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)zlib1.dll" />
|
||||
<DepsDLLs Include="$(DepsBinDir)zstd.dll" />
|
||||
|
||||
@@ -174,6 +174,14 @@ std::unique_ptr<ProgressCallback> Host::CreateHostProgressCallback()
|
||||
return ProgressCallback::CreateNullProgressCallback();
|
||||
}
|
||||
|
||||
void Host::ReportInfoAsync(const std::string_view title, const std::string_view message)
|
||||
{
|
||||
if (!title.empty() && !message.empty())
|
||||
INFO_LOG("ReportInfoAsync: {}: {}", title, message);
|
||||
else if (!message.empty())
|
||||
INFO_LOG("ReportInfoAsync: {}", message);
|
||||
}
|
||||
|
||||
void Host::ReportErrorAsync(const std::string_view title, const std::string_view message)
|
||||
{
|
||||
if (!title.empty() && !message.empty())
|
||||
|
||||
@@ -1221,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);
|
||||
|
||||
@@ -109,6 +109,7 @@ 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);
|
||||
|
||||
@@ -1612,6 +1612,18 @@ bool QtHost::DownloadFile(QWidget* parent, const QString& title, std::string url
|
||||
return true;
|
||||
}
|
||||
|
||||
void Host::ReportInfoAsync(const std::string_view title, const std::string_view message)
|
||||
{
|
||||
if (!title.empty() && !message.empty())
|
||||
INFO_LOG("ReportInfoAsync: {}: {}", title, message);
|
||||
else if (!message.empty())
|
||||
INFO_LOG("ReportInfoAsync: {}", message);
|
||||
|
||||
QMetaObject::invokeMethod(g_main_window, "reportInfo", Qt::QueuedConnection,
|
||||
Q_ARG(const QString&, title.empty() ? QString() : QString::fromUtf8(title.data(), title.size())),
|
||||
Q_ARG(const QString&, message.empty() ? QString() : QString::fromUtf8(message.data(), message.size())));
|
||||
}
|
||||
|
||||
void Host::ReportErrorAsync(const std::string_view title, const std::string_view message)
|
||||
{
|
||||
if (!title.empty() && !message.empty())
|
||||
|
||||
@@ -19,7 +19,7 @@ ControllerGlobalSettingsWidget::ControllerGlobalSettingsWidget(QWidget* parent,
|
||||
SettingsInterface* sif = dialog->getProfileSettingsInterface();
|
||||
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLSource, "InputSources", "SDL", true);
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLEnhancedMode, "InputSources", "SDLControllerEnhancedMode", false);
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLEnhancedMode, "InputSources", "SDLControllerEnhancedMode", true);
|
||||
connect(m_ui.enableSDLSource, &QCheckBox::checkStateChanged, this, &ControllerGlobalSettingsWidget::updateSDLOptionsEnabled);
|
||||
connect(m_ui.ledSettings, &QToolButton::clicked, this, &ControllerGlobalSettingsWidget::ledSettingsClicked);
|
||||
|
||||
@@ -146,7 +146,7 @@ ControllerLEDSettingsDialog::ControllerLEDSettingsDialog(QWidget* parent, Contro
|
||||
|
||||
SettingsInterface* sif = dialog->getProfileSettingsInterface();
|
||||
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLPS5PlayerLED, "InputSources", "SDLPS5PlayerLED", false);
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLPS5PlayerLED, "InputSources", "SDLPS5PlayerLED", true);
|
||||
connect(m_ui.buttonBox->button(QDialogButtonBox::Close), &QPushButton::clicked, this, &QDialog::accept);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
#include <bit>
|
||||
|
||||
InputBindingDialog::InputBindingDialog(SettingsInterface* sif, InputBindingInfo::Type bind_type, std::string section_name,
|
||||
std::string key_name, std::vector<std::string> bindings, QWidget* parent)
|
||||
std::string key_name, std::vector<std::string> bindings_settings, std::vector<std::string> bindings_ui, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_sif(sif)
|
||||
, m_bind_type(bind_type)
|
||||
, m_section_name(std::move(section_name))
|
||||
, m_key_name(std::move(key_name))
|
||||
, m_bindings(std::move(bindings))
|
||||
, m_bindings_settings(std::move(bindings_settings))
|
||||
, m_bindings_ui(std::move(bindings_ui))
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
m_ui.title->setText(tr("Bindings for %1 %2").arg(QString::fromStdString(m_section_name)).arg(QString::fromStdString(m_key_name)));
|
||||
@@ -32,6 +33,8 @@ InputBindingDialog::InputBindingDialog(SettingsInterface* sif, InputBindingInfo:
|
||||
connect(m_ui.removeBinding, &QPushButton::clicked, this, &InputBindingDialog::onRemoveBindingButtonClicked);
|
||||
connect(m_ui.clearBindings, &QPushButton::clicked, this, &InputBindingDialog::onClearBindingsButtonClicked);
|
||||
connect(m_ui.buttonBox, &QDialogButtonBox::rejected, [this]() { done(0); });
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceConnected, this, &InputBindingDialog::onInputDeviceConnected);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceDisconnected, this, &InputBindingDialog::onInputDeviceDisconnected);
|
||||
updateList();
|
||||
|
||||
// Only show the sensitivity controls for binds where it's applicable.
|
||||
@@ -210,11 +213,17 @@ void InputBindingDialog::addNewBinding()
|
||||
const std::string new_binding(InputManager::ConvertInputBindingKeysToString(m_bind_type, m_new_bindings.data(), m_new_bindings.size()));
|
||||
if (!new_binding.empty())
|
||||
{
|
||||
if (std::find(m_bindings.begin(), m_bindings.end(), new_binding) != m_bindings.end())
|
||||
if (std::find(m_bindings_settings.begin(), m_bindings_settings.end(), new_binding) != m_bindings_settings.end())
|
||||
return;
|
||||
|
||||
m_ui.bindingList->addItem(QString::fromStdString(new_binding));
|
||||
m_bindings.push_back(std::move(new_binding));
|
||||
m_bindings_settings.push_back(std::move(new_binding));
|
||||
|
||||
SmallString new_binding_temp{std::string_view{new_binding}};
|
||||
InputManager::PrettifyInputBinding(new_binding_temp, false);
|
||||
std::string new_binding_ui{new_binding_temp};
|
||||
|
||||
m_bindings_ui.push_back(new_binding_ui);
|
||||
m_ui.bindingList->addItem(QString::fromStdString(new_binding_ui));
|
||||
saveListToSettings();
|
||||
}
|
||||
}
|
||||
@@ -230,17 +239,19 @@ void InputBindingDialog::onAddBindingButtonClicked()
|
||||
void InputBindingDialog::onRemoveBindingButtonClicked()
|
||||
{
|
||||
const int row = m_ui.bindingList->currentRow();
|
||||
if (row < 0 || static_cast<size_t>(row) >= m_bindings.size())
|
||||
if (row < 0 || static_cast<size_t>(row) >= m_bindings_ui.size())
|
||||
return;
|
||||
|
||||
m_bindings.erase(m_bindings.begin() + row);
|
||||
m_bindings_settings.erase(m_bindings_settings.begin() + row);
|
||||
m_bindings_ui.erase(m_bindings_ui.begin() + row);
|
||||
delete m_ui.bindingList->takeItem(row);
|
||||
saveListToSettings();
|
||||
}
|
||||
|
||||
void InputBindingDialog::onClearBindingsButtonClicked()
|
||||
{
|
||||
m_bindings.clear();
|
||||
m_bindings_settings.clear();
|
||||
m_bindings_ui.clear();
|
||||
m_ui.bindingList->clear();
|
||||
saveListToSettings();
|
||||
}
|
||||
@@ -248,7 +259,7 @@ void InputBindingDialog::onClearBindingsButtonClicked()
|
||||
void InputBindingDialog::updateList()
|
||||
{
|
||||
m_ui.bindingList->clear();
|
||||
for (const std::string& binding : m_bindings)
|
||||
for (const std::string& binding : m_bindings_ui)
|
||||
m_ui.bindingList->addItem(QString::fromStdString(binding));
|
||||
}
|
||||
|
||||
@@ -256,8 +267,8 @@ void InputBindingDialog::saveListToSettings()
|
||||
{
|
||||
if (m_sif)
|
||||
{
|
||||
if (!m_bindings.empty())
|
||||
m_sif->SetStringList(m_section_name.c_str(), m_key_name.c_str(), m_bindings);
|
||||
if (!m_bindings_settings.empty())
|
||||
m_sif->SetStringList(m_section_name.c_str(), m_key_name.c_str(), m_bindings_settings);
|
||||
else
|
||||
m_sif->DeleteValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
m_sif->Save();
|
||||
@@ -265,8 +276,8 @@ void InputBindingDialog::saveListToSettings()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_bindings.empty())
|
||||
Host::SetBaseStringListSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_bindings);
|
||||
if (!m_bindings_settings.empty())
|
||||
Host::SetBaseStringListSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_bindings_settings);
|
||||
else
|
||||
Host::RemoveBaseSettingValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
Host::CommitBaseSettingChanges();
|
||||
@@ -337,6 +348,16 @@ void InputBindingDialog::onDeadzoneChanged(int value)
|
||||
m_ui.deadzoneValue->setText(tr("%1%").arg(value));
|
||||
}
|
||||
|
||||
void InputBindingDialog::onInputDeviceConnected(const QString& identifier, const QString& device_name)
|
||||
{
|
||||
ReloadBindNames();
|
||||
}
|
||||
|
||||
void InputBindingDialog::onInputDeviceDisconnected(const QString& identifier)
|
||||
{
|
||||
ReloadBindNames();
|
||||
}
|
||||
|
||||
void InputBindingDialog::hookInputManager()
|
||||
{
|
||||
InputManager::SetHook([this](InputBindingKey key, float value) {
|
||||
@@ -349,3 +370,17 @@ void InputBindingDialog::unhookInputManager()
|
||||
{
|
||||
InputManager::RemoveHook();
|
||||
}
|
||||
|
||||
void InputBindingDialog::ReloadBindNames()
|
||||
{
|
||||
m_bindings_ui.clear();
|
||||
m_bindings_ui.reserve(m_bindings_settings.size());
|
||||
for (int i = 0; i < m_bindings_settings.size(); i++)
|
||||
{
|
||||
SmallString binding{std::string_view{m_bindings_settings[i]}};
|
||||
InputManager::PrettifyInputBinding(binding, false);
|
||||
m_bindings_ui.push_back(std::string{binding});
|
||||
}
|
||||
|
||||
updateList();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class InputBindingDialog : public QDialog
|
||||
|
||||
public:
|
||||
InputBindingDialog(SettingsInterface* sif, InputBindingInfo::Type bind_type, std::string section_name, std::string key_name,
|
||||
std::vector<std::string> bindings, QWidget* parent);
|
||||
std::vector<std::string> bindings_settings, std::vector<std::string> bindings_ui, QWidget* parent);
|
||||
~InputBindingDialog();
|
||||
|
||||
protected Q_SLOTS:
|
||||
@@ -35,6 +35,9 @@ protected Q_SLOTS:
|
||||
void onSensitivityChanged(int value);
|
||||
void onDeadzoneChanged(int value);
|
||||
|
||||
void onInputDeviceConnected(const QString& identifier, const QString& device_name);
|
||||
void onInputDeviceDisconnected(const QString& identifier);
|
||||
|
||||
protected:
|
||||
enum : u32
|
||||
{
|
||||
@@ -55,13 +58,16 @@ protected:
|
||||
void hookInputManager();
|
||||
void unhookInputManager();
|
||||
|
||||
void ReloadBindNames();
|
||||
|
||||
Ui::InputBindingDialog m_ui;
|
||||
|
||||
SettingsInterface* m_sif;
|
||||
InputBindingInfo::Type m_bind_type;
|
||||
std::string m_section_name;
|
||||
std::string m_key_name;
|
||||
std::vector<std::string> m_bindings;
|
||||
std::vector<std::string> m_bindings_settings;
|
||||
std::vector<std::string> m_bindings_ui;
|
||||
std::vector<InputBindingKey> m_new_bindings;
|
||||
std::vector<std::pair<InputBindingKey, std::pair<float, float>>> m_value_ranges;
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ InputBindingWidget::InputBindingWidget(QWidget* parent)
|
||||
: QPushButton(parent)
|
||||
{
|
||||
connect(this, &QPushButton::clicked, this, &InputBindingWidget::onClicked);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceConnected, this, &InputBindingWidget::onInputDeviceConnected);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceDisconnected, this, &InputBindingWidget::onInputDeviceDisconnected);
|
||||
}
|
||||
|
||||
InputBindingWidget::InputBindingWidget(
|
||||
@@ -33,6 +35,8 @@ InputBindingWidget::InputBindingWidget(
|
||||
setMaximumWidth(225);
|
||||
|
||||
connect(this, &QPushButton::clicked, this, &InputBindingWidget::onClicked);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceConnected, this, &InputBindingWidget::onInputDeviceConnected);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceDisconnected, this, &InputBindingWidget::onInputDeviceDisconnected);
|
||||
|
||||
initialize(sif, bind_type, std::move(section_name), std::move(key_name));
|
||||
}
|
||||
@@ -62,20 +66,20 @@ void InputBindingWidget::updateText()
|
||||
const QString binding_tip(tr("\n\nLeft click to assign a new button\nShift + left click for additional bindings"));
|
||||
const QString binding_clear_tip(tr("\nRight click to clear binding"));
|
||||
|
||||
if (m_bindings.empty())
|
||||
if (m_bindings_ui.empty())
|
||||
{
|
||||
setText(QString());
|
||||
|
||||
setToolTip(tr("No bindings registered") + binding_tip);
|
||||
}
|
||||
else if (m_bindings.size() > 1)
|
||||
else if (m_bindings_ui.size() > 1)
|
||||
{
|
||||
setText(tr("%n bindings", "", static_cast<int>(m_bindings.size())));
|
||||
setText(tr("%n bindings", "", static_cast<int>(m_bindings_ui.size())));
|
||||
|
||||
// keep the full thing for the tooltip
|
||||
std::stringstream ss;
|
||||
bool first = true;
|
||||
for (const std::string& binding : m_bindings)
|
||||
for (const std::string& binding : m_bindings_ui)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
@@ -87,7 +91,7 @@ void InputBindingWidget::updateText()
|
||||
}
|
||||
else
|
||||
{
|
||||
QString binding_text(QString::fromStdString(m_bindings[0]));
|
||||
QString binding_text(QString::fromStdString(m_bindings_ui[0]));
|
||||
setToolTip(binding_text + binding_tip + binding_clear_tip);
|
||||
|
||||
// fix up accelerators, and if it's too long, ellipsise it
|
||||
@@ -232,13 +236,12 @@ void InputBindingWidget::setNewBinding()
|
||||
}
|
||||
}
|
||||
|
||||
m_bindings.clear();
|
||||
m_bindings.push_back(std::move(new_binding));
|
||||
m_bindings_ui.clear();
|
||||
m_bindings_ui.push_back(std::move(new_binding));
|
||||
}
|
||||
|
||||
void InputBindingWidget::clearBinding()
|
||||
{
|
||||
m_bindings.clear();
|
||||
if (m_sif)
|
||||
{
|
||||
m_sif->DeleteValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
@@ -256,14 +259,24 @@ void InputBindingWidget::clearBinding()
|
||||
|
||||
void InputBindingWidget::reloadBinding()
|
||||
{
|
||||
m_bindings = m_sif ? m_sif->GetStringList(m_section_name.c_str(), m_key_name.c_str()) :
|
||||
Host::GetBaseStringListSetting(m_section_name.c_str(), m_key_name.c_str());
|
||||
m_bindings_settings = m_sif ? m_sif->GetStringList(m_section_name.c_str(), m_key_name.c_str()) :
|
||||
Host::GetBaseStringListSetting(m_section_name.c_str(), m_key_name.c_str());
|
||||
|
||||
m_bindings_ui.clear();
|
||||
m_bindings_ui.reserve(m_bindings_settings.size());
|
||||
for (int i = 0; i < m_bindings_settings.size(); i++)
|
||||
{
|
||||
SmallString binding{std::string_view{m_bindings_settings[i]}};
|
||||
InputManager::PrettifyInputBinding(binding, false);
|
||||
m_bindings_ui.push_back(std::string{binding});
|
||||
}
|
||||
|
||||
updateText();
|
||||
}
|
||||
|
||||
void InputBindingWidget::onClicked()
|
||||
{
|
||||
if (m_bindings.size() > 1)
|
||||
if (m_bindings_ui.size() > 1)
|
||||
{
|
||||
openDialog();
|
||||
return;
|
||||
@@ -376,6 +389,16 @@ void InputBindingWidget::inputManagerHookCallback(InputBindingKey key, float val
|
||||
}
|
||||
}
|
||||
|
||||
void InputBindingWidget::onInputDeviceConnected(const QString& identifier, const QString& device_name)
|
||||
{
|
||||
reloadBinding();
|
||||
}
|
||||
|
||||
void InputBindingWidget::onInputDeviceDisconnected(const QString& identifier)
|
||||
{
|
||||
reloadBinding();
|
||||
}
|
||||
|
||||
void InputBindingWidget::hookInputManager()
|
||||
{
|
||||
InputManager::SetHook([this](InputBindingKey key, float value) {
|
||||
@@ -391,7 +414,7 @@ void InputBindingWidget::unhookInputManager()
|
||||
|
||||
void InputBindingWidget::openDialog()
|
||||
{
|
||||
InputBindingDialog binding_dialog(m_sif, m_bind_type, m_section_name, m_key_name, m_bindings, QtUtils::GetRootWidget(this));
|
||||
InputBindingDialog binding_dialog(m_sif, m_bind_type, m_section_name, m_key_name, m_bindings_settings, m_bindings_ui, QtUtils::GetRootWidget(this));
|
||||
binding_dialog.exec();
|
||||
reloadBinding();
|
||||
}
|
||||
@@ -422,6 +445,12 @@ void InputVibrationBindingWidget::setKey(ControllerSettingsWindow* dialog, std::
|
||||
m_section_name = std::move(section_name);
|
||||
m_key_name = std::move(key_name);
|
||||
m_binding = Host::GetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
|
||||
SmallString binding{std::string_view{m_binding}};
|
||||
|
||||
if (InputManager::PrettifyInputBinding(binding, false))
|
||||
m_binding = binding;
|
||||
|
||||
setText(QString::fromStdString(m_binding));
|
||||
}
|
||||
|
||||
@@ -440,12 +469,22 @@ void InputVibrationBindingWidget::onClicked()
|
||||
|
||||
const QString full_key(QStringLiteral("%1/%2").arg(QString::fromStdString(m_section_name)).arg(QString::fromStdString(m_key_name)));
|
||||
const QString current(QString::fromStdString(m_binding));
|
||||
QStringList input_options(m_dialog->getVibrationMotors());
|
||||
if (!current.isEmpty() && input_options.indexOf(current) < 0)
|
||||
QStringList input_setting_options(m_dialog->getVibrationMotors());
|
||||
QStringList input_ui_options;
|
||||
input_ui_options.reserve(input_setting_options.count());
|
||||
|
||||
for (QString motor : input_setting_options)
|
||||
{
|
||||
input_options.append(current);
|
||||
SmallStringBase motor_ui(motor.toStdString());
|
||||
InputManager::PrettifyInputBinding(motor_ui, false);
|
||||
input_ui_options.push_back(QString(motor_ui));
|
||||
}
|
||||
else if (input_options.isEmpty())
|
||||
|
||||
if (!current.isEmpty() && input_ui_options.indexOf(current) < 0)
|
||||
{
|
||||
input_setting_options.append(current);
|
||||
}
|
||||
else if (input_setting_options.isEmpty())
|
||||
{
|
||||
QMessageBox::critical(QtUtils::GetRootWidget(this), tr("Error"), tr("No devices with vibration motors were detected."));
|
||||
return;
|
||||
@@ -457,16 +496,25 @@ void InputVibrationBindingWidget::onClicked()
|
||||
input_dialog.setInputMode(QInputDialog::TextInput);
|
||||
input_dialog.setOptions(QInputDialog::UseListViewForComboBoxItems);
|
||||
input_dialog.setComboBoxEditable(false);
|
||||
input_dialog.setComboBoxItems(std::move(input_options));
|
||||
input_dialog.setComboBoxItems(std::move(input_ui_options));
|
||||
input_dialog.setTextValue(current);
|
||||
if (input_dialog.exec() == 0)
|
||||
return;
|
||||
|
||||
const QString new_value(input_dialog.textValue());
|
||||
m_binding = new_value.toStdString();
|
||||
Host::SetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_binding.c_str());
|
||||
Host::CommitBaseSettingChanges();
|
||||
setText(new_value);
|
||||
// If a controller is unplugged, we won't have the setting string to save
|
||||
// Skip saving if selected is an existing bind from an unplugged controller
|
||||
const int selected = input_setting_options.indexOf(input_dialog.textValue());
|
||||
if (selected >= 0)
|
||||
{
|
||||
// Update config
|
||||
const std::string new_setting_value(input_setting_options[selected].toStdString());
|
||||
Host::SetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str(), new_setting_value.c_str());
|
||||
Host::CommitBaseSettingChanges();
|
||||
// Update ui
|
||||
const QString new_ui_value(input_dialog.textValue());
|
||||
m_binding = new_ui_value.toStdString();
|
||||
setText(new_ui_value);
|
||||
}
|
||||
}
|
||||
|
||||
void InputVibrationBindingWidget::mouseReleaseEvent(QMouseEvent* e)
|
||||
|
||||
@@ -39,6 +39,9 @@ protected Q_SLOTS:
|
||||
void onInputListenTimerTimeout();
|
||||
void inputManagerHookCallback(InputBindingKey key, float value);
|
||||
|
||||
void onInputDeviceConnected(const QString& identifier, const QString& device_name);
|
||||
void onInputDeviceDisconnected(const QString& identifier);
|
||||
|
||||
protected:
|
||||
enum : u32
|
||||
{
|
||||
@@ -65,7 +68,8 @@ protected:
|
||||
InputBindingInfo::Type m_bind_type = InputBindingInfo::Type::Unknown;
|
||||
std::string m_section_name;
|
||||
std::string m_key_name;
|
||||
std::vector<std::string> m_bindings;
|
||||
std::vector<std::string> m_bindings_settings;
|
||||
std::vector<std::string> m_bindings_ui;
|
||||
std::vector<InputBindingKey> m_new_bindings;
|
||||
std::vector<std::pair<InputBindingKey, std::pair<float, float>>> m_value_ranges;
|
||||
QTimer* m_input_listen_timer = nullptr;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -138,6 +138,15 @@ void Host::ClearTranslationCache()
|
||||
s_translation_string_mutex.unlock();
|
||||
}
|
||||
|
||||
void Host::ReportFormattedInfoAsync(const std::string_view title, const char* format, ...)
|
||||
{
|
||||
std::va_list ap;
|
||||
va_start(ap, format);
|
||||
std::string message(StringUtil::StdStringFromFormatV(format, ap));
|
||||
va_end(ap);
|
||||
ReportInfoAsync(title, message);
|
||||
}
|
||||
|
||||
void Host::ReportFormattedErrorAsync(const std::string_view title, const char* format, ...)
|
||||
{
|
||||
std::va_list ap;
|
||||
|
||||
@@ -55,6 +55,10 @@ namespace Host
|
||||
void RemoveKeyedOSDMessage(std::string key);
|
||||
void ClearOSDMessages();
|
||||
|
||||
/// Displays an asynchronous error on the UI thread, i.e. doesn't block the caller.
|
||||
void ReportInfoAsync(const std::string_view title, const std::string_view message);
|
||||
void ReportFormattedInfoAsync(const std::string_view title, const char* format, ...);
|
||||
|
||||
/// Displays an asynchronous error on the UI thread, i.e. doesn't block the caller.
|
||||
void ReportErrorAsync(const std::string_view title, const std::string_view message);
|
||||
void ReportFormattedErrorAsync(const std::string_view title, const char* format, ...);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "common/Console.h"
|
||||
#include "common/Error.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -23,11 +23,11 @@ namespace
|
||||
void CloseDevice();
|
||||
|
||||
protected:
|
||||
__fi bool IsOpen() const { return (m_device_id != 0); }
|
||||
__fi bool IsOpen() const { return (m_stream != nullptr); }
|
||||
|
||||
static void AudioCallback(void* userdata, uint8_t* stream, int len);
|
||||
static void AudioCallback(void* userdata, SDL_AudioStream* stream, int additional_amount, int total_amount);
|
||||
|
||||
u32 m_device_id = 0;
|
||||
SDL_AudioStream* m_stream = nullptr;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
@@ -41,7 +41,7 @@ static bool InitializeSDLAudio(Error* error)
|
||||
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;
|
||||
@@ -102,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;
|
||||
}
|
||||
@@ -132,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,16 +508,20 @@ void FullscreenUI::GetStandardSelectionFooterText(SmallStringBase& dest, bool ba
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
ImGuiFullscreen::CreateFooterTextString(
|
||||
dest,
|
||||
std::array{std::make_pair(ICON_PF_DPAD_UP_DOWN, FSUI_VSTR("Change Selection")),
|
||||
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"))});
|
||||
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")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,18 +543,23 @@ void ImGuiFullscreen::GetFileSelectorHelpText(SmallStringBase& dest)
|
||||
{
|
||||
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(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"))});
|
||||
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")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,15 +568,19 @@ void ImGuiFullscreen::GetInputDialogHelpText(SmallStringBase& dest)
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
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(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"))});
|
||||
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")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -641,7 +654,7 @@ 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();
|
||||
|
||||
@@ -695,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)
|
||||
@@ -1383,7 +1398,8 @@ void FullscreenUI::DrawLandingWindow()
|
||||
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(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"))});
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Exit")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1393,7 +1409,8 @@ 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")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1448,17 +1465,21 @@ void FullscreenUI::DrawStartGameWindow()
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
SetFullscreenFooterText(std::array{std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, FSUI_VSTR("Navigate")),
|
||||
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(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"))});
|
||||
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")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1504,14 +1525,16 @@ void FullscreenUI::DrawExitWindow()
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, FSUI_VSTR("Navigate")),
|
||||
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"))});
|
||||
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")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1587,7 +1610,9 @@ void FullscreenUI::DrawInputBindingButton(
|
||||
return;
|
||||
|
||||
if (oneline)
|
||||
InputManager::PrettifyInputBinding(value);
|
||||
InputManager::PrettifyInputBinding(value, true);
|
||||
else
|
||||
InputManager::PrettifyInputBinding(value, false);
|
||||
|
||||
if (show_type)
|
||||
{
|
||||
@@ -3082,7 +3107,8 @@ void FullscreenUI::DrawSettingsWindow()
|
||||
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(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"))});
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back")),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3090,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")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3209,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"),
|
||||
@@ -3239,15 +3299,6 @@ 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))
|
||||
{
|
||||
ImGuiFullscreen::SetTheme(bsi->GetBoolValue("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[] = {
|
||||
@@ -3294,6 +3345,10 @@ void FullscreenUI::DrawInterfaceSettingsPage()
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -4095,7 +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)
|
||||
{
|
||||
@@ -4431,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);
|
||||
@@ -4885,13 +4941,15 @@ 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)
|
||||
{
|
||||
@@ -5368,15 +5426,19 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
|
||||
SetFullscreenFooterText(std::array{std::make_pair(ICON_PF_DPAD_UP_DOWN, FSUI_VSTR("Change Selection")),
|
||||
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"))});
|
||||
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")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5806,14 +5868,17 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
|
||||
std::make_pair(ICON_PF_DPAD, FSUI_VSTR("Select State")),
|
||||
std::make_pair(ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Options")),
|
||||
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"))});
|
||||
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")),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6104,15 +6169,19 @@ void FullscreenUI::DrawGameListWindow()
|
||||
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(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"))});
|
||||
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")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7084,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.");
|
||||
@@ -7094,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.");
|
||||
@@ -7547,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)]");
|
||||
@@ -7669,7 +7753,6 @@ 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)");
|
||||
@@ -7750,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");
|
||||
@@ -7759,9 +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");
|
||||
|
||||
@@ -86,7 +86,6 @@ namespace ImGuiFullscreen
|
||||
static u32 s_menu_button_index = 0;
|
||||
static u32 s_close_button_state = 0;
|
||||
static FocusResetType s_focus_reset_queued = FocusResetType::None;
|
||||
static bool s_light_theme = false;
|
||||
|
||||
static LRUCache<std::string, std::shared_ptr<GSTexture>> s_texture_cache(128, true);
|
||||
static std::shared_ptr<GSTexture> s_placeholder_texture;
|
||||
@@ -2668,10 +2667,10 @@ void ImGuiFullscreen::DrawNotifications(ImVec2& position, float spacing)
|
||||
ImFont* const title_font = ImGuiFullscreen::g_large_font;
|
||||
ImFont* const text_font = ImGuiFullscreen::g_medium_font;
|
||||
|
||||
const u32 toast_background_color = s_light_theme ? IM_COL32(241, 241, 241, 255) : IM_COL32(0x21, 0x21, 0x21, 255);
|
||||
const u32 toast_border_color = s_light_theme ? IM_COL32(0x88, 0x88, 0x88, 255) : IM_COL32(0x48, 0x48, 0x48, 255);
|
||||
const u32 toast_title_color = s_light_theme ? IM_COL32(1, 1, 1, 255) : IM_COL32(0xff, 0xff, 0xff, 255);
|
||||
const u32 toast_text_color = s_light_theme ? IM_COL32(0, 0, 0, 255) : IM_COL32(0xff, 0xff, 0xff, 255);
|
||||
const u32 toast_background_color = IM_COL32(0x21, 0x21, 0x21, 255);
|
||||
const u32 toast_border_color = IM_COL32(0x48, 0x48, 0x48, 255);
|
||||
const u32 toast_title_color = IM_COL32(0xff, 0xff, 0xff, 255);
|
||||
const u32 toast_text_color = IM_COL32(0xff, 0xff, 0xff, 255);
|
||||
|
||||
for (u32 index = 0; index < static_cast<u32>(s_notifications.size());)
|
||||
{
|
||||
@@ -2839,13 +2838,10 @@ void ImGuiFullscreen::DrawToast()
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiFullscreen::SetTheme(bool light)
|
||||
void ImGuiFullscreen::SetTheme(std::string_view theme)
|
||||
{
|
||||
s_light_theme = light;
|
||||
|
||||
if (!light)
|
||||
if (theme == "Dark")
|
||||
{
|
||||
// dark
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x212121, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
@@ -2863,9 +2859,8 @@ void ImGuiFullscreen::SetTheme(bool light)
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x002171, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else
|
||||
else if (theme == "Light")
|
||||
{
|
||||
// light
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0xc8c8c8, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xe1e2e1, 0xff);
|
||||
@@ -2883,4 +2878,175 @@ void ImGuiFullscreen::SetTheme(bool light)
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0xc0cfff, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
}
|
||||
else if (theme == "AMOLED")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0x0c0c0c, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x212121, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x0a0a0a, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xb5b5b5, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x8d8d8d, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0x191919, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x474747, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else if (theme == "CobaltSky")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x2b3760, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0x3b54ac, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x2b3760, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x202e5a, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xb5b5b5, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x222c4d, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x8d8d8d, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0x245dda, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x3a3d7b, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else if (theme == "GreyMatter")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x353944, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0x484d57, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x212121, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x292d35, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xb5b5b5, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x212121, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x8d8d8d, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0x191919, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x2a2e36, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else if (theme == "UntouchedLagoon")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x9db1bb, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0x1b7f7f, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x488c8c, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0xa2c2bc, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xadcfc8, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x488c8c, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x4b4b4b, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0x2a5151, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x475055, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
}
|
||||
else if (theme == "BabyPastel")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0xf1d9ee, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xe05885, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0xe05885, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0xeba0b9, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0xffaec9, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xe05885, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0xc3859a, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x4b4b4b, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0xeba0b9, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0xe05885, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0xdc6c68, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0xab5451, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
}
|
||||
else if (theme == "PizzaBrown")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0xd9c9ba, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0xaa5a36, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0xefad42, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0xe9bb93, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xf9e7ac, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0xefad42, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x4b4b4b, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0xaf1c2f, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0xab5451, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
}
|
||||
else if (theme == "ScarletDevil")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x782c44, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0xf0f0f0, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0xa73e5f, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x88475d, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x4f2c44, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0xb5b5b5, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x632438, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0xc80000, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x8a334e, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else if (theme == "VioletAngel")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x6e1e7d, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0x862c9c, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0x862c9c, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0x502657, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x321846, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0x9833d6, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x70269e, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x969696, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0xe200cb, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0xff00e6, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x561d79, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
else if (theme == "PCSX2Blue")
|
||||
{
|
||||
UIBackgroundColor = HEX_TO_IMVEC4(0x819af0, 0xff);
|
||||
UIBackgroundTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIBackgroundLineColor = HEX_TO_IMVEC4(0x89a5ff, 0xff);
|
||||
UIBackgroundHighlightColor = HEX_TO_IMVEC4(0xfefffe, 0xff);
|
||||
UIPopupBackgroundColor = HEX_TO_IMVEC4(0xb4cffe, 0xf2);
|
||||
UIPrimaryColor = HEX_TO_IMVEC4(0x92b6fe, 0xff);
|
||||
UIPrimaryLightColor = HEX_TO_IMVEC4(0x89a5ff, 0xff);
|
||||
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x7c8ef3, 0xff);
|
||||
UIPrimaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
UIDisabledColor = HEX_TO_IMVEC4(0x4b4b4b, 0xff);
|
||||
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);
|
||||
UIPrimaryLineColor = HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
UISecondaryColor = HEX_TO_IMVEC4(0x92b6fe, 0xff);
|
||||
UISecondaryStrongColor = HEX_TO_IMVEC4(0x0c53c5, 0xff);
|
||||
UISecondaryWeakColor = HEX_TO_IMVEC4(0x819af0, 0xff);
|
||||
UISecondaryTextColor = HEX_TO_IMVEC4(0x000000, 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace ImGuiFullscreen
|
||||
/// Initializes, setting up any state.
|
||||
bool Initialize(const char* placeholder_image_path);
|
||||
|
||||
void SetTheme(bool light);
|
||||
void SetTheme(std::string_view theme);
|
||||
void SetFonts(ImFont* standard_font, ImFont* medium_font, ImFont* large_font);
|
||||
bool UpdateLayoutScale();
|
||||
|
||||
|
||||
@@ -489,7 +489,7 @@ bool ImGuiManager::AddIconFonts(float size)
|
||||
{
|
||||
// clang-format off
|
||||
static constexpr ImWchar range_fa[] = { 0xe06f,0xe06f,0xf002,0xf002,0xf005,0xf005,0xf007,0xf007,0xf00c,0xf00e,0xf011,0xf011,0xf013,0xf013,0xf017,0xf017,0xf019,0xf019,0xf021,0xf023,0xf025,0xf028,0xf02b,0xf02b,0xf02e,0xf02e,0xf030,0xf030,0xf03a,0xf03a,0xf03d,0xf03e,0xf04b,0xf04c,0xf04e,0xf04e,0xf050,0xf050,0xf052,0xf052,0xf05a,0xf05a,0xf05e,0xf05e,0xf063,0xf063,0xf067,0xf067,0xf06a,0xf06a,0xf06e,0xf06e,0xf071,0xf071,0xf077,0xf078,0xf07b,0xf07c,0xf084,0xf084,0xf091,0xf091,0xf0ac,0xf0ad,0xf0b0,0xf0b0,0xf0c5,0xf0c5,0xf0c7,0xf0c8,0xf0cb,0xf0cb,0xf0d0,0xf0d0,0xf0dc,0xf0dc,0xf0e2,0xf0e2,0xf0eb,0xf0eb,0xf0f3,0xf0f3,0xf0fe,0xf0fe,0xf11b,0xf11c,0xf120,0xf121,0xf129,0xf12a,0xf140,0xf140,0xf14a,0xf14a,0xf15b,0xf15b,0xf15d,0xf15d,0xf187,0xf188,0xf191,0xf192,0xf1b3,0xf1b3,0xf1de,0xf1de,0xf1e6,0xf1e6,0xf1ea,0xf1eb,0xf1f8,0xf1f8,0xf1fc,0xf1fc,0xf21e,0xf21e,0xf245,0xf245,0xf26c,0xf26c,0xf279,0xf279,0xf2bd,0xf2bd,0xf2db,0xf2db,0xf2f2,0xf2f2,0xf302,0xf302,0xf3c1,0xf3c1,0xf3fd,0xf3fd,0xf410,0xf410,0xf462,0xf462,0xf466,0xf466,0xf4e2,0xf4e2,0xf51f,0xf51f,0xf545,0xf545,0xf54c,0xf54c,0xf553,0xf553,0xf56d,0xf56d,0xf5a2,0xf5a2,0xf65d,0xf65e,0xf6a9,0xf6a9,0xf70e,0xf70e,0xf756,0xf756,0xf780,0xf780,0xf794,0xf794,0xf815,0xf815,0xf84c,0xf84c,0xf8cc,0xf8cc,0x0,0x0 };
|
||||
static constexpr ImWchar range_pf[] = { 0x2198,0x2199,0x219e,0x21a3,0x21b0,0x21b3,0x21ba,0x21c3,0x21ce,0x21ce,0x21d0,0x21d4,0x21dc,0x21dd,0x21e0,0x21e3,0x21f3,0x21f3,0x21f7,0x21f8,0x21fa,0x21fb,0x221a,0x221a,0x227a,0x227d,0x22bf,0x22c8,0x2349,0x2349,0x235a,0x235e,0x2360,0x2361,0x2364,0x2367,0x237a,0x237b,0x237d,0x237d,0x237f,0x237f,0x23b2,0x23b5,0x23cc,0x23cc,0x23f4,0x23f7,0x2427,0x243a,0x243d,0x243d,0x2443,0x2443,0x2460,0x246b,0x248f,0x248f,0x24f5,0x24fd,0x24ff,0x24ff,0x2605,0x2605,0x2699,0x2699,0x278a,0x278e,0xe001,0xe001,0xff21,0xff3a,0x0,0x0 };
|
||||
static constexpr ImWchar range_pf[] = { 0x2198,0x2199,0x219e,0x21a7,0x21b0,0x21b3,0x21ba,0x21c3,0x21ce,0x21ce,0x21d0,0x21d4,0x21dc,0x21dd,0x21e0,0x21e3,0x21e6,0x21e8,0x21f3,0x21f3,0x21f7,0x21f8,0x21fa,0x21fb,0x2206,0x2208,0x221a,0x221a,0x227a,0x227d,0x22bf,0x22c8,0x2349,0x2349,0x235a,0x235e,0x2360,0x2361,0x2364,0x2367,0x237a,0x237b,0x237d,0x237d,0x237f,0x237f,0x23b2,0x23b5,0x23cc,0x23cc,0x23f4,0x23f7,0x2427,0x243a,0x243d,0x243d,0x2443,0x2443,0x2460,0x246b,0x248f,0x248f,0x24f5,0x24fd,0x24ff,0x24ff,0x2605,0x2605,0x2699,0x2699,0x278a,0x278e,0xe000,0xe001,0xff21,0xff3a,0x0,0x0 };
|
||||
// clang-format on
|
||||
|
||||
{
|
||||
|
||||
@@ -45,6 +45,17 @@ std::string DInputSource::GetDeviceIdentifier(u32 index)
|
||||
return fmt::format("DInput-{}", index);
|
||||
}
|
||||
|
||||
static constexpr const char* s_dinput_axis_names[] = {
|
||||
"X Axis",
|
||||
"Y Axis",
|
||||
"Z Axis",
|
||||
"Z Rotation",
|
||||
"X Rotation",
|
||||
"Y Rotation",
|
||||
"Slider 1",
|
||||
"Slider 2",
|
||||
};
|
||||
|
||||
static constexpr std::array<const char*, DInputSource::NUM_HAT_DIRECTIONS> s_hat_directions = {{"Up", "Down", "Left", "Right"}};
|
||||
|
||||
bool DInputSource::Initialize(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock)
|
||||
@@ -150,6 +161,15 @@ void DInputSource::Shutdown()
|
||||
GetDeviceIdentifier(index));
|
||||
m_controllers.pop_back();
|
||||
}
|
||||
|
||||
m_toplevel_window = nullptr;
|
||||
m_dinput.reset();
|
||||
m_dinput_module.reset();
|
||||
}
|
||||
|
||||
bool DInputSource::IsInitialized()
|
||||
{
|
||||
return m_toplevel_window;
|
||||
}
|
||||
|
||||
bool DInputSource::AddDevice(ControllerData& cd, const std::string& name)
|
||||
@@ -379,7 +399,7 @@ std::optional<InputBindingKey> DInputSource::ParseKeyString(const std::string_vi
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
TinyString DInputSource::ConvertKeyToString(InputBindingKey key)
|
||||
TinyString DInputSource::ConvertKeyToString(InputBindingKey key, bool display, bool migration)
|
||||
{
|
||||
TinyString ret;
|
||||
|
||||
@@ -387,18 +407,33 @@ TinyString DInputSource::ConvertKeyToString(InputBindingKey key)
|
||||
{
|
||||
if (key.source_subtype == InputSubclass::ControllerAxis)
|
||||
{
|
||||
const char* modifier = (key.modifier == InputModifier::FullAxis ? "Full" : (key.modifier == InputModifier::Negate ? "-" : "+"));
|
||||
ret.format("DInput-{}/{}Axis{}{}", u32(key.source_index), modifier, u32(key.data), (key.invert && !ShouldIgnoreInversion()) ? "~" : "");
|
||||
const char* modifier = (key.modifier == InputModifier::FullAxis ? (display ? "Full " : "Full") : (key.modifier == InputModifier::Negate ? "-" : "+"));
|
||||
if (display)
|
||||
{
|
||||
if (key.data < std::size(s_dinput_axis_names))
|
||||
ret.format("DInput-{} {}{}{}", u32(key.source_index), modifier, s_dinput_axis_names[key.data], key.invert ? "~" : "");
|
||||
else
|
||||
ret.format("DInput-{} {}Axis {}{}", u32(key.source_index), modifier, u32(key.data) + 1, key.invert ? "~" : "");
|
||||
}
|
||||
else
|
||||
ret.format("DInput-{}/{}Axis{}{}", u32(key.source_index), modifier, u32(key.data), (key.invert && (migration || !ShouldIgnoreInversion())) ? "~" : "");
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::ControllerButton && key.data >= MAX_NUM_BUTTONS)
|
||||
{
|
||||
// Note, hats currently get mapped to buttons
|
||||
const u32 hat_num = (key.data - MAX_NUM_BUTTONS) / NUM_HAT_DIRECTIONS;
|
||||
const u32 hat_dir = (key.data - MAX_NUM_BUTTONS) % NUM_HAT_DIRECTIONS;
|
||||
ret.format("DInput-{}/Hat{}{}", u32(key.source_index), hat_num, s_hat_directions[hat_dir]);
|
||||
if (display)
|
||||
ret.format("DInput-{} Hat {} {}", u32(key.source_index), hat_num + 1, s_hat_directions[hat_dir]);
|
||||
else
|
||||
ret.format("DInput-{}/Hat{}{}", u32(key.source_index), hat_num, s_hat_directions[hat_dir]);
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::ControllerButton)
|
||||
{
|
||||
ret.format("DInput-{}/Button{}", u32(key.source_index), u32(key.data));
|
||||
if (display)
|
||||
ret.format("DInput-{} Button {}", u32(key.source_index), u32(key.data) + 1);
|
||||
else
|
||||
ret.format("DInput-{}/Button{}", u32(key.source_index), u32(key.data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
||||
bool ReloadDevices() override;
|
||||
void Shutdown() override;
|
||||
bool IsInitialized() override;
|
||||
|
||||
void PollEvents() override;
|
||||
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
||||
@@ -47,7 +48,7 @@ public:
|
||||
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
||||
|
||||
std::optional<InputBindingKey> ParseKeyString(const std::string_view device, const std::string_view binding) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key, bool display = false, bool migration = false) override;
|
||||
TinyString ConvertKeyToIcon(InputBindingKey key) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "SIO/Sio.h"
|
||||
#include "USB/USB.h"
|
||||
#include "VMManager.h"
|
||||
#include "LayeredSettingsInterface.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
@@ -92,18 +93,23 @@ namespace InputManager
|
||||
static std::optional<InputBindingKey> ParseHostKeyboardKey(const std::string_view source, const std::string_view sub_binding);
|
||||
static std::optional<InputBindingKey> ParsePointerKey(const std::string_view source, const std::string_view sub_binding);
|
||||
|
||||
static TinyString ConvertKeyboardKeyToString(InputBindingKey key, bool display = false);
|
||||
static TinyString ConvertPointerKeyToString(InputBindingKey key, bool display = false);
|
||||
|
||||
static bool SplitBinding(const std::string_view binding, std::string_view* source, std::string_view* sub_binding);
|
||||
static void PrettifyInputBindingPart(const std::string_view binding, SmallString& ret, bool& changed);
|
||||
static void AddBinding(const std::string_view binding, const InputEventHandler& handler);
|
||||
static void AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler);
|
||||
static void PrettifyInputBindingPart(const std::string_view binding, SmallString& ret, bool& changed, bool use_icons);
|
||||
static std::shared_ptr<InputBinding> AddBinding(const std::string_view binding, const InputEventHandler& handler);
|
||||
// Will also apply SDL2-SDL3 migrations and update the provided section & key
|
||||
static void AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler,
|
||||
InputBindingInfo::Type binding_type, SettingsInterface& si, const char* section, const char* key, bool is_profile);
|
||||
static bool ParseBindingAndGetSource(const std::string_view binding, InputBindingKey* key, InputSource** source);
|
||||
|
||||
static bool IsAxisHandler(const InputEventHandler& handler);
|
||||
static float ApplySingleBindingScale(float sensitivity, float deadzone, float value);
|
||||
|
||||
static void AddHotkeyBindings(SettingsInterface& si);
|
||||
static void AddPadBindings(SettingsInterface& si, u32 pad);
|
||||
static void AddUSBBindings(SettingsInterface& si, u32 port);
|
||||
static void AddHotkeyBindings(SettingsInterface& si, bool is_profile);
|
||||
static void AddPadBindings(SettingsInterface& si, u32 pad, bool is_profile);
|
||||
static void AddUSBBindings(SettingsInterface& si, u32 port, bool is_profile);
|
||||
static void UpdateContinuedVibration();
|
||||
static void GenerateRelativeMouseEvents();
|
||||
|
||||
@@ -142,9 +148,12 @@ static const HotkeyInfo* const s_hotkey_list[] = {g_common_hotkeys, g_gs_hotkeys
|
||||
// Tracking host mouse movement and turning into relative events
|
||||
// 4 axes: pointer left/right, wheel vertical/horizontal. Last/Next/Normalized.
|
||||
// ------------------------------------------------------------------------
|
||||
static constexpr const std::array<const char*, static_cast<u8>(InputPointerAxis::Count)> s_pointer_axis_names = {
|
||||
static constexpr const std::array<const char*, static_cast<u8>(InputPointerAxis::Count)> s_pointer_axis_setting_names = {
|
||||
{"X", "Y", "WheelX", "WheelY"}};
|
||||
static constexpr const std::array<const char*, 3> s_pointer_button_names = {{"LeftButton", "RightButton", "MiddleButton"}};
|
||||
static constexpr const std::array<const char*, static_cast<u8>(InputPointerAxis::Count)> s_pointer_axis_names = {
|
||||
{"X", "Y", "Wheel X", "Wheel Y"}};
|
||||
static constexpr const std::array<const char*, 3> s_pointer_button_setting_names = {{"LeftButton", "RightButton", "MiddleButton"}};
|
||||
static constexpr const std::array<const char*, 3> s_pointer_button_names = {{"Left Button", "Right Button", "Middle Button"}};
|
||||
|
||||
struct PointerAxisState
|
||||
{
|
||||
@@ -232,7 +241,7 @@ std::optional<InputBindingKey> InputManager::ParseInputBindingKey(const std::str
|
||||
{
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
{
|
||||
std::optional<InputBindingKey> key = s_input_sources[i]->ParseKeyString(source, sub_binding);
|
||||
if (key.has_value())
|
||||
@@ -252,7 +261,7 @@ bool InputManager::ParseBindingAndGetSource(const std::string_view binding, Inpu
|
||||
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
{
|
||||
std::optional<InputBindingKey> parsed_key = s_input_sources[i]->ParseKeyString(source_string, sub_binding);
|
||||
if (parsed_key.has_value())
|
||||
@@ -267,7 +276,62 @@ bool InputManager::ParseBindingAndGetSource(const std::string_view binding, Inpu
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string InputManager::ConvertInputBindingKeyToString(InputBindingInfo::Type binding_type, InputBindingKey key)
|
||||
TinyString InputManager::ConvertKeyboardKeyToString(InputBindingKey key, bool display)
|
||||
{
|
||||
TinyString ret;
|
||||
|
||||
if (key.source_type == InputSourceType::Keyboard)
|
||||
{
|
||||
const std::optional<std::string> str(ConvertHostKeyboardCodeToString(key.data));
|
||||
if (str.has_value() && !str->empty())
|
||||
if (display)
|
||||
// Keyboard keys arn't spaced out for display yet
|
||||
ret.format("Keyboard {}", str->c_str());
|
||||
else
|
||||
ret.format("Keyboard/{}", str->c_str());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
TinyString InputManager::ConvertPointerKeyToString(InputBindingKey key, bool display)
|
||||
{
|
||||
TinyString ret;
|
||||
|
||||
if (key.source_type == InputSourceType::Pointer)
|
||||
{
|
||||
if (key.source_subtype == InputSubclass::PointerButton)
|
||||
{
|
||||
if (display)
|
||||
{
|
||||
if (key.data < s_pointer_button_setting_names.size())
|
||||
ret.format("Pointer-{} {}", u32{key.source_index}, s_pointer_button_names[key.data]);
|
||||
else
|
||||
ret.format("Pointer-{} Button{}", u32{key.source_index}, key.data + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key.data < s_pointer_button_setting_names.size())
|
||||
ret.format("Pointer-{}/{}", u32{key.source_index}, s_pointer_button_setting_names[key.data]);
|
||||
else
|
||||
ret.format("Pointer-{}/Button{}", u32{key.source_index}, key.data);
|
||||
}
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::PointerAxis)
|
||||
{
|
||||
if (display)
|
||||
ret.format("Pointer-{} {}{:c}", u32{key.source_index}, s_pointer_axis_setting_names[key.data],
|
||||
key.modifier == InputModifier::Negate ? '-' : '+');
|
||||
else
|
||||
ret.format("Pointer-{}/{}{:c}", u32{key.source_index}, s_pointer_axis_setting_names[key.data],
|
||||
key.modifier == InputModifier::Negate ? '-' : '+');
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string InputManager::ConvertInputBindingKeyToString(InputBindingInfo::Type binding_type, InputBindingKey key, bool migration)
|
||||
{
|
||||
if (binding_type == InputBindingInfo::Type::Pointer || binding_type == InputBindingInfo::Type::Device)
|
||||
{
|
||||
@@ -294,48 +358,35 @@ std::string InputManager::ConvertInputBindingKeyToString(InputBindingInfo::Type
|
||||
{
|
||||
if (key.source_type == InputSourceType::Keyboard)
|
||||
{
|
||||
const std::optional<std::string> str(ConvertHostKeyboardCodeToString(key.data));
|
||||
if (str.has_value() && !str->empty())
|
||||
return fmt::format("Keyboard/{}", str->c_str());
|
||||
return std::string(ConvertKeyboardKeyToString(key));
|
||||
}
|
||||
else if (key.source_type == InputSourceType::Pointer)
|
||||
{
|
||||
if (key.source_subtype == InputSubclass::PointerButton)
|
||||
{
|
||||
if (key.data < s_pointer_button_names.size())
|
||||
return fmt::format("Pointer-{}/{}", u32{key.source_index}, s_pointer_button_names[key.data]);
|
||||
else
|
||||
return fmt::format("Pointer-{}/Button{}", u32{key.source_index}, key.data);
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::PointerAxis)
|
||||
{
|
||||
return fmt::format("Pointer-{}/{}{:c}", u32{key.source_index}, s_pointer_axis_names[key.data],
|
||||
key.modifier == InputModifier::Negate ? '-' : '+');
|
||||
}
|
||||
return std::string(ConvertPointerKeyToString(key));
|
||||
}
|
||||
else if (key.source_type < InputSourceType::Count && s_input_sources[static_cast<u32>(key.source_type)])
|
||||
{
|
||||
return std::string(s_input_sources[static_cast<u32>(key.source_type)]->ConvertKeyToString(key));
|
||||
return std::string(s_input_sources[static_cast<u32>(key.source_type)]->ConvertKeyToString(key, false, migration));
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string InputManager::ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type, const InputBindingKey* keys, size_t num_keys)
|
||||
std::string InputManager::ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type, const InputBindingKey* keys, size_t num_keys, bool migration)
|
||||
{
|
||||
// can't have a chord of devices/pointers
|
||||
if (binding_type == InputBindingInfo::Type::Pointer || binding_type == InputBindingInfo::Type::Device)
|
||||
{
|
||||
// so only take the first
|
||||
if (num_keys > 0)
|
||||
return ConvertInputBindingKeyToString(binding_type, keys[0]);
|
||||
return ConvertInputBindingKeyToString(binding_type, keys[0], migration);
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
for (size_t i = 0; i < num_keys; i++)
|
||||
{
|
||||
const std::string keystr(ConvertInputBindingKeyToString(binding_type, keys[i]));
|
||||
const std::string keystr(ConvertInputBindingKeyToString(binding_type, keys[i], migration));
|
||||
if (keystr.empty())
|
||||
return std::string();
|
||||
|
||||
@@ -348,7 +399,7 @@ std::string InputManager::ConvertInputBindingKeysToString(InputBindingInfo::Type
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
|
||||
bool InputManager::PrettifyInputBinding(SmallStringBase& binding, bool use_icons)
|
||||
{
|
||||
if (binding.empty())
|
||||
return false;
|
||||
@@ -369,7 +420,7 @@ bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
|
||||
{
|
||||
if (!ret.empty())
|
||||
ret.append(" + ");
|
||||
PrettifyInputBindingPart(part, ret, changed);
|
||||
PrettifyInputBindingPart(part, ret, changed, use_icons);
|
||||
}
|
||||
}
|
||||
last = next + 1;
|
||||
@@ -381,7 +432,7 @@ bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
|
||||
{
|
||||
if (!ret.empty())
|
||||
ret.append(" + ");
|
||||
PrettifyInputBindingPart(part, ret, changed);
|
||||
PrettifyInputBindingPart(part, ret, changed, use_icons);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +442,7 @@ bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
|
||||
return changed;
|
||||
}
|
||||
|
||||
void InputManager::PrettifyInputBindingPart(const std::string_view binding, SmallString& ret, bool& changed)
|
||||
void InputManager::PrettifyInputBindingPart(const std::string_view binding, SmallString& ret, bool& changed, bool use_icons)
|
||||
{
|
||||
std::string_view source, sub_binding;
|
||||
if (!SplitBinding(binding, &source, &sub_binding))
|
||||
@@ -401,12 +452,30 @@ void InputManager::PrettifyInputBindingPart(const std::string_view binding, Smal
|
||||
if (source.starts_with("Keyboard"))
|
||||
{
|
||||
std::optional<InputBindingKey> key = ParseHostKeyboardKey(source, sub_binding);
|
||||
const char* icon = key.has_value() ? ConvertHostKeyboardCodeToIcon(key->data) : nullptr;
|
||||
if (icon)
|
||||
if (key.has_value())
|
||||
{
|
||||
ret.append(icon);
|
||||
changed = true;
|
||||
return;
|
||||
if (use_icons)
|
||||
{
|
||||
const char* icon = ConvertHostKeyboardCodeToIcon(key->data);
|
||||
if (icon)
|
||||
{
|
||||
ret.append(icon);
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.append(ConvertKeyboardKeyToString(key.value(), true));
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.append(ConvertKeyboardKeyToString(key.value(), true));
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (source.starts_with("Pointer"))
|
||||
@@ -414,7 +483,7 @@ void InputManager::PrettifyInputBindingPart(const std::string_view binding, Smal
|
||||
const std::optional<InputBindingKey> key = ParsePointerKey(source, sub_binding);
|
||||
if (key.has_value())
|
||||
{
|
||||
if (key->source_subtype == InputSubclass::PointerButton)
|
||||
if (use_icons && key->source_subtype == InputSubclass::PointerButton)
|
||||
{
|
||||
static constexpr const char* button_icons[] = {
|
||||
ICON_PF_MOUSE_BUTTON_1,
|
||||
@@ -424,32 +493,41 @@ void InputManager::PrettifyInputBindingPart(const std::string_view binding, Smal
|
||||
ICON_PF_MOUSE_BUTTON_5,
|
||||
};
|
||||
if (key->data < std::size(button_icons))
|
||||
{
|
||||
ret.append(button_icons[key->data]);
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
ret.append(ConvertPointerKeyToString(key.value(), true));
|
||||
}
|
||||
else
|
||||
ret.append(ConvertPointerKeyToString(key.value(), true));
|
||||
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
// We call ConvertKeyToIcon/String() even on disabled sources
|
||||
// This ensures consistant appearance between enabled and disabled sources
|
||||
if (s_input_sources[i])
|
||||
{
|
||||
std::optional<InputBindingKey> key = s_input_sources[i]->ParseKeyString(source, sub_binding);
|
||||
if (key.has_value())
|
||||
{
|
||||
const TinyString icon = s_input_sources[i]->ConvertKeyToIcon(key.value());
|
||||
if (!icon.empty())
|
||||
if (use_icons)
|
||||
{
|
||||
ret.append(icon);
|
||||
changed = true;
|
||||
return;
|
||||
const TinyString icon = s_input_sources[i]->ConvertKeyToIcon(key.value());
|
||||
if (!icon.empty())
|
||||
ret.append(icon);
|
||||
else
|
||||
ret.append(s_input_sources[i]->ConvertKeyToString(key.value(), true));
|
||||
}
|
||||
else
|
||||
ret.append(s_input_sources[i]->ConvertKeyToString(key.value(), true));
|
||||
|
||||
break;
|
||||
changed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -459,7 +537,7 @@ void InputManager::PrettifyInputBindingPart(const std::string_view binding, Smal
|
||||
}
|
||||
|
||||
|
||||
void InputManager::AddBinding(const std::string_view binding, const InputEventHandler& handler)
|
||||
std::shared_ptr<InputBinding> InputManager::AddBinding(const std::string_view binding, const InputEventHandler& handler)
|
||||
{
|
||||
std::shared_ptr<InputBinding> ibinding;
|
||||
const std::vector<std::string_view> chord_bindings(SplitChord(binding));
|
||||
@@ -493,17 +571,74 @@ void InputManager::AddBinding(const std::string_view binding, const InputEventHa
|
||||
}
|
||||
|
||||
if (!ibinding)
|
||||
return;
|
||||
return nullptr;
|
||||
|
||||
// plop it in the input map for all the keys
|
||||
for (u32 i = 0; i < ibinding->num_keys; i++)
|
||||
s_binding_map.emplace(ibinding->keys[i].MaskDirection(), ibinding);
|
||||
|
||||
return ibinding;
|
||||
}
|
||||
|
||||
void InputManager::AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler)
|
||||
void InputManager::AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler,
|
||||
InputBindingInfo::Type binding_type, SettingsInterface& si, const char* section, const char* key, bool is_profile)
|
||||
{
|
||||
std::vector<std::shared_ptr<InputBinding>> ibindings;
|
||||
|
||||
bool migrate = false;
|
||||
for (const std::string& binding : bindings)
|
||||
AddBinding(binding, handler);
|
||||
{
|
||||
std::shared_ptr<InputBinding> ibinding = AddBinding(binding, handler);
|
||||
ibindings.push_back(ibinding);
|
||||
|
||||
if (ibinding)
|
||||
{
|
||||
// Check for SDL2-3 migrations
|
||||
for (u32 i = 0; i < ibinding->num_keys; i++)
|
||||
{
|
||||
if (ibinding->keys[i].needs_migration)
|
||||
migrate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save migrations
|
||||
if (migrate)
|
||||
{
|
||||
std::vector<std::string> new_bindings;
|
||||
new_bindings.reserve(bindings.size());
|
||||
|
||||
for (int i = 0; i < bindings.size(); i++)
|
||||
{
|
||||
if (ibindings[i])
|
||||
new_bindings.push_back(ConvertInputBindingKeysToString(binding_type, ibindings[i]->keys, ibindings[i]->num_keys, true));
|
||||
else
|
||||
// Retain invalid bindings as is
|
||||
new_bindings.push_back(bindings[i]);
|
||||
}
|
||||
|
||||
if (is_profile)
|
||||
{
|
||||
// INISettingsInterface, can just update directly
|
||||
si.SetStringList(section, key, new_bindings);
|
||||
si.Save();
|
||||
}
|
||||
else
|
||||
{
|
||||
// LayeredSettingsInterface, Need to find which layer our binding came from
|
||||
LayeredSettingsInterface& lsi = static_cast<LayeredSettingsInterface&>(si);
|
||||
for (int i = 0; i < LayeredSettingsInterface::NUM_LAYERS; i++)
|
||||
{
|
||||
SettingsInterface* layer = lsi.GetLayer(static_cast<LayeredSettingsInterface::Layer>(i));
|
||||
if (layer && layer->GetStringList(section, key) == bindings)
|
||||
{
|
||||
// Layer found, update settings
|
||||
layer->SetStringList(section, key, new_bindings);
|
||||
layer->Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@@ -631,14 +766,14 @@ std::optional<InputBindingKey> InputManager::ParsePointerKey(const std::string_v
|
||||
return key;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < s_pointer_axis_names.size(); i++)
|
||||
for (u32 i = 0; i < s_pointer_axis_setting_names.size(); i++)
|
||||
{
|
||||
if (sub_binding.starts_with(s_pointer_axis_names[i]))
|
||||
if (sub_binding.starts_with(s_pointer_axis_setting_names[i]))
|
||||
{
|
||||
key.source_subtype = InputSubclass::PointerAxis;
|
||||
key.data = i;
|
||||
|
||||
const std::string_view dir_part(sub_binding.substr(std::strlen(s_pointer_axis_names[i])));
|
||||
const std::string_view dir_part(sub_binding.substr(std::strlen(s_pointer_axis_setting_names[i])));
|
||||
if (dir_part == "+")
|
||||
key.modifier = InputModifier::None;
|
||||
else if (dir_part == "-")
|
||||
@@ -650,9 +785,9 @@ std::optional<InputBindingKey> InputManager::ParsePointerKey(const std::string_v
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < s_pointer_button_names.size(); i++)
|
||||
for (u32 i = 0; i < s_pointer_button_setting_names.size(); i++)
|
||||
{
|
||||
if (sub_binding == s_pointer_button_names[i])
|
||||
if (sub_binding == s_pointer_button_setting_names[i])
|
||||
{
|
||||
key.source_subtype = InputSubclass::PointerButton;
|
||||
key.data = i;
|
||||
@@ -701,7 +836,7 @@ std::vector<const HotkeyInfo*> InputManager::GetHotkeyList()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void InputManager::AddHotkeyBindings(SettingsInterface& si)
|
||||
void InputManager::AddHotkeyBindings(SettingsInterface& si, bool is_profile)
|
||||
{
|
||||
for (const HotkeyInfo* hotkey_list : s_hotkey_list)
|
||||
{
|
||||
@@ -711,12 +846,12 @@ void InputManager::AddHotkeyBindings(SettingsInterface& si)
|
||||
if (bindings.empty())
|
||||
continue;
|
||||
|
||||
AddBindings(bindings, InputButtonEventHandler{hotkey->handler});
|
||||
AddBindings(bindings, InputButtonEventHandler{hotkey->handler}, InputBindingInfo::Type::Button, si, "Hotkeys", hotkey->name, is_profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index)
|
||||
void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index, bool is_profile)
|
||||
{
|
||||
const Pad::ControllerType type = EmuConfig.Pad.Ports[pad_index].Type;
|
||||
|
||||
@@ -753,7 +888,8 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index)
|
||||
AddBindings(
|
||||
bindings, InputAxisEventHandler{[pad_index, bind_index = bi.bind_index, sensitivity, deadzone](InputBindingKey key, float value) {
|
||||
Pad::SetControllerState(pad_index, bind_index, ApplySingleBindingScale(sensitivity, deadzone, value));
|
||||
}});
|
||||
}},
|
||||
bi.bind_type, si, section.c_str(), bi.name, is_profile);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -771,10 +907,12 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index)
|
||||
if (!bindings.empty())
|
||||
{
|
||||
const float deadzone = si.GetFloatValue(section.c_str(), fmt::format("Macro{}Deadzone", macro_button_index + 1).c_str(), 0.0f);
|
||||
AddBindings(bindings, InputAxisEventHandler{[pad_index, macro_button_index, deadzone](InputBindingKey key, float value) {
|
||||
const bool state = (value > deadzone);
|
||||
Pad::SetMacroButtonState(key, pad_index, macro_button_index, state);
|
||||
}});
|
||||
AddBindings(
|
||||
bindings, InputAxisEventHandler{[pad_index, macro_button_index, deadzone](InputBindingKey key, float value) {
|
||||
const bool state = (value > deadzone);
|
||||
Pad::SetMacroButtonState(key, pad_index, macro_button_index, state);
|
||||
}},
|
||||
InputBindingInfo::Type::Macro, si, section.c_str(), fmt::format("Macro{}", macro_button_index + 1).c_str(), is_profile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -811,7 +949,7 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index)
|
||||
}
|
||||
}
|
||||
|
||||
void InputManager::AddUSBBindings(SettingsInterface& si, u32 port)
|
||||
void InputManager::AddUSBBindings(SettingsInterface& si, u32 port, bool is_profile)
|
||||
{
|
||||
const std::string device(USB::GetConfigDevice(si, port));
|
||||
if (device.empty() || device == "None")
|
||||
@@ -835,9 +973,11 @@ void InputManager::AddUSBBindings(SettingsInterface& si, u32 port)
|
||||
{
|
||||
const float sensitivity = si.GetFloatValue(section.c_str(), fmt::format("{}Scale", bi.name).c_str(), 1.0f);
|
||||
const float deadzone = si.GetFloatValue(section.c_str(), fmt::format("{}Deadzone", bi.name).c_str(), 0.0f);
|
||||
AddBindings(bindings, InputAxisEventHandler{[port, bind_index = bi.bind_index, sensitivity, deadzone](InputBindingKey key, float value) {
|
||||
USB::SetDeviceBindValue(port, bind_index, ApplySingleBindingScale(sensitivity, deadzone, value));
|
||||
}});
|
||||
AddBindings(
|
||||
bindings, InputAxisEventHandler{[port, bind_index = bi.bind_index, sensitivity, deadzone](InputBindingKey key, float value) {
|
||||
USB::SetDeviceBindValue(port, bind_index, ApplySingleBindingScale(sensitivity, deadzone, value));
|
||||
}},
|
||||
bi.bind_type, si, section.c_str(), bind_name.c_str(), is_profile);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1391,7 +1531,7 @@ bool InputManager::DoEventHook(InputBindingKey key, float value)
|
||||
// Binding Updater
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
void InputManager::ReloadBindings(SettingsInterface& si, SettingsInterface& binding_si, SettingsInterface& hotkey_binding_si)
|
||||
void InputManager::ReloadBindings(SettingsInterface& si, SettingsInterface& binding_si, SettingsInterface& hotkey_binding_si, bool is_binding_profile, bool is_hotkey_profile)
|
||||
{
|
||||
PauseVibration();
|
||||
|
||||
@@ -1403,28 +1543,28 @@ void InputManager::ReloadBindings(SettingsInterface& si, SettingsInterface& bind
|
||||
s_pointer_move_callbacks.clear();
|
||||
|
||||
// Hotkeys use the base configuration, except if the custom hotkeys option is enabled.
|
||||
AddHotkeyBindings(hotkey_binding_si);
|
||||
AddHotkeyBindings(hotkey_binding_si, is_hotkey_profile);
|
||||
|
||||
// If there's an input profile, we load pad bindings from it alone, rather than
|
||||
// falling back to the base configuration.
|
||||
for (u32 pad = 0; pad < Pad::NUM_CONTROLLER_PORTS; pad++)
|
||||
AddPadBindings(binding_si, pad);
|
||||
AddPadBindings(binding_si, pad, is_binding_profile);
|
||||
|
||||
constexpr float ui_ctrl_range = 100.0f;
|
||||
constexpr float pointer_sensitivity = 0.05f;
|
||||
for (u32 axis = 0; axis <= static_cast<u32>(InputPointerAxis::Y); axis++)
|
||||
{
|
||||
s_pointer_axis_speed[axis] = si.GetFloatValue("Pad", fmt::format("Pointer{}Speed", s_pointer_axis_names[axis]).c_str(), 40.0f) /
|
||||
s_pointer_axis_speed[axis] = si.GetFloatValue("Pad", fmt::format("Pointer{}Speed", s_pointer_axis_setting_names[axis]).c_str(), 40.0f) /
|
||||
ui_ctrl_range * pointer_sensitivity;
|
||||
s_pointer_axis_dead_zone[axis] = std::min(
|
||||
si.GetFloatValue("Pad", fmt::format("Pointer{}DeadZone", s_pointer_axis_names[axis]).c_str(), 20.0f) / ui_ctrl_range, 1.0f);
|
||||
si.GetFloatValue("Pad", fmt::format("Pointer{}DeadZone", s_pointer_axis_setting_names[axis]).c_str(), 20.0f) / ui_ctrl_range, 1.0f);
|
||||
s_pointer_axis_range[axis] = 1.0f - s_pointer_axis_dead_zone[axis];
|
||||
}
|
||||
s_pointer_inertia = si.GetFloatValue("Pad", "PointerInertia", 10.0f) / ui_ctrl_range;
|
||||
s_pointer_pos = {};
|
||||
|
||||
for (u32 port = 0; port < USB::NUM_PORTS; port++)
|
||||
AddUSBBindings(binding_si, port);
|
||||
AddUSBBindings(binding_si, port, is_binding_profile);
|
||||
|
||||
UpdateHostMouseMode();
|
||||
}
|
||||
@@ -1461,7 +1601,7 @@ bool InputManager::ReloadDevices()
|
||||
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
changed |= s_input_sources[i]->ReloadDevices();
|
||||
}
|
||||
|
||||
@@ -1472,11 +1612,11 @@ void InputManager::CloseSources()
|
||||
{
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
{
|
||||
s_input_sources[i]->Shutdown();
|
||||
s_input_sources[i].reset();
|
||||
}
|
||||
s_input_sources[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1484,7 +1624,7 @@ void InputManager::PollSources()
|
||||
{
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
s_input_sources[i]->PollEvents();
|
||||
}
|
||||
|
||||
@@ -1504,7 +1644,7 @@ std::vector<std::pair<std::string, std::string>> InputManager::EnumerateDevices(
|
||||
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
{
|
||||
std::vector<std::pair<std::string, std::string>> devs(s_input_sources[i]->EnumerateDevices());
|
||||
if (ret.empty())
|
||||
@@ -1523,7 +1663,7 @@ std::vector<InputBindingKey> InputManager::EnumerateMotors()
|
||||
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i])
|
||||
if (s_input_sources[i]->IsInitialized())
|
||||
{
|
||||
std::vector<InputBindingKey> devs(s_input_sources[i]->EnumerateMotors());
|
||||
if (ret.empty())
|
||||
@@ -1583,7 +1723,7 @@ InputManager::GenericInputBindingMapping InputManager::GetGenericBindingMapping(
|
||||
{
|
||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||
{
|
||||
if (s_input_sources[i] && s_input_sources[i]->GetGenericBindingMapping(device, &mapping))
|
||||
if (s_input_sources[i]->IsInitialized() && s_input_sources[i]->GetGenericBindingMapping(device, &mapping))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1599,34 +1739,34 @@ bool InputManager::IsInputSourceEnabled(SettingsInterface& si, InputSourceType t
|
||||
template <typename T>
|
||||
void InputManager::UpdateInputSourceState(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock, InputSourceType type)
|
||||
{
|
||||
if (!s_input_sources[static_cast<u32>(type)])
|
||||
{
|
||||
std::unique_ptr<InputSource> source = std::make_unique<T>();
|
||||
if (!source->Initialize(si, settings_lock))
|
||||
Console.Error("(InputManager) Source '%s' failed to initialize.", InputSourceToString(type));
|
||||
|
||||
s_input_sources[static_cast<u32>(type)] = std::move(source);
|
||||
}
|
||||
|
||||
const bool enabled = IsInputSourceEnabled(si, type);
|
||||
if (enabled)
|
||||
{
|
||||
if (s_input_sources[static_cast<u32>(type)])
|
||||
if (s_input_sources[static_cast<u32>(type)]->IsInitialized())
|
||||
{
|
||||
s_input_sources[static_cast<u32>(type)]->UpdateSettings(si, settings_lock);
|
||||
}
|
||||
else
|
||||
else if (!s_input_sources[static_cast<u32>(type)]->Initialize(si, settings_lock))
|
||||
{
|
||||
std::unique_ptr<InputSource> source = std::make_unique<T>();
|
||||
if (!source->Initialize(si, settings_lock))
|
||||
{
|
||||
Console.Error("(InputManager) Source '%s' failed to initialize.", InputSourceToString(type));
|
||||
return;
|
||||
}
|
||||
|
||||
s_input_sources[static_cast<u32>(type)] = std::move(source);
|
||||
Console.Error("(InputManager) Source '%s' failed to initialize.", InputSourceToString(type));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_input_sources[static_cast<u32>(type)])
|
||||
if (s_input_sources[static_cast<u32>(type)]->IsInitialized())
|
||||
{
|
||||
settings_lock.unlock();
|
||||
s_input_sources[static_cast<u32>(type)]->Shutdown();
|
||||
settings_lock.lock();
|
||||
|
||||
s_input_sources[static_cast<u32>(type)].reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,8 @@ union InputBindingKey
|
||||
InputSubclass source_subtype : 3; ///< if 1, binding is for an axis and not a button (used for controllers)
|
||||
InputModifier modifier : 2;
|
||||
u32 invert : 1; ///< if 1, value is inverted prior to being sent to the sink
|
||||
u32 unused : 14;
|
||||
u32 needs_migration : 1; //< Used for SDL2-3 Migration, binding should be saved to complete migration
|
||||
u32 unused : 13;
|
||||
u32 data;
|
||||
};
|
||||
|
||||
@@ -80,6 +81,7 @@ union InputBindingKey
|
||||
r.bits = bits;
|
||||
r.modifier = InputModifier::None;
|
||||
r.invert = 0;
|
||||
r.needs_migration = false;
|
||||
return r;
|
||||
}
|
||||
};
|
||||
@@ -203,13 +205,13 @@ namespace InputManager
|
||||
std::optional<InputBindingKey> ParseInputBindingKey(const std::string_view binding);
|
||||
|
||||
/// Converts a input key to a string.
|
||||
std::string ConvertInputBindingKeyToString(InputBindingInfo::Type binding_type, InputBindingKey key);
|
||||
std::string ConvertInputBindingKeyToString(InputBindingInfo::Type binding_type, InputBindingKey key, bool migration = false);
|
||||
|
||||
/// Converts a chord of binding keys to a string.
|
||||
std::string ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type, const InputBindingKey* keys, size_t num_keys);
|
||||
std::string ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type, const InputBindingKey* keys, size_t num_keys, bool migration = false);
|
||||
|
||||
/// Represents a binding with icon fonts, if available.
|
||||
bool PrettifyInputBinding(SmallStringBase& binding);
|
||||
bool PrettifyInputBinding(SmallStringBase& binding, bool use_icons = true);
|
||||
|
||||
/// Splits a chord into individual bindings.
|
||||
std::vector<std::string_view> SplitChord(const std::string_view binding);
|
||||
@@ -231,7 +233,7 @@ namespace InputManager
|
||||
bool IsInputSourceEnabled(SettingsInterface& si, InputSourceType type);
|
||||
|
||||
/// Re-parses the config and registers all hotkey and pad bindings.
|
||||
void ReloadBindings(SettingsInterface& si, SettingsInterface& binding_si, SettingsInterface& hotkey_binding_si);
|
||||
void ReloadBindings(SettingsInterface& si, SettingsInterface& binding_si, SettingsInterface& hotkey_binding_si, bool is_binding_profile, bool is_hotkey_profile);
|
||||
|
||||
/// Re-parses the sources part of the config and initializes any backends.
|
||||
void ReloadSources(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock);
|
||||
|
||||
@@ -24,11 +24,13 @@ public:
|
||||
virtual void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) = 0;
|
||||
virtual bool ReloadDevices() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual bool IsInitialized() = 0;
|
||||
|
||||
virtual void PollEvents() = 0;
|
||||
|
||||
/// InputBinding functions can be called while uninitialized
|
||||
virtual std::optional<InputBindingKey> ParseKeyString(const std::string_view device, const std::string_view binding) = 0;
|
||||
virtual TinyString ConvertKeyToString(InputBindingKey key) = 0;
|
||||
virtual TinyString ConvertKeyToString(InputBindingKey key, bool display = false, bool migration = false) = 0;
|
||||
virtual TinyString ConvertKeyToIcon(InputBindingKey key) = 0;
|
||||
|
||||
/// Enumerates available devices. Returns a pair of the prefix (e.g. SDL-0) and the device name.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "Input/InputSource.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
||||
bool ReloadDevices() override;
|
||||
void Shutdown() override;
|
||||
bool IsInitialized() override;
|
||||
|
||||
void PollEvents() override;
|
||||
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
||||
@@ -35,7 +36,7 @@ public:
|
||||
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
||||
|
||||
std::optional<InputBindingKey> ParseKeyString(const std::string_view device, const std::string_view binding) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key, bool display = false, bool migration = false) override;
|
||||
TinyString ConvertKeyToIcon(InputBindingKey key) override;
|
||||
|
||||
bool ProcessSDLEvent(const SDL_Event* event);
|
||||
@@ -50,17 +51,17 @@ private:
|
||||
struct ControllerData
|
||||
{
|
||||
SDL_Haptic* haptic;
|
||||
SDL_GameController* game_controller;
|
||||
SDL_Gamepad* gamepad;
|
||||
SDL_Joystick* joystick;
|
||||
u16 rumble_intensity[2];
|
||||
int haptic_left_right_effect;
|
||||
int joystick_id;
|
||||
SDL_JoystickID joystick_id;
|
||||
int player_id;
|
||||
bool use_game_controller_rumble;
|
||||
bool use_gamepad_rumble;
|
||||
|
||||
// Used to disable Joystick controls that are used in GameController inputs so we don't get double events
|
||||
std::vector<bool> joy_button_used_in_gc;
|
||||
std::vector<bool> joy_axis_used_in_gc;
|
||||
// Used to disable Joystick controls that are used in Gamepad inputs so we don't get double events
|
||||
std::vector<bool> joy_button_used_in_pad;
|
||||
std::vector<bool> joy_axis_used_in_pad;
|
||||
|
||||
// Track last hat state so we can send "unpressed" events.
|
||||
std::vector<u8> last_hat_state;
|
||||
@@ -77,10 +78,10 @@ private:
|
||||
ControllerDataVector::iterator GetControllerDataForPlayerId(int id);
|
||||
int GetFreePlayerId() const;
|
||||
|
||||
bool OpenDevice(int index, bool is_gamecontroller);
|
||||
bool OpenDevice(int index, bool is_gamepad);
|
||||
bool CloseDevice(int joystick_index);
|
||||
bool HandleControllerAxisEvent(const SDL_ControllerAxisEvent* ev);
|
||||
bool HandleControllerButtonEvent(const SDL_ControllerButtonEvent* ev);
|
||||
bool HandleGamepadAxisEvent(const SDL_GamepadAxisEvent* ev);
|
||||
bool HandleGamepadButtonEvent(const SDL_GamepadButtonEvent* ev);
|
||||
bool HandleJoystickAxisEvent(const SDL_JoyAxisEvent* ev);
|
||||
bool HandleJoystickButtonEvent(const SDL_JoyButtonEvent* ev);
|
||||
bool HandleJoystickHatEvent(const SDL_JoyHatEvent* ev);
|
||||
@@ -88,13 +89,22 @@ private:
|
||||
|
||||
ControllerDataVector m_controllers;
|
||||
|
||||
// ConvertKeyToString and ConvertKeyToIcon can inspect the
|
||||
// currently connected gamepad to provide matching labels
|
||||
// ParseKeyString can also inspect the gamepad for migrations
|
||||
// Those functions can be called on the main thread, while
|
||||
// gamepad addition/removal is done on the CPU thread
|
||||
std::mutex m_controllers_key_mutex;
|
||||
|
||||
std::vector<u32> m_gamepads_needing_migration;
|
||||
|
||||
std::array<u32, MAX_LED_COLORS> m_led_colors{};
|
||||
std::vector<std::pair<std::string, std::string>> m_sdl_hints;
|
||||
|
||||
bool m_sdl_subsystem_initialized = false;
|
||||
bool m_controller_enhanced_mode = false;
|
||||
bool m_controller_raw_mode = false;
|
||||
bool m_controller_ps5_player_led = false;
|
||||
bool m_enable_enhanced_reports = false;
|
||||
bool m_use_raw_input = false;
|
||||
bool m_enable_ps5_player_leds = false;
|
||||
|
||||
#ifdef __APPLE__
|
||||
bool m_enable_iokit_driver = false;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
static const char* s_axis_names[XInputSource::NUM_AXES] = {
|
||||
static const char* s_axis_setting_names[XInputSource::NUM_AXES] = {
|
||||
"LeftX", // AXIS_LEFTX
|
||||
"LeftY", // AXIS_LEFTY
|
||||
"RightX", // AXIS_RIGHTX
|
||||
@@ -22,6 +22,14 @@ static const char* s_axis_names[XInputSource::NUM_AXES] = {
|
||||
"LeftTrigger", // AXIS_TRIGGERLEFT
|
||||
"RightTrigger", // AXIS_TRIGGERRIGHT
|
||||
};
|
||||
static const char* s_axis_names[XInputSource::NUM_AXES] = {
|
||||
"Left X", // AXIS_LEFTX
|
||||
"Left Y", // AXIS_LEFTY
|
||||
"Right X", // AXIS_RIGHTX
|
||||
"Right Y", // AXIS_RIGHTY
|
||||
"Left Trigger", // AXIS_TRIGGERLEFT
|
||||
"Right Trigger", // AXIS_TRIGGERRIGHT
|
||||
};
|
||||
static constexpr const char* s_axis_icons[][2] = {
|
||||
{ICON_PF_LEFT_ANALOG_LEFT, ICON_PF_LEFT_ANALOG_RIGHT}, // AXIS_LEFTX
|
||||
{ICON_PF_LEFT_ANALOG_UP, ICON_PF_LEFT_ANALOG_DOWN}, // AXIS_LEFTY
|
||||
@@ -39,7 +47,7 @@ static const GenericInputBinding s_xinput_generic_binding_axis_mapping[][2] = {
|
||||
{GenericInputBinding::Unknown, GenericInputBinding::R2}, // AXIS_TRIGGERRIGHT
|
||||
};
|
||||
|
||||
static const char* s_button_names[XInputSource::NUM_BUTTONS] = {
|
||||
static const char* s_button_setting_names[XInputSource::NUM_BUTTONS] = {
|
||||
"DPadUp", // XINPUT_GAMEPAD_DPAD_UP
|
||||
"DPadDown", // XINPUT_GAMEPAD_DPAD_DOWN
|
||||
"DPadLeft", // XINPUT_GAMEPAD_DPAD_LEFT
|
||||
@@ -56,6 +64,24 @@ static const char* s_button_names[XInputSource::NUM_BUTTONS] = {
|
||||
"Y", // XINPUT_GAMEPAD_Y
|
||||
"Guide", // XINPUT_GAMEPAD_GUIDE
|
||||
};
|
||||
static const char* s_button_names[XInputSource::NUM_BUTTONS] = {
|
||||
"D-Pad Up", // XINPUT_GAMEPAD_DPAD_UP
|
||||
"D-Pad Down", // XINPUT_GAMEPAD_DPAD_DOWN
|
||||
"D-Pad Left", // XINPUT_GAMEPAD_DPAD_LEFT
|
||||
"D-Pad Right", // XINPUT_GAMEPAD_DPAD_RIGHT
|
||||
"Start", // XINPUT_GAMEPAD_START
|
||||
"Back", // XINPUT_GAMEPAD_BACK
|
||||
"Left Stick", // XINPUT_GAMEPAD_LEFT_THUMB
|
||||
"Right Stick", // XINPUT_GAMEPAD_RIGHT_THUMB
|
||||
"Left Shoulder", // XINPUT_GAMEPAD_LEFT_SHOULDER
|
||||
"Right Shoulder", // XINPUT_GAMEPAD_RIGHT_SHOULDER
|
||||
"A", // XINPUT_GAMEPAD_A
|
||||
"B", // XINPUT_GAMEPAD_B
|
||||
"X", // XINPUT_GAMEPAD_X
|
||||
"Y", // XINPUT_GAMEPAD_Y
|
||||
"Guide", // XINPUT_GAMEPAD_GUIDE
|
||||
};
|
||||
|
||||
static const u16 s_button_masks[XInputSource::NUM_BUTTONS] = {
|
||||
XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT, XINPUT_GAMEPAD_START,
|
||||
XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB, XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER,
|
||||
@@ -133,6 +159,8 @@ bool XInputSource::Initialize(SettingsInterface& si, std::unique_lock<std::mutex
|
||||
if (!m_xinput_get_state || !m_xinput_set_state || !m_xinput_get_capabilities)
|
||||
{
|
||||
Console.Error("Failed to get XInput function pointers.");
|
||||
FreeLibrary(m_xinput_module);
|
||||
m_xinput_module = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -196,6 +224,11 @@ void XInputSource::Shutdown()
|
||||
m_xinput_get_extended = nullptr;
|
||||
}
|
||||
|
||||
bool XInputSource::IsInitialized()
|
||||
{
|
||||
return m_xinput_module;
|
||||
}
|
||||
|
||||
void XInputSource::PollEvents()
|
||||
{
|
||||
for (u32 i = 0; i < NUM_CONTROLLERS; i++)
|
||||
@@ -287,9 +320,9 @@ std::optional<InputBindingKey> XInputSource::ParseKeyString(const std::string_vi
|
||||
{
|
||||
// likely an axis
|
||||
const std::string_view axis_name(binding.substr(1));
|
||||
for (u32 i = 0; i < std::size(s_axis_names); i++)
|
||||
for (u32 i = 0; i < std::size(s_axis_setting_names); i++)
|
||||
{
|
||||
if (axis_name == s_axis_names[i])
|
||||
if (axis_name == s_axis_setting_names[i])
|
||||
{
|
||||
// found an axis!
|
||||
key.source_subtype = InputSubclass::ControllerAxis;
|
||||
@@ -302,9 +335,9 @@ std::optional<InputBindingKey> XInputSource::ParseKeyString(const std::string_vi
|
||||
else
|
||||
{
|
||||
// must be a button
|
||||
for (u32 i = 0; i < std::size(s_button_names); i++)
|
||||
for (u32 i = 0; i < std::size(s_button_setting_names); i++)
|
||||
{
|
||||
if (binding == s_button_names[i])
|
||||
if (binding == s_button_setting_names[i])
|
||||
{
|
||||
key.source_subtype = InputSubclass::ControllerButton;
|
||||
key.data = i;
|
||||
@@ -317,24 +350,33 @@ std::optional<InputBindingKey> XInputSource::ParseKeyString(const std::string_vi
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
TinyString XInputSource::ConvertKeyToString(InputBindingKey key)
|
||||
TinyString XInputSource::ConvertKeyToString(InputBindingKey key, bool display, bool migration)
|
||||
{
|
||||
TinyString ret;
|
||||
|
||||
if (key.source_type == InputSourceType::XInput)
|
||||
{
|
||||
if (key.source_subtype == InputSubclass::ControllerAxis && key.data < std::size(s_axis_names))
|
||||
if (key.source_subtype == InputSubclass::ControllerAxis && key.data < std::size(s_axis_setting_names))
|
||||
{
|
||||
const char modifier = key.modifier == InputModifier::Negate ? '-' : '+';
|
||||
ret.format("XInput-{}/{}{}", static_cast<u32>(key.source_index), modifier, s_axis_names[key.data]);
|
||||
if (display)
|
||||
ret.format("XInput-{} {}{}", static_cast<u32>(key.source_index), modifier, s_axis_names[key.data]);
|
||||
else
|
||||
ret.format("XInput-{}/{}{}", static_cast<u32>(key.source_index), modifier, s_axis_setting_names[key.data]);
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::ControllerButton && key.data < std::size(s_button_names))
|
||||
else if (key.source_subtype == InputSubclass::ControllerButton && key.data < std::size(s_button_setting_names))
|
||||
{
|
||||
ret.format("XInput-{}/{}", static_cast<u32>(key.source_index), s_button_names[key.data]);
|
||||
if (display)
|
||||
ret.format("XInput-{} {}", static_cast<u32>(key.source_index), s_button_names[key.data]);
|
||||
else
|
||||
ret.format("XInput-{}/{}", static_cast<u32>(key.source_index), s_button_setting_names[key.data]);
|
||||
}
|
||||
else if (key.source_subtype == InputSubclass::ControllerMotor)
|
||||
{
|
||||
ret.format("XInput-{}/{}Motor", static_cast<u32>(key.source_index), key.data ? "Large" : "Small");
|
||||
if (display)
|
||||
ret.format("XInput-{} {} Motor", static_cast<u32>(key.source_index), key.data ? "Large" : "Small");
|
||||
else
|
||||
ret.format("XInput-{}/{}Motor", static_cast<u32>(key.source_index), key.data ? "Large" : "Small");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,16 +446,16 @@ bool XInputSource::GetGenericBindingMapping(const std::string_view device, Input
|
||||
const GenericInputBinding negative = s_xinput_generic_binding_axis_mapping[i][0];
|
||||
const GenericInputBinding positive = s_xinput_generic_binding_axis_mapping[i][1];
|
||||
if (negative != GenericInputBinding::Unknown)
|
||||
mapping->emplace_back(negative, fmt::format("XInput-{}/-{}", pid, s_axis_names[i]));
|
||||
mapping->emplace_back(negative, fmt::format("XInput-{}/-{}", pid, s_axis_setting_names[i]));
|
||||
|
||||
if (positive != GenericInputBinding::Unknown)
|
||||
mapping->emplace_back(positive, fmt::format("XInput-{}/+{}", pid, s_axis_names[i]));
|
||||
mapping->emplace_back(positive, fmt::format("XInput-{}/+{}", pid, s_axis_setting_names[i]));
|
||||
}
|
||||
for (u32 i = 0; i < std::size(s_xinput_generic_binding_button_mapping); i++)
|
||||
{
|
||||
const GenericInputBinding binding = s_xinput_generic_binding_button_mapping[i];
|
||||
if (binding != GenericInputBinding::Unknown)
|
||||
mapping->emplace_back(binding, fmt::format("XInput-{}/{}", pid, s_button_names[i]));
|
||||
mapping->emplace_back(binding, fmt::format("XInput-{}/{}", pid, s_button_setting_names[i]));
|
||||
}
|
||||
|
||||
if (m_controllers[pid].has_small_motor)
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
||||
bool ReloadDevices() override;
|
||||
void Shutdown() override;
|
||||
bool IsInitialized() override;
|
||||
|
||||
void PollEvents() override;
|
||||
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
||||
@@ -84,7 +85,7 @@ public:
|
||||
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
||||
|
||||
std::optional<InputBindingKey> ParseKeyString(const std::string_view device, const std::string_view binding) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key) override;
|
||||
TinyString ConvertKeyToString(InputBindingKey key, bool display = false, bool migration = false) override;
|
||||
TinyString ConvertKeyToIcon(InputBindingKey key) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -167,8 +167,8 @@ void Pad::SetDefaultControllerConfig(SettingsInterface& si)
|
||||
InputManager::InputSourceToString(static_cast<InputSourceType>(i)),
|
||||
InputManager::GetInputSourceDefaultEnabled(static_cast<InputSourceType>(i)));
|
||||
}
|
||||
si.SetBoolValue("InputSources", "SDLControllerEnhancedMode", false);
|
||||
si.SetBoolValue("InputSources", "SDLPS5PlayerLED", false);
|
||||
si.SetBoolValue("InputSources", "SDLControllerEnhancedMode", true);
|
||||
si.SetBoolValue("InputSources", "SDLPS5PlayerLED", true);
|
||||
si.SetBoolValue("Pad", "MultitapPort1", false);
|
||||
si.SetBoolValue("Pad", "MultitapPort2", false);
|
||||
si.SetFloatValue("Pad", "PointerXScale", 8.0f);
|
||||
|
||||
@@ -156,7 +156,6 @@ void MemcardBusy::ClearBusy()
|
||||
sioLastFrameMcdBusy = 0;
|
||||
}
|
||||
|
||||
#include "common/Console.h"
|
||||
void MemcardBusy::CheckSaveStateDependency()
|
||||
{
|
||||
if (g_FrameCount - sioLastFrameMcdBusy > NUM_FRAMES_BEFORE_SAVESTATE_DEPENDENCY_WARNING)
|
||||
|
||||
@@ -118,8 +118,8 @@ namespace AutoEject
|
||||
extern void ClearAll();
|
||||
} // namespace AutoEject
|
||||
|
||||
// ~1 hour of memory card inactivity.
|
||||
constexpr u32 NUM_FRAMES_BEFORE_SAVESTATE_DEPENDENCY_WARNING = 60 * 60 * 60;
|
||||
// ~2 hours of memory card inactivity.
|
||||
constexpr u32 NUM_FRAMES_BEFORE_SAVESTATE_DEPENDENCY_WARNING = 60 * 60 * 60 * 2;
|
||||
|
||||
// Set to the current frame count when there is memory card activity.
|
||||
// Used to detect the last frame when memory card activity was detected,
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace usb_pad
|
||||
{
|
||||
DestroyEffects();
|
||||
|
||||
SDL_HapticClose(m_haptic);
|
||||
SDL_CloseHaptic(m_haptic);
|
||||
m_haptic = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ namespace usb_pad
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SDL_Haptic* haptic = SDL_HapticOpenFromJoystick(joystick);
|
||||
SDL_Haptic* haptic = SDL_OpenHapticFromJoystick(joystick);
|
||||
if (!haptic)
|
||||
{
|
||||
Console.Error(fmt::format("Haptic is not supported on {}.", device));
|
||||
@@ -77,16 +77,16 @@ namespace usb_pad
|
||||
// - Simagic Alpha Mini: Does NOT implement infinite durations (stops after some time, seeking hard numbers)
|
||||
constexpr u32 length = SDL_HAPTIC_INFINITY;
|
||||
|
||||
const unsigned int supported = SDL_HapticQuery(m_haptic);
|
||||
const unsigned int supported = SDL_GetHapticFeatures(m_haptic);
|
||||
if (supported & SDL_HAPTIC_CONSTANT)
|
||||
{
|
||||
m_constant_effect.type = SDL_HAPTIC_CONSTANT;
|
||||
m_constant_effect.constant.direction.type = SDL_HAPTIC_STEERING_AXIS;
|
||||
m_constant_effect.constant.length = length;
|
||||
|
||||
m_constant_effect_id = SDL_HapticNewEffect(m_haptic, &m_constant_effect);
|
||||
m_constant_effect_id = SDL_CreateHapticEffect(m_haptic, &m_constant_effect);
|
||||
if (m_constant_effect_id < 0)
|
||||
Console.Error("SDL_HapticNewEffect() for constant failed: %s", SDL_GetError());
|
||||
Console.Error("SDL_CreateHapticEffect() for constant failed: %s", SDL_GetError());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -99,9 +99,9 @@ namespace usb_pad
|
||||
m_spring_effect.condition.direction.type = SDL_HAPTIC_STEERING_AXIS;
|
||||
m_spring_effect.condition.length = length;
|
||||
|
||||
m_spring_effect_id = SDL_HapticNewEffect(m_haptic, &m_spring_effect);
|
||||
m_spring_effect_id = SDL_CreateHapticEffect(m_haptic, &m_spring_effect);
|
||||
if (m_spring_effect_id < 0)
|
||||
Console.Error("SDL_HapticNewEffect() for spring failed: %s", SDL_GetError());
|
||||
Console.Error("SDL_CreateHapticEffect() for spring failed: %s", SDL_GetError());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -114,9 +114,9 @@ namespace usb_pad
|
||||
m_damper_effect.condition.direction.type = SDL_HAPTIC_STEERING_AXIS;
|
||||
m_damper_effect.condition.length = length;
|
||||
|
||||
m_damper_effect_id = SDL_HapticNewEffect(m_haptic, &m_damper_effect);
|
||||
m_damper_effect_id = SDL_CreateHapticEffect(m_haptic, &m_damper_effect);
|
||||
if (m_damper_effect_id < 0)
|
||||
Console.Error("SDL_HapticNewEffect() for damper failed: %s", SDL_GetError());
|
||||
Console.Error("SDL_CreateHapticEffect() for damper failed: %s", SDL_GetError());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -129,9 +129,9 @@ namespace usb_pad
|
||||
m_friction_effect.condition.direction.type = SDL_HAPTIC_STEERING_AXIS;
|
||||
m_friction_effect.condition.length = length;
|
||||
|
||||
m_friction_effect_id = SDL_HapticNewEffect(m_haptic, &m_friction_effect);
|
||||
m_friction_effect_id = SDL_CreateHapticEffect(m_haptic, &m_friction_effect);
|
||||
if (m_friction_effect_id < 0)
|
||||
Console.Error("SDL_HapticNewEffect() for friction failed: %s", SDL_GetError());
|
||||
Console.Error("SDL_CreateHapticEffect() for friction failed: %s", SDL_GetError());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -149,10 +149,10 @@ namespace usb_pad
|
||||
{
|
||||
if (m_friction_effect_running)
|
||||
{
|
||||
SDL_HapticStopEffect(m_haptic, m_friction_effect_id);
|
||||
SDL_StopHapticEffect(m_haptic, m_friction_effect_id);
|
||||
m_friction_effect_running = false;
|
||||
}
|
||||
SDL_HapticDestroyEffect(m_haptic, m_friction_effect_id);
|
||||
SDL_DestroyHapticEffect(m_haptic, m_friction_effect_id);
|
||||
m_friction_effect_id = -1;
|
||||
}
|
||||
|
||||
@@ -160,10 +160,10 @@ namespace usb_pad
|
||||
{
|
||||
if (m_damper_effect_running)
|
||||
{
|
||||
SDL_HapticStopEffect(m_haptic, m_damper_effect_id);
|
||||
SDL_StopHapticEffect(m_haptic, m_damper_effect_id);
|
||||
m_damper_effect_running = false;
|
||||
}
|
||||
SDL_HapticDestroyEffect(m_haptic, m_damper_effect_id);
|
||||
SDL_DestroyHapticEffect(m_haptic, m_damper_effect_id);
|
||||
m_damper_effect_id = -1;
|
||||
}
|
||||
|
||||
@@ -171,10 +171,10 @@ namespace usb_pad
|
||||
{
|
||||
if (m_spring_effect_running)
|
||||
{
|
||||
SDL_HapticStopEffect(m_haptic, m_spring_effect_id);
|
||||
SDL_StopHapticEffect(m_haptic, m_spring_effect_id);
|
||||
m_spring_effect_running = false;
|
||||
}
|
||||
SDL_HapticDestroyEffect(m_haptic, m_spring_effect_id);
|
||||
SDL_DestroyHapticEffect(m_haptic, m_spring_effect_id);
|
||||
m_spring_effect_id = -1;
|
||||
}
|
||||
|
||||
@@ -182,10 +182,10 @@ namespace usb_pad
|
||||
{
|
||||
if (m_constant_effect_running)
|
||||
{
|
||||
SDL_HapticStopEffect(m_haptic, m_constant_effect_id);
|
||||
SDL_StopHapticEffect(m_haptic, m_constant_effect_id);
|
||||
m_constant_effect_running = false;
|
||||
}
|
||||
SDL_HapticDestroyEffect(m_haptic, m_constant_effect_id);
|
||||
SDL_DestroyHapticEffect(m_haptic, m_constant_effect_id);
|
||||
m_constant_effect_id = -1;
|
||||
}
|
||||
}
|
||||
@@ -199,8 +199,8 @@ namespace usb_pad
|
||||
if (m_constant_effect.constant.level != new_level)
|
||||
{
|
||||
m_constant_effect.constant.level = new_level;
|
||||
if (SDL_HapticUpdateEffect(m_haptic, m_constant_effect_id, &m_constant_effect) != 0)
|
||||
Console.Warning("SDL_HapticUpdateEffect() for constant failed: %s", SDL_GetError());
|
||||
if (!SDL_UpdateHapticEffect(m_haptic, m_constant_effect_id, &m_constant_effect))
|
||||
Console.Warning("SDL_UpdateHapticEffect() for constant failed: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
// Avoid re-running already-running effects by default. Re-running a running effect
|
||||
@@ -217,10 +217,10 @@ namespace usb_pad
|
||||
// This is the reason for use_ffb_dropout_workaround.
|
||||
if (!m_constant_effect_running || use_ffb_dropout_workaround)
|
||||
{
|
||||
if (SDL_HapticRunEffect(m_haptic, m_constant_effect_id, SDL_HAPTIC_INFINITY) == 0)
|
||||
if (SDL_RunHapticEffect(m_haptic, m_constant_effect_id, SDL_HAPTIC_INFINITY))
|
||||
m_constant_effect_running = true;
|
||||
else
|
||||
Console.Error("SDL_HapticRunEffect() for constant failed: %s", SDL_GetError());
|
||||
Console.Error("SDL_RunHapticEffect() for constant failed: %s", SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,15 +248,15 @@ namespace usb_pad
|
||||
m_spring_effect.condition.deadband[0] = ClampU16(ff.u.condition.deadband);
|
||||
m_spring_effect.condition.center[0] = ClampS16(ff.u.condition.center);
|
||||
|
||||
if (SDL_HapticUpdateEffect(m_haptic, m_spring_effect_id, &m_spring_effect) != 0)
|
||||
Console.Warning("SDL_HapticUpdateEffect() for spring failed: %s", SDL_GetError());
|
||||
if (!SDL_UpdateHapticEffect(m_haptic, m_spring_effect_id, &m_spring_effect))
|
||||
Console.Warning("SDL_UpdateHapticEffect() for spring failed: %s", SDL_GetError());
|
||||
|
||||
if (!m_spring_effect_running)
|
||||
{
|
||||
if (SDL_HapticRunEffect(m_haptic, m_spring_effect_id, SDL_HAPTIC_INFINITY) == 0)
|
||||
if (SDL_RunHapticEffect(m_haptic, m_spring_effect_id, SDL_HAPTIC_INFINITY))
|
||||
m_spring_effect_running = true;
|
||||
else
|
||||
Console.Error("SDL_HapticRunEffect() for spring failed: %s", SDL_GetError());
|
||||
Console.Error("SDL_RunHapticEffect() for spring failed: %s", SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,15 +272,15 @@ namespace usb_pad
|
||||
m_damper_effect.condition.deadband[0] = ClampU16(ff.u.condition.deadband);
|
||||
m_damper_effect.condition.center[0] = ClampS16(ff.u.condition.center);
|
||||
|
||||
if (SDL_HapticUpdateEffect(m_haptic, m_damper_effect_id, &m_damper_effect) != 0)
|
||||
Console.Warning("SDL_HapticUpdateEffect() for damper failed: %s", SDL_GetError());
|
||||
if (!SDL_UpdateHapticEffect(m_haptic, m_damper_effect_id, &m_damper_effect))
|
||||
Console.Warning("SDL_UpdateHapticEffect() for damper failed: %s", SDL_GetError());
|
||||
|
||||
if (!m_damper_effect_running)
|
||||
{
|
||||
if (SDL_HapticRunEffect(m_haptic, m_damper_effect_id, SDL_HAPTIC_INFINITY) == 0)
|
||||
if (SDL_RunHapticEffect(m_haptic, m_damper_effect_id, SDL_HAPTIC_INFINITY))
|
||||
m_damper_effect_running = true;
|
||||
else
|
||||
Console.Error("SDL_HapticRunEffect() for damper failed: %s", SDL_GetError());
|
||||
Console.Error("SDL_RunHapticEffect() for damper failed: %s", SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,12 +296,12 @@ namespace usb_pad
|
||||
m_friction_effect.condition.deadband[0] = ClampU16(ff.u.condition.deadband);
|
||||
m_friction_effect.condition.center[0] = ClampS16(ff.u.condition.center);
|
||||
|
||||
if (SDL_HapticUpdateEffect(m_haptic, m_friction_effect_id, &m_friction_effect) != 0)
|
||||
if (!SDL_UpdateHapticEffect(m_haptic, m_friction_effect_id, &m_friction_effect))
|
||||
{
|
||||
if (!m_friction_effect_running && SDL_HapticRunEffect(m_haptic, m_friction_effect_id, SDL_HAPTIC_INFINITY) == 0)
|
||||
if (!m_friction_effect_running && SDL_RunHapticEffect(m_haptic, m_friction_effect_id, SDL_HAPTIC_INFINITY))
|
||||
m_friction_effect_running = true;
|
||||
else
|
||||
Console.Error("SDL_HapticUpdateEffect() for friction failed: %s", SDL_GetError());
|
||||
Console.Error("SDL_UpdateHapticEffect() for friction failed: %s", SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,8 +309,8 @@ namespace usb_pad
|
||||
{
|
||||
if (m_autocenter_supported)
|
||||
{
|
||||
if (SDL_HapticSetAutocenter(m_haptic, value) != 0)
|
||||
Console.Warning("SDL_HapticSetAutocenter() failed: %s", SDL_GetError());
|
||||
if (!SDL_SetHapticAutocenter(m_haptic, value))
|
||||
Console.Warning("SDL_SetHapticAutocenter() failed: %s", SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ namespace usb_pad
|
||||
{
|
||||
if (m_constant_effect_running)
|
||||
{
|
||||
SDL_HapticStopEffect(m_haptic, m_constant_effect_id);
|
||||
SDL_StopHapticEffect(m_haptic, m_constant_effect_id);
|
||||
m_constant_effect_running = false;
|
||||
}
|
||||
}
|
||||
@@ -332,7 +332,7 @@ namespace usb_pad
|
||||
{
|
||||
if (m_spring_effect_running)
|
||||
{
|
||||
SDL_HapticStopEffect(m_haptic, m_spring_effect_id);
|
||||
SDL_StopHapticEffect(m_haptic, m_spring_effect_id);
|
||||
m_spring_effect_running = false;
|
||||
}
|
||||
}
|
||||
@@ -342,7 +342,7 @@ namespace usb_pad
|
||||
{
|
||||
if (m_damper_effect_running)
|
||||
{
|
||||
SDL_HapticStopEffect(m_haptic, m_damper_effect_id);
|
||||
SDL_StopHapticEffect(m_haptic, m_damper_effect_id);
|
||||
m_damper_effect_running = false;
|
||||
}
|
||||
}
|
||||
@@ -352,7 +352,7 @@ namespace usb_pad
|
||||
{
|
||||
if (m_friction_effect_running)
|
||||
{
|
||||
SDL_HapticStopEffect(m_haptic, m_friction_effect_id);
|
||||
SDL_StopHapticEffect(m_haptic, m_friction_effect_id);
|
||||
m_friction_effect_running = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,10 +624,10 @@ void VMManager::ReloadInputSources()
|
||||
LoadInputBindings(*si, lock);
|
||||
}
|
||||
|
||||
void VMManager::ReloadInputBindings()
|
||||
void VMManager::ReloadInputBindings(bool force)
|
||||
{
|
||||
// skip loading bindings if we're not running, since it'll get done on startup anyway
|
||||
if (!HasValidVM())
|
||||
if (!force && !HasValidVM())
|
||||
return;
|
||||
|
||||
FPControlRegisterBackup fpcr_backup(FPControlRegister::GetDefault());
|
||||
@@ -662,19 +662,19 @@ void VMManager::LoadInputBindings(SettingsInterface& si, std::unique_lock<std::m
|
||||
const bool use_profile_hotkeys = isi->GetBoolValue("Pad", "UseProfileHotkeyBindings", false);
|
||||
if (use_profile_hotkeys)
|
||||
{
|
||||
InputManager::ReloadBindings(si, *isi, *isi);
|
||||
InputManager::ReloadBindings(si, *isi, *isi, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Temporarily disable the input profile layer, so it doesn't take precedence.
|
||||
Host::Internal::SetInputSettingsLayer(nullptr, lock);
|
||||
InputManager::ReloadBindings(si, *isi, si);
|
||||
InputManager::ReloadBindings(si, *isi, si, true, false);
|
||||
Host::Internal::SetInputSettingsLayer(s_input_settings_interface.get(), lock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InputManager::ReloadBindings(si, si, si);
|
||||
InputManager::ReloadBindings(si, si, si, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,8 @@ namespace VMManager
|
||||
void ReloadInputSources();
|
||||
|
||||
/// Reloads input bindings.
|
||||
void ReloadInputBindings();
|
||||
/// Can be forced to load even when there is not an active virtual machine.
|
||||
void ReloadInputBindings(bool force = false);
|
||||
|
||||
/// Returns the save state filename for the given game serial/crc.
|
||||
std::string GetSaveStateFileName(const char* game_serial, u32 game_crc, s32 slot);
|
||||
|
||||
@@ -198,6 +198,8 @@ void CTC2() {
|
||||
vu1Finish(true);
|
||||
vu1ExecMicro(cpuRegs.GPR.r[_Rt_].US[0]); // Execute VU1 Micro SubRoutine
|
||||
break;
|
||||
case REG_CLIP_FLAG:
|
||||
VU0.clipflag = cpuRegs.GPR.r[_Rt_].UL[0];
|
||||
default:
|
||||
VU0.VI[_Fs_].UL = cpuRegs.GPR.r[_Rt_].UL[0];
|
||||
break;
|
||||
|
||||
1319
pcsx2/VUops.cpp
1319
pcsx2/VUops.cpp
File diff suppressed because it is too large
Load Diff
@@ -5,14 +5,6 @@
|
||||
#include "VU.h"
|
||||
#include "VUflags.h"
|
||||
|
||||
#define float_to_int4(x) ((float)x * (1.0f / 0.0625f))
|
||||
#define float_to_int12(x) ((float)x * (1.0f / 0.000244140625f))
|
||||
#define float_to_int15(x) ((float)x * (1.0f / 0.000030517578125))
|
||||
|
||||
#define int4_to_float(x) (float)((float)x * 0.0625f)
|
||||
#define int12_to_float(x) (float)((float)x * 0.000244140625f)
|
||||
#define int15_to_float(x) (float)((float)x * 0.000030517578125)
|
||||
|
||||
struct _VURegsNum {
|
||||
u8 pipe; // if 0xff, COP2
|
||||
u8 VFwrite;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DepsIncludeDir)\SDL2</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DepsIncludeDir)\SDL3</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\fmt\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\winwil\include</AdditionalIncludeDirectories>
|
||||
|
||||
@@ -109,7 +109,7 @@ void _freeX86reg(int x86reg);
|
||||
void _freeX86regWithoutWriteback(int x86reg);
|
||||
void _freeX86regs();
|
||||
void _flushX86regs();
|
||||
void _flushConstRegs();
|
||||
void _flushConstRegs(bool delete_const);
|
||||
void _flushConstReg(int reg);
|
||||
void _validateRegs();
|
||||
void _writebackX86Reg(int x86reg);
|
||||
|
||||
@@ -105,7 +105,7 @@ void _flushConstReg(int reg)
|
||||
}
|
||||
}
|
||||
|
||||
void _flushConstRegs()
|
||||
void _flushConstRegs(bool delete_const)
|
||||
{
|
||||
int zero_reg_count = 0;
|
||||
int minusone_reg_count = 0;
|
||||
@@ -134,6 +134,8 @@ void _flushConstRegs()
|
||||
{
|
||||
xMOV(ptr64[&cpuRegs.GPR.r[i].UD[0]], rax);
|
||||
g_cpuFlushedConstReg |= 1u << i;
|
||||
if (delete_const)
|
||||
g_cpuHasConstReg &= ~(1u << i);
|
||||
}
|
||||
}
|
||||
rax_is_zero = true;
|
||||
@@ -154,6 +156,8 @@ void _flushConstRegs()
|
||||
{
|
||||
xMOV(ptr64[&cpuRegs.GPR.r[i].UD[0]], rax);
|
||||
g_cpuFlushedConstReg |= 1u << i;
|
||||
if (delete_const)
|
||||
g_cpuHasConstReg &= ~(1u << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,6 +170,8 @@ void _flushConstRegs()
|
||||
|
||||
xWriteImm64ToMem(&cpuRegs.GPR.r[i].UD[0], rax, g_cpuConstRegs[i].UD[0]);
|
||||
g_cpuFlushedConstReg |= 1u << i;
|
||||
if (delete_const)
|
||||
g_cpuHasConstReg &= ~(1u << i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ void _eeFlushAllDirty()
|
||||
_flushX86regs();
|
||||
|
||||
// flush constants, do them all at once for slightly better codegen
|
||||
_flushConstRegs();
|
||||
_flushConstRegs(false);
|
||||
}
|
||||
|
||||
void _eeMoveGPRtoR(const xRegister32& to, int fromgpr, bool allow_preload)
|
||||
@@ -1225,7 +1225,7 @@ void iFlushCall(int flushtype)
|
||||
_flushXMMregs();
|
||||
|
||||
if (flushtype & FLUSH_CONSTANT_REGS)
|
||||
_flushConstRegs();
|
||||
_flushConstRegs(true);
|
||||
|
||||
if ((flushtype & FLUSH_PC) && !g_cpuFlushedPC)
|
||||
{
|
||||
|
||||
@@ -16,49 +16,42 @@ struct microVU;
|
||||
|
||||
struct mVU_Globals
|
||||
{
|
||||
u32 absclip[4], signbit[4], minvals[4], maxvals[4];
|
||||
u32 one[4];
|
||||
u32 Pi4[4];
|
||||
u32 T1[4], T2[4], T3[4], T4[4], T5[4], T6[4], T7[4], T8[4];
|
||||
u32 S2[4], S3[4], S4[4], S5[4];
|
||||
u32 E1[4], E2[4], E3[4], E4[4], E5[4], E6[4];
|
||||
float FTOI_4[4], FTOI_12[4], FTOI_15[4];
|
||||
float ITOF_4[4], ITOF_12[4], ITOF_15[4];
|
||||
#define __four(val) { val, val, val, val }
|
||||
u32 absclip [4] = __four(0x7fffffff);
|
||||
u32 signbit [4] = __four(0x80000000);
|
||||
u32 minvals [4] = __four(0xff7fffff);
|
||||
u32 maxvals [4] = __four(0x7f7fffff);
|
||||
u32 exponent[4] = __four(0x7f800000);
|
||||
u32 one [4] = __four(0x3f800000);
|
||||
u32 Pi4 [4] = __four(0x3f490fdb);
|
||||
u32 T1 [4] = __four(0x3f7ffff5);
|
||||
u32 T5 [4] = __four(0xbeaaa61c);
|
||||
u32 T2 [4] = __four(0x3e4c40a6);
|
||||
u32 T3 [4] = __four(0xbe0e6c63);
|
||||
u32 T4 [4] = __four(0x3dc577df);
|
||||
u32 T6 [4] = __four(0xbd6501c4);
|
||||
u32 T7 [4] = __four(0x3cb31652);
|
||||
u32 T8 [4] = __four(0xbb84d7e7);
|
||||
u32 S2 [4] = __four(0xbe2aaaa4);
|
||||
u32 S3 [4] = __four(0x3c08873e);
|
||||
u32 S4 [4] = __four(0xb94fb21f);
|
||||
u32 S5 [4] = __four(0x362e9c14);
|
||||
u32 E1 [4] = __four(0x3e7fffa8);
|
||||
u32 E2 [4] = __four(0x3d0007f4);
|
||||
u32 E3 [4] = __four(0x3b29d3ff);
|
||||
u32 E4 [4] = __four(0x3933e553);
|
||||
u32 E5 [4] = __four(0x36b63510);
|
||||
u32 E6 [4] = __four(0x353961ac);
|
||||
float FTOI_4 [4] = __four(16.0);
|
||||
float FTOI_12 [4] = __four(4096.0);
|
||||
float FTOI_15 [4] = __four(32768.0);
|
||||
float ITOF_4 [4] = __four(0.0625f);
|
||||
float ITOF_12 [4] = __four(0.000244140625);
|
||||
float ITOF_15 [4] = __four(0.000030517578125);
|
||||
#undef __four
|
||||
};
|
||||
|
||||
#define __four(val) { val, val, val, val }
|
||||
alignas(32) static const mVU_Globals mVUglob = {
|
||||
__four(0x7fffffff), // absclip
|
||||
__four(0x80000000), // signbit
|
||||
__four(0xff7fffff), // minvals
|
||||
__four(0x7f7fffff), // maxvals
|
||||
__four(0x3f800000), // ONE!
|
||||
__four(0x3f490fdb), // PI4!
|
||||
__four(0x3f7ffff5), // T1
|
||||
__four(0xbeaaa61c), // T5
|
||||
__four(0x3e4c40a6), // T2
|
||||
__four(0xbe0e6c63), // T3
|
||||
__four(0x3dc577df), // T4
|
||||
__four(0xbd6501c4), // T6
|
||||
__four(0x3cb31652), // T7
|
||||
__four(0xbb84d7e7), // T8
|
||||
__four(0xbe2aaaa4), // S2
|
||||
__four(0x3c08873e), // S3
|
||||
__four(0xb94fb21f), // S4
|
||||
__four(0x362e9c14), // S5
|
||||
__four(0x3e7fffa8), // E1
|
||||
__four(0x3d0007f4), // E2
|
||||
__four(0x3b29d3ff), // E3
|
||||
__four(0x3933e553), // E4
|
||||
__four(0x36b63510), // E5
|
||||
__four(0x353961ac), // E6
|
||||
__four(16.0), // FTOI_4
|
||||
__four(4096.0), // FTOI_12
|
||||
__four(32768.0), // FTOI_15
|
||||
__four(0.0625f), // ITOF_4
|
||||
__four(0.000244140625), // ITOF_12
|
||||
__four(0.000030517578125) // ITOF_15
|
||||
};
|
||||
alignas(32) static constexpr struct mVU_Globals mVUglob;
|
||||
|
||||
static const uint _Ibit_ = 1 << 31;
|
||||
static const uint _Ebit_ = 1 << 30;
|
||||
|
||||
@@ -544,36 +544,36 @@ mVUop(mVU_CLIP)
|
||||
const xmm& Fs = mVU.regAlloc->allocReg(_Fs_, 0, 0xf);
|
||||
const xmm& Ft = mVU.regAlloc->allocReg(_Ft_, 0, 0x1);
|
||||
const xmm& t1 = mVU.regAlloc->allocReg();
|
||||
const xmm& t2 = mVU.regAlloc->allocReg();
|
||||
|
||||
mVUunpack_xyzw(Ft, Ft, 0);
|
||||
mVUallocCFLAGa(mVU, gprT1, cFLAG.lastWrite);
|
||||
xSHL(gprT1, 6);
|
||||
|
||||
xAND.PS(Ft, ptr128[mVUglob.absclip]);
|
||||
xMOVAPS(t1, Ft);
|
||||
xPOR(t1, ptr128[mVUglob.signbit]);
|
||||
xMOVAPS (t1, ptr128[mVUglob.exponent]);
|
||||
xPAND (t1, Fs);
|
||||
xPXOR (t2, t2);
|
||||
xPCMP.EQD(t1, t2); // Denormal check
|
||||
xPANDN (t1, Fs); // If denormal, set to zero, which can't be greater than any nonnegative denormal in Ft
|
||||
xPAND (Ft, ptr128[mVUglob.absclip]);
|
||||
|
||||
xCMPNLE.PS(t1, Fs); // -w, -z, -y, -x
|
||||
xCMPLT.PS(Ft, Fs); // +w, +z, +y, +x
|
||||
xMOVAPS (Fs, ptr128[mVUglob.signbit]);
|
||||
xPXOR (Fs, t1); // Negate
|
||||
xPCMP.GTD(t1, Ft); // +w, +z, +y, +x
|
||||
xPCMP.GTD(Fs, Ft); // -w, -z, -y, -x
|
||||
|
||||
xMOVAPS(Fs, Ft); // Fs = +w, +z, +y, +x
|
||||
xUNPCK.LPS(Ft, t1); // Ft = -y,+y,-x,+x
|
||||
xUNPCK.HPS(Fs, t1); // Fs = -w,+w,-z,+z
|
||||
|
||||
xMOVMSKPS(gprT2, Fs); // -w,+w,-z,+z
|
||||
xAND(gprT2, 0x3);
|
||||
xSHL(gprT2, 4);
|
||||
xOR(gprT1, gprT2);
|
||||
|
||||
xMOVMSKPS(gprT2, Ft); // -y,+y,-x,+x
|
||||
xAND(gprT2, 0xf);
|
||||
xOR(gprT1, gprT2);
|
||||
xAND(gprT1, 0xffffff);
|
||||
xPBLEND.W (Fs, t1, 0x55); // Squish together
|
||||
xPACK.SSWB(Fs, Fs); // Convert u16 to u8
|
||||
xPMOVMSKB (gprT2, Fs); // Get bitmask
|
||||
xAND (gprT2, 0x3f); // Mask unused stuff
|
||||
xAND (gprT1, 0xffffff);
|
||||
xOR (gprT1, gprT2);
|
||||
|
||||
mVUallocCFLAGb(mVU, gprT1, cFLAG.write);
|
||||
mVU.regAlloc->clearNeeded(Fs);
|
||||
mVU.regAlloc->clearNeeded(Ft);
|
||||
mVU.regAlloc->clearNeeded(t1);
|
||||
mVU.regAlloc->clearNeeded(t2);
|
||||
mVU.profiler.EmitOp(opCLIP);
|
||||
}
|
||||
pass3
|
||||
|
||||
@@ -153,6 +153,8 @@ TEST(CodegenTests, SSETest)
|
||||
CODEGEN_TEST(xMOVAPS(ptr128[rax+r9], xmm8), "46 0f 29 04 08");
|
||||
CODEGEN_TEST(xBLEND.PS(xmm0, xmm1, 0x55), "66 0f 3a 0c c1 55");
|
||||
CODEGEN_TEST(xBLEND.PD(xmm8, xmm9, 0xaa), "66 45 0f 3a 0d c1 aa");
|
||||
CODEGEN_TEST(xPBLEND.W(xmm0, xmm1, 0x55), "66 0f 3a 0e c1 55");
|
||||
CODEGEN_TEST(xPBLEND.VB(xmm1, xmm2), "66 0f 38 10 ca");
|
||||
CODEGEN_TEST(xEXTRACTPS(ptr32[base], xmm1, 2), "66 0f 3a 17 0d f6 ff ff ff 02");
|
||||
CODEGEN_TEST(xMOVD(eax, xmm1), "66 0f 7e c8");
|
||||
CODEGEN_TEST(xMOVD(eax, xmm10), "66 44 0f 7e d0");
|
||||
|
||||
@@ -60,16 +60,16 @@ else()
|
||||
target_sources(core_test PRIVATE ${multi_isa_sources})
|
||||
endif()
|
||||
|
||||
if(WIN32 AND TARGET SDL2::SDL2)
|
||||
# Copy SDL2 DLL to binary directory.
|
||||
if(WIN32 AND TARGET SDL3::SDL3)
|
||||
# Copy SDL3 DLL to binary directory.
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
get_property(SDL2_DLL_PATH TARGET SDL2::SDL2 PROPERTY IMPORTED_LOCATION_DEBUG)
|
||||
get_property(SDL3_DLL_PATH TARGET SDL3::SDL3 PROPERTY IMPORTED_LOCATION_DEBUG)
|
||||
else()
|
||||
get_property(SDL2_DLL_PATH TARGET SDL2::SDL2 PROPERTY IMPORTED_LOCATION_RELEASE)
|
||||
get_property(SDL3_DLL_PATH TARGET SDL3::SDL3 PROPERTY IMPORTED_LOCATION_RELEASE)
|
||||
endif()
|
||||
if(SDL2_DLL_PATH)
|
||||
if(SDL3_DLL_PATH)
|
||||
add_custom_command(TARGET core_test POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:core_test>"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${SDL2_DLL_PATH}" "$<TARGET_FILE_DIR:core_test>")
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${SDL3_DLL_PATH}" "$<TARGET_FILE_DIR:core_test>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -39,6 +39,10 @@ std::unique_ptr<ProgressCallback> Host::CreateHostProgressCallback()
|
||||
return ProgressCallback::CreateNullProgressCallback();
|
||||
}
|
||||
|
||||
void Host::ReportInfoAsync(const std::string_view title, const std::string_view message)
|
||||
{
|
||||
}
|
||||
|
||||
void Host::ReportErrorAsync(const std::string_view title, const std::string_view message)
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user