Compare commits

...

28 Commits

Author SHA1 Message Date
KamFretoZ
3e8c2ef9a9 FSUI: Adds more icons 2026-01-12 12:05:17 +01:00
KamFretoZ
213569f3d7 Deps: Remove version number from fontawesome 2026-01-12 12:05:17 +01:00
KamFretoZ
0edcdf91db Deps: Bump FontAwesome to 7.1.0 2026-01-12 12:05:17 +01:00
Léane GRASSER
8253207bd2 UI: Rename Limit Depth to 24 Bits option values 2026-01-12 12:03:58 +01:00
Léane GRASSER
bc00be2ce5 Qt: Rename Limit 24 Bit Depth to Limit Depth to 24 Bits 2026-01-12 12:03:58 +01:00
refractionpcsx2
89c7463eb5 GS: Correct scaling of image for screenshots when Bilinear Sharp is enabled 2026-01-12 09:24:21 +01:00
PCSX2 Bot
93027c1e2e [ci skip] Qt: Update Base Translation. 2026-01-12 02:59:52 +01:00
TheLastRar
ee15846dd4 USB: Fix missing Train Mascon case warning 2026-01-11 16:45:05 -05:00
Ty
de03d2f672 Debugger: Properly reset the breakpoint skip first when skipped 2026-01-11 14:32:21 -05:00
YukiXXL
ae33c3d991 GameDB: SFOS cop2 fixes. (#13460)
SCES-52033:
Fixed "Cop2 problems." code that. Second address was wrong and was producing a bug.

SCUS-97264:
added fixes for Review Prototype (cop2, other languages)

SCUS-97397:
added fixes (cop2)

TCES-52033:
added fixes (cop2)
2026-01-11 10:12:31 +01:00
refractionpcsx2
61280a945d GS/HW: Tweak Native Scale Upscaled to work in more scenarios 2026-01-11 09:36:00 +01:00
PCSX2 Bot
e82712bf52 [ci skip] Qt: Update Base Translation. 2026-01-11 09:28:44 +01:00
refractionpcsx2
06307abd03 GS/HW: Only enable depth writes/floor calculation if depth is output 2026-01-11 02:36:55 +01:00
refractionpcsx2
daf735b047 GS/HW: Floor depth writes to improve Z testing 2026-01-11 02:36:55 +01:00
JordanTheToaster
f591c88aff GS/HW: Add Limit 24 Bit Depth Hack 2026-01-10 15:53:25 -05:00
refractionpcsx2
ca47a08882 GS: Fix up adding GS_to_GS transfers to the draw_transfers list 2026-01-10 15:50:59 -05:00
refractionpcsx2
92adacf99e GS: Disallow flipped GS->GS transfer when destination overwrites source 2026-01-10 15:50:59 -05:00
JordanTheToaster
43e5ec25ab microVU: Ignore MAC flags in block match if not required 2026-01-10 15:49:57 -05:00
KamFretoZ
1018b75847 DiscordRPC: Simplify Game Icon Retrieval 2026-01-10 15:49:45 -05:00
Shiva9361
3871d1bd5d Qt: Patch for distinguishing left and right variants of shift/alt/ctrl keys 2026-01-10 15:49:18 -05:00
Mrlinkwii
976d4a8dbb Revert "CI/Windows: Disable Qt's PCRE2 JIT"
This reverts commit 1ec4c248fb.
2026-01-10 15:47:32 -05:00
Ty
40b1b9b717 Qt: Add an EE SIO RX input textbox to the log window 2026-01-10 15:46:59 -05:00
Ty
a3b817cb1f Core: Use deque for EE SIO RX/TX FIFOs 2026-01-10 15:46:59 -05:00
SternXD
83e152cd21 GameDB: Add post-bloom alignment and native scaling for Urban Reign 2026-01-10 17:18:43 +01:00
TheLastRar
50a9568d65 GS/DX12: Backport DATE stencil one single pass from DX11/VK
Co-Authored-By: lightningterror <18107717+lightningterror@users.noreply.github.com>
2026-01-09 03:36:58 +01:00
KamFretoZ
a33cbdee09 Qt: Fix alternate row colors for Ruby/Emerald/Sapphire theme
For consistency
2026-01-08 20:18:11 +01:00
KamFretoZ
b02bcc5690 Qt: Cobalt Sky theme refresh 2026-01-08 20:18:11 +01:00
KamFretoZ
2e60a1d081 Qt: AMOLED theme refresh 2026-01-08 20:18:11 +01:00
70 changed files with 1413 additions and 950 deletions

View File

@@ -201,10 +201,6 @@ echo Building Qt base...
rmdir /S /Q "qtbase-everywhere-src-%QT%"
%SEVENZIP% x "qtbase-everywhere-src-%QT%.zip" || goto error
cd "qtbase-everywhere-src-%QT%" || goto error
rem Disable the PCRE2 JIT, it doesn't properly verify AVX2 support.
%PATCH% -p1 < "%SCRIPTDIR%\qtbase-disable-pcre2-jit.patch" || goto error
cmake -B build -DFEATURE_sql=OFF -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" %FORCEPDB% -DINPUT_gui=yes -DINPUT_widgets=yes -DINPUT_ssl=yes -DINPUT_openssl=no -DINPUT_schannel=yes -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON %QTBUILDSPEC% || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error

View File

@@ -1,35 +0,0 @@
--- qtbase/src/3rdparty/pcre2/CMakeLists.txt 2024-03-19 08:46:43.000000000 -0700
+++ qtbase/src/3rdparty/pcre2/CMakeLists.txt 2024-06-06 21:52:20.539619500 -0700
@@ -41,6 +41,7 @@
src/pcre2_xclass.c
DEFINES
HAVE_CONFIG_H
+ PCRE2_DISABLE_JIT
PUBLIC_DEFINES
PCRE2_CODE_UNIT_WIDTH=16
PUBLIC_INCLUDE_DIRECTORIES
@@ -52,23 +53,8 @@
## Scopes:
#####################################################################
-qt_internal_extend_target(BundledPcre2 CONDITION QNX OR UIKIT
- DEFINES
- PCRE2_DISABLE_JIT
-)
-
-qt_internal_extend_target(BundledPcre2 CONDITION (TEST_architecture_arch STREQUAL "arm") AND WIN32
- DEFINES
- PCRE2_DISABLE_JIT
-)
-
-qt_internal_extend_target(BundledPcre2 CONDITION (TEST_architecture_arch STREQUAL "arm64") AND WIN32
- DEFINES
- PCRE2_DISABLE_JIT
-)
-
if (APPLE)
- target_compile_options(BundledPcre2 PRIVATE "SHELL:-Xarch_arm64 -DPCRE2_DISABLE_JIT")
+ target_compile_options(BundledPcre2 PRIVATE "SHELL:-Xarch_arm64")
endif()
qt_internal_extend_target(BundledPcre2 CONDITION WIN32

View File

@@ -1,7 +1,7 @@
// Generated by https://github.com/juliettef/IconFontCppHeaders script GenerateIconFontCppHeaders.py
// for C and C++
// from codepoints https://github.com/FortAwesome/Font-Awesome/raw/6.x/metadata/icons.yml
// for use with font https://github.com/FortAwesome/Font-Awesome/blob/6.x/webfonts/fa-regular-400.ttf, https://github.com/FortAwesome/Font-Awesome/blob/6.x/webfonts/fa-solid-900.ttf
// from codepoints https://github.com/FortAwesome/Font-Awesome/raw/7.x/metadata/icons.yml
// for use with font https://github.com/FortAwesome/Font-Awesome/blob/7.x/webfonts/fa-regular-400.woff2 (You may need to convert the .woff2 files to .ttf depending upon your loader.), https://github.com/FortAwesome/Font-Awesome/blob/7.x/webfonts/fa-solid-900.woff2 (You may need to convert the .woff2 files to .ttf depending upon your loader.)
#pragma once
@@ -25,6 +25,7 @@
#define ICON_FA_A "A" // U+0041
#define ICON_FA_ADDRESS_BOOK "\xef\x8a\xb9" // U+f2b9
#define ICON_FA_ADDRESS_CARD "\xef\x8a\xbb" // U+f2bb
#define ICON_FA_ALARM_CLOCK "\xef\x8d\x8e" // U+f34e
#define ICON_FA_ALIGN_CENTER "\xef\x80\xb7" // U+f037
#define ICON_FA_ALIGN_JUSTIFY "\xef\x80\xb9" // U+f039
#define ICON_FA_ALIGN_LEFT "\xef\x80\xb6" // U+f036
@@ -218,6 +219,7 @@
#define ICON_FA_BURGER "\xef\xa0\x85" // U+f805
#define ICON_FA_BURST "\xee\x93\x9c" // U+e4dc
#define ICON_FA_BUS "\xef\x88\x87" // U+f207
#define ICON_FA_BUS_SIDE "\xee\xa0\x9d" // U+e81d
#define ICON_FA_BUS_SIMPLE "\xef\x95\x9e" // U+f55e
#define ICON_FA_BUSINESS_TIME "\xef\x99\x8a" // U+f64a
#define ICON_FA_C "C" // U+0043
@@ -650,8 +652,6 @@
#define ICON_FA_HANDS_PRAYING "\xef\x9a\x84" // U+f684
#define ICON_FA_HANDSHAKE "\xef\x8a\xb5" // U+f2b5
#define ICON_FA_HANDSHAKE_ANGLE "\xef\x93\x84" // U+f4c4
#define ICON_FA_HANDSHAKE_SIMPLE "\xef\x93\x86" // U+f4c6
#define ICON_FA_HANDSHAKE_SIMPLE_SLASH "\xee\x81\x9f" // U+e05f
#define ICON_FA_HANDSHAKE_SLASH "\xee\x81\xa0" // U+e060
#define ICON_FA_HANUKIAH "\xef\x9b\xa6" // U+f6e6
#define ICON_FA_HARD_DRIVE "\xef\x82\xa0" // U+f0a0
@@ -665,7 +665,6 @@
#define ICON_FA_HEAD_SIDE_VIRUS "\xee\x81\xa4" // U+e064
#define ICON_FA_HEADING "\xef\x87\x9c" // U+f1dc
#define ICON_FA_HEADPHONES "\xef\x80\xa5" // U+f025
#define ICON_FA_HEADPHONES_SIMPLE "\xef\x96\x8f" // U+f58f
#define ICON_FA_HEADSET "\xef\x96\x90" // U+f590
#define ICON_FA_HEART "\xef\x80\x84" // U+f004
#define ICON_FA_HEART_CIRCLE_BOLT "\xee\x93\xbc" // U+e4fc
@@ -680,6 +679,7 @@
#define ICON_FA_HELICOPTER_SYMBOL "\xee\x94\x82" // U+e502
#define ICON_FA_HELMET_SAFETY "\xef\xa0\x87" // U+f807
#define ICON_FA_HELMET_UN "\xee\x94\x83" // U+e503
#define ICON_FA_HEXAGON "\xef\x8c\x92" // U+f312
#define ICON_FA_HEXAGON_NODES "\xee\x9a\x99" // U+e699
#define ICON_FA_HEXAGON_NODES_BOLT "\xee\x9a\x9a" // U+e69a
#define ICON_FA_HIGHLIGHTER "\xef\x96\x91" // U+f591
@@ -852,6 +852,7 @@
#define ICON_FA_MOBILE_RETRO "\xee\x94\xa7" // U+e527
#define ICON_FA_MOBILE_SCREEN "\xef\x8f\x8f" // U+f3cf
#define ICON_FA_MOBILE_SCREEN_BUTTON "\xef\x8f\x8d" // U+f3cd
#define ICON_FA_MOBILE_VIBRATE "\xee\xa0\x96" // U+e816
#define ICON_FA_MONEY_BILL "\xef\x83\x96" // U+f0d6
#define ICON_FA_MONEY_BILL_1 "\xef\x8f\x91" // U+f3d1
#define ICON_FA_MONEY_BILL_1_WAVE "\xef\x94\xbb" // U+f53b
@@ -881,6 +882,7 @@
#define ICON_FA_NETWORK_WIRED "\xef\x9b\xbf" // U+f6ff
#define ICON_FA_NEUTER "\xef\x88\xac" // U+f22c
#define ICON_FA_NEWSPAPER "\xef\x87\xaa" // U+f1ea
#define ICON_FA_NON_BINARY "\xee\xa0\x87" // U+e807
#define ICON_FA_NOT_EQUAL "\xef\x94\xbe" // U+f53e
#define ICON_FA_NOTDEF "\xee\x87\xbe" // U+e1fe
#define ICON_FA_NOTE_STICKY "\xef\x89\x89" // U+f249
@@ -888,6 +890,7 @@
#define ICON_FA_O "O" // U+004f
#define ICON_FA_OBJECT_GROUP "\xef\x89\x87" // U+f247
#define ICON_FA_OBJECT_UNGROUP "\xef\x89\x88" // U+f248
#define ICON_FA_OCTAGON "\xef\x8c\x86" // U+f306
#define ICON_FA_OIL_CAN "\xef\x98\x93" // U+f613
#define ICON_FA_OIL_WELL "\xee\x94\xb2" // U+e532
#define ICON_FA_OM "\xef\x99\xb9" // U+f679
@@ -916,6 +919,7 @@
#define ICON_FA_PEN_RULER "\xef\x96\xae" // U+f5ae
#define ICON_FA_PEN_TO_SQUARE "\xef\x81\x84" // U+f044
#define ICON_FA_PENCIL "\xef\x8c\x83" // U+f303
#define ICON_FA_PENTAGON "\xee\x9e\x90" // U+e790
#define ICON_FA_PEOPLE_ARROWS "\xee\x81\xa8" // U+e068
#define ICON_FA_PEOPLE_CARRY_BOX "\xef\x93\x8e" // U+f4ce
#define ICON_FA_PEOPLE_GROUP "\xee\x94\xb3" // U+e533
@@ -1090,6 +1094,7 @@
#define ICON_FA_SD_CARD "\xef\x9f\x82" // U+f7c2
#define ICON_FA_SECTION "\xee\x91\x87" // U+e447
#define ICON_FA_SEEDLING "\xef\x93\x98" // U+f4d8
#define ICON_FA_SEPTAGON "\xee\xa0\xa0" // U+e820
#define ICON_FA_SERVER "\xef\x88\xb3" // U+f233
#define ICON_FA_SHAPES "\xef\x98\x9f" // U+f61f
#define ICON_FA_SHARE "\xef\x81\xa4" // U+f064
@@ -1118,6 +1123,8 @@
#define ICON_FA_SIGNATURE "\xef\x96\xb7" // U+f5b7
#define ICON_FA_SIGNS_POST "\xef\x89\xb7" // U+f277
#define ICON_FA_SIM_CARD "\xef\x9f\x84" // U+f7c4
#define ICON_FA_SINGLE_QUOTE_LEFT "\xee\xa0\x9b" // U+e81b
#define ICON_FA_SINGLE_QUOTE_RIGHT "\xee\xa0\x9c" // U+e81c
#define ICON_FA_SINK "\xee\x81\xad" // U+e06d
#define ICON_FA_SITEMAP "\xef\x83\xa8" // U+f0e8
#define ICON_FA_SKULL "\xef\x95\x8c" // U+f54c
@@ -1141,6 +1148,7 @@
#define ICON_FA_SPELL_CHECK "\xef\xa2\x91" // U+f891
#define ICON_FA_SPIDER "\xef\x9c\x97" // U+f717
#define ICON_FA_SPINNER "\xef\x84\x90" // U+f110
#define ICON_FA_SPIRAL "\xee\xa0\x8a" // U+e80a
#define ICON_FA_SPLOTCH "\xef\x96\xbc" // U+f5bc
#define ICON_FA_SPOON "\xef\x8b\xa5" // U+f2e5
#define ICON_FA_SPRAY_CAN "\xef\x96\xbd" // U+f5bd
@@ -1325,8 +1333,6 @@
#define ICON_FA_USER_GRADUATE "\xef\x94\x81" // U+f501
#define ICON_FA_USER_GROUP "\xef\x94\x80" // U+f500
#define ICON_FA_USER_INJURED "\xef\x9c\xa8" // U+f728
#define ICON_FA_USER_LARGE "\xef\x90\x86" // U+f406
#define ICON_FA_USER_LARGE_SLASH "\xef\x93\xba" // U+f4fa
#define ICON_FA_USER_LOCK "\xef\x94\x82" // U+f502
#define ICON_FA_USER_MINUS "\xef\x94\x83" // U+f503
#define ICON_FA_USER_NINJA "\xef\x94\x84" // U+f504
@@ -1351,7 +1357,6 @@
#define ICON_FA_V "V" // U+0056
#define ICON_FA_VAN_SHUTTLE "\xef\x96\xb6" // U+f5b6
#define ICON_FA_VAULT "\xee\x8b\x85" // U+e2c5
#define ICON_FA_VECTOR_SQUARE "\xef\x97\x8b" // U+f5cb
#define ICON_FA_VENUS "\xef\x88\xa1" // U+f221
#define ICON_FA_VENUS_DOUBLE "\xef\x88\xa6" // U+f226
#define ICON_FA_VENUS_MARS "\xef\x88\xa8" // U+f228

View File

@@ -2239,6 +2239,8 @@ SCAJ-20152:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SCAJ-20153:
name: "コード・エイジ コマンダーズ"
@@ -5600,7 +5602,7 @@ SCES-52033:
author=refraction
// Cop2 problems.
patch=0,EE,003953F8,word,48438000
patch=0,EE,003735FC,word,4B06521B
patch=0,EE,003953FC,word,4B06521B
author=YukiXXL
// Speed Correction (25 FPS)
patch=1,EE,00175E1C,extended,00000019
@@ -6229,6 +6231,8 @@ SCES-53688:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SCES-53795:
name: "SingStar - '80s"
@@ -7698,6 +7702,8 @@ SCKA-20065:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SCKA-20066:
name: "아이토이 - 플레이 3"
@@ -11686,6 +11692,15 @@ SCUS-97264:
// Cop2 problems.
patch=0,EE,003735F8,word,48438000
patch=0,EE,003735FC,word,4B06521B
062BC79E:
content: |-
author=YukiXXL
// Cop2 problems.
patch=0,EE,00395D28,word,48438000
patch=0,EE,00395D2C,word,4B06521B
// Other languages SNDVAG fix
patch=1,EE,204A0C3C,word,482E7325
patch=1,EE,204A0C40,word,0000474F
SCUS-97265:
name: "Jak II"
region: "NTSC-U"
@@ -12073,12 +12088,21 @@ SCUS-97396:
gsHWFixes:
PCRTCOffsets: 1 # Fixes boot videos screen size.
SCUS-97397:
name: "Syphon Filter - The Omega Strain"
name: "Syphon Filter - The Omega Strain Public Beta 1.0"
region: "NTSC-U"
gsHWFixes:
autoFlush: 2 # Fixes lights going through walls.
preloadFrameData: 1 # Fixes light flicker.
halfPixelOffset: 2 # Corrects light position.
gameFixes:
- EETimingHack # Fixes random hangs.
patches:
C909A32E:
content: |-
author=YukiXXL
// Cop2 problems.
patch=0,EE,00367798,word,48438000
patch=0,EE,0036779C,word,4B06521B
SCUS-97398:
name: "Siren [Demo]"
region: "NTSC-U"
@@ -35952,6 +35976,8 @@ SLPM-60272:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SLPM-60273:
name: "絶体絶命都市2 -凍てついた記憶たち- [体験版 Type-B]"
@@ -60340,6 +60366,8 @@ SLPS-25557:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SLPS-25558:
name: "ネオジオ バトルコロシアム"
@@ -70360,6 +70388,8 @@ SLUS-21209:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SLUS-21212:
name: "Spartan - Total Warrior"
@@ -75768,6 +75798,9 @@ TCES-52033:
0DDA2728:
content: |-
author=YukiXXL
// Cop2 problems.
patch=0,EE,0038E8E8,word,48438000
patch=0,EE,0038E8EC,word,4B06521B
// Speed Correction (25 FPS)
patch=1,EE,00175a7c,extended,00000019
patch=1,EE,00175848,extended,00000019

Binary file not shown.

View File

@@ -71,6 +71,7 @@
#define PS_DITHER 0
#define PS_DITHER_ADJUST 0
#define PS_ZCLAMP 0
#define PS_ZFLOOR 0
#define PS_SCANMSK 0
#define PS_AUTOMATIC_LOD 0
#define PS_MANUAL_LOD 0
@@ -138,7 +139,7 @@ struct PS_OUTPUT
#endif
#endif
#endif
#if PS_ZCLAMP
#if PS_ZCLAMP || PS_ZFLOOR
float depth : SV_Depth;
#endif
};
@@ -1209,8 +1210,16 @@ PS_OUTPUT ps_main(PS_INPUT input)
#endif // PS_DATE != 1/2
#if PS_ZFLOOR
float depth_value = floor(input.p.z * exp2(32.0f)) * exp2(-32.0f);
#else
float depth_value = input.p.z;
#endif
#if PS_ZCLAMP
output.depth = min(input.p.z, MaxDepthPS);
output.depth = min(depth_value, MaxDepthPS);
#elif PS_ZFLOOR
output.depth = depth_value;
#endif
return output;

View File

@@ -1143,7 +1143,16 @@ void ps_main()
#endif
#endif
#if PS_ZCLAMP
gl_FragDepth = min(gl_FragCoord.z, MaxDepthPS);
#if PS_ZFLOOR
float depth_value = floor(gl_FragCoord.z * exp2(32.0f)) * exp2(-32.0f);
#else
float depth_value = gl_FragCoord.z;
#endif
#if PS_ZCLAMP
gl_FragDepth = min(depth_value, MaxDepthPS);
#elif PS_ZFLOOR
gl_FragDepth = depth_value;
#endif
}

