Compare commits

...

24 Commits

Author SHA1 Message Date
chaoticgd
cd0c1607ef GameList: Clip flag and compatibility pixmaps to the available space 2025-05-31 02:35:34 +02:00
chaoticgd
26a4f71385 GameList: Prevent "Invalid" entry type appearing in filter list 2025-05-31 02:35:34 +02:00
chaoticgd
06b3e6ad71 GameList: Fix region flag icons for non-English languages 2025-05-31 02:35:34 +02:00
lightningterror
79d22a8d77 GS/HW: Add/adjust logs for failed texture creation. 2025-05-31 02:04:12 +02:00
lightningterror
9914212600 GS/GL: Add another hazard check, colclip hw.
Bonus, add missing texture copies info when doing shader copies.
2025-05-31 02:04:12 +02:00
lightningterror
765f55e67b GS/TC: Fine tune Frame buffer conversion. 2025-05-31 01:55:40 +02:00
PCSX2 Bot
2d922cc035 [ci skip] Qt: Update Base Translation. 2025-05-30 15:57:49 +02:00
TellowKrinkle
42e0625ab3 Interpreter: Fix FTOI on negative numbers 2025-05-29 13:15:09 +02:00
TellowKrinkle
c72e894fc7 iR5900: Faster FTOI 2025-05-29 13:15:09 +02:00
JordanTheToaster
5bc2342d47 MemoryCardFile: Fix memory card sorting on Linux 2025-05-29 13:07:27 +02:00
Ty
ea2b0b5e59 CI: Fix a regression for flathub uploads 2025-05-28 19:22:47 -04:00
refractionpcsx2
d70cc0221a GS/DX12: Fix HDR copy scissor area 2025-05-28 22:32:12 +02:00
refractionpcsx2
b12587b44e GameDB: Add Tex in RT for Bard's Tale 2025-05-28 18:33:27 +01:00
refractionpcsx2
c4708bdc35 GameDB: Add Tex in RT to required games 2025-05-28 18:01:49 +02:00
refractionpcsx2
1fa2c0bf50 GS/TC: Replace half right with Tex in RT, only update needed dirty 2025-05-28 18:01:49 +02:00
lightningterror
b4c70d357a GS/HW: Restore old coverage after updating mip layers. 2025-05-28 18:00:45 +02:00
PCSX2 Bot
f18262ee96 [ci skip] PAD: Update to latest controller database. 2025-05-26 21:18:58 +02:00
refractionpcsx2
c1f1761482 GS/HW: Invalidate cleared area if overlapping existing dirty 2025-05-26 13:45:47 +02:00
PCSX2 Bot
067c3eea16 [ci skip] Qt: Update Base Translation. 2025-05-26 02:03:40 +02:00
KamFretoZ
6957cc7001 FSUI: Fix save state duplicate entry 2025-05-26 01:46:30 +02:00
PCSX2 Bot
7dea23eea8 [ci skip] Qt: Update Base Translation. 2025-05-24 20:10:08 -04:00
TheTechnician27
319ec1f774 OSD: Fix performance overlay overwriting dump stats when shifted left 2025-05-24 12:33:32 +02:00
JohnSmith774
2079532e83 GameDB: Add memcard filters for some NTSC-J titles. (#12708)
Add memcard filters for OutRun2 SP - SPECIAL TOURS.
Add memcard filters for Another Century's Episode 2 Special Vocal Version.
Add memcard filters for Armored Core - Last Raven.
2025-05-24 12:32:03 +02:00
Mrlinkwii
de1d646fe9 github-workflows: Fix a broken link. 2025-05-24 12:30:08 +02:00
26 changed files with 1245 additions and 1162 deletions

View File

@@ -132,7 +132,7 @@ jobs:
- name: Push to Flathub (beta)
if: ${{ inputs.publish == true && (inputs.stableBuild == false || inputs.stableBuild == 'false') }}
uses: flatpak/flatpak-github-actions/flatpak-builder@10a3c29f0162516f0f68006be14c92f34bd4fa6c
uses: flatpak/flatpak-github-actions/flat-manager@10a3c29f0162516f0f68006be14c92f34bd4fa6c
with:
flat-manager-url: https://hub.flathub.org/
repository: beta
@@ -141,7 +141,7 @@ jobs:
- name: Push to Flathub (stable)
if: ${{ inputs.publish == true && (inputs.stableBuild == true || inputs.stableBuild == 'true') }}
uses: flatpak/flatpak-github-actions/flatpak-builder@10a3c29f0162516f0f68006be14c92f34bd4fa6c
uses: flatpak/flatpak-github-actions/flat-manager@10a3c29f0162516f0f68006be14c92f34bd4fa6c
with:
flat-manager-url: https://hub.flathub.org/
repository: stable

View File

@@ -19,7 +19,7 @@ jobs:
pr-message: |-
## Thank you for submitting a contribution to PCSX2
As this is your first pull request, [please be aware of the contributing guidelines](https://github.com/PCSX2/pcsx2/blob/master/.github/CONTRIBUTING.md).
As this is your first pull request, [please be aware of the contributing guidelines](https://pcsx2.net/docs/contributing/).
Additionally, as per recent changes in GitHub Actions, your pull request will need to be approved by a maintainer before GitHub Actions can run against it. [You can find more information about this change here.](https://github.blog/2021-04-22-github-actions-update-helping-maintainers-combat-bad-actors/)

View File

@@ -3874,6 +3874,8 @@ SCED-52841:
speedHacks:
mtvu: 0 # Fixes SPS when entering Spain in Jackie's and Jade's character models.
instantVU1: 0 # Fixes SPS when entering Spain in Jackie's and Jade's character models.
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
SCED-52846:
name: "Killzone [Demo]"
region: "PAL-E"
@@ -5645,6 +5647,8 @@ SCES-52412:
speedHacks:
mtvu: 0 # Fixes SPS when entering Spain in Jackie's and Jade's character models.
instantVU1: 0 # Fixes SPS when entering Spain in Jackie's and Jade's character models.
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
SCES-52423:
name: "Smash Court Tennis - Pro Tournament 2"
region: "PAL-M5"
@@ -15539,6 +15543,7 @@ SLES-50672:
region: "PAL-M5"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
roundSprite: 1 # Fixes lines in menus.
SLES-50677:
@@ -17730,12 +17735,14 @@ SLES-51525:
name: "Fallout - Brotherhood of Steel"
region: "PAL-M3"
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance and reduces hash cache size when moving.
roundSprite: 1 # Fixes HUD garbage.
SLES-51526:
name: "Fallout - Brotherhood of Steel"
region: "PAL-M3"
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance and reduces hash cache size when moving.
roundSprite: 1 # Fixes HUD garbage.
SLES-51547:
@@ -19299,6 +19306,7 @@ SLES-52187:
region: "PAL-M3"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
roundSprite: 1 # Fixes lines in sprites but still some lines left.
estimateTextureRegion: 1 # Improves performance.
SLES-52188:
@@ -19306,6 +19314,7 @@ SLES-52188:
region: "PAL-M3"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
roundSprite: 1 # Fixes lines in sprites but still some lines left.
estimateTextureRegion: 1 # Improves performance.
SLES-52190:
@@ -19625,6 +19634,7 @@ SLES-52325:
gameFixes:
- BlitInternalFPSHack # Fixes internal fps detection in some areas.
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
roundSprite: 1 # Fixes lines in menus HUD and in game.
halfPixelOffset: 2 # Fixes edge garbage.
@@ -19729,6 +19739,7 @@ SLES-52373:
gameFixes:
- BlitInternalFPSHack # Fixes internal fps detection in some areas.
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
roundSprite: 1 # Fixes lines in menus HUD and in game.
halfPixelOffset: 2 # Fixes edge garbage.
@@ -21184,6 +21195,8 @@ SLES-52853:
name: "Miami Vice"
region: "PAL-M6"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
SLES-52854:
name: "Capcom Fighting Jam"
region: "PAL-E"
@@ -21284,6 +21297,7 @@ SLES-52894:
name-sort: "Bard's Tale, The"
region: "PAL-E"
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
SLES-52895:
name: "Nickelodeon The SpongeBob SquarePants Movie"
@@ -21854,6 +21868,7 @@ SLES-53039:
region: "PAL-M4"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
roundSprite: 1 # Fixes lines in menus HUD and in game.
halfPixelOffset: 2 # Fixes erroneous line in menus.
@@ -22176,6 +22191,8 @@ SLES-53149:
SLES-53150:
name: "10 Pin - Champions Alley"
region: "PAL-M6"
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
SLES-53151:
name: "Juiced"
region: "PAL-I"
@@ -22196,6 +22213,7 @@ SLES-53154:
name-sort: "Bard's Tale, The"
region: "PAL-M8"
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
SLES-53155:
name: "Star Wars - Episode III - Revenge of the Sith"
@@ -22863,6 +22881,8 @@ SLES-53433:
SLES-53434:
name: "Red Baron"
region: "PAL-M3"
gsHWFixes:
textureInsideRT: 1 # Fixes trees.
SLES-53435:
name: "SAS Anti-Terror Force"
region: "PAL-M3"
@@ -26080,6 +26100,7 @@ SLES-54423:
name: "Justice League Heroes"
region: "PAL-M5"
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
clampModes:
vuClampMode: 2 # Fixes ingame SPS for the capes.
@@ -31422,6 +31443,7 @@ SLKA-25246:
name-sort: "Bard's Tale, The"
region: "NTSC-K"
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
SLKA-25247:
name: "Prince of Persia - Warrior Within"
@@ -44705,6 +44727,7 @@ SLPM-65845:
region: "NTSC-J"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
roundSprite: 1 # Fixes lines in sprites but still some lines left.
estimateTextureRegion: 1 # Improves performance.
SLPM-65846:
@@ -45101,6 +45124,7 @@ SLPM-65915:
name-en: "Fallout - Brotherhood of Steel"
region: "NTSC-J"
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance and reduces hash cache size when moving.
roundSprite: 1 # Fixes HUD garbage.
SLPM-65916:
@@ -49579,6 +49603,8 @@ SLPM-66628:
autoFlush: 2 # Reduces post-processing misalignment.
halfPixelOffset: 2 # Fixes bloom misalignment still a bit misaligned.
roundSprite: 1 # Fixes bloom misalignment still a bit misaligned + font artifacts.
memcardFilters:
- "SLPM-66643"
SLPM-66629:
name: "ダージュ・オブ・ケルベロス -ファイナルファンタジーⅫ - インターナショナル [Ultimate Hits]"
name-sort: "だーじゅ・おぶ・けるべろす ふぁいなるふぁんたじー7 いんたーなしょなる [Ultimate Hits]"
@@ -52274,6 +52300,14 @@ SLPM-68520:
halfPixelOffset: 2 # Corrects shadow alignment and reduces blurriness.
recommendedBlendingLevel: 3 # Fixes level and map menu brightness.
preloadFrameData: 1 # Fixes glowing emblems.
memcardFilters:
- "SLPS-25338"
- "SLPS-25339"
- "SLPS-73202"
- "SLPS-73203"
- "SLPS-25408"
- "SLPS-25462"
- "SLPS-73247"
SLPM-68521:
name: ".hack//frägment [先行リリース版]"
name-sort: "どっとはっく fragment [せんこうりりーすばん]"
@@ -56472,6 +56506,7 @@ SLPS-25139:
region: "NTSC-J"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
roundSprite: 1 # Fixes lines in menus.
SLPS-25140:
@@ -56480,6 +56515,7 @@ SLPS-25140:
name-en: "Baldur's Gate - Dark Alliance [Standard Edition]"
region: "NTSC-J"
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
roundSprite: 1 # Fixes lines in menus.
SLPS-25141:
@@ -57336,6 +57372,7 @@ SLPS-25291:
region: "NTSC-J"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
texturePreloading: 1 # Performs much better with partial preload.
estimateTextureRegion: 1 # Improves performance.
SLPS-25292:
@@ -60608,6 +60645,9 @@ SLPS-25829:
region: "NTSC-J"
gsHWFixes:
nativeScaling: 1 # Fixes post processing.
memcardFilters:
- "SLPS-25394"
- "SLPS-25623"
SLPS-25830:
name: "ゼロの使い魔 夢魔が紡ぐ夜風の幻想曲 [限定版]"
name-sort: "ぜろのつかいま むまがつむぐよかぜのげんそうきょく [げんていばん]"
@@ -62653,6 +62693,7 @@ SLUS-20035:
gameFixes:
- SoftwareRendererFMVHack # Fixes FMVs.
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
roundSprite: 1 # Fixes lines in menus.
SLUS-20037:
@@ -65013,6 +65054,7 @@ SLUS-20539:
region: "NTSC-U"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance and reduces hash cache size when moving.
roundSprite: 1 # Fixes HUD garbage.
SLUS-20540:
@@ -65167,6 +65209,7 @@ SLUS-20565:
gameFixes:
- BlitInternalFPSHack # Fixes internal fps detection in some areas.
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
SLUS-20566:
name: "Buffy the Vampire Slayer - Chaos Bleeds"
@@ -65762,6 +65805,7 @@ SLUS-20675:
gameFixes:
- SoftwareRendererFMVHack # Fixes FMVs.
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
roundSprite: 1 # Fixes lines in sprites but still some lines left.
estimateTextureRegion: 1 # Improves performance.
SLUS-20676:
@@ -66459,6 +66503,7 @@ SLUS-20803:
region: "NTSC-U"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance and reduces hash cache size.
SLUS-20804:
name: "Forgotten Realms - Demon Stone"
@@ -67456,6 +67501,7 @@ SLUS-20973:
region: "NTSC-U"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
roundSprite: 1 # Fixes lines in menus HUD and in game.
halfPixelOffset: 2 # Fixes erroneous line in menus.
@@ -69166,6 +69212,8 @@ SLUS-21246:
SLUS-21247:
name: "Jackie Chan Adventures"
region: "NTSC-U"
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
SLUS-21248:
name: "Legend of Kay"
region: "NTSC-U"
@@ -69598,6 +69646,7 @@ SLUS-21304:
region: "NTSC-U"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
clampModes:
vuClampMode: 2 # Ingame capes become SPS mess with lower than extra VU clamp.
@@ -73710,6 +73759,8 @@ SLUS-29084:
SLUS-29085:
name: "Champions of Norrath - Realms of EverQuest"
region: "NTSC-U"
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
SLUS-29086:
name: "FIFA Soccer 2004 [Demo]"
region: "NTSC-U"
@@ -73730,6 +73781,7 @@ SLUS-29088:
gameFixes:
- BlitInternalFPSHack # Fixes internal fps detection in some areas.
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
SLUS-29089:
name: "Resident Evil Outbreak [Public Beta 1.0]"
@@ -73854,6 +73906,7 @@ SLUS-29126:
region: "NTSC-U"
compat: 4
gsHWFixes:
textureInsideRT: 1 # Fixes half right.
estimateTextureRegion: 1 # Improves performance.
roundSprite: 1 # Fixes lines in menus HUD and in game.
halfPixelOffset: 2 # Fixes erroneous line in menus.

View File

@@ -154,6 +154,7 @@
03000000120c0000f10e000000000000,Brook PS2 Adapter,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000120c0000310c000000000000,Brook Super Converter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000d81d00000b00000000000000,Buffalo BSGP1601 Series,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,
030000005a1c00002400000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
030000005b1c00002400000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
030000005b1c00002500000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
030000006d04000042c2000000000000,ChillStream,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
@@ -336,6 +337,7 @@
03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows,
03000000242e00006a48000000000000,Hyperkin RetroN Sq,a:b3,b:b7,back:b5,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b0,rightshoulder:b1,start:b4,x:b2,y:b6,platform:Windows,
03000000242f00000a20000000000000,Hyperkin Scout,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
03000000242e00000a20000000000000,Hyperkin Scout Premium SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
03000000242e00006a38000000000000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Windows,
03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows,
03000000d81d00000f00000000000000,iBuffalo BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -418,7 +420,7 @@
03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000242e0000f500000000000000,Mayflash N64 Adapter,a:b2,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows,
03000000242f0000f500000000000000,Mayflash N64 Adapter,a:b2,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows,
03000000242f0000f400000000000000,Mayflash N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows,
03000000790000007918000000000000,Mayflash N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,righttrigger:b7,rightx:a3,righty:a2,start:b8,platform:Windows,
030000008f0e00001030000000000000,Mayflash Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b7,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
@@ -484,7 +486,7 @@
030000008916000000fd000000000000,Onza TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
0300000009120000072f000000000000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:-a2,leftx:a0,lefty:a1,righttrigger:-a5,start:b11,x:b3,y:b4,platform:Windows,
0300000009120000072f000000000000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:-a2,leftx:a0,lefty:a1,righttrigger:-a5,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,
03000000120c0000f60e000000000000,P4 Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -691,6 +693,7 @@
03000000317300000100000000000000,Sony DualShock 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000666600006706000000000000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,
03000000e30500009605000000000000,Sony PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
03000000fe1400002a23000000000000,Sony PlayStation Adapter,a:b0,b:b1,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,x:b2,y:b3,platform:Windows,
030000004c050000da0c000000000000,Sony PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000632500002306000000000000,Sony PlayStation Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
03000000f0250000c183000000000000,Sony PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -1008,6 +1011,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000550900001472000025050000,NVIDIA Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,
030000004b120000014d000000010000,Nyko Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Mac OS X,
0300000009120000072f000000010000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a2,leftx:a0,lefty:a1,righttrigger:a5,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Mac OS X,
030000006f0e00000901000002010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000d620000011a7000000020000,PowerA Core Plus Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,

View File

@@ -440,7 +440,7 @@ bool GameListModel::titlesLessThan(int left_row, int right_row) const
const GameList::Entry* left = GameList::GetEntryByIndex(left_row);
const GameList::Entry* right = GameList::GetEntryByIndex(right_row);
return QtHost::LocaleSensitiveCompare(QString::fromStdString(left->GetTitleSort(m_prefer_english_titles)),
QString::fromStdString(right->GetTitleSort(m_prefer_english_titles))) < 0;
QString::fromStdString(right->GetTitleSort(m_prefer_english_titles))) < 0;
}
bool GameListModel::lessThan(const QModelIndex& left_index, const QModelIndex& right_index, int column) const
@@ -569,7 +569,7 @@ QIcon GameListModel::getIconForType(GameList::EntryType type)
QIcon GameListModel::getIconForRegion(GameList::Region region)
{
return QIcon(
QStringLiteral("%1/icons/flags/%2.svg").arg(QtHost::GetResourcesBasePath()).arg(GameList::RegionToString(region)));
QStringLiteral("%1/icons/flags/%2.svg").arg(QtHost::GetResourcesBasePath()).arg(GameList::RegionToString(region, false)));
}
void GameListModel::loadThemeSpecificImages()

View File

@@ -128,12 +128,16 @@ namespace
const int pix_width = static_cast<int>(pix.width() / pix.devicePixelRatio());
const int pix_height = static_cast<int>(pix.height() / pix.devicePixelRatio());
// Clip the pixmaps so they don't extend outside the column
painter->save();
painter->setClipRect(option.rect);
// Draw the icon, using code derived from QItemDelegate::drawDecoration()
const bool enabled = option.state & QStyle::State_Enabled;
const QPoint p = QPoint((r.width() - pix_width) / 2, (r.height() - pix_height) / 2);
if (option.state & QStyle::State_Selected)
{
// See QItemDelegate::selectedPixmap()
// See QItemDelegate::selectedPixmap()
QString key = QString::fromStdString(fmt::format("{:016X}-{:d}", pix.cacheKey(), enabled));
QPixmap pm;
if (!QPixmapCache::find(key, &pm))
@@ -159,6 +163,9 @@ namespace
{
painter->drawPixmap(r.topLeft() + p, pix);
}
// Restore the old clip path.
painter->restore();
}
};
} // namespace
@@ -181,15 +188,20 @@ void GameListWidget::initialize()
m_sort_model->setSourceModel(m_model);
m_ui.setupUi(this);
for (u32 type = 0; type < static_cast<u32>(GameList::EntryType::Count); type++)
{
m_ui.filterType->addItem(GameListModel::getIconForType(static_cast<GameList::EntryType>(type)),
qApp->translate("GameList", GameList::EntryTypeToDisplayString(static_cast<GameList::EntryType>(type))));
if (type != static_cast<u32>(GameList::EntryType::Invalid))
{
m_ui.filterType->addItem(GameListModel::getIconForType(static_cast<GameList::EntryType>(type)),
GameList::EntryTypeToString(static_cast<GameList::EntryType>(type), true));
}
}
for (u32 region = 0; region < static_cast<u32>(GameList::Region::Count); region++)
{
m_ui.filterRegion->addItem(GameListModel::getIconForRegion(static_cast<GameList::Region>(region)),
qApp->translate("GameList", GameList::RegionToString(static_cast<GameList::Region>(region))));
GameList::RegionToString(static_cast<GameList::Region>(region), true));
}
connect(m_ui.viewGameList, &QPushButton::clicked, this, &GameListWidget::showGameList);

