Compare commits

...
37 Commits
Author SHA1 Message Date
kenshen112andrefractionpcsx2 0284c35f4c GameDB: Add Fatal Frame 1 / Project Zero final boss game bug fix patch 2023-02-18 05:04:20 +00:00
TheTechnician27andGitHub 6ce33de287 UI: Update and Add mouseover dialog (#8119) 2023-02-18 01:58:32 +00:00
refractionpcsx2 6ccfa011d4 Pad/Counters: Rearrange Pad/Core updates on VSync
Apparently this gets around some weird input lag issue.
2023-02-18 01:13:39 +00:00
refractionpcsx2 c9078af45e GS: Bump shader cache version 2023-02-17 19:40:16 +00:00
refractionpcsx2 6745428d0c GS-SW: Fix SW texture dumping 2023-02-17 19:06:35 +00:00
refractionpcsx2 925e874ada GS-HW: Fix real 16bit value shuffles 2023-02-17 19:06:35 +00:00
lightningterror 03f0f2f803 GameDB: Add missing db entry for Silent Scope 3.
Korean version.
2023-02-17 16:35:46 +01:00
lightningterror 857360d6b2 GameDB: Add full mipmap with ps2 trilinear to Matrix, The - Path of Neo.
Improves ground textures to match sw renderer.
2023-02-17 16:35:46 +01:00
Stenzekandrefractionpcsx2 2dd76c3f12 GS/HW: Force region match on fixed TEX0
Fixes lightmapping in Spinter Cell - Double Agent.
2023-02-17 13:20:04 +00:00
Stenzekandrefractionpcsx2 666de3a874 GS/HW: Allow hardware sampling when clamp_max is larger
Fixes some mipmapping issues in GT4.
2023-02-17 13:20:04 +00:00
Stenzekandrefractionpcsx2 e0e9b64db6 GS/HW: Fix region textures being used when redundant 2023-02-17 13:20:04 +00:00
JordanTheToasterandrefractionpcsx2 2f521348c6 GameDB: Add VU Sync hack to Salt Lake 2002
Fixes the awful flickering and missing textures that happens all over the game.
2023-02-17 13:12:33 +00:00
Stenzekandrefractionpcsx2 8ac2949a1f GS/HW: Fix incorrect bitfield width in height cache
This lead to duplication and possibly larger-than-intended heights.
2023-02-16 16:44:40 +00:00
Stenzekandrefractionpcsx2 d0d5d991ce GS/HW: Fix repeat sampler being used for region clamp/repeat
The coordinates are clamped in the shader, but normalized UV of 1 and
bilinear may repeat.
2023-02-16 16:44:40 +00:00
Mrlinkwiiandrefractionpcsx2 1fc2d7de3c GameDB : remove skipdraw from Need for Speed - Undercover 2023-02-16 15:00:27 +00:00
refractionpcsx2 2598e8d9b9 GS-PCRTC: Fix Anti-blur in screen offset.
No this doesn't mean it won't look blurry, that's a downside of screen offsets in some games, but it might look *less* blurry.
2023-02-16 14:47:09 +00:00
refractionpcsx2 01f65e98e6 GS-PCRTC: Fix up some PCRTC anti-blur behaviour + code cleanup 2023-02-16 14:47:09 +00:00
Ganael LaplancheandGitHub c5330cf166 Common: FreeBSD fixes. (#8163)
* Fix SIGSEGV handler on FreeBSD

* Fix config dir location on FreeBSD
2023-02-16 09:30:18 +01:00
JordanTheToasterandrefractionpcsx2 b78796d0c1 GameDB: Add HPO Special to Arthur and the minimoys
Fixes misaligned bloom that looks gross.
2023-02-16 00:32:17 +00:00
RedDevilusandrefractionpcsx2 da1e9db2c0 GameDB: Ruff Trigger
Rename Europe serial and fix offset and blooming.
2023-02-15 19:18:11 +00:00
RedDevilusandrefractionpcsx2 6beb6aa05b GameDB: Bakugan Battle Brawlers
Se Deinterlace to Adaptive TFF. I thought this was fixed but needs to be checked later.
2023-02-15 19:15:49 +00:00
MrlinkwiiandGitHub 6ea7777a3a GS-HW: remove Fighting Beauty Wulong & Spartan Total Warrior CRC (#8158) 2023-02-15 14:56:53 +00:00
Stenzekandrefractionpcsx2 f97191e241 GS/HW: Split up consecutive channel shuffles 2023-02-15 11:04:05 +00:00
Stenzekandrefractionpcsx2 51420dade4 VMManager: Clear host root on booting ISO 2023-02-15 10:04:39 +00:00
Tokman5andrefractionpcsx2 cc55c01197 GameDB: Add EETimingHack to Crazy Taxi 2023-02-15 10:04:04 +00:00
JordanTheToasterandrefractionpcsx2 86ce464ee3 GameDB: Fix V-Rally 3 graphical corruption
Fixes random graphical corruption that can happen by adding EE Timing hack.
2023-02-15 00:04:44 +00:00
refractionpcsx2 0fa52a75ad GS-HW: Optimise readback performance for some cases 2023-02-14 22:27:35 +00:00
Mrlinkwiiandrefractionpcsx2 c91e7dc3b0 GameDB: remove not needed hw fixes for Metal Slug 6 2023-02-14 22:27:17 +00:00
Mrlinkwiiandrefractionpcsx2 88034b176c GS-HW:purge MetalSlug6 CRC 2023-02-14 22:27:17 +00:00
JordanTheToasterandrefractionpcsx2 efeaff488c GameDB: Add HPO Special to 007 EON
Lines bad must fix lines.
2023-02-14 17:49:53 +00:00
BerylskidandGitHub 5df30f5bdd OSD: Change the lower limit of OSD Scale from 100 to 50 (#8135) 2023-02-14 14:03:24 +00:00
C.W. BettsandGitHub cf179c42b8 cmake: Quiet macOS building warning, we can build on macOS just fine. (#8136) 2023-02-14 11:32:39 +01:00
BerylskidandGitHub a615f8bf17 Qt: Change "Save State On Shutdown" to Unchecked (#8147) 2023-02-14 10:30:34 +00:00
refractionpcsx2 b38964e814 GS: Partial revert of #8101 pending investigation.
Sometimes great ideas don't always go smoothly to plan, this is one of those, but it will be back when we work out what's up with Soul Calibur 2 and DBZ BT3 :)
2023-02-14 10:23:09 +00:00
JordanTheToasterandrefractionpcsx2 013c9eec58 GameDB: Various fixes
Some fixes I missed in the last PR because I am a doughnut and can't remember what I needed to do.
2023-02-14 00:20:52 +00:00
refractionpcsx2 ddbd6eddf7 GameDB: Add Autoflush for Astro Boy and CPU Sprite for Alias 2023-02-14 00:18:08 +00:00
refractionpcsx2 982fd42683 GS: Preload whenever it matches an upload. GUI option forces preloads. 2023-02-14 00:18:08 +00:00
42 changed files with 489 additions and 250 deletions
+146 -18
View File
@@ -503,6 +503,8 @@ SCAJ-20008:
gsHWFixes:
preloadFrameData: 1 # Fixes fog and make lights on cars work again.
autoFlush: 1 # Fixes sun luminosity and penetration of objects.
gameFixes:
- EETimingHack # Fixes random graphical corruption.
SCAJ-20009:
name: "Herdy Gerdy"
region: "NTSC-Unk"
@@ -1493,6 +1495,10 @@ SCAJ-25034:
SCAJ-25037:
name: "Astro Boy Atom"
region: "NTSC-Unk"
roundModes:
eeRoundMode: 0 # Fixes character behaviour.
gsHWFixes:
autoFlush: 1 # Fixes flame bloom.
SCAJ-25045:
name: "Sakura Taisen V - Episode 0"
region: "NTSC-Unk"
@@ -8940,6 +8946,10 @@ SLAJ-25035:
SLAJ-25037:
name: "Astro Boy Atom"
region: "NTSC-Unk"
roundModes:
eeRoundMode: 0 # Fixes character behaviour.
gsHWFixes:
autoFlush: 1 # Fixes flame bloom.
SLAJ-25039:
name: "Beni no Umi 2"
region: "NTSC-Unk"
@@ -9042,6 +9052,8 @@ SLAJ-25072:
name: "Matrix, The - Path of Neo"
region: "NTSC-Unk"
gsHWFixes:
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
halfPixelOffset: 2 # Fix effects upscaling.
SLAJ-25073:
name: "Resident Evil 4"
@@ -9266,6 +9278,8 @@ SLED-51901:
SLED-52326:
name: "007 - Everything or Nothing [Demo]"
region: "PAL-E"
gsHWFixes:
halfPixelOffset: 2 # Fixes lines in cutscenes.
SLED-52375:
name: "Fight Night 2004 [Demo]"
region: "PAL-E"
@@ -9298,6 +9312,8 @@ SLED-52485:
region: "PAL-E"
gsHWFixes:
cpuCLUTRender: 1 # Fixes lights penetrating objects.
autoFlush: 1 # Helps with the light penetration problem.
cpuSpriteRenderBW: 1 # Fixes light glows.
SLED-52488:
name: "Suffering, The [Demo]"
region: "PAL-E"
@@ -9411,8 +9427,6 @@ SLED-53732:
region: "PAL"
gameFixes:
- EETimingHack # Fixes garbage textures flashing on the character model.
gsHWFixes:
getSkipCount: "GSC_Spartan"
SLED-53745:
name: "Total Overdose [Demo]"
region: "PAL-M5"
@@ -9425,6 +9439,8 @@ SLED-53845:
name: "Matrix, The - Path of Neo [Demo]"
region: "PAL-E"
gsHWFixes:
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
halfPixelOffset: 2 # Fix effects upscaling.
SLED-53937:
name: "Black [Demo]"
@@ -10003,9 +10019,14 @@ SLES-50215:
name: "Crazy Taxi"
region: "PAL-M4"
compat: 5
gameFixes:
- EETimingHack # Fixes credits screen.
SLES-50217:
name: "Dave Mirra Freestyle BMX 2"
region: "PAL-E-S"
gsHWFixes:
mipmap: 2 # Fixes noisy bumpy textures.
trilinearFiltering: 1 # Smoothes out mipmapping
SLES-50218:
name: "All-Star Baseball 2002"
region: "PAL-E"
@@ -10311,8 +10332,10 @@ SLES-50355:
gsHWFixes:
halfPixelOffset: 3 # Fixes ghosting on Batman
SLES-50356:
name: "ESPN International Winter Sports"
name: "Salt Lake 2002"
region: "PAL-E"
gameFixes:
- VUSyncHack # Fixes flickering and missing textures.
SLES-50358:
name: "Devil May Cry"
region: "PAL-M5"
@@ -10818,8 +10841,10 @@ SLES-50639:
region: "PAL-E"
compat: 5
SLES-50640:
name: "Salt Lake City 2002 Olympic Winter Games"
name: "Salt Lake 2002"
region: "PAL-M4"
gameFixes:
- VUSyncHack # Fixes flickering and missing textures.
SLES-50641:
name: "Dynasty Warriors 3"
region: "PAL-M3"
@@ -10984,6 +11009,8 @@ SLES-50725:
gsHWFixes:
preloadFrameData: 1 # Fixes fog and make lights on cars work again.
autoFlush: 1 # Fixes sun luminosity and penetration of objects.
gameFixes:
- EETimingHack # Fixes random graphical corruption.
SLES-50726:
name: "Myst III - Exile"
region: "PAL-M6"
@@ -11247,6 +11274,13 @@ SLES-50821:
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
disablePartialInvalidation: 1 # Fixes ghost rendering.
patches:
"22E91837":
content: |-
author=WeirdBeardGame, TellowKrinkle, CheeseyBurrito.
// Wraps sceVu0ScaleVector in if statement to prevent bad divide by zero behaviour.
patch=1,EE,0011f3b4,word,46156032
patch=1,EE,0011f3b8,word,45010002
SLES-50822:
name: "Shadow Hearts"
region: "PAL-M3"
@@ -11368,6 +11402,10 @@ SLES-50846:
SLES-50848:
name: "Speed Kings"
region: "PAL-M5"
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned bloom.
speedHacks:
InstantVU1SpeedHack: 0 # Fixes graphical corruption.
patches:
4C133D9D:
content: |-
@@ -13410,11 +13448,15 @@ SLES-51821:
region: "PAL-M5"
gsHWFixes:
cpuCLUTRender: 1 # Fixes lights penetrating objects.
autoFlush: 1 # Helps with the light penetration problem.
cpuSpriteRenderBW: 1 # Fixes light glows.
SLES-51822:
name: "Alias"
region: "PAL-I"
gsHWFixes:
cpuCLUTRender: 1 # Fixes lights penetrating objects.
autoFlush: 1 # Helps with the light penetration problem.
cpuSpriteRenderBW: 1 # Fixes light glows.
SLES-51823:
name: "Hunter - The Reckoning Wayward"
region: "PAL-M3"
@@ -13895,6 +13937,8 @@ SLES-52005:
name: "007 - Everything or Nothing"
region: "PAL-M5"
compat: 5
gsHWFixes:
halfPixelOffset: 2 # Fixes lines in cutscenes.
SLES-52008:
name: "NBA Live 2004"
region: "PAL-M5"
@@ -13987,6 +14031,8 @@ SLES-52046:
name: "007 - Everything or Nothing"
region: "PAL-F-G"
compat: 5
gsHWFixes:
halfPixelOffset: 2 # Fixes lines in cutscenes.
SLES-52047:
name: "Sims, The - Bustin' Out"
region: "PAL-M6"
@@ -14847,6 +14893,8 @@ SLES-52486:
region: "PAL-M5"
roundModes:
eeRoundMode: 0 # Fixes character behaviour.
gsHWFixes:
autoFlush: 1 # Fixes flame bloom.
SLES-52490:
name: "Dance UK - Extra Trax"
region: "PAL-E"
@@ -15912,15 +15960,23 @@ SLES-52908:
SLES-52909:
name: "UEFA Champions League 2004-2005"
region: "PAL-E-G"
gameFixes:
- EETimingHack # Fixes graphical corruption.
SLES-52910:
name: "UEFA Champions League 2005"
region: "PAL-F-G"
gameFixes:
- EETimingHack # Fixes graphical corruption.
SLES-52911:
name: "UEFA Champions League 2005"
region: "PAL-I-S"
gameFixes:
- EETimingHack # Fixes graphical corruption.
SLES-52912:
name: "UEFA Champions League 2005"
region: "PAL-E-DU"
gameFixes:
- EETimingHack # Fixes graphical corruption.
SLES-52913:
name: "Suikoden IV"
region: "PAL-M5"
@@ -17044,15 +17100,11 @@ SLES-53393:
compat: 5
gameFixes:
- EETimingHack # Fixes garbage textures flashing on the character model.
gsHWFixes:
getSkipCount: "GSC_Spartan"
SLES-53396:
name: "Spartan - Total Warrior"
region: "PAL-M3"
gameFixes:
- EETimingHack # Fixes garbage textures flashing on the character model.
gsHWFixes:
getSkipCount: "GSC_Spartan"
SLES-53398:
name: "Zombie Zone"
region: "PAL-E"
@@ -17226,6 +17278,8 @@ SLES-53462:
name: "Matrix, The - Path of Neo"
region: "PAL-M5"
gsHWFixes:
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
halfPixelOffset: 2 # Fix effects upscaling.
SLES-53463:
name: "NHL '06"
@@ -18219,6 +18273,8 @@ SLES-53759:
name: "Matrix, The - Path of Neo"
region: "PAL-M5"
gsHWFixes:
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
halfPixelOffset: 2 # Fix effects upscaling.
SLES-53760:
name: "Rugby Challenge 2006"
@@ -18306,6 +18362,8 @@ SLES-53799:
region: "PAL-M4"
compat: 5
gsHWFixes:
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
halfPixelOffset: 2 # Fix effects upscaling.
SLES-53800:
name: "Rampage - Total Destruction"
@@ -18841,10 +18899,13 @@ SLES-54018:
name: "Jackpot Madness"
region: "PAL-E"
SLES-54021:
name: "Ruff Trigger"
name: "Ruff Trigger - The Vanocore Conspiracy"
region: "PAL-M5"
gameFixes:
- EETimingHack # Fixes game engine errors when going ingame.
gsHWFixes:
cpuCLUTRender: 1 # Bring back blooming scattering like in software mode.
halfPixelOffset: 1 # Fixes misalignment like volcano lighting.
patches:
B02C81E5:
content: |-
@@ -19821,6 +19882,8 @@ SLES-54402:
SLES-54420:
name: "Arthur and the Minimoys"
region: "PAL-M7"
gsHWFixes:
halfPixelOffset: 2 # Fixes misaligned bloom.
SLES-54421:
name: "Happy Feet"
region: "PAL-M5"
@@ -22710,6 +22773,8 @@ SLES-55579:
eeRoundMode: 1 # Fixes black textures in conjunction with VU0 clamping set to none.
clampModes:
vu0ClampMode: 0 # Fixes black textures and SPS.
gsHWFixes:
deinterlace: 8 # Game requires AdaptiveTFF de-interlacing when auto for the (starter) FMVs.
SLES-55581:
name: "FIFA 10"
region: "PAL-M5"
@@ -23731,6 +23796,8 @@ SLKA-25159:
region: "NTSC-K"
roundModes:
eeRoundMode: 0 # Fixes character behaviour.
gsHWFixes:
autoFlush: 1 # Fixes flame bloom.
SLKA-25160:
name: "Shin Megami Tensei III - Nocturne Maniax"
region: "NTSC-K"
@@ -24162,6 +24229,8 @@ SLKA-25303:
name: "Matrix, The - Path of Neo"
region: "NTSC-K"
gsHWFixes:
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
halfPixelOffset: 2 # Fix effects upscaling.
SLKA-25304:
name: "Burnout Revenge"
@@ -25586,6 +25655,8 @@ SLPM-62101:
SLPM-62102:
name: "Crazy Taxi"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes credits screen.
SLPM-62103:
name: "EX Okuman Chouja Game - The Money Battle"
region: "NTSC-J"
@@ -27602,6 +27673,9 @@ SLPM-64544:
SLPM-64549:
name: "Siksin-ui Seong"
region: "NTSC-K"
SLPM-64552:
name: "Silent Scope 3"
region: "NTSC-K"
SLPM-65001:
name: "Kessen"
region: "NTSC-J"
@@ -28216,6 +28290,8 @@ SLPM-65191:
gsHWFixes:
preloadFrameData: 1 # Fixes fog and make lights on cars work again.
autoFlush: 1 # Fixes sun luminosity and penetration of objects.
gameFixes:
- EETimingHack # Fixes random graphical corruption.
SLPM-65192:
name: "NBA Live 2003"
region: "NTSC-J"
@@ -29136,6 +29212,8 @@ SLPM-65445:
SLPM-65446:
name: "007 - Everything or Nothing"
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 2 # Fixes lines in cutscenes.
SLPM-65447:
name: "Kunoichi"
region: "NTSC-J"
@@ -29432,6 +29510,8 @@ SLPM-65539:
gsHWFixes:
preloadFrameData: 1 # Fixes fog and make lights on cars work again.
autoFlush: 1 # Fixes sun luminosity and penetration of objects.
gameFixes:
- EETimingHack # Fixes random graphical corruption.
SLPM-65540:
name: "Galaxy Angel - Moonlit Lovers [First Limited Edition]"
region: "NTSC-J"
@@ -29467,6 +29547,8 @@ SLPM-65551:
region: "NTSC-J"
roundModes:
eeRoundMode: 0 # Fixes character behaviour.
gsHWFixes:
autoFlush: 1 # Fixes flame bloom.
SLPM-65552:
name: "Metal Wolf Rev [Limited Edition]"
region: "NTSC-J"
@@ -30041,6 +30123,8 @@ SLPM-65724:
SLPM-65725:
name: "007 - Everything or Nothing [EA Best Hits]"
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 2 # Fixes lines in cutscenes.
SLPM-65726:
name: "Star Wars - Jango Fett [EA Best Hits]"
region: "NTSC-J"
@@ -31699,6 +31783,8 @@ SLPM-66177:
name: "Matrix, The - Path of Neo"
region: "NTSC-J"
gsHWFixes:
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
halfPixelOffset: 2 # Fix effects upscaling.
SLPM-66178:
name: "pop'n music 7 [Konami The Best]"
@@ -32724,8 +32810,6 @@ SLPM-66444:
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes garbage textures flashing on the character model.
gsHWFixes:
getSkipCount: "GSC_Spartan"
SLPM-66445:
name: "Persona 3"
region: "NTSC-J"
@@ -37045,6 +37129,13 @@ SLPS-25074:
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
disablePartialInvalidation: 1 # Fixes ghost rendering.
patches:
9883194E:
content: |-
author=WeirdBeardGame, TellowKrinkle, CheeseyBurrito.
// Wraps sceVu0ScaleVector in if statement to prevent bad divide by zero behaviour.
patch=1,EE,0011de3c,word,46156032
patch=1,EE,0011de40,word,45010002
SLPS-25075:
name: "Sidewinder F"
region: "NTSC-J"
@@ -37093,6 +37184,11 @@ SLPS-25088:
textureInsideRT: 1 # Fixes wrong visuals for the summon Anima and The (Triple) Magus Sisters.
getSkipCount: "GSC_FFXGames"
beforeDraw: "OI_FFX"
SLPS-25089:
name: "Salt Lake 2002"
region: "NTSC-J"
gameFixes:
- VUSyncHack # Fixes flickering and missing textures.
SLPS-25094:
name: "Reveal Fantasia"
region: "NTSC-J"
@@ -39162,7 +39258,8 @@ SLPS-25657:
region: "NTSC-J"
compat: 5
gsHWFixes:
getSkipCount: "GSC_FightingBeautyWulong"
autoFlush: 1 # Helps ghosting.
halfPixelOffset: 2 # Helps ghosting when upscaling.
SLPS-25658:
name: "Binchou-Tan - Shiwase Goyomi [Shokai Genteiban]"
region: "NTSC-J"
@@ -39220,8 +39317,6 @@ SLPS-25674:
name: "Metal Slug 6"
region: "NTSC-J"
compat: 5
gsHWFixes:
beforeDraw: "OI_MetalSlug6"
SLPS-25675:
name: "Battle Stadium D.O.N"
region: "NTSC-J"
@@ -41364,6 +41459,9 @@ SLUS-20159:
name: "Dave Mirra Freestyle BMX 2"
region: "NTSC-U"
compat: 5
gsHWFixes:
mipmap: 2 # Fixes noisy bumpy textures.
trilinearFiltering: 1 # Smoothes out mipmapping
SLUS-20160:
name: "Winback - Covert Operations"
region: "NTSC-U"
@@ -41511,6 +41609,8 @@ SLUS-20202:
name: "Crazy Taxi"
region: "NTSC-U"
compat: 5
gameFixes:
- EETimingHack # Fixes credits screen.
SLUS-20204:
name: "Smuggler's Run 2 - Hostile Territory"
region: "NTSC-U"
@@ -42308,6 +42408,8 @@ SLUS-20377:
SLUS-20378:
name: "Salt Lake 2002"
region: "NTSC-U"
gameFixes:
- VUSyncHack # Fixes flickering and missing textures.
patches:
466D1C13:
content: |-
@@ -42370,6 +42472,13 @@ SLUS-20388:
gsHWFixes:
halfPixelOffset: 2 # Reduces blurriness.
disablePartialInvalidation: 1 # Fixes ghost rendering.
patches:
339A0B8C:
content: |-
author=WeirdBeardGame, TellowKrinkle, CheeseyBurrito.
// Wraps sceVu0ScaleVector in if statement to prevent bad divide by zero behaviour.
patch=1,EE,0011f0cc,word,46156032
patch=1,EE,0011f0d0,word,45010002
SLUS-20389:
name: "Endgame"
region: "NTSC-U"
@@ -42904,6 +43013,8 @@ SLUS-20496:
gsHWFixes:
preloadFrameData: 1 # Fixes fog and make lights on cars work again.
autoFlush: 1 # Fixes sun luminosity and penetration of objects.
gameFixes:
- EETimingHack # Fixes random graphical corruption.
SLUS-20497:
name: "Burnout 2 - Point of Impact"
region: "NTSC-U"
@@ -43321,6 +43432,10 @@ SLUS-20584:
name: "Speed Kings"
region: "NTSC-U"
compat: 3
gsHWFixes:
halfPixelOffset: 1 # Fixes misaligned bloom.
speedHacks:
InstantVU1SpeedHack: 0 # Fixes graphical corruption.
patches:
C90920FC:
content: |-
@@ -43746,6 +43861,8 @@ SLUS-20673:
compat: 5
gsHWFixes:
cpuCLUTRender: 1 # Fixes lights penetrating objects.
autoFlush: 1 # Helps with the light penetration problem.
cpuSpriteRenderBW: 1 # Fixes light glows.
SLUS-20674:
name: "Cyber Troopers - Virtual-On Marz"
region: "NTSC-U"
@@ -44107,6 +44224,8 @@ SLUS-20751:
name: "007 - Everything or Nothing"
region: "NTSC-U"
compat: 5
gsHWFixes:
halfPixelOffset: 2 # Fixes lines in cutscenes.
SLUS-20752:
name: "Madden NFL 2004"
region: "NTSC-U"
@@ -44659,6 +44778,8 @@ SLUS-20867:
compat: 5
roundModes:
eeRoundMode: 0 # Fixes character behaviour.
gsHWFixes:
autoFlush: 1 # Fixes flame bloom.
SLUS-20868:
name: "MVP Baseball 2004"
region: "NTSC-U"
@@ -46462,8 +46583,6 @@ SLUS-21212:
compat: 5
gameFixes:
- EETimingHack # Fixes garbage textures flashing on the character model.
gsHWFixes:
getSkipCount: "GSC_Spartan"
SLUS-21213:
name: "Madden NFL '06"
region: "NTSC-U"
@@ -46862,6 +46981,8 @@ SLUS-21273:
region: "NTSC-U"
compat: 5
gsHWFixes:
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
halfPixelOffset: 2 # Fix effects upscaling.
SLUS-21274:
name: "OutRun 2006 - Coast 2 Coast"
@@ -47030,6 +47151,8 @@ SLUS-21304:
SLUS-21305:
name: "Arthur and the Invisibles - The Game"
region: "NTSC-U"
gsHWFixes:
halfPixelOffset: 2 # Fixes misaligned bloom.
SLUS-21306:
name: "Ghost Rider"
region: "NTSC-U"
@@ -47080,6 +47203,9 @@ SLUS-21314:
compat: 4
gameFixes:
- EETimingHack # Needed to go ingame.
gsHWFixes:
cpuCLUTRender: 1 # Bring back blooming scattering like in software mode.
halfPixelOffset: 1 # Fixes misalignment like volcano lighting.
patches:
F73488D5:
content: |-
@@ -49505,8 +49631,6 @@ SLUS-21801:
compat: 5
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
skipDrawStart: 1 # Removes even more blurriness and garbage texture like on top left.
skipDrawEnd: 1 # Removes even more blurriness and garbage texture like on top left.
SLUS-21802:
name: "Naked Brothers Band - The Video Game"
region: "NTSC-U"
@@ -49928,6 +50052,8 @@ SLUS-21902:
eeRoundMode: 1 # Fixes black textures in conjunction with VU0 clamping set to none.
clampModes:
vu0ClampMode: 0 # Fixes black textures and SPS.
gsHWFixes:
deinterlace: 8 # Game requires AdaptiveTFF de-interlacing when auto for the (starter) FMVs.
SLUS-21904:
name: "Teenage Mutant Ninja Turtles - Smash-Up"
region: "NTSC-U"
@@ -50611,6 +50737,8 @@ SLUS-29093:
SLUS-29095:
name: "007 - Everything or Nothing [Demo]"
region: "NTSC-U"
gsHWFixes:
halfPixelOffset: 2 # Fixes lines in cutscenes.
SLUS-29096:
name: "Final Night 2004 [Demo]"
region: "NTSC-U"
+25 -13
View File
@@ -38,6 +38,7 @@
#define PS_POINT_SAMPLER 0
#define PS_SHUFFLE 0
#define PS_READ_BA 0
#define PS_READ16_SRC 0
#define PS_DFMT 0
#define PS_DEPTH_FMT 0
#define PS_PAL_FMT 0
@@ -877,26 +878,37 @@ PS_OUTPUT ps_main(PS_INPUT input)
{
uint4 denorm_c = uint4(C);
uint2 denorm_TA = uint2(float2(TA.xy) * 255.0f + 0.5f);
// Mask will take care of the correct destination
if (PS_READ_BA)
C.rb = C.bb;
else
C.rb = C.rr;
if (PS_READ_BA)
if (PS_READ16_SRC)
{
C.rb = (float2)float((denorm_c.r >> 3) | (((denorm_c.g >> 3) & 0x7u) << 5));
if (denorm_c.a & 0x80u)
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.y & 0x80u)));
C.ga = (float2)float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.y & 0x80u));
else
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.x & 0x80u)));
C.ga = (float2)float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.x & 0x80u));
}
else
{
if (denorm_c.g & 0x80u)
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.y & 0x80u)));
// Mask will take care of the correct destination
if (PS_READ_BA)
C.rb = C.bb;
else
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.x & 0x80u)));
C.rb = C.rr;
if (PS_READ_BA)
{
if (denorm_c.a & 0x80u)
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.x & 0x80u)));
}
else
{
if (denorm_c.g & 0x80u)
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.x & 0x80u)));
}
}
}
+10 -3
View File
@@ -871,7 +871,13 @@ void ps_main()
#if PS_SHUFFLE
uvec4 denorm_c = uvec4(C);
uvec2 denorm_TA = uvec2(vec2(TA.xy) * 255.0f + 0.5f);
#if PS_READ16_SRC
C.rb = vec2(float((denorm_c.r >> 3) | (((denorm_c.g >> 3) & 0x7u) << 5)));
if (bool(denorm_c.a & 0x80u))
C.ga = vec2(float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.y & 0x80u)));
else
C.ga = vec2(float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.x & 0x80u)));
#else
// Write RB part. Mask will take care of the correct destination
#if PS_READ_BA
C.rb = C.bb;
@@ -907,9 +913,10 @@ void ps_main()
// float sel = step(128.0f, c.g);
// vec2 c_shuffle = vec2((denorm_c.gg & 0x7Fu) | (denorm_TA & 0x80u));
// c.ga = mix(c_shuffle.xx, c_shuffle.yy, sel);
#endif
#endif // PS_READ_BA
#endif
#endif // READ16_SRC
#endif // PS_SHUFFLE
// Must be done before alpha correction
+23 -15
View File
@@ -328,6 +328,7 @@ void main()
#define PS_POINT_SAMPLER 0
#define PS_SHUFFLE 0
#define PS_READ_BA 0
#define PS_READ16_SRC 0
#define PS_DFMT 0
#define PS_DEPTH_FMT 0
#define PS_PAL_FMT 0
@@ -1175,24 +1176,31 @@ void main()
#if PS_SHUFFLE
uvec4 denorm_c = uvec4(C);
uvec2 denorm_TA = uvec2(vec2(TA.xy) * 255.0f + 0.5f);
// Mask will take care of the correct destination
#if PS_READ_BA
C.rb = C.bb;
#else
C.rb = C.rr;
#endif
#if PS_READ_BA
#if PS_READ16_SRC
C.rb = vec2(float((denorm_c.r >> 3) | (((denorm_c.g >> 3) & 0x7u) << 5)));
if ((denorm_c.a & 0x80u) != 0u)
C.ga = vec2(float((denorm_c.a & 0x7Fu) | (denorm_TA.y & 0x80u)));
C.ga = vec2(float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.y & 0x80u)));
else
C.ga = vec2(float((denorm_c.a & 0x7Fu) | (denorm_TA.x & 0x80u)));
C.ga = vec2(float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.x & 0x80u)));
#else
if ((denorm_c.g & 0x80u) != 0u)
C.ga = vec2(float((denorm_c.g & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = vec2(float((denorm_c.g & 0x7Fu) | (denorm_TA.x & 0x80u)));
// Mask will take care of the correct destination
#if PS_READ_BA
C.rb = C.bb;
#else
C.rb = C.rr;
#endif
#if PS_READ_BA
if ((denorm_c.a & 0x80u) != 0u)
C.ga = vec2(float((denorm_c.a & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = vec2(float((denorm_c.a & 0x7Fu) | (denorm_TA.x & 0x80u)));
#else
if ((denorm_c.g & 0x80u) != 0u)
C.ga = vec2(float((denorm_c.g & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = vec2(float((denorm_c.g & 0x7Fu) | (denorm_TA.x & 0x80u)));
#endif
#endif
#endif
+3 -2
View File
@@ -10,8 +10,9 @@ function(detectOperatingSystem)
if(WIN32)
set(Windows TRUE PARENT_SCOPE)
elseif(UNIX AND APPLE)
# No easy way to filter out iOS.
message(WARNING "OS X/iOS isn't supported, the build will most likely fail")
if(IOS)
message(WARNING "iOS isn't supported, the build will most likely fail")
endif()
set(MacOSX TRUE PARENT_SCOPE)
elseif(UNIX)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
+2
View File
@@ -100,6 +100,8 @@ static void SysPageFaultSignalFilter(int signal, siginfo_t* siginfo, void* ctx)
#if defined(__APPLE__) && defined(__x86_64__)
void* const exception_pc = reinterpret_cast<void*>(static_cast<ucontext_t*>(ctx)->uc_mcontext->__ss.__rip);
#elif defined(__FreeBSD__) && defined(__x86_64__)
void* const exception_pc = reinterpret_cast<void*>(static_cast<ucontext_t*>(ctx)->uc_mcontext.mc_rip);
#elif defined(__x86_64__)
void* const exception_pc = reinterpret_cast<void*>(static_cast<ucontext_t*>(ctx)->uc_mcontext.gregs[REG_RIP]);
#else
+2 -2
View File
@@ -72,7 +72,7 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsDialog* dialog, QWidget*
dialog->registerWidgetHelp(m_ui.eeClampMode, tr("Clamping Mode"), tr("Normal (Default)"), tr(""));
dialog->registerWidgetHelp(m_ui.eeRecompiler, tr("Enable Recompiler"), tr("Checked"),
tr("Performs just - in - time binary translation of 64 - bit MIPS - IV machine code to x86."));
tr("Performs just-in-time binary translation of 64-bit MIPS-IV machine code to x86."));
dialog->registerWidgetHelp(m_ui.eeWaitLoopDetection, tr("Wait Loop Detection"), tr("Checked"),
tr("Moderate speedup for some games, with no known side effects."));
@@ -86,7 +86,7 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsDialog* dialog, QWidget*
tr("Uses backpatching to avoid register flushing on every memory access."));
dialog->registerWidgetHelp(m_ui.pauseOnTLBMiss, tr("Pause On TLB Miss"), tr("Unchecked"),
tr("Pauses the virtual machine when a TLB miss occurs, instead of ignoring it and continuing. Note the the VM will pause after the "
tr("Pauses the virtual machine when a TLB miss occurs, instead of ignoring it and continuing. Note that the VM will pause after the "
"end of the block, not on the instruction which caused the exception. Refer to the console to see the address where the invalid "
"access occurred."));
@@ -120,8 +120,8 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsDialog* dialog, QWidget
tr("Allows games and homebrew to access files / folders directly on the host computer."));
dialog->registerWidgetHelp(m_ui.optimalFramePacing, tr("Optimal Frame Pacing"), tr("Unchecked"),
tr("Sets the vsync queue size to 0, making every frame be completed and presented by the GS before input is polled, and the next frame begins. "
"Using this setting can reduce input lag, at the cost of measurably higher CPU and GPU requirements."));
tr("Sets the VSync queue size to 0, making every frame be completed and presented by the GS before input is polled and the next frame begins. "
"Using this setting can reduce input lag at the cost of measurably higher CPU and GPU requirements."));
dialog->registerWidgetHelp(m_ui.maxFrameLatency, tr("Maximum Frame Latency"), tr("2 Frames"),
tr("Sets the maximum number of frames that can be queued up to the GS, before the CPU thread will wait for one of them to complete before continuing. "
"Higher values can assist with smoothing out irregular frame times, but add additional input lag."));
+22 -11
View File
@@ -372,7 +372,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
dialog->registerWidgetHelp(m_ui.PCRTCOverscan, tr("Show Overscan"), tr("Unchecked"),
tr("Enables the option to show the overscan area on games which draw more than the safe area of the screen."));
dialog->registerWidgetHelp(m_ui.fmvAspectRatio, tr("FMV Aspect Ratio"), tr("Off (Default)"), tr("Overrides the FMV aspect ratio."));
dialog->registerWidgetHelp(m_ui.fmvAspectRatio, tr("FMV Aspect Ratio"), tr("Off (Default)"),
tr("Overrides the full-motion video (FMV) aspect ratio."));
dialog->registerWidgetHelp(m_ui.PCRTCAntiBlur, tr("Anti-Blur"), tr("Checked"),
tr("Enables internal Anti-Blur hacks. Less accurate to PS2 rendering but will make a lot of games look less blurry."));
@@ -402,24 +403,32 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
tr("Selects the quality at which screenshots will be compressed. Higher values preserve more detail for JPEG, and reduce file "
"size for PNG."));
dialog->registerWidgetHelp(m_ui.stretchY, tr("Stretch Height"), tr("100%"), tr(""));
dialog->registerWidgetHelp(m_ui.stretchY, tr("Stretch Height"), tr("100%"),
tr("Stretches (> 100%) or squashes (< 100%) the vertical component of the display"));
dialog->registerWidgetHelp(m_ui.fullscreenModes, tr("Fullscreen Mode"), tr("Borderless Fullscreen"),
tr("Chooses the fullscreen resolution and frequency."));
dialog->registerWidgetHelp(m_ui.cropLeft, tr("Left"), tr("0px"), tr(""));
dialog->registerWidgetHelp(m_ui.cropLeft, tr("Left"), tr("0px"),
tr("Changes number of pixels cropped from the left side of the display"));
dialog->registerWidgetHelp(m_ui.cropTop, tr("Top"), tr("0px"), tr(""));
dialog->registerWidgetHelp(m_ui.cropTop, tr("Top"), tr("0px"),
tr("Changes number of pixels cropped from the top of the display"));
dialog->registerWidgetHelp(m_ui.cropRight, tr("Right"), tr("0px"), tr(""));
dialog->registerWidgetHelp(m_ui.cropRight, tr("Right"), tr("0px"),
tr("Changes number of pixels cropped from the right side of the display"));
dialog->registerWidgetHelp(m_ui.cropBottom, tr("Bottom"), tr("0px"), tr(""));
dialog->registerWidgetHelp(m_ui.cropBottom, tr("Bottom"), tr("0px"),
tr("Changes number of pixels cropped from the bottom of the display"));
}
// Rendering tab
{
// Hardware
dialog->registerWidgetHelp(m_ui.upscaleMultiplier, tr("Internal Resolution"), tr("Native (PS2) (Default)"), tr(""));
dialog->registerWidgetHelp(m_ui.upscaleMultiplier, tr("Internal Resolution"), tr("Native (PS2) (Default)"),
tr("Control the resolution at which games are rendered. High resolutions can impact performance on"
"older or lower-end GPUs.<br>Non-native resolution may cause minor graphical issues in some games.<br>"
"FMV resolution will remain unchanged, as the video files are pre-rendered."));
dialog->registerWidgetHelp(
m_ui.mipmapping, tr("Mipmapping"), tr("Automatic (Default)"), tr("Control the accuracy level of the mipmapping emulation."));
@@ -491,7 +500,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
dialog->registerWidgetHelp(m_ui.cpuSpriteRenderBW, tr("CPU Sprite Renderer Size"), tr("0 (Disabled)"), tr(""));
dialog->registerWidgetHelp(m_ui.cpuCLUTRender, tr("Software Clut Render"), tr("0 (Disabled)"), tr(""));
dialog->registerWidgetHelp(m_ui.cpuCLUTRender, tr("Software CLUT Render"), tr("0 (Disabled)"), tr(""));
dialog->registerWidgetHelp(m_ui.skipDrawStart, tr("Skipdraw Range Start"), tr("0"),
tr("Completely skips drawing surfaces from the surface in the left box up to the surface specified in the box on the right."));
@@ -592,13 +601,14 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
dialog->registerWidgetHelp(m_ui.shadeBoostSaturation, tr("Saturation"), tr("50"), tr(""));
dialog->registerWidgetHelp(m_ui.tvShader, tr("TV Shader"), tr("None (Default)"), tr(""));
dialog->registerWidgetHelp(m_ui.tvShader, tr("TV Shader"), tr("None (Default)"),
tr("Applies a shader which replicates the visual effects of different styles of television set."));
}
// OSD tab
{
dialog->registerWidgetHelp(
m_ui.osdScale, tr("OSD Scale"), tr("100%"), tr("Scales the size of the onscreen OSD from 100% to 500%."));
m_ui.osdScale, tr("OSD Scale"), tr("100%"), tr("Scales the size of the onscreen OSD from 50% to 500%."));
dialog->registerWidgetHelp(m_ui.osdShowMessages, tr("Show OSD Messages"), tr("Checked"),
tr("Shows on-screen-display messages when events occur such as save states being "
@@ -654,7 +664,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
tr("Allows the GPU instead of just the CPU to transform lines into sprites. "
"This reduces CPU load and bandwidth requirement, but it is heavier on the GPU."));
dialog->registerWidgetHelp(m_ui.gsDumpCompression, tr("GS Dump Compression"), tr("Zstandard (zst)"), tr(""));
dialog->registerWidgetHelp(m_ui.gsDumpCompression, tr("GS Dump Compression"), tr("Zstandard (zst)"),
tr("Change the compression algorithm used when creating a GS dump."));
dialog->registerWidgetHelp(m_ui.useBlitSwapChain, tr("Use Blit Swap Chain"), tr("Unchecked"),
tr("Uses a blit presentation model instead of flipping when using the Direct3D 11 "
+1 -1
View File
@@ -1536,7 +1536,7 @@
<string>%</string>
</property>
<property name="minimum">
<number>100</number>
<number>50</number>
</property>
<property name="maximum">
<number>500</number>
@@ -129,7 +129,7 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsDialog* dialog, QWidget
m_ui.confirmShutdown, tr("Confirm Shutdown"), tr("Checked"),
tr("Determines whether a prompt will be displayed to confirm shutting down the virtual machine "
"when the hotkey is pressed."));
dialog->registerWidgetHelp(m_ui.saveStateOnShutdown, tr("Save State On Shutdown"), tr("Checked"),
dialog->registerWidgetHelp(m_ui.saveStateOnShutdown, tr("Save State On Shutdown"), tr("Unchecked"),
tr("Automatically saves the emulator state when powering down or exiting. You can then "
"resume directly from where you left off next time."));
dialog->registerWidgetHelp(m_ui.pauseOnStart, tr("Pause On Start"), tr("Unchecked"),
@@ -58,7 +58,7 @@ MemoryCardConvertDialog::MemoryCardConvertDialog(QWidget* parent, QString select
SetType(MemoryCardType::File, MemoryCardFileType::PS2_8MB, "A standard, 8 MB memory card. Most compatible, but smallest capacity.");
break;
case 16:
SetType(MemoryCardType::File, MemoryCardFileType::PS2_16MB, "2x larger as a standard memory card. May have some compatibility issues.");
SetType(MemoryCardType::File, MemoryCardFileType::PS2_16MB, "2x larger than a standard memory card. May have some compatibility issues.");
break;
case 32:
SetType(MemoryCardType::File, MemoryCardFileType::PS2_32MB, "4x larger than a standard memory card. Likely to have compatibility issues.");
+1 -1
View File
@@ -115,7 +115,7 @@ void SettingsDialog::setupUi(const GameList::Entry* game)
{
addWidget(m_game_fix_settings_widget = new GameFixSettingsWidget(this, m_ui.settingsContainer), tr("Game Fix"),
QStringLiteral("close-line"),
tr("<strong>Game Fix Settings</strong><hr>Gamefixes can work around incorrect emulation in some titles<br>however they can "
tr("<strong>Game Fix Settings</strong><hr>Gamefixes can work around incorrect emulation in some titles.<br>However, they can "
"also cause problems in games if used incorrectly.<br>It is best to leave them all disabled unless advised otherwise."));
}
+4 -4
View File
@@ -602,9 +602,12 @@ static __fi void frameLimit()
static __fi void VSyncStart(u32 sCycle)
{
// Update vibration at the end of a frame.
VSyncUpdateCore();
PAD::Update();
VSyncUpdateCore();
frameLimit(); // limit FPS
gsPostVsyncStart(); // MUST be after framelimit; doing so before causes funk with frame times!
VSyncCheckExit();
if(EmuConfig.Trace.Enabled && EmuConfig.Trace.EE.m_EnableAll)
SysTrace.EE.Counters.Write( " ================ EE COUNTER VSYNC START (frame: %d) ================", g_FrameCount );
@@ -671,9 +674,6 @@ static __fi void VSyncEnd(u32 sCycle)
if (!(g_FrameCount % 60))
sioNextFrame();
frameLimit(); // limit FPS
gsPostVsyncStart(); // MUST be after framelimit; doing so before causes funk with frame times!
VSyncCheckExit();
// This doesn't seem to be needed here. Games only seem to break with regard to the
// vsyncstart irq.
//cpuRegs.eCycle[30] = 2;
+2 -2
View File
@@ -169,8 +169,8 @@ The clamp modes are also numerically based.
* alignSprite [`0` or `1`] {Off or On} Default: Off (`0`)
* mergeSprite [`0` or `1`] {Off or On} Default: Off (`0`)
* wildArmsHack [`0` or `1`] {Off or On} Default: Off (`0`)
* skipDrawStart [Value between `0` to `100000`] {0-100000} Default: Off (`0`)
* skipDrawEnd [Value between `0` to `100000`] {0-100000} Default: Off (`0`)
* skipDrawStart [Value between `0` to `10000`] {0-10000} Default: Off (`0`)
* skipDrawEnd [Value between `0` to `10000`] {0-10000} Default: Off (`0`)
* halfPixelOffset [`0` or `1` or `2` or `3`] {Off, Normal Vertex, Special Texture or Special Texture Aggressive} Default: Off (`0`)
* roundSprite [`0` or `1` or `2`] {Off, Half or Full} Default: Off (`0`)
+1 -1
View File
@@ -160,7 +160,7 @@ void CommonHost::SetDataDirectory()
EmuFolders::DataRoot = Path::Combine(StringUtil::WideStringToUTF8String(documents_directory), "PCSX2");
CoTaskMemFree(documents_directory);
}
#elif defined(__linux__)
#elif defined(__linux__) || defined(__FreeBSD__)
// Use $XDG_CONFIG_HOME/PCSX2 if it exists.
const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
if (xdg_config_home && Path::IsAbsolute(xdg_config_home))
+2 -2
View File
@@ -90,7 +90,7 @@ bool ImGuiManager::Initialize()
return false;
}
s_global_scale = std::max(1.0f, g_host_display->GetWindowScale() * (EmuConfig.GS.OsdScale / 100.0f));
s_global_scale = std::max(0.5f, g_host_display->GetWindowScale() * (EmuConfig.GS.OsdScale / 100.0f));
ImGui::CreateContext();
@@ -185,7 +185,7 @@ void ImGuiManager::WindowResized()
void ImGuiManager::UpdateScale()
{
const float window_scale = g_host_display ? g_host_display->GetWindowScale() : 1.0f;
const float scale = std::max(window_scale * (EmuConfig.GS.OsdScale / 100.0f), 1.0f);
const float scale = std::max(window_scale * (EmuConfig.GS.OsdScale / 100.0f), 0.5f);
if (scale == s_global_scale && (!HasFullscreenFonts() || !ImGuiFullscreen::UpdateLayoutScale()))
return;
+24 -21
View File
@@ -1758,14 +1758,18 @@ void GSState::Write(const u8* mem, int len)
// Invalid the CLUT if it crosses paths.
m_mem.m_clut.InvalidateRange(write_start_bp, write_end_bp);
if (GSConfig.PreloadFrameWithGSData)
GSVector4i r;
r.left = m_env.TRXPOS.DSAX;
r.top = m_env.TRXPOS.DSAY;
r.right = r.left + m_env.TRXREG.RRW;
r.bottom = r.top + m_env.TRXREG.RRH;
// Store the transfer for preloading new RT's.
if (m_draw_transfers.size() == 0 || (m_draw_transfers.size() > 0 && blit.DBP != m_draw_transfers.back().blit.DBP))
{
// Store the transfer for preloading new RT's.
if (m_draw_transfers.size() == 0 || (m_draw_transfers.size() > 0 && blit.DBP != m_draw_transfers.back().blit.DBP))
{
GSUploadQueue new_transfer = { blit, s_n };
m_draw_transfers.push_back(new_transfer);
}
GSUploadQueue new_transfer = { blit, r, s_n };
m_draw_transfers.push_back(new_transfer);
}
GL_CACHE("Write! ... => 0x%x W:%d F:%s (DIR %d%d), dPos(%d %d) size(%d %d)",
@@ -1776,12 +1780,6 @@ void GSState::Write(const u8* mem, int len)
if (m_tr.end == 0 && len >= m_tr.total)
{
// received all data in one piece, no need to buffer it
GSVector4i r;
r.left = m_env.TRXPOS.DSAX;
r.top = m_env.TRXPOS.DSAY;
r.right = r.left + m_env.TRXREG.RRW;
r.bottom = r.top + m_env.TRXREG.RRH;
ExpandTarget(m_env.BITBLTBUF, r);
InvalidateVideoMem(blit, r, true);
@@ -1917,15 +1915,20 @@ void GSState::Move()
Flush(GSFlushReason::LOCALTOLOCALMOVE);
}
if (GSConfig.PreloadFrameWithGSData)
// Store the transfer for preloading new RT's.
if (m_draw_transfers.size() == 0 || (m_draw_transfers.size() > 0 && dbp != m_draw_transfers.back().blit.DBP))
{
// Store the transfer for preloading new RT's.
if (m_draw_transfers.size() == 0 || (m_draw_transfers.size() > 0 && dbp != m_draw_transfers.back().blit.DBP))
{
GSUploadQueue new_transfer = { m_env.BITBLTBUF, s_n };
m_draw_transfers.push_back(new_transfer);
}
GSVector4i r;
r.left = m_env.TRXPOS.DSAX;
r.top = m_env.TRXPOS.DSAY;
r.right = r.left + m_env.TRXREG.RRW;
r.bottom = r.top + m_env.TRXREG.RRH;
GSUploadQueue new_transfer = { m_env.BITBLTBUF, r, s_n };
m_draw_transfers.push_back(new_transfer);
}
// Invalid the CLUT if it crosses paths.
m_mem.m_clut.InvalidateRange(write_start_bp, write_end_bp);
@@ -2920,7 +2923,7 @@ __forceinline void GSState::HandleAutoFlush()
const GSVector2i offset = GSVector2i(m_context->XYOFFSET.OFX, m_context->XYOFFSET.OFY);
const GSVector4i scissor = GSVector4i(m_context->scissor.in);
GSVector4i old_tex_rect = GSVector4i(0, 0, 0, 0);
GSVector4i old_tex_rect = GSVector4i::zero();
int current_draw_end = m_index.tail;
while (current_draw_end >= n)
+60 -22
View File
@@ -209,6 +209,7 @@ public:
struct GSUploadQueue
{
GIFRegBITBLTBUF blit;
GSVector4i rect;
int draw;
};
@@ -354,7 +355,7 @@ public:
bool IsAnalogue()
{
GSVideoMode video = static_cast<GSVideoMode>(videomode + 1);
const GSVideoMode video = static_cast<GSVideoMode>(videomode + 1);
return video == GSVideoMode::NTSC || video == GSVideoMode::PAL || video == GSVideoMode::HDTV_1080I;
}
@@ -381,7 +382,7 @@ public:
returnValue.x = 0;
// When interlaced, the vertical base offset is doubled
int verticalOffset = VideoModeOffsets[videomode].w * (1 << interlaced);
const int verticalOffset = VideoModeOffsets[videomode].w * (1 << interlaced);
if (abs(PCRTCDisplays[0].displayOffset.y - verticalOffset) <
abs(PCRTCDisplays[1].displayOffset.y - verticalOffset))
@@ -421,7 +422,7 @@ public:
bool FrameWrap()
{
GSVector4i combined_rect = GSVector4i(PCRTCDisplays[0].framebufferRect.runion(PCRTCDisplays[1].framebufferRect));
const GSVector4i combined_rect = GSVector4i(PCRTCDisplays[0].framebufferRect.runion(PCRTCDisplays[1].framebufferRect));
return combined_rect.w >= 2048 || combined_rect.z >= 2048;
}
@@ -442,7 +443,7 @@ public:
{
if (PCRTCDisplays[0].enabled && PCRTCDisplays[1].enabled)
{
GSVector4i combined_size = PCRTCDisplays[0].displayRect.runion(PCRTCDisplays[1].displayRect);
const GSVector4i combined_size = PCRTCDisplays[0].displayRect.runion(PCRTCDisplays[1].displayRect);
resolution = { combined_size.width(), combined_size.height() };
}
else if (PCRTCDisplays[0].enabled)
@@ -503,20 +504,20 @@ public:
if (combined_rect.z >= 2048)
{
int high_x = (PCRTCDisplays[0].framebufferRect.x > PCRTCDisplays[1].framebufferRect.x) ? PCRTCDisplays[0].framebufferRect.x : PCRTCDisplays[1].framebufferRect.x;
const int high_x = (PCRTCDisplays[0].framebufferRect.x > PCRTCDisplays[1].framebufferRect.x) ? PCRTCDisplays[0].framebufferRect.x : PCRTCDisplays[1].framebufferRect.x;
combined_rect.z -= GSConfig.UseHardwareRenderer() ? 2048 : high_x;
combined_rect.x = 0;
}
if (combined_rect.w >= 2048)
{
int high_y = (PCRTCDisplays[0].framebufferRect.y > PCRTCDisplays[1].framebufferRect.y) ? PCRTCDisplays[0].framebufferRect.y : PCRTCDisplays[1].framebufferRect.y;
const int high_y = (PCRTCDisplays[0].framebufferRect.y > PCRTCDisplays[1].framebufferRect.y) ? PCRTCDisplays[0].framebufferRect.y : PCRTCDisplays[1].framebufferRect.y;
combined_rect.w -= GSConfig.UseHardwareRenderer() ? 2048 : high_y;
combined_rect.y = 0;
}
// Cap the framebuffer read to the maximum display height, otherwise the hardware renderer gets messy.
int min_mag = std::max(1, std::min(PCRTCDisplays[0].magnification.y, PCRTCDisplays[1].magnification.y));
const int min_mag = std::max(1, std::min(PCRTCDisplays[0].magnification.y, PCRTCDisplays[1].magnification.y));
combined_rect.w = std::min(combined_rect.w, combined_rect.y + (max_height / min_mag));
return GSVector2i(combined_rect.z, combined_rect.w);
}
@@ -612,16 +613,24 @@ public:
// Only considered if "Anti-blur" is enabled.
void CalculateFramebufferOffset()
{
if (GSConfig.PCRTCAntiBlur && PCRTCDisplays[0].enabled && PCRTCSameSrc)
if (GSConfig.PCRTCAntiBlur && PCRTCSameSrc)
{
if (abs(PCRTCDisplays[1].framebufferOffsets.y - PCRTCDisplays[0].framebufferOffsets.y) == 1
&& PCRTCDisplays[0].displayOffset.y == PCRTCDisplays[1].displayOffset.y)
&& PCRTCDisplays[0].displayRect.y == PCRTCDisplays[1].displayRect.y)
{
if (PCRTCDisplays[1].framebufferOffsets.y < PCRTCDisplays[0].framebufferOffsets.y)
PCRTCDisplays[0].framebufferOffsets.y = PCRTCDisplays[1].framebufferOffsets.y;
else
PCRTCDisplays[1].framebufferOffsets.y = PCRTCDisplays[0].framebufferOffsets.y;
}
if (abs(PCRTCDisplays[1].framebufferOffsets.x - PCRTCDisplays[0].framebufferOffsets.x) == 1
&& PCRTCDisplays[0].displayRect.x == PCRTCDisplays[1].displayRect.x)
{
if (PCRTCDisplays[1].framebufferOffsets.x < PCRTCDisplays[0].framebufferOffsets.x)
PCRTCDisplays[0].framebufferOffsets.x = PCRTCDisplays[1].framebufferOffsets.x;
else
PCRTCDisplays[1].framebufferOffsets.x = PCRTCDisplays[0].framebufferOffsets.x;
}
}
PCRTCDisplays[0].framebufferRect.x += PCRTCDisplays[0].framebufferOffsets.x;
PCRTCDisplays[0].framebufferRect.z += PCRTCDisplays[0].framebufferOffsets.x;
@@ -657,6 +666,7 @@ public:
{
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[PCRTCDisplays[display].PSM];
// Software mode - See note below.
GSVector4i r = PCRTCDisplays[display].framebufferRect;
r = r.ralign<Align_Outside>(psm.bs);
@@ -668,6 +678,7 @@ public:
}
else
{
// Software Mode Note:
// This code is to read the framebuffer nicely block aligned in software, then leave the remaining offset in to the block.
// In hardware mode this doesn't happen, it reads the whole framebuffer, so we need to keep the offset.
if (!GSConfig.UseHardwareRenderer())
@@ -693,6 +704,7 @@ public:
// If using screen offsets, calculate the positions here.
void CalculateDisplayOffset(bool scanmask)
{
const bool both_enabled = PCRTCDisplays[0].enabled && PCRTCDisplays[1].enabled;
// Offsets are generally ignored, the "hacky" way of doing the displays, but direct to framebuffers.
if (!GSConfig.PCRTCOffsets)
{
@@ -701,13 +713,16 @@ public:
GSVector2i zeroDisplay = NearestToZeroOffset();
GSVector2i baseOffset = PCRTCDisplays[zeroDisplay.y].displayOffset;
int blurOffset = abs(PCRTCDisplays[1].displayOffset.y - PCRTCDisplays[0].displayOffset.y);
if (GSConfig.PCRTCAntiBlur && !scanmask && blurOffset < 4)
if (both_enabled)
{
if (PCRTCDisplays[1].displayOffset.y > PCRTCDisplays[0].displayOffset.y)
PCRTCDisplays[1].displayOffset.y -= blurOffset;
else
PCRTCDisplays[0].displayOffset.y -= blurOffset;
int blurOffset = abs(PCRTCDisplays[1].displayOffset.y - PCRTCDisplays[0].displayOffset.y);
if (GSConfig.PCRTCAntiBlur && !scanmask && blurOffset < 4)
{
if (PCRTCDisplays[1].displayOffset.y > PCRTCDisplays[0].displayOffset.y)
PCRTCDisplays[1].displayOffset.y -= blurOffset;
else
PCRTCDisplays[0].displayOffset.y -= blurOffset;
}
}
// If there's a single pixel offset, account for it else it can throw interlacing out.
@@ -732,7 +747,7 @@ public:
// Handle difference in offset between the two displays, used in games like DmC and Time Crisis 2 (for split screen).
// Offset is not screen based, but relative to each other.
if (PCRTCDisplays[0].enabled && PCRTCDisplays[1].enabled)
if (both_enabled)
{
GSVector2i offset;
@@ -770,14 +785,18 @@ public:
{
const GSVector4i offsets = !GSConfig.PCRTCOverscan ? VideoModeOffsets[videomode] : VideoModeOffsetsOverscan[videomode];
GSVector2i offset = { 0, 0 };
GSVector2i zeroDisplay = NearestToZeroOffset();
int blurOffset = abs(PCRTCDisplays[1].displayOffset.y - PCRTCDisplays[0].displayOffset.y);
if (GSConfig.PCRTCAntiBlur && !scanmask && blurOffset < 4)
if (both_enabled)
{
if (PCRTCDisplays[1].displayOffset.y > PCRTCDisplays[0].displayOffset.y)
PCRTCDisplays[1].displayOffset.y -= blurOffset;
else
PCRTCDisplays[0].displayOffset.y -= blurOffset;
int blurOffset = abs(PCRTCDisplays[1].displayOffset.y - PCRTCDisplays[0].displayOffset.y);
if (GSConfig.PCRTCAntiBlur && !scanmask && blurOffset < 4)
{
if (PCRTCDisplays[1].displayOffset.y > PCRTCDisplays[0].displayOffset.y)
PCRTCDisplays[1].displayOffset.y -= blurOffset;
else
PCRTCDisplays[0].displayOffset.y -= blurOffset;
}
}
for (int i = 0; i < 2; i++)
@@ -791,6 +810,25 @@ public:
PCRTCDisplays[i].displayRect.y += offset.y;
PCRTCDisplays[i].displayRect.w += offset.y;
}
if (both_enabled)
{
GSVector2i offset;
offset.x = (PCRTCDisplays[1 - zeroDisplay.x].displayRect.x - PCRTCDisplays[zeroDisplay.x].displayRect.x);
offset.y = (PCRTCDisplays[1 - zeroDisplay.y].displayRect.y - PCRTCDisplays[zeroDisplay.y].displayRect.y);
if (offset.x > 0 && offset.x < 4 && GSConfig.PCRTCAntiBlur)
{
PCRTCDisplays[1 - zeroDisplay.x].displayRect.x -= offset.x;
PCRTCDisplays[1 - zeroDisplay.x].displayRect.z -= offset.x;
}
if (offset.y > 0 && offset.y < 4 && GSConfig.PCRTCAntiBlur)
{
PCRTCDisplays[1 - zeroDisplay.y].displayRect.y -= offset.y;
PCRTCDisplays[1 - zeroDisplay.y].displayRect.w -= offset.y;
}
}
}
}
} PCRTCDisplays;
+1
View File
@@ -314,6 +314,7 @@ struct alignas(16) GSHWDrawConfig
u32 ltf : 1;
// Shuffle and fbmask effect
u32 shuffle : 1;
u32 real16src: 1;
u32 read_ba : 1;
u32 write_rg : 1;
u32 fbmask : 1;
+2 -2
View File
@@ -80,10 +80,11 @@ bool GSRenderer::Merge(int field)
GSVector2i fs(0, 0);
GSTexture* tex[3] = { NULL, NULL, NULL };
int y_offset[3] = { 0, 0, 0 };
bool feedback_merge = m_regs->EXTWRITE.WRITE == 1;
const bool feedback_merge = m_regs->EXTWRITE.WRITE == 1;
PCRTCDisplays.SetVideoMode(GetVideoMode());
PCRTCDisplays.EnableDisplays(m_regs->PMODE, m_regs->SMODE2, isReallyInterlaced());
PCRTCDisplays.CheckSameSource();
if (!PCRTCDisplays.PCRTCDisplays[0].enabled && !PCRTCDisplays.PCRTCDisplays[1].enabled)
return false;
@@ -96,7 +97,6 @@ bool GSRenderer::Merge(int field)
PCRTCDisplays.SetRects(1, m_regs->DISP[1].DISPLAY, m_regs->DISP[1].DISPFB);
PCRTCDisplays.CalculateDisplayOffset(m_scanmask_used);
PCRTCDisplays.CalculateFramebufferOffset();
PCRTCDisplays.CheckSameSource();
// Only need to check the right/bottom on software renderer, hardware always gets the full texture then cuts a bit out later.
if (PCRTCDisplays.FrameRectMatch() && !PCRTCDisplays.FrameWrap() && !feedback_merge)
+1
View File
@@ -34,6 +34,7 @@ private:
protected:
GSVector2i m_real_size{0, 0};
bool m_texture_shuffle = false;
bool m_copy_16bit_to_target_shuffle = false;
virtual GSTexture* GetOutput(int i, int& y_offset) = 0;
virtual GSTexture* GetFeedbackOutput() { return nullptr; }
@@ -160,6 +160,7 @@ void GSDevice11::SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstant
sm.AddMacro("PS_POINT_SAMPLER", sel.point_sampler);
sm.AddMacro("PS_SHUFFLE", sel.shuffle);
sm.AddMacro("PS_READ_BA", sel.read_ba);
sm.AddMacro("PS_READ16_SRC", sel.real16src);
sm.AddMacro("PS_CHANNEL_FETCH", sel.channel);
sm.AddMacro("PS_TALES_OF_ABYSS_HLE", sel.tales_of_abyss_hle);
sm.AddMacro("PS_URBAN_CHAOS_HLE", sel.urban_chaos_hle);
+1
View File
@@ -1501,6 +1501,7 @@ const ID3DBlob* GSDevice12::GetTFXPixelShader(const GSHWDrawConfig::PSSelector&
sm.AddMacro("PS_POINT_SAMPLER", sel.point_sampler);
sm.AddMacro("PS_SHUFFLE", sel.shuffle);
sm.AddMacro("PS_READ_BA", sel.read_ba);
sm.AddMacro("PS_READ16_SRC", sel.real16src);
sm.AddMacro("PS_CHANNEL_FETCH", sel.channel);
sm.AddMacro("PS_TALES_OF_ABYSS_HLE", sel.tales_of_abyss_hle);
sm.AddMacro("PS_URBAN_CHAOS_HLE", sel.urban_chaos_hle);
-61
View File
@@ -170,25 +170,6 @@ bool GSHwHack::GSC_SacredBlaze(GSRendererHW& r, const GSFrameInfo& fi, int& skip
return true;
}
bool GSHwHack::GSC_Spartan(GSRendererHW& r, const GSFrameInfo& fi, int& skip)
{
if (skip == 0)
{
if (fi.TME)
{
// depth textures (bully, mgs3s1 intro, Front Mission 5)
if ((fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) ||
// General, often problematic post processing
(GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)))
{
skip = 2;
}
}
}
return true;
}
bool GSHwHack::GSC_Oneechanbara2Special(GSRendererHW& r, const GSFrameInfo& fi, int& skip)
{
if (skip == 0)
@@ -499,21 +480,6 @@ bool GSHwHack::GSC_SakuraWarsSoLongMyLove(GSRendererHW& r, const GSFrameInfo& fi
return true;
}
bool GSHwHack::GSC_FightingBeautyWulong(GSRendererHW& r, const GSFrameInfo& fi, int& skip)
{
if (skip == 0)
{
if (!s_nativeres && fi.TME && (fi.TBP0 == 0x0700 || fi.TBP0 == 0x0a80) && (fi.TPSM == PSM_PSMCT32 || fi.TPSM == PSM_PSMCT24))
{
// Don't enable hack on native res if crc is below aggressive.
// removes glow/blur which cause ghosting and other sprite issues similar to Tekken 5
skip = 1;
}
}
return true;
}
bool GSHwHack::GSC_GodHand(GSRendererHW& r, const GSFrameInfo& fi, int& skip)
{
if (skip == 0)
@@ -1036,30 +1002,6 @@ bool GSHwHack::OI_FFX(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCa
return true;
}
bool GSHwHack::OI_MetalSlug6(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
// missing red channel fix (looks alright in pcsx2 r5000+)
GSVertex* RESTRICT v = r.m_vertex.buff;
for (size_t i = r.m_vertex.next; i > 0; i--, v++)
{
const u32 c = v->RGBAQ.U32[0];
const u32 r = (c >> 0) & 0xff;
const u32 g = (c >> 8) & 0xff;
const u32 b = (c >> 16) & 0xff;
if (r == 0 && g != 0 && b != 0)
{
v->RGBAQ.U32[0] = (c & 0xffffff00) | ((g + b + 1) >> 1);
}
}
r.m_vt.Update(r.m_vertex.buff, r.m_index.buff, r.m_vertex.tail, r.m_index.tail, r.m_vt.m_primclass);
return true;
}
bool GSHwHack::OI_RozenMaidenGebetGarden(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
@@ -1282,7 +1224,6 @@ const GSHwHack::Entry<GSRendererHW::GSC_Ptr> GSHwHack::s_get_skip_count_function
// Channel Effect
CRC_F(GSC_CrashBandicootWoC, CRCHackLevel::Partial),
CRC_F(GSC_GiTS, CRCHackLevel::Partial),
CRC_F(GSC_Spartan, CRCHackLevel::Partial),
CRC_F(GSC_SteambotChronicles, CRCHackLevel::Partial),
// Depth Issue
@@ -1296,7 +1237,6 @@ const GSHwHack::Entry<GSRendererHW::GSC_Ptr> GSHwHack::s_get_skip_count_function
CRC_F(GSC_DeathByDegreesTekkenNinaWilliams, CRCHackLevel::Partial), // + Upscaling issues
// Upscaling hacks
CRC_F(GSC_FightingBeautyWulong, CRCHackLevel::Partial),
CRC_F(GSC_Oneechanbara2Special, CRCHackLevel::Partial),
CRC_F(GSC_UltramanFightingEvolution, CRCHackLevel::Partial),
CRC_F(GSC_YakuzaGames, CRCHackLevel::Partial),
@@ -1322,7 +1262,6 @@ const GSHwHack::Entry<GSRendererHW::OI_Ptr> GSHwHack::s_before_draw_functions[]
CRC_F(OI_DBZBTGames, CRCHackLevel::Minimum),
CRC_F(OI_FFXII, CRCHackLevel::Minimum),
CRC_F(OI_FFX, CRCHackLevel::Minimum),
CRC_F(OI_MetalSlug6, CRCHackLevel::Minimum),
CRC_F(OI_RozenMaidenGebetGarden, CRCHackLevel::Minimum),
CRC_F(OI_SonicUnleashed, CRCHackLevel::Minimum),
CRC_F(OI_ArTonelico2, CRCHackLevel::Minimum),
-3
View File
@@ -24,7 +24,6 @@ public:
static bool GSC_Manhunt2(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_CrashBandicootWoC(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_SacredBlaze(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_Spartan(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_Oneechanbara2Special(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_SakuraTaisen(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_SFEX3(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
@@ -39,7 +38,6 @@ public:
static bool GSC_Kunoichi(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_ZettaiZetsumeiToshi2(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_SakuraWarsSoLongMyLove(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_FightingBeautyWulong(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_GodHand(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_KnightsOfTheTemple2(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
static bool GSC_UltramanFightingEvolution(GSRendererHW& r, const GSFrameInfo& fi, int& skip);
@@ -63,7 +61,6 @@ public:
static bool OI_DBZBTGames(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
static bool OI_FFXII(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
static bool OI_FFX(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
static bool OI_MetalSlug6(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
static bool OI_RozenMaidenGebetGarden(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
static bool OI_SonicUnleashed(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
static bool OI_ArTonelico2(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
+25 -15
View File
@@ -166,10 +166,15 @@ void GSRendererHW::VSync(u32 field, bool registers_written)
if ((s_n - iter->draw) > 5)
iter = m_draw_transfers.erase(iter);
else
{
iter++;
}
}
}
}
else
m_draw_transfers.clear();
if (GSConfig.LoadTextureReplacements)
GSTextureReplacements::ProcessAsyncLoadedTextures();
@@ -1328,7 +1333,7 @@ void GSRendererHW::Draw()
}
// SW CLUT Render enable.
bool preload = GSConfig.PreloadFrameWithGSData | (m_force_preload > 0);
bool force_preload = GSConfig.PreloadFrameWithGSData;
if (GSConfig.UserHacks_CPUCLUTRender > 0 || GSConfig.UserHacks_GPUTargetCLUTMode != GSGPUTargetCLUTMode::Disabled)
{
const CLUTDrawTestResult result = (GSConfig.UserHacks_CPUCLUTRender == 2) ? PossibleCLUTDrawAggressive() : PossibleCLUTDraw();
@@ -1349,14 +1354,17 @@ void GSRendererHW::Draw()
!IsOpaque()) // Blending enabled
{
GL_INS("Forcing preload due to partial/blended CLUT draw");
preload = m_force_preload = true;
force_preload = true;
}
}
}
if (m_channel_shuffle)
{
m_channel_shuffle = draw_sprite_tex && (m_context->TEX0.PSM == PSM_PSMT8) && single_page;
// NFSU2 does consecutive channel shuffles with blending, reducing the alpha channel over time.
// Fortunately, it seems to change the FBMSK along the way, so this check alone is sufficient.
m_channel_shuffle = draw_sprite_tex && m_context->TEX0.PSM == PSM_PSMT8 && single_page &&
m_last_channel_shuffle_fbmsk == m_context->FRAME.FBMSK;
if (m_channel_shuffle)
{
GL_CACHE("Channel shuffle effect detected SKIP");
@@ -1370,6 +1378,7 @@ void GSRendererHW::Draw()
{
GL_INS("Channel shuffle effect detected");
m_channel_shuffle = true;
m_last_channel_shuffle_fbmsk = m_context->FRAME.FBMSK;
}
else
{
@@ -1386,6 +1395,7 @@ void GSRendererHW::Draw()
m_src = nullptr;
m_texture_shuffle = false;
m_copy_16bit_to_target_shuffle = false;
m_tex_is_fb = false;
// The rectangle of the draw
@@ -1556,7 +1566,7 @@ void GSRendererHW::Draw()
GSTextureCache::Target* rt = nullptr;
if (!no_rt)
rt = m_tc->LookupTarget(TEX0, t_size, GSTextureCache::RenderTarget, true, fm, false, unscaled_target_size.x, unscaled_target_size.y, preload);
rt = m_tc->LookupTarget(TEX0, t_size, GSTextureCache::RenderTarget, true, fm, false, unscaled_target_size.x, unscaled_target_size.y, force_preload);
TEX0.TBP0 = context->ZBUF.Block();
TEX0.TBW = context->FRAME.FBW;
@@ -1564,18 +1574,17 @@ void GSRendererHW::Draw()
GSTextureCache::Target* ds = nullptr;
if (!no_ds)
ds = m_tc->LookupTarget(TEX0, t_size, GSTextureCache::DepthStencil, context->DepthWrite(), 0, false, 0, 0, preload);
ds = m_tc->LookupTarget(TEX0, t_size, GSTextureCache::DepthStencil, context->DepthWrite(), 0, false, unscaled_target_size.x, unscaled_target_size.y, force_preload);
if (process_texture)
{
GIFRegCLAMP MIP_CLAMP = context->CLAMP;
bool copy_16bit_to_target_shuffle = false;
if (rt)
{
// copy of a 16bit source in to this target, make sure it's opaque and not bilinear to reduce false positives.
copy_16bit_to_target_shuffle = context->TEX0.TBP0 != context->FRAME.Block() && rt->m_32_bits_fmt == true && IsOpaque() && !(context->TEX1.MMIN & 1);
m_copy_16bit_to_target_shuffle = context->TEX0.TBP0 != context->FRAME.Block() && rt->m_32_bits_fmt == true && IsOpaque()
&& !(context->TEX1.MMIN & 1) && !m_src->m_32_bits_fmt && context->FRAME.FBMSK;
}
// Hypothesis: texture shuffle is used as a postprocessing effect so texture will be an old target.
@@ -1583,7 +1592,7 @@ void GSRendererHW::Draw()
//
// Both input and output are 16 bits and texture was initially 32 bits!
m_texture_shuffle = (GSLocalMemory::m_psm[context->FRAME.PSM].bpp == 16) && (tex_psm.bpp == 16)
&& draw_sprite_tex && (m_src->m_32_bits_fmt || copy_16bit_to_target_shuffle);
&& draw_sprite_tex && (m_src->m_32_bits_fmt || m_copy_16bit_to_target_shuffle);
// Okami mustn't call this code
if (m_texture_shuffle && m_vertex.next < 3 && PRIM->FST && ((m_context->FRAME.FBMSK & fm_mask) == 0))
@@ -1616,6 +1625,7 @@ void GSRendererHW::Draw()
{
GL_INS("Channel shuffle effect detected (2nd shot)");
m_channel_shuffle = true;
m_last_channel_shuffle_fbmsk = m_context->FRAME.FBMSK;
}
else
{
@@ -2198,7 +2208,7 @@ void GSRendererHW::EmulateTextureShuffleAndFbmask()
m_conf.ps.write_rg = !write_ba && features.texture_barrier && m_context->TEST.DATE;
m_conf.ps.read_ba = read_ba;
m_conf.ps.real16src = m_copy_16bit_to_target_shuffle;
// Please bang my head against the wall!
// 1/ Reduce the frame mask to a 16 bit format
const u32 m = m_context->FRAME.FBMSK & GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk;
@@ -3080,7 +3090,7 @@ __ri static constexpr bool IsRedundantClamp(u8 clamp, u32 clamp_min, u32 clamp_m
// That way trilinear etc still works.
const u32 textent = (1u << tsize) - 1u;
if (clamp == CLAMP_REGION_CLAMP)
return (clamp_min == 0 && clamp_max == textent);
return (clamp_min == 0 && clamp_max >= textent);
else if (clamp == CLAMP_REGION_REPEAT)
return (clamp_max == 0 && clamp_min == textent);
else
@@ -3111,10 +3121,10 @@ void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Source* tex)
const u8 wms = EffectiveClamp(m_context->CLAMP.WMS, tex->m_region.HasX() || redundant_wms);
const u8 wmt = EffectiveClamp(m_context->CLAMP.WMT, tex->m_region.HasY() || redundant_wmt);
const bool complex_wms_wmt = !!((wms | wmt) & 2);
GL_CACHE("WMS: %s [%s%s] WMT: %s [%s%s] Complex: %d MINU: %d MINV: %d MINV: %d MAXV: %d",
GL_CACHE("WMS: %s [%s%s] WMT: %s [%s%s] Complex: %d MINU: %d MAXU: %d MINV: %d MAXV: %d",
clamp_modes[m_context->CLAMP.WMS], redundant_wms ? "redundant," : "", clamp_modes[wms],
clamp_modes[m_context->CLAMP.WMT], redundant_wmt ? "redundant," : "", clamp_modes[wmt],
complex_wms_wmt, m_context->CLAMP.MINU, m_context->CLAMP.MINV, m_context->CLAMP.MAXU, m_context->CLAMP.MAXV);
complex_wms_wmt, m_context->CLAMP.MINU, m_context->CLAMP.MAXU, m_context->CLAMP.MINV, m_context->CLAMP.MAXV);
const bool need_mipmap = IsMipMapDraw();
const bool shader_emulated_sampler = tex->m_palette || cpsm.fmt != 0 || complex_wms_wmt || psm.depth;
@@ -3343,8 +3353,8 @@ void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Source* tex)
m_conf.cb_vs.texture_scale = GSVector2(tc_oh_ts.x, tc_oh_ts.y);
// Only enable clamping in CLAMP mode. REGION_CLAMP will be done manually in the shader
m_conf.sampler.tau = (wms != CLAMP_CLAMP);
m_conf.sampler.tav = (wmt != CLAMP_CLAMP);
m_conf.sampler.tau = (wms == CLAMP_REPEAT);
m_conf.sampler.tav = (wmt == CLAMP_REPEAT);
if (shader_emulated_sampler)
{
m_conf.sampler.biln = 0;
+3 -1
View File
@@ -107,8 +107,10 @@ private:
int m_skip = 0;
int m_skip_offset = 0;
bool m_tex_is_fb = false;
u32 m_last_channel_shuffle_fbmsk = 0;
bool m_channel_shuffle = false;
bool m_tex_is_fb = false;
bool m_userhacks_tcoffset = false;
float m_userhacks_tcoffset_x = 0.0f;
float m_userhacks_tcoffset_y = 0.0f;
+71 -23
View File
@@ -216,7 +216,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0
__ri static GSTextureCache::Source* FindSourceInMap(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA,
const GSLocalMemory::psm_t& psm_s, const u32* clut, const GSTexture* gpu_clut, const GSVector2i& compare_lod,
const GSTextureCache::SourceRegion& region, FastList<GSTextureCache::Source*>& map)
const GSTextureCache::SourceRegion& region, u32 fixed_tex0, FastList<GSTextureCache::Source*>& map)
{
for (auto i = map.begin(); i != map.end(); ++i)
{
@@ -248,7 +248,10 @@ __ri static GSTextureCache::Source* FindSourceInMap(const GIFRegTEX0& TEX0, cons
continue;
}
if (s->m_region.bits != 0 && s->m_region.bits != region.bits)
// When fixed tex0 is used, we must find a matching region texture. The base likely
// doesn't contain to the correct region. Bit cheeky here, avoid a logical or by
// adding the invalid tex0 bit in.
if (((s->m_region.bits | fixed_tex0) != 0) && s->m_region.bits != region.bits)
continue;
// Same base mip texture, but we need to check that MXL was the same as well.
@@ -279,7 +282,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
{
// Another Lupin case here, it uses region clamp with UV (not ST), puts a clamp region further
// into the texture, but a smaller TW/TH. Catch this by looking for a clamp range above TW.
const u32 rw = CLAMP.MAXU - CLAMP.MAXU + 1;
const u32 rw = CLAMP.MAXU - CLAMP.MINU + 1;
if (rw < (1u << TEX0.TW) || CLAMP.MAXU >= (1u << TEX0.TW))
{
region.SetX(CLAMP.MINU, CLAMP.MAXU + 1);
@@ -322,15 +325,16 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
// Region textures might be placed in a different page, so check that first.
const u32 lookup_page = TEX0.TBP0 >> 5;
const bool is_fixed_tex0 = region.IsFixedTEX0(1 << TEX0.TW, 1 << TEX0.TH);
if (region.GetMinX() != 0 || region.GetMinY() != 0)
{
const GSOffset offset(psm_s.info, TEX0.TBP0, TEX0.TBW, TEX0.PSM);
const u32 region_page = offset.bn(region.GetMinX(), region.GetMinY()) >> 5;
if (lookup_page != region_page)
src = FindSourceInMap(TEX0, TEXA, psm_s, clut, gpu_clut, compare_lod, region, m_src.m_map[region_page]);
src = FindSourceInMap(TEX0, TEXA, psm_s, clut, gpu_clut, compare_lod, region, is_fixed_tex0, m_src.m_map[region_page]);
}
if (!src)
src = FindSourceInMap(TEX0, TEXA, psm_s, clut, gpu_clut, compare_lod, region, m_src.m_map[lookup_page]);
src = FindSourceInMap(TEX0, TEXA, psm_s, clut, gpu_clut, compare_lod, region, is_fixed_tex0, m_src.m_map[lookup_page]);
Target* dst = nullptr;
@@ -386,11 +390,18 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
// 2/ even with upscaling
// 3/ for both Direct3D and OpenGL
if (GSConfig.UserHacks_CPUFBConversion && (psm == PSM_PSMT4 || psm == PSM_PSMT8))
{
// 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).
// 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.
Read(t, t->m_valid);
if (!t->m_drawn_since_read.rempty())
{
Read(t, t->m_drawn_since_read);
t->m_drawn_since_read = GSVector4i::zero();
}
}
else
dst = t;
@@ -762,7 +773,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
GL_CACHE("TC: Lookup %s(%s) %dx%d, miss (0x%x, %s)", is_frame ? "Frame" : "Target", to_string(type), size.x, size.y, bp, psm_str(TEX0.PSM));
dst = CreateTarget(TEX0, size.x, size.y, type, true);
// In theory new textures contain invalidated data. Still in theory a new target
// must contains the content of the GS memory.
// In practice, TC will wrongly invalidate some RT. For example due to write on the alpha
@@ -775,19 +785,22 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
// From a performance point of view, it might cost a little on big upscaling
// but normally few RT are miss so it must remain reasonable.
const bool supported_fmt = !GSConfig.UserHacks_DisableDepthSupport || psm_s.depth == 0;
const bool forced_preload = GSRendererHW::GetInstance()->m_force_preload > 0;
if ((is_frame || preload || forced_preload) && TEX0.TBW > 0 && supported_fmt)
if (TEX0.TBW > 0 && supported_fmt)
{
if (!is_frame && !forced_preload)
const bool forced_preload = GSRendererHW::GetInstance()->m_force_preload > 0;
const GSVector4i newrect = GSVector4i(0, 0, real_w, real_h);
if (!is_frame && !forced_preload && !preload)
{
std::vector<GSState::GSUploadQueue>::iterator iter;
for (iter = GSRendererHW::GetInstance()->m_draw_transfers.begin(); iter != GSRendererHW::GetInstance()->m_draw_transfers.end(); )
{
if (iter->blit.DBP == TEX0.TBP0 && GSUtil::HasSharedBits(iter->blit.DPSM, TEX0.PSM))
// If the format, and location doesn't match, but also the upload is at least the size of the target, don't preload.
if (iter->blit.DBP == TEX0.TBP0 && GSUtil::HasCompatibleBits(iter->blit.DPSM, TEX0.PSM) && iter->rect.rintersect(newrect).eq(newrect))
{
GSRendererHW::GetInstance()->m_draw_transfers.erase(iter);
GL_INS("Preloading the RT DATA");
const GSVector4i newrect = GSVector4i(0, 0, real_w, real_h);
AddDirtyRectTarget(dst, newrect, TEX0.PSM, TEX0.TBW);
dst->Update(true);
break;
@@ -798,7 +811,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
else
{
GL_INS("Preloading the RT DATA");
const GSVector4i newrect = GSVector4i(0, 0, real_w, real_h);
AddDirtyRectTarget(dst, newrect, TEX0.PSM, TEX0.TBW);
dst->Update(true);
}
@@ -811,7 +823,8 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
}
if (is_frame)
dst->m_dirty_alpha = false;
dst->readbacks_since_draw = 0;
assert(dst && dst->m_texture && dst->m_texture->GetScale() == new_s);
assert(dst && dst->m_dirty.empty());
@@ -1408,7 +1421,14 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r
if (GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t->m_TEX0.PSM))
{
if (GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM))
Read(t, r.rintersect(t->m_valid));
{
const GSVector4i draw_rect = (t->readbacks_since_draw > 0) ? t->m_drawn_since_read : r.rintersect(t->m_drawn_since_read);
Read(t, draw_rect);
t->readbacks_since_draw++;
if(draw_rect.rintersect(t->m_drawn_since_read).eq(t->m_drawn_since_read))
t->m_drawn_since_read = GSVector4i::zero();
}
}
}
}
@@ -1447,6 +1467,10 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r
// note: r.rintersect breaks Wizardry and Chaos Legion
// Read(t, t->m_valid) works in all tested games but is very slow in GUST titles ><
// If the game has been spamming downloads, we've already read the whole texture back at this point.
if (t->m_drawn_since_read.rempty())
continue;
// propagate the format from the result of a channel effect
// texture is 16/8 bit but the real data is 32
// common use for shuffling is moving data into the alpha channel
@@ -1462,16 +1486,39 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r
const GSVector4i rb_rc((!GSConfig.UserHacks_DisablePartialInvalidation && targetr.x == 0 && targetr.y == 0) ? t->m_valid : targetr.rintersect(t->m_valid));
DevCon.Error("Skipping depth readback of %ux%u @ %u,%u", rb_rc.width(), rb_rc.height(), rb_rc.left, rb_rc.top);
}
else if (GSConfig.UserHacks_DisablePartialInvalidation)
{
Read(t, targetr.rintersect(t->m_valid));
}
else
{
if (targetr.x == 0 && targetr.y == 0) // Full screen read?
Read(t, t->m_valid);
else // Block level read?
Read(t, targetr.rintersect(t->m_valid));
// If it's a download to the EE, or we've done multiple reads of the same texture between draws, just get it all.
if (!GSConfig.UserHacks_DisablePartialInvalidation && t->readbacks_since_draw > 0)
{
Read(t, t->m_drawn_since_read);
t->m_drawn_since_read = GSVector4i::zero();
t->readbacks_since_draw++;
}
else if(!targetr.rintersect(t->m_drawn_since_read).rempty()) // Block level read?
{
// Read full width of drawn area, it's not much slower and makes invalidation easier.
GSVector4i full_lines = GSVector4i(0, targetr.y, t->m_valid.z, targetr.w);
full_lines = full_lines.rintersect(t->m_drawn_since_read);
Read(t, full_lines);
// After reading, try to cut down our "dirty" rect.
if (full_lines.rintersect(t->m_drawn_since_read).eq(t->m_drawn_since_read))
t->m_drawn_since_read = GSVector4i::zero();
else
{
// Try to cut down how much we read next, if we can.
if (full_lines.w >= t->m_drawn_since_read.y)
{
if (full_lines.y <= t->m_drawn_since_read.y)
t->m_drawn_since_read.y = full_lines.w;
else if (full_lines.w >= t->m_drawn_since_read.w)
t->m_drawn_since_read.w = full_lines.y;
}
}
t->readbacks_since_draw++;
}
}
}
}
@@ -3192,6 +3239,7 @@ void GSTextureCache::Target::UpdateValidity(const GSVector4i& rect)
else
m_valid = m_valid.runion(rect);
m_drawn_since_read = m_drawn_since_read.runion(rect);
// Block of the bottom right texel of the validity rectangle, last valid block of the texture
// TODO: This is not correct when the PSM changes. e.g. a 512x448 target being shuffled will become 512x896 temporarily, and
// at the moment, we blow the valid rect out to twice the size. The only thing stopping everything breaking is the fact
+10 -8
View File
@@ -234,13 +234,15 @@ public:
class Target : public Surface
{
public:
const int m_type;
bool m_used;
const int m_type = 0;
bool m_used = false;
GSDirtyRectList m_dirty;
GSVector4i m_valid;
const bool m_depth_supported;
bool m_dirty_alpha;
bool m_is_frame;
GSVector4i m_valid{};
GSVector4i m_drawn_since_read{};
const bool m_depth_supported = false;
bool m_dirty_alpha = true;
bool m_is_frame = false;
int readbacks_since_draw = 0;
public:
Target(const GIFRegTEX0& TEX0, const bool depth_supported, const int type);
@@ -303,10 +305,10 @@ public:
struct
{
u32 fbp : 9;
u32 fbp : 14;
u32 fbw : 6;
u32 psm : 6;
u32 pad : 11;
u32 pad : 6;
};
};
+1
View File
@@ -1379,6 +1379,7 @@ void GSDeviceMTL::MRESetHWPipelineState(GSHWDrawConfig::VSSelector vssel, GSHWDr
setFnConstantB(m_fn_constants, pssel.ltf, GSMTLConstantIndex_PS_LTF);
setFnConstantB(m_fn_constants, pssel.shuffle, GSMTLConstantIndex_PS_SHUFFLE);
setFnConstantB(m_fn_constants, pssel.read_ba, GSMTLConstantIndex_PS_READ_BA);
setFnConstantB(m_fn_constants, pssel.real16src, GSMTLConstantIndex_PS_READ16_SRC);
setFnConstantB(m_fn_constants, pssel.write_rg, GSMTLConstantIndex_PS_WRITE_RG);
setFnConstantB(m_fn_constants, pssel.fbmask, GSMTLConstantIndex_PS_FBMASK);
setFnConstantI(m_fn_constants, pssel.blend_a, GSMTLConstantIndex_PS_BLEND_A);
@@ -175,6 +175,7 @@ enum GSMTLFnConstants
GSMTLConstantIndex_PS_LTF,
GSMTLConstantIndex_PS_SHUFFLE,
GSMTLConstantIndex_PS_READ_BA,
GSMTLConstantIndex_PS_READ16_SRC,
GSMTLConstantIndex_PS_WRITE_RG,
GSMTLConstantIndex_PS_FBMASK,
GSMTLConstantIndex_PS_BLEND_A,
+16 -4
View File
@@ -42,6 +42,7 @@ constant bool PS_ADJT [[function_constant(GSMTLConstantIndex_PS_AD
constant bool PS_LTF [[function_constant(GSMTLConstantIndex_PS_LTF)]];
constant bool PS_SHUFFLE [[function_constant(GSMTLConstantIndex_PS_SHUFFLE)]];
constant bool PS_READ_BA [[function_constant(GSMTLConstantIndex_PS_READ_BA)]];
constant bool PS_READ16_SRC [[function_constant(GSMTLConstantIndex_PS_READ16_SRC)]];
constant bool PS_WRITE_RG [[function_constant(GSMTLConstantIndex_PS_WRITE_RG)]];
constant bool PS_FBMASK [[function_constant(GSMTLConstantIndex_PS_FBMASK)]];
constant uint PS_BLEND_A [[function_constant(GSMTLConstantIndex_PS_BLEND_A)]];
@@ -950,11 +951,22 @@ struct PSMain
uint4 denorm_c = uint4(C);
uint2 denorm_TA = uint2(cb.ta * 255.5f);
C.rb = PS_READ_BA ? C.bb : C.rr;
if (PS_READ_BA)
C.ga = (denorm_c.a & 0x7F) | (denorm_c.a & 0x80 ? denorm_TA.y & 0x80 : denorm_TA.x & 0x80);
if (PS_READ16_SRC)
{
C.rb = (denorm_c.r >> 3) | (((denorm_c.g >> 3) & 0x7u) << 5);
if (denorm_c.a & 0x80)
C.ga = (denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.y & 0x80);
else
C.ga = (denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.x & 0x80);
}
else
C.ga = (denorm_c.g & 0x7F) | (denorm_c.g & 0x80 ? denorm_TA.y & 0x80 : denorm_TA.x & 0x80);
{
C.rb = PS_READ_BA ? C.bb : C.rr;
if (PS_READ_BA)
C.ga = (denorm_c.a & 0x7F) | (denorm_c.a & 0x80 ? denorm_TA.y & 0x80 : denorm_TA.x & 0x80);
else
C.ga = (denorm_c.g & 0x7F) | (denorm_c.g & 0x80 ? denorm_TA.y & 0x80 : denorm_TA.x & 0x80);
}
}
// Must be done before alpha correction
@@ -1060,6 +1060,7 @@ std::string GSDeviceOGL::GetPSSource(const PSSelector& sel)
+ fmt::format("#define PS_IIP {}\n", sel.iip)
+ fmt::format("#define PS_SHUFFLE {}\n", sel.shuffle)
+ fmt::format("#define PS_READ_BA {}\n", sel.read_ba)
+ fmt::format("#define PS_READ16_SRC {}\n", sel.real16src)
+ fmt::format("#define PS_WRITE_RG {}\n", sel.write_rg)
+ fmt::format("#define PS_FBMASK {}\n", sel.fbmask)
+ fmt::format("#define PS_HDR {}\n", sel.hdr)
+7 -7
View File
@@ -189,7 +189,7 @@ GSTexture* GSRendererSW::GetOutput(int i, int& y_offset)
{
if (GSConfig.SaveFrame && s_n >= GSConfig.SaveN)
{
m_texture[i]->Save(GetDrawDumpPath("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, (int)curFramebuffer.Block(), psm_str(curFramebuffer.PSM)));
m_texture[index]->Save(GetDrawDumpPath("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, (int)curFramebuffer.Block(), psm_str(curFramebuffer.PSM)));
}
}
}
@@ -469,18 +469,18 @@ void GSRendererSW::Draw()
{
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
s = GetDrawDumpPath("%05d_f%lld_rt0_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, PCRTCDisplays.GetFramebufferRect(-1).width(), 512);
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, r.width(), r.height());
}
s = GetDrawDumpPath("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, PCRTCDisplays.GetFramebufferRect(-1).width(), 512);
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, r.width(), r.height());
}
if (GSConfig.SaveDepth && s_n >= GSConfig.SaveN)
{
s = GetDrawDumpPath("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, PCRTCDisplays.GetFramebufferRect(-1).width(), 512);
m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, r.width(), r.height());
}
Queue(data);
@@ -493,18 +493,18 @@ void GSRendererSW::Draw()
{
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
s = GetDrawDumpPath("%05d_f%lld_rt1_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, PCRTCDisplays.GetFramebufferRect(-1).width(), 512);
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, r.width(), r.height());
}
s = GetDrawDumpPath("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, PCRTCDisplays.GetFramebufferRect(-1).width(), 512);
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, r.width(), r.height());
}
if (GSConfig.SaveDepth && s_n >= GSConfig.SaveN)
{
s = GetDrawDumpPath("%05d_f%lld_rz1_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, PCRTCDisplays.GetFramebufferRect(-1).width(), 512);
m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, r.width(), r.height());
}
if (GSConfig.SaveL > 0 && (s_n - GSConfig.SaveN) > GSConfig.SaveL)
+1
View File
@@ -1983,6 +1983,7 @@ VkShaderModule GSDeviceVK::GetTFXFragmentShader(const GSHWDrawConfig::PSSelector
AddMacro(ss, "PS_IIP", sel.iip);
AddMacro(ss, "PS_SHUFFLE", sel.shuffle);
AddMacro(ss, "PS_READ_BA", sel.read_ba);
AddMacro(ss, "PS_READ16_SRC", sel.real16src);
AddMacro(ss, "PS_WRITE_RG", sel.write_rg);
AddMacro(ss, "PS_FBMASK", sel.fbmask);
AddMacro(ss, "PS_HDR", sel.hdr);
+5
View File
@@ -96,6 +96,11 @@ void Hle_SetElfPath(const char* elfFileName)
Console.WriteLn("HLE Host: Set 'host:' root path to: %s\n", hostRoot.c_str());
}
void Hle_ClearElfPath()
{
hostRoot = {};
}
namespace R3000A
{
+2
View File
@@ -86,3 +86,5 @@ namespace R3000A
} // namespace R3000A
extern void Hle_SetElfPath(const char* elfFileName);
extern void Hle_ClearElfPath();
+1 -1
View File
@@ -15,4 +15,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 = 12;
static constexpr u32 SHADER_CACHE_VERSION = 13;
+2 -2
View File
@@ -513,9 +513,9 @@ namespace usb_lightgun
{SettingInfo::Type::Float, "scale_y", "Y Scale (Sensitivity)",
"Scales the position to simulate CRT curvature.", "100", "0", "200", "0.1", "%.2f%%", nullptr, nullptr,
1.0f},
{SettingInfo::Type::Float, "center_x", "Center X", "Sets the center position of the simulated screen.",
{SettingInfo::Type::Float, "center_x", "Center X", "Sets the horizontal center position of the simulated screen.",
"320", "0", "1024", "1", "%.0fpx", nullptr, nullptr, 1.0f},
{SettingInfo::Type::Float, "center_y", "Center Y", "Sets the center position of the simulated screen.",
{SettingInfo::Type::Float, "center_y", "Center Y", "Sets the vertical center position of the simulated screen.",
"120", "0", "1024", "1", "%.0fpx", nullptr, nullptr, 1.0f},
{SettingInfo::Type::Integer, "screen_width", "Screen Width", "Sets the width of the simulated screen.",
"640", "1", "1024", "1", "%dpx", nullptr, nullptr, 1.0f},
+4
View File
@@ -905,6 +905,10 @@ bool VMManager::ApplyBootParameters(VMBootParameters params, std::string* state_
Hle_SetElfPath(s_elf_override.c_str());
EmuConfig.UseBOOT2Injection = true;
}
else
{
Hle_ClearElfPath();
}
return true;
}
+1 -1
View File
@@ -137,7 +137,7 @@ static bool LoadBiosVersion(std::FILE* fp, u32& version, std::string& descriptio
version |= strtol(vermin, (char**)NULL, 0);
foundRomVer = true;
Console.WriteLn("Bios Found: %s", description.c_str());
Console.WriteLn("BIOS Found: %s", description.c_str());
}
if ((rd.fileSize % 0x10) == 0)