View File

@@ -288,6 +288,7 @@ void main()
#define PS_DITHER 0
#define PS_DITHER_ADJUST 0
#define PS_ZCLAMP 0
#define PS_ZFLOOR 0
#define PS_FEEDBACK_LOOP 0
#define PS_TEX_IS_FB 0
#endif
@@ -1400,8 +1401,16 @@ void main()
#endif
#endif
#if PS_ZFLOOR
float depth_value = floor(gl_FragCoord.z * exp2(32.0f)) * exp2(-32.0f);;
#else
float depth_value = gl_FragCoord.z;
#endif
#if PS_ZCLAMP
gl_FragDepth = min(gl_FragCoord.z, MaxDepthPS);
#elif PS_ZFLOOR
gl_FragDepth = depth_value;
#endif
#endif // PS_DATE

View File

@@ -5,10 +5,14 @@
#include "MainWindow.h"
#include "QtHost.h"
#include "SettingWidgetBinder.h"
#include "VMManager.h"
#include <QtCore/QLatin1StringView>
#include <QtCore/QUtf8StringView>
#include <QtGui/QIcon>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QScrollBar>
@@ -46,6 +50,12 @@ void LogWindow::updateSettings()
const bool new_enabled = Host::GetBaseBoolSettingValue("Logging", "EnableLogWindow", false) && !Host::InNoGUIMode();
const bool attach_to_main = Host::GetBaseBoolSettingValue("Logging", "AttachLogWindowToMainWindow", true);
const bool curr_enabled = Log::IsHostOutputEnabled();
const bool input_enabled = Host::GetBaseBoolSettingValue("Logging", "ShowEESIOInput");
if(g_log_window && g_log_window->m_line_input)
{
g_log_window->m_input_widget->setVisible(input_enabled);
}
if (new_enabled == curr_enabled)
{
@@ -171,6 +181,10 @@ void LogWindow::createUi()
action->setCheckable(true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "EnableTimestamps", true);
action = settings_menu->addAction(tr("Show EE SIO &Input"));
action->setCheckable(true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "ShowEESIOInput", false);
settings_menu->addSeparator();
// TODO: Log Level
@@ -181,6 +195,30 @@ void LogWindow::createUi()
m_text->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
m_text->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
m_text->setWordWrapMode(QTextOption::WrapAnywhere);
m_text->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_line_input = new QLineEdit(this);
connect(m_line_input, &QLineEdit::returnPressed, this, &LogWindow::onInputEntered);
m_local_echo_checkbox = new QCheckBox(tr("Local Echo"), this);
m_local_echo_checkbox->setChecked(m_local_echo);
connect(m_local_echo_checkbox, &QCheckBox::checkStateChanged, this, [&](Qt::CheckState state)
{
m_local_echo = state == Qt::CheckState::Checked;
});
m_newline_on_enter_checkbox = new QCheckBox(tr("Newline on send"), this);
m_newline_on_enter_checkbox->setChecked(m_newline_on_enter);
connect(m_newline_on_enter_checkbox, &QCheckBox::checkStateChanged, this, [&](Qt::CheckState state)
{
m_newline_on_enter = state == Qt::CheckState::Checked;
});
m_input_hbox = new QHBoxLayout(this);
m_input_hbox->addWidget(m_line_input, 1);
m_input_hbox->addWidget(m_local_echo_checkbox);
m_input_hbox->addWidget(m_newline_on_enter_checkbox);
m_input_hbox->setSpacing(8);
#if defined(_WIN32)
QFont font("Consolas");
@@ -194,7 +232,19 @@ void LogWindow::createUi()
#endif
m_text->setFont(font);
setCentralWidget(m_text);
QWidget* central_widget = new QWidget(this);
m_input_widget = new QWidget(this);
m_input_widget->setVisible(Host::GetBaseBoolSettingValue("Logging", "ShowEESIOInput"));
m_input_widget->setLayout(m_input_hbox);
QVBoxLayout* vlayout = new QVBoxLayout(central_widget);
vlayout->setContentsMargins(0, 0, 0, 0);
vlayout->setSpacing(0);
vlayout->addWidget(m_text);
vlayout->addWidget(m_input_widget);
central_widget->setLayout(vlayout);
setCentralWidget(central_widget);
}
void LogWindow::onClearTriggered()
@@ -361,6 +411,31 @@ void LogWindow::appendMessage(quint32 level, quint32 color, const QString& messa
}
}
void LogWindow::onInputEntered()
{
QString text = m_line_input->text();
if (text.isEmpty() && !m_newline_on_enter)
return;
if(m_newline_on_enter)
text.append('\n');
std::string str = text.toUtf8().toStdString();
if(VMManager::WriteBytesToEESIORXFIFO({reinterpret_cast<const u8*>(str.data()), str.size()}))
{
m_line_input->clear();
if(m_local_echo)
// appendMessage expects a newline to be at the end of the string
appendMessage(0, 0, m_newline_on_enter ? text : (text + '\n') );
QTextCursor cursor(m_text->textCursor());
cursor.movePosition(QTextCursor::End);
m_text->setTextCursor(cursor);
}
}
void LogWindow::saveSize()
{
const int current_width = Host::GetBaseIntSettingValue("UI", "LogWindowWidth", DEFAULT_WIDTH);

View File

@@ -5,6 +5,9 @@
#include "common/Console.h"
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QPlainTextEdit>
@@ -36,6 +39,7 @@ private Q_SLOTS:
void onClearTriggered();
void onSaveTriggered();
void appendMessage(quint32 level, quint32 color, const QString& message);
void onInputEntered();
private:
static constexpr int DEFAULT_WIDTH = 750;
@@ -45,8 +49,15 @@ private:
void restoreSize();
QPlainTextEdit* m_text;
QLineEdit* m_line_input;
QMenu* m_level_menu;
QWidget* m_input_widget;
QHBoxLayout* m_input_hbox;
QCheckBox* m_local_echo_checkbox;
QCheckBox* m_newline_on_enter_checkbox;
bool m_local_echo = false;
bool m_newline_on_enter = true;
bool m_attached_to_main_window = true;
bool m_destroying = false;
};