View File

@@ -33,7 +33,7 @@ GameSummaryWidget::GameSummaryWidget(const GameList::Entry* entry, SettingsWindo
for (int i = 0; i < m_ui.region->count(); i++)
{
m_ui.region->setItemIcon(i,
QIcon(QStringLiteral("%1/icons/flags/%2.svg").arg(base_path).arg(GameList::RegionToString(static_cast<GameList::Region>(i)))));
QIcon(QStringLiteral("%1/icons/flags/%2.svg").arg(base_path).arg(GameList::RegionToString(static_cast<GameList::Region>(i), false))));
}
m_entry_path = entry->path;
@@ -73,16 +73,17 @@ void GameSummaryWidget::populateDetails(const GameList::Entry* entry)
m_ui.type->setCurrentIndex(static_cast<int>(entry->type));
m_ui.region->setCurrentIndex(static_cast<int>(entry->region));
//: First arg is a GameList compat; second is a string with space followed by star rating OR empty if Unknown compat
m_ui.compatibility->setText(tr("%0%1")
.arg(GameList::EntryCompatibilityRatingToString(entry->compatibility_rating))
.arg([entry]() {
if (entry->compatibility_rating == GameList::CompatibilityRating::Unknown)
return QStringLiteral("");
m_ui.compatibility->setText(
tr("%0%1")
.arg(GameList::EntryCompatibilityRatingToString(entry->compatibility_rating, true))
.arg([entry]() {
if (entry->compatibility_rating == GameList::CompatibilityRating::Unknown)
return QStringLiteral("");
const qsizetype compatibility_value = static_cast<qsizetype>(entry->compatibility_rating);
//: First arg is filled-in stars for game compatibility; second is empty stars; should be swapped for RTL languages
return tr(" %0%1").arg(QStringLiteral("").repeated(compatibility_value - 1)).arg(QStringLiteral("").repeated(6 - compatibility_value));
}()));
const qsizetype compatibility_value = static_cast<qsizetype>(entry->compatibility_rating);
//: First arg is filled-in stars for game compatibility; second is empty stars; should be swapped for RTL languages
return tr(" %0%1").arg(QStringLiteral("").repeated(compatibility_value - 1)).arg(QStringLiteral("").repeated(6 - compatibility_value));
}()));
int row = 0;
m_ui.detailsFormLayout->getWidgetPosition(m_ui.titleSort, &row, nullptr);
@@ -156,7 +157,7 @@ void GameSummaryWidget::onDiscPathChanged(const QString& value)
// force rescan of elf to update the serial
g_main_window->rescanFile(m_entry_path);
auto lock = GameList::GetLock();
const GameList::Entry* entry = GameList::GetEntryForPath(m_entry_path.c_str());
if (entry)

