mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-07-31 19:28:40 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0284c35f4c | ||
|
|
6ce33de287 | ||
|
|
6ccfa011d4 | ||
|
|
c9078af45e | ||
|
|
6745428d0c | ||
|
|
925e874ada | ||
|
|
03f0f2f803 | ||
|
|
857360d6b2 | ||
|
|
2dd76c3f12 | ||
|
|
666de3a874 | ||
|
|
e0e9b64db6 | ||
|
|
2f521348c6 | ||
|
|
8ac2949a1f | ||
|
|
d0d5d991ce | ||
|
|
1fc2d7de3c | ||
|
|
2598e8d9b9 | ||
|
|
01f65e98e6 | ||
|
|
c5330cf166 | ||
|
|
b78796d0c1 | ||
|
|
da1e9db2c0 | ||
|
|
6beb6aa05b | ||
|
|
6ea7777a3a | ||
|
|
f97191e241 | ||
|
|
51420dade4 | ||
|
|
cc55c01197 | ||
|
|
86ce464ee3 | ||
|
|
0fa52a75ad | ||
|
|
c91e7dc3b0 | ||
|
|
88034b176c | ||
|
|
efeaff488c | ||
|
|
5df30f5bdd | ||
|
|
cf179c42b8 | ||
|
|
a615f8bf17 | ||
|
|
b38964e814 | ||
|
|
013c9eec58 | ||
|
|
ddbd6eddf7 | ||
|
|
982fd42683 |
+146
-18
@@ -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"
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."));
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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`)
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
|
||||
@@ -86,3 +86,5 @@ namespace R3000A
|
||||
} // namespace R3000A
|
||||
|
||||
extern void Hle_SetElfPath(const char* elfFileName);
|
||||
extern void Hle_ClearElfPath();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user