View File

@@ -67,6 +67,17 @@ struct KeyCodeName
const char* icon_name;
};
// Extended keys for left/right versions, Non conflicting with Qt::Key enum
enum ExtendedKeys
{
Key_RightShift = 0x01100022,
Key_LeftShift = 0x01100023,
Key_RightControl = 0x01100024,
Key_LeftControl = 0x01100025,
Key_RightAlt = 0x01100026,
Key_LeftAlt = 0x01100027,
};
static constexpr const KeyCodeName s_qt_key_names[] = {
{Qt::Key_Escape, "Escape", ICON_PF_ESC},
{Qt::Key_Tab, "Tab", ICON_PF_TAB},
@@ -92,6 +103,13 @@ static constexpr const KeyCodeName s_qt_key_names[] = {
{Qt::Key_Control, "Control", ICON_PF_CTRL},
{Qt::Key_Meta, "Meta", ICON_PF_SUPER},
{Qt::Key_Alt, "Alt", ICON_PF_ALT},
// patch for left and right versions of the keys
{ExtendedKeys::Key_LeftShift, "LShift", ICON_PF_SHIFT},
{ExtendedKeys::Key_RightShift, "RShift", ICON_PF_SHIFT},
{ExtendedKeys::Key_LeftControl, "LCtrl", ICON_PF_CTRL},
{ExtendedKeys::Key_RightControl, "RCtrl", ICON_PF_CTRL},
{ExtendedKeys::Key_LeftAlt, "LAlt", ICON_PF_ALT},
{ExtendedKeys::Key_RightAlt, "RAlt", ICON_PF_ALT},
{Qt::Key_CapsLock, "CapsLock", ICON_PF_CAPS},
{Qt::Key_NumLock, "NumLock", ICON_PF_NUMLOCK},
{Qt::Key_ScrollLock, "ScrollLock", ICON_PF_SCRLK},
@@ -575,6 +593,41 @@ u32 QtUtils::KeyEventToCode(const QKeyEvent* ev)
const u8 keycode = set_keycode ? map_text_to_keycode(text) : 0;
int key = ev->key();
if (key == Qt::Key_Shift || key == Qt::Key_Alt || key == Qt::Key_Control)
{
#if defined(Q_OS_WIN) or defined(Q_OS_LINUX)
// Scan codes (Tested it)
// 0x2A : Left shift
// 0x36 : Right shift
// 0x1D : Left ctrl
// 0xE01D : Right ctrl
// 0x38 : Left alt
// right alt can become ctrl + right alt in some keyboard layouts (windows)
// but thats fine for our use case
switch (ev->nativeScanCode())
{
case 0x2A:
key = ExtendedKeys::Key_LeftShift;
break;
case 0x36:
key = ExtendedKeys::Key_RightShift;
break;
case 0x1D:
key = ExtendedKeys::Key_LeftControl;
break;
case 0xE01D:
key = ExtendedKeys::Key_RightControl;
break;
case 0x38:
key = ExtendedKeys::Key_LeftAlt;
break;
default:
break;
}
#endif
}
if (keycode != 0)
key = keycode; // Override key if mapped

View File

@@ -14,8 +14,31 @@
<string/>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
<item row="3" column="1">
<widget class="QComboBox" name="hwAutoFlush">
<item row="8" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="0">
<widget class="QLabel" name="skipDrawLabel">
<property name="text">
<string>Skip Draw Range:</string>
</property>
<property name="buddy">
<cstring>skipDrawStart</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="textureInsideRt">
<item>
<property name="text">
<string>Disabled (Default)</string>
@@ -23,12 +46,12 @@
</item>
<item>
<property name="text">
<string>Enabled (Sprites Only)</string>
<string>Inside Target</string>
</property>
</item>
<item>
<property name="text">
<string>Enabled (All Primitives)</string>
<string>Merge Targets</string>
</property>
</item>
</widget>
@@ -43,41 +66,6 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="skipDrawLabel">
<property name="text">
<string>Skip Draw Range:</string>
</property>
<property name="buddy">
<cstring>skipDrawStart</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cpuCLUTRender">
<property name="currentText">
<string extracomment="0 (Disabled)">0 (Disabled)</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>0 (Disabled)</string>
</property>
</item>
<item>
<property name="text">
<string>1 (Normal)</string>
</property>
</item>
<item>
<property name="text">
<string>2 (Aggressive)</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="cpuCLUTRenderLayout" stretch="0,0">
<item>
@@ -160,8 +148,36 @@
</item>
</layout>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="textureInsideRt">
<item row="3" column="0">
<widget class="QLabel" name="hwAutoFlushLabel">
<property name="text">
<string>Auto Flush:</string>
</property>
<property name="buddy">
<cstring>hwAutoFlush</cstring>
</property>
</widget>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="skipDrawLayout">
<item>
<widget class="QSpinBox" name="skipDrawStart">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="skipDrawEnd">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="gpuTargetCLUTMode">
<item>
<property name="text">
<string>Disabled (Default)</string>
@@ -169,12 +185,57 @@
</item>
<item>
<property name="text">
<string>Inside Target</string>
<string>Enabled (Exact Match)</string>
</property>
</item>
<item>
<property name="text">
<string>Merge Targets</string>
<string>Enabled (Check Inside Target)</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="cpuCLUTRenderLabel">
<property name="text">
<string>CPU Sprite Render Size:</string>
</property>
<property name="buddy">
<cstring>cpuSpriteRenderBW</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="gpuTargetCLUTLabel">
<property name="text">
<string extracomment="CLUT: Color Look Up Table, often referred to as a palette in non-PS2 things. GPU Target CLUT: GPU handling of when a game uses data from a render target as a CLUT.">GPU Target CLUT:</string>
</property>
<property name="buddy">
<cstring>gpuTargetCLUTMode</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cpuCLUTRender">
<property name="currentText">
<string extracomment="0 (Disabled)">0 (Disabled)</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>0 (Disabled)</string>
</property>
</item>
<item>
<property name="text">
<string>1 (Normal)</string>
</property>
</item>
<item>
<property name="text">
<string>2 (Aggressive)</string>
</property>
</item>
</widget>
@@ -189,7 +250,26 @@
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<item row="3" column="1">
<widget class="QComboBox" name="hwAutoFlush">
<item>
<property name="text">
<string>Disabled (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Enabled (Sprites Only)</string>
</property>
</item>
<item>
<property name="text">
<string>Enabled (All Primitives)</string>
</property>
</item>
</widget>
</item>
<item row="7" column="0" colspan="2">
<layout class="QGridLayout" name="hwFixesLayout">
<item row="4" column="0">
<widget class="QCheckBox" name="estimateTextureRegion">
@@ -256,28 +336,8 @@
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="hwAutoFlushLabel">
<property name="text">
<string>Auto Flush:</string>
</property>
<property name="buddy">
<cstring>hwAutoFlush</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="gpuTargetCLUTLabel">
<property name="text">
<string extracomment="CLUT: Color Look Up Table, often referred to as a palette in non-PS2 things. GPU Target CLUT: GPU handling of when a game uses data from a render target as a CLUT.">GPU Target CLUT:</string>
</property>
<property name="buddy">
<cstring>gpuTargetCLUTMode</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="gpuTargetCLUTMode">
<item row="5" column="1">
<widget class="QComboBox" name="limit24BitDepth">
<item>
<property name="text">
<string>Disabled (Default)</string>
@@ -285,57 +345,23 @@
</item>
<item>
<property name="text">
<string>Enabled (Exact Match)</string>
<string>Prioritize Upper Bits</string>
</property>
</item>
<item>
<property name="text">
<string>Enabled (Check Inside Target)</string>
<string>Prioritize Lower Bits</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="cpuCLUTRenderLabel">
<item row="5" column="0">
<widget class="QLabel" name="limitDepthLabel">
<property name="text">
<string>CPU Sprite Render Size:</string>
</property>
<property name="buddy">
<cstring>cpuSpriteRenderBW</cstring>
<string>Limit Depth to 24 Bits</string>
</property>
</widget>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="skipDrawLayout">
<item>
<widget class="QSpinBox" name="skipDrawStart">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="skipDrawEnd">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>

View File

@@ -147,6 +147,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
sif, m_fixes.disablePartialInvalidation, "EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_fixes.textureInsideRt, "EmuCore/GS", "UserHacks_TextureInsideRt", static_cast<int>(GSTextureInRtMode::Disabled));
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_fixes.limit24BitDepth, "EmuCore/GS", "UserHacks_Limit24BitDepth", static_cast<int>(GSLimit24BitDepth::Disabled));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_fixes.readTCOnClose, "EmuCore/GS", "UserHacks_ReadTCOnClose", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_fixes.estimateTextureRegion, "EmuCore/GS", "UserHacks_EstimateTextureRegion", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_fixes.gpuPaletteConversion, "EmuCore/GS", "paltex", false);
@@ -624,6 +626,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
dialog()->registerWidgetHelp(m_fixes.textureInsideRt, tr("Texture Inside RT"), tr("Disabled"),
tr("Allows the texture cache to reuse as an input texture the inner portion of a previous framebuffer."));
dialog()->registerWidgetHelp(m_fixes.limit24BitDepth, tr("Limit Depth to 24 Bits"), tr("Disabled"),
tr("Truncate 32-bit depth values to 24 bits. Helps games struggling with Z-fighting."));
dialog()->registerWidgetHelp(m_fixes.readTCOnClose, tr("Read Targets When Closing"), tr("Unchecked"),
tr("Flushes all targets in the texture cache back to local memory when shutting down. Can prevent lost visuals when saving "
"state or switching graphics APIs, but can also cause graphical corruption."));

View File

@@ -437,26 +437,26 @@ void QtHost::SetStyleFromSettings()
// Alternative dark theme.
qApp->setStyle(QStyleFactory::create("Fusion"));
const QColor gray(150, 150, 150);
const QColor royalBlue(29, 41, 81);
const QColor darkishBlue(17, 30, 108);
const QColor abyssBlue(39, 58, 114);
const QColor darkishBlue(29, 41, 81);
const QColor lighterBlue(25, 32, 130);
const QColor highlight(36, 93, 218);
const QColor link(0, 202, 255);
const QColor blue(198, 238, 255);
const QColor gray(150, 150, 150);
QPalette cobaltSkyPalette;
cobaltSkyPalette.setColor(QPalette::Window, royalBlue);
cobaltSkyPalette.setColor(QPalette::Window, abyssBlue);
cobaltSkyPalette.setColor(QPalette::WindowText, Qt::white);
cobaltSkyPalette.setColor(QPalette::Base, royalBlue.lighter());
cobaltSkyPalette.setColor(QPalette::AlternateBase, darkishBlue);
cobaltSkyPalette.setColor(QPalette::Base, darkishBlue);
cobaltSkyPalette.setColor(QPalette::AlternateBase, darkishBlue.darker());
cobaltSkyPalette.setColor(QPalette::ToolTipBase, darkishBlue);
cobaltSkyPalette.setColor(QPalette::ToolTipText, Qt::white);
cobaltSkyPalette.setColor(QPalette::Text, Qt::white);
cobaltSkyPalette.setColor(QPalette::Button, lighterBlue);
cobaltSkyPalette.setColor(QPalette::ButtonText, Qt::white);
cobaltSkyPalette.setColor(QPalette::Link, link);
cobaltSkyPalette.setColor(QPalette::Highlight, highlight);
cobaltSkyPalette.setColor(QPalette::Link, blue);
cobaltSkyPalette.setColor(QPalette::Highlight, abyssBlue.lighter());
cobaltSkyPalette.setColor(QPalette::HighlightedText, Qt::white);
cobaltSkyPalette.setColor(QPalette::PlaceholderText, gray);
cobaltSkyPalette.setColor(QPalette::Active, QPalette::Button, lighterBlue);
cobaltSkyPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
@@ -475,9 +475,9 @@ void QtHost::SetStyleFromSettings()
// 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 black(5, 5, 5);
const QColor gray(22, 22, 29);
const QColor lighterGray(65, 79, 98);
const QColor blue(198, 238, 255);
QPalette AMOLEDPalette;
@@ -519,7 +519,7 @@ void QtHost::SetStyleFromSettings()
rubyPalette.setColor(QPalette::Window, slate);
rubyPalette.setColor(QPalette::WindowText, Qt::white);
rubyPalette.setColor(QPalette::Base, slate.lighter());
rubyPalette.setColor(QPalette::AlternateBase, slate.lighter());
rubyPalette.setColor(QPalette::AlternateBase, slate.darker());
rubyPalette.setColor(QPalette::ToolTipBase, slate);
rubyPalette.setColor(QPalette::ToolTipText, Qt::white);
rubyPalette.setColor(QPalette::Text, Qt::white);
@@ -553,7 +553,7 @@ void QtHost::SetStyleFromSettings()
sapphirePalette.setColor(QPalette::Window, slate);
sapphirePalette.setColor(QPalette::WindowText, Qt::white);
sapphirePalette.setColor(QPalette::Base, slate.lighter());
sapphirePalette.setColor(QPalette::AlternateBase, slate.lighter());
sapphirePalette.setColor(QPalette::AlternateBase, slate.darker());
sapphirePalette.setColor(QPalette::ToolTipBase, slate);
sapphirePalette.setColor(QPalette::ToolTipText, Qt::white);
sapphirePalette.setColor(QPalette::Text, Qt::white);
@@ -587,7 +587,7 @@ void QtHost::SetStyleFromSettings()
emeraldPalette.setColor(QPalette::Window, slate);
emeraldPalette.setColor(QPalette::WindowText, Qt::white);
emeraldPalette.setColor(QPalette::Base, slate.lighter());
emeraldPalette.setColor(QPalette::AlternateBase, slate.lighter());
emeraldPalette.setColor(QPalette::AlternateBase, slate.darker());
emeraldPalette.setColor(QPalette::ToolTipBase, slate);
emeraldPalette.setColor(QPalette::ToolTipText, Qt::white);
emeraldPalette.setColor(QPalette::Text, Qt::white);

File diff suppressed because it is too large Load Diff

View File

@@ -1043,21 +1043,11 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
s_has_leaderboards = has_leaderboards;
s_has_rich_presence = rc_client_has_rich_presence(client);
s_game_icon = {};
s_game_icon_url = {};
s_game_icon_url = info->badge_url;
// ensure fullscreen UI is ready for notifications
MTGS::RunOnGSThread(&ImGuiManager::InitializeFullscreenUI);
char url_buffer[URL_BUFFER_SIZE];
if (int err = rc_client_game_get_image_url(info, url_buffer, std::size(url_buffer)); err == RC_OK)
{
s_game_icon_url = url_buffer;
}
else
{
ReportRCError(err, "rc_client_game_get_image_url() failed: ");
}
if (const std::string_view badge_name = info->badge_name; !badge_name.empty())
{
s_game_icon = Path::Combine(s_image_directory, fmt::format("game_{}.png", badge_name));

View File

@@ -6,7 +6,7 @@
#include "CDVD/IsoFileFormats.h"
#include "Config.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "common/Assertions.h"
#include "common/Console.h"

View File

@@ -432,6 +432,13 @@ enum class GSTextureInRtMode : u8
MergeTargets,
};
enum class GSLimit24BitDepth : u8
{
Disabled,
PrioritizeUpper,
PrioritizeLower,
};
enum class GSBilinearDirtyMode : u8
{
Automatic,
@@ -844,6 +851,7 @@ struct Pcsx2Config
u8 UserHacks_CPUCLUTRender = 0;
GSGPUTargetCLUTMode UserHacks_GPUTargetCLUTMode = GSGPUTargetCLUTMode::Disabled;
GSTextureInRtMode UserHacks_TextureInsideRt = GSTextureInRtMode::Disabled;
GSLimit24BitDepth UserHacks_Limit24BitDepth = GSLimit24BitDepth::Disabled;
GSBilinearDirtyMode UserHacks_BilinearHack = GSBilinearDirtyMode::Automatic;
TriFiltering TriFilter = TriFiltering::Automatic;
s8 OverrideTextureBarriers = -1;

View File

@@ -11,6 +11,8 @@
std::vector<BreakPoint> CBreakPoints::breakPoints_;
u32 CBreakPoints::breakSkipFirstAtEE_ = 0;
u32 CBreakPoints::breakSkipFirstAtIop_ = 0;
bool CBreakPoints::pendingClearSkipFirstAtEE_ = false;
bool CBreakPoints::pendingClearSkipFirstAtIop_ = false;
std::vector<MemCheck> CBreakPoints::memChecks_;
std::vector<MemCheck*> CBreakPoints::cleanupMemChecks_;
bool CBreakPoints::breakpointTriggered_ = false;
@@ -391,10 +393,12 @@ void CBreakPoints::SetSkipFirst(BreakPointCpu cpu, u32 pc)
if (cpu == BREAKPOINT_EE)
{
breakSkipFirstAtEE_ = standardizeBreakpointAddress(pc);
pendingClearSkipFirstAtEE_ = false;
}
else if (cpu == BREAKPOINT_IOP)
{
breakSkipFirstAtIop_ = pc;
pendingClearSkipFirstAtIop_ = false;
}
}
@@ -407,10 +411,29 @@ u32 CBreakPoints::CheckSkipFirst(BreakPointCpu cpu, u32 cmpPc)
return 0;
}
void CBreakPoints::ClearSkipFirst()
void CBreakPoints::ClearSkipFirst(BreakPointCpu cpu)
{
breakSkipFirstAtEE_ = 0;
breakSkipFirstAtIop_ = 0;
if((cpu & BREAKPOINT_EE) != 0)
pendingClearSkipFirstAtEE_ = true;
else if ((cpu & BREAKPOINT_IOP) != 0)
pendingClearSkipFirstAtIop_ = true;
if(cpu == BREAKPOINT_IOP_AND_EE)
CommitClearSkipFirst(BREAKPOINT_IOP_AND_EE);
}
void CBreakPoints::CommitClearSkipFirst(BreakPointCpu cpu)
{
if((cpu & BREAKPOINT_EE) != 0 && pendingClearSkipFirstAtEE_)
{
pendingClearSkipFirstAtEE_ = false;
breakSkipFirstAtEE_ = 0;
}
else if ((cpu & BREAKPOINT_IOP) != 0 && pendingClearSkipFirstAtIop_)
{
pendingClearSkipFirstAtIop_ = true;
breakSkipFirstAtIop_ = 0;
}
}
const std::vector<MemCheck> CBreakPoints::GetMemCheckRanges()