File diff suppressed because it is too large Load Diff

View File

@@ -249,7 +249,6 @@ void CTC1() {
void CVT_S() {
_FdValf_ = (float)_FsValSl_;
_FdValf_ = fpuDouble( _FdValUl_ );
}
void CVT_W() {

View File

@@ -2507,15 +2507,17 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
{
config.colclip_update_area = config.drawarea;
const GSVector4 dRect = GSVector4((config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly) ? GSVector4i::loadh(rtsize) : config.drawarea);
const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy();
colclip_rt = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::ColorClip);
if (!colclip_rt)
{
Console.Warning("D3D11: Failed to allocate ColorClip render target, aborting draw.");
return;
}
g_gs_device->SetColorClipTexture(colclip_rt);
// Warning: StretchRect must be called before BeginScene otherwise
// vertices will be overwritten. Trust me you don't want to do that.
const GSVector4 dRect = GSVector4((config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly) ? GSVector4i::loadh(rtsize) : config.drawarea);
const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy();
StretchRect(config.rt, sRect, colclip_rt, dRect, ShaderConvert::COLCLIP_INIT, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
}
@@ -2526,7 +2528,10 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
{
primid_tex = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::PrimID, false);
if (!primid_tex)
{
Console.WriteLn("D3D11: Failed to allocate DATE image, aborting draw.");
return;
}
StretchRect(colclip_rt ? colclip_rt : config.rt, GSVector4(config.drawarea) / GSVector4(rtsize).xyxy(),
primid_tex, GSVector4(config.drawarea), m_date.primid_init_ps[static_cast<u8>(config.datm)].get(), nullptr, false);
@@ -2617,6 +2622,9 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
if (config.tex && config.tex == config.rt)
PSSetShaderResource(0, draw_rt_clone);
}
else
Console.Warning("D3D11: Failed to allocate temp texture for RT copy.");
}
GSTexture* draw_ds_clone = nullptr;
@@ -2630,6 +2638,8 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
CopyRect(config.ds, draw_ds_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
PSSetShaderResource(0, draw_ds_clone);
}
else
Console.Warning("D3D11: Failed to allocate temp texture for DS copy.");
}
SetupVS(config.vs, &config.cb_vs);

