mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-08-17 03:18:07 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8e0f355fc | ||
|
|
3202fd88d2 | ||
|
|
1c66c904ab | ||
|
|
784e090081 | ||
|
|
2d08d3dc94 | ||
|
|
237b9754c6 | ||
|
|
74bbccdf59 | ||
|
|
062d625901 | ||
|
|
3f30c2bda2 | ||
|
|
0702692746 | ||
|
|
11a218b1aa | ||
|
|
f4acff1321 | ||
|
|
a8ee746c39 | ||
|
|
ddd5fc7bf3 | ||
|
|
22dfe05287 | ||
|
|
fa78e1295a | ||
|
|
4a634ca154 | ||
|
|
bd1f5d0888 | ||
|
|
2f028c5f40 | ||
|
|
56c8843406 | ||
|
|
37c4c596b5 | ||
|
|
7b0bde4f1f | ||
|
|
5c5c7d64a8 | ||
|
|
565189d08c | ||
|
|
682580e318 | ||
|
|
74e3d6470a | ||
|
|
b4e6a715fc | ||
|
|
85f0d44997 |
@@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Validate GameDB
|
||||
env:
|
||||
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
# echo ${{ github.event.pull_request.title }}
|
||||
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Checkout Submodules
|
||||
if: steps.cache-submodules.outputs.cache-hit != 'true'
|
||||
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
# echo ${{ github.event.pull_request.title }}
|
||||
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Checkout Submodules
|
||||
run: git submodule update --init --recursive -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# Docs - https://github.com/mathieudutour/github-tag-action
|
||||
# Workflows cannot trigger other workflows implicitly
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Get Latest DB and Prepare DB File
|
||||
run: |
|
||||
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Checkout Submodules
|
||||
run: git submodule update --init --recursive -j $env:NUMBER_OF_PROCESSORS
|
||||
|
||||
@@ -505,6 +505,8 @@ SCAJ-20079:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
SCAJ-20080:
|
||||
name: "Kaena"
|
||||
region: "NTSC-Unk"
|
||||
@@ -720,6 +722,8 @@ SCAJ-20135:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
memcardFilters:
|
||||
- "SCAJ-20135"
|
||||
- "SLPS-25467"
|
||||
@@ -3861,6 +3865,8 @@ SCKA-20025:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
SCKA-20026:
|
||||
name: "Gungrave O.D."
|
||||
region: "NTSC-K"
|
||||
@@ -3954,6 +3960,8 @@ SCKA-20051:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
memcardFilters:
|
||||
- "SCKA-20051"
|
||||
- "SCKA-20025"
|
||||
@@ -7146,7 +7154,7 @@ SLED-50117:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty [Demo] [Zone of the Enders Bonus Disc]"
|
||||
region: "PAL-E"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLED-50359:
|
||||
name: "Devil May Cry [Demo]"
|
||||
region: "PAL-E"
|
||||
@@ -8126,17 +8134,17 @@ SLES-50383:
|
||||
region: "PAL-M3"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLES-50384:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty"
|
||||
region: "PAL-I"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLES-50385:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty"
|
||||
region: "PAL-S"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLES-50386:
|
||||
name: "Crash Bandicoot - Wrath of Cortex"
|
||||
region: "PAL-M6"
|
||||
@@ -14996,6 +15004,8 @@ SLES-53828:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
SLES-53829:
|
||||
name: "Raiden III"
|
||||
region: "PAL-E"
|
||||
@@ -15132,6 +15142,8 @@ SLES-53903:
|
||||
SLES-53904:
|
||||
name: "DT Racer"
|
||||
region: "PAL-M5"
|
||||
clampModes:
|
||||
vuClampMode: 0 # Fixes black artifacts on tracks
|
||||
SLES-53906:
|
||||
name: "50cent - Bulletproof"
|
||||
region: "PAL-F"
|
||||
@@ -18754,7 +18766,7 @@ SLES-82009:
|
||||
region: "PAL-M5"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLES-82010:
|
||||
name: "Metal Gear Solid 2, Document of"
|
||||
region: "PAL-E"
|
||||
@@ -19635,7 +19647,7 @@ SLKA-35001:
|
||||
region: "NTSC-K"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLKA-35003:
|
||||
name: "Sakura Taisen - Atsuki Chishioni"
|
||||
region: "NTSC-K"
|
||||
@@ -22225,12 +22237,12 @@ SLPM-65077:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty [Premium Package]"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLPM-65078:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLPM-65080:
|
||||
name: "Tokimeki Memorial 3"
|
||||
region: "NTSC-J"
|
||||
@@ -26631,7 +26643,7 @@ SLPM-66503:
|
||||
name: "Metal Gear Solid 2 [Mega Hits]"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLPM-66504:
|
||||
name: "Onimusha 2 [Mega Hits]"
|
||||
region: "NTSC-J"
|
||||
@@ -27575,7 +27587,7 @@ SLPM-66792:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty [20th Anniversary Edition]"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLPM-66794:
|
||||
name: "Metal Gear Solid 3 - Snake Eater [20th Anniversary Edition]"
|
||||
region: "NTSC-J"
|
||||
@@ -28145,7 +28157,7 @@ SLPM-67002:
|
||||
name: "Metal Gear Solid 2 - Substance"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLPM-67003:
|
||||
name: "Sakura Taisen - Atsuki Chishioni"
|
||||
region: "NTSC-J"
|
||||
@@ -30751,6 +30763,8 @@ SLPS-25360:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
SLPS-25361:
|
||||
name: "Smash Court Professional Tournament 2"
|
||||
region: "NTSC-J"
|
||||
@@ -31149,6 +31163,8 @@ SLPS-25467:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
memcardFilters:
|
||||
- "SCAJ-20135"
|
||||
- "SLPS-25467"
|
||||
@@ -32829,6 +32845,8 @@ SLPS-73210:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
SLPS-73211:
|
||||
name: "Summon Night 3 [PlayStation 2 The Best]"
|
||||
region: "NTSC-J"
|
||||
@@ -32987,6 +33005,8 @@ SLPS-73240:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
SLPS-73241:
|
||||
name: "Minna Daisuki Katamari Damacy [PlayStation 2 The Best]"
|
||||
region: "NTSC-J"
|
||||
@@ -32994,6 +33014,8 @@ SLPS-73241:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
memcardFilters:
|
||||
- "SCAJ-20135"
|
||||
- "SLPS-25467"
|
||||
@@ -33623,7 +33645,7 @@ SLUS-20144:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLUS-20145:
|
||||
name: "Ring of Red"
|
||||
region: "NTSC-U"
|
||||
@@ -35338,7 +35360,7 @@ SLUS-20554:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLUS-20555:
|
||||
name: "Reel Fishing 3"
|
||||
region: "NTSC-U"
|
||||
@@ -37314,6 +37336,8 @@ SLUS-21008:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
SLUS-21009:
|
||||
name: "Sega Classics Collection"
|
||||
region: "NTSC-U"
|
||||
@@ -37894,6 +37918,13 @@ SLUS-21151:
|
||||
name: "Disney-Pixar's Cars"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
patches:
|
||||
F2A25D7B:
|
||||
content: |-
|
||||
author=refraction
|
||||
// COP2 Rearrangement. Fixes broken collisions.
|
||||
patch=1,EE,00203dd8,word,484e9000
|
||||
patch=1,EE,00203ddc,word,4bdbd9ff
|
||||
SLUS-21152:
|
||||
name: "Shin Megami Tensei: Digital Devil Saga 2"
|
||||
region: "NTSC-U"
|
||||
@@ -38255,6 +38286,8 @@ SLUS-21230:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes performance and falling through floor and other gameplay.
|
||||
memcardFilters: # Allows import of constellations from Katamari Damacy.
|
||||
- "SLUS-21230"
|
||||
- "SLUS-21008"
|
||||
@@ -41486,7 +41519,7 @@ SLUS-29003:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
- DMABusyHack # Fixes broken half-bottom artifacts.
|
||||
SLUS-29004:
|
||||
name: "Unison & Dead or Alive 2 Hardcore [Demo]"
|
||||
region: "NTSC-U"
|
||||
|
||||
@@ -877,7 +877,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,
|
||||
030000006f0e00000302000025040000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000006f0e00000702000003060000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000791d00000103000009010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||
03000000791d00000103000009010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||
050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,
|
||||
050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,
|
||||
030000005e0400008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
@@ -967,6 +967,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
05000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,
|
||||
05000000503200000210000045010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,
|
||||
05000000503200000210000046010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,
|
||||
05000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,x:b2,y:b3,back:b9,guide:b10,start:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b6,rightstick:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:+a5,righttrigger:-a4,platform:Linux,
|
||||
03000000120c00000500000010010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,
|
||||
03000000ef0500000300000000010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,
|
||||
03000000c62400001b89000011010000,BDA MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
@@ -988,6 +989,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000004f04000004b3000010010000,Dual Power 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
|
||||
030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||
03000000242f00009100000000010000,EasySMX ESM-9101,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
|
||||
030000006e0500000320000010010000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,
|
||||
030000006e0500000720000010010000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux,
|
||||
03000000430b00000300000000010000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||
@@ -1144,7 +1146,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
||||
050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux,
|
||||
050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
|
||||
05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,
|
||||
03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||
03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
|
||||
@@ -1322,7 +1324,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000006f0e00000302000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000006f0e00000702000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||
05000000ac0500003232000001000000,VR Box Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||
03000000791d00000103000010010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||
03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||
0000000058626f782033363020576900,Xbox 360 Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
|
||||
030000005e0400001907000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
|
||||
@@ -149,10 +149,10 @@ namespace GL
|
||||
const char* gl_renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
|
||||
const char* gl_version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||
const char* gl_shading_language_version = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
Console.WriteLn(Color_Magenta, "GL_VENDOR: %s", gl_vendor);
|
||||
Console.WriteLn(Color_Magenta, "GL_RENDERER: %s", gl_renderer);
|
||||
Console.WriteLn(Color_Magenta, "GL_VERSION: %s", gl_version);
|
||||
Console.WriteLn(Color_Magenta, "GL_SHADING_LANGUAGE_VERSION: %s", gl_shading_language_version);
|
||||
DevCon.WriteLn(Color_Magenta, "GL_VENDOR: %s", gl_vendor);
|
||||
DevCon.WriteLn(Color_Magenta, "GL_RENDERER: %s", gl_renderer);
|
||||
DevCon.WriteLn(Color_Magenta, "GL_VERSION: %s", gl_version);
|
||||
DevCon.WriteLn(Color_Magenta, "GL_SHADING_LANGUAGE_VERSION: %s", gl_shading_language_version);
|
||||
|
||||
DisableBrokenExtensions(gl_vendor, gl_renderer);
|
||||
|
||||
|
||||
+14
-37
@@ -59,41 +59,6 @@ namespace Vulkan
|
||||
|
||||
Context::~Context() = default;
|
||||
|
||||
bool Context::CheckValidationLayerAvailablility()
|
||||
{
|
||||
u32 extension_count = 0;
|
||||
VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkEnumerateInstanceExtensionProperties failed: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<VkExtensionProperties> extension_list(extension_count);
|
||||
res = vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_list.data());
|
||||
pxAssert(res == VK_SUCCESS);
|
||||
|
||||
u32 layer_count = 0;
|
||||
res = vkEnumerateInstanceLayerProperties(&layer_count, nullptr);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkEnumerateInstanceExtensionProperties failed: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<VkLayerProperties> layer_list(layer_count);
|
||||
res = vkEnumerateInstanceLayerProperties(&layer_count, layer_list.data());
|
||||
pxAssert(res == VK_SUCCESS);
|
||||
|
||||
// Check for both VK_EXT_debug_utils and VK_LAYER_LUNARG_standard_validation
|
||||
return (std::find_if(extension_list.begin(), extension_list.end(),
|
||||
[](const auto& it) { return strcmp(it.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0; }) !=
|
||||
extension_list.end() &&
|
||||
std::find_if(layer_list.begin(), layer_list.end(), [](const auto& it) {
|
||||
return strcmp(it.layerName, "VK_LAYER_KHRONOS_validation") == 0;
|
||||
}) != layer_list.end());
|
||||
}
|
||||
|
||||
VkInstance Context::CreateVulkanInstance(
|
||||
const WindowInfo* wi, bool enable_debug_utils, bool enable_validation_layer)
|
||||
{
|
||||
@@ -306,8 +271,20 @@ namespace Vulkan
|
||||
VkInstance instance = CreateVulkanInstance(wi, enable_debug_utils, enable_validation_layer);
|
||||
if (instance == VK_NULL_HANDLE)
|
||||
{
|
||||
Vulkan::UnloadVulkanLibrary();
|
||||
return false;
|
||||
if (enable_debug_utils || enable_validation_layer)
|
||||
{
|
||||
// Try again without the validation layer.
|
||||
enable_debug_utils = false;
|
||||
enable_validation_layer = false;
|
||||
instance = CreateVulkanInstance(wi, enable_debug_utils, enable_validation_layer);
|
||||
if (instance == VK_NULL_HANDLE)
|
||||
{
|
||||
Vulkan::UnloadVulkanLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
Console.Error("Vulkan validation/debug layers requested but are unavailable. Creating non-debug device.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!Vulkan::LoadVulkanInstanceFunctions(instance))
|
||||
|
||||
@@ -55,9 +55,6 @@ namespace Vulkan
|
||||
|
||||
~Context();
|
||||
|
||||
// Determines if the Vulkan validation layer is available on the system.
|
||||
static bool CheckValidationLayerAvailablility();
|
||||
|
||||
// Helper method to create a Vulkan instance.
|
||||
static VkInstance CreateVulkanInstance(
|
||||
const WindowInfo* wi, bool enable_debug_utils, bool enable_validation_layer);
|
||||
|
||||
@@ -49,12 +49,7 @@ DisplayWidget::~DisplayWidget() = default;
|
||||
|
||||
qreal DisplayWidget::devicePixelRatioFromScreen() const
|
||||
{
|
||||
QScreen* screen_for_ratio;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
screen_for_ratio = windowHandle()->screen();
|
||||
#else
|
||||
screen_for_ratio = screen();
|
||||
#endif
|
||||
const QScreen* screen_for_ratio = screen();
|
||||
if (!screen_for_ratio)
|
||||
screen_for_ratio = QGuiApplication::primaryScreen();
|
||||
|
||||
|
||||
+34
-6
@@ -16,6 +16,7 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
@@ -137,12 +138,16 @@ void EmuThread::setVMPaused(bool paused)
|
||||
VMManager::SetPaused(paused);
|
||||
}
|
||||
|
||||
void EmuThread::shutdownVM(bool allow_save_to_state /* = true */, bool blocking /* = false */)
|
||||
bool EmuThread::shutdownVM(bool allow_confirm /* = true */, bool allow_save_to_state /* = true */, bool blocking /* = false */)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "shutdownVM", Qt::QueuedConnection, Q_ARG(bool, allow_save_to_state),
|
||||
Q_ARG(bool, blocking));
|
||||
// only confirm on UI thread because we need to display a msgbox
|
||||
if (allow_confirm && g_main_window && !g_main_window->confirmShutdown())
|
||||
return false;
|
||||
|
||||
QMetaObject::invokeMethod(this, "shutdownVM", Qt::QueuedConnection, Q_ARG(bool, false),
|
||||
Q_ARG(bool, allow_save_to_state), Q_ARG(bool, blocking));
|
||||
|
||||
if (blocking)
|
||||
{
|
||||
@@ -151,16 +156,17 @@ void EmuThread::shutdownVM(bool allow_save_to_state /* = true */, bool blocking
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
|
||||
}
|
||||
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
const VMState state = VMManager::GetState();
|
||||
if (state == VMState::Paused)
|
||||
m_event_loop->quit();
|
||||
else if (state != VMState::Running)
|
||||
return;
|
||||
return true;
|
||||
|
||||
VMManager::SetState(VMState::Stopping);
|
||||
return true;
|
||||
}
|
||||
|
||||
void EmuThread::loadState(const QString& filename)
|
||||
@@ -285,6 +291,9 @@ void EmuThread::executeVM()
|
||||
destroyVM();
|
||||
m_event_loop->processEvents(QEventLoop::AllEvents);
|
||||
return;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -365,6 +374,22 @@ void EmuThread::applySettings()
|
||||
VMManager::ApplySettings();
|
||||
}
|
||||
|
||||
void EmuThread::reloadGameSettings()
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::reloadGameSettings, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
// this will skip applying settings when they're not active
|
||||
if (VMManager::ReloadGameSettings())
|
||||
{
|
||||
// none of these settings below are per-game.. for now. but in case they are in the future.
|
||||
checkForSettingChanges();
|
||||
}
|
||||
}
|
||||
|
||||
void EmuThread::checkForSettingChanges()
|
||||
{
|
||||
if (VMManager::HasValidVM())
|
||||
@@ -607,6 +632,9 @@ HostDisplay* EmuThread::acquireHostDisplay(HostDisplay::RenderAPI api)
|
||||
|
||||
g_gs_window_info = s_host_display->GetWindowInfo();
|
||||
|
||||
Console.WriteLn(Color_StrongGreen, "%s Graphics Driver Info:", HostDisplay::RenderAPIToString(s_host_display->GetRenderAPI()));
|
||||
Console.Indent().WriteLn(s_host_display->GetDriverInfo());
|
||||
|
||||
return s_host_display.get();
|
||||
}
|
||||
|
||||
@@ -738,7 +766,7 @@ ScopedVMPause::ScopedVMPause(bool was_paused)
|
||||
|
||||
ScopedVMPause::~ScopedVMPause()
|
||||
{
|
||||
if (m_was_paused)
|
||||
if (!m_was_paused)
|
||||
g_emu_thread->setVMPaused(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ public Q_SLOTS:
|
||||
void startVM(std::shared_ptr<VMBootParameters> boot_params);
|
||||
void resetVM();
|
||||
void setVMPaused(bool paused);
|
||||
void shutdownVM(bool allow_save_to_state = true, bool blocking = false);
|
||||
bool shutdownVM(bool allow_confirm = true, bool allow_save_to_state = true, bool blocking = false);
|
||||
void loadState(const QString& filename);
|
||||
void loadStateFromSlot(qint32 slot);
|
||||
void saveState(const QString& filename);
|
||||
@@ -65,6 +65,7 @@ public Q_SLOTS:
|
||||
void toggleFullscreen();
|
||||
void setFullscreen(bool fullscreen);
|
||||
void applySettings();
|
||||
void reloadGameSettings();
|
||||
void toggleSoftwareRendering();
|
||||
void switchRenderer(GSRendererType renderer);
|
||||
void changeDisc(const QString& path);
|
||||
|
||||
+1
-5
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <cstdlib>
|
||||
#include <csignal>
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "EmuThread.h"
|
||||
@@ -184,13 +185,9 @@ static bool ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr<VMBo
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
std::shared_ptr<VMBootParameters> autoboot;
|
||||
@@ -216,7 +213,6 @@ int main(int argc, char* argv[])
|
||||
|
||||
const int result = app.exec();
|
||||
|
||||
EmuThread::stop();
|
||||
QtHost::Shutdown();
|
||||
return result;
|
||||
}
|
||||
|
||||
+51
-21
@@ -16,6 +16,7 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtGui/QCloseEvent>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QProgressBar>
|
||||
@@ -39,6 +40,7 @@
|
||||
#include "Settings/ControllerSettingsDialog.h"
|
||||
#include "Settings/GameListSettingsWidget.h"
|
||||
#include "Settings/InterfaceSettingsWidget.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
static constexpr char DISC_IMAGE_FILTER[] =
|
||||
@@ -170,6 +172,21 @@ void MainWindow::connectSignals()
|
||||
});
|
||||
connect(m_ui.actionGridViewRefreshCovers, &QAction::triggered, m_game_list_widget, &GameListWidget::refreshGridCovers);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableSystemConsole, "Logging", "EnableSystemConsole", false);
|
||||
connect(m_ui.actionEnableSystemConsole, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
#ifndef PCSX2_DEVBUILD
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableVerboseLogging, "Logging", "EnableVerbose", false);
|
||||
connect(m_ui.actionEnableVerboseLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
#else
|
||||
// Dev builds always have verbose logging.
|
||||
m_ui.actionEnableVerboseLogging->setChecked(true);
|
||||
m_ui.actionEnableVerboseLogging->setEnabled(false);
|
||||
#endif
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableEEConsoleLogging, "Logging", "EnableEEConsole", false);
|
||||
connect(m_ui.actionEnableEEConsoleLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableIOPConsoleLogging, "Logging", "EnableIOPConsole", false);
|
||||
connect(m_ui.actionEnableIOPConsoleLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
|
||||
// These need to be queued connections to stop crashing due to menus opening/closing and switching focus.
|
||||
connect(m_game_list_widget, &GameListWidget::refreshProgress, this, &MainWindow::onGameListRefreshProgress);
|
||||
connect(m_game_list_widget, &GameListWidget::refreshComplete, this, &MainWindow::onGameListRefreshComplete);
|
||||
@@ -213,7 +230,7 @@ void MainWindow::connectVMThreadSignals(EmuThread* thread)
|
||||
void MainWindow::recreate()
|
||||
{
|
||||
if (m_vm_valid)
|
||||
g_emu_thread->shutdownVM(true, true);
|
||||
g_emu_thread->shutdownVM(false, true, true);
|
||||
|
||||
close();
|
||||
g_main_window = nullptr;
|
||||
@@ -241,11 +258,8 @@ void MainWindow::setStyleFromSettings()
|
||||
// Alternative white theme.
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
|
||||
const QColor lighterGray(75, 75, 75);
|
||||
const QColor darkGray(53, 53, 53);
|
||||
const QColor gray(128, 128, 128);
|
||||
const QColor black(25, 25, 25);
|
||||
const QColor teal(0, 128, 128);
|
||||
const QColor teal(0, 128, 128);
|
||||
const QColor tameTeal(160, 190, 185);
|
||||
const QColor grayBlue(160, 180, 190);
|
||||
|
||||
@@ -279,18 +293,12 @@ void MainWindow::setStyleFromSettings()
|
||||
// Alternative light theme.
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
|
||||
const QColor lighterGray(75, 75, 75);
|
||||
const QColor gray(150, 150, 150);
|
||||
const QColor black(25, 25, 25);
|
||||
const QColor darkPink(180, 80, 200);
|
||||
const QColor pink(255, 174, 201);
|
||||
const QColor brightPink(255, 230, 255);
|
||||
const QColor congoPink(255, 127, 121);
|
||||
const QColor yellow(255, 235, 180);
|
||||
const QColor darkGreen(161, 240, 183);
|
||||
const QColor green(221, 239, 226);
|
||||
const QColor blue(221, 225, 239);
|
||||
const QColor darkBlue(100, 95, 250);
|
||||
|
||||
QPalette standardPalette;
|
||||
standardPalette.setColor(QPalette::Window, pink);
|
||||
@@ -322,13 +330,10 @@ void MainWindow::setStyleFromSettings()
|
||||
// Alternative light theme.
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
|
||||
const QColor lighterGray(75, 75, 75);
|
||||
const QColor gray(128, 128, 128);
|
||||
const QColor black(25, 25, 25);
|
||||
const QColor darkBlue(73, 97, 177);
|
||||
const QColor blue(106, 156, 255);
|
||||
const QColor lightBlue(130, 155, 241);
|
||||
const QColor brightBlue(164, 184, 255);
|
||||
|
||||
QPalette standardPalette;
|
||||
standardPalette.setColor(QPalette::Window, lightBlue);
|
||||
@@ -394,7 +399,6 @@ void MainWindow::setStyleFromSettings()
|
||||
// adapted from https://gist.github.com/QuantumCD/6245215
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
|
||||
const QColor lighterGray(75, 75, 75);
|
||||
const QColor darkGray(53, 53, 53);
|
||||
const QColor gray(128, 128, 128);
|
||||
const QColor black(25, 25, 25);
|
||||
@@ -431,9 +435,6 @@ void MainWindow::setStyleFromSettings()
|
||||
// Alternative dark theme.
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
|
||||
const QColor lighterGray(75, 75, 75);
|
||||
const QColor gray(128, 128, 128);
|
||||
const QColor black(25, 25, 25);
|
||||
const QColor darkRed(80, 45, 69);
|
||||
const QColor purplishRed(120, 45, 69);
|
||||
const QColor brightRed(200, 45, 69);
|
||||
@@ -640,6 +641,25 @@ void MainWindow::invalidateSaveStateCache() { m_save_states_invalidated = true;
|
||||
|
||||
void MainWindow::reportError(const QString& title, const QString& message) { QMessageBox::critical(this, title, message); }
|
||||
|
||||
bool MainWindow::confirmShutdown()
|
||||
{
|
||||
if (!m_vm_valid || !QtHost::GetBaseBoolSettingValue("UI", "ConfirmShutdown", true))
|
||||
return true;
|
||||
|
||||
ScopedVMPause pauser(m_vm_paused);
|
||||
|
||||
return (QMessageBox::question(g_main_window, tr("Confirm Shutdown"),
|
||||
tr("Are you sure you want to shut down the virtual machine?\n\nAll unsaved progress will be lost.")) == QMessageBox::Yes);
|
||||
}
|
||||
|
||||
void MainWindow::requestExit()
|
||||
{
|
||||
if (!g_emu_thread->shutdownVM(true, true, false))
|
||||
return;
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
void Host::InvalidateSaveStateCache() { QMetaObject::invokeMethod(g_main_window, &MainWindow::invalidateSaveStateCache, Qt::QueuedConnection); }
|
||||
|
||||
void MainWindow::onGameListRefreshProgress(const QString& status, int current, int total)
|
||||
@@ -692,7 +712,7 @@ void MainWindow::onGameListEntryContextMenuRequested(const QPoint& point)
|
||||
QAction* action = menu.addAction(tr("Properties..."));
|
||||
action->setEnabled(!entry->serial.empty());
|
||||
if (action->isEnabled())
|
||||
connect(action, &QAction::triggered, [this, entry]() { SettingsDialog::openGamePropertiesDialog(entry, entry->crc); });
|
||||
connect(action, &QAction::triggered, [entry]() { SettingsDialog::openGamePropertiesDialog(entry, entry->crc); });
|
||||
|
||||
action = menu.addAction(tr("Open Containing Directory..."));
|
||||
connect(action, &QAction::triggered, [this, entry]() {
|
||||
@@ -899,6 +919,11 @@ void MainWindow::onThemeChangedFromSettings()
|
||||
g_main_window->doSettings();
|
||||
}
|
||||
|
||||
void MainWindow::onLoggingOptionChanged()
|
||||
{
|
||||
QtHost::UpdateLogging();
|
||||
}
|
||||
|
||||
void MainWindow::onVMStarting()
|
||||
{
|
||||
m_vm_valid = true;
|
||||
@@ -961,7 +986,12 @@ void MainWindow::onGameChanged(const QString& path, const QString& serial, const
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
g_emu_thread->shutdownVM(true, true);
|
||||
if (!g_emu_thread->shutdownVM(true, true, true))
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
saveStateToConfig();
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
@@ -1461,7 +1491,7 @@ void MainWindow::populateSaveStateMenu(QMenu* menu, const QString& serial, quint
|
||||
timestamp = tr("Empty");
|
||||
|
||||
QString title(tr("Save Slot %1 (%2)").arg(i).arg(timestamp));
|
||||
connect(menu->addAction(title), &QAction::triggered, [this, i]() { g_emu_thread->saveStateToSlot(i); });
|
||||
connect(menu->addAction(title), &QAction::triggered, [i]() { g_emu_thread->saveStateToSlot(i); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ public Q_SLOTS:
|
||||
void refreshGameList(bool invalidate_cache);
|
||||
void invalidateSaveStateCache();
|
||||
void reportError(const QString& title, const QString& message);
|
||||
bool confirmShutdown();
|
||||
void requestExit();
|
||||
|
||||
private Q_SLOTS:
|
||||
DisplayWidget* createDisplay(bool fullscreen, bool render_to_main);
|
||||
@@ -92,6 +94,7 @@ private Q_SLOTS:
|
||||
void onToolsOpenDataDirectoryTriggered();
|
||||
void onThemeChanged();
|
||||
void onThemeChangedFromSettings();
|
||||
void onLoggingOptionChanged();
|
||||
|
||||
void onVMStarting();
|
||||
void onVMStarted();
|
||||
@@ -104,7 +107,7 @@ private Q_SLOTS:
|
||||
void recreate();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* event);
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
|
||||
private:
|
||||
enum : s32
|
||||
|
||||
+170
-102
@@ -45,7 +45,8 @@
|
||||
<string>Change Disc</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="dvd-line"/>
|
||||
<iconset theme="dvd-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<actiongroup name="actionGroupChangeDiscSubImages"/>
|
||||
<addaction name="actionChangeDiscFromFile"/>
|
||||
@@ -59,7 +60,8 @@
|
||||
<string>Cheats</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="flask-line"/>
|
||||
<iconset theme="flask-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuLoadState">
|
||||
@@ -67,7 +69,8 @@
|
||||
<string>Load State</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-open-line"/>
|
||||
<iconset theme="folder-open-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuSaveState">
|
||||
@@ -75,7 +78,8 @@
|
||||
<string>Save State</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="save-3-line"/>
|
||||
<iconset theme="save-3-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="actionStartFile"/>
|
||||
@@ -141,6 +145,11 @@
|
||||
<addaction name="menuDebugSwitchRenderer"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionReloadPatches"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionEnableSystemConsole"/>
|
||||
<addaction name="actionEnableVerboseLogging"/>
|
||||
<addaction name="actionEnableEEConsoleLogging"/>
|
||||
<addaction name="actionEnableIOPConsoleLogging"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_View">
|
||||
<property name="title">
|
||||
@@ -151,7 +160,8 @@
|
||||
<string>&Window Size</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="window-2-line"/>
|
||||
<iconset theme="window-2-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="actionViewToolbar"/>
|
||||
@@ -185,6 +195,9 @@
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="visible">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Toolbar</string>
|
||||
</property>
|
||||
@@ -203,9 +216,6 @@
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<addaction name="actionStartFile"/>
|
||||
<addaction name="actionStartDisc"/>
|
||||
<addaction name="actionStartBios"/>
|
||||
@@ -227,143 +237,160 @@
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
<action name="actionStartFile">
|
||||
<property name="icon">
|
||||
<iconset theme="file-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Start &File...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="file-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionStartDisc">
|
||||
<property name="icon">
|
||||
<iconset theme="disc-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Start &Disc...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="disc-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionStartBios">
|
||||
<property name="icon">
|
||||
<iconset theme="hard-drive-2-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Start &BIOS</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="hard-drive-2-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionScanForNewGames">
|
||||
<property name="icon">
|
||||
<iconset theme="file-search-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Scan For New Games</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="file-search-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRescanAllGames">
|
||||
<property name="icon">
|
||||
<iconset theme="refresh-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Rescan All Games</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="refresh-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPowerOff">
|
||||
<property name="icon">
|
||||
<iconset theme="shut-down-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Shut &Down</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="shut-down-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionReset">
|
||||
<property name="icon">
|
||||
<iconset theme="restart-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Reset</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="restart-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPause">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="pause-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Pause</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="pause-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionLoadState">
|
||||
<property name="icon">
|
||||
<iconset theme="folder-open-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Load State</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-open-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveState">
|
||||
<property name="icon">
|
||||
<iconset theme="save-3-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Save State</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="save-3-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExit">
|
||||
<property name="icon">
|
||||
<iconset theme="door-open-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>E&xit</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="door-open-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionBIOSSettings">
|
||||
<property name="icon">
|
||||
<iconset theme="hard-drive-2-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&BIOS</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="hard-drive-2-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSystemSettings">
|
||||
<property name="icon">
|
||||
<iconset theme="artboard-2-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>System</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="artboard-2-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEmulationSettings">
|
||||
<property name="icon">
|
||||
<iconset theme="dashboard-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Emulation</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="dashboard-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionControllerSettings">
|
||||
<property name="icon">
|
||||
<iconset theme="gamepad-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Controllers</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="gamepad-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHotkeySettings">
|
||||
<property name="icon">
|
||||
<iconset theme="keyboard-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Hotkeys</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="keyboard-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGraphicsSettings">
|
||||
<property name="icon">
|
||||
<iconset theme="brush-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Graphics</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="brush-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPostProcessingSettings">
|
||||
<property name="text">
|
||||
@@ -371,12 +398,13 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionFullscreen">
|
||||
<property name="icon">
|
||||
<iconset theme="fullscreen-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fullscreen</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="fullscreen-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionResolution_Scale">
|
||||
<property name="text">
|
||||
@@ -400,7 +428,8 @@
|
||||
</action>
|
||||
<action name="actionCheckForUpdates">
|
||||
<property name="icon">
|
||||
<iconset theme="download-2-line"/>
|
||||
<iconset theme="download-2-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Check for &Updates...</string>
|
||||
@@ -421,60 +450,67 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionChangeDisc">
|
||||
<property name="icon">
|
||||
<iconset theme="dvd-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Change Disc...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="dvd-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCheats">
|
||||
<property name="icon">
|
||||
<iconset theme="flask-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cheats...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="flask-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAudioSettings">
|
||||
<property name="icon">
|
||||
<iconset theme="volume-up-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Audio</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="volume-up-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGameListSettings">
|
||||
<property name="icon">
|
||||
<iconset theme="folder-settings-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Game List</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-settings-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionInterfaceSettings">
|
||||
<property name="icon">
|
||||
<iconset theme="settings-3-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Interface</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="settings-3-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAddGameDirectory">
|
||||
<property name="icon">
|
||||
<iconset theme="folder-add-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add Game Directory...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-add-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSettings">
|
||||
<property name="icon">
|
||||
<iconset theme="settings-3-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Settings...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="settings-3-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionChangeDiscFromFile">
|
||||
<property name="text">
|
||||
@@ -502,20 +538,22 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionScreenshot">
|
||||
<property name="icon">
|
||||
<iconset theme="screenshot-2-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Screenshot</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="screenshot-2-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMemoryCardSettings">
|
||||
<property name="icon">
|
||||
<iconset theme="sd-card-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Memory Cards</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="sd-card-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewToolbar">
|
||||
<property name="checkable">
|
||||
@@ -551,42 +589,46 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewGameList">
|
||||
<property name="icon">
|
||||
<iconset theme="list-check">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Game &List</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="list-check"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewSystemDisplay">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="tv-2-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>System &Display</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="tv-2-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewGameProperties">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="file-settings-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Game &Properties</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="file-settings-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewGameGrid">
|
||||
<property name="icon">
|
||||
<iconset theme="function-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Game &Grid</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="function-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGridViewShowTitles">
|
||||
<property name="checkable">
|
||||
@@ -640,6 +682,32 @@
|
||||
<string>Reload Cheats/Patches</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnableSystemConsole">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable System Console</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnableVerboseLogging">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Verbose Logging</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnableEEConsoleLogging">
|
||||
<property name="text">
|
||||
<string>Enable EE Console Logging</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnableIOPConsoleLogging">
|
||||
<property name="text">
|
||||
<string>Enable IOP Console Logging</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources/resources.qrc"/>
|
||||
|
||||
+92
-22
@@ -15,6 +15,15 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <csignal>
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "common/RedtapeWindows.h"
|
||||
#endif
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/FileSystem.h"
|
||||
@@ -26,9 +35,6 @@
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#include "EmuThread.h"
|
||||
#include "GameList/GameListWidget.h"
|
||||
#include "MainWindow.h"
|
||||
@@ -42,11 +48,15 @@ static constexpr u32 SETTINGS_SAVE_DELAY = 1000;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Local function declarations
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
namespace QtHost {
|
||||
static void InitializeWxRubbish();
|
||||
static bool InitializeConfig();
|
||||
static void HookSignals();
|
||||
static bool SetCriticalFolders();
|
||||
static void SetDefaultConfig();
|
||||
static void QueueSettingsSave();
|
||||
static void SaveSettings();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Local variable declarations
|
||||
@@ -72,12 +82,21 @@ bool QtHost::Initialize()
|
||||
return false;
|
||||
}
|
||||
|
||||
HookSignals();
|
||||
return true;
|
||||
}
|
||||
|
||||
void QtHost::Shutdown() {}
|
||||
void QtHost::Shutdown()
|
||||
{
|
||||
EmuThread::stop();
|
||||
if (g_main_window)
|
||||
{
|
||||
g_main_window->close();
|
||||
delete g_main_window;
|
||||
}
|
||||
}
|
||||
|
||||
static bool SetCriticalFolders()
|
||||
bool QtHost::SetCriticalFolders()
|
||||
{
|
||||
std::string program_path(FileSystem::GetProgramPath());
|
||||
EmuFolders::AppRoot = wxDirName(wxFileName(StringUtil::UTF8StringToWxString(program_path)));
|
||||
@@ -110,7 +129,7 @@ void QtHost::UpdateFolders()
|
||||
EmuFolders::EnsureFoldersExist();
|
||||
}
|
||||
|
||||
bool InitializeConfig()
|
||||
bool QtHost::InitializeConfig()
|
||||
{
|
||||
if (!SetCriticalFolders())
|
||||
return false;
|
||||
@@ -138,7 +157,7 @@ bool InitializeConfig()
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetDefaultConfig()
|
||||
void QtHost::SetDefaultConfig()
|
||||
{
|
||||
EmuConfig = Pcsx2Config();
|
||||
EmuFolders::SetDefaults();
|
||||
@@ -247,7 +266,7 @@ void QtHost::RemoveBaseSettingValue(const char* section, const char* key)
|
||||
QueueSettingsSave();
|
||||
}
|
||||
|
||||
void SaveSettings()
|
||||
void QtHost::SaveSettings()
|
||||
{
|
||||
pxAssertRel(!g_emu_thread->isOnEmuThread(), "Saving should happen on the UI thread.");
|
||||
|
||||
@@ -261,7 +280,7 @@ void SaveSettings()
|
||||
s_settings_save_timer.release();
|
||||
}
|
||||
|
||||
void QueueSettingsSave()
|
||||
void QtHost::QueueSettingsSave()
|
||||
{
|
||||
if (s_settings_save_timer)
|
||||
return;
|
||||
@@ -338,9 +357,38 @@ void PatchesVerboseReset()
|
||||
// FIXME
|
||||
}
|
||||
|
||||
static void SignalHandler(int signal)
|
||||
{
|
||||
// First try the normal (graceful) shutdown/exit.
|
||||
static bool graceful_shutdown_attempted = false;
|
||||
if (!graceful_shutdown_attempted && g_main_window)
|
||||
{
|
||||
std::fprintf(stderr, "Received CTRL+C, attempting graceful shutdown. Press CTRL+C again to force.\n");
|
||||
graceful_shutdown_attempted = true;
|
||||
|
||||
// This could be a bit risky invoking from a signal handler... hopefully it's okay.
|
||||
QMetaObject::invokeMethod(g_main_window, &MainWindow::requestExit, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
std::signal(signal, SIG_DFL);
|
||||
|
||||
// MacOS is missing std::quick_exit() despite it being C++11...
|
||||
#ifndef __APPLE__
|
||||
std::quick_exit(1);
|
||||
#else
|
||||
_Exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void QtHost::HookSignals()
|
||||
{
|
||||
std::signal(SIGINT, SignalHandler);
|
||||
std::signal(SIGTERM, SignalHandler);
|
||||
}
|
||||
|
||||
// Replacement for Console so we actually get output to our console window on Windows.
|
||||
#ifdef _WIN32
|
||||
#include "common/RedtapeWindows.h"
|
||||
|
||||
static bool s_debugger_attached = false;
|
||||
static bool s_console_handle_set = false;
|
||||
@@ -433,24 +481,32 @@ static const IConsoleWriter ConsoleWriter_WinQt =
|
||||
ConsoleWinQt_Newline,
|
||||
ConsoleWinQt_SetTitle,
|
||||
};
|
||||
|
||||
static BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType)
|
||||
{
|
||||
Console.WriteLn("Handler %u", dwCtrlType);
|
||||
if (dwCtrlType != CTRL_C_EVENT)
|
||||
return FALSE;
|
||||
|
||||
SignalHandler(SIGTERM);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void QtHost::UpdateLogging()
|
||||
{
|
||||
// TODO: Make this an actual option.
|
||||
bool console_logging_enabled = false;
|
||||
const bool system_console_enabled = QtHost::GetBaseBoolSettingValue("Logging", "EnableSystemConsole", false);
|
||||
|
||||
#if defined(_DEBUG) || defined(PCSX2_DEVBUILD)
|
||||
console_logging_enabled = true;
|
||||
#endif
|
||||
const bool any_logging_sinks = system_console_enabled;
|
||||
DevConWriterEnabled = any_logging_sinks && QtHost::GetBaseBoolSettingValue("Logging", "EnableVerbose", false);
|
||||
SysConsole.eeConsole.Enabled = any_logging_sinks && QtHost::GetBaseBoolSettingValue("Logging", "EnableEEConsole", true);
|
||||
SysConsole.iopConsole.Enabled = any_logging_sinks && QtHost::GetBaseBoolSettingValue("Logging", "EnableIOPConsole", true);
|
||||
|
||||
DevConWriterEnabled = console_logging_enabled;
|
||||
SysConsole.eeConsole.Enabled = console_logging_enabled;
|
||||
SysConsole.iopConsole.Enabled = console_logging_enabled;
|
||||
|
||||
if (console_logging_enabled)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (system_console_enabled)
|
||||
{
|
||||
s_debugger_attached = IsDebuggerPresent();
|
||||
if (!s_console_handle_set)
|
||||
{
|
||||
@@ -471,17 +527,31 @@ void QtHost::UpdateLogging()
|
||||
}
|
||||
|
||||
if (!s_console_handle && !s_debugger_attached)
|
||||
{
|
||||
Console_SetActiveHandler(ConsoleWriter_Null);
|
||||
SetConsoleCtrlHandler(ConsoleCtrlHandler, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console_SetActiveHandler(ConsoleWriter_WinQt);
|
||||
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console_SetActiveHandler(ConsoleWriter_Null);
|
||||
SetConsoleCtrlHandler(ConsoleCtrlHandler, FALSE);
|
||||
}
|
||||
#else
|
||||
if (system_console_enabled)
|
||||
{
|
||||
Console_SetActiveHandler(ConsoleWriter_Stdout);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Console_SetActiveHandler(ConsoleWriter_Null);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#include <wx/module.h>
|
||||
@@ -491,7 +561,7 @@ extern "C" HINSTANCE wxGetInstance();
|
||||
extern void wxSetInstance(HINSTANCE hInst);
|
||||
#endif
|
||||
|
||||
void InitializeWxRubbish()
|
||||
void QtHost::InitializeWxRubbish()
|
||||
{
|
||||
wxLog::DoCreateOnDemand();
|
||||
wxLog::GetActiveTarget();
|
||||
|
||||
@@ -20,11 +20,7 @@
|
||||
#include <QtGui/QDesktopServices>
|
||||
#include <QtGui/QKeyEvent>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QtGui/QAction>
|
||||
#else
|
||||
#include <QtWidgets/QAction>
|
||||
#endif
|
||||
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QDialog>
|
||||
|
||||
@@ -14,16 +14,12 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QtCore/QtCore>
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QtCore/QtCore>
|
||||
#include <QtGui/QAction>
|
||||
#else
|
||||
#include <QtWidgets/QAction>
|
||||
#endif
|
||||
|
||||
#include <QtWidgets/QCheckBox>
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
@@ -124,7 +120,7 @@ namespace SettingWidgetBinder
|
||||
}
|
||||
static std::optional<int> getNullableIntValue(const QComboBox* widget)
|
||||
{
|
||||
return isNullValue(widget) ? std::nullopt : std::optional<int>(widget->currentIndex() + 1);
|
||||
return isNullValue(widget) ? std::nullopt : std::optional<int>(widget->currentIndex() - 1);
|
||||
}
|
||||
static void setNullableIntValue(QComboBox* widget, std::optional<int> value)
|
||||
{
|
||||
@@ -152,13 +148,8 @@ namespace SettingWidgetBinder
|
||||
static QString getStringValue(const QComboBox* widget)
|
||||
{
|
||||
const QVariant currentData(widget->currentData());
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
if (currentData.type() == QVariant::String)
|
||||
return currentData.toString();
|
||||
#else
|
||||
if (currentData.metaType().id() == QMetaType::QString)
|
||||
return currentData.toString();
|
||||
#endif
|
||||
|
||||
return widget->currentText();
|
||||
}
|
||||
@@ -408,21 +399,21 @@ namespace SettingWidgetBinder
|
||||
else
|
||||
Accessor::setNullableBoolValue(widget, std::nullopt);
|
||||
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section, key]() {
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key)]() {
|
||||
if (std::optional<bool> new_value = Accessor::getNullableBoolValue(widget); new_value.has_value())
|
||||
sif->SetBoolValue(section.c_str(), key.c_str(), new_value.value());
|
||||
else
|
||||
sif->DeleteValue(section.c_str(), key.c_str());
|
||||
|
||||
sif->Save();
|
||||
g_emu_thread->applySettings();
|
||||
g_emu_thread->reloadGameSettings();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Accessor::setBoolValue(widget, value);
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key]() {
|
||||
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() {
|
||||
const bool new_value = Accessor::getBoolValue(widget);
|
||||
QtHost::SetBaseBoolSettingValue(section.c_str(), key.c_str(), new_value);
|
||||
g_emu_thread->applySettings();
|
||||
@@ -448,21 +439,21 @@ namespace SettingWidgetBinder
|
||||
else
|
||||
Accessor::setNullableIntValue(widget, std::nullopt);
|
||||
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section, key]() {
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key), option_offset]() {
|
||||
if (std::optional<int> new_value = Accessor::getNullableIntValue(widget); new_value.has_value())
|
||||
sif->SetIntValue(section.c_str(), key.c_str(), new_value.value());
|
||||
sif->SetIntValue(section.c_str(), key.c_str(), new_value.value() + option_offset);
|
||||
else
|
||||
sif->DeleteValue(section.c_str(), key.c_str());
|
||||
|
||||
sif->Save();
|
||||
g_emu_thread->applySettings();
|
||||
g_emu_thread->reloadGameSettings();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Accessor::setIntValue(widget, static_cast<int>(value));
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key, option_offset]() {
|
||||
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), option_offset]() {
|
||||
const int new_value = Accessor::getIntValue(widget);
|
||||
QtHost::SetBaseIntSettingValue(section.c_str(), key.c_str(), new_value + option_offset);
|
||||
g_emu_thread->applySettings();
|
||||
@@ -487,21 +478,21 @@ namespace SettingWidgetBinder
|
||||
else
|
||||
Accessor::setNullableFloatValue(widget, std::nullopt);
|
||||
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section, key]() {
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key)]() {
|
||||
if (std::optional<float> new_value = Accessor::getNullableFloatValue(widget); new_value.has_value())
|
||||
sif->SetFloatValue(section.c_str(), key.c_str(), new_value.value());
|
||||
else
|
||||
sif->DeleteValue(section.c_str(), key.c_str());
|
||||
|
||||
sif->Save();
|
||||
g_emu_thread->applySettings();
|
||||
g_emu_thread->reloadGameSettings();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Accessor::setFloatValue(widget, value);
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key]() {
|
||||
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() {
|
||||
const float new_value = Accessor::getFloatValue(widget);
|
||||
QtHost::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
|
||||
g_emu_thread->applySettings();
|
||||
@@ -527,21 +518,21 @@ namespace SettingWidgetBinder
|
||||
else
|
||||
Accessor::setNullableIntValue(widget, std::nullopt);
|
||||
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section, key, range]() {
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key), range]() {
|
||||
if (std::optional<int> new_value = Accessor::getNullableIntValue(widget); new_value.has_value())
|
||||
sif->SetFloatValue(section.c_str(), key.c_str(), static_cast<float>(new_value.value()) / range);
|
||||
else
|
||||
sif->DeleteValue(section.c_str(), key.c_str());
|
||||
|
||||
sif->Save();
|
||||
g_emu_thread->applySettings();
|
||||
g_emu_thread->reloadGameSettings();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Accessor::setIntValue(widget, static_cast<int>(value * range));
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key, range]() {
|
||||
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), range]() {
|
||||
const float new_value = (static_cast<float>(Accessor::getIntValue(widget)) / range);
|
||||
QtHost::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
|
||||
g_emu_thread->applySettings();
|
||||
@@ -567,21 +558,21 @@ namespace SettingWidgetBinder
|
||||
else
|
||||
Accessor::setNullableStringValue(widget, std::nullopt);
|
||||
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section, key]() {
|
||||
Accessor::connectValueChanged(widget, [widget, sif, section = std::move(section), key = std::move(key)]() {
|
||||
if (std::optional<QString> new_value = Accessor::getNullableStringValue(widget); new_value.has_value())
|
||||
sif->SetStringValue(section.c_str(), key.c_str(), new_value->toUtf8().constData());
|
||||
else
|
||||
sif->DeleteValue(section.c_str(), key.c_str());
|
||||
|
||||
sif->Save();
|
||||
g_emu_thread->applySettings();
|
||||
g_emu_thread->reloadGameSettings();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Accessor::setStringValue(widget, value);
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key]() {
|
||||
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() {
|
||||
const QString new_value = Accessor::getStringValue(widget);
|
||||
if (!new_value.isEmpty())
|
||||
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.toUtf8().constData());
|
||||
@@ -621,7 +612,7 @@ namespace SettingWidgetBinder
|
||||
Accessor::setNullableIntValue(widget, std::nullopt);
|
||||
}
|
||||
|
||||
Accessor::connectValueChanged(widget, [&]() {
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key), to_string_function]() {
|
||||
if (std::optional<int> new_value = Accessor::getNullableIntValue(widget); new_value.has_value())
|
||||
{
|
||||
const char* string_value = to_string_function(static_cast<DataType>(static_cast<UnderlyingType>(new_value.value())));
|
||||
@@ -633,7 +624,7 @@ namespace SettingWidgetBinder
|
||||
}
|
||||
|
||||
sif->Save();
|
||||
g_emu_thread->applySettings();
|
||||
g_emu_thread->reloadGameSettings();
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -643,7 +634,7 @@ namespace SettingWidgetBinder
|
||||
else
|
||||
Accessor::setIntValue(widget, static_cast<int>(static_cast<UnderlyingType>(default_value)));
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key, to_string_function]() {
|
||||
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), to_string_function]() {
|
||||
const DataType value = static_cast<DataType>(static_cast<UnderlyingType>(Accessor::getIntValue(widget)));
|
||||
const char* string_value = to_string_function(value);
|
||||
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), string_value);
|
||||
@@ -691,21 +682,21 @@ namespace SettingWidgetBinder
|
||||
}
|
||||
Accessor::setNullableIntValue(widget, sif_int_value);
|
||||
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section, key, enum_names]() {
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key), enum_names]() {
|
||||
if (std::optional<int> new_value = Accessor::getNullableIntValue(widget); new_value.has_value())
|
||||
sif->SetStringValue(section.c_str(), key.c_str(), enum_names[new_value.value()]);
|
||||
else
|
||||
sif->DeleteValue(section.c_str(), key.c_str());
|
||||
|
||||
sif->Save();
|
||||
g_emu_thread->applySettings();
|
||||
g_emu_thread->reloadGameSettings();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Accessor::setIntValue(widget, static_cast<int>(enum_index));
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key, enum_names]() {
|
||||
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), enum_names]() {
|
||||
const UnderlyingType value = static_cast<UnderlyingType>(Accessor::getIntValue(widget));
|
||||
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), enum_names[value]);
|
||||
g_emu_thread->applySettings();
|
||||
@@ -753,14 +744,14 @@ namespace SettingWidgetBinder
|
||||
}
|
||||
Accessor::setNullableIntValue(widget, sif_int_value);
|
||||
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section, key, enum_names]() {
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key), enum_names]() {
|
||||
if (std::optional<int> new_value = Accessor::getNullableIntValue(widget); new_value.has_value())
|
||||
sif->SetStringValue(section.c_str(), key.c_str(), enum_names[new_value.value()]);
|
||||
else
|
||||
sif->DeleteValue(section.c_str(), key.c_str());
|
||||
|
||||
sif->Save();
|
||||
g_emu_thread->applySettings();
|
||||
g_emu_thread->reloadGameSettings();
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -768,7 +759,7 @@ namespace SettingWidgetBinder
|
||||
if (enum_index >= 0)
|
||||
Accessor::setIntValue(widget, enum_index);
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key, enum_values]() {
|
||||
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), enum_values]() {
|
||||
const int value = Accessor::getIntValue(widget);
|
||||
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), enum_values[value]);
|
||||
g_emu_thread->applySettings();
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
SettingsInterface* sif = dialog->getSettingsInterface();
|
||||
// SettingsInterface* sif = dialog->getSettingsInterface();
|
||||
|
||||
m_ui.setupUi(this);
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ void GameListSettingsWidget::addPathToTable(const std::string& path, bool recurs
|
||||
m_ui.searchDirectoryList->setCellWidget(row, 1, cb);
|
||||
cb->setChecked(recursive);
|
||||
|
||||
connect(cb, &QCheckBox::stateChanged, [this, item](int state) {
|
||||
connect(cb, &QCheckBox::stateChanged, [item](int state) {
|
||||
const std::string path(item->text().toStdString());
|
||||
if (state == Qt::Checked)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
|
||||
@@ -41,7 +41,7 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsDialog* dialog, QWidget
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.inhibitScreensaver, "UI", "InhibitScreensaver", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.discordPresence, "UI", "DiscordPresence", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.confirmPowerOff, "UI", "ConfirmPowerOff", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.confirmShutdown, "UI", "ConfirmShutdown", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveStateOnExit, "EmuCore", "AutoStateLoadSave", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pauseOnStart, "UI", "StartPaused", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pauseOnFocusLoss, "UI", "PauseOnFocusLoss", false);
|
||||
@@ -84,8 +84,8 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsDialog* dialog, QWidget
|
||||
}
|
||||
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.confirmPowerOff, tr("Confirm Power Off"), tr("Checked"),
|
||||
tr("Determines whether a prompt will be displayed to confirm shutting down the emulator/game "
|
||||
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.saveStateOnExit, tr("Save State On Exit"), tr("Checked"),
|
||||
tr("Automatically saves the emulator state when powering down or exiting. You can then "
|
||||
|
||||
@@ -61,9 +61,9 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="confirmPowerOff">
|
||||
<widget class="QCheckBox" name="confirmShutdown">
|
||||
<property name="text">
|
||||
<string>Confirm Power Off</string>
|
||||
<string>Confirm Shutdown</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
MemoryCardSettingsWidget::MemoryCardSettingsWidget(SettingsDialog* dialog, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
SettingsInterface* sif = dialog->getSettingsInterface();
|
||||
// SettingsInterface* sif = dialog->getSettingsInterface();
|
||||
|
||||
m_ui.setupUi(this);
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ private Q_SLOTS:
|
||||
void onRestoreDefaultsClicked();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent*);
|
||||
void closeEvent(QCloseEvent*) override;
|
||||
|
||||
private:
|
||||
enum : u32
|
||||
|
||||
@@ -37,7 +37,7 @@ SystemSettingsWidget::SystemSettingsWidget(SettingsDialog* dialog, QWidget* pare
|
||||
|
||||
m_ui.setupUi(this);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.eeCycleSkipping, "EmuCore/Speedhacks", "EECycleSkip", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.eeCycleSkipping, "EmuCore/Speedhacks", "EECycleSkip", DEFAULT_EE_CYCLE_SKIP);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.MTVU, "EmuCore/Speedhacks", "vuThread", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.instantVU1, "EmuCore/Speedhacks", "vu1Instant", true);
|
||||
|
||||
@@ -138,13 +138,15 @@ void VulkanHostDisplay::DestroyRenderSurface()
|
||||
std::string VulkanHostDisplay::GetDriverInfo() const
|
||||
{
|
||||
std::string ret;
|
||||
const u32 version = g_vulkan_context->GetDeviceProperties().apiVersion;
|
||||
const u32 api_version = g_vulkan_context->GetDeviceProperties().apiVersion;
|
||||
const u32 driver_version = g_vulkan_context->GetDeviceProperties().driverVersion;
|
||||
if (g_vulkan_context->GetOptionalExtensions().vk_khr_driver_properties)
|
||||
{
|
||||
const VkPhysicalDeviceDriverProperties& props = g_vulkan_context->GetDeviceDriverProperties();
|
||||
ret = StringUtil::StdStringFromFormat(
|
||||
"Vulkan %u.%u.%u\nConformance Version %u.%u.%u.%u\n%s\n%s\n%s",
|
||||
VK_API_VERSION_MAJOR(version), VK_API_VERSION_MINOR(version), VK_API_VERSION_PATCH(version),
|
||||
"Driver %u.%u.%u\nVulkan %u.%u.%u\nConformance Version %u.%u.%u.%u\n%s\n%s\n%s",
|
||||
VK_VERSION_MAJOR(driver_version), VK_VERSION_MINOR(driver_version), VK_VERSION_PATCH(driver_version),
|
||||
VK_API_VERSION_MAJOR(api_version), VK_API_VERSION_MINOR(api_version), VK_API_VERSION_PATCH(api_version),
|
||||
props.conformanceVersion.major, props.conformanceVersion.minor, props.conformanceVersion.subminor, props.conformanceVersion.patch,
|
||||
props.driverInfo, props.driverName,
|
||||
g_vulkan_context->GetDeviceProperties().deviceName);
|
||||
@@ -152,8 +154,9 @@ std::string VulkanHostDisplay::GetDriverInfo() const
|
||||
else
|
||||
{
|
||||
ret = StringUtil::StdStringFromFormat(
|
||||
"Vulkan %u.%u.%u\n%s",
|
||||
VK_API_VERSION_MAJOR(version), VK_API_VERSION_MINOR(version), VK_API_VERSION_PATCH(version),
|
||||
"Driver %u.%u.%u\nVulkan %u.%u.%u\n%s",
|
||||
VK_VERSION_MAJOR(driver_version), VK_VERSION_MINOR(driver_version), VK_VERSION_PATCH(driver_version),
|
||||
VK_API_VERSION_MAJOR(api_version), VK_API_VERSION_MINOR(api_version), VK_API_VERSION_PATCH(api_version),
|
||||
g_vulkan_context->GetDeviceProperties().deviceName);
|
||||
}
|
||||
|
||||
|
||||
+147
-49
@@ -209,7 +209,6 @@ void GSState::Reset()
|
||||
m_vertex.tail = 0;
|
||||
m_vertex.next = 0;
|
||||
m_index.tail = 0;
|
||||
|
||||
m_scanmask_used = false;
|
||||
}
|
||||
|
||||
@@ -895,10 +894,7 @@ void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
|
||||
GL_REG("TEX0_%d = 0x%x_%x", i, r->U32[1], r->U32[0]);
|
||||
|
||||
GIFRegTEX0 TEX0 = r->TEX0;
|
||||
|
||||
bool MTBA_reload = false;
|
||||
if ((m_env.CTXT[i].TEX0.TBP0 != TEX0.TBP0 || tex_flushed) && m_env.CTXT[i].TEX1.MTBA)
|
||||
MTBA_reload = true;
|
||||
const bool MTBAreload = ((tex_flushed && (i == m_env.PRIM.CTXT)) || (r->TEX0.TBP0 != m_env.CTXT[i].TEX0.TBP0)) ? true : false;
|
||||
|
||||
// Spec max is 10
|
||||
//
|
||||
@@ -916,20 +912,22 @@ void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
|
||||
|
||||
ApplyTEX0<i>(TEX0);
|
||||
|
||||
// When the texture cache reloads any MIPS need to update too, so let's do that here.
|
||||
// This is essentially triggered by the texture page change, so if TEXFLUSH is called and a draw doesn't proceed it, or TBP changes.
|
||||
// Textures must be of equal width/height and a minimum of 32x32
|
||||
if (MTBA_reload && TEX0.TW == TEX0.TH && TEX0.TW >= 5)
|
||||
if (MTBAreload && m_env.CTXT[i].TEX1.MTBA && m_env.CTXT[i].TEX0.TW == m_env.CTXT[i].TEX0.TH && m_env.CTXT[i].TEX0.TW >= 5)
|
||||
{
|
||||
// NOTE 1: TEX1.MXL must not be automatically set to 3 here.
|
||||
// NOTE 2: Mipmap levels are tightly packed, if (tbw << 6) > (1 << tw) then the left-over space to the right is used. (common for PSM_PSMT4)
|
||||
// NOTE 3: Non-rectangular textures are treated as rectangular when calculating the occupied space (height is extended, not sure about width)
|
||||
|
||||
u32 bp = TEX0.TBP0;
|
||||
u32 bw = TEX0.TBW;
|
||||
u32 w = 1u << TEX0.TW;
|
||||
u32 h = 1u << TEX0.TH;
|
||||
u32 minwidth = m_context->TEX1.MMIN >= 4 ? 8 : 1;
|
||||
u32 bp = m_env.CTXT[i].TEX0.TBP0;
|
||||
u32 bw = m_env.CTXT[i]. TEX0.TBW;
|
||||
u32 w = 1u << m_env.CTXT[i].TEX0.TW;
|
||||
u32 h = 1u << m_env.CTXT[i].TEX0.TH;
|
||||
u32 minwidth = m_env.CTXT[i].TEX1.MMIN >= 4 ? 8 : 1;
|
||||
|
||||
const u32 bpp = GSLocalMemory::m_psm[TEX0.PSM].bpp;
|
||||
const u32 bpp = GSLocalMemory::m_psm[m_env.CTXT[i].TEX0.PSM].bpp;
|
||||
|
||||
bp += (int)((w * h * ((float)bpp / 8))) >> 8;
|
||||
|
||||
@@ -944,7 +942,7 @@ void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
|
||||
m_env.CTXT[i].MIPTBP1.TBW1 = bw;
|
||||
|
||||
bp += (int)((w * h * ((float)bpp / 8))) >> 8;
|
||||
|
||||
|
||||
if (w > minwidth)
|
||||
{
|
||||
bw = std::max<u32>(bw >> 1, 1);
|
||||
@@ -961,7 +959,7 @@ void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
|
||||
{
|
||||
bw = std::max<u32>(bw >> 1, 1);
|
||||
}
|
||||
|
||||
|
||||
m_env.CTXT[i].MIPTBP1.TBP3 = bp;
|
||||
m_env.CTXT[i].MIPTBP1.TBW3 = bw;
|
||||
}
|
||||
@@ -1132,8 +1130,14 @@ void GSState::GIFRegHandlerFOGCOL(const GIFReg* RESTRICT r)
|
||||
|
||||
void GSState::GIFRegHandlerTEXFLUSH(const GIFReg* RESTRICT r)
|
||||
{
|
||||
GL_REG("TEXFLUSH = 0x%x_%x", r->U32[1], r->U32[0]);
|
||||
GL_REG("TEXFLUSH = 0x%x_%x PRIM TME %x", r->U32[1], r->U32[0], PRIM->TME);
|
||||
|
||||
tex_flushed = true;
|
||||
// Some games do a single sprite draw to itself, then flush the texture cache, then use that texture again.
|
||||
// This won't get picked up by the new autoflush logic (which checks for page crossings for the PS2 Texture Cache flush)
|
||||
// so we need to do it here.
|
||||
if(m_userhacks_auto_flush)
|
||||
Flush();
|
||||
}
|
||||
|
||||
template <int i>
|
||||
@@ -1506,7 +1510,6 @@ void GSState::FlushPrim()
|
||||
g_perfmon.Put(GSPerfMon::Prim, m_index.tail / GSUtil::GetVertexCount(PRIM->PRIM));
|
||||
|
||||
m_index.tail = 0;
|
||||
|
||||
m_vertex.head = 0;
|
||||
|
||||
if (unused > 0)
|
||||
@@ -2428,33 +2431,104 @@ GSState::PRIM_OVERLAP GSState::PrimitiveOverlap()
|
||||
return overlap;
|
||||
}
|
||||
|
||||
__forceinline void GSState::HandleAutoFlush()
|
||||
{
|
||||
// To briefly explain what's going on here, what we are checking for is draws over a texture when the source and destination are themselves.
|
||||
// Because one page of the texture gets buffered in the Texture Cache (the PS2's one) if any of those pixels are overwritten, you still read the old data.
|
||||
// So we need to calculate if a page boundary is being crossed for the format it is in and if the same part of the texture being written and read inside the draw.
|
||||
if ((m_context->FRAME.Block() == m_context->TEX0.TBP0) && (m_context->TEX0.PSM == m_context->FRAME.PSM) && PRIM->TME && (m_context->FRAME.FBMSK != 0xFFFFFFFF))
|
||||
{
|
||||
const int page_mask_x = ~(GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.x - 1);
|
||||
const int page_mask_y = ~(GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.y - 1);
|
||||
const GSVector4i page_mask = { page_mask_x, page_mask_y, page_mask_x, page_mask_y };
|
||||
|
||||
size_t n = 1;
|
||||
|
||||
switch (GSUtil::GetPrimClass(PRIM->PRIM))
|
||||
{
|
||||
case GS_POINT_CLASS:
|
||||
n = 1;
|
||||
break;
|
||||
case GS_LINE_CLASS:
|
||||
case GS_SPRITE_CLASS:
|
||||
n = 2;
|
||||
break;
|
||||
case GS_TRIANGLE_CLASS:
|
||||
n = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
GSVector4i tex_coord;
|
||||
// Prepare the currently processed vertex.
|
||||
if (PRIM->FST)
|
||||
{
|
||||
tex_coord.x = m_v.U >> 4;
|
||||
tex_coord.y = m_v.V >> 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
tex_coord.x = (int)((1 << m_context->TEX0.TW) * (m_v.ST.S / m_v.RGBAQ.Q));
|
||||
tex_coord.y = (int)((1 << m_context->TEX0.TH) * (m_v.ST.T / m_v.RGBAQ.Q));
|
||||
}
|
||||
|
||||
GSVector4i tex_rect = tex_coord.xyxy();
|
||||
GSVector4i next_rect = tex_rect;
|
||||
const int current_tex_end = (int)(m_index.tail - (m_index.tail % n)) - 1;
|
||||
bool page_crossed = false;
|
||||
|
||||
// Check previous texture co-ordindates to see if we have changed page
|
||||
for (int i = m_index.tail - 1; i >= current_tex_end; i--)
|
||||
{
|
||||
const GSVertex* v = &m_vertex.buff[m_index.buff[i]];
|
||||
|
||||
if (PRIM->FST)
|
||||
{
|
||||
tex_coord.x = v->U >> 4;
|
||||
tex_coord.y = v->V >> 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
tex_coord.x = (int)((1 << m_context->TEX0.TW) * (v->ST.S / v->RGBAQ.Q));
|
||||
tex_coord.y = (int)((1 << m_context->TEX0.TH) * (v->ST.T / v->RGBAQ.Q));
|
||||
}
|
||||
|
||||
next_rect.x = std::min(next_rect.x, tex_coord.x);
|
||||
next_rect.z = std::max(next_rect.z, tex_coord.x);
|
||||
next_rect.y = std::min(next_rect.y, tex_coord.y);
|
||||
next_rect.w = std::max(next_rect.w, tex_coord.y);
|
||||
|
||||
const GSVector4i pages = next_rect & page_mask;
|
||||
|
||||
// We have changed page, so ignore the old textures co-ordinates.
|
||||
if (!pages.xyxy().eq(pages.zwzw()))
|
||||
{
|
||||
page_crossed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
tex_rect = next_rect;
|
||||
}
|
||||
|
||||
tex_rect += GSVector4i(0, 0, 1, 1); // Intersect goes on space inside the rect
|
||||
|
||||
if(page_crossed)
|
||||
{
|
||||
// Update the vertex trace, scissor it (important for Jak 3!) and intersect with the current texture.
|
||||
if((m_index.tail - 1) == current_tex_end)
|
||||
m_vt.Update(m_vertex.buff, m_index.buff, m_vertex.tail - m_vertex.head, m_index.tail, GSUtil::GetPrimClass(PRIM->PRIM));
|
||||
|
||||
GSVector4i area_out = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in));
|
||||
if (!area_out.rintersect(tex_rect).rempty())
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <u32 prim, bool auto_flush, bool index_swap>
|
||||
__forceinline void GSState::VertexKick(u32 skip)
|
||||
{
|
||||
ASSERT(m_vertex.tail < m_vertex.maxcount + 3);
|
||||
|
||||
size_t head = m_vertex.head;
|
||||
size_t tail = m_vertex.tail;
|
||||
size_t next = m_vertex.next;
|
||||
size_t xy_tail = m_vertex.xy_tail;
|
||||
|
||||
// callers should write XYZUVF to m_v.m[1] in one piece to have this load store-forwarded, either by the cpu or the compiler when this function is inlined
|
||||
|
||||
GSVector4i v0(m_v.m[0]);
|
||||
GSVector4i v1(m_v.m[1]);
|
||||
|
||||
GSVector4i* RESTRICT tailptr = (GSVector4i*)&m_vertex.buff[tail];
|
||||
|
||||
tailptr[0] = v0;
|
||||
tailptr[1] = v1;
|
||||
|
||||
const GSVector4i xy = v1.xxxx().u16to32().sub32(m_ofxy);
|
||||
|
||||
GSVector4i::storel(&m_vertex.xy[xy_tail & 3], xy.blend16<0xf0>(xy.sra32(4)).ps32());
|
||||
|
||||
m_vertex.tail = ++tail;
|
||||
m_vertex.xy_tail = ++xy_tail;
|
||||
|
||||
size_t n = 0;
|
||||
|
||||
switch (prim)
|
||||
@@ -2485,6 +2559,37 @@ __forceinline void GSState::VertexKick(u32 skip)
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_context->FRAME.FBMSK != 0xFFFFFFFF)
|
||||
m_mem.m_clut.Invalidate(m_context->FRAME.Block());
|
||||
|
||||
if (auto_flush && m_index.tail >= n)
|
||||
HandleAutoFlush();
|
||||
|
||||
ASSERT(m_vertex.tail < m_vertex.maxcount + 3);
|
||||
|
||||
size_t head = m_vertex.head;
|
||||
size_t tail = m_vertex.tail;
|
||||
size_t next = m_vertex.next;
|
||||
size_t xy_tail = m_vertex.xy_tail;
|
||||
|
||||
// callers should write XYZUVF to m_v.m[1] in one piece to have this load store-forwarded, either by the cpu or the compiler when this function is inlined
|
||||
|
||||
GSVector4i v0(m_v.m[0]);
|
||||
GSVector4i v1(m_v.m[1]);
|
||||
|
||||
GSVector4i* RESTRICT tailptr = (GSVector4i*)&m_vertex.buff[tail];
|
||||
|
||||
tailptr[0] = v0;
|
||||
tailptr[1] = v1;
|
||||
|
||||
const GSVector4i xy = v1.xxxx().u16to32().sub32(m_ofxy);
|
||||
|
||||
GSVector4i::storel(&m_vertex.xy[xy_tail & 3], xy.blend16<0xf0>(xy.sra32(4)).ps32());
|
||||
|
||||
m_vertex.tail = ++tail;
|
||||
m_vertex.xy_tail = ++xy_tail;
|
||||
|
||||
|
||||
size_t m = tail - head;
|
||||
|
||||
if (m < n)
|
||||
@@ -2664,15 +2769,8 @@ __forceinline void GSState::VertexKick(u32 skip)
|
||||
__assume(0);
|
||||
}
|
||||
|
||||
if (m_context->FRAME.FBMSK != 0xFFFFFFFF)
|
||||
{
|
||||
m_mem.m_clut.Invalidate(m_context->FRAME.Block());
|
||||
|
||||
if (auto_flush && PRIM->TME && (m_context->FRAME.Block() == m_context->TEX0.TBP0) && (m_context->TEX0.PSM == m_context->FRAME.PSM))
|
||||
{
|
||||
FlushPrim();
|
||||
}
|
||||
}
|
||||
if (PRIM->TME)
|
||||
tex_flushed = false;
|
||||
}
|
||||
|
||||
/// Checks if region repeat is used (applying it does something to at least one of the values in min...max)
|
||||
|
||||
+3
-2
@@ -156,12 +156,12 @@ protected:
|
||||
int m_skip;
|
||||
int m_skip_offset;
|
||||
bool m_userhacks_auto_flush;
|
||||
bool tex_flushed;
|
||||
|
||||
GSVertex m_v;
|
||||
float m_q;
|
||||
GSVector4i m_scissor;
|
||||
GSVector4i m_ofxy;
|
||||
bool tex_flushed;
|
||||
|
||||
bool m_scanmask_used;
|
||||
|
||||
@@ -185,7 +185,8 @@ protected:
|
||||
void UpdateVertexKick();
|
||||
|
||||
void GrowVertexBuffer();
|
||||
|
||||
void HandleAutoFlush();
|
||||
|
||||
template <u32 prim, bool auto_flush, bool index_swap>
|
||||
void VertexKick(u32 skip);
|
||||
|
||||
|
||||
@@ -49,6 +49,9 @@ GSVertexTrace::GSVertexTrace(const GSState* state)
|
||||
|
||||
void GSVertexTrace::Update(const void* vertex, const u32* index, int v_count, int i_count, GS_PRIM_CLASS primclass)
|
||||
{
|
||||
if (i_count == 0)
|
||||
return;
|
||||
|
||||
m_primclass = primclass;
|
||||
|
||||
u32 iip = m_state->PRIM->IIP;
|
||||
|
||||
@@ -351,7 +351,7 @@ bool GSC_Tekken5(const GSFrameInfo& fi, int& skip)
|
||||
// Let's enable this hack for Aggressive only since it's an upscaling issue for both renders.
|
||||
skip = 95;
|
||||
}
|
||||
else if (fi.TME && (fi.FBP == 0x02bc0 || fi.FBP == 0x02be0 || fi.FBP == 0x02d00 || fi.FBP == 0x03480 || fi.FBP == 0x034a0) && fi.FPSM == fi.TPSM && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32)
|
||||
else if (fi.TZTST == 1 && fi.TME && (fi.FBP == 0x02bc0 || fi.FBP == 0x02be0 || fi.FBP == 0x02d00 || fi.FBP == 0x03480 || fi.FBP == 0x034a0) && fi.FPSM == fi.TPSM && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32)
|
||||
{
|
||||
// The moving display effect(flames) is not emulated properly in the entire screen so let's remove the effect in the stage: Burning Temple. Related to half screen bottom issue.
|
||||
// Fixes black lines in the stage: Burning Temple - caused by upscaling. Note the black lines can also be fixed with Merge Sprite hack.
|
||||
|
||||
@@ -1967,7 +1967,6 @@ void GSRendererHW::OI_DoubleHalfClear(GSTexture* rt, GSTexture* ds)
|
||||
&& (m_context->FRAME.PSM & 0xF) == (m_context->ZBUF.PSM & 0xF) && (u32)(GSVector4i(m_vt.m_max.p).z) == 0)
|
||||
{
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
const GSLocalMemory::psm_t& frame_psm = GSLocalMemory::m_psm[m_context->FRAME.PSM];
|
||||
|
||||
// Z and color must be constant and the same
|
||||
if (m_vt.m_eq.rgba != 0xFFFF || !m_vt.m_eq.z || v[1].XYZ.Z != v[1].RGBAQ.U32[0])
|
||||
|
||||
@@ -528,7 +528,7 @@ void GSRendererNew::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER)
|
||||
// PABE: Check condition early as an optimization.
|
||||
const bool PABE = PRIM->ABE && m_env.PABE.PABE && (GetAlphaMinMax().max < 128);
|
||||
// FBMASK: Color is not written, no need to do blending.
|
||||
const int temp_fbmask = m_conf.ps.dfmt == 2 ? 0x00F8F8F8 : 0x00FFFFFF;
|
||||
const u32 temp_fbmask = m_conf.ps.dfmt == 2 ? 0x00F8F8F8 : 0x00FFFFFF;
|
||||
const bool FBMASK = (m_context->FRAME.FBMSK & temp_fbmask) == temp_fbmask;
|
||||
|
||||
// No blending or coverage anti-aliasing so early exit
|
||||
@@ -773,9 +773,14 @@ void GSRendererNew::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER)
|
||||
#endif
|
||||
if (color_dest_blend)
|
||||
{
|
||||
// Blend output will be Cd, no need to set Af.
|
||||
m_conf.blend = {blend_index, 0, ALPHA.C == 2, false, false};
|
||||
// Blend output will be Cd, disable hw/sw blending.
|
||||
m_conf.blend = {};
|
||||
sw_blending = false; // DATE_PRIMID
|
||||
|
||||
// Output is Cd, set rgb write to 0.
|
||||
m_conf.colormask.wr = 0;
|
||||
m_conf.colormask.wg = 0;
|
||||
m_conf.colormask.wb = 0;
|
||||
}
|
||||
else if (sw_blending)
|
||||
{
|
||||
@@ -784,16 +789,30 @@ void GSRendererNew::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER)
|
||||
m_conf.ps.blend_c = ALPHA.C;
|
||||
m_conf.ps.blend_d = ALPHA.D;
|
||||
|
||||
if (m_conf.ps.blend_a == m_conf.ps.blend_b)
|
||||
{
|
||||
// A == B
|
||||
// (A - B) * C will be 0 so set A B to Cs, C to As
|
||||
m_conf.ps.blend_a = 0;
|
||||
m_conf.ps.blend_b = 0;
|
||||
m_conf.ps.blend_c = 0;
|
||||
}
|
||||
else if (m_conf.ps.blend_c == 2)
|
||||
{
|
||||
// Require the fix alpha vlaue
|
||||
m_conf.cb_ps.TA_MaxDepth_Af.a = static_cast<float>(ALPHA.FIX) / 128.0f;
|
||||
}
|
||||
|
||||
if (accumulation_blend)
|
||||
{
|
||||
// Keep HW blending to do the addition/subtraction
|
||||
m_conf.blend = {blend_index, 0, false, true, false};
|
||||
if (ALPHA.A == 2)
|
||||
if (m_conf.ps.blend_a == 2)
|
||||
{
|
||||
// The blend unit does a reverse subtraction so it means
|
||||
// the shader must output a positive value.
|
||||
// Replace 0 - Cs by Cs - 0
|
||||
m_conf.ps.blend_a = ALPHA.B;
|
||||
m_conf.ps.blend_a = m_conf.ps.blend_b;
|
||||
m_conf.ps.blend_b = 2;
|
||||
}
|
||||
// Remove the addition/substraction from the SW blending
|
||||
@@ -804,7 +823,7 @@ void GSRendererNew::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER)
|
||||
}
|
||||
else if (blend_mix)
|
||||
{
|
||||
m_conf.blend = {blend_index, ALPHA.FIX, ALPHA.C == 2, false, true};
|
||||
m_conf.blend = {blend_index, ALPHA.FIX, m_conf.ps.blend_c == 2, false, true};
|
||||
m_conf.ps.blend_mix = 1;
|
||||
|
||||
if (blend_mix1)
|
||||
@@ -847,10 +866,6 @@ void GSRendererNew::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER)
|
||||
else
|
||||
m_conf.require_one_barrier |= !blend_non_recursive;
|
||||
}
|
||||
|
||||
// Require the fix alpha vlaue
|
||||
if (ALPHA.C == 2)
|
||||
m_conf.cb_ps.TA_MaxDepth_Af.a = static_cast<float>(ALPHA.FIX) / 128.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -914,9 +914,9 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
|
||||
// Called each time you want to read from the GS memory
|
||||
void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r)
|
||||
{
|
||||
u32 bp = off.bp();
|
||||
u32 psm = off.psm();
|
||||
u32 bw = off.bw();
|
||||
const u32 bp = off.bp();
|
||||
const u32 psm = off.psm();
|
||||
[[maybe_unused]] const u32 bw = off.bw();
|
||||
|
||||
GL_CACHE("TC: InvalidateLocalMem off(0x%x, %u, %s) r(%d, %d => %d, %d)",
|
||||
bp,
|
||||
@@ -2448,7 +2448,7 @@ GSTextureCache::SurfaceOffset GSTextureCache::ComputeSurfaceOffset(const Surface
|
||||
|
||||
const GSVector4i& r1 = so.b2a_offset;
|
||||
const GSVector4i& r2 = b_rect;
|
||||
const GSVector4i ri = r1.rintersect(r2);
|
||||
[[maybe_unused]] const GSVector4i ri = r1.rintersect(r2);
|
||||
assert(!so.is_valid || (r1.eq(ri) && r1.x >= 0 && r1.y >= 0 && r1.z > 0 && r1.w > 0));
|
||||
|
||||
// Clear cache if size too big.
|
||||
|
||||
@@ -455,7 +455,7 @@ void GSDrawScanline::DrawScanline(int pixels, int left, int top, const GSVertexS
|
||||
skip = left & 7;
|
||||
steps = pixels + skip - 8;
|
||||
left -= skip;
|
||||
test = GSVector8i::i8to32c(g_const->m_test_256b[skip]) | GSVector8i::i8to32c(g_const->m_test_256b[15 + (steps & (steps >> 31))]);
|
||||
test = GSVector8i::i8to32(g_const->m_test_256b[skip]) | GSVector8i::i8to32(g_const->m_test_256b[15 + (steps & (steps >> 31))]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1561,7 +1561,7 @@ void GSDrawScanline::DrawScanline(int pixels, int left, int top, const GSVertexS
|
||||
|
||||
if (!sel.notest)
|
||||
{
|
||||
test = GSVector8i::i8to32c(g_const->m_test_256b[15 + (steps & (steps >> 31))]);
|
||||
test = GSVector8i::i8to32(g_const->m_test_256b[15 + (steps & (steps >> 31))]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -736,8 +736,14 @@ void Dialog::Save()
|
||||
m_ui.Save();
|
||||
// only save the adapter when it makes sense to
|
||||
// prevents changing the adapter, switching to another renderer and saving
|
||||
if (m_adapter_select->GetCount() > 1) // First option is system default
|
||||
theApp.SetConfig("Adapter", m_adapter_select->GetStringSelection().c_str());
|
||||
if (m_adapter_select->GetCount() > 1)
|
||||
{
|
||||
// First option is system default
|
||||
if (m_adapter_select->GetSelection() == 0)
|
||||
theApp.SetConfig("Adapter", "");
|
||||
else
|
||||
theApp.SetConfig("Adapter", m_adapter_select->GetStringSelection().c_str());
|
||||
}
|
||||
|
||||
m_hacks_panel->Save();
|
||||
m_renderer_panel->Save();
|
||||
|
||||
+7
-4
@@ -116,7 +116,7 @@ void VMManager::SetState(VMState state)
|
||||
SetTimerResolutionIncreased(state == VMState::Running);
|
||||
s_state.store(state);
|
||||
|
||||
if (state == VMState::Paused || old_state == VMState::Paused)
|
||||
if (state != VMState::Stopping && (state == VMState::Paused || old_state == VMState::Paused))
|
||||
{
|
||||
if (state == VMState::Paused)
|
||||
{
|
||||
@@ -1158,10 +1158,13 @@ void VMManager::ApplySettings()
|
||||
}
|
||||
}
|
||||
|
||||
void VMManager::ReloadGameSettings()
|
||||
bool VMManager::ReloadGameSettings()
|
||||
{
|
||||
if (UpdateGameSettingsLayer())
|
||||
ApplySettings();
|
||||
if (!UpdateGameSettingsLayer())
|
||||
return false;
|
||||
|
||||
ApplySettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
static void HotkeyAdjustTargetSpeed(double delta)
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ namespace VMManager
|
||||
void ApplySettings();
|
||||
|
||||
/// Reloads game specific settings, and applys any changes present.
|
||||
void ReloadGameSettings();
|
||||
bool ReloadGameSettings();
|
||||
|
||||
/// Reloads cheats/patches. If verbose is set, the number of patches loaded will be shown in the OSD.
|
||||
void ReloadPatches(bool verbose);
|
||||
|
||||
@@ -130,6 +130,9 @@ HostDisplay* Host::AcquireHostDisplay(HostDisplay::RenderAPI api)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Console.WriteLn(Color_StrongGreen, "%s Graphics Driver Info:", HostDisplay::RenderAPIToString(s_host_display->GetRenderAPI()));
|
||||
Console.Indent().WriteLn(s_host_display->GetDriverInfo());
|
||||
|
||||
return s_host_display.get();
|
||||
}
|
||||
|
||||
|
||||
@@ -535,6 +535,12 @@ void recLDL()
|
||||
#ifdef LOADSTORE_RECOMPILE
|
||||
int t2reg;
|
||||
|
||||
if (GPR_IS_CONST1(_Rt_))
|
||||
{
|
||||
_flushConstReg(_Rt_);
|
||||
_eeOnWriteReg(_Rt_, 0);
|
||||
}
|
||||
|
||||
if (GPR_IS_CONST1(_Rs_))
|
||||
{
|
||||
u32 srcadr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_;
|
||||
@@ -610,6 +616,12 @@ void recLDR()
|
||||
|
||||
#ifdef LOADSTORE_RECOMPILE
|
||||
int t2reg;
|
||||
|
||||
if (GPR_IS_CONST1(_Rt_))
|
||||
{
|
||||
_flushConstReg(_Rt_);
|
||||
_eeOnWriteReg(_Rt_, 0);
|
||||
}
|
||||
|
||||
if (GPR_IS_CONST1(_Rs_))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user