View File

@@ -135,7 +135,8 @@ public:
static void SetSkipFirst(BreakPointCpu cpu, u32 pc);
static u32 CheckSkipFirst(BreakPointCpu cpu, u32 pc);
static void ClearSkipFirst();
static void ClearSkipFirst(BreakPointCpu cpu = BREAKPOINT_IOP_AND_EE);
static void CommitClearSkipFirst(BreakPointCpu cpu);
// Includes uncached addresses.
static const std::vector<MemCheck> GetMemCheckRanges();
@@ -169,9 +170,9 @@ private:
static std::vector<BreakPoint> breakPoints_;
static u32 breakSkipFirstAtEE_;
static u64 breakSkipFirstTicksEE_;
static bool pendingClearSkipFirstAtEE_;
static u32 breakSkipFirstAtIop_;
static u64 breakSkipFirstTicksIop_;
static bool pendingClearSkipFirstAtIop_;
static bool breakpointTriggered_;
static BreakPointCpu breakpointTriggeredCpu_;

View File

@@ -48,7 +48,7 @@
#include "common/SmallString.h"
#include "common/StringUtil.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "fmt/format.h"

View File

@@ -10,7 +10,7 @@
#include "SPU2/spu2.h"
#include "Host.h"
#include "Host/AudioStream.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/BitUtils.h"

View File