View File

@@ -3849,7 +3849,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
colclip_rt->TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
draw_rt = static_cast<GSTexture12*>(config.rt);
OMSetRenderTargets(draw_rt, draw_ds, config.scissor);
OMSetRenderTargets(draw_rt, draw_ds, config.colclip_update_area);
// if this target was cleared and never drawn to, perform the clear as part of the resolve here.
BeginRenderPass(GetLoadOpForTexture(draw_rt), D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
@@ -3917,7 +3917,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
{
EndRenderPass();
GL_PUSH("Copy RT to temp texture {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
GL_PUSH("D3D12: Copy RT to temp texture {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
config.drawarea.width(), config.drawarea.height());
draw_rt_clone->SetState(GSTexture::State::Invalidated);
@@ -3927,6 +3927,8 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
if (config.tex && config.tex == config.rt)
PSSetShaderResource(0, draw_rt_clone, true);
}
else
Console.Warning("D3D12: Failed to allocate temp texture for RT copy.");
}
if (config.tex && config.tex == config.ds)
@@ -3937,13 +3939,15 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
{
EndRenderPass();
GL_PUSH("Copy RT to temp texture {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
GL_PUSH("D3D12: Copy DS to temp texture {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
config.drawarea.width(), config.drawarea.height());
draw_ds_clone->SetState(GSTexture::State::Invalidated);
CopyRect(config.ds, draw_ds_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
PSSetShaderResource(0, draw_ds_clone, true);
}
else
Console.Warning("D3D12: Failed to allocate temp texture for DS copy.");
}
// Switch to colclip target for colclip hw rendering
@@ -3958,7 +3962,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
colclip_rt = static_cast<GSTexture12*>(CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::ColorClip, false));
if (!colclip_rt)
{
Console.WriteLn("D3D12: Failed to allocate ColorClip render target, aborting draw.");
Console.Warning("D3D12: Failed to allocate ColorClip render target, aborting draw.");
if (date_image)
Recycle(date_image);
@@ -4038,6 +4042,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
// rt -> colclip hw blit if enabled
if (colclip_rt && (config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly || config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertAndResolve) && config.rt->GetState() == GSTexture::State::Dirty)
{
OMSetRenderTargets(draw_rt, draw_ds, GSVector4i::loadh(rtsize));
SetUtilityTexture(static_cast<GSTexture12*>(config.rt), m_point_sampler_cpu);
SetPipeline(m_colclip_setup_pipelines[pipe.ds].get());
@@ -4047,8 +4052,10 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
GL_POP();
}
// Restore original scissor, not sure if needed since the render pass has already been started. But to be safe.
OMSetRenderTargets(draw_rt, draw_ds, config.scissor);
}
// VB/IB upload, if we did DATE setup and it's not colclip hw this has already been done
SetPrimitiveTopology(s_primitive_topology_mapping[static_cast<u8>(config.topology)]);
if (!date_image || colclip_rt)
@@ -4111,7 +4118,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
colclip_rt->TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
draw_rt = static_cast<GSTexture12*>(config.rt);
OMSetRenderTargets(draw_rt, draw_ds, config.scissor);
OMSetRenderTargets(draw_rt, draw_ds, config.colclip_update_area);
// if this target was cleared and never drawn to, perform the clear as part of the resolve here.
BeginRenderPass(GetLoadOpForTexture(draw_rt), D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,

View File

@@ -3803,6 +3803,9 @@ void GSRendererHW::Draw()
const GSVector4 tmin = m_vt.m_min.t;
const GSVector4 tmax = m_vt.m_max.t;
// Backup original coverage.
const GSVector4i coverage = tmm.coverage;
for (int layer = m_lod.x + 1; layer <= m_lod.y; layer++)
{
const GIFRegTEX0 MIP_TEX0(GetTex0Layer(layer));
@@ -3824,6 +3827,9 @@ void GSRendererHW::Draw()
src->m_texture->ClearMipmapGenerationFlag();
m_vt.m_min.t = tmin;
m_vt.m_max.t = tmax;
// Restore original coverage.
tmm.coverage = coverage;
}
}

View File

@@ -1232,7 +1232,6 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
}
Target* dst = nullptr;
bool half_right = false;
int x_offset = 0;
int y_offset = 0;
@@ -1437,7 +1436,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
const u32 channel_mask = GSUtil::GetChannelMask(psm);
const u32 channels = t->m_dirty.GetDirtyChannels() & channel_mask;
const bool dirty_overlap = !t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size).rintersect(new_rect).rempty();
// If the source is reading the rt, make sure it's big enough.
if (!possible_shuffle && t && GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM)&& real_fmt_match)
{
@@ -1454,7 +1453,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
ResizeTarget(t, resize_rect, bp, psm, bw);
}
// If not all channels are clean/dirty or only part of the rect is dirty, we need to update the target.
if (((channels & channel_mask) != channel_mask || partial))
if (dirty_overlap && ((channels & channel_mask) != channel_mask || partial))
{
t->Update();
rect_clean = true;
@@ -1589,14 +1588,13 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
// DevCon.Warning("Expected %x Got %x shuffle %d draw %d", psm, t_psm, possible_shuffle, GSState::s_n);
if (match)
{
// It is a complex to convert the code in shader. As a reference, let's do it on the CPU, it will be slow but
// 1/ it just works :)
// 2/ even with upscaling
// 3/ for both Direct3D and OpenGL
if (psm == PSMT4 || (GSConfig.UserHacks_CPUFBConversion && psm == PSMT8))
// It is a complex to convert the code in shader. As a reference, let's do it on the CPU,
// it will be slow but can work even with upscaling, also fine tune it so it's not enabled when not needed.
if (psm == PSMT4 || (GSConfig.UserHacks_CPUFBConversion && psm == PSMT8 && (!possible_shuffle || GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp != 32)))
{
// Forces 4-bit and 8-bit frame buffer conversion to be done on the CPU instead of the GPU, but performance will be slower.
// There is no dedicated shader to handle 4-bit conversion (Stuntman has been confirmed to use 4-bit).
// There is no dedicated shader to handle 4-bit conversion (Beyond Good and Evil and Stuntman).
// Note: Stuntman no longer hits the PSMT4 code path.
// Direct3D10/11 and OpenGL support 8-bit fb conversion but don't render some corner cases properly (Harry Potter games).
// The hack can fix glitches in some games.
if (!t->m_drawn_since_read.rempty())
@@ -1639,22 +1637,6 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
}
}
}
else if ((t->m_TEX0.TBW >= 16) && GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0 + t->m_TEX0.TBW * 0x10, t->m_TEX0.PSM))
{
// Detect half of the render target (fix snow engine game)
// Target Page (8KB) have always a width of 64 pixels
// Half of the Target is TBW/2 pages * 8KB / (1 block * 256B) = 0x10
if (!t->HasValidBitsForFormat(psm, req_color, req_alpha, t->m_TEX0.TBW == TEX0.TBW) && !(possible_shuffle && GSLocalMemory::m_psm[psm].bpp == 16 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32))
continue;
half_right = true;
dst = t;
found_t = true;
tex_merge_rt = false;
x_offset = 0;
y_offset = 0;
break;
}
// Make sure the texture actually is INSIDE the RT, it's possibly not valid if it isn't.
// Also check BP >= TBP, create source isn't equpped to expand it backwards and all data comes from the target. (GH3)
else if (GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::InsideTargets &&
@@ -2003,9 +1985,8 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
#ifdef ENABLE_OGL_DEBUG
if (dst)
{
GL_CACHE("TC: dst %s hit (%s, OFF <%d,%d>): (0x%x, %s)",
GL_CACHE("TC: dst %s hit (OFF <%d,%d>): (0x%x, %s)",
to_string(dst->m_type),
half_right ? "half" : "full",
x_offset,
y_offset,
TEX0.TBP0,
@@ -2017,7 +1998,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
}
#endif
src = CreateSource(TEX0, TEXA, dst, half_right, x_offset, y_offset, lod, &r, gpu_clut, region);
src = CreateSource(TEX0, TEXA, dst, x_offset, y_offset, lod, &r, gpu_clut, region);
if (!src) [[unlikely]]
return nullptr;
}
@@ -3938,24 +3919,30 @@ void GSTextureCache::InvalidateContainedTargets(u32 start_bp, u32 end_bp, u32 wr
continue;
}
const u32 offset = (std::abs(static_cast<int>(start_bp - t->m_TEX0.TBP0)) >> 5) % std::max(1U, t->m_TEX0.TBW);
// If not fully contained but they are aligned and or clean, just dirty the area.
if (type != DepthStencil && start_bp != t->m_TEX0.TBP0 && (t->m_TEX0.TBP0 < start_bp || t->UnwrappedEndBlock() > end_bp) && (offset == 0 || t->m_dirty.size() == 0))
if (type != DepthStencil && start_bp != t->m_TEX0.TBP0 && (t->m_TEX0.TBP0 < start_bp || t->UnwrappedEndBlock() > end_bp))
{
if (write_bw == t->m_TEX0.TBW && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == GSLocalMemory::m_psm[write_psm].bpp)
{
const u32 page_offset = ((end_bp - start_bp) >> 5);
const u32 end_width = write_bw * 64;
const u32 end_height = ((page_offset / std::max(write_bw, 1U)) * GSLocalMemory::m_psm[write_psm].pgs.y) + GSLocalMemory::m_psm[write_psm].pgs.y;
const GSVector4i r = GSVector4i(0, 0, end_width, end_height);
const GSVector4i invalidate_r = TranslateAlignedRectByPage(t, start_bp, write_psm, write_bw, r, false).rintersect(t->m_valid); // it is invalidation but we need a real rect.
RGBAMask mask;
mask._u32 = GSUtil::GetChannelMask(write_psm);
AddDirtyRectTarget(t, invalidate_r, t->m_TEX0.PSM, t->m_TEX0.TBW, mask, false);
}
const u32 offset = (std::abs(static_cast<int>(start_bp - t->m_TEX0.TBP0)) >> 5) % std::max(1U, t->m_TEX0.TBW);
const GSVector4i dirty_rect = t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size).rintersect(t->m_valid);
const u32 end_page_offset = ((end_bp - start_bp) >> 5);
const u32 end_width = write_bw * 64;
const u32 end_height = ((end_page_offset / std::max(write_bw, 1U)) * GSLocalMemory::m_psm[write_psm].pgs.y) + GSLocalMemory::m_psm[write_psm].pgs.y;
const GSVector4i r = GSVector4i(0, 0, end_width, end_height);
const GSVector4i invalidate_r = TranslateAlignedRectByPage(t, start_bp, write_psm, write_bw, r, false).rintersect(t->m_valid); // it is invalidation but we need a real rect.
++i;
continue;
if (offset == 0 || dirty_rect.rempty() || !dirty_rect.rintersect(invalidate_r).rempty())
{
if (write_bw == t->m_TEX0.TBW && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == GSLocalMemory::m_psm[write_psm].bpp)
{
RGBAMask mask;
mask._u32 = GSUtil::GetChannelMask(write_psm);
AddDirtyRectTarget(t, invalidate_r, t->m_TEX0.PSM, t->m_TEX0.TBW, mask, false);
}
++i;
continue;
}
}
InvalidateSourcesFromTarget(t);
@@ -5360,7 +5347,7 @@ void GSTextureCache::IncAge()
}
//Fixme: Several issues in here. Not handling depth stencil, pitch conversion doesnt work.
GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst, bool half_right, int x_offset, int y_offset, const GSVector2i* lod, const GSVector4i* src_range, GSTexture* gpu_clut, SourceRegion region)
GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst, int x_offset, int y_offset, const GSVector2i* lod, const GSVector4i* src_range, GSTexture* gpu_clut, SourceRegion region)
{
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
Source* src = new Source(TEX0, TEXA);
@@ -5398,7 +5385,10 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
const int w = static_cast<int>(std::ceil(scale * tw));
const int h = static_cast<int>(std::ceil(scale * th));
dst->Update();
const GSVector4i read_rect = GSVector4i(x_offset, y_offset, x_offset + tw, y_offset + th);
// Do this first as we could be adding in alpha from an upgraded 24bit target. if the rect intersects a dirty area.
if (!dst->m_dirty.empty() && !read_rect.rintersect(dst->m_dirty.GetTotalRect(dst->m_TEX0, dst->m_unscaled_size)).rempty())
dst->Update();
// If we have a source larger than the target (from tex-in-rt), texelFetch() for target region will return black.
if constexpr (force_target_copy)
@@ -5677,34 +5667,11 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
const bool use_texture = (shader == ShaderConvert::COPY && !source_rect_empty);
GSVector4i region_rect = GSVector4i(0, 0, tw, th);
if (half_right)
{
// You typically hit this code in snow engine game. Dstsize is the size of of Dx/GL RT
// which is set to some arbitrary number. h/w are based on the input texture
// so the only reliable way to find the real size of the target is to use the TBW value.
const int half_width = static_cast<int>(dst->m_TEX0.TBW * (64 / 2));
if (half_width < dst->m_unscaled_size.x)
{
const int copy_width = std::min(half_width, dst->m_unscaled_size.x - half_width);
region_rect = GSVector4i(half_width, 0, half_width + copy_width, th);
GL_CACHE("TC: Half right fix: %d,%d => %d,%d", region_rect.x, region_rect.y, region_rect.z, region_rect.w);
sRect = sRect.blend32<5>(GSVector4i(GSVector4(region_rect.rintersect(dst->GetUnscaledRect())) * GSVector4(dst->m_scale)));
new_size.x = sRect.width();
src->m_unscaled_size.x = copy_width;
}
else
{
DevCon.Error("TC: Invalid half-right copy with width %d from %dx%d texture", half_width * 2, dst->m_unscaled_size.x, dst->m_unscaled_size.y);
}
}
// Assuming everything matches up, instead of copying the target, we can just sample it directly.
// It's the same as doing the copy first, except we save GPU time.
// TODO: We still need to copy if the TBW is mismatched. Except when TBW <= 1 (Jak 2).
const GSVector2i dst_texture_size = dst->m_texture->GetSize();
if ((!half_right || region_rect.z >= dst->m_unscaled_size.x) && // not a smaller subsample
use_texture && // not reinterpreting the RT
if (use_texture && // not reinterpreting the RT
!force_target_copy)
{
// sample the target directly

View File

@@ -441,7 +441,7 @@ protected:
std::unique_ptr<GSDownloadTexture> m_uint16_download_texture;
std::unique_ptr<GSDownloadTexture> m_uint32_download_texture;
Source* CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* t, bool half_right, int x_offset, int y_offset, const GSVector2i* lod, const GSVector4i* src_range, GSTexture* gpu_clut, SourceRegion region);
Source* CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* t, int x_offset, int y_offset, const GSVector2i* lod, const GSVector4i* src_range, GSTexture* gpu_clut, SourceRegion region);
bool PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, const GSVector2i& valid_size, bool is_frame,
bool preload, bool preserve_target, const GSVector4i draw_rect, Target* dst, GSTextureCache::Source* src = nullptr);

