Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dfd1846b93 | ||
|
|
872205abc6 | ||
|
|
c52cebd20a | ||
|
|
f449b54f87 | ||
|
|
ffcb6e2f6f | ||
|
|
5daa1aa115 | ||
|
|
1dc009f752 | ||
|
|
009b4ff5e7 | ||
|
|
f1a947af92 | ||
|
|
97c098b1ff | ||
|
|
e252cb6643 | ||
|
|
75c0236e1e | ||
|
|
9c4a98bc25 | ||
|
|
9cba11cde5 | ||
|
|
fac5512b04 | ||
|
|
ed9bf05971 | ||
|
|
19d0f3bdc5 | ||
|
|
2abe53de43 | ||
|
|
37a25750d7 | ||
|
|
d3e288447f |
25
.github/workflows/scripts/linux/appimage-qt.sh
vendored
@@ -63,9 +63,9 @@ declare -a REMOVE_LIBS=(
|
||||
|
||||
set -e
|
||||
|
||||
LINUXDEPLOY=./linuxdeploy-x86_64
|
||||
LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64
|
||||
APPIMAGETOOL=./appimagetool-x86_64
|
||||
LINUXDEPLOY=./linuxdeploy-x86_64.AppImage
|
||||
LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
APPIMAGETOOL=./appimagetool-x86_64.AppImage
|
||||
PATCHELF=patchelf
|
||||
|
||||
if [ ! -f "$LINUXDEPLOY" ]; then
|
||||
@@ -78,11 +78,8 @@ if [ ! -f "$LINUXDEPLOY_PLUGIN_QT" ]; then
|
||||
chmod +x "$LINUXDEPLOY_PLUGIN_QT"
|
||||
fi
|
||||
|
||||
# Using go-appimage
|
||||
# Backported from https://github.com/stenzek/duckstation/pull/3251
|
||||
if [ ! -f "$APPIMAGETOOL" ]; then
|
||||
APPIMAGETOOLURL=$(wget -q https://api.github.com/repos/probonopd/go-appimage/releases -O - | sed 's/[()",{} ]/\n/g' | grep -o 'https.*continuous.*tool.*86_64.*mage$' | head -1)
|
||||
"$PCSX2DIR/tools/retry.sh" wget -O "$APPIMAGETOOL" "$APPIMAGETOOLURL"
|
||||
"$PCSX2DIR/tools/retry.sh" wget -O "$APPIMAGETOOL" https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
chmod +x "$APPIMAGETOOL"
|
||||
fi
|
||||
|
||||
@@ -190,17 +187,6 @@ echo "Generating AppStream metainfo..."
|
||||
mkdir -p "$OUTDIR/usr/share/metainfo"
|
||||
"$SCRIPTDIR/generate-metainfo.sh" "$OUTDIR/usr/share/metainfo/net.pcsx2.PCSX2.appdata.xml"
|
||||
|
||||
# Copy in AppRun hooks.
|
||||
# Unfortunately linuxdeploy is a bit lame and doesn't let us provide our own AppRun hooks, instead
|
||||
# they have to come from plugins.. and screw writing one of those just to disable Wayland.
|
||||
echo "Copying AppRun hooks..."
|
||||
mkdir -p "$OUTDIR/apprun-hooks"
|
||||
for hookpath in "$SCRIPTDIR/apprun-hooks"/*; do
|
||||
hookname=$(basename "$hookpath")
|
||||
cp -v "$hookpath" "$OUTDIR/apprun-hooks/$hookname"
|
||||
sed -i -e 's/exec /source "$this_dir"\/apprun-hooks\/"'"$hookname"'"\nexec /' "$OUTDIR/AppRun"
|
||||
done
|
||||
|
||||
echo "Generating AppImage..."
|
||||
GIT_VERSION=$(git tag --points-at HEAD)
|
||||
|
||||
@@ -213,5 +199,4 @@ if [[ "${GIT_VERSION}" == "" ]]; then
|
||||
fi
|
||||
|
||||
rm -f "$NAME.AppImage"
|
||||
ARCH=x86_64 VERSION="${GIT_VERSION}" "$APPIMAGETOOL" -s "$OUTDIR" && mv ./*.AppImage "$NAME.AppImage"
|
||||
|
||||
$APPIMAGETOOL -v "$OUTDIR" "$NAME.AppImage"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
if [[ -z "$I_WANT_A_BROKEN_WAYLAND_UI" ]]; then
|
||||
echo "Forcing X11 instead of Wayland, due to various protocol limitations"
|
||||
echo "and Qt issues. If you want to use Wayland, launch PCSX2 with"
|
||||
echo "I_WANT_A_BROKEN_WAYLAND_UI=YES set."
|
||||
export QT_QPA_PLATFORM=xcb
|
||||
else
|
||||
echo "Wayland is not being disabled. Do not complain when things break."
|
||||
fi
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
"--device=all",
|
||||
"--share=network",
|
||||
"--share=ipc",
|
||||
"--socket=x11",
|
||||
"--socket=wayland",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=pulseaudio",
|
||||
"--talk-name=org.freedesktop.ScreenSaver",
|
||||
"--env=QT_QPA_PLATFORM=xcb"
|
||||
"--talk-name=org.freedesktop.ScreenSaver"
|
||||
],
|
||||
"modules": [
|
||||
"modules/10-libpcap.json",
|
||||
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 2.3 MiB |
@@ -6,17 +6,21 @@
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0+</project_license>
|
||||
<name>PCSX2</name>
|
||||
<developer_name>PCSX2</developer_name>
|
||||
<summary>PlayStation 2 Emulator</summary>
|
||||
<developer id="net.pcsx2">
|
||||
<name>PCSX2 Team</name>
|
||||
</developer>
|
||||
<summary>PlayStation 2 emulator</summary>
|
||||
<description>
|
||||
<p>PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a combination of MIPS CPU Interpreters, Recompilers, and a Virtual Machine which manages hardware states and PS2 system memory. This allows you to play PS2 games on your PC, with many additional features and benefits.</p>
|
||||
<p>PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not affiliated in any way with Sony Interactive Entertainment.</p>
|
||||
</description>
|
||||
<url type="homepage">https://pcsx2.net/</url>
|
||||
<url type="vcs-browser">https://github.com/PCSX2/pcsx2</url>
|
||||
<url type="bugtracker">https://github.com/PCSX2/pcsx2/issues</url>
|
||||
<url type="donation">https://github.com/sponsors/PCSX2</url>
|
||||
<url type="faq">https://pcsx2.net/docs/</url>
|
||||
<url type="help">https://pcsx2.net/discord</url>
|
||||
<url type="contribute">https://github.com/PCSX2/pcsx2/blob/master/.github/CONTRIBUTING.md</url>
|
||||
<url type="translate">https://crowdin.com/project/pcsx2-emulator</url>
|
||||
<url type="contact">https://mastodon.social/@PCSX2</url>
|
||||
<screenshots>
|
||||
@@ -37,6 +41,26 @@
|
||||
</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<categories>
|
||||
<category>Game</category>
|
||||
<category>Emulator</category>
|
||||
</categories>
|
||||
<branding>
|
||||
<color type="primary" scheme_preference="light">#3584e4</color>
|
||||
<color type="primary" scheme_preference="dark">#241f31</color>
|
||||
</branding>
|
||||
<supports>
|
||||
<control>keyboard</control>
|
||||
<control>pointing</control>
|
||||
<internet>offline-only</internet>
|
||||
</supports>
|
||||
<recommends>
|
||||
<control>gamepad</control>
|
||||
<memory>8192</memory>
|
||||
</recommends>
|
||||
<requires>
|
||||
<display_length compare="ge">768</display_length>
|
||||
</requires>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<update_contact>pcsx2_AT_pcsx2.net</update_contact>
|
||||
<releases>
|
||||
|
||||
@@ -2015,7 +2015,6 @@ SCAJ-20132:
|
||||
eeClampMode: 2 # Fixes wrong color on some characters and breakable objects.
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 1 # Fixes ghosting characters.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SCAJ-20133:
|
||||
name: "Kagero 2 - Dark Illusion"
|
||||
@@ -13630,7 +13629,7 @@ SLED-53954:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLED-53977:
|
||||
name: "Dragon Quest - The Journey of the Cursed King"
|
||||
region: "PAL-E"
|
||||
@@ -15351,7 +15350,6 @@ SLES-50723:
|
||||
name: "TOCA Race Driver"
|
||||
region: "PAL-M3"
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes lighting.
|
||||
halfPixelOffset: 1 # Fixes vertical lines
|
||||
SLES-50725:
|
||||
name: "V-Rally 3"
|
||||
@@ -15449,7 +15447,6 @@ SLES-50767:
|
||||
name: "V8 Supercars Australia - Race Driver"
|
||||
region: "PAL-A"
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes lighting.
|
||||
halfPixelOffset: 1 # Fixes vertical lines
|
||||
SLES-50768:
|
||||
name: "Rally Championship"
|
||||
@@ -15616,13 +15613,11 @@ SLES-50816:
|
||||
region: "PAL-M3"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes lighting.
|
||||
halfPixelOffset: 1 # Fixes vertical lines
|
||||
SLES-50818:
|
||||
name: "Pro Race Driver"
|
||||
region: "PAL-I"
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes lighting.
|
||||
halfPixelOffset: 1 # Fixes vertical lines
|
||||
SLES-50820:
|
||||
name: "Micro Machines"
|
||||
@@ -18283,7 +18278,7 @@ SLES-51914:
|
||||
- "SLES-51914"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Mostly aligns post processing.
|
||||
nativeScaling: 2 # Fixes post processing smoothness and position.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
disablePartialInvalidation: 1 # Fixes textureless graphics ingame.
|
||||
bilinearUpscale: 2 # Gets rid of center vertical line when upscaling.
|
||||
SLES-51915:
|
||||
@@ -22913,7 +22908,7 @@ SLES-53556:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLES-53557:
|
||||
name: "Need for Speed - Most Wanted"
|
||||
region: "PAL-E"
|
||||
@@ -23703,7 +23698,6 @@ SLES-53794:
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Fix effects upscaling.
|
||||
nativeScaling: 2 # Fixes post effects.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SLES-53796:
|
||||
name: "FIFA Street 2"
|
||||
@@ -24385,7 +24379,7 @@ SLES-54027:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLES-54030:
|
||||
name: "Black"
|
||||
region: "PAL-E"
|
||||
@@ -25141,7 +25135,7 @@ SLES-54317:
|
||||
region: "PAL-M5"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes alignment on fire effects.
|
||||
halfPixelOffset: 4 # Fixes alignment on fire effects.
|
||||
SLES-54319:
|
||||
name: "Biker Mice from Mars"
|
||||
region: "PAL-M5"
|
||||
@@ -25713,7 +25707,6 @@ SLES-54483:
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes car reflections.
|
||||
mergeSprite: 1 # Fixes bluriness.
|
||||
halfPixelOffset: 4 # Fixes bluriness.
|
||||
nativeScaling: 2 # Fixes post lighting.
|
||||
autoFlush: 1 # Fixes post alignment.
|
||||
@@ -29913,7 +29906,7 @@ SLKA-25093:
|
||||
- "SLKA-25093"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Mostly aligns post processing.
|
||||
nativeScaling: 2 # Fixes post processing smoothness and position.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
disablePartialInvalidation: 1 # Fixes textureless graphics ingame.
|
||||
bilinearUpscale: 2 # Gets rid of center vertical line when upscaling.
|
||||
SLKA-25095:
|
||||
@@ -30986,7 +30979,7 @@ SLKA-25341:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLKA-25342:
|
||||
name: "Ryu ga Gotoku"
|
||||
region: "NTSC-K"
|
||||
@@ -32048,7 +32041,6 @@ SLPM-55081:
|
||||
eeClampMode: 2 # Fixes wrong color on some characters and breakable objects.
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 1 # Fixes ghosting characters.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SLPM-55082:
|
||||
name: "真・三國無双5 Special [ディスク 1]"
|
||||
@@ -34510,7 +34502,6 @@ SLPM-61120:
|
||||
eeClampMode: 2 # Fixes wrong color on some characters and breakable objects.
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 1 # Fixes ghosting characters.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SLPM-61121:
|
||||
name: "KAIDO ~峠の伝説~ [体験版]"
|
||||
@@ -41214,7 +41205,7 @@ SLPM-65413:
|
||||
- "SLPM-65413"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Mostly aligns post processing.
|
||||
nativeScaling: 2 # Fixes post processing smoothness and position.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
disablePartialInvalidation: 1 # Fixes textureless graphics ingame.
|
||||
bilinearUpscale: 2 # Gets rid of center vertical line when upscaling.
|
||||
SLPM-65414:
|
||||
@@ -44547,7 +44538,6 @@ SLPM-65999:
|
||||
eeClampMode: 2 # Fixes wrong color on some characters and breakable objects.
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 1 # Fixes ghosting characters.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SLPM-66000:
|
||||
name: "コンフリクトデルタⅡ ~湾岸戦争1991~"
|
||||
@@ -48135,7 +48125,7 @@ SLPM-66567:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLPM-66568:
|
||||
name: "ブラザー イン アームズ ロード トゥ ヒル サーティ [UBISOFT BEST]"
|
||||
name-sort: "ぶらざー いん あーむず ろーど とぅ ひる さーてぃ [UBISOFT BEST]"
|
||||
@@ -62650,7 +62640,6 @@ SLUS-20329:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes lighting.
|
||||
halfPixelOffset: 1 # Fixes vertical lines
|
||||
SLUS-20330:
|
||||
name: "NBA 2K2 - Sega Sports"
|
||||
@@ -64556,7 +64545,7 @@ SLUS-20694:
|
||||
- "SLUS-20710"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Mostly aligns post processing.
|
||||
nativeScaling: 2 # Fixes post processing smoothness and position.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
disablePartialInvalidation: 1 # Fixes textureless graphics ingame.
|
||||
bilinearUpscale: 2 # Gets rid of center vertical line when upscaling.
|
||||
SLUS-20695:
|
||||
@@ -67988,7 +67977,7 @@ SLUS-21271:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLUS-21272:
|
||||
name: "Super Monkey Ball Adventure"
|
||||
region: "NTSC-U"
|
||||
@@ -68244,7 +68233,7 @@ SLUS-21306:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
mergeSprite: 1 # Fixes alignment on fire effects.
|
||||
halfPixelOffset: 4 # Fixes alignment on fire effects.
|
||||
SLUS-21307:
|
||||
name: "Ice Age 2 - The Meltdown"
|
||||
region: "NTSC-U"
|
||||
@@ -68706,7 +68695,6 @@ SLUS-21373:
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 4 # Fix effects upscaling.
|
||||
nativeScaling: 2 # Fixes post effects.
|
||||
mergeSprite: 1 # Align sprite fixes FMVs but not garbage in-game, so needs merge sprite instead.
|
||||
texturePreloading: 1 # Performs better with partial preload because it is slow on locations outside gameplay foremost.
|
||||
SLUS-21374:
|
||||
name: "Marvel - Ultimate Alliance"
|
||||
@@ -68886,7 +68874,7 @@ SLUS-21399:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLUS-21400:
|
||||
name: "Monster House"
|
||||
region: "NTSC-U"
|
||||
@@ -69212,7 +69200,6 @@ SLUS-21449:
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes car reflections.
|
||||
mergeSprite: 1 # Fixes bluriness.
|
||||
halfPixelOffset: 4 # Fixes bluriness.
|
||||
nativeScaling: 2 # Fixes post lighting.
|
||||
autoFlush: 1 # Fixes post alignment.
|
||||
@@ -72687,7 +72674,7 @@ SLUS-29185:
|
||||
cpuSpriteRenderBW: 2 # Fixes some bad textures.
|
||||
cpuCLUTRender: 1 # Fixes the rest of the bad textures.
|
||||
roundSprite: 1 # Reduces misaligned bloom.
|
||||
mergeSprite: 1 # Removes bloom explosion around electrical lights and other light sources such as moon/sun.
|
||||
nativeScaling: 1 # Fixes post processing smoothness and position.
|
||||
SLUS-29188:
|
||||
name: "Steambot Chronicles [Regular Demo]"
|
||||
region: "NTSC-U"
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 91 KiB |
@@ -111,7 +111,7 @@ layout(binding = 3) uniform sampler2D img_prim_min;
|
||||
//layout(pixel_center_integer) in vec4 gl_FragCoord;
|
||||
#endif
|
||||
|
||||
vec4 fetch_rt()
|
||||
vec4 sample_from_rt()
|
||||
{
|
||||
#if !NEEDS_RT
|
||||
return vec4(0.0);
|
||||
@@ -127,7 +127,7 @@ vec4 fetch_rt()
|
||||
vec4 sample_c(vec2 uv)
|
||||
{
|
||||
#if PS_TEX_IS_FB == 1
|
||||
return fetch_rt();
|
||||
return sample_from_rt();
|
||||
#elif PS_REGION_RECT
|
||||
return texelFetch(TextureSampler, ivec2(uv), 0);
|
||||
#else
|
||||
@@ -312,7 +312,7 @@ int fetch_raw_depth()
|
||||
float multiplier = exp2(32.0f);
|
||||
|
||||
#if PS_TEX_IS_FB == 1
|
||||
return int(fetch_rt().r * multiplier);
|
||||
return int(sample_from_rt().r * multiplier);
|
||||
#else
|
||||
return int(texelFetch(TextureSampler, ivec2(gl_FragCoord.xy), 0).r * multiplier);
|
||||
#endif
|
||||
@@ -321,7 +321,7 @@ int fetch_raw_depth()
|
||||
vec4 fetch_raw_color()
|
||||
{
|
||||
#if PS_TEX_IS_FB == 1
|
||||
return fetch_rt();
|
||||
return sample_from_rt();
|
||||
#else
|
||||
return texelFetch(TextureSampler, ivec2(gl_FragCoord.xy), 0);
|
||||
#endif
|
||||
@@ -697,8 +697,6 @@ vec4 ps_color()
|
||||
|
||||
vec4 C = tfx(T, PSin.c);
|
||||
|
||||
atst(C);
|
||||
|
||||
fog(C, PSin.t_float.z);
|
||||
|
||||
return C;
|
||||
@@ -709,9 +707,9 @@ void ps_fbmask(inout vec4 C)
|
||||
// FIXME do I need special case for 16 bits
|
||||
#if PS_FBMASK
|
||||
#if PS_HDR == 1
|
||||
vec4 RT = trunc(fetch_rt() * 65535.0f);
|
||||
vec4 RT = trunc(sample_from_rt() * 65535.0f);
|
||||
#else
|
||||
vec4 RT = trunc(fetch_rt() * 255.0f + 0.1f);
|
||||
vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
|
||||
#endif
|
||||
C = vec4((uvec4(C) & ~FbMask) | (uvec4(RT) & FbMask));
|
||||
#endif
|
||||
@@ -799,7 +797,7 @@ float As = As_rgba.a;
|
||||
#endif
|
||||
|
||||
#if SW_BLEND_NEEDS_RT
|
||||
vec4 RT = fetch_rt();
|
||||
vec4 RT = sample_from_rt();
|
||||
#else
|
||||
// Not used, but we define it to make the selection below simpler.
|
||||
vec4 RT = vec4(0.0f);
|
||||
@@ -974,9 +972,9 @@ void ps_main()
|
||||
|
||||
#if PS_WRITE_RG == 1
|
||||
// Pseudo 16 bits access.
|
||||
float rt_a = fetch_rt().g;
|
||||
float rt_a = sample_from_rt().g;
|
||||
#else
|
||||
float rt_a = fetch_rt().a;
|
||||
float rt_a = sample_from_rt().a;
|
||||
#endif
|
||||
|
||||
#if (PS_DATE & 3) == 1
|
||||
@@ -1028,9 +1026,9 @@ void ps_main()
|
||||
|
||||
#if SW_AD_TO_HW
|
||||
#if PS_RTA_CORRECTION
|
||||
vec4 RT = trunc(fetch_rt() * 128.0f + 0.1f);
|
||||
vec4 RT = trunc(sample_from_rt() * 128.0f + 0.1f);
|
||||
#else
|
||||
vec4 RT = trunc(fetch_rt() * 255.0f + 0.1f);
|
||||
vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
|
||||
#endif
|
||||
|
||||
vec4 alpha_blend = vec4(RT.a / 128.0f);
|
||||
|
||||
@@ -954,7 +954,7 @@ vec4 ps_color()
|
||||
T.a = float(denorm_c_before.a & 0x80u);
|
||||
#else
|
||||
T.r = float((denorm_c_before.r << 3) & 0xF8u);
|
||||
T.g = float(((denorm_c_before.r >> 2) & 0x38) | ((denorm_c_before.g << 6) & 0xC0u));
|
||||
T.g = float(((denorm_c_before.r >> 2) & 0x38u) | ((denorm_c_before.g << 6) & 0xC0u));
|
||||
T.b = float((denorm_c_before.g << 1) & 0xF8u);
|
||||
T.a = float(denorm_c_before.g & 0x80u);
|
||||
#endif
|
||||
|
||||
@@ -168,6 +168,7 @@ else()
|
||||
${DBUS_LINK_LIBRARIES}
|
||||
X11::X11
|
||||
X11::Xrandr
|
||||
X11::Xi
|
||||
)
|
||||
if(USE_BACKTRACE)
|
||||
target_compile_definitions(common PRIVATE "HAS_LIBBACKTRACE=1")
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <mach/task.h>
|
||||
#include <mach/vm_map.h>
|
||||
#include <mutex>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||
|
||||
// Darwin (OSX) is a bit different from Linux when requesting properties of
|
||||
@@ -127,6 +128,69 @@ bool Common::InhibitScreensaver(bool inhibit)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Common::SetMousePosition(int x, int y)
|
||||
{
|
||||
// Little bit ugly but;
|
||||
// Creating mouse move events and posting them wasn't very reliable.
|
||||
// Calling CGWarpMouseCursorPosition without CGAssociateMouseAndMouseCursorPosition(false)
|
||||
// ends up with the cursor feeling "sticky".
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
CGWarpMouseCursorPosition(CGPointMake(x, y));
|
||||
CGAssociateMouseAndMouseCursorPosition(true); // The default state
|
||||
return;
|
||||
}
|
||||
|
||||
CFMachPortRef mouseEventTap = nullptr;
|
||||
CFRunLoopSourceRef mouseRunLoopSource = nullptr;
|
||||
|
||||
static std::function<void(int, int)> fnMouseMoveCb;
|
||||
CGEventRef mouseMoveCallback(CGEventTapProxy, CGEventType type, CGEventRef event, void* arg)
|
||||
{
|
||||
if (type == kCGEventMouseMoved)
|
||||
{
|
||||
const CGPoint location = CGEventGetLocation(event);
|
||||
fnMouseMoveCb(location.x, location.y);
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
bool Common::AttachMousePositionCb(std::function<void(int, int)> cb)
|
||||
{
|
||||
if (!AXIsProcessTrusted())
|
||||
{
|
||||
Console.Warning("Process isn't trusted with accessibility permissions. Mouse tracking will not work!");
|
||||
}
|
||||
|
||||
fnMouseMoveCb = cb;
|
||||
mouseEventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault,
|
||||
CGEventMaskBit(kCGEventMouseMoved), mouseMoveCallback, nullptr);
|
||||
if (!mouseEventTap)
|
||||
{
|
||||
Console.Warning("Unable to create mouse moved event tap. Mouse tracking will not work!");
|
||||
return false;
|
||||
}
|
||||
|
||||
mouseRunLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, mouseEventTap, 0);
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), mouseRunLoopSource, kCFRunLoopCommonModes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Common::DetachMousePositionCb()
|
||||
{
|
||||
if (mouseRunLoopSource)
|
||||
{
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), mouseRunLoopSource, kCFRunLoopCommonModes);
|
||||
CFRelease(mouseRunLoopSource);
|
||||
}
|
||||
if (mouseEventTap)
|
||||
{
|
||||
CFRelease(mouseEventTap);
|
||||
}
|
||||
mouseRunLoopSource = nullptr;
|
||||
mouseEventTap = nullptr;
|
||||
}
|
||||
|
||||
void Threading::Sleep(int ms)
|
||||
{
|
||||
usleep(1000 * ms);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "common/Pcsx2Defs.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -198,4 +199,8 @@ namespace Common
|
||||
/// Abstracts platform-specific code for asynchronously playing a sound.
|
||||
/// On Windows, this will use PlaySound(). On Linux, it will shell out to aplay. On MacOS, it uses NSSound.
|
||||
bool PlaySoundAsync(const char* path);
|
||||
|
||||
void SetMousePosition(int x, int y);
|
||||
bool AttachMousePositionCb(std::function<void(int,int)> cb);
|
||||
void DetachMousePositionCb();
|
||||
} // namespace Common
|
||||
|
||||
@@ -13,17 +13,20 @@
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <optional>
|
||||
#include <dbus/dbus.h>
|
||||
#include <spawn.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <dbus/dbus.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <ctype.h>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
|
||||
// Returns 0 on failure (not supported by the operating system).
|
||||
u64 GetPhysicalMemory()
|
||||
@@ -177,6 +180,111 @@ bool Common::InhibitScreensaver(bool inhibit)
|
||||
return SetScreensaverInhibitDBus(inhibit, "PCSX2", "PCSX2 VM is running.");
|
||||
}
|
||||
|
||||
void Common::SetMousePosition(int x, int y)
|
||||
{
|
||||
Display* display = XOpenDisplay(nullptr);
|
||||
if (!display)
|
||||
return;
|
||||
|
||||
Window root = DefaultRootWindow(display);
|
||||
XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);
|
||||
XFlush(display);
|
||||
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
|
||||
static std::function<void(int, int)> fnMouseMoveCb;
|
||||
static std::atomic<bool> trackingMouse = false;
|
||||
static std::thread mouseThread;
|
||||
|
||||
void mouseEventLoop()
|
||||
{
|
||||
Threading::SetNameOfCurrentThread("X11 Mouse Thread");
|
||||
Display* display = XOpenDisplay(nullptr);
|
||||
if (!display)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int opcode, eventcode, error;
|
||||
if (!XQueryExtension(display, "XInputExtension", &opcode, &eventcode, &error))
|
||||
{
|
||||
XCloseDisplay(display);
|
||||
return;
|
||||
}
|
||||
|
||||
const Window root = DefaultRootWindow(display);
|
||||
XIEventMask evmask;
|
||||
unsigned char mask[(XI_LASTEVENT + 7) / 8] = {0};
|
||||
|
||||
evmask.deviceid = XIAllDevices;
|
||||
evmask.mask_len = sizeof(mask);
|
||||
evmask.mask = mask;
|
||||
XISetMask(mask, XI_RawMotion);
|
||||
|
||||
XISelectEvents(display, root, &evmask, 1);
|
||||
XSync(display, False);
|
||||
|
||||
XEvent event;
|
||||
while (trackingMouse)
|
||||
{
|
||||
// XNextEvent is blocking, this is a zombie process risk if no events arrive
|
||||
// while we are trying to shutdown.
|
||||
// https://nrk.neocities.org/articles/x11-timeout-with-xsyncalarm might be
|
||||
// a better solution than using XPending.
|
||||
if (!XPending(display))
|
||||
{
|
||||
Threading::Sleep(1);
|
||||
Threading::SpinWait();
|
||||
continue;
|
||||
}
|
||||
|
||||
XNextEvent(display, &event);
|
||||
if (event.xcookie.type == GenericEvent &&
|
||||
event.xcookie.extension == opcode &&
|
||||
XGetEventData(display, &event.xcookie))
|
||||
{
|
||||
XIRawEvent* raw_event = reinterpret_cast<XIRawEvent*>(event.xcookie.data);
|
||||
if (raw_event->evtype == XI_RawMotion)
|
||||
{
|
||||
Window w;
|
||||
int root_x, root_y, win_x, win_y;
|
||||
unsigned int mask;
|
||||
XQueryPointer(display, root, &w, &w, &root_x, &root_y, &win_x, &win_y, &mask);
|
||||
|
||||
if (fnMouseMoveCb)
|
||||
fnMouseMoveCb(root_x, root_y);
|
||||
}
|
||||
XFreeEventData(display, &event.xcookie);
|
||||
}
|
||||
}
|
||||
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
|
||||
bool Common::AttachMousePositionCb(std::function<void(int, int)> cb)
|
||||
{
|
||||
fnMouseMoveCb = cb;
|
||||
|
||||
if (trackingMouse)
|
||||
return true;
|
||||
|
||||
trackingMouse = true;
|
||||
mouseThread = std::thread(mouseEventLoop);
|
||||
mouseThread.detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Common::DetachMousePositionCb()
|
||||
{
|
||||
trackingMouse = false;
|
||||
fnMouseMoveCb = nullptr;
|
||||
if (mouseThread.joinable())
|
||||
{
|
||||
mouseThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
bool Common::PlaySoundAsync(const char* path)
|
||||
{
|
||||
#ifdef __linux__
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "common/Console.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/HostSys.h"
|
||||
#include "common/RedtapeWindows.h"
|
||||
@@ -86,6 +87,61 @@ bool Common::InhibitScreensaver(bool inhibit)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Common::SetMousePosition(int x, int y)
|
||||
{
|
||||
SetCursorPos(x, y);
|
||||
}
|
||||
|
||||
/*
|
||||
static HHOOK mouseHook = nullptr;
|
||||
static std::function<void(int, int)> fnMouseMoveCb;
|
||||
LRESULT CALLBACK Mousecb(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (nCode >= 0 && wParam == WM_MOUSEMOVE)
|
||||
{
|
||||
MSLLHOOKSTRUCT* mouse = (MSLLHOOKSTRUCT*)lParam;
|
||||
fnMouseMoveCb(mouse->pt.x, mouse->pt.y);
|
||||
}
|
||||
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
|
||||
}
|
||||
*/
|
||||
|
||||
// This (and the above) works, but is not recommended on Windows and is only here for consistency.
|
||||
// Defer to using raw input instead.
|
||||
bool Common::AttachMousePositionCb(std::function<void(int, int)> cb)
|
||||
{
|
||||
/*
|
||||
if (mouseHook)
|
||||
Common::DetachMousePositionCb();
|
||||
|
||||
fnMouseMoveCb = cb;
|
||||
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, Mousecb, GetModuleHandle(NULL), 0);
|
||||
if (!mouseHook)
|
||||
{
|
||||
Console.Warning("Failed to set mouse hook: %d", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(PCSX2_DEBUG) || defined(PCSX2_DEVBUILD)
|
||||
static bool warned = false;
|
||||
if (!warned)
|
||||
{
|
||||
Console.Warning("Mouse hooks are enabled, and this isn't a release build! Using a debugger, or loading symbols, _will_ stall the hook and cause global mouse lag.");
|
||||
warned = true;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
void Common::DetachMousePositionCb()
|
||||
{
|
||||
/*
|
||||
UnhookWindowsHookEx(mouseHook);
|
||||
mouseHook = nullptr;
|
||||
*/
|
||||
}
|
||||
|
||||
bool Common::PlaySoundAsync(const char* path)
|
||||
{
|
||||
const std::wstring wpath = FileSystem::GetWin32Path(path);
|
||||
|
||||
@@ -104,6 +104,15 @@ MainWindow::MainWindow()
|
||||
pxAssert(!g_main_window);
|
||||
g_main_window = this;
|
||||
|
||||
// Native window rendering is broken in wayland.
|
||||
// Let's work around it by disabling it for every widget besides
|
||||
// DisplayWidget.
|
||||
// Additionally, alien widget rendering is much more performant, so we
|
||||
// should have a nice responsiveness boost in our UI :)
|
||||
// QTBUG-133919, reported upstream by govanify
|
||||
QGuiApplication::setAttribute(Qt::AA_NativeWindows, false);
|
||||
QGuiApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
s_use_central_widget = DisplayContainer::isRunningOnWayland();
|
||||
#endif
|
||||
@@ -115,6 +124,8 @@ MainWindow::~MainWindow()
|
||||
cancelGameListRefresh();
|
||||
destroySubWindows();
|
||||
|
||||
Common::DetachMousePositionCb();
|
||||
|
||||
// we compare here, since recreate destroys the window later
|
||||
if (g_main_window == this)
|
||||
g_main_window = nullptr;
|
||||
@@ -150,6 +161,9 @@ void MainWindow::initialize()
|
||||
#ifdef _WIN32
|
||||
registerForDeviceNotifications();
|
||||
#endif
|
||||
|
||||
if (Host::GetBoolSettingValue("EmuCore", "EnableMouseLock", false))
|
||||
setupMouseMoveHandler();
|
||||
}
|
||||
|
||||
// TODO: Figure out how to set this in the .ui file
|
||||
@@ -1071,6 +1085,21 @@ bool MainWindow::shouldHideMainWindow() const
|
||||
QtHost::InNoGUIMode();
|
||||
}
|
||||
|
||||
bool MainWindow::shouldMouseLock() const
|
||||
{
|
||||
if (!s_vm_valid || s_vm_paused)
|
||||
return false;
|
||||
|
||||
if (!Host::GetBoolSettingValue("EmuCore", "EnableMouseLock", false))
|
||||
return false;
|
||||
|
||||
bool windowsHidden = (!m_debugger_window || m_debugger_window->isHidden()) &&
|
||||
(!m_controller_settings_window || m_controller_settings_window->isHidden()) &&
|
||||
(!m_settings_window || m_settings_window->isHidden());
|
||||
|
||||
return windowsHidden && (isActiveWindow() || isRenderingFullscreen());
|
||||
}
|
||||
|
||||
bool MainWindow::shouldAbortForMemcardBusy(const VMLock& lock)
|
||||
{
|
||||
if (MemcardBusy::IsBusy() && !GSDumpReplayer::IsReplayingDump())
|
||||
@@ -2234,6 +2263,15 @@ void MainWindow::registerForDeviceNotifications()
|
||||
DEV_BROADCAST_DEVICEINTERFACE_W filter = {sizeof(DEV_BROADCAST_DEVICEINTERFACE_W), DBT_DEVTYP_DEVICEINTERFACE};
|
||||
m_device_notification_handle =
|
||||
RegisterDeviceNotificationW((HANDLE)winId(), &filter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
|
||||
|
||||
// Set up the raw input device for mouse grabbing
|
||||
RAWINPUTDEVICE rid;
|
||||
rid.usUsagePage = 0x01; // Generic desktop controls
|
||||
rid.usUsage = 0x02; // Mouse
|
||||
rid.dwFlags = RIDEV_INPUTSINK;
|
||||
rid.hwndTarget = (HWND)winId();
|
||||
|
||||
RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2262,6 +2300,26 @@ bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr
|
||||
*result = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg->message == WM_INPUT)
|
||||
{
|
||||
UINT dwSize = 40;
|
||||
static BYTE lpb[40];
|
||||
if (GetRawInputData((HRAWINPUT)msg->lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)))
|
||||
{
|
||||
const RAWINPUT* raw = (RAWINPUT*)lpb;
|
||||
if (raw->header.dwType == RIM_TYPEMOUSE)
|
||||
{
|
||||
const RAWMOUSE& mouse = raw->data.mouse;
|
||||
if (mouse.usFlags == MOUSE_MOVE_ABSOLUTE || mouse.usFlags == MOUSE_MOVE_RELATIVE)
|
||||
{
|
||||
POINT cursorPos;
|
||||
GetCursorPos(&cursorPos);
|
||||
checkMousePosition(cursorPos.x, cursorPos.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QMainWindow::nativeEvent(eventType, message, result);
|
||||
@@ -2541,6 +2599,53 @@ QWidget* MainWindow::getDisplayContainer() const
|
||||
return (m_display_container ? static_cast<QWidget*>(m_display_container) : static_cast<QWidget*>(m_display_widget));
|
||||
}
|
||||
|
||||
void MainWindow::setupMouseMoveHandler()
|
||||
{
|
||||
auto mouse_cb_fn = [](int x, int y)
|
||||
{
|
||||
if(g_main_window)
|
||||
g_main_window->checkMousePosition(x, y);
|
||||
};
|
||||
|
||||
if(!Common::AttachMousePositionCb(mouse_cb_fn))
|
||||
{
|
||||
Console.Warning("Unable to setup mouse position cb!");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void MainWindow::checkMousePosition(int x, int y)
|
||||
{
|
||||
if (!shouldMouseLock())
|
||||
return;
|
||||
|
||||
const QPoint globalCursorPos = {x, y};
|
||||
QRect windowBounds = isRenderingFullscreen() ? screen()->geometry() : geometry();
|
||||
if (windowBounds.contains(globalCursorPos))
|
||||
return;
|
||||
|
||||
Common::SetMousePosition(
|
||||
std::clamp(globalCursorPos.x(), windowBounds.left(), windowBounds.right()),
|
||||
std::clamp(globalCursorPos.y(), windowBounds.top(), windowBounds.bottom()));
|
||||
|
||||
/*
|
||||
Provided below is how we would handle this if we were using low level hooks (What is used in Common::AttachMouseCb)
|
||||
We currently use rawmouse on Windows, so Common::SetMousePosition called directly works fine.
|
||||
*/
|
||||
#if 0
|
||||
// We are currently in a low level hook. SetCursorPos here (what is in Common::SetMousePosition) will not work!
|
||||
// Let's (a)buse Qt's event loop to dispatch the call at a later time, outside of the hook.
|
||||
QMetaObject::invokeMethod(
|
||||
this, [=]() {
|
||||
Common::SetMousePosition(
|
||||
std::clamp(globalCursorPos.x(), windowBounds.left(), windowBounds.right()),
|
||||
std::clamp(globalCursorPos.y(), windowBounds.top(), windowBounds.bottom()));
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::saveDisplayWindowGeometryToConfig()
|
||||
{
|
||||
QWidget* container = getDisplayContainer();
|
||||
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
void rescanFile(const std::string& path);
|
||||
|
||||
void openDebugger();
|
||||
|
||||
void checkMousePosition(int x, int y);
|
||||
public Q_SLOTS:
|
||||
void checkForUpdates(bool display_message, bool force_check);
|
||||
void refreshGameList(bool invalidate_cache);
|
||||
@@ -128,7 +128,7 @@ private Q_SLOTS:
|
||||
void mouseModeRequested(bool relative_mode, bool hide_cursor);
|
||||
void releaseRenderWindow();
|
||||
void focusDisplayWidget();
|
||||
|
||||
void setupMouseMoveHandler();
|
||||
void onGameListRefreshComplete();
|
||||
void onGameListRefreshProgress(const QString& status, int current, int total);
|
||||
void onGameListSelectionChanged();
|
||||
@@ -182,7 +182,6 @@ private Q_SLOTS:
|
||||
void onInputRecPlayActionTriggered();
|
||||
void onInputRecStopActionTriggered();
|
||||
void onInputRecOpenViewer();
|
||||
|
||||
void onVMStarting();
|
||||
void onVMStarted();
|
||||
void onVMPaused();
|
||||
@@ -240,6 +239,7 @@ private:
|
||||
bool isRenderingToMain() const;
|
||||
bool shouldHideMouseCursor() const;
|
||||
bool shouldHideMainWindow() const;
|
||||
bool shouldMouseLock() const;
|
||||
void switchToGameListView();
|
||||
void switchToEmulationView();
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "InterfaceSettingsWidget.h"
|
||||
#include "AutoUpdaterDialog.h"
|
||||
#include "Common.h"
|
||||
#include "MainWindow.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsWindow.h"
|
||||
@@ -36,6 +37,8 @@ const char* InterfaceSettingsWidget::THEME_NAMES[] = {
|
||||
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Cobalt Sky (Blue) [Dark]"),
|
||||
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "AMOLED (Black) [Dark]"),
|
||||
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Ruby (Black/Red) [Dark]"),
|
||||
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Sapphire (Black/Blue) [Dark]"),
|
||||
@@ -61,6 +64,7 @@ const char* InterfaceSettingsWidget::THEME_VALUES[] = {
|
||||
"ScarletDevilRed",
|
||||
"VioletAngelPurple",
|
||||
"CobaltSky",
|
||||
"AMOLED",
|
||||
"Ruby",
|
||||
"Sapphire",
|
||||
"Emerald",
|
||||
@@ -80,6 +84,13 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* dialog, QWidget
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pauseOnControllerDisconnection, "UI", "PauseOnControllerDisconnection", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.discordPresence, "EmuCore", "EnableDiscordPresence", false);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.mouseLock, "EmuCore", "EnableMouseLock", false);
|
||||
connect(m_ui.mouseLock, &QCheckBox::checkStateChanged, [](Qt::CheckState state) {
|
||||
if (state == Qt::Checked)
|
||||
Common::AttachMousePositionCb([](int x, int y) { g_main_window->checkMousePosition(x, y); });
|
||||
else
|
||||
Common::DetachMousePositionCb();
|
||||
});
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.startFullscreen, "UI", "StartFullscreen", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.doubleClickTogglesFullscreen, "UI", "DoubleClickTogglesFullscreen",
|
||||
true);
|
||||
@@ -161,6 +172,9 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* dialog, QWidget
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.discordPresence, tr("Enable Discord Presence"), tr("Unchecked"),
|
||||
tr("Shows the game you are currently playing as part of your profile in Discord."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.mouseLock, tr("Enable Mouse Lock"), tr("Unchecked"),
|
||||
tr("Locks the mouse cursor to the windows when PCSX2 is in focus and all other windows are closed.<br><b>Unavailable on Linux Wayland.</b><br><b>Requires accessibility permissions on macOS.</b>"));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.doubleClickTogglesFullscreen, tr("Double-Click Toggles Fullscreen"), tr("Checked"),
|
||||
tr("Allows switching in and out of fullscreen mode by double-clicking the game window."));
|
||||
|
||||
@@ -50,6 +50,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="mouseLock">
|
||||
<property name="text">
|
||||
<string>Enable Mouse Lock</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="pauseOnStart">
|
||||
<property name="text">
|
||||
|
||||
@@ -183,6 +183,14 @@ QString MemoryCardSettingsWidget::getSelectedCard() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool MemoryCardSettingsWidget::isSelectedCardFormatted() const
|
||||
{
|
||||
const QList<QTreeWidgetItem*> selection(m_ui.cardList->selectedItems());
|
||||
if (!selection.empty())
|
||||
return selection[0]->data(0, Qt::UserRole).toBool();
|
||||
return false;
|
||||
}
|
||||
|
||||
void MemoryCardSettingsWidget::updateCardActions()
|
||||
{
|
||||
QString selectedCard = getSelectedCard();
|
||||
@@ -263,6 +271,12 @@ void MemoryCardSettingsWidget::convertCard()
|
||||
if (selectedCard.isEmpty())
|
||||
return;
|
||||
|
||||
if (!isSelectedCardFormatted())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Cannot convert an unformatted memory card."));
|
||||
return;
|
||||
}
|
||||
|
||||
MemoryCardConvertDialog dialog(QtUtils::GetRootWidget(this), selectedCard);
|
||||
|
||||
if (dialog.IsSetup() && dialog.exec() == QDialog::Accepted)
|
||||
@@ -442,6 +456,10 @@ void MemoryCardListWidget::refresh(SettingsWindow* dialog)
|
||||
item->setText(1, getSizeSummary(mcd));
|
||||
item->setText(2, mcd.formatted ? tr("Yes") : tr("No"));
|
||||
item->setText(3, mtime.toString(QLocale::system().dateTimeFormat(QLocale::ShortFormat)));
|
||||
|
||||
// store formatted metadata
|
||||
item->setData(0, Qt::UserRole, mcd.formatted);
|
||||
|
||||
addTopLevelItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ private:
|
||||
void createCard();
|
||||
|
||||
QString getSelectedCard() const;
|
||||
bool isSelectedCardFormatted() const;
|
||||
void updateCardActions();
|
||||
void deleteCard();
|
||||
void renameCard();
|
||||
|
||||
@@ -280,7 +280,7 @@ void QtHost::SetStyleFromSettings()
|
||||
pizzaPalette.setColor(QPalette::Link, highlight.darker());
|
||||
pizzaPalette.setColor(QPalette::Highlight, highlight);
|
||||
pizzaPalette.setColor(QPalette::HighlightedText, Qt::white);
|
||||
|
||||
|
||||
pizzaPalette.setColor(QPalette::Active, QPalette::Button, extr);
|
||||
pizzaPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray.darker());
|
||||
pizzaPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray.darker());
|
||||
@@ -428,6 +428,42 @@ void QtHost::SetStyleFromSettings()
|
||||
qApp->setPalette(cobaltSkyPalette);
|
||||
qApp->setStyleSheet(QString());
|
||||
}
|
||||
else if (theme == "AMOLED")
|
||||
{
|
||||
// Custom palette by KamFretoZ, A pure concentrated darkness
|
||||
// of a theme designed for maximum eye comfort and benefits
|
||||
// OLED screens.
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
|
||||
const QColor black(0, 0, 0);
|
||||
const QColor gray(25, 25, 25);
|
||||
const QColor lighterGray(75, 75, 75);
|
||||
const QColor blue(198, 238, 255);
|
||||
|
||||
QPalette AMOLEDPalette;
|
||||
AMOLEDPalette.setColor(QPalette::Window, black);
|
||||
AMOLEDPalette.setColor(QPalette::WindowText, Qt::white);
|
||||
AMOLEDPalette.setColor(QPalette::Base, gray);
|
||||
AMOLEDPalette.setColor(QPalette::AlternateBase, black);
|
||||
AMOLEDPalette.setColor(QPalette::ToolTipBase, gray);
|
||||
AMOLEDPalette.setColor(QPalette::ToolTipText, Qt::white);
|
||||
AMOLEDPalette.setColor(QPalette::Text, Qt::white);
|
||||
AMOLEDPalette.setColor(QPalette::Button, gray);
|
||||
AMOLEDPalette.setColor(QPalette::ButtonText, Qt::white);
|
||||
AMOLEDPalette.setColor(QPalette::Link, blue);
|
||||
AMOLEDPalette.setColor(QPalette::Highlight, lighterGray);
|
||||
AMOLEDPalette.setColor(QPalette::HighlightedText, Qt::white);
|
||||
AMOLEDPalette.setColor(QPalette::PlaceholderText, QColor(Qt::white).darker());
|
||||
|
||||
AMOLEDPalette.setColor(QPalette::Active, QPalette::Button, gray);
|
||||
AMOLEDPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(Qt::white).darker());
|
||||
AMOLEDPalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(Qt::white).darker());
|
||||
AMOLEDPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(Qt::white).darker());
|
||||
AMOLEDPalette.setColor(QPalette::Disabled, QPalette::Light, QColor(Qt::white).darker());
|
||||
|
||||
qApp->setPalette(AMOLEDPalette);
|
||||
qApp->setStyleSheet(QString());
|
||||
}
|
||||
else if (theme == "Ruby")
|
||||
{
|
||||
// Custom palette by Daisouji, Black as main color and Red as complimentary.
|
||||
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 6.1 KiB |
@@ -2750,7 +2750,7 @@ void GSRendererHW::Draw()
|
||||
|
||||
// Preserve downscaled target when copying directly from a downscaled target, or it's a normal draw using a downscaled target. Clears that are drawing to the target can also preserve size.
|
||||
// Of course if this size is different (in width) or this is a shuffle happening, this will be bypassed.
|
||||
const bool preserve_downscale_draw = scale_draw < 0 || (scale_draw == 0 && ((src && src->m_from_target && src->m_from_target->m_downscaled) || is_possible_mem_clear == ClearType::ClearWithDraw));
|
||||
const bool preserve_downscale_draw = std::abs(scale_draw) == 1 || (scale_draw == 0 && ((src && src->m_from_target && src->m_from_target->m_downscaled) || is_possible_mem_clear == ClearType::ClearWithDraw));
|
||||
|
||||
rt = g_texture_cache->LookupTarget(FRAME_TEX0, t_size, ((src && src->m_scale != 1) && GSConfig.UserHacks_NativeScaling == GSNativeScaling::Normal && !possible_shuffle) ? GetTextureScaleFactor() : target_scale, GSTextureCache::RenderTarget, true,
|
||||
fm, false, force_preload, preserve_rt_rgb, preserve_rt_alpha, unclamped_draw_rect, possible_shuffle, is_possible_mem_clear && FRAME_TEX0.TBP0 != m_cached_ctx.ZBUF.Block(), GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && preserve_downscale_draw && is_possible_mem_clear != ClearType::NormalClear);
|
||||
|
||||
@@ -865,8 +865,15 @@ std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_card
|
||||
if (!IsMemoryCardFolder(fd.FileName))
|
||||
continue;
|
||||
|
||||
FolderMemoryCard sourceFolderMemoryCard;
|
||||
Pcsx2Config::McdOptions config;
|
||||
config.Enabled = true;
|
||||
config.Type = MemoryCardType::Folder;
|
||||
sourceFolderMemoryCard.Open(fd.FileName, config, (8 * 1024 * 1024) / FolderMemoryCard::ClusterSize, false, "");
|
||||
|
||||
mcds.push_back({std::move(basename), std::move(fd.FileName), fd.ModificationTime,
|
||||
MemoryCardType::Folder, MemoryCardFileType::Unknown, 0u, true});
|
||||
MemoryCardType::Folder, MemoryCardFileType::Unknown, 0u, sourceFolderMemoryCard.IsFormatted()});
|
||||
sourceFolderMemoryCard.Close(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -318,6 +318,8 @@ public:
|
||||
void Open(std::string fullPath, const Pcsx2Config::McdOptions& mcdOptions, const u32 sizeInClusters, const bool enableFiltering, std::string filter, bool simulateFileWrites = false);
|
||||
// Close the memory card and flush changes to the file system. Set flush to false to not store changes.
|
||||
void Close(bool flush = true);
|
||||
// Checks whether the Memory Card is formatted.
|
||||
bool IsFormatted() const;
|
||||
|
||||
// Closes and reopens card with given filter options if they differ from the current ones (returns true),
|
||||
// or does nothing if they match already (returns false).
|
||||
@@ -363,8 +365,6 @@ protected:
|
||||
// initializes memory card data, as if it was fresh from the factory
|
||||
void InitializeInternalData();
|
||||
|
||||
bool IsFormatted() const;
|
||||
|
||||
// returns the in-memory address of data the given memory card adr corresponds to
|
||||
// returns nullptr if adr corresponds to a folder or file entry
|
||||
u8* GetSystemBlockPointer(const u32 adr);
|
||||
@@ -558,4 +558,4 @@ public:
|
||||
u64 GetCRC(uint slot);
|
||||
void NextFrame(uint slot);
|
||||
bool ReIndex(uint slot, const bool enableFiltering, const std::string& filter);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
/// Version number for GS and other shaders. Increment whenever any of the contents of the
|
||||
/// shaders change, to invalidate the cache.
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 58;
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 59;
|
||||
|
||||