@@ -806,12 +806,12 @@ void GSState::DumpTransferList(const std::string& filename)
(*file) << std::endl;
// clear, EE->GS, or GS->GS
(*file) << LIST_ITEM << "type: " << (transfer.zero_clear ? "clear" : (transfer.ee_to_gs ? "EE_to_GS" : "GS_to_GS")) << std::endl;
(*file) << LIST_ITEM << "type: " << (transfer.zero_clear ? "clear" : ((transfer.transfer_type == EEGS_TransferType::EE_to_GS) ? "EE_to_GS" : "GS_to_GS")) << std::endl;
// Dump BITBLTBUF
(*file) << INDENT << "BITBLTBUF: " << OPEN_MAP;
const bool gs_to_gs = !transfer.ee_to_gs && !transfer.zero_clear;
const bool gs_to_gs = (transfer.transfer_type == EEGS_TransferType::GS_to_GS) && !transfer.zero_clear;
if (gs_to_gs)
{
@@ -857,7 +857,7 @@ void GSState::DumpTransferImages()
const GSUploadQueue& transfer = m_draw_transfers[i];
std::string filename;
if (transfer.ee_to_gs || transfer.zero_clear)
if ((transfer.transfer_type == EEGS_TransferType::EE_to_GS) || transfer.zero_clear)
{
// clear or EE->GS: only the destination info is relevant.
filename = GetDrawDumpPath("%05d_transfer%02d_%s_%04x_%d_%s_%d_%d_%d_%d.png",
@@ -2365,7 +2365,7 @@ void GSState::Write(const u8* mem, int len)
s_last_transfer_draw_n = s_n;
// Store the transfer for preloading new RT's.
if ((m_draw_transfers.size() > 0 && blit.DBP == m_draw_transfers.back().blit.DBP))
if ((m_draw_transfers.size() > 0 && blit.DBP == m_draw_transfers.back().blit.DBP && m_draw_transfers.back().transfer_type == EEGS_TransferType::EE_to_GS))
{
// Same BP, let's update the rect.
GSUploadQueue transfer = m_draw_transfers.back();
@@ -2377,7 +2377,7 @@ void GSState::Write(const u8* mem, int len)
}
else
{
const GSUploadQueue new_transfer = { blit, r, s_n, false, true };
const GSUploadQueue new_transfer = {blit, r, s_n, false, EEGS_TransferType::EE_to_GS};
m_draw_transfers.push_back(new_transfer);
}
@@ -2519,21 +2519,31 @@ void GSState::Move()
InvalidateLocalMem(m_env.BITBLTBUF, GSVector4i(sx, sy, sx + w, sy + h));
InvalidateVideoMem(m_env.BITBLTBUF, GSVector4i(dx, dy, dx + w, dy + h));
const bool overlaps = m_env.BITBLTBUF.SBP == m_env.BITBLTBUF.DBP;
const bool intersect = overlaps && !(GSVector4i(sx, sy, sx + w, sy + h).rintersect(GSVector4i(dx, dy, dx + w, dy + h)).rempty());
int xinc = 1;
int yinc = 1;
if (m_env.TRXPOS.DIRX)
{
sx += w - 1;
dx += w - 1;
xinc = -1;
// Only allow it to reverse if the destination is behind the source.
if (!intersect || (sx <= dx && (sx == dx || ((!m_env.TRXPOS.DIRY && sy >= dy) || (m_env.TRXPOS.DIRY && sy < dy)))))
{
sx += w - 1;
dx += w - 1;
xinc = -1;
}
}
if (m_env.TRXPOS.DIRY)
{
sy += h - 1;
dy += h - 1;
yinc = -1;
// Only allow it to reverse if the destination is behind the source.
if (!intersect || (sy <= dy && (sy == dy || ((!m_env.TRXPOS.DIRX && sx >= dx) || (m_env.TRXPOS.DIRX && sx < dx)))))
{
sy += h - 1;
dy += h - 1;
yinc = -1;
}
}
const GSLocalMemory::psm_t& spsm = GSLocalMemory::m_psm[m_env.BITBLTBUF.SPSM];
@@ -2556,7 +2566,7 @@ void GSState::Move()
s_last_transfer_draw_n = s_n;
// Store the transfer for preloading new RT's.
if ((m_draw_transfers.size() > 0 && m_env.BITBLTBUF.DBP == m_draw_transfers.back().blit.DBP))
if ((m_draw_transfers.size() > 0 && m_env.BITBLTBUF.DBP == m_draw_transfers.back().blit.DBP && m_draw_transfers.back().transfer_type == EEGS_TransferType::GS_to_GS))
{
// Same BP, let's update the rect.
GSUploadQueue transfer = m_draw_transfers.back();
@@ -2568,11 +2578,11 @@ void GSState::Move()
}
else
{
const GSUploadQueue new_transfer = { m_env.BITBLTBUF, r, s_n, false, false };
const GSUploadQueue new_transfer = {m_env.BITBLTBUF, r, s_n, false, EEGS_TransferType::GS_to_GS};
m_draw_transfers.push_back(new_transfer);
}
auto copy = [this, sbp, dbp, sx, sy, dx, dy, w, h, yinc, xinc](const GSOffset& dpo, const GSOffset& spo, auto&& pxCopyFn)
auto copy = [this, sbp, dbp, sx, sy, dx, dy, w, h, yinc, xinc, intersect](const GSOffset& dpo, const GSOffset& spo, auto&& pxCopyFn)
{
int _sy = sy, _dy = dy; // Faster with local copied variables, compiler optimizations are dumb
if (xinc > 0)
@@ -2584,8 +2594,6 @@ void GSState::Move()
// Copying from itself to itself (rotating textures) used in Gitaroo Man stage 8
// What probably happens is because the copy is buffered, the source stays just ahead of the destination.
// No need to do all this if the copy source/destination don't intersect, however.
const bool intersect = !(GSVector4i(sx, sy, sx + w, sy + h).rintersect(GSVector4i(dx, dy, dx + w, dy + h)).rempty());
if (intersect && sbp == dbp && (((_sy < _dy) && ((ypage + page_height) > _dy)) || ((sx < dx) && ((xpage + page_width) > dx))))
{
int starty = (yinc > 0) ? 0 : h-1;
@@ -4657,6 +4665,14 @@ __forceinline void GSState::VertexKick(u32 skip)
u32 next = m_vertex.next;
u32 xy_tail = m_vertex.xy_tail;
if (GSIsHardwareRenderer() && GSLocalMemory::m_psm[m_context->ZBUF.PSM].bpp == 32)
{
if (GSConfig.UserHacks_Limit24BitDepth == GSLimit24BitDepth::PrioritizeUpper)
m_v.XYZ.Z = ((m_v.XYZ.Z >> 8) & ~0xFF) | (m_v.XYZ.Z & 0xFF);
else if (GSConfig.UserHacks_Limit24BitDepth == GSLimit24BitDepth::PrioritizeLower)
m_v.XYZ.Z &= 0x00FFFFFF;
}
// callers should write XYZUVF to m_v.m[1] in one piece to have this load store-forwarded, either by the cpu or the compiler when this function is inlined
const GSVector4i new_v0(m_v.m[0]);

View File

@@ -211,13 +211,20 @@ protected:
void CorrectATEAlphaMinMax(const u32 atst, const int aref);
public:
enum EEGS_TransferType
{
EE_to_GS,
GS_to_GS,
GS_to_EE
};
struct GSUploadQueue
{
GIFRegBITBLTBUF blit;
GSVector4i rect;
int draw;
bool zero_clear;
bool ee_to_gs;
EEGS_TransferType transfer_type;
};
enum NoGapsType

View File

@@ -918,10 +918,15 @@ void GSDevice::Resize(int width, int height)
GSVector2i s = m_current->GetSize();
int multiplier = 1;
while (width > s.x || height > s.y)
if ((width > s.x || height > s.y))
{
s = m_current->GetSize() * GSVector2i(++multiplier);
while (width > s.x || height > s.y)
{
s = m_current->GetSize() * GSVector2i(++multiplier);
}
}
else
s = GSVector2i(width, height);
if (ResizeRenderTarget(&dTex, s.x, s.y, false, false))
{

View File

@@ -401,6 +401,7 @@ struct alignas(16) GSHWDrawConfig
// Depth clamp
u32 zclamp : 1;
u32 zfloor : 1;
// Hack
u32 tcoffsethack : 1;

View File

@@ -22,7 +22,7 @@
#include "common/Timer.h"
#include "fmt/format.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include <algorithm>
#include <array>
@@ -714,6 +714,15 @@ void GSRenderer::VSync(u32 field, bool registers_written, bool idle_frame)
u32 screenshot_width, screenshot_height;
std::vector<u32> screenshot_pixels;
if (GSConfig.LinearPresent == GSPostBilinearMode::BilinearSharp)
{
const GSTexture* current = g_gs_device->GetCurrent();
const GSVector2i internal_res = GetInternalResolution();
if (current->GetWidth() > internal_res.x || current->GetHeight() > internal_res.y)
g_gs_device->Resize(internal_res.x, internal_res.y);
}
if (!m_dump && m_dump_frames > 0)
{
if (GSConfig.UserHacks_ReadTCOnClose)

View File

@@ -15,7 +15,7 @@
#include "common/StringUtil.h"
#include "common/Path.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include <appmodel.h>
#include <array>

View File

@@ -16,7 +16,7 @@
#include "common/StringUtil.h"
#include "imgui.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include <bit>
#include <fstream>
@@ -1760,6 +1760,7 @@ void GSDevice11::SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstant
sm.AddMacro("PS_DITHER", sel.dither);
sm.AddMacro("PS_DITHER_ADJUST", sel.dither_adjust);
sm.AddMacro("PS_ZCLAMP", sel.zclamp);
sm.AddMacro("PS_ZFLOOR", sel.zfloor);
sm.AddMacro("PS_SCANMSK", sel.scanmsk);
sm.AddMacro("PS_AUTOMATIC_LOD", sel.automatic_lod);
sm.AddMacro("PS_MANUAL_LOD", sel.manual_lod);

View File

@@ -750,6 +750,8 @@ bool GSDevice12::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
InitializeState();
InitializeSamplers();
// Reference stencil isn't tied to pipeline, so we can set it once and leave it.
SetStencilRef(1);
return true;
}
@@ -2920,6 +2922,7 @@ const ID3DBlob* GSDevice12::GetTFXPixelShader(const GSHWDrawConfig::PSSelector&
sm.AddMacro("PS_DITHER", sel.dither);
sm.AddMacro("PS_DITHER_ADJUST", sel.dither_adjust);
sm.AddMacro("PS_ZCLAMP", sel.zclamp);
sm.AddMacro("PS_ZFLOOR", sel.zfloor);
sm.AddMacro("PS_SCANMSK", sel.scanmsk);
sm.AddMacro("PS_AUTOMATIC_LOD", sel.automatic_lod);
sm.AddMacro("PS_MANUAL_LOD", sel.manual_lod);
@@ -3740,7 +3743,7 @@ void GSDevice12::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSV
IASetVertexBuffer(vertices, sizeof(vertices[0]), 4);
SetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
SetPipeline(m_convert[SetDATMShader(datm)].get());
SetStencilRef(1);
// Reference stencil value set on Create()
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
@@ -3828,26 +3831,6 @@ GSTexture12* GSDevice12::SetupPrimitiveTrackingDATE(GSHWDrawConfig& config, Pipe
void GSDevice12::RenderHW(GSHWDrawConfig& config)
{
// Destination Alpha Setup
const bool stencil_DATE_One = config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne;
const bool stencil_DATE = (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil || stencil_DATE_One);
// TODO: Backport from vk.
if (stencil_DATE_One)
{
config.ps.date = 0;
config.alpha_second_pass.ps.date = 0;
if (!config.ps.IsFeedbackLoop())
{
config.require_one_barrier = false;
config.require_full_barrier = false;
}
if (!config.alpha_second_pass.ps.IsFeedbackLoop())
{
config.alpha_second_pass.require_one_barrier = false;
config.alpha_second_pass.require_full_barrier = false;
}
}
GSTexture12* colclip_rt = static_cast<GSTexture12*>(g_gs_device->GetColorClipTexture());
GSTexture12* draw_rt = static_cast<GSTexture12*>(config.rt);
@@ -3910,8 +3893,29 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
}
}
if (stencil_DATE)
SetupDATE(draw_rt, config.ds, config.datm, config.drawarea);
// Destination Alpha Setup
const bool need_barrier = m_features.texture_barrier && (config.require_one_barrier || config.require_full_barrier);
switch (config.destination_alpha)
{
case GSHWDrawConfig::DestinationAlphaMode::Off: // No setup
case GSHWDrawConfig::DestinationAlphaMode::Full: // No setup
case GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking: // Setup is done below
break;
case GSHWDrawConfig::DestinationAlphaMode::StencilOne: // setup is done below
{
// we only need to do the setup here if we don't have barriers, in which case do full DATE.
if (!need_barrier)
{
SetupDATE(draw_rt, config.ds, config.datm, config.drawarea);
config.destination_alpha = GSHWDrawConfig::DestinationAlphaMode::Stencil;
}
}
break;
case GSHWDrawConfig::DestinationAlphaMode::Stencil:
SetupDATE(draw_rt, config.ds, config.datm, config.drawarea);
break;
}
// stream buffer in first, in case we need to exec
SetVSConstantBuffer(config.cb_vs);
@@ -4033,6 +4037,17 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
// For depth testing and sampling, use a read only dsv, otherwise use a write dsv
OMSetRenderTargets(draw_rt, draw_ds, config.scissor, config.tex && config.tex == config.ds);
// DX12 equivalent of vkCmdClearAttachments for StencilOne
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne)
{
EndRenderPass();
// Make sure the DSV is in writeable state
draw_ds->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
D3D12_RECT rect = {config.drawarea.left, config.drawarea.top, config.drawarea.left + config.drawarea.width(), config.drawarea.top + config.drawarea.height()};
GetCommandList()->ClearDepthStencilView(draw_ds->GetWriteDescriptor(), D3D12_CLEAR_FLAG_STENCIL, 0.0f, 1, 1, &rect);
}
// Begin render pass if new target or out of the area.
if (!m_in_render_pass)
{
@@ -4042,14 +4057,18 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
// Denormalize clear color for hw colclip.
clear_color *= GSVector4::cxpr(255.0f / 65535.0f, 255.0f / 65535.0f, 255.0f / 65535.0f, 1.0f);
}
const bool stencil_DATE = config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne;
BeginRenderPass(GetLoadOpForTexture(draw_rt),
draw_rt ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
GetLoadOpForTexture(draw_ds),
draw_ds ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
stencil_DATE ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE :
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
stencil_DATE ? (feedback ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE :
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD) :
stencil_DATE ? (need_barrier ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE :
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD) :
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
clear_color, draw_ds ? draw_ds->GetClearDepth() : 0.0f, 1);
}

View File

@@ -3194,6 +3194,7 @@ void GSRendererHW::Draw()
float target_scale = GetTextureScaleFactor();
bool scaled_copy = false;
int scale_draw = IsScalingDraw(src, m_primitive_covers_without_gaps != NoGapsType::GapsFound);
if (GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off)
{
if (target_scale > 1.0f && scale_draw > 0)
@@ -3202,9 +3203,15 @@ void GSRendererHW::Draw()
// 2 == Upscale, so likely putting it over the top of the render target.
if (scale_draw == 1)
{
if (!PRIM->ABE || GSConfig.UserHacks_NativeScaling < GSNativeScaling::NormalUpscaled)
target_scale = 1.0f;
m_downscale_source = src->m_from_target ? src->m_from_target->GetScale() > 1.0f : false;
const bool highlights_only = m_cached_ctx.TEST.ATE || (PRIM->ABE && m_context->ALPHA.C == 2 && m_context->ALPHA.FIX == 255);
// If it's alpha tested/stenciling for the bloom, we don't want to using the Upscaled versions. Also if the source is already native scale, may as well keep it so.
// Overlap check is for games such as Tomb Raider, where it recursively downsamples.
// Also make sure this isn't a blend, just draw (possibly with modulation).
if (GSConfig.UserHacks_NativeScaling < GSNativeScaling::NormalUpscaled || highlights_only || !PRIM->ABE || (src->m_from_target && src->m_from_target->Overlaps(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, m_r)))
{
target_scale = 1.0f;
}
}
else
m_downscale_source = ((GSConfig.UserHacks_NativeScaling != GSNativeScaling::Aggressive && GSConfig.UserHacks_NativeScaling != GSNativeScaling::AggressiveUpscaled) || !src->m_from_target) ? false : src->m_from_target->GetScale() > 1.0f; // Bad for GTA + Full Spectrum Warrior, good for Sacred Blaze + Parappa.
@@ -3232,7 +3239,7 @@ void GSRendererHW::Draw()
// This upscaling hack is for games which construct P8 textures by drawing a bunch of small sprites in C32,
// then reinterpreting it as P8. We need to keep the off-screen intermediate textures at native resolution,
// but not propagate that through to the normal render targets. Test Case: Crash Wrath of Cortex.
if (no_ds && src && !m_channel_shuffle && src->m_from_target && (GSConfig.UserHacks_NativePaletteDraw || (src->m_target_direct && src->m_from_target->m_downscaled && scale_draw <= 1)) &&
if (no_ds && src && !m_channel_shuffle && src->m_from_target && (GSConfig.UserHacks_NativePaletteDraw || (src->m_target_direct && src->m_from_target->m_downscaled && scale_draw <= 1)) &&
src->m_scale == 1.0f && (src->m_TEX0.PSM == PSMT8 || src->m_TEX0.TBP0 == m_cached_ctx.FRAME.Block()))
{
GL_CACHE("HW: Using native resolution for target based on texture source");
@@ -3525,7 +3532,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 = (GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && (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;
const bool preserve_downscale_draw = (GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && ((std::abs(scale_draw) == 1 && !scaled_copy) || (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 || GSConfig.UserHacks_NativeScaling == GSNativeScaling::NormalUpscaled) && !possible_shuffle) ? GetTextureScaleFactor() : target_scale, GSTextureCache::RenderTarget, true,
fm, false, force_preload, preserve_rt_rgb, preserve_rt_alpha, lookup_rect, possible_shuffle, is_possible_mem_clear && FRAME_TEX0.TBP0 != m_cached_ctx.ZBUF.Block(),
@@ -5138,6 +5145,7 @@ void GSRendererHW::EmulateZbuffer(const GSTextureCache::Target* ds)
m_conf.cb_vs.max_depth = GSVector2i(0xFFFFFFFF);
//ps_cb.MaxDepth = GSVector4(0.0f, 0.0f, 0.0f, 1.0f);
m_conf.ps.zclamp = 0;
m_conf.ps.zfloor = !m_cached_ctx.ZBUF.ZMSK;
if (clamp_z)
{
@@ -7024,7 +7032,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
// When using native HPO, the top-left column/row of pixels are often not drawn. Clamp these away to avoid sampling black,
// causing bleeding into the edges of the downsampled texture.
const u32 downsample_factor = static_cast<u32>(src_target->GetScale());
const GSVector2i clamp_min = (GSConfig.UserHacks_HalfPixelOffset < GSHalfPixelOffset::Native) ?
const GSVector2i clamp_min = (GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native) ?
GSVector2i(0, 0) :
GSVector2i(downsample_factor, downsample_factor);
GSVector4i copy_rect = tmm.coverage;
@@ -9222,7 +9230,7 @@ int GSRendererHW::IsScalingDraw(GSTextureCache::Source* src, bool no_gaps)
const bool no_resize = (std::abs(draw_size.x - tex_size.x) <= 1 && std::abs(draw_size.y - tex_size.y) <= 1);
const bool can_maintain = no_resize || (!is_target_src && m_index.tail == 2);
if (!src || ((!is_target_src || src->m_from_target->m_downscaled) && can_maintain))
if (!src || ((!is_target_src || (src->m_from_target->m_downscaled || GSConfig.UserHacks_NativeScaling > GSNativeScaling::Aggressive)) && can_maintain))
return -1;
const GSDrawingContext& next_ctx = m_env.CTXT[m_env.PRIM.CTXT];
@@ -9237,7 +9245,7 @@ int GSRendererHW::IsScalingDraw(GSTextureCache::Source* src, bool no_gaps)
// Only allow non-bilineared downscales if it's most of the target (misdetections of shadows in Naruto, Transformers etc), otherwise it's fine.
const GSVector4i src_valid = src->m_from_target ? src->m_from_target->m_valid : src->m_valid_rect;
const GSVector2i tex_size_half = GSVector2i((src->GetRegion().HasX() ? src->GetRegionSize().x : src_valid.width()) / 2, (src->GetRegion().HasY() ? src->GetRegionSize().y : src_valid.height()) / 2);
const bool possible_downscale = m_context->TEX1.MMIN == 1 || !src->m_from_target || src->m_from_target->m_downscaled || tex_size.x >= tex_size_half.x || tex_size.y >= tex_size_half.y;
const bool possible_downscale = m_context->TEX1.MMIN == 1 || !src->m_from_target || src->m_from_target->m_downscaled || GSConfig.UserHacks_NativeScaling > GSNativeScaling::Aggressive || tex_size.x >= tex_size_half.x || tex_size.y >= tex_size_half.y;
if (is_downscale && (draw_size.x >= PCRTCDisplays.GetResolution().x || !possible_downscale))
return 0;

View File

@@ -2756,7 +2756,22 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
if (!tex)
return nullptr;
g_gs_device->StretchRect(dst->m_texture, sRect, tex, dRect, (type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY, dst->m_scale < scale);
if (scale == 1.0f)
{
// When using native HPO, the top-left column/row of pixels are often not drawn. Clamp these away to avoid sampling black,
// causing bleeding into the edges of the downsampled texture.
const u32 downsample_factor = static_cast<u32>(dst->GetScale());
const GSVector2i clamp_min = (GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native) ?
GSVector2i(0, 0) :
GSVector2i(downsample_factor, downsample_factor);
const GSVector4 dRect = GSVector4(dst->GetUnscaledRect());
g_gs_device->FilteredDownsampleTexture(dst->m_texture, tex, downsample_factor, clamp_min, dRect);
}
else
g_gs_device->StretchRect(dst->m_texture, sRect, tex, dRect, (type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY, dst->m_scale < scale);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
m_target_memory_usage = (m_target_memory_usage - dst->m_texture->GetMemUsage()) + tex->GetMemUsage();

View File

@@ -12,7 +12,7 @@
#include "Config.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "GS/GSExtra.h"
#include "GS/GSLocalMemory.h"
#include "GS/Renderers/HW/GSTextureReplacements.h"

View File

@@ -1878,6 +1878,7 @@ void GSDeviceMTL::MRESetHWPipelineState(GSHWDrawConfig::VSSelector vssel, GSHWDr
setFnConstantI(m_fn_constants, pssel.dither, GSMTLConstantIndex_PS_DITHER);
setFnConstantI(m_fn_constants, pssel.dither_adjust, GSMTLConstantIndex_PS_DITHER_ADJUST);
setFnConstantB(m_fn_constants, pssel.zclamp, GSMTLConstantIndex_PS_ZCLAMP);
setFnConstantB(m_fn_constants, pssel.zfloor, GSMTLConstantIndex_PS_ZFLOOR);
setFnConstantB(m_fn_constants, pssel.tcoffsethack, GSMTLConstantIndex_PS_TCOFFSETHACK);
setFnConstantB(m_fn_constants, pssel.urban_chaos_hle, GSMTLConstantIndex_PS_URBAN_CHAOS_HLE);
setFnConstantB(m_fn_constants, pssel.tales_of_abyss_hle, GSMTLConstantIndex_PS_TALES_OF_ABYSS_HLE);

View File

@@ -208,6 +208,7 @@ enum GSMTLFnConstants
GSMTLConstantIndex_PS_DITHER,
GSMTLConstantIndex_PS_DITHER_ADJUST,
GSMTLConstantIndex_PS_ZCLAMP,
GSMTLConstantIndex_PS_ZFLOOR,
GSMTLConstantIndex_PS_TCOFFSETHACK,
GSMTLConstantIndex_PS_URBAN_CHAOS_HLE,
GSMTLConstantIndex_PS_TALES_OF_ABYSS_HLE,

View File

@@ -61,6 +61,7 @@ constant uint PS_CHANNEL [[function_constant(GSMTLConstantIndex_PS_CH
constant uint PS_DITHER [[function_constant(GSMTLConstantIndex_PS_DITHER)]];
constant uint PS_DITHER_ADJUST [[function_constant(GSMTLConstantIndex_PS_DITHER_ADJUST)]];
constant bool PS_ZCLAMP [[function_constant(GSMTLConstantIndex_PS_ZCLAMP)]];
constant bool PS_ZFLOOR [[function_constant(GSMTLConstantIndex_PS_ZFLOOR)]];
constant bool PS_TCOFFSETHACK [[function_constant(GSMTLConstantIndex_PS_TCOFFSETHACK)]];
constant bool PS_URBAN_CHAOS_HLE [[function_constant(GSMTLConstantIndex_PS_URBAN_CHAOS_HLE)]];
constant bool PS_TALES_OF_ABYSS_HLE [[function_constant(GSMTLConstantIndex_PS_TALES_OF_ABYSS_HLE)]];
@@ -102,6 +103,7 @@ constant bool NEEDS_RT = NEEDS_RT_FOR_AFAIL || NEEDS_RT_EARLY || (!PS_PRIM_CHECK
constant bool PS_COLOR0 = !PS_NO_COLOR;
constant bool PS_COLOR1 = !PS_NO_COLOR1;
constant bool PS_ZOUTPUT = PS_ZCLAMP || PS_ZFLOOR;
struct MainVSIn
{
@@ -137,7 +139,7 @@ struct MainPSOut
{
float4 c0 [[color(0), index(0), function_constant(PS_COLOR0)]];
float4 c1 [[color(0), index(1), function_constant(PS_COLOR1)]];
float depth [[depth(less), function_constant(PS_ZCLAMP)]];
float depth [[depth(less), function_constant(PS_ZOUTPUT)]];
};
// MARK: - Vertex functions
@@ -1209,8 +1211,13 @@ struct PSMain
}
if (PS_COLOR1)
out.c1 = alpha_blend;
float depth_value = PS_ZFLOOR ? (floor(in.p.z * exp2(32.0f)) * exp2(-32.0f)) : in.p.z;
if (PS_ZCLAMP)
out.depth = min(in.p.z, cb.max_depth);
out.depth = min(depth_value, cb.max_depth);
else if (PS_ZFLOOR)
out.depth = depth_value;
return out;
}

View File

@@ -15,7 +15,7 @@
#include "common/StringUtil.h"
#include "imgui.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include <cinttypes>
#include <fstream>
@@ -1389,7 +1389,9 @@ std::string GSDeviceOGL::GetPSSource(const PSSelector& sel)
+ fmt::format("#define PS_DITHER {}\n", sel.dither)
+ fmt::format("#define PS_DITHER_ADJUST {}\n", sel.dither_adjust)
+ fmt::format("#define PS_ZCLAMP {}\n", sel.zclamp)
+ fmt::format("#define PS_ZFLOOR {}\n", sel.zfloor)
+ fmt::format("#define PS_BLEND_MIX {}\n", sel.blend_mix)
+ fmt::format("#define PS_ZCLAMP {}\n", sel.zclamp)
+ fmt::format("#define PS_ROUND_INV {}\n", sel.round_inv)
+ fmt::format("#define PS_FIXED_ONE_A {}\n", sel.fixed_one_a)
+ fmt::format("#define PS_PABE {}\n", sel.pabe)

View File

@@ -4777,6 +4777,7 @@ VkShaderModule GSDeviceVK::GetTFXFragmentShader(const GSHWDrawConfig::PSSelector
AddMacro(ss, "PS_DITHER", sel.dither);
AddMacro(ss, "PS_DITHER_ADJUST", sel.dither_adjust);
AddMacro(ss, "PS_ZCLAMP", sel.zclamp);
AddMacro(ss, "PS_ZFLOOR", sel.zfloor);
AddMacro(ss, "PS_PABE", sel.pabe);
AddMacro(ss, "PS_SCANMSK", sel.scanmsk);
AddMacro(ss, "PS_TEX_IS_FB", sel.tex_is_fb);

View File

@@ -4,7 +4,7 @@
#include "GameDatabase.h"
#include "GS/GS.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "vtlb.h"
#include "common/Console.h"

View File

@@ -13,7 +13,7 @@
#include "cubeb/cubeb.h"
#include "fmt/format.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#ifdef _WIN32
#include "common/RedtapeWindows.h"

View File

@@ -4,7 +4,7 @@
#include "Achievements.h"
#include "GS.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "ImGui/FullscreenUI.h"
#include "ImGui/ImGuiOverlays.h"
#include "Input/InputManager.h"

View File

@@ -11,15 +11,27 @@
#include "fmt/format.h"
#include <deque>
using namespace R5900;
const int rdram_devices = 2; // put 8 for TOOL and 2 for PS2 and PSX
int rdram_sdevid = 0;
std::deque<u8> ee_sio_rx_fifo;
std::deque<u8> ee_sio_tx_fifo;
void hwReset()
{
std::memset(eeHw, 0, sizeof(eeHw));
{
std::deque<u8> empty_rx;
std::swap(ee_sio_rx_fifo, empty_rx);
std::deque<u8> empty_tx;
std::swap(ee_sio_tx_fifo, empty_tx);
}
psHu32(SBUS_F260) = 0x1D000060;
// i guess this is kinda a version, it's used by some bioses

View File

@@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include <deque>
#pragma once
namespace EEMemoryMap
@@ -355,3 +357,6 @@ extern void hwReset();
extern const int rdram_devices;
extern int rdram_sdevid;
extern std::deque<u8> ee_sio_rx_fifo;
extern std::deque<u8> ee_sio_tx_fifo;

View File

@@ -125,7 +125,23 @@ mem32_t _hwRead32(u32 mem)
switch( mem )
{
case SIO_ISR:
// Not (yet) hardware tested
// The PS2SDK behaviour is as follows:
// TX: Don't write to TX FIFO until until bit 15 is 0
// RX: RX FIFO has data when bits 8-11 are not 0 (maybe a byte count?)
// RX: When reading from the RX FIFO, set bits 0-2 to 1 (why??)
// For TX, we don't do any LLE buffering, so we can keep bit 15 to 0
// For RX, just hack it so when the ee_rx_fifo.size() != 0, ISR = 0xf00
if(!ee_sio_rx_fifo.empty())
return 0xf00;
return 0x0;
break;
case 0x1000f410:
case MCH_RICM:
return 0;
@@ -211,6 +227,16 @@ mem32_t hwRead32_page_0F_INTC_HACK(u32 mem)
template< uint page >
mem8_t _hwRead8(u32 mem)
{
if(mem == SIO_RXFIFO)
{
if(ee_sio_rx_fifo.empty())
return 0; // needs hardware test, what does it return with the FIFO is empty
const char c = ee_sio_rx_fifo.front();
ee_sio_rx_fifo.pop_front();
return c;
}
u32 ret32 = _hwRead32<page, false>(mem & ~0x03);
return ((u8*)&ret32)[mem & 0x03];
}

View File

@@ -285,26 +285,35 @@ void _hwWrite8(u32 mem, u8 value)
#endif
if (mem == SIO_TXFIFO)
{
static bool included_newline = false;
static char sio_buffer[1024];
static int sio_count;
if (value == '\r')
static bool last_char_was_cr = false;
// skip the \n in \r\n
if(last_char_was_cr && (value == '\n'))
{
included_newline = true;
sio_buffer[sio_count++] = '\n';
last_char_was_cr = false;
return;
}
else if (!included_newline || (value != '\n'))
last_char_was_cr = value == '\r';
bool should_flush_cause_newline = false;
if (last_char_was_cr)
{
included_newline = false;
sio_buffer[sio_count++] = value;
should_flush_cause_newline = true;
ee_sio_tx_fifo.push_back('\n');
}
else
{
should_flush_cause_newline = value == '\n';
ee_sio_tx_fifo.push_back(value);
}
if ((sio_count == std::size(sio_buffer)-1) || (sio_count != 0 && sio_buffer[sio_count-1] == '\n'))
// Check if the only thing in the buffer
if (ee_sio_tx_fifo.size() == 1024 || should_flush_cause_newline)
{
sio_buffer[sio_count] = 0;
eeConLog( ShiftJIS_ConvertString(sio_buffer) );
sio_count = 0;
std::string output_string(ee_sio_tx_fifo.begin(), ee_sio_tx_fifo.end());
eeConLog(ShiftJIS_ConvertString(output_string.c_str()));
ee_sio_tx_fifo.clear();
}
return;
}

View File

@@ -45,7 +45,7 @@
#include "SIO/Pad/Pad.h"
#include "SIO/Sio.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "IconsPromptFont.h"
#include "imgui.h"
#include "imgui_internal.h"
@@ -1439,7 +1439,7 @@ void FullscreenUI::DoVMInitialize(const VMBootParameters& boot_params, bool swit
if (switch_to_landing_on_failure)
MTGS::RunOnGSThread(SwitchToLanding);
return;
}
@@ -6589,57 +6589,57 @@ void FullscreenUI::DrawAdvancedSettingsPage()
{
MenuHeading(FSUI_CSTR("Emotion Engine"));
DrawIntListSetting(bsi, FSUI_CSTR("Rounding Mode"),
DrawIntListSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROW_TREND_DOWN, "Rounding Mode"),
FSUI_CSTR("Determines how the results of floating-point operations are rounded. Some games need specific settings."),
"EmuCore/CPU", "FPU.Roundmode", static_cast<int>(FPRoundMode::ChopZero), ee_rounding_mode_settings,
std::size(ee_rounding_mode_settings), true);
DrawIntListSetting(bsi, FSUI_CSTR("Division Rounding Mode"),
DrawIntListSetting(bsi, FSUI_ICONSTR(ICON_FA_DIVIDE, "Division Rounding Mode"),
FSUI_CSTR("Determines how the results of floating-point division is rounded. Some games need specific settings."),
"EmuCore/CPU", "FPUDiv.Roundmode", static_cast<int>(FPRoundMode::Nearest),
ee_rounding_mode_settings, std::size(ee_rounding_mode_settings), true);
DrawClampingModeSetting(bsi, FSUI_CSTR("Clamping Mode"),
DrawClampingModeSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROW_TURN_DOWN, "Clamping Mode"),
FSUI_CSTR("Determines how out-of-range floating point numbers are handled. Some games need specific settings."), -1);
DrawToggleSetting(bsi, FSUI_CSTR("Enable EE Recompiler"),
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_MICROCHIP, "Enable EE Recompiler"),
FSUI_CSTR("Performs just-in-time binary translation of 64-bit MIPS-IV machine code to native code."), "EmuCore/CPU/Recompiler",
"EnableEE", true);
DrawToggleSetting(bsi, FSUI_CSTR("Enable EE Cache"), FSUI_CSTR("Enables simulation of the EE's cache. Slow."),
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_BUCKET, "Enable EE Cache"), FSUI_CSTR("Enables simulation of the EE's cache. Slow."),
"EmuCore/CPU/Recompiler", "EnableEECache", false);
DrawToggleSetting(bsi, FSUI_CSTR("Enable INTC Spin Detection"),
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROWS_SPIN, "Enable INTC Spin Detection"),
FSUI_CSTR("Huge speedup for some games, with almost no compatibility side effects."), "EmuCore/Speedhacks", "IntcStat", true);
DrawToggleSetting(bsi, FSUI_CSTR("Enable Wait Loop Detection"),
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROWS_SPIN, "Enable Wait Loop Detection"),
FSUI_CSTR("Moderate speedup for some games, with no known side effects."), "EmuCore/Speedhacks", "WaitLoop", true);
DrawToggleSetting(bsi, FSUI_CSTR("Enable Fast Memory Access"),
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_MEMORY, "Enable Fast Memory Access"),
FSUI_CSTR("Uses backpatching to avoid register flushing on every memory access."), "EmuCore/CPU/Recompiler", "EnableFastmem",
true);
MenuHeading(FSUI_CSTR("Vector Units"));
DrawIntListSetting(bsi, FSUI_CSTR("VU0 Rounding Mode"),
DrawIntListSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROW_TREND_DOWN, "VU0 Rounding Mode"),
FSUI_CSTR("Determines how the results of floating-point operations are rounded. Some games need specific settings."),
"EmuCore/CPU", "VU0.Roundmode", static_cast<int>(FPRoundMode::ChopZero),
ee_rounding_mode_settings, std::size(ee_rounding_mode_settings), true);
DrawClampingModeSetting(bsi, FSUI_CSTR("VU0 Clamping Mode"),
DrawClampingModeSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROW_TURN_DOWN, "VU0 Clamping Mode"),
FSUI_CSTR("Determines how out-of-range floating point numbers are handled. Some games need specific settings."), 0);
DrawIntListSetting(bsi, FSUI_CSTR("VU1 Rounding Mode"),
DrawIntListSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROW_TREND_DOWN, "VU1 Rounding Mode"),
FSUI_CSTR("Determines how the results of floating-point operations are rounded. Some games need specific settings."),
"EmuCore/CPU", "VU1.Roundmode", static_cast<int>(FPRoundMode::ChopZero),
ee_rounding_mode_settings, std::size(ee_rounding_mode_settings), true);
DrawClampingModeSetting(bsi, FSUI_CSTR("VU1 Clamping Mode"),
DrawClampingModeSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROW_TURN_DOWN, "VU1 Clamping Mode"),
FSUI_CSTR("Determines how out-of-range floating point numbers are handled. Some games need specific settings."), 1);
DrawToggleSetting(bsi, FSUI_CSTR("Enable VU0 Recompiler (Micro Mode)"),
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_MICROCHIP, "Enable VU0 Recompiler (Micro Mode)"),
FSUI_CSTR("New Vector Unit recompiler with much improved compatibility. Recommended."), "EmuCore/CPU/Recompiler", "EnableVU0",
true);
DrawToggleSetting(bsi, FSUI_CSTR("Enable VU1 Recompiler"),
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_MICROCHIP, "Enable VU1 Recompiler"),
FSUI_CSTR("New Vector Unit recompiler with much improved compatibility. Recommended."), "EmuCore/CPU/Recompiler", "EnableVU1",
true);
DrawToggleSetting(bsi, FSUI_CSTR("Enable VU Flag Optimization"),
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_FLAG, "Enable VU Flag Optimization"),
FSUI_CSTR("Good speedup and high compatibility, may cause graphical errors."), "EmuCore/Speedhacks", "vuFlagHack", true);
DrawToggleSetting(bsi, FSUI_CSTR("Enable Instant VU1"),
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_CLOCK, "Enable Instant VU1"),
FSUI_CSTR("Runs VU1 instantly. Provides a modest speed improvement in most games. Safe for most games, but a few games may exhibit graphical errors."),
"EmuCore/Speedhacks", "vu1Instant", true);
MenuHeading(FSUI_CSTR("I/O Processor"));
DrawToggleSetting(bsi, FSUI_CSTR("Enable IOP Recompiler"),
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_MICROCHIP, "Enable IOP Recompiler"),
FSUI_CSTR("Performs just-in-time binary translation of 32-bit MIPS-I machine code to native code."), "EmuCore/CPU/Recompiler",
"EnableIOP", true);

View File

@@ -22,7 +22,7 @@
#include "common/Threading.h"
#include "common/Timer.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "imgui_internal.h"
#include "imgui_stdlib.h"
@@ -708,16 +708,16 @@ void ImGuiFullscreen::EndLayout()
const float notification_margin = LayoutScale(10.0f);
const float spacing = LayoutScale(10.0f);
const float notification_vertical_pos = GetNotificationVerticalPosition();
// Get the horizonal position based on alignment
float horizontal_pos;
if (s_notification_horizontal_position <= 0.0f)
horizontal_pos = notification_margin; // Left
else if (s_notification_horizontal_position >= 1.0f)
else if (s_notification_horizontal_position >= 1.0f)
horizontal_pos = ImGui::GetIO().DisplaySize.x - notification_margin; // Right
else
horizontal_pos = ImGui::GetIO().DisplaySize.x * s_notification_horizontal_position; // Center
ImVec2 position(horizontal_pos, notification_vertical_pos * ImGui::GetIO().DisplaySize.y +
((notification_vertical_pos >= 0.5f) ? -notification_margin : notification_margin));
DrawProgressDialogs(position, spacing);
@@ -2574,11 +2574,11 @@ void ImGuiFullscreen::DrawInputDialog()
ImGuiInputTextFlags flags = ImGuiInputTextFlags_None;
if (s_input_dialog_filter_type != InputFilterType::None)
flags |= ImGuiInputTextFlags_CallbackCharFilter;
if (s_focus_reset_queued != FocusResetType::None)
ImGui::SetKeyboardFocusHere();
ImGui::InputText("##input", &s_input_dialog_text, flags,
ImGui::InputText("##input", &s_input_dialog_text, flags,
(s_input_dialog_filter_type != InputFilterType::None) ? input_callback : nullptr,
(s_input_dialog_filter_type != InputFilterType::None) ? static_cast<void*>(&s_input_dialog_filter_type) : nullptr);
@@ -3056,7 +3056,7 @@ void ImGuiFullscreen::DrawNotifications(ImVec2& position, float spacing)
final_x = position.x - box_width;
else if (s_notification_horizontal_position > 0.0f && s_notification_horizontal_position < 1.0f)
final_x = position.x - (box_width * 0.5f);
const ImVec2 box_min(final_x, actual_y);
const ImVec2 box_max(box_min.x + box_width, box_min.y + box_height);
const u32 background_color = (toast_background_color & ~IM_COL32_A_MASK) | (opacity << IM_COL32_A_SHIFT);
@@ -3209,14 +3209,14 @@ void ImGuiFullscreen::SetTheme(std::string_view theme)
}
else if (theme == "AMOLED")
{
UIBackgroundColor = HEX_TO_IMVEC4(0x000000, 0xff);
UIBackgroundColor = HEX_TO_IMVEC4(0x0A0A0A, 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);
UIPrimaryDarkColor = HEX_TO_IMVEC4(0x0A0A0A, 0xff);
UIPrimaryTextColor = HEX_TO_IMVEC4(0xffffff, 0xff);
UIDisabledColor = HEX_TO_IMVEC4(0x8d8d8d, 0xff);
UITextHighlightColor = HEX_TO_IMVEC4(0x676767, 0xff);

View File

@@ -5,7 +5,7 @@
#include "common/Pcsx2Defs.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "imgui.h"
#include "imgui_internal.h"

View File

@@ -6,7 +6,7 @@
#include "Counters.h"
#include "GS/GS.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "ImGui/FullscreenUI.h"
#include "ImGui/ImGuiFullscreen.h"
#include "ImGui/ImGuiManager.h"

View File

@@ -10,7 +10,7 @@
#include "GS/Renderers/Common/GSDevice.h"
#include "GS/Renderers/HW/GSTextureReplacements.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "IconsPromptFont.h"
#include "ImGui/FullscreenUI.h"
#include "ImGui/ImGuiAnimated.h"
@@ -619,6 +619,8 @@ __ri void ImGuiManager::DrawSettingsOverlay(float scale, float margin, float spa
APPEND("SD={}/{} ", GSConfig.SkipDrawStart, GSConfig.SkipDrawEnd);
if (GSConfig.UserHacks_TextureInsideRt != GSTextureInRtMode::Disabled)
APPEND("TexRT={} ", static_cast<unsigned>(GSConfig.UserHacks_TextureInsideRt));
if (GSConfig.UserHacks_Limit24BitDepth != GSLimit24BitDepth::Disabled)
APPEND("TDR={} ", static_cast<unsigned>(GSConfig.UserHacks_Limit24BitDepth));
if (GSConfig.UserHacks_BilinearHack != GSBilinearDirtyMode::Automatic)
APPEND("BLU={} ", static_cast<unsigned>(GSConfig.UserHacks_BilinearHack));
if (GSConfig.UserHacks_ForceEvenSpritePosition)

View File

@@ -67,7 +67,10 @@ void intBreakpoint(bool memcheck)
{
const u32 pc = cpuRegs.pc;
if (CBreakPoints::CheckSkipFirst(BREAKPOINT_EE, pc) != 0)
{
CBreakPoints::ClearSkipFirst(BREAKPOINT_EE);
return;
}
if (!memcheck)
{
@@ -161,6 +164,8 @@ static void execI()
intBreakpoint(false);
intCheckMemcheck();
CBreakPoints::CommitClearSkipFirst(BREAKPOINT_EE);
#endif
const u32 pc = cpuRegs.pc;

View File

@@ -6,7 +6,7 @@
#include "MTGS.h"
#include "MTVU.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "VMManager.h"
#include "common/FPControl.h"

View File

@@ -20,7 +20,7 @@
#include "Patch.h"
#include "R5900.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "fmt/format.h"
#include <algorithm>

View File

@@ -755,6 +755,7 @@ Pcsx2Config::GSOptions::GSOptions()
ManualUserHacks = false;
UserHacks_AlignSpriteX = false;
UserHacks_AutoFlush = GSHWAutoFlushLevel::Disabled;
UserHacks_Limit24BitDepth = GSLimit24BitDepth::Disabled;
UserHacks_CPUFBConversion = false;
UserHacks_ReadTCOnClose = false;
UserHacks_DisableDepthSupport = false;
@@ -847,6 +848,7 @@ bool Pcsx2Config::GSOptions::OptionsAreEqual(const GSOptions& right) const
OpEqu(UserHacks_CPUCLUTRender) &&
OpEqu(UserHacks_GPUTargetCLUTMode) &&
OpEqu(UserHacks_TextureInsideRt) &&
OpEqu(UserHacks_Limit24BitDepth) &&
OpEqu(UserHacks_BilinearHack) &&
OpEqu(OverrideTextureBarriers) &&
@@ -983,6 +985,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
SettingsWrapIntEnumEx(UserHacks_BilinearHack, "UserHacks_BilinearHack");
SettingsWrapBitBoolEx(UserHacks_NativePaletteDraw, "UserHacks_NativePaletteDraw");
SettingsWrapIntEnumEx(UserHacks_TextureInsideRt, "UserHacks_TextureInsideRt");
SettingsWrapIntEnumEx(UserHacks_Limit24BitDepth, "UserHacks_Limit24BitDepth");
SettingsWrapBitBoolEx(UserHacks_EstimateTextureRegion, "UserHacks_EstimateTextureRegion");
SettingsWrapBitBoolEx(FXAA, "fxaa");
SettingsWrapBitBool(ShadeBoost);
@@ -1111,6 +1114,7 @@ void Pcsx2Config::GSOptions::MaskUserHacks()
UserHacks_CPUFBConversion = false;
UserHacks_ReadTCOnClose = false;
UserHacks_TextureInsideRt = GSTextureInRtMode::Disabled;
UserHacks_Limit24BitDepth = GSLimit24BitDepth::Disabled;
UserHacks_EstimateTextureRegion = false;
UserHacks_TCOffsetX = 0;
UserHacks_TCOffsetY = 0;

View File

@@ -120,7 +120,10 @@ void psxBreakpoint(bool memcheck)
{
u32 pc = psxRegs.pc;
if (CBreakPoints::CheckSkipFirst(BREAKPOINT_IOP, pc) != 0)
{
CBreakPoints::ClearSkipFirst(BREAKPOINT_IOP);
return;
}
if (!memcheck)
{
@@ -208,6 +211,8 @@ static __fi void execI()
psxBreakpoint(false);
psxCheckMemcheck();
CBreakPoints::CommitClearSkipFirst(BREAKPOINT_IOP);
#endif
// Inject IRX hack

View File

@@ -6,7 +6,7 @@
#include "DebugTools/Debug.h"
#include "common/Console.h"
#include "IconsPromptFont.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "GS.h"
#include "Host.h"

View File

@@ -14,7 +14,7 @@
#include "Input/SDLInputSource.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "VMManager.h"
#include "common/Assertions.h"

View File

@@ -38,7 +38,7 @@
#include "common/StringUtil.h"
#include "common/ZipHelpers.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "fmt/format.h"
#include <csetjmp>

View File

@@ -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 = 77;
static constexpr u32 SHADER_CACHE_VERSION = 78;

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "USB/qemu-usb/qusb.h"
#include "USB/qemu-usb/desc.h"
#include "USB/qemu-usb/USBinternal.h"

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-3.0+
#include "usb-pad.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "IconsPromptFont.h"
#include "USB/qemu-usb/USBinternal.h"
#include "USB/usb-pad/usb-pad-sdl-ff.h"

View File

@@ -5,7 +5,7 @@
#include "common/Console.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "IconsPromptFont.h"
#include "Input/InputManager.h"
#include "StateWrapper.h"
@@ -209,6 +209,8 @@ namespace usb_pad
s->power_notches = USB::GetConfigInt(si, s->port, TypeName(), "power_notches", 5);
s->brake_notches = USB::GetConfigInt(si, s->port, TypeName(), "brake_notches", 8);
break;
default:
break;
}
}

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-3.0+
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "IconsPromptFont.h"
#include "Input/InputManager.h"
#include "StateWrapper.h"

View File

@@ -14,7 +14,7 @@
#include "fmt/format.h"
#include "StateWrapper.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
namespace usb_printer
{

View File

@@ -55,7 +55,7 @@
#include "common/Timer.h"
#include "common/emitter/x86emitter.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome.h"
#include "IconsPromptFont.h"
#include "cpuinfo.h"
#include "discord_rpc.h"
@@ -526,6 +526,7 @@ void VMManager::SetDefaultLoggingSettings(SettingsInterface& si)
si.SetBoolValue("Logging", "EnableSystemConsole", false);
si.SetBoolValue("Logging", "EnableFileLogging", true);
si.SetBoolValue("Logging", "EnableTimestamps", true);
si.SetBoolValue("Logging", "EnableEESIOInput", false);
si.SetBoolValue("Logging", "EnableVerbose", false);
si.SetBoolValue("Logging", "EnableEEConsole", false);
si.SetBoolValue("Logging", "EnableIOPConsole", false);
@@ -3725,15 +3726,16 @@ void VMManager::UpdateDiscordPresence(bool update_session_time)
auto lock = Achievements::GetLock();
if (Achievements::HasRichPresence())
if (Achievements::HasActiveGame() && Achievements::HasAchievementsOrLeaderboards())
{
rp.state = (state_string = StringUtil::Ellipsise(Achievements::GetRichPresenceString(), 128)).c_str();
if (const std::string& icon_url = Achievements::GetGameIconURL(); !icon_url.empty())
{
rp.largeImageKey = icon_url.c_str();
rp.largeImageText = s_title.c_str();
}
if (Achievements::HasRichPresence())
rp.state = (state_string = StringUtil::Ellipsise(Achievements::GetRichPresenceString(), 128)).c_str();
}
Discord_UpdatePresence(&rp);
@@ -3747,3 +3749,15 @@ void VMManager::PollDiscordPresence()
Discord_RunCallbacks();
}
bool VMManager::WriteBytesToEESIORXFIFO(const std::span<const u8> data)
{
if(ee_sio_rx_fifo.size() + data.size() > 1024)
{
Console.Warning("EE RX FIFO is full, not appending more bytes.");
return false;
}
ee_sio_rx_fifo.insert(ee_sio_rx_fifo.end(), data.begin(), data.end());
return true;
}

View File

@@ -6,6 +6,7 @@
#include <functional>
#include <mutex>
#include <optional>
#include <span>
#include <string>
#include <string_view>
#include <vector>
@@ -264,6 +265,9 @@ namespace VMManager
/// Called when the rich presence string, provided by RetroAchievements, changes.
void UpdateDiscordPresence(bool update_session_time);
/// Append bytes to the EE SIO RX FIFO. If it returns false, the FIFO is full and data is not inserted.
bool WriteBytesToEESIORXFIFO(const std::span<const u8> data);
/// Internal callbacks, implemented in the emu core.
namespace Internal
{

View File

@@ -1259,7 +1259,10 @@ static bool psxDynarecCheckBreakpoint()
{
u32 pc = psxRegs.pc;
if (CBreakPoints::CheckSkipFirst(BREAKPOINT_IOP, pc) == pc)
{
CBreakPoints::ClearSkipFirst(BREAKPOINT_IOP);
return false;
}
int bpFlags = psxIsBreakpointNeeded(pc);
bool hit = false;
@@ -1299,8 +1302,10 @@ static bool psxDynarecMemcheck(size_t i)
auto mc = CBreakPoints::GetMemChecks(BREAKPOINT_IOP)[i];
if (CBreakPoints::CheckSkipFirst(BREAKPOINT_IOP, pc) == pc)
{
CBreakPoints::ClearSkipFirst(BREAKPOINT_IOP);
return false;
}
if (mc.hasCond)
{
if (!mc.cond.Evaluate())
@@ -1373,7 +1378,7 @@ static void psxRecMemcheck(u32 op, u32 bits, bool store)
}
}
static void psxEncodeBreakpoint()
static bool psxEncodeBreakpoint()
{
if (psxIsBreakpointNeeded(psxpc) != 0)
{
@@ -1381,14 +1386,17 @@ static void psxEncodeBreakpoint()
xFastCall((void*)psxDynarecCheckBreakpoint);
xTEST(al, al);
xJNZ(iopExitRecompiledCode);
return true;
}
return false;
}
static void psxEncodeMemcheck()
static bool psxEncodeMemcheck()
{
int needed = psxIsMemcheckNeeded(psxpc);
if (needed == 0)
return;
return false;
u32 op = iopMemRead32(needed == 2 ? psxpc + 4 : psxpc);
const R5900::OPCODE& opcode = R5900::GetInstruction(op);
@@ -1409,6 +1417,7 @@ static void psxEncodeMemcheck()
psxRecMemcheck(op, 64, store);
break;
}
return true;
}
void psxRecompileNextInstruction(bool delayslot, bool swapped_delayslot)
@@ -1437,12 +1446,10 @@ void psxRecompileNextInstruction(bool delayslot, bool swapped_delayslot)
EEINST* old_inst_info = g_pCurInstInfo;
s_recompilingDelaySlot = delayslot;
// add breakpoint
if (!delayslot)
{
// Broken on x64
psxEncodeBreakpoint();
psxEncodeMemcheck();
if(psxEncodeBreakpoint() || psxEncodeMemcheck())
xFastCall((void*)CBreakPoints::CommitClearSkipFirst, BREAKPOINT_IOP);
}
else
{

View File

@@ -1498,7 +1498,10 @@ void dynarecCheckBreakpoint()
{
u32 pc = cpuRegs.pc;
if (CBreakPoints::CheckSkipFirst(BREAKPOINT_EE, pc) != 0)
{
CBreakPoints::ClearSkipFirst(BREAKPOINT_EE);
return;
}
const int bpFlags = isBreakpointNeeded(pc);
bool hit = false;
@@ -1532,7 +1535,10 @@ void dynarecMemcheck(size_t i)
const u32 op = memRead32(cpuRegs.pc);
const OPCODE& opcode = GetInstruction(op);
if (CBreakPoints::CheckSkipFirst(BREAKPOINT_EE, pc) != 0)
{
CBreakPoints::ClearSkipFirst(BREAKPOINT_EE);
return;
}
auto mc = CBreakPoints::GetMemChecks(BREAKPOINT_EE)[i];
@@ -1606,20 +1612,22 @@ void recMemcheck(u32 op, u32 bits, bool store)
}
}
void encodeBreakpoint()
bool encodeBreakpoint()
{
if (isBreakpointNeeded(pc) != 0)
{
iFlushCall(FLUSH_EVERYTHING | FLUSH_PC);
xFastCall((void*)dynarecCheckBreakpoint);
return true;
}
return false;
}
void encodeMemcheck()
bool encodeMemcheck()
{
const int needed = isMemcheckNeeded(pc);
if (needed == 0)
return;
return false;
const u32 op = memRead32(needed == 2 ? pc + 4 : pc);
const OPCODE& opcode = GetInstruction(op);
@@ -1643,6 +1651,7 @@ void encodeMemcheck()
recMemcheck(op, 128, store);
break;
}
return true;
}
void recompileNextInstruction(bool delayslot, bool swapped_delay_slot)
@@ -1653,8 +1662,8 @@ void recompileNextInstruction(bool delayslot, bool swapped_delay_slot)
// add breakpoint
if (!delayslot)
{
encodeBreakpoint();
encodeMemcheck();
if(encodeBreakpoint() || encodeMemcheck())
xFastCall((void*)CBreakPoints::CommitClearSkipFirst, BREAKPOINT_EE);
}
else
{

View File

@@ -233,7 +233,13 @@ public:
const u64 quick64 = pState->quick64[0];
for (const microBlockLinkRef& ref : quickLookup)
{
if (ref.quick != quick64) continue;
// if we're using the flag hack, ignore the mac flags going in to the new block too if an exact match wasn't requested.
if (mVUsFlagHack)
{
if ((ref.quick & ~0x0C04) != (quick64 & ~0x0C04)) continue;
}
else if (ref.quick != quick64) continue;
if (doConstProp && (ref.pBlock->pState.vi15 != pState->vi15)) continue;
if (doConstProp && (ref.pBlock->pState.vi15v != pState->vi15v)) continue;
return ref.pBlock;

View File

@@ -23,7 +23,7 @@ import functools
# pylint: disable=bare-except, disable=missing-function-docstring
src_dirs = [os.path.join(os.path.dirname(__file__), "..", "pcsx2"), os.path.join(os.path.dirname(__file__), "..", "pcsx2-qt")]
fa_file = os.path.join(os.path.dirname(__file__), "..", "3rdparty", "include", "IconsFontAwesome6.h")
fa_file = os.path.join(os.path.dirname(__file__), "..", "3rdparty", "include", "IconsFontAwesome.h")
pf_file = os.path.join(os.path.dirname(__file__), "..", "3rdparty", "include", "IconsPromptFont.h")
dst_file = os.path.join(os.path.dirname(__file__), "..", "pcsx2", "ImGui", "ImGuiManager.cpp")