View File

@@ -2424,7 +2424,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
const GSVector4 dRect(config.colclip_update_area);
const GSVector4 sRect = dRect / GSVector4(size.x, size.y).xyxy();
StretchRect(colclip_rt, sRect, config.rt, dRect, ShaderConvert::COLCLIP_RESOLVE, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
Recycle(colclip_rt);
g_gs_device->SetColorClipTexture(nullptr);
@@ -2444,6 +2444,14 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
config.colclip_update_area = config.drawarea;
colclip_rt = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::ColorClip, false);
if (!colclip_rt)
{
Console.Warning("GL: Failed to allocate ColorClip render target, aborting draw.");
return;
}
OMSetRenderTargets(colclip_rt, config.ds, nullptr);
g_gs_device->SetColorClipTexture(colclip_rt);
@@ -2451,6 +2459,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
const GSVector4 dRect = GSVector4((config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly) ? GSVector4i::loadh(rtsize) : config.drawarea);
const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy();
StretchRect(config.rt, sRect, colclip_rt, dRect, ShaderConvert::COLCLIP_INIT, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
}
}
@@ -2462,6 +2471,11 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
break; // No setup
case GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking:
primid_texture = InitPrimDateTexture(colclip_rt ? colclip_rt : config.rt, config.drawarea, config.datm);
if (!primid_texture)
{
Console.WriteLn("GL: Failed to allocate DATE image, aborting draw.");
return;
}
break;
case GSHWDrawConfig::DestinationAlphaMode::StencilOne:
if (m_features.texture_barrier)
@@ -2498,6 +2512,8 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
config.drawarea.width(), config.drawarea.height());
CopyRect(colclip_rt ? colclip_rt : config.rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
}
else
Console.Warning("GL: Failed to allocate temp texture for RT copy.");
}
IASetVertexBuffer(config.verts, config.nverts);
@@ -2713,7 +2729,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
const GSVector4 dRect(config.colclip_update_area);
const GSVector4 sRect = dRect / GSVector4(size.x, size.y).xyxy();
StretchRect(colclip_rt, sRect, config.rt, dRect, ShaderConvert::COLCLIP_RESOLVE, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
Recycle(colclip_rt);
g_gs_device->SetColorClipTexture(nullptr);

View File

@@ -5625,7 +5625,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
date_image = SetupPrimitiveTrackingDATE(config);
if (!date_image)
{
Console.WriteLn("Failed to allocate DATE image, aborting draw.");
Console.WriteLn("VK: Failed to allocate DATE image, aborting draw.");
return;
}
@@ -5726,12 +5726,14 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
{
EndRenderPass();
GL_PUSH("Copy RT to temp texture for fbmask {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
GL_PUSH("VK: Copy RT to temp texture for fbmask {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
config.drawarea.width(), config.drawarea.height());
CopyRect(draw_rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
PSSetShaderResource(2, draw_rt_clone, true);
}
else
Console.Warning("VK: Failed to allocate temp texture for RT copy.");
}
// Switch to colclip target for colclip hw rendering
@@ -5744,7 +5746,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
colclip_rt = static_cast<GSTextureVK*>(CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::ColorClip, false));
if (!colclip_rt)
{
Console.WriteLn("Failed to allocate ColorClip render target, aborting draw.");
Console.Warning("VK: Failed to allocate ColorClip render target, aborting draw.");
if (date_image)
Recycle(date_image);

View File

@@ -379,8 +379,8 @@ void GSDumpReplayer::RenderUI()
do \
{ \
text_size = font->CalcTextSizeA(font->FontSize, std::numeric_limits<float>::max(), -1.0f, (text), nullptr, nullptr); \
dl->AddText(font, font->FontSize, ImVec2(margin + shadow_offset, position_y + shadow_offset), IM_COL32(0, 0, 0, 100), (text)); \
dl->AddText(font, font->FontSize, ImVec2(margin, position_y), color, (text)); \
dl->AddText(font, font->FontSize, ImVec2(GSConfig.OsdPerformancePos == OsdOverlayPos::TopLeft ? ImGuiManager::GetWindowWidth() - margin - text_size.x + shadow_offset : margin + shadow_offset, position_y + shadow_offset), IM_COL32(0, 0, 0, 100), (text)); \
dl->AddText(font, font->FontSize, ImVec2(GSConfig.OsdPerformancePos == OsdOverlayPos::TopLeft ? ImGuiManager::GetWindowWidth() - margin - text_size.x : margin, position_y), color, (text)); \
position_y += text_size.y + spacing; \
} while (0)

View File

@@ -91,42 +91,98 @@ static std::recursive_mutex s_mutex;
static GameList::CacheMap s_cache_map;
static std::FILE* s_cache_write_stream = nullptr;
const char* GameList::EntryTypeToString(EntryType type)
const char* GameList::EntryTypeToString(EntryType type, bool translate)
{
static std::array<const char*, static_cast<int>(EntryType::Count)> names = {{"PS2Disc", "PS1Disc", "ELF"}};
return names[static_cast<int>(type)];
static constexpr std::array<const char*, static_cast<int>(EntryType::Count)> names = {
TRANSLATE_NOOP("GameList", "PS2 Disc"),
TRANSLATE_NOOP("GameList", "PS1 Disc"),
TRANSLATE_NOOP("GameList", "ELF"),
TRANSLATE_NOOP("GameList", "Invalid"),
};
const char* name = names.at(static_cast<int>(type));
if (translate)
name = TRANSLATE("GameList", name);
return name;
}
const char* GameList::EntryTypeToDisplayString(EntryType type)
const char* GameList::RegionToString(Region region, bool translate)
{
static std::array<const char*, static_cast<int>(EntryType::Count)> names = {{TRANSLATE("GameList", "PS2 Disc"), TRANSLATE("GameList", "PS1 Disc"), TRANSLATE("GameList", "ELF")}};
return names[static_cast<int>(type)];
static constexpr std::array<const char*, static_cast<int>(Region::Count)> names = {
TRANSLATE_NOOP("GameList", "NTSC-B"),
TRANSLATE_NOOP("GameList", "NTSC-C"),
TRANSLATE_NOOP("GameList", "NTSC-HK"),
TRANSLATE_NOOP("GameList", "NTSC-J"),
TRANSLATE_NOOP("GameList", "NTSC-K"),
TRANSLATE_NOOP("GameList", "NTSC-T"),
TRANSLATE_NOOP("GameList", "NTSC-U"),
TRANSLATE_NOOP("GameList", "Other"),
TRANSLATE_NOOP("GameList", "PAL-A"),
TRANSLATE_NOOP("GameList", "PAL-AF"),
TRANSLATE_NOOP("GameList", "PAL-AU"),
TRANSLATE_NOOP("GameList", "PAL-BE"),
TRANSLATE_NOOP("GameList", "PAL-E"),
TRANSLATE_NOOP("GameList", "PAL-F"),
TRANSLATE_NOOP("GameList", "PAL-FI"),
TRANSLATE_NOOP("GameList", "PAL-G"),
TRANSLATE_NOOP("GameList", "PAL-GR"),
TRANSLATE_NOOP("GameList", "PAL-I"),
TRANSLATE_NOOP("GameList", "PAL-IN"),
TRANSLATE_NOOP("GameList", "PAL-M"),
TRANSLATE_NOOP("GameList", "PAL-NL"),
TRANSLATE_NOOP("GameList", "PAL-NO"),
TRANSLATE_NOOP("GameList", "PAL-P"),
TRANSLATE_NOOP("GameList", "PAL-PL"),
TRANSLATE_NOOP("GameList", "PAL-R"),
TRANSLATE_NOOP("GameList", "PAL-S"),
TRANSLATE_NOOP("GameList", "PAL-SC"),
TRANSLATE_NOOP("GameList", "PAL-SW"),
TRANSLATE_NOOP("GameList", "PAL-SWI"),
TRANSLATE_NOOP("GameList", "PAL-UK"),
};
const char* name = names.at(static_cast<int>(region));
if (translate)
name = TRANSLATE("GameList", name);
return name;
}
const char* GameList::RegionToString(Region region)
const char* GameList::EntryCompatibilityRatingToString(CompatibilityRating rating, bool translate)
{
static std::array<const char*, static_cast<int>(Region::Count)> names = {{"NTSC-B", "NTSC-C", "NTSC-HK", "NTSC-J", "NTSC-K", "NTSC-T",
"NTSC-U", TRANSLATE("GameList", "Other"), "PAL-A", "PAL-AF", "PAL-AU", "PAL-BE", "PAL-E", "PAL-F", "PAL-FI", "PAL-G", "PAL-GR", "PAL-I", "PAL-IN", "PAL-M",
"PAL-NL", "PAL-NO", "PAL-P", "PAL-PL", "PAL-R", "PAL-S", "PAL-SC", "PAL-SW", "PAL-SWI", "PAL-UK"}};
return names[static_cast<int>(region)];
}
const char* GameList::EntryCompatibilityRatingToString(CompatibilityRating rating)
{
// clang-format off
const char* name = "";
switch (rating)
{
case CompatibilityRating::Unknown: return TRANSLATE("GameList", "Unknown");
case CompatibilityRating::Nothing: return TRANSLATE("GameList", "Nothing");
case CompatibilityRating::Intro: return TRANSLATE("GameList", "Intro");
case CompatibilityRating::Menu: return TRANSLATE("GameList", "Menu");
case CompatibilityRating::InGame: return TRANSLATE("GameList", "In-Game");
case CompatibilityRating::Playable: return TRANSLATE("GameList", "Playable");
case CompatibilityRating::Perfect: return TRANSLATE("GameList", "Perfect");
default: return "";
case CompatibilityRating::Unknown:
name = TRANSLATE_NOOP("GameList", "Unknown");
break;
case CompatibilityRating::Nothing:
name = TRANSLATE_NOOP("GameList", "Nothing");
break;
case CompatibilityRating::Intro:
name = TRANSLATE_NOOP("GameList", "Intro");
break;
case CompatibilityRating::Menu:
name = TRANSLATE_NOOP("GameList", "Menu");
break;
case CompatibilityRating::InGame:
name = TRANSLATE_NOOP("GameList", "In-Game");
break;
case CompatibilityRating::Playable:
name = TRANSLATE_NOOP("GameList", "Playable");
break;
case CompatibilityRating::Perfect:
name = TRANSLATE_NOOP("GameList", "Perfect");
break;
default:
return "";
}
// clang-format on
if (translate)
name = TRANSLATE("GameList", name);
return name;
}
bool GameList::IsScannableFilename(const std::string_view path)
@@ -591,15 +647,18 @@ void GameList::ScanDirectory(const char* path, bool recursive, bool only_cache,
Console.WriteLn("Scanning %s%s", path, recursive ? " (recursively)" : "");
progress->PushState();
progress->SetStatusText(fmt::format(
recursive ? TRANSLATE_FS("GameList", "Scanning directory {} (recursively)...") :
TRANSLATE_FS("GameList", "Scanning directory {}..."),
path).c_str());
if (recursive)
progress->SetStatusText(
fmt::format(TRANSLATE_FS("GameList", "Scanning directory {} (recursively)..."), path).c_str());
else
progress->SetStatusText(
fmt::format(TRANSLATE_FS("GameList", "Scanning directory {}..."), path).c_str());
FileSystem::FindResultsArray files;
FileSystem::FindFiles(path, "*",
recursive ? (FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RECURSIVE) :
(FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES),
(FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES),
&files, progress);
u32 files_scanned = 0;
@@ -622,7 +681,7 @@ void GameList::ScanDirectory(const char* path, bool recursive, bool only_cache,
}
const std::string_view filename = Path::GetFileName(ffd.FileName);
progress->SetStatusText(fmt::format(TRANSLATE_FS("GameList","Scanning {}..."), filename.data()).c_str());
progress->SetStatusText(fmt::format(TRANSLATE_FS("GameList", "Scanning {}..."), filename.data()).c_str());
ScanFile(std::move(ffd.FileName), ffd.ModificationTime, lock, played_time_map, custom_attributes_ini);
progress->SetProgressValue(files_scanned);
}
@@ -1300,7 +1359,7 @@ bool GameList::DownloadCovers(const std::vector<std::string>& url_templates, boo
continue;
}
progress->SetStatusText(fmt::format(TRANSLATE_FS("GameList","Downloading cover for {0} [{1}]..."), entry->title, entry->serial).c_str());
progress->SetStatusText(fmt::format(TRANSLATE_FS("GameList", "Downloading cover for {0} [{1}]..."), entry->title, entry->serial).c_str());
}
// we could actually do a few in parallel here...

View File

@@ -104,10 +104,9 @@ namespace GameList
__fi bool IsDisc() const { return (type == EntryType::PS1Disc || type == EntryType::PS2Disc); }
};
const char* EntryTypeToString(EntryType type);
const char* EntryTypeToDisplayString(EntryType type);
const char* RegionToString(Region region);
const char* EntryCompatibilityRatingToString(CompatibilityRating rating);
const char* EntryTypeToString(EntryType type, bool translate);
const char* RegionToString(Region region, bool translate);
const char* EntryCompatibilityRatingToString(CompatibilityRating rating, bool translate);
/// Fills in boot parameters (iso or elf) based on the game list entry.
void FillBootParametersForEntry(VMBootParameters* params, const Entry* entry);

View File

@@ -3316,15 +3316,15 @@ void FullscreenUI::DrawSummarySettingsPage()
CopyTextToClipboard(FSUI_STR("Game serial copied to clipboard."), s_game_settings_entry->serial);
if (MenuButton(FSUI_ICONSTR(ICON_FA_CODE, "CRC"), fmt::format("{:08X}", s_game_settings_entry->crc).c_str(), true))
CopyTextToClipboard(FSUI_STR("Game CRC copied to clipboard."), fmt::format("{:08X}", s_game_settings_entry->crc));
if (MenuButton(FSUI_ICONSTR(ICON_FA_BOX, "Type"), GameList::EntryTypeToDisplayString(s_game_settings_entry->type), true))
CopyTextToClipboard(FSUI_STR("Game type copied to clipboard."), GameList::EntryTypeToDisplayString(s_game_settings_entry->type));
if (MenuButton(FSUI_ICONSTR(ICON_FA_GLOBE, "Region"), GameList::RegionToString(s_game_settings_entry->region), true))
CopyTextToClipboard(FSUI_STR("Game region copied to clipboard."), GameList::RegionToString(s_game_settings_entry->region));
if (MenuButton(FSUI_ICONSTR(ICON_FA_BOX, "Type"), GameList::EntryTypeToString(s_game_settings_entry->type, true), true))
CopyTextToClipboard(FSUI_STR("Game type copied to clipboard."), GameList::EntryTypeToString(s_game_settings_entry->type, true));
if (MenuButton(FSUI_ICONSTR(ICON_FA_GLOBE, "Region"), GameList::RegionToString(s_game_settings_entry->region, true), true))
CopyTextToClipboard(FSUI_STR("Game region copied to clipboard."), GameList::RegionToString(s_game_settings_entry->region, true));
if (MenuButton(FSUI_ICONSTR(ICON_FA_STAR, "Compatibility Rating"),
GameList::EntryCompatibilityRatingToString(s_game_settings_entry->compatibility_rating), true))
GameList::EntryCompatibilityRatingToString(s_game_settings_entry->compatibility_rating, true), true))
{
CopyTextToClipboard(FSUI_STR("Game compatibility copied to clipboard."),
GameList::EntryCompatibilityRatingToString(s_game_settings_entry->compatibility_rating));
GameList::EntryCompatibilityRatingToString(s_game_settings_entry->compatibility_rating, true));
}
if (MenuButton(FSUI_ICONSTR(ICON_FA_FOLDER_OPEN, "Path"), s_game_settings_entry->path.c_str(), true))
CopyTextToClipboard(FSUI_STR("Game path copied to clipboard."), s_game_settings_entry->path);
@@ -5738,9 +5738,12 @@ u32 FullscreenUI::PopulateSaveStateListEntries(const std::string& title, const s
if (InitializeSaveStateListEntry(&li, title, serial, crc, i) || !s_save_state_selector_loading)
s_save_state_selector_slots.push_back(std::move(li));
SaveStateListEntry bli;
if (InitializeSaveStateListEntry(&bli, title, serial, crc, i, true) || !s_save_state_selector_loading)
s_save_state_selector_slots.push_back(std::move(bli));
if (s_save_state_selector_loading)
{
SaveStateListEntry bli;
if (InitializeSaveStateListEntry(&bli, title, serial, crc, i, true))
s_save_state_selector_slots.push_back(std::move(bli));
}
}
return static_cast<u32>(s_save_state_selector_slots.size());
@@ -6456,9 +6459,9 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
summary.clear();
if (entry->serial.empty())
fmt::format_to(std::back_inserter(summary), "{} - ", GameList::RegionToString(entry->region));
fmt::format_to(std::back_inserter(summary), "{} - ", GameList::RegionToString(entry->region, true));
else
fmt::format_to(std::back_inserter(summary), "{} - {} - ", entry->serial, GameList::RegionToString(entry->region));
fmt::format_to(std::back_inserter(summary), "{} - {} - ", entry->serial, GameList::RegionToString(entry->region, true));
const std::string_view filename(Path::GetFileName(entry->path));
summary.append(filename);
@@ -6560,12 +6563,12 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
// region
{
std::string flag_texture(fmt::format("icons/flags/{}.svg", GameList::RegionToString(selected_entry->region)));
std::string flag_texture(fmt::format("icons/flags/{}.svg", GameList::RegionToString(selected_entry->region, false)));
ImGui::TextUnformatted(FSUI_CSTR("Region: "));
ImGui::SameLine();
DrawCachedSvgTextureAsync(flag_texture, LayoutScale(23.0f, 16.0f), SvgScaling::Fit);
ImGui::SameLine();
ImGui::Text(" (%s)", GameList::RegionToString(selected_entry->region));
ImGui::Text(" (%s)", GameList::RegionToString(selected_entry->region, true));
}
// compatibility
@@ -6576,7 +6579,7 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
DrawSvgTexture(s_game_compatibility_textures[static_cast<u32>(selected_entry->compatibility_rating) - 1].get(), LayoutScale(64.0f, 16.0f));
ImGui::SameLine();
}
ImGui::Text(" (%s)", GameList::EntryCompatibilityRatingToString(selected_entry->compatibility_rating));
ImGui::Text(" (%s)", GameList::EntryCompatibilityRatingToString(selected_entry->compatibility_rating, true));
// play time
ImGui::TextUnformatted(
@@ -7302,7 +7305,7 @@ void FullscreenUI::DrawAchievementsSettingsPage(std::unique_lock<std::mutex>& se
};
OpenFileSelector(FSUI_ICONSTR(ICON_FA_FOLDER_OPEN, "Select Leaderboard Submit Sound"), false, std::move(callback), GetAudioFileFilters());
}
MenuHeading(FSUI_CSTR("Account"));
if (bsi->ContainsValue("Achievements", "Token"))
{

View File

@@ -887,6 +887,7 @@ std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_card
}
}
std::sort(mcds.begin(), mcds.end(), [](auto& a, auto& b) { return a.name < b.name; });
return mcds;
}

View File

@@ -879,12 +879,10 @@ static __fi u32 floatToInt(u32 uvalue)
float fvalue = std::bit_cast<float>(uvalue);
if (Offset)
fvalue *= std::bit_cast<float>(0x3f800000 + (Offset << 23));
s32 svalue = std::bit_cast<s32>(fvalue);
uvalue = std::bit_cast<u32>(fvalue);
if (svalue >= static_cast<s32>(0x4f000000))
return 0x7fffffff;
else if (svalue <= static_cast<s32>(0xcf000000))
return 0x80000000;
if ((uvalue & 0x7f800000) >= 0x4f000000)
return (uvalue & 0x80000000) ? 0x80000000 : 0x7fffffff;
else
return static_cast<u32>(static_cast<s32>(fvalue));
}

View File

@@ -26,8 +26,6 @@ namespace DOUBLE
void recC_EQ_xmm(int info);
void recC_LE_xmm(int info);
void recC_LT_xmm(int info);
void recCVT_S_xmm(int info);
void recCVT_W();
void recDIV_S_xmm(int info);
void recMADD_S_xmm(int info);
void recMADDA_S_xmm(int info);
@@ -993,15 +991,16 @@ void recCVT_S_xmm(int info)
}
}
FPURECOMPILE_CONSTCODE(CVT_S, XMMINFO_WRITED | XMMINFO_READS);
void recCVT_S()
{
// Float version is fully accurate, no double version
eeFPURecompileCode(recCVT_S_xmm, R5900::Interpreter::OpcodeImpl::COP1::CVT_S, XMMINFO_WRITED | XMMINFO_READS);
}
void recCVT_W()
{
if (CHECK_FPU_FULL)
{
DOUBLE::recCVT_W();
return;
}
// Float version is fully accurate, no double version
// If we have the following EmitOP() on the top then it'll get calculated twice when CHECK_FPU_FULL is true
// as we also have an EmitOP() at recCVT_W() on iFPUd.cpp. hence we have it below the possible return.
EE::Profiler.EmitOp(eeOpcode::CVTW);
@@ -1010,26 +1009,23 @@ void recCVT_W()
if (regs >= 0)
{
if (CHECK_FPU_EXTRA_OVERFLOW)
fpuFloat2(regs);
xCVTTSS2SI(eax, xRegisterSSE(regs));
xMOVMSKPS(edx, xRegisterSSE(regs)); //extract the signs
xAND(edx, 1); // keep only LSB
xMOVD(edx, xRegisterSSE(regs));
}
else
{
xCVTTSS2SI(eax, ptr32[&fpuRegs.fpr[_Fs_]]);
xMOV(edx, ptr[&fpuRegs.fpr[_Fs_]]);
xSHR(edx, 31); // mov sign to lsb
}
//kill register allocation for dst because we write directly to fpuRegs.fpr[_Fd_]
_deleteFPtoXMMreg(_Fd_, DELETE_REG_FREE_NO_WRITEBACK);
xADD(edx, 0x7FFFFFFF); // 0x7FFFFFFF if positive, 0x8000 0000 if negative
xCMP(eax, 0x80000000); // If the result is indefinitive
xCMOVE(eax, edx); // Saturate it
// cvttss2si converts unrepresentable values to 0x80000000, so negative values are already handled.
// So we just need to handle positive values.
xCMP(edx, 0x4f000000); // If the input is greater than INT_MAX
xMOV(edx, 0x7fffffff);
xCMOVGE(eax, edx); // Saturate it
//Write the result
xMOV(ptr[&fpuRegs.fpr[_Fd_]], eax);

View File

@@ -540,57 +540,10 @@ FPURECOMPILE_CONSTCODE(C_LT, XMMINFO_READS | XMMINFO_READT);
//------------------------------------------------------------------
// CVT.x XMM
//------------------------------------------------------------------
void recCVT_S_xmm(int info)
{
EE::Profiler.EmitOp(eeOpcode::CVTS_F);
if (info & PROCESS_EE_D)
{
if (info & PROCESS_EE_S)
xCVTDQ2PS(xRegisterSSE(EEREC_D), xRegisterSSE(EEREC_S));
else
xCVTSI2SS(xRegisterSSE(EEREC_D), ptr32[&fpuRegs.fpr[_Fs_]]);
}
else
{
const int temp = _allocTempXMMreg(XMMT_FPS);
xCVTSI2SS(xRegisterSSE(temp), ptr32[&fpuRegs.fpr[_Fs_]]);
xMOVSS(ptr32[&fpuRegs.fpr[_Fd_]], xRegisterSSE(temp));
_freeXMMreg(temp);
}
}
// CVT.S: Identical to non-double variant, omitted
// CVT.W: Identical to non-double variant, omitted
FPURECOMPILE_CONSTCODE(CVT_S, XMMINFO_WRITED | XMMINFO_READS);
void recCVT_W() //called from iFPU.cpp's recCVT_W
{
EE::Profiler.EmitOp(eeOpcode::CVTW);
int regs = _checkXMMreg(XMMTYPE_FPREG, _Fs_, MODE_READ);
if (regs >= 0)
{
xCVTTSS2SI(eax, xRegisterSSE(regs));
xMOVMSKPS(edx, xRegisterSSE(regs)); // extract the signs
xAND(edx, 1); // keep only LSB
}
else
{
xCVTTSS2SI(eax, ptr32[&fpuRegs.fpr[_Fs_]]);
xMOV(edx, ptr[&fpuRegs.fpr[_Fs_]]);
xSHR(edx, 31); //mov sign to lsb
}
//kill register allocation for dst because we write directly to fpuRegs.fpr[_Fd_]
_deleteFPtoXMMreg(_Fd_, DELETE_REG_FREE_NO_WRITEBACK);
xADD(edx, 0x7FFFFFFF); // 0x7FFFFFFF if positive, 0x8000 0000 if negative
xCMP(eax, 0x80000000); // If the result is indefinitive
xCMOVE(eax, edx); // Saturate it
//Write the result
xMOV(ptr[&fpuRegs.fpr[_Fd_]], eax);
}
//------------------------------------------------------------------

View File

@@ -42,6 +42,7 @@ struct mVU_Globals
u32 E4 [4] = __four(0x3933e553);
u32 E5 [4] = __four(0x36b63510);
u32 E6 [4] = __four(0x353961ac);
u32 I32MAXF [4] = __four(0x4effffff);
float FTOI_4 [4] = __four(16.0);
float FTOI_12 [4] = __four(4096.0);
float FTOI_15 [4] = __four(32768.0);

View File

@@ -484,23 +484,19 @@ static void mVU_FTOIx(mP, const float* addr, microOpcode opEnum)
return;
const xmm& Fs = mVU.regAlloc->allocReg(_Fs_, _Ft_, _X_Y_Z_W, !((_Fs_ == _Ft_) && (_X_Y_Z_W == 0xf)));
const xmm& t1 = mVU.regAlloc->allocReg();
const xmm& t2 = mVU.regAlloc->allocReg();
// Note: For help understanding this algorithm see recVUMI_FTOI_Saturate()
xMOVAPS(t1, Fs);
// cvttps2dq returns 0x8000000 for any unrepresentable values.
// We want it to return 0x8000000 for negative and 0x7fffffff for positive.
// So for unrepresentable positive values, xor with 0xffffffff to turn 0x80000000 into 0x7fffffff.
if (addr)
xMUL.PS(Fs, ptr128[addr]);
xMOVAPS(t1, Fs);
xPCMP.GTD(t1, ptr128[mVUglob.I32MAXF]);
xCVTTPS2DQ(Fs, Fs);
xPXOR(t1, ptr128[mVUglob.signbit]);
xPSRA.D(t1, 31);
xMOVAPS(t2, Fs);
xPCMP.EQD(t2, ptr128[mVUglob.signbit]);
xAND.PS(t1, t2);
xPADD.D(Fs, t1);
xPXOR(Fs, t1);
mVU.regAlloc->clearNeeded(Fs);
mVU.regAlloc->clearNeeded(t1);
mVU.regAlloc->clearNeeded(t2);
mVU.profiler.EmitOp(opEnum);
}
pass3