Compare commits

...
241 Commits
Author SHA1 Message Date
seta-sanandrefractionpcsx2 577d6e735c Gamedb: Add Bumpy Trot Trial serial 2022-04-06 15:17:47 +01:00
Ty Lamontagneandlightningterror 7668123aaa gitignore: ignore bin/textures 2022-04-06 01:30:22 +02:00
MrlinkwiiandGitHub 0b87d580c3 Gamedb: Add Hachi-One Diver serial. (#5828) 2022-04-05 20:40:14 +02:00
Connor McLaughlinandrefractionpcsx2 170a03cac6 GSDump: Drop last packet of truncated dumps 2022-04-05 12:08:06 +01:00
PCSX2 Botandlightningterror 70d8acb812 PAD: Update to latest controller database. 2022-04-05 13:02:32 +02:00
TheLastRarandrefractionpcsx2 2670d5a9aa Core: Move Applying GameFixes into GameEntry
Also add similar logging to GS Hardware fixes (on Qt)
2022-04-05 11:12:14 +01:00
TheLastRarandrefractionpcsx2 44081671ac Config: Fix saving/loading EnableGameFixes in Core 2022-04-05 11:12:14 +01:00
refractionpcsx2 462b304bea GameDB: Update Simple Series entries 2022-04-05 11:06:58 +01:00
Odin Vexandrefractionpcsx2 059f58803c Remove erroneous unmanaged cleanup of managed code
`loadYamlFile` calls `OpenManagedCFile` which handles closing the file-handle used. Thus, closing the file-handle outside the API call to `OpenManagedCFile` is not necessary.
2022-04-05 11:04:51 +01:00
refractionpcsx2 e170e9281d GS: Fix reversed reversed GS copies. 2022-04-04 18:07:54 +01:00
Connor McLaughlinandrefractionpcsx2 5987e03463 GS: Force min/mag linear when trilinear is forced
Trilinear implies that min/mag will be linear. Less confusing, makes
sense, and the min/mag point + mip linear case is currently not handled
properly with regard to the GS registers.
2022-04-04 17:01:23 +01:00
Connor McLaughlinandrefractionpcsx2 ddbdfd47be GS: Make hardware renderer trilinear consistent
Trilinear without bilinear was inconsistent previously.
2022-04-04 17:01:23 +01:00
Connor McLaughlinandrefractionpcsx2 1b83e17d60 GS: Add automatic trilinear filtering level 2022-04-04 17:01:23 +01:00
AndreAuthandGitHub bc7ed4e7d0 GameDB: Metal Gear Solid 3 PAL - Fix blurry characters (#5819) 2022-04-04 11:33:16 +01:00
refractionpcsx2 283c7fa88c GS: Improve autoflush rect checks 2022-04-04 11:25:25 +01:00
Connor McLaughlinandrefractionpcsx2 d01ee3163d Qt: Add performance metrics to status bar 2022-04-03 23:59:05 +01:00
Mrlinkwiiandrefractionpcsx2 90457e32b6 Gamedb: update changes to pdf 2022-04-03 10:09:05 +01:00
refractionpcsx2 4cb6c94693 CI/Docs: Update validation and document 2022-04-03 08:50:09 +01:00
refractionpcsx2 93c78a27b3 GS: Add interlace override to gamedb, revert earlier change 2022-04-03 08:50:09 +01:00
Connor McLaughlinandrefractionpcsx2 50452848e7 BiosTools: Bounds check strings in LoadBiosVersion() 2022-04-03 07:57:42 +01:00
Connor McLaughlinandrefractionpcsx2 4f70fd9583 VMManager: Make EE rec toggles reliable
Before, it'd swap out the Cpu while it was executing...
2022-04-03 07:57:02 +01:00
Connor McLaughlinandrefractionpcsx2 e6c8354ec8 EERec: Purge PCSX2_SEH define
No longer needed since we don't have 32-bit.
2022-04-03 07:57:02 +01:00
Connor McLaughlinandrefractionpcsx2 a1e77002c3 iR5900: Exit on NeedsReset not IsReset
This is an edge case which can be hit in Goemon, but also when changing
settings in Qt, as they will be applied at guest vsync time, which is
called within the JIT.

Also, do the reset before entering JIT code, rather than when the first
block is compiled.
2022-04-03 07:57:02 +01:00
Connor McLaughlinandlightningterror 099cd52381 gitignore: Remove unused portaudio files 2022-04-03 06:09:09 +02:00
lightningterror 0d1675fbaa GS-hw: Purge custom resolution entirely.
Code debt, not used anymore, get rid of it.
2022-04-02 16:54:26 +02:00
lightningterror f021da5627 GS-tc-hw: Fix Normal Half pixel offset on 7x upscale. 2022-04-01 13:58:54 +02:00
refractionpcsx2 906480b8e2 GS: Only flush on PRIM if a new draw is requested 2022-04-01 10:48:22 +01:00
refractionpcsx2 38b83af714 GS: Improve interlace handling and odd frames 2022-04-01 10:48:01 +01:00
Tyler Wildingandrefractionpcsx2 05dab12b7c releases: simplify discord announcements, and link to the right page 2022-04-01 10:45:59 +01:00
TellowKrinkleandtellowkrinkle c0628a64a6 GS: Add Metal renderer to settings 2022-03-31 23:51:27 -05:00
TellowKrinkleandtellowkrinkle 5ecaa9459d GS: Add Metal renderer 2022-03-31 23:51:27 -05:00
TellowKrinkleandtellowkrinkle 24b2277206 GS: Give names to blend enums 2022-03-31 23:51:27 -05:00
TellowKrinkleandtellowkrinkle 8e60d2c72e GS: Rename Int32 texture to PrimID
Not always Int32
2022-03-31 23:51:27 -05:00
TellowKrinkleandtellowkrinkle cfe2f9e6b4 Common: Add helpers for enum classes 2022-03-31 23:51:27 -05:00
TellowKrinkleandtellowkrinkle 0a11b5898a CMake: Disable PCH for mm files 2022-03-31 23:51:27 -05:00
TellowKrinkleandtellowkrinkle be49de6fa0 Config: Format Pcsx2Config 2022-03-31 23:51:27 -05:00
RedDevilusandrefractionpcsx2 1ad52e918b GameDB: Caspian
Reduces ghosting but on normal vertex causes the rainbow corruption at the screen sides
2022-03-31 15:45:12 +01:00
Tzerinasandrefractionpcsx2 53388336d2 GameDB: Fixes for Tomb Raider Games
Added the FMV Hack for every game except Underworld and the missing mipmap Setting for the US version of Legend.
2022-03-31 15:44:58 +01:00
Chromaryuandrefractionpcsx2 4e1496e736 GameDB: Add Zwei AutoFix 2022-03-31 15:43:22 +01:00
RedDevilusandrefractionpcsx2 216c964d13 GameDB: Silent Hill Origins
Wildarms while making the alignment perfect in the 3D environment, messes with the maps.
2022-03-31 12:03:31 +01:00
Angel TolozaandGitHub 6bb828eb8f GameDB : Atelier Marie + Elie: Salburg no Renkinjutsushi 1&2 (#5784) 2022-03-30 23:45:14 +01:00
Tzerinasandrefractionpcsx2 511845a1c4 GameDB: Corrected GSHW Fixes for Radiata Stories
Adds Special (Texture) and Align Sprite to Radiata Stories.
2022-03-30 23:39:28 +01:00
RedDevilusandrefractionpcsx2 89f10e1605 GameDB: ':' to '-' + GS and other fixes
Windows doesn't like you to use ':' in folders this caused issues for when CK1 did savestates in folders and now it's also messing with unable to add covers in Qt so better to replace them and also to avoid other issues now and the future.
GS HW Fixes and other fixes for:
- Adventures of Cookie & Cream, The
- Brothers in Arms - Earned in Blood / Road to Hill 30
- Black
- Chaos Legion
- God Hand
- Knockout Kings 2001
- Kuon
- Outrun 2006 / 2 SP
- Project Eden
- Psi-Ops - The Mindgate
- Punisher, The
- Ratchet Deadlocked (USA) / Gladiator (Europe) / 3 Up Your Arsenal
- Silent Hills Origins / Shattered Memories / 3 / 4
- SoulCalibur II / III

Also made sure that the comments and their spacing were consistent.
2022-03-30 23:38:18 +01:00
Connor McLaughlinandlightningterror 76b4e93604 Vulkan/ShaderCache: Don't delete cache when running 2 instances 2022-03-30 12:38:08 +02:00
Connor McLaughlinandlightningterror cec089a271 D3D11/ShaderCache: Don't delete cache when running 2 instances 2022-03-30 12:38:08 +02:00
PCSX2 Botandlightningterror b4bd36c4b2 PAD: Update to latest controller database. 2022-03-28 18:04:15 +02:00
RedDevilusandrefractionpcsx2 338eb42b04 Qt: Reduce max SPU - Change Speed Preset
Qt has a leftover from the old SPU2-X values which is 3000 ms (3 seconds) latency meaning that if an user sets it to the max it will do something like this: Videoframe ~150 / 180 happens and it makes the first sound after 3 seconds for the first videoframe which is far too long. Also changed 1% speed as it messed with the GSdump player and too stuttery to be usable in other usecases.
2022-03-28 10:44:04 +01:00
lightningterror 8e42fce0aa gamedb: Add alignSprite to GOW 2.
Fixes water vertical lines.
2022-03-28 10:16:59 +02:00
lightningterror a7900b342e GS-hw: Purge GodOfWar 1 and 2 crc hacks.
Not needed, can be solved with upscaling hw hacks, and gs db fixes are a thing.
2022-03-28 09:59:41 +02:00
Connor McLaughlinandlightningterror 506bbe1c08 GS/OpenGL: Don't emit #extension after #define for FXAA
This is technically not valid GLSL.
2022-03-28 09:24:51 +02:00
Connor McLaughlinandlightningterror d32d8cc0ec Shaders/FXAA: Fix warnings with Vulkan compiler 2022-03-28 09:24:51 +02:00
Connor McLaughlinandlightningterror 0cb9655523 GS/Vulkan: Remove unused color attribute
Would likely be getting optimized out anyway.
2022-03-28 09:24:51 +02:00
Connor McLaughlinandlightningterror 3067bef82d GS/Vulkan: Implement FXAA 2022-03-28 09:24:51 +02:00
Connor McLaughlinandlightningterror 486764be03 GS/Vulkan: Implement shadeboost 2022-03-28 09:24:51 +02:00
Connor McLaughlinandlightningterror 5e336138d0 Qt: Add shadeboost settings 2022-03-28 09:24:51 +02:00
Connor McLaughlinandlightningterror 4a5180bc0a GS: Put shadeboost params in uniforms
Compiling variants for these is silly.
2022-03-28 09:24:51 +02:00
dependabot[bot]andlightningterror dd28e33612 Bump peter-evans/create-pull-request from 3 to 4
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 3 to 4.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v3...v4)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 09:10:03 +02:00
dependabot[bot]andlightningterror b66c0411df Bump actions/cache from 2.1.7 to 3
Bumps [actions/cache](https://github.com/actions/cache) from 2.1.7 to 3.
- [Release notes](https://github.com/actions/cache/releases)
- [Commits](https://github.com/actions/cache/compare/v2.1.7...v3)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 09:09:41 +02:00
arcum42andGitHub c59b114a1d Build: Remove cross compiling from build.sh. (#5713) 2022-03-27 17:38:41 -07:00
TheLastRarandrefractionpcsx2 352faeddb2 DEV9: Add Socket api mode 2022-03-27 16:16:19 +01:00
TheLastRarandrefractionpcsx2 140d44d826 DEV9: Add code for reading ARP, TCP & ICMP packets 2022-03-27 16:16:19 +01:00
TheLastRarandrefractionpcsx2 db220001f6 DEV9: Add cloning of packets 2022-03-27 16:16:19 +01:00
TheLastRarandrefractionpcsx2 5ac9b5576a DEV9: Add PayloadData classes 2022-03-27 16:16:19 +01:00
TheLastRarandrefractionpcsx2 b23873e0ed DEV9: Add adapter reset function 2022-03-27 16:16:19 +01:00
TheLastRarandrefractionpcsx2 284ec35699 DEV9: Add GetHeaderLength() to IP_Packet 2022-03-27 16:16:19 +01:00
TheLastRarandrefractionpcsx2 cb0e629dd3 DEV9: Make internal servers protected 2022-03-27 16:16:19 +01:00
TheLastRarandrefractionpcsx2 1aaadd6228 DEV9: Make DHCP_Server::GetGatewaysLinux() public
Needed for auto adapter on linux, if only to check if an adapter has a gateway
2022-03-27 16:16:19 +01:00
TheLastRarandrefractionpcsx2 e20a357340 DEV9: Allow user DHCP settings to be overridden 2022-03-27 16:16:19 +01:00
TheLastRarandrefractionpcsx2 fef2952d47 DEV9: Fix typo in DHCP_Packet 2022-03-27 16:16:19 +01:00
TheLastRarandrefractionpcsx2 f4b2e0dd7a DEV9: Correct PayloadPtr::WriteBytes() 2022-03-27 16:16:19 +01:00
Connor McLaughlinandrefractionpcsx2 d3aace98ac GS/OpenGL: Fix fb target conflict without fbfetch 2022-03-27 04:33:20 +01:00
Connor McLaughlinandrefractionpcsx2 3a7f82eb66 GS/HW: Fix fbmask not inserting barriers
Or, missing the fb copy for D3D/barriers off.

Regression from fbfetch PR.
2022-03-27 04:33:20 +01:00
Connor McLaughlinandrefractionpcsx2 3e24b678c4 Build: Don't install pcsx2 core static lib on Linux 2022-03-26 14:11:33 +00:00
Connor McLaughlinandrefractionpcsx2 2ab6ca06ed Qt: Fix compile issues on Linux 2022-03-26 14:11:33 +00:00
Connor McLaughlinandrefractionpcsx2 9ac5041b43 Qt: Fix double entries in audio output modules 2022-03-26 14:11:33 +00:00
Connor McLaughlinandrefractionpcsx2 9262422d01 Qt: Add missing null terminator in audio settings 2022-03-26 07:56:52 +00:00
Mrlinkwiiandrefractionpcsx2 9f04becc7a GameDB : various game improvements 2022-03-25 17:00:57 +00:00
RedDevilusandrefractionpcsx2 8485af6cac GameDB: GS HW Fix XI
The game also needs round sprite half for the transitional areas and red forest because of vertical lines similar to Star Ocean 3.
+ other fixes, read the GameDB comments for more information.
Relevant games:
- Atelier Iris 3 - Grand Phantasm
- Baldur's Gate - Dark Alliance 1 / 2
- Call of Duty 2 - Big Red One
- Dark Cloud 1 / 2
- Mana Khemia 1 / 2
- Sims 2 - Castaway
- Valkyrie 2 - Silmeria
2022-03-25 16:31:07 +00:00
TheLastRarandrefractionpcsx2 48f7e6c63f DEV9: Add Qt UI 2022-03-25 13:50:25 +00:00
TheLastRarandrefractionpcsx2 e1fb84d6a3 DEV9: Separate HddCreate code from Wx
Also disable auto generating an image on boot if one is not found
2022-03-25 13:50:25 +00:00
TheLastRarandrefractionpcsx2 5db9a738c5 Config: Integrate internal DNS host list on Qt 2022-03-25 13:50:25 +00:00
TheLastRarandrefractionpcsx2 145e75624d Config: Allow setting DNS1/2 internal instead of manual/auto 2022-03-25 13:50:25 +00:00
Connor McLaughlinandrefractionpcsx2 d09b49e17c Qt: Hook up automatic mapping 2022-03-25 12:51:31 +00:00
Connor McLaughlinandrefractionpcsx2 fdc3ca1227 PAD: Add automatic mapping functions 2022-03-25 12:51:31 +00:00
Connor McLaughlinandrefractionpcsx2 51d47a1455 InputManager: Add generic input mappings 2022-03-25 12:51:31 +00:00
Connor McLaughlinandrefractionpcsx2 9504671919 PAD: Add macro buttons 2022-03-25 12:51:31 +00:00
Connor McLaughlinandrefractionpcsx2 e5248db844 StringUtil: Add SplitString() 2022-03-25 12:51:31 +00:00
Connor McLaughlinandrefractionpcsx2 551d013b63 Qt: Add shutdown hotkey 2022-03-25 12:51:18 +00:00
Connor McLaughlinandrefractionpcsx2 d65950cda2 VMManager: Add BIOS check on startup
Except when running GS dumps.
2022-03-25 12:51:18 +00:00
Connor McLaughlinandrefractionpcsx2 15c38a0a4e GSDumpReplayer: Add missing license header 2022-03-25 12:51:18 +00:00
TheLastRarandrefractionpcsx2 74ed14496b Qt: GS Settings Fixes 2022-03-25 10:26:23 +00:00
Connor McLaughlinandrefractionpcsx2 1fa6fb0a8c Qt: Add memory card settings 2022-03-25 10:26:09 +00:00
Connor McLaughlinandrefractionpcsx2 3dc6ae115f Qt: Implement (partial) audio settings 2022-03-25 10:26:09 +00:00
Connor McLaughlinandrefractionpcsx2 fa36b9b5cb MemoryCardFile: Add formatted/mtime to query, rename/delete ops 2022-03-25 10:26:09 +00:00
Connor McLaughlinandrefractionpcsx2 47fff9304b FileSystem: Add DeleteDirectory() and recursive variant 2022-03-25 10:26:09 +00:00
Mrlinkwiiandrefractionpcsx2 29c0d93864 GUI/Docs : update compatibility URLs 2022-03-23 10:27:36 +00:00
RedDevilusandrefractionpcsx2 38ff521851 GameDB: Megaman + Nicktoons
Megaman X - Command Mission flickering FMV fix and fix for the lighting in the game Nicktoons Unite!
2022-03-22 22:02:30 +00:00
RedDevilusandrefractionpcsx2 34de1bffc6 GameDB: Remove outdated comments
The gameDB still had some leftover comments that aren't true anymore. In the past before 1.7.2002 / https://github.com/PCSX2/pcsx2/pull/3936 you needed to use full boot to correctly pass your chosen BIOS language to be piped to the game. Basically fast boot defaulted to the first entry in the available language list.
Full boot:
If you want to see BIOS logo - Good
Region check - Bad

Fast boot:
Immediately jump into the game - Good
Skips region check - Good
Now acts like full boot for languages - Good
2022-03-22 20:58:02 +00:00
Connor McLaughlinandrefractionpcsx2 8dc1592278 GSDumpReplayer: Fix ReadFIFO2 packet executing on wrong thread 2022-03-22 16:50:31 +00:00
Mrlinkwiiandrefractionpcsx2 5b86205349 Gamedb: add 'VUSyncHack' to Totally Spies! Totally Party 2022-03-22 14:45:35 +00:00
Mrlinkwiiandrefractionpcsx2 0d4fbd540e Gamedb: Fix 'SLES-54453' title 2022-03-22 14:27:39 +00:00
Connor McLaughlinandrefractionpcsx2 b9edabc236 Qt: Fix incorrect setting binding for display linear 2022-03-22 13:38:26 +00:00
Connor McLaughlinandrefractionpcsx2 180d9ae9c9 Qt: Correct EE/IOP console defaults 2022-03-22 13:38:26 +00:00
Connor McLaughlinandrefractionpcsx2 80cc2f0cb7 Qt: Log machine caps on startup 2022-03-22 13:38:26 +00:00
Connor McLaughlinandrefractionpcsx2 1927896442 GS: Fix some edge cases with fbfetch
Second alpha pass with A masked, DATE enabled, etc.
2022-03-21 20:24:09 +00:00
RedDevilusandrefractionpcsx2 bf9c1176b6 GameDB: Fix Midnightclub 3 + Add Evangelion Jo
Special texture to:
Midnight club 3
Evangelion - Jo
2022-03-21 20:23:54 +00:00
Tzerinasandrefractionpcsx2 166156519a GameDB: Fixes to TeamICO games.
Adds the Software Renderer FMV hack to ICO and Half-Pixel Offset (Vertex) to both games.
2022-03-21 20:16:46 +00:00
lightningterror d89daa1b25 misc: A few more 32bit cleanups. 2022-03-21 20:56:03 +01:00
lightningterror efc17f265c readme: Update to reflect recent drop of 32bit. 2022-03-21 20:28:33 +01:00
lightningterror 8427e6fd3e emitter test: Cleanup 32bit code. 2022-03-21 20:21:36 +01:00
lightningterror f1ac712eba build: Remove _M_X86_64, __M_X86_64, _M_X86_32 defines.
32bit cleanup.
2022-03-21 20:21:36 +01:00
lightningterror 0d4394a749 core: Clean up 32bit code. 2022-03-21 20:21:36 +01:00
lightningterror 9dac598113 common: Clean up 32bit code. 2022-03-21 20:21:36 +01:00
lightningterror 6db573d255 emitter: Clean up 32bit code. 2022-03-21 20:21:36 +01:00
Connor McLaughlinandrefractionpcsx2 9b21f31b0d GS/Vulkan: Fix crash is vertex/index buffer causes exec 2022-03-21 18:36:31 +00:00
lightningterror 2fedecb809 GS-hw: Purge Evangelion crc hack.
It's broken, HPO special does the job.
Someone should add it to the hw gamefixes.
2022-03-21 17:25:25 +01:00
PCSX2 Botandlightningterror b24a8c70e3 PAD: Update to latest controller database. 2022-03-21 17:14:41 +01:00
RedDevilusandrefractionpcsx2 d6684efd26 GameDB: GS HW Batch X
Relevant:
Bully
Colosseum - Road to Freedom
Dark Chronicle (Dark Cloud 2)
Killzone
God of War
Gun
Midnight Club 3
Mortal Kombat - Deadly Alliance
Need for Speed Carbon / Most Wanted / Undercover
Prince of Persia - Sand of Time / The Two Thrones / Warrior Within
Resident Evil 4 (BioHazard 4)
Thrillville / Off the Rails
2022-03-21 15:04:45 +00:00
TellowKrinkleandrefractionpcsx2 644241959a GS: Fix inverted DSB check 2022-03-21 02:33:38 +00:00
TellowKrinkleandrefractionpcsx2 273c1b1922 GS: Clean up leftover definitions
Accidentally leftover during the blend op refactor
2022-03-21 02:33:38 +00:00
Connor McLaughlinandrefractionpcsx2 45682c382f GS: Add NO_COLOR flag to PS (depth-only) 2022-03-20 23:41:33 +00:00
Connor McLaughlinandrefractionpcsx2 4e6b86f8f4 GS/Vulkan: Use VK_ARM_rasterization_order_attachment_access if available 2022-03-20 23:41:33 +00:00
Connor McLaughlinandrefractionpcsx2 a6b4ca69db GS/Vulkan: Support rendering without D32S8 2022-03-20 23:41:33 +00:00
Connor McLaughlinandrefractionpcsx2 6b32e00097 GS: Make factors part of blend state
Instead of using the blend map indices.
2022-03-20 23:41:33 +00:00
Connor McLaughlinandrefractionpcsx2 19d310475b GS: Draw alpha pass when dual source blend is missing 2022-03-20 23:41:33 +00:00
Connor McLaughlinandrefractionpcsx2 a8b9df3952 GS: Utilize GL_EXT_framebuffer_fetch where available 2022-03-20 23:41:33 +00:00
Connor McLaughlinandrefractionpcsx2 bb75c78c1a GS: Add option to disable texture barriers/geometry shaders 2022-03-20 23:41:33 +00:00
Mrlinkwiiandrefractionpcsx2 57ea137982 Gamedb: add missing serials 2022-03-20 23:25:42 +00:00
refractionpcsx2 9721ed0fb3 GS: Use pixel format mask for FBMSK checks 2022-03-20 23:24:42 +00:00
Mrlinkwiiandrefractionpcsx2 224863fbd5 GameDB: adds 'VUSyncHack' to Panzer Elite Action - Fields of Glory 2022-03-20 17:40:43 +00:00
Mrlinkwiiandrefractionpcsx2 1d459d8fab Gamedb: Remove VU rounding form 'Hitman - Contracts' 2022-03-20 15:30:00 +00:00
arcum42@gmail.comandrefractionpcsx2 33e0ac729e Core: Remove memcmp_mmx. 2022-03-20 12:54:58 +00:00
Connor McLaughlinandrefractionpcsx2 268ecf42c3 Build: Remove 32bit configs from vsprops 2022-03-20 12:53:42 +00:00
refractionpcsx2 708281f00b GS: Properly detect 16bit format on Texture Shuffle + Convert 2022-03-20 06:49:16 +00:00
RedDevilusandrefractionpcsx2 56b68a50e9 GameDB: Even more GS HW Fixes
Affects:
Ape Escape 3
Armored Core Last Raven
Berserk
Forever Kingdom
Front Mission 4 / 5
Need For Speed Underground 1 / 2
Kings Field 4 - The Ancient City
Test Drive Unlimited
Jak 2 / 3 / X
2022-03-20 05:57:18 +00:00
RedDevilusandrefractionpcsx2 e4048dc2dd CI: Update labeler to expand WX 2022-03-20 04:50:29 +00:00
TheLastRarandrefractionpcsx2 5949c772d1 Qt: Fix bugs relating to per-game settings 2022-03-20 04:13:45 +00:00
RafaelTrepaUnCarballoandrefractionpcsx2 63998b64cc fix comment format 2022-03-20 04:10:11 +00:00
RafaelTrepaUnCarballoandrefractionpcsx2 fbb3ea142a Add files via upload
Added gshack (wild arms hack) for all releases of Wild Arms Alter Code F
2022-03-20 04:10:11 +00:00
Tyler Wildingandrefractionpcsx2 435f760b5d GameDB: remove duplicate YAML keys 2022-03-20 04:03:03 +00:00
Tyler Wildingandrefractionpcsx2 f47129bd72 deps: update rapid-yaml to v0.4.1 2022-03-20 04:03:03 +00:00
Tyler Wildingandrefractionpcsx2 aa42acfe22 common: fix method name and clarify some behaviour 2022-03-20 04:03:03 +00:00
Tyler Wildingandrefractionpcsx2 ddfe6ac5c1 memcard: update ryml parsing for folder memory cards
also make the file handling safer
2022-03-20 04:03:03 +00:00
Tyler Wildingandrefractionpcsx2 624dff1b96 gamedb: move away from deprecated ryml::parse func 2022-03-20 04:03:03 +00:00
Tyler Wildingandrefractionpcsx2 8d498b564d deps: update rapid-yaml to latest commit
has a bug fix that we hit in folder memory cards
2022-03-20 04:03:03 +00:00
Christian Kennyandrefractionpcsx2 26561261bc Core: Remove unused code 2022-03-20 04:00:27 +00:00
Connor McLaughlinandrefractionpcsx2 44728be719 Misc: Fix incorrect printf of std::string_view 2022-03-20 04:00:13 +00:00
Tzerinasandrefractionpcsx2 678bb1218b GameDB: Add fixes for Tak Games
SoftwareRendererFMVHack for Tak 1&2, Half-Pixel Offset (Texture) for Guardians of Gross.
2022-03-20 04:00:04 +00:00
RedDevilusandrefractionpcsx2 c496e80eac PCSX2-GUI: Rename skipdraw and IDC for Partial Invalidation
Skipdraw and SkipDrawOffset isn't obvious to what it is. SkipDrawStart and SkipDrawEnd makes it obvious it's a range of values.
Also forgot to change the IDC for Disabling Partial Invalidation.
2022-03-20 03:59:38 +00:00
refractionpcsx2 269db188d0 Build: Remove 32bit from CMake. 2022-03-20 00:39:39 +00:00
refractionpcsx2 f5afbfd4f5 GS: Remove 32bit code from SW renderer 2022-03-20 00:39:39 +00:00
refractionpcsx2 ccd86a242c EE/VU JIT: Remove 32bit code 2022-03-20 00:39:39 +00:00
refractionpcsx2 42a5cb7ad2 Build: Remove 32bit targets from VS solution 2022-03-20 00:39:39 +00:00
Tyler Wildingandrefractionpcsx2 6977323d88 ci: remove redundant words from job names
its always 64bit now!
2022-03-19 21:19:48 +00:00
Tyler Wildingandrefractionpcsx2 7b1d03d45a ci: add link to previous release page in discord announcement 2022-03-19 21:19:48 +00:00
Tyler Wildingandrefractionpcsx2 8a4f1ef51a ci: stop building 32-bit
At this point -- not cleaning up the solution files / etc, only our actions.

Until the 32bit code itself is removed, we should still have an easy way to flip these back on.
2022-03-19 21:19:48 +00:00
Mrlinkwiiandrefractionpcsx2 9b50bb2e81 Gamedb: remove no longer needed comments 2022-03-19 15:56:06 +00:00
Connor McLaughlinandrefractionpcsx2 4f27d779a1 GS/DX11: Fix incorrect format check for compressed textures 2022-03-19 03:57:20 +00:00
RedDevilusandrefractionpcsx2 73c6353351 Qt: Partial Invalidation
Some missing strings from the renaming.
2022-03-18 23:47:21 +00:00
Immersion95andGitHub f571b66a43 GameDB: HW fixes for Mega Man/Rockman X7 + Clamping mode fix (#5694) 2022-03-18 20:53:48 +00:00
BuildToolsandrefractionpcsx2 901664ba44 GameDB: Rename fastTextureInvalidation
Attempt 2 renames fastTextureInvalidation to disablePartialInvalidation for more consistency with the new GUI name.
2022-03-18 13:52:36 +00:00
Immersion95andrefractionpcsx2 02012b5491 GameDB: HW fixes for Rockman X8
SoftwareRendererFMVHack for the NTSC-J & NTSC-K version of Megaman X8
2022-03-18 10:24:58 +00:00
TellowKrinkleandtellowkrinkle 4f57e40c91 GS:SW: Fix lod on x64 2022-03-18 03:59:51 -05:00
RedDevilusandrefractionpcsx2 832e536a9e GameDB: Haunting Ground + 50 Cent and Level 5
Ranging from blurriness to font artifacts.
2022-03-18 08:44:33 +00:00
BuildToolsandrefractionpcsx2 c2316ca5bc GUI: Rename Fast Texture Invalidation
Renames Fast Texture Invalidation to Disable Partial Invalidation.

Update GraphicsSettingsWidget.ui
2022-03-18 02:11:12 +00:00
refractionpcsx2 3535edcfa1 GameDB: Add partial preloading to Stolen 2022-03-17 18:40:11 +00:00
KrossXandrefractionpcsx2 a4932ed0f1 GameDB: Add DMABusy fix to Shining Wind 2022-03-17 14:33:07 +00:00
515d9040a1 GameDB: Add gsHWFixes for Tales of Symphonia
Co-Authored-By: RedDevilus <martensregis@gmail.com>
2022-03-17 09:16:20 +00:00
Connor McLaughlinandrefractionpcsx2 fe3a743814 ImGuiManager: Cap usage percents to 100% 2022-03-17 09:10:12 +00:00
Connor McLaughlinandrefractionpcsx2 8e08cd772b PerformanceMetrics: Add GPU time 2022-03-17 09:10:12 +00:00
Connor McLaughlinandrefractionpcsx2 206f80c5f4 GS: Compute SW CPU per-thread not per-draw 2022-03-17 09:10:12 +00:00
RedDevilusandrefractionpcsx2 c6ce380042 GameDB: More GS HW Fixes
Some extra comments for Monster Lab and SSX Tricky.

New entries:

- Alter Echo
- Beyond Good and Evil
- Dragon Ball Z - Budokai Tenkaichi 2
- Fatal Frame 1 / 3
- Ghost in the Shell - Stand Alone Complex
- Global Defence Force
- Xenosaga 1 / 2 / 3
2022-03-17 08:57:58 +00:00
lightningterror 939d98d660 Qt: Allow skipdraw up to 10k max. 2022-03-17 02:44:14 +01:00
lightningterror c9a3420f85 GS: Fix Wunused-variable warnings. 2022-03-17 00:50:28 +01:00
refractionpcsx2 9a1a399bac GameDB: Add a bunch of hw fixes and upscaling fixes 2022-03-16 23:40:53 +00:00
RedDevilusandrefractionpcsx2 c8aac1dca9 GameDB: Ace Combat + Soul Calibur + Metal Gear Solid Series
Missing mipmap from the Europese Ace Combat Zero/4/5, Align Sprite for them and Round Sprite. Align Sprite for SoulCalibur series.
Metal Gear 2 substance gets round sprite for font and Metal Gear 3 Subsistence gets Special (Texture) for blurriness.
2022-03-16 22:38:39 +00:00
lightningterror 14c17916f5 GS-hw: Optimize blending equations based on alpha value.
It will allow us to use free sw blending without texture barriers.

Will be especially helpful for opengl/vulkan.
2022-03-16 15:17:00 +01:00
RedDevilusandGitHub 7b0576d7cc GameDB: Dog Island and COD Final Fronts (#5671) 2022-03-16 07:24:05 +00:00
Blackbird88andGitHub ecb118d5af GameDB: Add gsHWFixes for GTA LCS/VCS (#5662)
Co authored by @Blackbird88
2022-03-15 20:22:19 +00:00
RedDevilusandrefractionpcsx2 efbf187b35 GameDB: Upscaling GS Batch 2
Adds second batch of upscaling fixes.
2022-03-15 20:21:15 +00:00
Tzerinasandrefractionpcsx2 2ea3feba90 GameDB: Add Upscaling Fixes to Onimusha 3
Adds Half-Pixel Offset: Special (Texture) and Round Sprite (Full) to Onimusha 3: Demon Siege
2022-03-15 20:19:06 +00:00
Tzerinasandrefractionpcsx2 f265257efb GameDB: Add Software FMV to Grandia 2 and Xtreme
Adds the SoftwareRendererFMV hack to Grandia 2 and Xtreme. Also adjusted titles.
2022-03-15 20:18:43 +00:00
lightningterror 13cc0caed7 GS Debugger: Fix hw hacks behavior not properly disabling. 2022-03-15 15:46:24 +01:00
refractionpcsx2 2068240e1a GS: Adjust Auto Flush to catch edge cases
Affected Beyond Good and Evil water
2022-03-15 10:15:21 +00:00
Tzerinasandrefractionpcsx2 7f5901f022 GameDB: GS HW renderer fixes for Tales of the Abyss
Description of Changes
Add Half-Pixel Offset: Special (Texture) to Tales of the Abyss.
2022-03-15 09:38:24 +00:00
a022de6225 GameDB: Add gsHWFixes for Shutokou Battle 01. (#5659)
Co-authored-by: Tokman5 <isozin_1210@yahoo.co.jp>
2022-03-15 08:12:52 +00:00
RedDevilusandrefractionpcsx2 f5570b7f40 GameDB: Rogue Galaxy
Adds half roundsprite to make upscaled HW more like software mode such as minimap while fighting.
2022-03-15 08:11:17 +00:00
RedDevilusandrefractionpcsx2 7e1c48694a GameDB: Upscaling GS Batch 1
Fixes the lint and adds a bunch of upscaling fixes.
2022-03-15 00:54:38 +00:00
lightningterror a546f61ea8 Qt: Fix Round sprite hack not applying. 2022-03-14 23:43:25 +01:00
PCSX2 Botandlightningterror 7ecac10eee PAD: Update to latest controller database. 2022-03-14 22:20:49 +01:00
Mrlinkwiiandrefractionpcsx2 ee2e10e86b GameDB: correct and update serials 2022-03-14 19:15:50 +00:00
RedDevilusandrefractionpcsx2 7752f44a90 GameDB: Documentation
Add values for GameDB, GUI options and the default to easier make GameDB changes
2022-03-14 19:14:40 +00:00
refractionpcsx2 e01fc3eb47 GS: Loosen requirement for half bottom 2022-03-14 19:14:26 +00:00
SaltyBetandrefractionpcsx2 910c8190e0 GameDB: Added missing variants of NAMCO games 2022-03-14 15:47:02 +00:00
SaltyBetandrefractionpcsx2 a62ccc0d69 GameDB: Auto GS HW renderer fixes for some NAMCO games
- Tekken 4
- Tekken 5
- Tekken Tag Tournament
2022-03-14 15:47:02 +00:00
Dreadmothandrefractionpcsx2 4f47041108 GameDB: Metal Arms - Glitch in the System (PAL)
Force disable mVU Flag Hack to prevent SPS
2022-03-14 15:33:39 +00:00
Connor McLaughlinandrefractionpcsx2 16cfde0538 GS: Use single array for dump packets 2022-03-14 15:26:19 +00:00
Connor McLaughlinandrefractionpcsx2 6a15d46461 Qt: Improve boot filename autodetection 2022-03-14 15:26:19 +00:00
Connor McLaughlinandrefractionpcsx2 4331ae1925 VMManager: Support playing back GS dumps 2022-03-14 15:26:19 +00:00
Connor McLaughlinandrefractionpcsx2 4d85d916b7 GS: Move dump file loading to core 2022-03-14 15:26:19 +00:00
Connor McLaughlinandrefractionpcsx2 4f4b14dd4d GameList: Add GetEntryByCRC() 2022-03-14 15:26:19 +00:00
Connor McLaughlinandrefractionpcsx2 444e650711 StringUtil: Add StartsWithNoCase/EndsWithNoCase 2022-03-14 15:26:19 +00:00
refractionpcsx2 c65ccaa153 GS-Config: Clear missing manual GS fixes 2022-03-14 11:08:39 +00:00
Connor McLaughlinandrefractionpcsx2 6b54db9b75 GS/VertexTrace: Fix min/max when last provoking vertex unsupported
This was causing incorrect min/max alpha values due to the index swap,
which caused the sides of text boxes in KH to disappear (because the
alpha test optimized to always failing).

Closes #5639.
2022-03-14 08:47:32 +00:00
Mrlinkwiiandrefractionpcsx2 3bab470db6 Docs : Add GS hardware fixes and MTVUSpeedHack 2022-03-13 18:33:37 +00:00
refractionpcsx2 adf01cb56a GS-Build: Fix Dump Verticles for linux 2022-03-13 05:01:51 +00:00
refractionpcsx2 bbe3af7f61 GS-Debug: Dump verticles with draws
- Move context dumping to the top so we see it as the game set, not after we've messed with it.
Thanks to tadanokojin for these changes
2022-03-13 03:46:16 +00:00
refractionpcsx2 3e7d32c807 GameDB: Give slightly clearer message for GS Fix override 2022-03-13 03:18:44 +00:00
refractionpcsx2 76e25cb738 GameDB: Add mipmapping/trilinear for Hot Shots/Everybody's Golf games 2022-03-13 02:34:29 +00:00
refractionpcsx2 8f0dc34847 GS: Improvements to MTBA address calculation 2022-03-13 01:55:08 +00:00
RedDevilusandrefractionpcsx2 fc6ec2cc02 GameDB: Transformers Armada: Prelude to Energon
Adds missing VIFFIFO + force disabling MTVU for not getting black screen
2022-03-13 01:53:48 +00:00
refractionpcsx2 34b7b07ff8 GameDB: Added a whole host of auto GS HW renderer fixes 2022-03-13 01:53:15 +00:00
Connor McLaughlinandrefractionpcsx2 6c33b73cdd GS: Make TC offset changable without recreating 2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 1e86ba4120 GS: Append game serial/name to dump filename 2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 89c79aa6c3 GSDump: Add embedded screenshot 2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 4ed748fa30 GSDump: Add extensible header and serial
Serial is used to apply hw fixes.
2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 5569e94f41 GS: Make setting change detection more fine grained
Avoids the slower full restart when it's not needed.
2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 892eec79ed Workflows: Fix lint-gamedb for gsHWFixes 2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 b248b4a8af GameDB: Add HW fixes for GTASA/GOW/GOW2 2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 39fe467b64 GS: Purge CRCs of unused titles 2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 1c301ec889 GS: Move point list palette to gamedb 2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 de5690ddcb GS: Move texture-inside-rt flag to gamedb 2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 f376c8f7ae GS: Remove second source of truth for HWMipmap 2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 2e199d47a8 GS: Move automatic mipmapping override to gamedb 2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 96269db93e GameDatabase: Add ability to override GS fixes 2022-03-12 20:48:51 +00:00
Connor McLaughlinandrefractionpcsx2 d35db63d73 GS: Reference GSConfig instead of using theApp
Removes multiple sources of truth, enables overrides.
2022-03-12 20:48:51 +00:00
refractionpcsx2 9d003486c2 GS-hw: Attempt to improve half screen detection 2022-03-12 12:28:18 +00:00
refractionpcsx2 0c4b85980c GS: Support local to local transfers that overwrite themselves 2022-03-12 12:27:43 +00:00
Connor McLaughlinandrefractionpcsx2 5961db6b9b GS/Vulkan: Elide render pass restarts on depth buffer toggle 2022-03-12 12:22:51 +00:00
Connor McLaughlinandrefractionpcsx2 d0039c2920 Gif_Unit: Vectorize analyzeTag() 2022-03-12 12:10:32 +00:00
TellowKrinkleandrefractionpcsx2 5bdec2f532 x86emitter: Fix x64 8-bit rmw codegen 2022-03-11 12:59:57 +00:00
refractionpcsx2 fd758bb307 GameDB: Added MTVU disable to InstantVU off games 2022-03-11 10:25:15 +00:00
refractionpcsx2 a11d09ebdf Git: Update GameDB Validation script 2022-03-11 10:25:15 +00:00
refractionpcsx2 d294064da6 GameDB: Disable MTVU on T-Bit games 2022-03-11 10:25:15 +00:00
refractionpcsx2 fd4a5acc40 MTVU: Try to make T-Bit more reliable.
Add MTVUSpeedHack option to GameDB so it can be forcefully disabled
2022-03-11 10:25:15 +00:00
refractionpcsx2 05a7a61257 GS/Autoflush: Handle different page widths/arrangements 2022-03-11 10:24:26 +00:00
refractionpcsx2 90a4a11d49 GS: Add Auto Flush for Z buffer draws
Adjust Burnout CRC hack
2022-03-11 10:24:26 +00:00
lightningterror d9f914eb7c GS-hw: Move the Ad to As equation swap when alpha is masked to Basic level and higher on gl/vk.
Safer this way, otherwise need to take in to account when accumulation, non recursive, and blend mix is enabled, or manually enable them on Minimum level.

Everything that we need is enabled on Basic level.

Change is done for clamp 1 only.
2022-03-09 23:24:44 +01:00
TheLastRarandrefractionpcsx2 134242973b Config: Set a sane default value for HddSizeSectors 2022-03-09 10:07:54 +00:00
TheLastRarandrefractionpcsx2 92900d8dc8 Config: Fix manual subnet mask save/load 2022-03-09 10:07:54 +00:00
Ziemasandrefractionpcsx2 7a970e1d00 Filesystem: Properly convert stat return to bool.
Two of the overloads where wrong.
2022-03-09 09:33:51 +00:00
331 changed files with 25813 additions and 6907 deletions
+5
View File
@@ -27,6 +27,11 @@
'GUI/WX':
- 'pcsx2/gui/*'
- 'pcsx2/gui/**/*'
- 'pcsx2/SPU2/wx/*'
- 'pcsx2/SPU2/wx/**/*'
- 'pcsx2/PAD/Linux/wx_dialog/*'
- 'pcsx2/PAD/Linux/wx_dialog/**/*'
- 'pcsx2/GS/Window/GSwxDialog.h'
'GUI/Qt':
- 'pcsx2-qt/*'
- 'pcsx2-qt/**/*'
+6 -12
View File
@@ -44,12 +44,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
platform: x86
compiler: gcc
cmakeflags: -DLTO_PCSX2_CORE=ON
appimage: true
experimental: false
- os: ubuntu-18.04
platform: x64
compiler: gcc
@@ -57,7 +51,7 @@ jobs:
appimage: true
experimental: false
- os: ubuntu-18.04
platform: x86
platform: x64
compiler: clang
# Need to disable PCH until cmake 3.17
# (PCH conflicts with ccache, fixed by https://gitlab.kitware.com/cmake/cmake/-/merge_requests/4400)
@@ -66,21 +60,21 @@ jobs:
appimage: false
experimental: false
- os: ubuntu-18.04
platform: x86
platform: x64
compiler: gcc
cmakeflags: -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON
detail: " nopch"
appimage: false
experimental: false
- os: ubuntu-18.04
platform: x86
platform: x64
compiler: gcc
cmakeflags: -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON -DARCH_FLAG=-march=haswell
detail: " avx2 nopch"
appimage: false
experimental: false
name: ${{ matrix.platform }} | ${{ matrix.compiler }}${{ matrix.detail }}
name: ${{ matrix.compiler }}${{ matrix.detail }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
@@ -120,7 +114,7 @@ jobs:
message("::set-output name=timestamp::${current_date}")
- name: ccache cache files
uses: actions/cache@v2.1.7
uses: actions/cache@v3
with:
path: .ccache
key: ${{ matrix.os }} ${{ matrix.platform }} ${{ matrix.compiler }}${{ matrix.detail }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
@@ -160,7 +154,7 @@ jobs:
run: .github/workflows/scripts/linux/install-packages.sh
- name: Cache Dependencies
uses: actions/cache@v2.1.7
uses: actions/cache@v3
with:
path: |
3rdparty/${{ env.SDL }}
-1
View File
@@ -70,7 +70,6 @@ jobs:
platform: [x64]
experimental: [false]
name: ${{ matrix.platform }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
@@ -8,52 +8,17 @@ if (!releaseInfo.prerelease) {
process.exit(0);
}
const assets = releaseInfo.assets;
let windowsAssetLinks = "";
let linuxAssetLinks = "";
for (var i = 0; i < assets.length; i++) {
let asset = assets[i];
if (asset.name.includes("symbols")) {
continue;
}
if (asset.name.includes("windows")) {
let friendlyName = asset.name;
try {
friendlyName = asset.name.split("windows-")[1].split(".7z")[0].replace("-", " ");
} catch (e) {
console.log(e);
}
windowsAssetLinks += `- [${friendlyName}](${asset.browser_download_url})\n`
} else if (asset.name.includes("linux")) {
let friendlyName = asset.name;
try {
friendlyName = asset.name.split("linux-")[1].split(".AppImage")[0].replace("-", " ");
} catch (e) {
console.log(e);
}
linuxAssetLinks += `- [${friendlyName}](${asset.browser_download_url})\n`
}
}
// Publish Webhook
const embed = new MessageEmbed()
.setColor('#FF8000')
.setTitle('New PCSX2 Nightly Build Available!')
.setDescription("To download the latest or previous builds, [visit the official downloads page](https://pcsx2.net/downloads/).")
.addFields(
{ name: 'Version', value: releaseInfo.tag_name, inline: true },
{ name: 'Release Link', value: `[Github Release](${releaseInfo.html_url})`, inline: true },
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true },
{ name: 'Included Changes', value: releaseInfo.body, inline: false }
);
if (windowsAssetLinks != "") {
embed.addField('Windows Downloads', windowsAssetLinks, false);
}
if (linuxAssetLinks != "") {
embed.addField('Linux Downloads', linuxAssetLinks, false);
}
const webhookClient = new WebhookClient({ url: process.env.DISCORD_BUILD_WEBHOOK });
await webhookClient.send({
embeds: [embed],
@@ -111,11 +111,8 @@ const { data: releaseAssetsPost } = await octokit.rest.repos.listReleaseAssets({
// Expected Assets, if we have all of them, we will publish it
let expectedAssets = {
"windows-32bit-sse4": false,
"windows-32bit-avx2": false,
"windows-64bit-sse4": false,
"windows-64bit-avx2": false,
"linux-appimage-32bit": false,
"linux-appimage-64bit": false
}
@@ -12,6 +12,7 @@ allowed_game_options = [
"roundModes",
"clampModes",
"gameFixes",
"gsHWFixes",
"speedHacks",
"memcardFilters",
"patches",
@@ -19,24 +20,56 @@ allowed_game_options = [
allowed_round_modes = ["eeRoundMode", "vuRoundMode"]
allowed_clamp_modes = ["eeClampMode", "vuClampMode"]
allowed_game_fixes = [
"VuAddSubHack",
"FpuCompareHack",
"FpuMulHack",
"FpuNegDivHack",
"XGKickHack",
"EETimingHack",
"GoemonTlbHack",
"SoftwareRendererFMVHack",
"SkipMPEGHack",
"OPHFlagHack",
"EETimingHack",
"DMABusyHack",
"GIFFIFOHack",
"VIFFIFOHack",
"VIF1StallHack",
"GIFFIFOHack",
"GoemonTlbHack",
"VUSyncHack",
"VuAddSubHack",
"IbitHack",
"VUSyncHack",
"VUOverflowHack",
"XGKickHack",
]
allowed_speed_hacks = ["mvuFlagSpeedHack", "InstantVU1SpeedHack"]
allowed_gs_hw_fixes = [
"autoFlush",
"conservativeFramebuffer",
"cpuFramebufferConversion",
"disableDepthSupport",
"wrapGSMem",
"preloadFrameData",
"disablePartialInvalidation",
"textureInsideRT",
"alignSprite",
"mergeSprite",
"wildArmsHack",
"pointListPalette",
"mipmap",
"trilinearFiltering",
"skipDrawStart",
"skipDrawEnd",
"halfBottomOverride",
"halfPixelOffset",
"roundSprite",
"texturePreloading",
"interlace",
]
gs_hw_fix_ranges = {
"mipmap": (0, 2),
"trilinearFiltering": (0, 2),
"skipDrawStart": (0, 100000),
"skipDrawEnd": (0, 100000),
"halfPixelOffset": (0, 3),
"roundSprite": (0, 2),
"interlace": (0, 7),
}
allowed_speed_hacks = ["mvuFlagSpeedHack", "InstantVU1SpeedHack", "MTVUSpeedHack"]
# Patches are allowed to have a 'default' key or a crc-32 key, followed by
allowed_patch_options = ["author", "content"]
@@ -94,6 +127,29 @@ def validate_game_fixes(serial, key, value):
validate_valid_options(serial, key, gamefix, allowed_game_fixes)
def validate_gs_hw_fix_value(serial, key, value):
low, high = 0, 1
if key in gs_hw_fix_ranges:
low, high = gs_hw_fix_ranges[key]
validate_int_option(serial, key, value, low, high)
def validate_gs_hw_fixes(serial, key, value):
if not isinstance(value, dict):
issue_list.append("[{}]: 'gsHWFixes' must be a valid object".format(serial))
return
for fix, fix_value in value.items():
validate_valid_options(serial, key, fix, allowed_gs_hw_fixes)
validate_gs_hw_fix_value(serial, fix, fix_value)
# skipdraw range must have end >= start
skip_draw_start = value["skipDrawStart"] if "skipDrawStart" in value else 0
skip_draw_end = value["skipDrawEnd"] if "skipDrawEnd" in value else 0
if isinstance(skip_draw_start, int) and isinstance(skip_draw_end, int) and skip_draw_end < skip_draw_start:
issue_list.append("[{}]: skipDrawStart({}) must be greater or equal to skipDrawEnd({})".format(
serial, skip_draw_start, skip_draw_end))
def validate_speed_hacks(serial, key, value):
if not isinstance(value, dict):
issue_list.append("[{}]: 'speedHacks' must be a valid object".format(serial))
@@ -145,6 +201,7 @@ option_validation_handlers = {
)
),
"gameFixes": (lambda serial, key, value: validate_game_fixes(serial, key, value)),
"gsHWFixes": (lambda serial, key, value: validate_gs_hw_fixes(serial, key, value)),
"speedHacks": (lambda serial, key, value: validate_speed_hacks(serial, key, value)),
"memcardFilters": (
lambda serial, key, value: validate_list_of_strings(serial, key, value)
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
mv ./game_controller_db.txt ${{github.workspace}}/bin/resources/game_controller_db.txt
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
uses: peter-evans/create-pull-request@v4
with:
title: "PAD: Update to latest controller database"
commit-message: "PAD: Update to latest controller database."
+7 -10
View File
@@ -41,14 +41,11 @@ jobs:
fail-fast: false
matrix:
os: [windows-2019]
platform: [Win32, x64]
platform: [x64]
configuration: [Release, Release AVX2, CMake, Qt]
experimental: [false]
exclude:
- platform: win32
configuration: Qt
name: ${{ matrix.platform }} | ${{ matrix.configuration }}
name: ${{ matrix.configuration }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
@@ -70,18 +67,18 @@ jobs:
run: git submodule update --init --recursive -j $env:NUMBER_OF_PROCESSORS
- name: Setup Buildcache
if: matrix.configuration == 'CMake' # TODO: buildcache on VS
uses: mikehardy/buildcache-action@v1.2.2
with:
cache_key: ${{ matrix.os }} ${{ matrix.platform }} ${{ matrix.configuration }}
if: matrix.configuration == 'CMake' # TODO: buildcache on VS
- name: Verify VS Project Files
run: .github\workflows\scripts\windows\validate-vs-filters.ps1
if: matrix.configuration != 'CMake'
run: .github\workflows\scripts\windows\validate-vs-filters.ps1
- name: Setup msbuild
uses: microsoft/setup-msbuild@v1
if: matrix.configuration != 'CMake'
uses: microsoft/setup-msbuild@v1
- name: Download Qt build files
if: matrix.configuration == 'Qt'
@@ -93,6 +90,7 @@ jobs:
del qt-6.2.2-x64.7z
- name: Generate CMake
if: matrix.configuration == 'CMake'
id: cmake
shell: cmd
run: |
@@ -102,7 +100,6 @@ jobs:
echo ::set-output name=buildtype::%type%
echo ::set-output name=vcvars::%vcvars%
cmake . -B build -DCMAKE_BUILD_TYPE=%type% -DLTO_PCSX2_CORE=ON -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_CXX_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON
if: matrix.configuration == 'CMake'
- name: Build PCSX2
shell: cmd
@@ -123,11 +120,11 @@ jobs:
)
- name: Run Tests
if: matrix.configuration == 'CMake'
shell: cmd
run: |
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
cmake --build build --config ${{ steps.cmake.outputs.buildtype }} --target unittests
if: matrix.configuration == 'CMake'
- name: Prepare Artifact Metadata
id: artifact-metadata
+1 -14
View File
@@ -90,25 +90,12 @@ oprofile_data/
/bin/plugins
/bin/snaps
/bin/sstates
/bin/textures
/bin/translations
/deps
/ipch
!/3rdparty/libjpeg/change.log
/3rdparty/portaudio/portaudio-2.0.pc
/3rdparty/portaudio/bin
/3rdparty/portaudio/bin-*
/3rdparty/portaudio/autom4te.cache
/3rdparty/portaudio/libtool
/3rdparty/portaudio/config.*
/3rdparty/portaudio/lib-stamp
/3rdparty/portaudio/Makefile
/3rdparty/portaudio/bindings
/3rdparty/portaudio/test
/3rdparty/portaudio/testcvs
/3rdparty/portaudio/src/hostapi/asio/ASIOSDK/common
/3rdparty/portaudio/src/hostapi/asio/ASIOSDK/host
/3rdparty/portaudio/src/hostapi/wasapi/mingw-include
/3rdparty/**/include/wx/setup.h
/3rdparty/**/wx/msw/rcdefs.h
/pcsx2/gui/Resources/*.h
+10 -15
View File
@@ -52,6 +52,7 @@
<ClInclude Include="rapidyaml\src\ryml_std.hpp" />
<ClInclude Include="rapidyaml\src\c4\yml\detail\checks.hpp" />
<ClInclude Include="rapidyaml\src\c4\yml\detail\parser_dbg.hpp" />
<ClInclude Include="rapidyaml\src\c4\yml\detail\print.hpp" />
<ClInclude Include="rapidyaml\src\c4\yml\detail\stack.hpp" />
<ClInclude Include="rapidyaml\src\c4\yml\common.hpp" />
<ClCompile Include="rapidyaml\src\c4\yml\common.cpp" />
@@ -72,8 +73,7 @@
<ClCompile Include="rapidyaml\src\c4\yml\tree.cpp" />
<ClInclude Include="rapidyaml\src\c4\yml\writer.hpp" />
<ClInclude Include="rapidyaml\src\c4\yml\yml.hpp" />
<Natvis Include="rapidyaml\src\ryml.natvis">
</Natvis>
<Natvis Include="rapidyaml\src\ryml.natvis"></Natvis>
<ClInclude Include="rapidyaml\ext\c4core\src\c4\allocator.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\base64.hpp" />
<ClCompile Include="rapidyaml\ext\c4core\src\c4\base64.cpp" />
@@ -89,6 +89,7 @@
<ClInclude Include="rapidyaml\ext\c4core\src\c4\config.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\cpu.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ctor_dtor.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\dump.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\enum.hpp" />
<ClCompile Include="rapidyaml\ext\c4core\src\c4\error.cpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\error.hpp" />
@@ -107,35 +108,29 @@
<ClInclude Include="rapidyaml\ext\c4core\src\c4\restrict.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\span.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\std.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\std_fwd.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\string.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\string_fwd.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\tuple.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\vector.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\vector_fwd.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\substr.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\substr_fwd.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\szconv.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\time.hpp" />
<ClCompile Include="rapidyaml\ext\c4core\src\c4\time.cpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\type_name.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\types.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\unrestrict.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\utf.hpp" />
<ClCompile Include="rapidyaml\ext\c4core\src\c4\utf.cpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\windows.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\windows_pop.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\windows_push.hpp" />
<Natvis Include="rapidyaml\ext\c4core\src\c4\c4core.natvis">
</Natvis>
<Natvis Include="rapidyaml\ext\c4core\src\c4\c4core.natvis"></Natvis>
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\debugbreak\debugbreak.h" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\rng\rng.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\sg14\inplace_function.h" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float.hpp" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\ascii_number.h" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\bigint.h" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\decimal_to_binary.h" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\digit_comparison.h" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\fast_float.h" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\fast_table.h" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\float_common.h" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\parse_number.h" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\simple_decimal_conversion.h" />
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float_all.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
+1 -294
View File
@@ -54,6 +54,7 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glad", "3rdparty\glad\glad.vcxproj", "{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ryml", "3rdparty\rapidyaml\ryml.vcxproj", "{DE9653B6-17DD-356A-9EE0-28A731772587}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cubeb", "3rdparty\cubeb\cubeb.vcxproj", "{BF74C473-DC04-44B3-92E8-4145F4E77342}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simpleini", "3rdparty\simpleini\simpleini.vcxproj", "{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}"
@@ -64,594 +65,300 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glslang", "3rdparty\glslang
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug AVX2|Win32 = Debug AVX2|Win32
Debug AVX2|x64 = Debug AVX2|x64
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Devel AVX2|Win32 = Devel AVX2|Win32
Devel AVX2|x64 = Devel AVX2|x64
Devel|Win32 = Devel|Win32
Devel|x64 = Devel|x64
Release AVX2|Win32 = Release AVX2|Win32
Release AVX2|x64 = Release AVX2|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug AVX2|Win32.ActiveCfg = Debug AVX2|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug AVX2|Win32.Build.0 = Debug AVX2|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug AVX2|x64.ActiveCfg = Debug AVX2|x64
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug AVX2|x64.Build.0 = Debug AVX2|x64
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|Win32.ActiveCfg = Debug|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|Win32.Build.0 = Debug|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|x64.ActiveCfg = Debug|x64
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|x64.Build.0 = Debug|x64
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel AVX2|Win32.ActiveCfg = Devel AVX2|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel AVX2|Win32.Build.0 = Devel AVX2|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel AVX2|x64.ActiveCfg = Devel AVX2|x64
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel AVX2|x64.Build.0 = Devel AVX2|x64
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel|Win32.ActiveCfg = Devel|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel|Win32.Build.0 = Devel|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel|x64.ActiveCfg = Devel|x64
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel|x64.Build.0 = Devel|x64
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release AVX2|Win32.ActiveCfg = Release AVX2|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release AVX2|Win32.Build.0 = Release AVX2|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release AVX2|x64.ActiveCfg = Release AVX2|x64
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release AVX2|x64.Build.0 = Release AVX2|x64
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|Win32.ActiveCfg = Release|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|Win32.Build.0 = Release|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|x64.ActiveCfg = Release|x64
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|x64.Build.0 = Release|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|Win32.Build.0 = Debug|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|x64.ActiveCfg = Debug|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|x64.Build.0 = Debug|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|Win32.ActiveCfg = Debug|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|Win32.Build.0 = Debug|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|x64.ActiveCfg = Debug|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|x64.Build.0 = Debug|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|Win32.Build.0 = Devel|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|x64.ActiveCfg = Devel|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|x64.Build.0 = Devel|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|Win32.ActiveCfg = Devel|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|Win32.Build.0 = Devel|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|x64.ActiveCfg = Devel|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|x64.Build.0 = Devel|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|Win32.ActiveCfg = Release|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|Win32.Build.0 = Release|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|x64.ActiveCfg = Release|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|x64.Build.0 = Release|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|Win32.ActiveCfg = Release|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|Win32.Build.0 = Release|Win32
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|x64.ActiveCfg = Release|x64
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|x64.Build.0 = Release|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|Win32.Build.0 = Debug|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|x64.ActiveCfg = Debug|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|x64.Build.0 = Debug|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|Win32.ActiveCfg = Debug|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|Win32.Build.0 = Debug|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|x64.ActiveCfg = Debug|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|x64.Build.0 = Debug|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|Win32.Build.0 = Devel|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|x64.ActiveCfg = Devel|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|x64.Build.0 = Devel|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|Win32.ActiveCfg = Devel|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|Win32.Build.0 = Devel|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|x64.ActiveCfg = Devel|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|x64.Build.0 = Devel|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|Win32.ActiveCfg = Release|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|Win32.Build.0 = Release|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|x64.ActiveCfg = Release|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|x64.Build.0 = Release|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|Win32.ActiveCfg = Release|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|Win32.Build.0 = Release|Win32
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|x64.ActiveCfg = Release|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|x64.Build.0 = Release|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|Win32.Build.0 = Debug|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|x64.ActiveCfg = Debug|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|x64.Build.0 = Debug|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|Win32.ActiveCfg = Debug|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|Win32.Build.0 = Debug|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|x64.ActiveCfg = Debug|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|x64.Build.0 = Debug|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|Win32.Build.0 = Devel|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|x64.ActiveCfg = Devel|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|x64.Build.0 = Devel|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|Win32.ActiveCfg = Devel|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|Win32.Build.0 = Devel|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|x64.ActiveCfg = Devel|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|x64.Build.0 = Devel|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|Win32.ActiveCfg = Release|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|Win32.Build.0 = Release|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|x64.ActiveCfg = Release|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|x64.Build.0 = Release|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|Win32.ActiveCfg = Release|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|Win32.Build.0 = Release|Win32
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|x64.ActiveCfg = Release|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|x64.Build.0 = Release|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|Win32.Build.0 = Debug|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|x64.ActiveCfg = Debug|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|x64.Build.0 = Debug|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|Win32.ActiveCfg = Debug|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|Win32.Build.0 = Debug|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|x64.ActiveCfg = Debug|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|x64.Build.0 = Debug|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|Win32.Build.0 = Devel|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|x64.ActiveCfg = Devel|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|x64.Build.0 = Devel|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|Win32.ActiveCfg = Devel|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|Win32.Build.0 = Devel|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|x64.ActiveCfg = Devel|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|x64.Build.0 = Devel|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|Win32.ActiveCfg = Release|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|Win32.Build.0 = Release|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|x64.ActiveCfg = Release|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|x64.Build.0 = Release|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|Win32.ActiveCfg = Release|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|Win32.Build.0 = Release|Win32
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|x64.ActiveCfg = Release|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|x64.Build.0 = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|Win32.Build.0 = Debug|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|x64.ActiveCfg = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|x64.Build.0 = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|Win32.ActiveCfg = Debug|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|Win32.Build.0 = Debug|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|x64.ActiveCfg = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|x64.Build.0 = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|Win32.Build.0 = Devel|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|x64.ActiveCfg = Devel|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|x64.Build.0 = Devel|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|Win32.ActiveCfg = Devel|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|Win32.Build.0 = Devel|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|x64.ActiveCfg = Devel|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|x64.Build.0 = Devel|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|Win32.ActiveCfg = Release|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|Win32.Build.0 = Release|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|x64.ActiveCfg = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|x64.Build.0 = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|Win32.ActiveCfg = Release|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|Win32.Build.0 = Release|Win32
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|x64.ActiveCfg = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|x64.Build.0 = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|Win32.Build.0 = Debug|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|x64.ActiveCfg = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|x64.Build.0 = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.ActiveCfg = Debug|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.Build.0 = Debug|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.ActiveCfg = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.Build.0 = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|Win32.Build.0 = Devel|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|x64.ActiveCfg = Devel|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|x64.Build.0 = Devel|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|Win32.ActiveCfg = Devel|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|Win32.Build.0 = Devel|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|x64.ActiveCfg = Devel|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|x64.Build.0 = Devel|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|Win32.ActiveCfg = Release|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|Win32.Build.0 = Release|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|x64.ActiveCfg = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|x64.Build.0 = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|Win32.ActiveCfg = Release|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|Win32.Build.0 = Release|Win32
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.ActiveCfg = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.Build.0 = Release|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug AVX2|Win32.Build.0 = Debug|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug AVX2|x64.ActiveCfg = Debug|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug AVX2|x64.Build.0 = Debug|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug|Win32.ActiveCfg = Debug|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug|Win32.Build.0 = Debug|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug|x64.ActiveCfg = Debug|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug|x64.Build.0 = Debug|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel AVX2|Win32.Build.0 = Devel|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel AVX2|x64.ActiveCfg = Devel|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel AVX2|x64.Build.0 = Devel|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel|Win32.ActiveCfg = Devel|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel|Win32.Build.0 = Devel|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel|x64.ActiveCfg = Devel|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel|x64.Build.0 = Devel|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release AVX2|Win32.ActiveCfg = Release|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release AVX2|Win32.Build.0 = Release|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release AVX2|x64.ActiveCfg = Release|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release AVX2|x64.Build.0 = Release|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release|Win32.ActiveCfg = Release|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release|Win32.Build.0 = Release|Win32
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release|x64.ActiveCfg = Release|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release|x64.Build.0 = Release|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug AVX2|Win32.Build.0 = Debug|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug AVX2|x64.ActiveCfg = Debug|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug AVX2|x64.Build.0 = Debug|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|Win32.ActiveCfg = Debug|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|Win32.Build.0 = Debug|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|x64.ActiveCfg = Debug|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|x64.Build.0 = Debug|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel AVX2|Win32.Build.0 = Devel|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel AVX2|x64.ActiveCfg = Devel|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel AVX2|x64.Build.0 = Devel|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel|Win32.ActiveCfg = Devel|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel|Win32.Build.0 = Devel|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel|x64.ActiveCfg = Devel|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel|x64.Build.0 = Devel|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release AVX2|Win32.ActiveCfg = Release|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release AVX2|Win32.Build.0 = Release|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release AVX2|x64.ActiveCfg = Release|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release AVX2|x64.Build.0 = Release|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|Win32.ActiveCfg = Release|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|Win32.Build.0 = Release|Win32
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|x64.ActiveCfg = Release|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|x64.Build.0 = Release|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|Win32.Build.0 = Debug|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|x64.ActiveCfg = Debug|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|x64.Build.0 = Debug|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|Win32.ActiveCfg = Debug|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|Win32.Build.0 = Debug|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|x64.ActiveCfg = Debug|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|x64.Build.0 = Debug|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|Win32.Build.0 = Devel|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|x64.ActiveCfg = Devel|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|x64.Build.0 = Devel|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|Win32.ActiveCfg = Devel|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|Win32.Build.0 = Devel|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|x64.ActiveCfg = Devel|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|x64.Build.0 = Devel|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|Win32.ActiveCfg = Release|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|Win32.Build.0 = Release|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|x64.ActiveCfg = Release|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|x64.Build.0 = Release|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|Win32.ActiveCfg = Release|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|Win32.Build.0 = Release|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.ActiveCfg = Release|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.Build.0 = Release|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|Win32.Build.0 = Debug|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|x64.ActiveCfg = Debug|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|x64.Build.0 = Debug|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|Win32.ActiveCfg = Debug|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|Win32.Build.0 = Debug|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|x64.ActiveCfg = Debug|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|x64.Build.0 = Debug|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|Win32.Build.0 = Devel|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|x64.ActiveCfg = Devel|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|x64.Build.0 = Devel|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|Win32.ActiveCfg = Devel|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|Win32.Build.0 = Devel|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|x64.ActiveCfg = Devel|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|x64.Build.0 = Devel|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|Win32.ActiveCfg = Release|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|Win32.Build.0 = Release|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|x64.ActiveCfg = Release|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|x64.Build.0 = Release|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|Win32.ActiveCfg = Release|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|Win32.Build.0 = Release|Win32
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|x64.ActiveCfg = Release|x64
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|x64.Build.0 = Release|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|Win32.Build.0 = Debug|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|x64.ActiveCfg = Debug|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|x64.Build.0 = Debug|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|Win32.ActiveCfg = Debug|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|Win32.Build.0 = Debug|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|x64.ActiveCfg = Debug|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|x64.Build.0 = Debug|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|Win32.Build.0 = Devel|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|x64.ActiveCfg = Devel|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|x64.Build.0 = Devel|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|Win32.ActiveCfg = Devel|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|Win32.Build.0 = Devel|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|x64.ActiveCfg = Devel|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|x64.Build.0 = Devel|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|Win32.ActiveCfg = Release|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|Win32.Build.0 = Release|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|x64.ActiveCfg = Release|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|x64.Build.0 = Release|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|Win32.ActiveCfg = Release|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|Win32.Build.0 = Release|Win32
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|x64.ActiveCfg = Release|x64
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|x64.Build.0 = Release|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|Win32.Build.0 = Debug|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|x64.ActiveCfg = Debug|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|x64.Build.0 = Debug|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.ActiveCfg = Debug|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.Build.0 = Debug|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.ActiveCfg = Debug|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.Build.0 = Debug|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|Win32.Build.0 = Devel|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|x64.ActiveCfg = Devel|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|x64.Build.0 = Devel|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|Win32.ActiveCfg = Devel|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|Win32.Build.0 = Devel|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|x64.ActiveCfg = Devel|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|x64.Build.0 = Devel|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|Win32.ActiveCfg = Release|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|Win32.Build.0 = Release|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|x64.ActiveCfg = Release|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|x64.Build.0 = Release|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.ActiveCfg = Release|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.Build.0 = Release|Win32
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.ActiveCfg = Release|x64
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.Build.0 = Release|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|Win32.Build.0 = Debug|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|x64.ActiveCfg = Debug|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|x64.Build.0 = Debug|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|Win32.ActiveCfg = Debug|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|Win32.Build.0 = Debug|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|x64.ActiveCfg = Debug|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|x64.Build.0 = Debug|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|Win32.Build.0 = Devel|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|x64.ActiveCfg = Devel|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|x64.Build.0 = Devel|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|Win32.ActiveCfg = Devel|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|Win32.Build.0 = Devel|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|x64.ActiveCfg = Devel|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|x64.Build.0 = Devel|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|Win32.ActiveCfg = Release|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|Win32.Build.0 = Release|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|x64.ActiveCfg = Release|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|x64.Build.0 = Release|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|Win32.ActiveCfg = Release|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|Win32.Build.0 = Release|Win32
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|x64.ActiveCfg = Release|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|x64.Build.0 = Release|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|Win32.Build.0 = Debug|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|x64.ActiveCfg = Debug|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|x64.Build.0 = Debug|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|Win32.ActiveCfg = Debug|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|Win32.Build.0 = Debug|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|x64.ActiveCfg = Debug|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|x64.Build.0 = Debug|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|Win32.Build.0 = Devel|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|x64.ActiveCfg = Devel|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|x64.Build.0 = Devel|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|Win32.ActiveCfg = Devel|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|Win32.Build.0 = Devel|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|x64.ActiveCfg = Devel|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|x64.Build.0 = Devel|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|Win32.ActiveCfg = Release|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|Win32.Build.0 = Release|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|x64.ActiveCfg = Release|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|x64.Build.0 = Release|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|Win32.ActiveCfg = Release|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|Win32.Build.0 = Release|Win32
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|x64.ActiveCfg = Release|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|x64.Build.0 = Release|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|Win32.Build.0 = Debug|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|x64.ActiveCfg = Debug|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|x64.Build.0 = Debug|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|Win32.ActiveCfg = Debug|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|Win32.Build.0 = Debug|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|x64.ActiveCfg = Debug|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|x64.Build.0 = Debug|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|Win32.Build.0 = Devel|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|x64.ActiveCfg = Devel|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|x64.Build.0 = Devel|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|Win32.ActiveCfg = Devel|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|Win32.Build.0 = Devel|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|x64.ActiveCfg = Devel|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|x64.Build.0 = Devel|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|Win32.ActiveCfg = Release|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|Win32.Build.0 = Release|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|x64.ActiveCfg = Release|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|x64.Build.0 = Release|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|Win32.ActiveCfg = Release|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|Win32.Build.0 = Release|Win32
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|x64.ActiveCfg = Release|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|x64.Build.0 = Release|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|Win32.Build.0 = Debug|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|x64.ActiveCfg = Debug|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|x64.Build.0 = Debug|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|Win32.ActiveCfg = Debug|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|Win32.Build.0 = Debug|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|x64.ActiveCfg = Debug|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|x64.Build.0 = Debug|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|Win32.Build.0 = Devel|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|x64.ActiveCfg = Devel|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|x64.Build.0 = Devel|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|Win32.ActiveCfg = Devel|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|Win32.Build.0 = Devel|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|x64.ActiveCfg = Devel|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|x64.Build.0 = Devel|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|Win32.ActiveCfg = Release|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|Win32.Build.0 = Release|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|x64.ActiveCfg = Release|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|x64.Build.0 = Release|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|Win32.ActiveCfg = Release|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|Win32.Build.0 = Release|Win32
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|x64.ActiveCfg = Release|x64
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|x64.Build.0 = Release|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|Win32.Build.0 = Debug|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|x64.ActiveCfg = Debug|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|x64.Build.0 = Debug|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|Win32.ActiveCfg = Debug|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|Win32.Build.0 = Debug|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|x64.ActiveCfg = Debug|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|x64.Build.0 = Debug|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|Win32.Build.0 = Devel|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|x64.ActiveCfg = Devel|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|x64.Build.0 = Devel|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|Win32.ActiveCfg = Devel|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|Win32.Build.0 = Devel|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|x64.ActiveCfg = Devel|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|x64.Build.0 = Devel|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|Win32.ActiveCfg = Release|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|Win32.Build.0 = Release|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|x64.ActiveCfg = Release|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|x64.Build.0 = Release|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Release|Win32.ActiveCfg = Release|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Release|Win32.Build.0 = Release|Win32
{4639972E-424E-4E13-8B07-CA403C481346}.Release|x64.ActiveCfg = Release|x64
{4639972E-424E-4E13-8B07-CA403C481346}.Release|x64.Build.0 = Release|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|Win32.Build.0 = Debug|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|x64.ActiveCfg = Debug|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|x64.Build.0 = Debug|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|Win32.ActiveCfg = Debug|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|Win32.Build.0 = Debug|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|x64.ActiveCfg = Debug|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|x64.Build.0 = Debug|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|Win32.Build.0 = Devel|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|x64.ActiveCfg = Devel|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|x64.Build.0 = Devel|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|Win32.ActiveCfg = Devel|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|Win32.Build.0 = Devel|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|x64.ActiveCfg = Devel|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|x64.Build.0 = Devel|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|Win32.ActiveCfg = Release|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|Win32.Build.0 = Release|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|x64.ActiveCfg = Release|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|x64.Build.0 = Release|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|Win32.ActiveCfg = Release|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|Win32.Build.0 = Release|Win32
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|x64.ActiveCfg = Release|x64
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|x64.Build.0 = Release|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|Win32.Build.0 = Debug|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|x64.ActiveCfg = Debug|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|x64.Build.0 = Debug|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|Win32.ActiveCfg = Debug|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|Win32.Build.0 = Debug|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|x64.ActiveCfg = Debug|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|x64.Build.0 = Debug|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|Win32.Build.0 = Devel|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|x64.ActiveCfg = Devel|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|x64.Build.0 = Devel|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|Win32.ActiveCfg = Devel|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|Win32.Build.0 = Devel|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|x64.ActiveCfg = Devel|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|x64.Build.0 = Devel|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|Win32.ActiveCfg = Release|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|Win32.Build.0 = Release|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|x64.ActiveCfg = Release|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|x64.Build.0 = Release|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|Win32.ActiveCfg = Release|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|Win32.Build.0 = Release|Win32
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|x64.ActiveCfg = Release|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|x64.Build.0 = Release|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|Win32.Build.0 = Debug|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|x64.ActiveCfg = Debug|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|x64.Build.0 = Debug|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|Win32.ActiveCfg = Debug|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|Win32.Build.0 = Debug|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|x64.ActiveCfg = Debug|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|x64.Build.0 = Debug|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|Win32.Build.0 = Devel|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|x64.ActiveCfg = Devel|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|x64.Build.0 = Devel|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|Win32.ActiveCfg = Devel|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|Win32.Build.0 = Devel|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|x64.ActiveCfg = Devel|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|x64.Build.0 = Devel|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|Win32.ActiveCfg = Release|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|Win32.Build.0 = Release|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|x64.ActiveCfg = Release|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|x64.Build.0 = Release|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|Win32.ActiveCfg = Release|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|Win32.Build.0 = Release|Win32
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|x64.ActiveCfg = Release|x64
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|x64.Build.0 = Release|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|Win32.Build.0 = Debug|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|x64.ActiveCfg = Debug|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|x64.Build.0 = Debug|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|Win32.ActiveCfg = Debug|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|Win32.Build.0 = Debug|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|x64.ActiveCfg = Debug|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|x64.Build.0 = Debug|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|Win32.Build.0 = Devel|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|x64.ActiveCfg = Devel|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|x64.Build.0 = Devel|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|Win32.ActiveCfg = Devel|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|Win32.Build.0 = Devel|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|x64.ActiveCfg = Devel|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|x64.Build.0 = Devel|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|Win32.ActiveCfg = Release|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|Win32.Build.0 = Release|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|x64.ActiveCfg = Release|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|x64.Build.0 = Release|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|Win32.ActiveCfg = Release|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|Win32.Build.0 = Release|Win32
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|x64.ActiveCfg = Release|x64
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|x64.Build.0 = Release|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|Win32.Build.0 = Debug|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|x64.ActiveCfg = Debug|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|x64.Build.0 = Debug|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|Win32.ActiveCfg = Debug|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|Win32.Build.0 = Debug|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|x64.ActiveCfg = Debug|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|x64.Build.0 = Debug|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|Win32.Build.0 = Devel|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|x64.ActiveCfg = Devel|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|x64.Build.0 = Devel|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|Win32.ActiveCfg = Devel|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|Win32.Build.0 = Devel|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|x64.ActiveCfg = Devel|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|x64.Build.0 = Devel|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|Win32.ActiveCfg = Release|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|Win32.Build.0 = Release|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|x64.ActiveCfg = Release|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|x64.Build.0 = Release|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|Win32.ActiveCfg = Release|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|Win32.Build.0 = Release|Win32
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|x64.ActiveCfg = Release|x64
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|x64.Build.0 = Release|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|Win32.Build.0 = Debug|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|x64.ActiveCfg = Debug|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|x64.Build.0 = Debug|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|Win32.ActiveCfg = Debug|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|Win32.Build.0 = Debug|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|x64.ActiveCfg = Debug|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|x64.Build.0 = Debug|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|Win32.Build.0 = Devel|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|x64.ActiveCfg = Devel|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|x64.Build.0 = Devel|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|Win32.ActiveCfg = Devel|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|Win32.Build.0 = Devel|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|x64.ActiveCfg = Devel|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|x64.Build.0 = Devel|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|Win32.ActiveCfg = Release|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|Win32.Build.0 = Release|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|x64.ActiveCfg = Release|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|x64.Build.0 = Release|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|Win32.ActiveCfg = Release|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|Win32.Build.0 = Release|Win32
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|x64.ActiveCfg = Release|x64
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|x64.Build.0 = Release|x64
EndGlobalSection
+3 -2
View File
@@ -9,7 +9,7 @@ PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to
## Project Details
The PCSX2 project has been running for more than ten years. Past versions could only run a few public domain game demos, but newer versions can run most games at full speed, including popular titles such as Final Fantasy X and Devil May Cry 3. Visit the [PCSX2 compatibility list](https://pcsx2.net/compatibility-list.html) to check the latest compatibility status of games (with more than 2500 titles tested), or ask for help in the [official forums](https://forums.pcsx2.net/).
The PCSX2 project has been running for more than ten years. Past versions could only run a few public domain game demos, but newer versions can run most games at full speed, including popular titles such as Final Fantasy X and Devil May Cry 3. Visit the [PCSX2 compatibility list](https://pcsx2.net/compat/) to check the latest compatibility status of games (with more than 2500 titles tested), or ask for help in the [official forums](https://forums.pcsx2.net/).
The latest officially released stable version is version 1.6.0.
@@ -23,7 +23,7 @@ Development builds are also available from [Github](https://github.com/PCSX2/pcs
| Operating System | CPU | GPU | RAM |
| ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| - Windows 8.1 or newer (32 or 64 bit) <br/> - Ubuntu 18.04/Debian or newer, Arch Linux, or other distro (32 or 64 bit) | - Supports SSE4.1 <br/> - [PassMark Single Thread Performance](https://www.cpubenchmark.net/singleThread.html) rating near or greater than 1600 <br/> - Two physical cores, with hyperthreading | - Direct3D10 support <br/> - OpenGL 3.x support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 3000 (GeForce GTX 750) <br/> - 2 GB Video Memory | 4 GB |
| - Windows 8.1 or newer (64 bit) <br/> - Ubuntu 18.04/Debian or newer, Arch Linux, or other distro (64 bit) | - Supports SSE4.1 <br/> - [PassMark Single Thread Performance](https://www.cpubenchmark.net/singleThread.html) rating near or greater than 1600 <br/> - Two physical cores, with hyperthreading | - Direct3D10 support <br/> - OpenGL 3.x support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 3000 (GeForce GTX 750) <br/> - 2 GB Video Memory | 4 GB |
_Note: Recommended Single Thread Performance is based on moderately complex games. Games that pushed the PS2 hardware to its limits will struggle on CPUs at this level. Some release titles and 2D games which underutilized the PS2 hardware may run on CPUs rated as low as 1200. A quick reference for CPU **intensive games**: [Wiki](https://wiki.pcsx2.net/Category:CPU_intensive_games), [Forum](https://forums.pcsx2.net/Thread-LIST-The-Most-CPU-Intensive-Games) and CPU **light** games: [Forum](https://forums.pcsx2.net/Thread-LIST-Games-that-don-t-need-a-strong-CPU-to-emulate)_
@@ -40,6 +40,7 @@ _Note: Recommended GPU is based on 3x Internal, ~1080p resolution requirements.
- You need the [Visual C++ 2019 x86 Redistributables](https://support.microsoft.com/en-us/help/2977003/) to run PCSX2.
- Windows XP and Direct3D9 support was dropped after stable release 1.4.0.
- Windows 7 and Windows 8 support was dropped after stable release 1.6.0.
- 32 bit support was dropped after stable release 1.6.0.
- Make sure to update your operating system and drivers to ensure you have the best experience possible. Having a newer GPU is also recommended so you have the latest supported drivers.
- Because of copyright issues, and the complexity of trying to work around it, you need a BIOS dump extracted from a legitimately-owned PS2 console to use the emulator. For more information about the BIOS and how to get it from your console, visit [this page](pcsx2/Docs/PCSX2_FAQ.md#question-13-where-do-i-get-a-ps2-bios).
- PCSX2 uses two CPU cores for emulation by default. A third core can be used via the MTVU speed hack, which is compatible with most games. This can be a significant speedup on CPUs with 3+ cores, but it may be a slowdown on GS-limited games (or on CPUs with fewer than 2 cores). Software renderers will then additionally use however many rendering threads it is set to and will need higher core counts to run efficiently.
Binary file not shown.
+4379 -1304
View File
File diff suppressed because it is too large Load Diff
+32 -21
View File
@@ -39,6 +39,7 @@
03000000c82d00000360000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000361000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000660000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000131000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00002867000000000000,8BitDo S30 Modkit,a:b0,b:b1,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b8,lefttrigger:b9,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00000130000000000000,8BitDo SF30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000060000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
@@ -181,7 +182,7 @@
03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Windows,
03000000b40400001224000000000000,Flydigi Vader 2 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,paddle3:b17,paddle4:b18,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
030000008305000000a0000000000000,G08XU,a:b0,b:b1,back:b4,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b5,x:b2,y:b3,platform:Windows,
03000000ac0500002d02000000000000,G2U,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000ac0500002d02000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
0300000066f700000100000000000000,Game VIB Joystick,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:Windows,
03000000260900002625000000000000,GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,
03000000341a000005f7000000000000,GameCube Controller,a:b2,b:b3,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b1,y:b0,platform:Windows,
@@ -190,8 +191,8 @@
03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
030000008f0e00000d31000000000000,Gamepad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000280400000140000000000000,GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000ac0500003d03000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000ac0500004d04000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000ac0500003d03000000000000,GameSir G3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000ac0500004d04000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
030000004c0e00001035000000000000,Gamester,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
030000000d0f00001110000000000000,GameStick Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
0300000047530000616d000000000000,GameStop,a:b0,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:b2,y:b3,platform:Windows,
@@ -390,8 +391,8 @@
030000006b140000080d000000000000,Nacon Revolution Unlimited Pro Controller,a:b1,b:b2,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:b0,y:b3,platform:Windows,
03000000bd12000001c0000000000000,Nebular,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:a5,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
03000000eb0300000000000000000000,NeGcon Adapter,a:a2,b:b13,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,lefttrigger:a4,leftx:a1,righttrigger:b11,start:b3,x:a3,y:b12,platform:Windows,
0300000092120000474e000000000000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Windows,
0300000038070000efbe000000000000,NEO SE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
0300000092120000474e000000000000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Windows,
03000000921200004b46000000000000,NES 2 port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows,
03000000000f00000100000000000000,NES Controller,a:b1,b:b0,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
03000000571d00002100000000000000,NES Controller,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
@@ -400,10 +401,10 @@
030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Windows,
03000000050b00000045000000000000,Nexus,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Windows,
03000000152000000182000000000000,NGDS,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:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
030000007e0500001920000000000000,Nintendo Switch N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Windows,
030000007e0500001720000000000000,Nintendo Switch Online Controller,a:b0,b:b1,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:b2,y:b3,platform:Windows,
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000007e0500001920000000000000,NSO N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Windows,
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000000d0500000308000000000000,Nostromo N45,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:Windows,
030000007e0500001720000000000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Windows,
03000000550900001472000000000000,NVIDIA Controller,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,
03000000550900001072000000000000,NVIDIA Shield,a:b9,b:b8,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b3,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b2,righttrigger:a4,rightx:a2,righty:a5,start:b0,x:b7,y:b6,platform:Windows,
030000005509000000b4000000000000,NVIDIA Virtual,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
@@ -527,7 +528,7 @@
03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
03000000830500006020000000000000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
03000000bd12000013d0000000000000,Retrolink Sega Saturn Classic Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,
03000000bd12000015d0000000000000,Retrolink Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000bd12000015d0000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,leftshoulder:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
0300000000f000000300000000000000,RetroUSB RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
0300000000f00000f100000000000000,RetroUSB Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
03000000830500000960000000000000,Revenger,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b5,platform:Windows,
@@ -540,12 +541,12 @@
030000006f0e00001e01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00002801000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00002f01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
03000000050b00005819000000000000,ROG Chakram Core,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
03000000050b0000181a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
03000000050b00001a1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
03000000050b00001c1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
030000004f04000001d0000000000000,Rumble Force,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:Windows,
030000008916000000fe000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000c6240000045d000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
@@ -707,7 +708,7 @@
03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000450c00002043000000000000,Xeox SL6556BK,a:b0,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:b2,y:b3,platform:Windows,
030000006f0e00000300000000000000,XGear,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
03000000ac0500005b05000000000000,Xiaoji Gamesir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000ac0500005b05000000000000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000172700004431000000000000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
@@ -732,6 +733,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00000190000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,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:b4,y:b3,platform:Mac OS X,
03000000c82d00000660000000020000,8BitDo Pro 2,a:b1,b:b0,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:b4,y:b3,platform:Mac OS X,
03000000c82d00000131000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000102800000900000000000000,8Bitdo SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00001290000001000000,8BitDo SN30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00004028000000010000,8Bitdo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
@@ -758,6 +760,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000d8140000cecf000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000a306000022f6000001030000,Cyborg V3 Rumble Pad PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,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,
030000000d0f00008400000000010000,Fighting Commander,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00008500000000010000,Fighting Commander,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:Mac OS X,
03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
@@ -819,6 +822,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000d620000011a7000010050000,Nintendo Switch PowerA 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:Mac OS X,
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
030000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Mac OS X,
030000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000550900001472000025050000,NVIDIA Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,
030000006f0e00000901000002010000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
@@ -833,6 +838,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000004c050000c405000000010000,PS4 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000cc09000000010000,PS4 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
050000004c050000e60c000000010000,PS5 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
03000000222c00000020000000010000,Qanba Drone Arcade Stick,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008916000000fd000000000000,Razer Onza TE,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,
03000000321500000204000000010000,Razer Panthera 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:Mac OS X,
03000000321500000104000000010000,Razer Panthera 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -877,7 +883,6 @@ 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,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,
@@ -921,6 +926,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
03000000c82d00000660000011010000,8BitDo Pro 2,a:b1,b:b0,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:b4,y:b3,platform:Linux,
05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,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:b4,y:b3,platform:Linux,
03000000c82d00000131000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00000061000000010000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
030000003512000012ab000010010000,8Bitdo SFC30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,
@@ -967,7 +973,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,
05000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:-a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,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,
@@ -986,18 +992,20 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,
03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,
03000000a306000022f6000011010000,Cyborg V3 Rumble,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:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,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,
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,
03000000242f00009100000000010000,EasySMX ESM-9101,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,
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,
03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
05000000ac0500002d0200001b010000,Gamesir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,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,
03000000bc2000005656000011010000,Gamesir T4w,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,
05000000ac0500002d0200001b010000,GameSir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,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,
03000000558500001b06000010010000,GameSir G4 Pro,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,platform:Linux,
03000000bc2000005656000011010000,GameSir T4w,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,
0500000047532047616d657061640000,GameStop Gamepad,a:b0,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:b2,y:b3,platform:Linux,
030000006f0e00000104000000010000,Gamestop Logic3 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,
030000008f0e00000800000010010000,Gasia PlayStation Gamepad,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,
@@ -1107,6 +1115,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e0400008e02000062230000,Microsoft Xbox 360,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,
030000005e040000d102000001010000,Microsoft Xbox One,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,
030000005e040000d102000003020000,Microsoft Xbox One,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,
060000005e040000120b000009050000,Microsoft Xbox One,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,
030000005e040000dd02000003020000,Microsoft Xbox One 2015,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,
030000005e040000e302000003020000,Microsoft Xbox One Elite,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,
030000005e040000000b000008040000,Microsoft Xbox One Elite 2,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,
@@ -1137,17 +1146,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
060000007e0500000820000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,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,
050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b16,b:b15,back:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b14,y:b17,platform:Linux,
050000007e0500001920000001000000,Nintendo Switch N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux,
050000007e0500001720000001000000,Nintendo Switch Online 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,
050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux,
03000000d620000013a7000011010000,Nintendo Switch PowerA 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,
03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus 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,
030000007e0500000920000011810000,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,
050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
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 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,
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,
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,
050000007e0500001720000001000000,NSO SNES 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,
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,
05000000550900001472000001000000,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,
@@ -1324,7 +1333,6 @@ 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,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,
@@ -1352,14 +1360,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
060000005e040000ea0200000b050000,Xbox One S 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,
030000005e040000120b000001050000,Xbox Series 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,
030000005e040000120b000005050000,Xbox Series 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,
030000005e040000120b00000d050000,Xbox Series 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,misc1:b11,platform:Linux,
030000005e040000130b000005050000,Xbox Series Controller,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,
050000005e040000130b000001050000,Xbox Series Controller,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,
050000005e040000130b000005050000,Xbox Series Controller,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,
050000005e040000130b000009050000,Xbox Series Controller,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,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
060000005e040000120b00000b050000,Xbox Series 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,
050000005e040000130b000011050000,Xbox Series X Controller,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,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000130b000013050000,Xbox Series Controller,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,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000130b000007050000,Xbox Wireless Controller,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,
03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,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:b2,y:b3,platform:Linux,
03000000ac0500005b05000010010000,Xiaoji Gamesir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000ac0500005b05000010010000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,
03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,
xinput,XInput 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,
+103 -81
View File
@@ -1,8 +1,11 @@
#if defined(SHADER_MODEL) || defined(FXAA_GLSL_130)
#if defined(SHADER_MODEL) || defined(FXAA_GLSL_130) || defined(FXAA_GLSL_VK) || defined(__METAL_VERSION__)
#ifndef FXAA_GLSL_130
#define FXAA_GLSL_130 0
#endif
#ifndef FXAA_GLSL_VK
#define FXAA_GLSL_VK 0
#endif
#define UHQ_FXAA 1 //High Quality Fast Approximate Anti Aliasing. Adapted for GS from Timothy Lottes FXAA 3.11.
#define FxaaSubpixMax 0.0 //[0.00 to 1.00] Amount of subpixel aliasing removal. 0.00: Edge only antialiasing (no blurring)
@@ -17,6 +20,12 @@ in vec2 PSin_t;
layout(location = 0) out vec4 SV_Target0;
#elif (FXAA_GLSL_VK == 1)
layout(location = 0) in vec2 PSin_t;
layout(location = 0) out vec4 SV_Target0;
layout(set = 0, binding = 0) uniform sampler2D TextureSampler;
#elif (SHADER_MODEL >= 0x400)
Texture2D Texture : register(t0);
SamplerState TextureSampler : register(s0);
@@ -38,6 +47,8 @@ struct PS_OUTPUT
float4 c : SV_Target0;
};
#elif defined(__METAL_VERSION__)
static constexpr sampler MAIN_SAMPLER(coord::normalized, address::clamp_to_edge, filter::linear);
#endif
/*------------------------------------------------------------------------------
@@ -52,7 +63,10 @@ struct PS_OUTPUT
#define FXAA_HLSL_4 1
#define FXAA_GATHER4_ALPHA 0
#elif (FXAA_GLSL_130 == 1)
#elif (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
#define FXAA_GATHER4_ALPHA 1
#elif defined(__METAL_VERSION__)
#define FXAA_GATHER4_ALPHA 1
#endif
@@ -72,7 +86,7 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; };
#define FxaaDiscard clip(-1)
#define FxaaSat(x) saturate(x)
#elif (FXAA_GLSL_130 == 1)
#elif (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
#define int2 ivec2
#define float2 vec2
#define float3 vec3
@@ -89,23 +103,31 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; };
#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
#endif
#elif defined(__METAL_VERSION__)
#define FxaaTex texture2d<float>
#define FxaaTexTop(t, p) t.sample(MAIN_SAMPLER, p)
#define FxaaTexOff(t, p, o, r) t.sample(MAIN_SAMPLER, p, o)
#define FxaaTexAlpha4(t, p) t.gather(MAIN_SAMPLER, p, 0, component::w)
#define FxaaTexOffAlpha4(t, p, o) t.gather(MAIN_SAMPLER, p, o, component::w)
#define FxaaDiscard discard_fragment()
#define FxaaSat(x) saturate(x)
#endif
#define FxaaEdgeThreshold 0.063
#define FxaaEdgeThresholdMin 0.00
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 2.0
#define FXAA_QUALITY__P5 2.0
#define FXAA_QUALITY__P6 2.0
#define FXAA_QUALITY__P7 2.0
#define FXAA_QUALITY__P8 2.0
#define FXAA_QUALITY__P9 2.0
#define FXAA_QUALITY__P10 4.0
#define FXAA_QUALITY__P11 8.0
#define FXAA_QUALITY__P12 8.0
#define FXAA_QUALITY_P0 1.0
#define FXAA_QUALITY_P1 1.5
#define FXAA_QUALITY_P2 2.0
#define FXAA_QUALITY_P3 2.0
#define FXAA_QUALITY_P4 2.0
#define FXAA_QUALITY_P5 2.0
#define FXAA_QUALITY_P6 2.0
#define FXAA_QUALITY_P7 2.0
#define FXAA_QUALITY_P8 2.0
#define FXAA_QUALITY_P9 2.0
#define FXAA_QUALITY_P10 4.0
#define FXAA_QUALITY_P11 8.0
#define FXAA_QUALITY_P12 8.0
/*------------------------------------------------------------------------------
[GAMMA PREPASS CODE SECTION]
@@ -142,14 +164,8 @@ float3 LinearToRGBGamma(float3 color, float gamma)
return color;
}
float4 PreGammaPass(float4 color, float2 uv0)
float4 PreGammaPass(float4 color)
{
#if (SHADER_MODEL >= 0x400)
color = Texture.Sample(TextureSampler, uv0);
#elif (FXAA_GLSL_130 == 1)
color = texture(TextureSampler, uv0);
#endif
const float GammaConst = 2.233;
color.rgb = RGBGammaToLinear(color.rgb, GammaConst);
color.rgb = LinearToRGBGamma(color.rgb, GammaConst);
@@ -276,11 +292,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if( horzSpan) posB.y += lengthSign * 0.5;
float2 posN;
posN.x = posB.x - offNP.x * FXAA_QUALITY__P0;
posN.y = posB.y - offNP.y * FXAA_QUALITY__P0;
posN.x = posB.x - offNP.x * FXAA_QUALITY_P0;
posN.y = posB.y - offNP.y * FXAA_QUALITY_P0;
float2 posP;
posP.x = posB.x + offNP.x * FXAA_QUALITY__P0;
posP.y = posB.y + offNP.y * FXAA_QUALITY__P0;
posP.x = posB.x + offNP.x * FXAA_QUALITY_P0;
posP.y = posB.y + offNP.y * FXAA_QUALITY_P0;
float subpixD = ((-2.0)*subpixC) + 3.0;
float lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
float subpixE = subpixC * subpixC;
@@ -295,11 +311,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
lumaEndP -= lumaNN * 0.5;
bool doneN = abs(lumaEndN) >= gradientScaled;
bool doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1;
bool doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
@@ -308,11 +324,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
@@ -321,11 +337,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
@@ -334,11 +350,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
@@ -347,11 +363,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
@@ -360,11 +376,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
@@ -373,11 +389,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
@@ -386,11 +402,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
@@ -399,11 +415,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
@@ -412,11 +428,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
@@ -425,11 +441,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
@@ -438,11 +454,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12;
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12;
}}}}}}}}}}}
float dstN = posM.x - posN.x;
@@ -470,10 +486,12 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
return float4(FxaaTexTop(tex, posM).xyz, lumaM);
}
#if (FXAA_GLSL_130 == 1)
#if (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
float4 FxaaPass(float4 FxaaColor, float2 uv0)
#elif (SHADER_MODEL >= 0x400)
float4 FxaaPass(float4 FxaaColor : COLOR0, float2 uv0 : TEXCOORD0)
#elif defined(__METAL_VERSION__)
float4 FxaaPass(float4 FxaaColor, float2 uv0, texture2d<float> tex)
#endif
{
@@ -486,9 +504,12 @@ float4 FxaaPass(float4 FxaaColor : COLOR0, float2 uv0 : TEXCOORD0)
Texture.GetDimensions(PixelSize.x, PixelSize.y);
FxaaColor = FxaaPixelShader(uv0, tex, 1.0/PixelSize.xy, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin);
#elif (FXAA_GLSL_130 == 1)
#elif (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
vec2 PixelSize = textureSize(TextureSampler, 0);
FxaaColor = FxaaPixelShader(uv0, TextureSampler, 1.0/PixelSize.xy, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin);
#elif defined(__METAL_VERSION__)
float2 PixelSize = float2(tex.get_width(), tex.get_height());
FxaaColor = FxaaPixelShader(uv0, tex, 1.f/PixelSize, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin);
#endif
return FxaaColor;
@@ -497,12 +518,12 @@ float4 FxaaPass(float4 FxaaColor : COLOR0, float2 uv0 : TEXCOORD0)
/*------------------------------------------------------------------------------
[MAIN() & COMBINE PASS CODE SECTION]
------------------------------------------------------------------------------*/
#if (FXAA_GLSL_130 == 1)
#if (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
void ps_main()
void main()
{
vec4 color = texture(TextureSampler, PSin_t);
color = PreGammaPass(color, PSin_t);
color = PreGammaPass(color);
color = FxaaPass(color, PSin_t);
SV_Target0 = color;
@@ -515,7 +536,7 @@ PS_OUTPUT ps_main(VS_OUTPUT input)
float4 color = Texture.Sample(TextureSampler, input.t);
color = PreGammaPass(color, input.t);
color = PreGammaPass(color);
color = FxaaPass(color, input.t);
output.c = color;
@@ -523,6 +544,7 @@ PS_OUTPUT ps_main(VS_OUTPUT input)
return output;
}
// Metal main function in in fxaa.metal
#endif
#endif
+11 -11
View File
@@ -1,5 +1,13 @@
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
Texture2D Texture;
SamplerState Sampler;
cbuffer cb0
{
float4 params;
};
/*
** Contrast, saturation, brightness
** Code of this function is from TGM's shader pack
@@ -9,9 +17,9 @@
// For all settings: 1.0 = 100% 0.5=50% 1.5 = 150%
float4 ContrastSaturationBrightness(float4 color) // Ported to HLSL
{
const float sat = SB_SATURATION / 50.0;
const float brt = SB_BRIGHTNESS / 50.0;
const float con = SB_CONTRAST / 50.0;
float brt = params.x;
float con = params.y;
float sat = params.z;
// Increase or decrease these values to adjust r, g and b color channels separately
const float AvgLumR = 0.5;
@@ -30,14 +38,6 @@ float4 ContrastSaturationBrightness(float4 color) // Ported to HLSL
return color;
}
Texture2D Texture;
SamplerState Sampler;
cbuffer cb0
{
float4 BGColor;
};
struct PS_INPUT
{
float4 p : SV_Position;
+21
View File
@@ -57,6 +57,10 @@
#define PS_AUTOMATIC_LOD 0
#define PS_MANUAL_LOD 0
#define PS_TEX_IS_FB 0
#define PS_NO_COLOR 0
#define PS_NO_COLOR1 0
#define PS_NO_ABLEND 0
#define PS_ONLY_ALPHA 0
#endif
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
@@ -99,8 +103,12 @@ struct PS_INPUT
struct PS_OUTPUT
{
#if !PS_NO_COLOR
float4 c0 : SV_Target0;
#if !PS_NO_COLOR1
float4 c1 : SV_Target1;
#endif
#endif
#if PS_ZCLAMP
float depth : SV_Depth;
#endif
@@ -854,8 +862,21 @@ PS_OUTPUT ps_main(PS_INPUT input)
ps_fbmask(C, input.p.xy);
#if !PS_NO_COLOR
output.c0 = C / 255.0f;
#if !PS_NO_COLOR1
output.c1 = (float4)(alpha_blend);
#endif
#if PS_NO_ABLEND
// write alpha blend factor into col0
output.c0.a = alpha_blend;
#endif
#if PS_ONLY_ALPHA
// rgb isn't used
output.c0.rgb = float3(0.0f, 0.0f, 0.0f);
#endif
#endif
#if PS_ZCLAMP
output.depth = min(input.p.z, MaxDepthPS);
+5 -3
View File
@@ -11,6 +11,8 @@
#ifdef FRAGMENT_SHADER
uniform vec4 params;
in vec4 PSin_p;
in vec2 PSin_t;
in vec4 PSin_c;
@@ -20,9 +22,9 @@ layout(location = 0) out vec4 SV_Target0;
// For all settings: 1.0 = 100% 0.5=50% 1.5 = 150%
vec4 ContrastSaturationBrightness(vec4 color)
{
const float sat = SB_SATURATION / 50.0;
const float brt = SB_BRIGHTNESS / 50.0;
const float con = SB_CONTRAST / 50.0;
float brt = params.x;
float con = params.y;
float sat = params.z;
// Increase or decrease these values to adjust r, g and b color channels separately
const float AvgLumR = 0.5;
+80 -4
View File
@@ -20,6 +20,7 @@
#endif
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
#define SW_BLEND_NEEDS_RT (SW_BLEND && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1))
#ifdef FRAGMENT_SHADER
@@ -38,12 +39,36 @@ in SHADER
#endif
} PSin;
// Same buffer but 2 colors for dual source blending
layout(location = 0, index = 0) out vec4 SV_Target0;
layout(location = 0, index = 1) out vec4 SV_Target1;
#define TARGET_0_QUALIFIER out
// Only enable framebuffer fetch when we actually need it.
#if HAS_FRAMEBUFFER_FETCH && (PS_TEX_IS_FB == 1 || PS_FBMASK || SW_BLEND_NEEDS_RT || PS_DATE != 0)
// We need to force the colour to be defined here, to read from it.
// Basically the only scenario where this'll happen is RGBA masked and DATE is active.
#undef PS_NO_COLOR
#define PS_NO_COLOR 0
#if defined(GL_EXT_shader_framebuffer_fetch)
#undef TARGET_0_QUALIFIER
#define TARGET_0_QUALIFIER inout
#define LAST_FRAG_COLOR SV_Target0
#endif
#endif
#if !PS_NO_COLOR
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
// Same buffer but 2 colors for dual source blending
layout(location = 0, index = 0) TARGET_0_QUALIFIER vec4 SV_Target0;
layout(location = 0, index = 1) out vec4 SV_Target1;
#else
layout(location = 0) TARGET_0_QUALIFIER vec4 SV_Target0;
#endif
#endif
layout(binding = 1) uniform sampler2D PaletteSampler;
#if !HAS_FRAMEBUFFER_FETCH
layout(binding = 2) uniform sampler2D RtSampler; // note 2 already use by the image below
#endif
#ifndef DISABLE_GL42_image
#if PS_DATE > 0
@@ -79,7 +104,11 @@ layout(early_fragment_tests) in;
vec4 sample_c(vec2 uv)
{
#if PS_TEX_IS_FB == 1
#if HAS_FRAMEBUFFER_FETCH
return LAST_FRAG_COLOR;
#else
return texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0);
#endif
#else
#if PS_POINT_SAMPLER
@@ -234,7 +263,11 @@ mat4 sample_4p(vec4 u)
int fetch_raw_depth()
{
#if PS_TEX_IS_FB == 1
#if HAS_FRAMEBUFFER_FETCH
return int(LAST_FRAG_COLOR.r * exp2(32.0f));
#else
return int(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0).r * exp2(32.0f));
#endif
#else
return int(texelFetch(TextureSampler, ivec2(gl_FragCoord.xy), 0).r * exp2(32.0f));
#endif
@@ -243,7 +276,11 @@ int fetch_raw_depth()
vec4 fetch_raw_color()
{
#if PS_TEX_IS_FB == 1
#if HAS_FRAMEBUFFER_FETCH
return LAST_FRAG_COLOR;
#else
return texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0);
#endif
#else
return texelFetch(TextureSampler, ivec2(gl_FragCoord.xy), 0);
#endif
@@ -603,7 +640,11 @@ void ps_fbmask(inout vec4 C)
{
// FIXME do I need special case for 16 bits
#if PS_FBMASK
#if HAS_FRAMEBUFFER_FETCH
vec4 RT = trunc(LAST_FRAG_COLOR * 255.0f + 0.1f);
#else
vec4 RT = trunc(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0) * 255.0f + 0.1f);
#endif
C = vec4((uvec4(C) & ~FbMask) | (uvec4(RT) & FbMask));
#endif
}
@@ -659,7 +700,14 @@ void ps_blend(inout vec4 Color, float As)
return;
#endif
vec3 Cs = Color.rgb;
#if SW_BLEND_NEEDS_RT
#if HAS_FRAMEBUFFER_FETCH
vec4 RT = trunc(LAST_FRAG_COLOR * 255.0f + 0.1f);
#else
vec4 RT = trunc(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0) * 255.0f + 0.1f);
#endif
#if PS_DFMT == FMT_24
float Ad = 1.0f;
@@ -671,7 +719,7 @@ void ps_blend(inout vec4 Color, float As)
// Let the compiler do its jobs !
vec3 Cd = RT.rgb;
vec3 Cs = Color.rgb;
#endif
#if PS_BLEND_A == 0
vec3 A = Cs;
@@ -748,14 +796,24 @@ void ps_main()
if ((int(gl_FragCoord.y) & 1) == (PS_SCANMSK & 1))
discard;
#endif
#if PS_DATE != 0
#if ((PS_DATE & 3) == 1 || (PS_DATE & 3) == 2)
#if PS_WRITE_RG == 1
// Pseudo 16 bits access.
#if HAS_FRAMEBUFFER_FETCH
float rt_a = LAST_FRAG_COLOR.g;
#else
float rt_a = texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0).g;
#endif
#else
#if HAS_FRAMEBUFFER_FETCH
float rt_a = LAST_FRAG_COLOR.a;
#else
float rt_a = texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0).a;
#endif
#endif
#if (PS_DATE & 3) == 1
// DATM == 0: Pixel with alpha equal to 1 will failed
@@ -784,6 +842,7 @@ void ps_main()
if (gl_PrimitiveID > stencil_ceil) {
discard;
}
#endif
#endif
vec4 C = ps_color();
@@ -845,7 +904,11 @@ void ps_main()
// Must be done before alpha correction
#if (PS_BLEND_C == 1 && PS_CLR_HW > 3)
#if HAS_FRAMEBUFFER_FETCH
vec4 RT = trunc(LAST_FRAG_COLOR * 255.0f + 0.1f);
#else
vec4 RT = trunc(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0) * 255.0f + 0.1f);
#endif
float alpha_blend = (PS_DFMT == FMT_24) ? 1.0f : RT.a / 128.0f;
#else
float alpha_blend = C.a / 128.0f;
@@ -885,8 +948,21 @@ void ps_main()
ps_fbmask(C);
#if !PS_NO_COLOR
SV_Target0 = C / 255.0f;
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
SV_Target1 = vec4(alpha_blend);
#endif
#if PS_NO_ABLEND
// write alpha blend factor into col0
SV_Target0.a = alpha_blend;
#endif
#if PS_ONLY_ALPHA
// rgb isn't used
SV_Target0.rgb = vec3(0.0f);
#endif
#endif
#if PS_ZCLAMP
gl_FragDepth = min(gl_FragCoord.z, MaxDepthPS);
@@ -6,16 +6,13 @@
layout(location = 0) in vec4 a_pos;
layout(location = 1) in vec2 a_tex;
layout(location = 2) in vec4 a_color;
layout(location = 0) out vec2 v_tex;
layout(location = 1) out vec4 v_color;
void main()
{
gl_Position = vec4(a_pos.x, -a_pos.y, a_pos.z, a_pos.w);
v_tex = a_tex;
v_color = a_color;
}
#endif
@@ -23,7 +20,6 @@ void main()
#ifdef FRAGMENT_SHADER
layout(location = 0) in vec2 v_tex;
layout(location = 1) in vec4 v_color;
#if defined(ps_convert_rgba8_16bits) || defined(ps_convert_float32_32bits)
layout(location = 0) out uint o_col0;
@@ -0,0 +1,71 @@
//#version 420 // Keep it for editor detection
#ifdef VERTEX_SHADER
layout(location = 0) in vec4 a_pos;
layout(location = 1) in vec2 a_tex;
layout(location = 0) out vec2 v_tex;
void main()
{
gl_Position = vec4(a_pos.x, -a_pos.y, a_pos.z, a_pos.w);
v_tex = a_tex;
}
#endif
/*
** Contrast, saturation, brightness
** Code of this function is from TGM's shader pack
** http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=21057
** TGM's author comment about the license (included in the previous link)
** "do with it, what you want! its total free!
** (but would be nice, if you say that you used my shaders :wink: ) but not necessary"
*/
#ifdef FRAGMENT_SHADER
layout(push_constant) uniform cb0
{
vec4 params;
};
layout(set = 0, binding = 0) uniform sampler2D samp0;
layout(location = 0) in vec2 v_tex;
layout(location = 0) out vec4 o_col0;
// For all settings: 1.0 = 100% 0.5=50% 1.5 = 150%
vec4 ContrastSaturationBrightness(vec4 color)
{
float brt = params.x;
float con = params.y;
float sat = params.z;
// Increase or decrease these values to adjust r, g and b color channels separately
const float AvgLumR = 0.5;
const float AvgLumG = 0.5;
const float AvgLumB = 0.5;
const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
vec3 brtColor = color.rgb * brt;
float dot_intensity = dot(brtColor, LumCoeff);
vec3 intensity = vec3(dot_intensity, dot_intensity, dot_intensity);
vec3 satColor = mix(intensity, brtColor, sat);
vec3 conColor = mix(AvgLumin, satColor, con);
color.rgb = conColor;
return color;
}
void main()
{
vec4 c = texture(samp0, v_tex);
o_col0 = ContrastSaturationBrightness(c);
}
#endif
+27 -10
View File
@@ -378,7 +378,7 @@ layout(location = 0) in VSOutput
#endif
} vsIn;
#ifndef DISABLE_DUAL_SOURCE
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
layout(location = 0, index = 0) out vec4 o_col0;
layout(location = 0, index = 1) out vec4 o_col1;
#else
@@ -389,7 +389,13 @@ layout(set = 1, binding = 0) uniform sampler2D Texture;
layout(set = 1, binding = 1) uniform sampler2D Palette;
#if PS_FEEDBACK_LOOP_IS_NEEDED
layout(input_attachment_index = 0, set = 2, binding = 0) uniform subpassInput RtSampler;
#ifndef DISABLE_TEXTURE_BARRIER
layout(input_attachment_index = 0, set = 2, binding = 0) uniform subpassInput RtSampler;
vec4 sample_from_rt() { return subpassLoad(RtSampler); }
#else
layout(set = 2, binding = 0) uniform texture2D RtSampler;
vec4 sample_from_rt() { return texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0); }
#endif
#endif
#if PS_DATE > 0
@@ -399,7 +405,7 @@ layout(set = 2, binding = 1) uniform texture2D PrimMinTexture;
vec4 sample_c(vec2 uv)
{
#if PS_TEX_IS_FB
return subpassLoad(RtSampler);
return sample_from_rt();
#else
#if PS_POINT_SAMPLER
// Weird issue with ATI/AMD cards,
@@ -549,7 +555,7 @@ mat4 sample_4p(vec4 u)
int fetch_raw_depth(ivec2 xy)
{
#if PS_TEX_IS_FB
vec4 col = subpassLoad(RtSampler);
vec4 col = sample_from_rt();
#else
vec4 col = texelFetch(Texture, xy, 0);
#endif
@@ -559,7 +565,7 @@ int fetch_raw_depth(ivec2 xy)
vec4 fetch_raw_color(ivec2 xy)
{
#if PS_TEX_IS_FB
return subpassLoad(RtSampler);
return sample_from_rt();
#else
return texelFetch(Texture, xy, 0);
#endif
@@ -935,7 +941,7 @@ vec4 ps_color()
void ps_fbmask(inout vec4 C)
{
#if PS_FBMASK
vec4 RT = trunc(subpassLoad(RtSampler) * 255.0f + 0.1f);
vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
C = vec4((uvec4(C) & ~FbMask) | (uvec4(RT) & FbMask));
#endif
}
@@ -995,7 +1001,7 @@ void ps_blend(inout vec4 Color, float As)
#endif
#if PS_FEEDBACK_LOOP_IS_NEEDED
vec4 RT = trunc(subpassLoad(RtSampler) * 255.0f + 0.1f);
vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
#else
// Not used, but we define it to make the selection below simpler.
vec4 RT = vec4(0.0f);
@@ -1095,9 +1101,9 @@ void main()
#if PS_WRITE_RG == 1
// Pseudo 16 bits access.
float rt_a = subpassLoad(RtSampler).g;
float rt_a = sample_from_rt().g;
#else
float rt_a = subpassLoad(RtSampler).a;
float rt_a = sample_from_rt().a;
#endif
#if (PS_DATE & 3) == 1
@@ -1195,11 +1201,22 @@ void main()
ps_fbmask(C);
#if !PS_NO_COLOR
o_col0 = C / 255.0f;
#ifndef DISABLE_DUAL_SOURCE
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
o_col1 = vec4(alpha_blend);
#endif
#if PS_NO_ABLEND
// write alpha blend factor into col0
o_col0.a = alpha_blend;
#endif
#if PS_ONLY_ALPHA
// rgb isn't used
o_col0.rgb = vec3(0.0f);
#endif
#endif
#if PS_ZCLAMP
gl_FragDepth = min(gl_FragCoord.z, MaxDepthPS);
#endif
+4 -35
View File
@@ -31,22 +31,16 @@ set_ncpu_toolfile()
switch_wxconfig()
{
# Helper to easily switch wx-config on my system
if [ "$useCross" -eq 0 ] && [ "$(uname -m)" = "x86_64" ] && [ -e "/usr/lib/i386-linux-gnu/wx/config/gtk2-unicode-3.0" ]; then
if [ "$(uname -m)" = "x86_64" ] && [ -e "/usr/lib/i386-linux-gnu/wx/config/gtk2-unicode-3.0" ]; then
sudo update-alternatives --set wx-config /usr/lib/x86_64-linux-gnu/wx/config/gtk2-unicode-3.0
fi
if [ "$useCross" -eq 2 ] && [ "$(uname -m)" = "x86_64" ] && [ -e "/usr/lib/x86_64-linux-gnu/wx/config/gtk2-unicode-3.0" ]; then
sudo update-alternatives --set wx-config /usr/lib/i386-linux-gnu/wx/config/gtk2-unicode-3.0
fi
}
find_freetype()
{
if [ "$useCross" -eq 0 ] && [ "$(uname -m)" = "x86_64" ] && [ -e "/usr/include/x86_64-linux-gnu/freetype2/ft2build.h" ]; then
if [ "$(uname -m)" = "x86_64" ] && [ -e "/usr/include/x86_64-linux-gnu/freetype2/ft2build.h" ]; then
export GTKMM_BASEPATH=/usr/include/x86_64-linux-gnu/freetype2
fi
if [ "$useCross" -eq 2 ] && [ "$(uname -m)" = "x86_64" ] && [ -e "/usr/include/i386-linux-gnu/freetype2/ft2build.h" ]; then
export GTKMM_BASEPATH=/usr/include/i386-linux-gnu/freetype2
fi
}
set_make()
@@ -62,18 +56,10 @@ set_make()
set_compiler()
{
if [ "$useClang" -eq 1 ]; then
if [ "$useCross" -eq 0 ]; then
CC=clang CXX=clang++ cmake $flags "$root" 2>&1 | tee -a "$log"
else
CC="clang -m32" CXX="clang++ -m32" cmake $flags "$root" 2>&1 | tee -a "$log"
fi
CC=clang CXX=clang++ cmake $flags "$root" 2>&1 | tee -a "$log"
else
if [ "$useIcc" -eq 1 ]; then
if [ "$useCross" -eq 0 ]; then
CC="icc" CXX="icpc" cmake $flags "$root" 2>&1 | tee -a "$log"
else
CC="icc -m32" CXX="icpc -m32" cmake $flags "$root" 2>&1 | tee -a "$log"
fi
CC="icc" CXX="icpc" cmake $flags "$root" 2>&1 | tee -a "$log"
else
# Default compiler AKA GCC
cmake $flags "$root" 2>&1 | tee -a "$log"
@@ -164,9 +150,6 @@ cleanBuild=0
useClang=0
useIcc=0
# 0 => no, 1 => yes
useCross=0
CoverityBuild=0
cppcheck=0
clangTidy=0
@@ -202,8 +185,6 @@ for ARG in "$@"; do
--no-portaudio ) flags="$flags -DPORTAUDIO_API=FALSE" ;;
--no-simd ) flags="$flags -DDISABLE_ADVANCE_SIMD=TRUE" ;;
--no-trans ) flags="$flags -DNO_TRANSLATION=TRUE" ;;
--cross-multilib ) flags="$flags $i386_flag"; useCross=1; ;;
--no-cross-multilib ) useCross=0; ;;
--coverity ) CoverityBuild=1; cleanBuild=1; ;;
--vtune ) flags="$flags -DUSE_VTUNE=TRUE" ;;
-D* ) flags="$flags $ARG" ;;
@@ -220,10 +201,6 @@ for ARG in "$@"; do
echo "--clean : Do a clean build."
echo "--no-simd : Only allow sse2"
echo
echo "** Developer option **"
echo "--cross-multilib: Build a 32bit PCSX2 on a 64bit machine using multilib."
echo "--no-cross-multilib: Build a native version of PCSX2 (default)"
echo
echo "** Distribution Compatibilities **"
echo "--no-portaudio : Skip portaudio for SPU2."
echo "--use-system-yaml : Use system rapidyaml library"
@@ -255,14 +232,6 @@ if [ "$cleanBuild" -eq 1 ]; then
rm -fr "$build"/*
fi
if [ "$useCross" -eq 1 ]; then
echo "Cross compiling."
flags="$flags $i386_flag"
elif [ "$useCross" -ne 1 ]; then
useCross=0
echo "Compiling natively."
fi
switch_wxconfig
# Workaround for Debian. Cmake failed to find freetype include path
+10 -37
View File
@@ -140,44 +140,13 @@ endif()
# Architecture bitness detection
include(TargetArch)
target_architecture(PCSX2_TARGET_ARCHITECTURES)
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64" OR ${PCSX2_TARGET_ARCHITECTURES} MATCHES "i386")
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
message(STATUS "Compiling a ${PCSX2_TARGET_ARCHITECTURES} build on a ${CMAKE_HOST_SYSTEM_PROCESSOR} host.")
else()
message(FATAL_ERROR "Unsupported architecture: ${PCSX2_TARGET_ARCHITECTURES}")
endif()
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "i386")
# * -fPIC option was removed for multiple reasons.
# - Code only supports the x86 architecture.
# - code uses the ebx register so it's not compliant with PIC.
# - Impacts the performance too much.
# - Only plugins. No package will link to them.
set(CMAKE_POSITION_INDEPENDENT_CODE OFF)
if(NOT DEFINED ARCH_FLAG)
if (MSVC)
set(ARCH_FLAG /arch:SSE2)
else()
if (DISABLE_ADVANCE_SIMD)
if (USE_ICC)
set(ARCH_FLAG "-msse2 -msse4.1")
else()
set(ARCH_FLAG "-msse -msse2 -msse4.1 -mfxsr -march=i686")
endif()
else()
# AVX requires some fix of the ABI (mangling) (default 2)
# Note: V6 requires GCC 4.7
#set(ARCH_FLAG "-march=native -fabi-version=6")
set(ARCH_FLAG "-mfxsr -march=native")
endif()
endif()
endif()
list(APPEND PCSX2_DEFS _ARCH_32=1 _M_X86=1 _M_X86_32=1)
set(_ARCH_32 1)
set(_M_X86 1)
set(_M_X86_32 1)
elseif(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
# x86_64 requires -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
@@ -193,10 +162,9 @@ elseif(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
set(ARCH_FLAG "-march=native")
endif()
endif()
list(APPEND PCSX2_DEFS _ARCH_64=1 _M_X86=1 _M_X86_64=1 __M_X86_64=1)
list(APPEND PCSX2_DEFS _ARCH_64=1 _M_X86=1)
set(_ARCH_64 1)
set(_M_X86 1)
set(_M_X86_64 1)
else()
# All but i386 requires -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
@@ -337,9 +305,14 @@ endif()
# MacOS-specific things
#-------------------------------------------------------------------------------
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13)
if(NOT CMAKE_GENERATOR MATCHES "Xcode")
# Assume Xcode builds aren't being used for distribution
# Helpful because Xcode builds don't build multiple metallibs for different macOS versions
# Also helpful because Xcode's interactive shader debugger requires apps be built for the latest macOS
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13)
endif()
if (APPLE AND ${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS 10.14 AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 9)
if (APPLE AND CMAKE_OSX_DEPLOYMENT_TARGET AND "${CMAKE_OSX_DEPLOYMENT_TARGET}" VERSION_LESS 10.14 AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 9)
# Older versions of the macOS stdlib don't have operator new(size_t, align_val_t)
# Disable use of them with this flag
# Not great, but also no worse that what we were getting before we turned on C++17
+4 -3
View File
@@ -53,7 +53,6 @@ target_sources(common PRIVATE
emitter/LnxCpuDetect.cpp
emitter/WinCpuDetect.cpp
emitter/x86emitter.cpp
x86/MemcpyFast.cpp
Darwin/DarwinThreads.cpp
Darwin/DarwinMisc.cpp
Darwin/DarwinSemaphore.cpp
@@ -73,6 +72,7 @@ target_sources(common PRIVATE
boost_spsc_queue.hpp
Console.h
Dependencies.h
EnumOps.h
EventSource.h
Exceptions.h
FastJmp.h
@@ -86,6 +86,7 @@ target_sources(common PRIVATE
MemcpyFast.h
MemsetFast.inl
MD5Digest.h
MRCHelpers.h
Path.h
PageFaultSource.h
PrecompiledHeader.h
@@ -185,8 +186,8 @@ elseif(APPLE)
GL/ContextAGL.h
)
set_source_files_properties(GL/ContextAGL.mm PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
target_compile_options(common PUBLIC -fobjc-arc)
target_link_options(common PUBLIC -fobjc-link-runtime)
target_compile_options(common PRIVATE -fobjc-arc)
target_link_options(common PRIVATE -fobjc-link-runtime)
else()
if(X11_API OR WAYLAND_API)
target_sources(common PRIVATE
+10
View File
@@ -130,7 +130,17 @@ bool D3D11::ShaderCache::ReadExisting(const std::string& index_filename, const s
{
m_index_file = FileSystem::OpenCFile(index_filename.c_str(), "r+b");
if (!m_index_file)
{
// special case here: when there's a sharing violation (i.e. two instances running),
// we don't want to blow away the cache. so just continue without a cache.
if (errno == EACCES)
{
Console.WriteLn("Failed to open shader cache index with EACCES, are you running two instances?");
return true;
}
return false;
}
u32 file_version = 0;
u32 data_version = 0;
+96
View File
@@ -0,0 +1,96 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <type_traits>
namespace detail
{
/// Marks an enum as supporting boolean operators
template <typename T>
struct enum_is_flags : public std::false_type {};
/// For return types that should be convertible to bool
template <typename Enum>
struct enum_bool_helper
{
Enum value;
constexpr enum_bool_helper(Enum value): value(value) {}
constexpr operator Enum() const { return value; }
constexpr operator bool() const { return static_cast<bool>(static_cast<typename std::underlying_type<Enum>::type>(value)); }
};
};
#define MARK_ENUM_AS_FLAGS(T) template<> struct detail::enum_is_flags<T> : public std::true_type {}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum>::type
operator|(Enum lhs, Enum rhs) noexcept
{
using underlying = typename std::underlying_type<Enum>::type;
return static_cast<Enum>(static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, detail::enum_bool_helper<Enum>>::type
operator&(Enum lhs, Enum rhs) noexcept
{
using underlying = typename std::underlying_type<Enum>::type;
return static_cast<Enum>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum>::type
operator^(Enum lhs, Enum rhs) noexcept
{
using underlying = typename std::underlying_type<Enum>::type;
return static_cast<Enum>(static_cast<underlying>(lhs) ^ static_cast<underlying>(rhs));
}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum&>::type
operator|=(Enum& lhs, Enum rhs) noexcept
{
return lhs = lhs | rhs;
}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum&>::type
operator&=(Enum& lhs, Enum rhs) noexcept
{
return lhs = lhs & rhs;
}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum&>::type
operator^=(Enum& lhs, Enum rhs) noexcept
{
return lhs = lhs ^ rhs;
}
template<typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, bool>::type
operator!(Enum e) noexcept
{
return !static_cast<typename std::underlying_type<Enum>::type>(e);
}
template<typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum>::type
operator~(Enum e) noexcept
{
return static_cast<Enum>(~static_cast<typename std::underlying_type<Enum>::type>(e));
}
-47
View File
@@ -12,51 +12,6 @@
; You should have received a copy of the GNU General Public License along with PCSX2.
; If not, see <http://www.gnu.org/licenses/>.
IFDEF _M_X86_32
; -----------------------------------------
; 32-bit X86
; -----------------------------------------
.386
.model flat
_TEXT SEGMENT
PUBLIC @fastjmp_set@4
PUBLIC @fastjmp_jmp@8
; void fastjmp_set(fastjmp_buf*)
@fastjmp_set@4 PROC
mov eax, dword ptr [esp]
mov edx, esp ; fixup stack pointer, so it doesn't include the call to fastjmp_set
add edx, 4
mov dword ptr [ecx], eax ; actually eip
mov dword ptr [ecx + 4], ebx
mov dword ptr [ecx + 8], edx ; actually esp
mov dword ptr [ecx + 12], ebp
mov dword ptr [ecx + 16], esi
mov dword ptr [ecx + 20], edi
xor eax, eax
ret
@fastjmp_set@4 ENDP
; void __fastcall fastjmp_jmp(fastjmp_buf*, int)
@fastjmp_jmp@8 PROC
mov eax, edx ; return code
mov edx, dword ptr [ecx + 0]
mov ebx, dword ptr [ecx + 4]
mov esp, dword ptr [ecx + 8]
mov ebp, dword ptr [ecx + 12]
mov esi, dword ptr [ecx + 16]
mov edi, dword ptr [ecx + 20]
jmp edx
@fastjmp_jmp@8 ENDP
_TEXT ENDS
ENDIF ; _M_X86_32
IFDEF _M_X86_64
; -----------------------------------------
; 64-bit X86
; -----------------------------------------
@@ -124,6 +79,4 @@ fastjmp_jmp ENDP
_TEXT ENDS
ENDIF ; _M_X86_64
END
-34
View File
@@ -23,8 +23,6 @@
#define PREFIX ""
#endif
#if defined(_M_X86_64)
asm(
"\t.global " PREFIX "fastjmp_set\n"
"\t.global " PREFIX "fastjmp_jmp\n"
@@ -57,36 +55,4 @@ asm(
jmp *%rdx
)");
#elif defined(_M_X86_32)
asm(
"\t.global " PREFIX "fastjmp_set\n"
"\t.global " PREFIX "fastjmp_jmp\n"
"\t.text\n"
"\t" PREFIX "fastjmp_set:" R"(
movl 0(%esp), %eax
movl %esp, %edx # fixup stack pointer, so it doesn't include the call to fastjmp_set
addl $4, %edx
movl %eax, 0(%ecx) # actually eip
movl %ebx, 4(%ecx)
movl %edx, 8(%ecx) # actually esp
movl %ebp, 12(%ecx)
movl %esi, 16(%ecx)
movl %edi, 20(%ecx)
xorl %eax, %eax
ret
)"
"\t" PREFIX "fastjmp_jmp:" R"(
movl %edx, %eax
movl 0(%ecx), %edx # actually eip
movl 4(%ecx), %ebx
movl 8(%ecx), %esp # actually esp
movl 12(%ecx), %ebp
movl 16(%ecx), %esi
movl 20(%ecx), %edi
jmp *%edx
)");
#endif
#endif // __WIN32
+2 -6
View File
@@ -20,14 +20,10 @@
struct fastjmp_buf
{
#if defined(_M_X86_64) && defined(_WIN32)
#if defined(_WIN32)
static constexpr std::size_t BUF_SIZE = 240;
#elif defined(_M_X86_64)
static constexpr std::size_t BUF_SIZE = 64;
#elif defined(_M_X86_32)
static constexpr std::size_t BUF_SIZE = 24;
#else
#error Unknown architecture.
static constexpr std::size_t BUF_SIZE = 64;
#endif
alignas(16) std::uint8_t buf[BUF_SIZE];
+51 -9
View File
@@ -504,7 +504,7 @@ std::optional<std::vector<u8>> FileSystem::ReadBinaryFile(const char* filename)
std::optional<std::vector<u8>> FileSystem::ReadBinaryFile(std::FILE* fp)
{
std::fseek(fp, 0, SEEK_END);
long size = std::ftell(fp);
const long size = std::ftell(fp);
std::fseek(fp, 0, SEEK_SET);
if (size < 0)
return std::nullopt;
@@ -528,13 +528,14 @@ std::optional<std::string> FileSystem::ReadFileToString(const char* filename)
std::optional<std::string> FileSystem::ReadFileToString(std::FILE* fp)
{
std::fseek(fp, 0, SEEK_END);
long size = std::ftell(fp);
const long size = std::ftell(fp);
std::fseek(fp, 0, SEEK_SET);
if (size < 0)
return std::nullopt;
std::string res;
res.resize(static_cast<size_t>(size));
// NOTE - assumes mode 'rb', for example, this will fail over missing Windows carriage return bytes
if (size > 0 && std::fread(res.data(), 1u, static_cast<size_t>(size), fp) != static_cast<size_t>(size))
return std::nullopt;
@@ -553,7 +554,7 @@ bool FileSystem::WriteBinaryFile(const char* filename, const void* data, size_t
return true;
}
bool FileSystem::WriteFileToString(const char* filename, const std::string_view& sv)
bool FileSystem::WriteStringToFile(const char* filename, const std::string_view& sv)
{
ManagedCFilePtr fp = OpenManagedCFile(filename, "wb");
if (!fp)
@@ -574,6 +575,29 @@ bool FileSystem::EnsureDirectoryExists(const char* path, bool recursive)
return FileSystem::CreateDirectoryPath(path, recursive);
}
bool FileSystem::RecursiveDeleteDirectory(const char* path)
{
FindResultsArray results;
if (FindFiles(path, "*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_FOLDERS | FILESYSTEM_FIND_HIDDEN_FILES, &results))
{
for (const FILESYSTEM_FIND_DATA& fd : results)
{
if (fd.Attributes & FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY)
{
if (!RecursiveDeleteDirectory(fd.FileName.c_str()))
return false;
}
else
{
if (!DeleteFilePath(fd.FileName.c_str()))
return false;
}
}
}
return DeleteDirectory(path);
}
#ifdef _WIN32
static u32 TranslateWin32Attributes(u32 Win32Attributes)
@@ -1039,15 +1063,15 @@ bool FileSystem::DeleteFilePath(const char* path)
#endif
}
bool FileSystem::RenamePath(const char* old_path, const char* new_patah)
bool FileSystem::RenamePath(const char* old_path, const char* new_path)
{
const std::wstring old_wpath(StringUtil::UTF8StringToWideString(old_path));
const std::wstring new_wpath(StringUtil::UTF8StringToWideString(new_patah));
const std::wstring new_wpath(StringUtil::UTF8StringToWideString(new_path));
#ifndef _UWP
if (!MoveFileExW(old_wpath.c_str(), new_wpath.c_str(), MOVEFILE_REPLACE_EXISTING))
{
Console.Error("MoveFileEx('%s', '%s') failed: %08X", old_path, new_patah, GetLastError());
Console.Error("MoveFileEx('%s', '%s') failed: %08X", old_path, new_path, GetLastError());
return false;
}
#else
@@ -1063,7 +1087,7 @@ bool FileSystem::RenamePath(const char* old_path, const char* new_patah)
if (!MoveFileFromAppW(old_wpath.c_str(), new_wpath.c_str()))
{
Log_ErrorPrintf("MoveFileFromAppW('%s', '%s') failed: %08X", old_path, new_patah, GetLastError());
Log_ErrorPrintf("MoveFileFromAppW('%s', '%s') failed: %08X", old_path, new_path, GetLastError());
return false;
}
#endif
@@ -1071,6 +1095,12 @@ bool FileSystem::RenamePath(const char* old_path, const char* new_patah)
return true;
}
bool FileSystem::DeleteDirectory(const char* path)
{
const std::wstring wpath(StringUtil::UTF8StringToWideString(path));
return RemoveDirectoryW(wpath.c_str());
}
std::string FileSystem::GetProgramPath()
{
std::wstring buffer;
@@ -1269,7 +1299,7 @@ bool FileSystem::FindFiles(const char* Path, const char* Pattern, u32 Flags, Fin
bool FileSystem::StatFile(const char* path, struct stat* st)
{
return stat(path, st);
return stat(path, st) == 0;
}
bool FileSystem::StatFile(std::FILE* fp, struct stat* st)
@@ -1278,7 +1308,7 @@ bool FileSystem::StatFile(std::FILE* fp, struct stat* st)
if (fd < 0)
return false;
return fstat(fd, st);
return fstat(fd, st) == 0;
}
bool FileSystem::StatFile(const char* path, FILESYSTEM_STAT_DATA* sd)
@@ -1484,6 +1514,18 @@ bool FileSystem::RenamePath(const char* old_path, const char* new_path)
return true;
}
bool FileSystem::DeleteDirectory(const char* path)
{
if (path[0] == '\0')
return false;
struct stat sysStatData;
if (stat(path, &sysStatData) != 0 || !S_ISDIR(sysStatData.st_mode))
return false;
return (unlink(path) == 0);
}
std::string FileSystem::GetProgramPath()
{
#if defined(__linux__)
+7 -1
View File
@@ -142,7 +142,7 @@ namespace FileSystem
std::optional<std::string> ReadFileToString(const char* filename);
std::optional<std::string> ReadFileToString(std::FILE* fp);
bool WriteBinaryFile(const char* filename, const void* data, size_t data_length);
bool WriteFileToString(const char* filename, const std::string_view& sv);
bool WriteStringToFile(const char* filename, const std::string_view& sv);
/// creates a directory in the local filesystem
/// if the directory already exists, the return value will be true.
@@ -154,6 +154,12 @@ namespace FileSystem
/// Returns false if it does not exist and creation failed.
bool EnsureDirectoryExists(const char* path, bool recursive);
/// Removes a directory.
bool DeleteDirectory(const char* path);
/// Recursively removes a directory and all subdirectories/files.
bool RecursiveDeleteDirectory(const char* path);
/// Returns the path to the current executable.
std::string GetProgramPath();
+97
View File
@@ -0,0 +1,97 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __OBJC__
#error This header is for use with Objective-C++ only.
#endif
#if __has_feature(objc_arc)
#error This file is for manual reference counting! Compile without -fobjc-arc
#endif
#pragma once
#include <cstddef>
#include <utility>
/// Managed Obj-C pointer
template <typename T>
class MRCOwned
{
T ptr;
MRCOwned(T ptr): ptr(ptr) {}
public:
MRCOwned(): ptr(nullptr) {}
MRCOwned(std::nullptr_t): ptr(nullptr) {}
MRCOwned(MRCOwned&& other)
: ptr(other.ptr)
{
other.ptr = nullptr;
}
MRCOwned(const MRCOwned& other)
: ptr(other.ptr)
{
[ptr retain];
}
~MRCOwned()
{
if (ptr)
[ptr release];
}
operator T() const { return ptr; }
MRCOwned& operator=(const MRCOwned& other)
{
[other.ptr retain];
if (ptr)
[ptr release];
ptr = other.ptr;
return *this;
}
MRCOwned& operator=(MRCOwned&& other)
{
std::swap(ptr, other.ptr);
return *this;
}
void Reset()
{
[ptr release];
ptr = nullptr;
}
T Get() const { return ptr; }
static MRCOwned Transfer(T ptr)
{
return MRCOwned(ptr);
}
static MRCOwned Retain(T ptr)
{
[ptr retain];
return MRCOwned(ptr);
}
};
/// Take ownership of an Obj-C pointer (equivalent to __bridge_transfer)
template<typename T>
static inline MRCOwned<T> MRCTransfer(T ptr)
{
return MRCOwned<T>::Transfer(ptr);
}
/// Retain an Obj-C pointer (equivalent to __bridge)
template<typename T>
static inline MRCOwned<T> MRCRetain(T ptr)
{
return MRCOwned<T>::Retain(ptr);
}
-8
View File
@@ -19,14 +19,6 @@
#include "common/Pcsx2Types.h"
#include "common/Pcsx2Defs.h"
// For 32-bit MSVC compiles, memcmp performs much worse than memcmp_mmx and
// other implementations. So for this combination only, prefer memcmp_mmx
#if defined(_MSC_VER) && !defined(_M_X86_64)
extern u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize);
#else
#define memcmp_mmx memcmp
#endif
// This method can clear any object-like entity -- which is anything that is not a pointer.
// Structures, static arrays, etc. No need to include sizeof() crap, this does it automatically
// for you!
+1 -5
View File
@@ -110,11 +110,7 @@ static const int __pagesize = PCSX2_PAGESIZE;
// happens *by design* like all the friggen time >_<)
#ifndef __fastcall
#ifndef _M_X86_32
#define __fastcall // Attribute not available, and x86_32 is pretty much the only cc that passes literally everything in registers
#else
#define __fastcall __attribute__((fastcall))
#endif
#define __fastcall
#endif
#define __vectorcall __fastcall
#define _inline __inline__ __attribute__((unused))
-5
View File
@@ -225,12 +225,7 @@ extern bool pxParseAssignmentString(const wxString& src, wxString& ldest, wxStri
#define pxsFmt FastFormatUnicode().Write
#define pxsFmtV FastFormatUnicode().WriteV
#ifdef _M_X86_64
#define pxsPtr(ptr) pxsFmt("0x%016" PRIXPTR, (ptr)).c_str()
#else
#define pxsPtr(ptr) pxsFmt("0x%08" PRIXPTR, (ptr)).c_str()
#endif
extern wxString& operator+=(wxString& str1, const FastFormatUnicode& str2);
extern wxString operator+(const wxString& str1, const FastFormatUnicode& str2);
+24
View File
@@ -251,6 +251,30 @@ namespace StringUtil
return str.substr(start, end - start + 1);
}
std::vector<std::string_view> SplitString(const std::string_view& str, char delimiter, bool skip_empty /*= true*/)
{
std::vector<std::string_view> res;
std::string_view::size_type last_pos = 0;
std::string_view::size_type pos;
while (last_pos < str.size() && (pos = str.find(delimiter, last_pos)) != std::string_view::npos)
{
std::string_view part(StripWhitespace(str.substr(last_pos, pos - last_pos)));
if (!skip_empty || !part.empty())
res.push_back(std::move(part));
last_pos = pos + 1;
}
if (last_pos < str.size())
{
std::string_view part(StripWhitespace(str.substr(last_pos)));
if (!skip_empty || !part.empty())
res.push_back(std::move(part));
}
return res;
}
std::wstring UTF8StringToWideString(const std::string_view& str)
{
std::wstring ret;
+14
View File
@@ -153,9 +153,23 @@ namespace StringUtil
return (str.length() >= suffix_length && str.compare(str.length() - suffix_length, suffix_length, suffix) == 0);
}
/// StartsWith/EndsWith variants which aren't case sensitive.
static inline bool StartsWithNoCase(const std::string_view& str, const char* prefix)
{
return (Strncasecmp(str.data(), prefix, std::strlen(prefix)) == 0);
}
static inline bool EndsWithNoCase(const std::string_view& str, const char* suffix)
{
const std::size_t suffix_length = std::strlen(suffix);
return (str.length() >= suffix_length && Strncasecmp(str.data() + (str.length() - suffix_length), suffix, suffix_length) == 0);
}
/// Strip whitespace from the start/end of the string.
std::string_view StripWhitespace(const std::string_view& str);
/// Splits a string based on a single character delimiter.
std::vector<std::string_view> SplitString(const std::string_view& str, char delimiter, bool skip_empty = true);
/// Strided memcpy/memcmp.
static inline void StrideMemCpy(void* dst, std::size_t dst_stride, const void* src, std::size_t src_stride,
std::size_t copy_size, std::size_t count)
+5
View File
@@ -352,6 +352,11 @@ namespace Vulkan
}
}
void GraphicsPipelineBuilder::AddBlendFlags(u32 flags)
{
m_blend_state.flags |= flags;
}
void GraphicsPipelineBuilder::ClearBlendAttachments()
{
m_blend_attachments = {};
+1
View File
@@ -112,6 +112,7 @@ namespace Vulkan
VkBlendOp op, VkBlendFactor alpha_src_factor, VkBlendFactor alpha_dst_factor, VkBlendOp alpha_op,
VkColorComponentFlags write_mask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
void AddBlendFlags(u32 flags);
void ClearBlendAttachments();
void SetBlendConstants(float r, float g, float b, float a);
+97 -15
View File
@@ -445,6 +445,8 @@ namespace Vulkan
SupportsExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, false);
m_optional_extensions.vk_khr_driver_properties =
SupportsExtension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, false);
m_optional_extensions.vk_arm_rasterization_order_attachment_access =
SupportsExtension(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME, false);
return true;
}
@@ -597,11 +599,19 @@ namespace Vulkan
// provoking vertex
VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT};
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM rasterization_order_access_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM};
if (m_optional_extensions.vk_ext_provoking_vertex)
{
provoking_vertex_feature.provokingVertexLast = VK_TRUE;
Util::AddPointerToChain(&device_info, &provoking_vertex_feature);
}
if (m_optional_extensions.vk_arm_rasterization_order_attachment_access)
{
rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess = VK_TRUE;
Util::AddPointerToChain(&device_info, &rasterization_order_access_feature);
}
VkResult res = vkCreateDevice(m_physical_device, &device_info, nullptr, &m_device);
if (res != VK_SUCCESS)
@@ -621,6 +631,9 @@ namespace Vulkan
vkGetDeviceQueue(m_device, m_present_queue_family_index, 0, &m_present_queue);
}
m_gpu_timing_supported = (queue_family_properties[m_graphics_queue_family_index].timestampValidBits > 0);
DevCon.WriteLn("GPU timing is %s", m_gpu_timing_supported ? "supported" : "not supported");
ProcessDeviceExtensions();
return true;
}
@@ -633,20 +646,21 @@ namespace Vulkan
VkPhysicalDeviceFeatures2 features2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex_features = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT};
void** pNext = &features2.pNext;
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM rasterization_order_access_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM};
// add in optional feature structs
if (m_optional_extensions.vk_ext_provoking_vertex)
{
*pNext = &provoking_vertex_features;
pNext = &provoking_vertex_features.pNext;
}
Util::AddPointerToChain(&features2, &provoking_vertex_features);
if (m_optional_extensions.vk_arm_rasterization_order_attachment_access)
Util::AddPointerToChain(&features2, &rasterization_order_access_feature);
// query
vkGetPhysicalDeviceFeatures2(m_physical_device, &features2);
// confirm we actually support it
m_optional_extensions.vk_ext_provoking_vertex &= (provoking_vertex_features.provokingVertexLast == VK_TRUE);
m_optional_extensions.vk_arm_rasterization_order_attachment_access &= (rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess == VK_TRUE);
}
if (vkGetPhysicalDeviceProperties2)
@@ -667,6 +681,8 @@ namespace Vulkan
Console.WriteLn("VK_EXT_provoking_vertex is %s",
m_optional_extensions.vk_ext_provoking_vertex ? "supported" : "NOT supported");
Console.WriteLn("VK_ARM_rasterization_order_attachment_access is %s",
m_optional_extensions.vk_arm_rasterization_order_attachment_access ? "supported" : "NOT supported");
}
bool Context::CreateAllocator()
@@ -823,11 +839,30 @@ namespace Vulkan
return false;
}
Vulkan::Util::SetObjectName(g_vulkan_context->GetDevice(), m_global_descriptor_pool, "Global Descriptor Pool");
if (m_gpu_timing_supported)
{
const VkQueryPoolCreateInfo query_create_info = {VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, nullptr,
0, VK_QUERY_TYPE_TIMESTAMP, NUM_COMMAND_BUFFERS * 2, 0};
res = vkCreateQueryPool(m_device, &query_create_info, nullptr, &m_timestamp_query_pool);
if (res != VK_SUCCESS)
{
LOG_VULKAN_ERROR(res, "vkCreateQueryPool failed: ");
return false;
}
}
return true;
}
void Context::DestroyGlobalDescriptorPool()
{
if (m_timestamp_query_pool != VK_NULL_HANDLE)
{
vkDestroyQueryPool(m_device, m_timestamp_query_pool, nullptr);
m_timestamp_query_pool = VK_NULL_HANDLE;
}
if (m_global_descriptor_pool != VK_NULL_HANDLE)
{
vkDestroyDescriptorPool(m_device, m_global_descriptor_pool, nullptr);
@@ -920,6 +955,18 @@ namespace Vulkan
vkDeviceWaitIdle(m_device);
}
float Context::GetAndResetAccumulatedGPUTime()
{
const float time = m_accumulated_gpu_time;
m_accumulated_gpu_time = 0.0f;
return time;
}
void Context::SetEnableGPUTiming(bool enabled)
{
m_gpu_timing_enabled = enabled && m_gpu_timing_supported;
}
void Context::WaitForCommandBufferCompletion(u32 index)
{
// Wait for this command buffer to be completed.
@@ -968,6 +1015,11 @@ namespace Vulkan
}
}
if (m_gpu_timing_enabled)
{
vkCmdWriteTimestamp(m_current_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, m_timestamp_query_pool, m_current_frame * 2 + 1);
}
res = vkEndCommandBuffer(resources.command_buffers[1]);
if (res != VK_SUCCESS)
{
@@ -1145,6 +1197,29 @@ namespace Vulkan
// using the lower 32 bits of the fence index should be sufficient here, I hope...
vmaSetCurrentFrameIndex(m_allocator, static_cast<u32>(m_next_fence_counter));
if (m_gpu_timing_enabled)
{
std::array<u64, 2> timestamps;
res = vkGetQueryPoolResults(m_device, m_timestamp_query_pool, index * 2, static_cast<u32>(timestamps.size()),
sizeof(u64) * timestamps.size(), timestamps.data(), sizeof(u64), VK_QUERY_RESULT_64_BIT);
if (res == VK_SUCCESS)
{
// if we didn't write the timestamp at the start of the cmdbuffer (just enabled timing), the first TS will be zero
if (timestamps[0] > 0)
{
const u64 ns_diff = (timestamps[1] - timestamps[0]) * static_cast<u64>(m_device_properties.limits.timestampPeriod);
m_accumulated_gpu_time += static_cast<double>(ns_diff) / 1000000.0;
}
}
else
{
LOG_VULKAN_ERROR(res, "vkGetQueryPoolResults failed: ");
}
vkCmdResetQueryPool(m_current_command_buffer, m_timestamp_query_pool, index * 2, 2);
vkCmdWriteTimestamp(m_current_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, m_timestamp_query_pool, index * 2);
}
}
void Context::ExecuteCommandBuffer(bool wait_for_completion)
@@ -1326,15 +1401,19 @@ namespace Vulkan
input_reference.layout = VK_IMAGE_LAYOUT_GENERAL;
input_reference_ptr = &input_reference;
subpass_dependency.srcSubpass = 0;
subpass_dependency.dstSubpass = 0;
subpass_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpass_dependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
subpass_dependency.srcAccessMask =
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpass_dependency.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
subpass_dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
subpass_dependency_ptr = &subpass_dependency;
if (!g_vulkan_context->GetOptionalExtensions().vk_arm_rasterization_order_attachment_access)
{
// don't need the framebuffer-local dependency when we have rasterization order attachment access
subpass_dependency.srcSubpass = 0;
subpass_dependency.dstSubpass = 0;
subpass_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpass_dependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
subpass_dependency.srcAccessMask =
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpass_dependency.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
subpass_dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
subpass_dependency_ptr = &subpass_dependency;
}
}
num_attachments++;
@@ -1353,7 +1432,10 @@ namespace Vulkan
num_attachments++;
}
const VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, input_reference_ptr ? 1u : 0u,
const VkSubpassDescriptionFlags subpass_flags =
(key.color_feedback_loop && g_vulkan_context->GetOptionalExtensions().vk_arm_rasterization_order_attachment_access)
? VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM : 0;
const VkSubpassDescription subpass = {subpass_flags, VK_PIPELINE_BIND_POINT_GRAPHICS, input_reference_ptr ? 1u : 0u,
input_reference_ptr ? input_reference_ptr : nullptr, color_reference_ptr ? 1u : 0u,
color_reference_ptr ? color_reference_ptr : nullptr, nullptr, depth_reference_ptr, 0, nullptr};
const VkRenderPassCreateInfo pass_info = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0u,
+11 -2
View File
@@ -51,6 +51,7 @@ namespace Vulkan
bool vk_ext_provoking_vertex : 1;
bool vk_ext_memory_budget : 1;
bool vk_khr_driver_properties : 1;
bool vk_arm_rasterization_order_attachment_access : 1;
};
~Context();
@@ -208,6 +209,9 @@ namespace Vulkan
void WaitForGPUIdle();
float GetAndResetAccumulatedGPUTime();
void SetEnableGPUTiming(bool enabled);
private:
Context(VkInstance instance, VkPhysicalDevice physical_device);
@@ -284,14 +288,19 @@ namespace Vulkan
VkDescriptorPool m_global_descriptor_pool = VK_NULL_HANDLE;
VkQueue m_graphics_queue = VK_NULL_HANDLE;
u32 m_graphics_queue_family_index = 0;
VkQueue m_present_queue = VK_NULL_HANDLE;
u32 m_graphics_queue_family_index = 0;
u32 m_present_queue_family_index = 0;
VkQueryPool m_timestamp_query_pool = VK_NULL_HANDLE;
float m_accumulated_gpu_time = 0.0f;
bool m_gpu_timing_enabled = false;
bool m_gpu_timing_supported = false;
std::array<FrameResources, NUM_COMMAND_BUFFERS> m_frame_resources;
u64 m_next_fence_counter = 1;
u64 m_completed_fence_counter = 0;
u32 m_current_frame;
u32 m_current_frame = 0;
StreamBuffer m_texture_upload_buffer;
+10
View File
@@ -214,7 +214,17 @@ namespace Vulkan
{
m_index_file = FileSystem::OpenCFile(index_filename.c_str(), "r+b");
if (!m_index_file)
{
// special case here: when there's a sharing violation (i.e. two instances running),
// we don't want to blow away the cache. so just continue without a cache.
if (errno == EACCES)
{
Console.WriteLn("Failed to open shader cache index with EACCES, are you running two instances?");
return true;
}
return false;
}
u32 file_version = 0;
u32 data_version = 0;
+1 -6
View File
@@ -78,7 +78,6 @@
<ClCompile Include="Vulkan\Texture.cpp" />
<ClCompile Include="Vulkan\Util.cpp" />
<ClCompile Include="WindowInfo.cpp" />
<ClCompile Include="x86\MemcpyFast.cpp" />
<ClCompile Include="PathUtils.cpp" />
<ClCompile Include="Perf.cpp" />
<ClCompile Include="PrecompiledHeader.cpp">
@@ -111,11 +110,7 @@
</ItemGroup>
<ItemGroup>
<None Include="EventSource.inl" />
<MASM Include="FastJmp.asm">
<FileType>Document</FileType>
<PreprocessorDefinitions Condition="'$(Platform)'=='Win32'">_M_X86_32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_M_X86_64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</MASM>
<MASM Include="FastJmp.asm" />
<None Include="Vulkan\EntryPoints.inl" />
</ItemGroup>
<ItemGroup>
-3
View File
@@ -49,9 +49,6 @@
<ClCompile Include="Linux\LnxThreads.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="x86\MemcpyFast.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="emitter\movs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
-4
View File
@@ -230,9 +230,7 @@ void x86capabilities::Identify()
Model = (regs[0] >> 4) & 0xf;
FamilyID = (regs[0] >> 8) & 0xf;
TypeID = (regs[0] >> 12) & 0x3;
#ifdef __M_X86_64
//u32 x86_64_8BITBRANDID = regs[1] & 0xff;
#endif
Flags = regs[3];
Flags2 = regs[2];
}
@@ -251,9 +249,7 @@ void x86capabilities::Identify()
{
cpuid(regs, 0x80000001);
#ifdef __M_X86_64
//u32 x86_64_12BITBRANDID = regs[1] & 0xfff;
#endif
EFlags2 = regs[2];
EFlags = regs[3];
}
+1 -1
View File
@@ -45,7 +45,7 @@ namespace x86Emitter
{
if (sibdest.Is8BitOp())
{
xOpWrite(sibdest.GetPrefix16(), 0x80, InstType, sibdest);
xOpWrite(sibdest.GetPrefix16(), 0x80, InstType, sibdest, 1);
xWrite<s8>(imm);
}
-2
View File
@@ -65,10 +65,8 @@ namespace x86Emitter
void operator()(void* f, u32 a1, u32 a2) const;
void operator()(void* f, void* a1) const;
#ifdef __M_X86_64
void operator()(void* f, const xRegisterLong& a1, const xRegisterLong& a2 = xEmptyReg) const;
void operator()(void* f, u32 a1, const xRegisterLong& a2) const;
#endif
template <typename T>
__fi void operator()(T* func, u32 a1, const xRegisterLong& a2 = xEmptyReg) const
-4
View File
@@ -70,7 +70,6 @@ namespace x86Emitter
#endif
};
#ifdef __M_X86_64
// --------------------------------------------------------------------------------------
// xImpl_MovImm64
// --------------------------------------------------------------------------------------
@@ -82,7 +81,6 @@ namespace x86Emitter
void operator()(const xRegister64& to, s64 imm, bool preserve_flags = false) const;
};
#endif
// --------------------------------------------------------------------------------------
// xImpl_CMov
@@ -131,10 +129,8 @@ namespace x86Emitter
void operator()(const xRegister16or32or64& to, const xIndirect8& sibsrc) const;
void operator()(const xRegister32or64& to, const xRegister16& from) const;
void operator()(const xRegister32or64& to, const xIndirect16& sibsrc) const;
#ifdef __M_X86_64
void operator()(const xRegister64& to, const xRegister32& from) const;
void operator()(const xRegister64& to, const xIndirect32& sibsrc) const;
#endif
//void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const;
//void operator()( const xRegister16or32& to, const xDirectOrIndirect8& src ) const;
-5
View File
@@ -57,11 +57,8 @@ namespace x86Emitter
// flags.
extern const xImpl_Mov xMOV;
#ifdef __M_X86_64
extern const xImpl_MovImm64 xMOV64;
#endif
extern const xImpl_Test xTEST;
extern const xImpl_Group2 xROL, xROR,
xRCL, xRCR,
xSHL, xSHR,
@@ -222,7 +219,6 @@ namespace x86Emitter
/// May use `tmp` on x86-64
void xWriteImm64ToMem(u64* addr, const xAddressReg& tmp, u64 imm);
#ifdef __M_X86_64
//////////////////////////////////////////////////////////////////////////////////////////
/// Helper function to run operations with large immediates
/// If the immediate fits in 32 bits, runs op(target, imm)
@@ -240,7 +236,6 @@ namespace x86Emitter
op(dst, tmpRegister);
}
}
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// JMP / Jcc Instructions!
-10
View File
@@ -125,11 +125,7 @@ namespace x86Emitter
const xRegisterInt& reg = param1.IsReg() ? param1 : param2;
#ifdef __M_X86_64
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
#else
u8 nR = 0x80;
#endif
u8 L = reg.IsWideSIMD() ? 4 : 0;
u8 nv = (~param2.GetId() & 0xF) << 3;
@@ -155,15 +151,9 @@ namespace x86Emitter
const xRegisterInt& reg = param1.IsReg() ? param1 : param2;
#ifdef __M_X86_64
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
u8 nB = param3.IsExtended() ? 0x00 : 0x20;
u8 nX = 0x40; // likely unused so hardwired to disabled
#else
u8 nR = 0x80;
u8 nB = 0x20;
u8 nX = 0x40;
#endif
u8 L = reg.IsWideSIMD() ? 4 : 0;
u8 W = (w == -1) ? (reg.GetOperandSize() == 8 ? 0x80 : 0) : // autodetect the size
0x80 * w; // take directly the W value
-4
View File
@@ -93,7 +93,6 @@ namespace x86Emitter
}
}
#ifdef __M_X86_64
void xImpl_FastCall::operator()(void* f, const xRegisterLong& a1, const xRegisterLong& a2) const
{
prepareRegsForFastcall(a1, a2);
@@ -118,7 +117,6 @@ namespace x86Emitter
xMOV(arg1reg, a1);
(*this)(f, arg1reg, arg2reg);
}
#endif
void xImpl_FastCall::operator()(void* f, void* a1) const
{
@@ -214,10 +212,8 @@ namespace x86Emitter
s32* bah = xJcc32(comparison);
sptr distance = (sptr)target - (sptr)xGetPtr();
#ifdef __M_X86_64
// This assert won't physically happen on x86 targets
pxAssertDev(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target is too far away, needs an indirect register");
#endif
*bah = (s32)distance;
}
+2 -28
View File
@@ -55,18 +55,7 @@ namespace x86Emitter
// mov eax has a special from when writing directly to a DISP32 address
// (sans any register index/base registers).
#ifndef __M_X86_64
// Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr
if (from.IsAccumulator() && dest.Index.IsEmpty() && dest.Base.IsEmpty())
{
xOpAccWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xa2 : 0xa3, from, dest);
xWrite32(dest.Displacement);
}
else
#endif
{
xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, dest);
}
xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, dest);
}
void xImpl_Mov::operator()(const xRegisterInt& to, const xIndirectVoid& src) const
@@ -74,18 +63,7 @@ namespace x86Emitter
// mov eax has a special from when reading directly from a DISP32 address
// (sans any register index/base registers).
#ifndef __M_X86_64
// Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr
if (to.IsAccumulator() && src.Index.IsEmpty() && src.Base.IsEmpty())
{
xOpAccWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xa0 : 0xa1, to, src);
xWrite32(src.Displacement);
}
else
#endif
{
xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0x8a : 0x8b, to, src);
}
xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0x8a : 0x8b, to, src);
}
void xImpl_Mov::operator()(const xIndirect64orLess& dest, sptr imm) const
@@ -153,7 +131,6 @@ namespace x86Emitter
const xImpl_Mov xMOV;
#ifdef __M_X86_64
void xImpl_MovImm64::operator()(const xRegister64& to, s64 imm, bool preserve_flags) const
{
if (imm == (u32)imm || imm == (s32)imm)
@@ -169,7 +146,6 @@ namespace x86Emitter
}
const xImpl_MovImm64 xMOV64;
#endif
// --------------------------------------------------------------------------------------
// CMOVcc
@@ -241,7 +217,6 @@ namespace x86Emitter
xOpWrite0F(SignExtend ? 0xbf : 0xb7, to, sibsrc);
}
#ifdef __M_X86_64
void xImpl_MovExtend::operator()(const xRegister64& to, const xRegister32& from) const
{
EbpAssert();
@@ -255,7 +230,6 @@ namespace x86Emitter
pxAssertMsg(SignExtend, "Use mov for 64-bit movzx");
xOpWrite(0, 0x63, to, sibsrc);
}
#endif
const xImpl_MovExtend xMOVSX = {true};
const xImpl_MovExtend xMOVZX = {false};
+1 -2
View File
@@ -93,9 +93,8 @@ namespace x86Emitter
//
__emitinline void SimdPrefix(u8 prefix, u16 opcode)
{
#ifdef __M_X86_64
pxAssertMsg(prefix == 0, "REX prefix must be just before the opcode");
#endif
const bool is16BitOpcode = ((opcode & 0xff) == 0x38) || ((opcode & 0xff) == 0x3a);
// If the lower byte is not a valid prefix and the upper byte is non-zero it
+2 -73
View File
@@ -151,17 +151,12 @@ const xRegister8
ah(4), ch(5),
dh(6), bh(7);
#if defined(_WIN32) || !defined(__M_X86_64)
#if defined(_WIN32)
const xAddressReg
arg1reg = rcx,
arg2reg = rdx,
#ifdef __M_X86_64
arg3reg = r8,
arg4reg = r9,
#else
arg3reg = xRegisterEmpty(),
arg4reg = xRegisterEmpty(),
#endif
calleeSavedReg1 = rdi,
calleeSavedReg2 = rsi;
@@ -214,7 +209,6 @@ const xRegister32
"e12", "e13", "e14", "e15"
};
#ifdef __M_X86_64
const char* const x86_regnames_gpr64[] =
{
"rax", "rcx", "rdx", "rbx",
@@ -222,7 +216,6 @@ const xRegister32
"r8", "r9", "r10", "r11",
"r12", "r13", "r14", "r15"
};
#endif
const char* const x86_regnames_sse[] =
{
@@ -252,10 +245,8 @@ const xRegister32
return x86_regnames_gpr16[Id];
case 4:
return x86_regnames_gpr32[Id];
#ifdef __M_X86_64
case 8:
return x86_regnames_gpr64[Id];
#endif
case 16:
return x86_regnames_sse[Id];
}
@@ -300,9 +291,6 @@ const xRegister32
void EmitSibMagic(uint regfield, const void* address, int extraRIPOffset)
{
sptr displacement = (sptr)address;
#ifndef __M_X86_64
ModRM(0, regfield, ModRm_UseDisp32);
#else
sptr ripRelative = (sptr)address - ((sptr)x86Ptr + sizeof(s8) + sizeof(s32) + extraRIPOffset);
// Can we use a rip-relative address? (Prefer this over eiz because it's a byte shorter)
if (ripRelative == (s32)ripRelative)
@@ -316,7 +304,6 @@ const xRegister32
ModRM(0, regfield, ModRm_UseSib);
SibSB(0, Sib_EIZ, Sib_UseDisp32);
}
#endif
xWrite<s32>((s32)displacement);
}
@@ -440,11 +427,9 @@ const xRegister32
//////////////////////////////////////////////////////////////////////////////////////////
__emitinline static void EmitRex(bool w, bool r, bool x, bool b)
{
#ifdef __M_X86_64
const u8 rex = 0x40 | (w << 3) | (r << 2) | (x << 1) | (u8)b;
if (rex != 0x40)
xWrite8(rex);
#endif
}
void EmitRex(uint regfield, const void* address)
@@ -989,12 +974,8 @@ const xRegister32
__emitinline u32* xLEA_Writeback(xAddressReg to)
{
#ifdef __M_X86_64
xOpWrite(0, 0x8d, to, ptr[(void*)(0xdcdcdcd + (uptr)xGetPtr() + 7)]);
#else
xOpAccWrite(0, 0xb8 | to.Id, 0, to);
xWrite32(0xcdcdcdcd);
#endif
return (u32*)xGetPtr() - 1;
}
@@ -1045,12 +1026,7 @@ const xRegister32
}
else
{
#ifdef __M_X86_64
xOpWrite(to.GetPrefix16(), 0xff, isDec ? 1 : 0, to);
#else
to.prefix16();
xWrite8((isDec ? 0x48 : 0x40) | to.Id);
#endif
}
}
@@ -1200,25 +1176,10 @@ const xRegister32
//////////////////////////////////////////////////////////////////////////////////////////
// Helper object to handle ABI frame
#ifdef __M_X86_64
// All x86-64 calling conventions ensure/require stack to be 16 bytes aligned
// I couldn't find documentation on when, but compilers would indicate it's before the call: https://gcc.godbolt.org/z/KzTfsz
#define ALIGN_STACK(v) xADD(rsp, v)
#elif defined(__GNUC__)
// GCC ensures/requires stack to be 16 bytes aligned before the call
// Call will store 4 bytes. EDI/ESI/EBX will take another 12 bytes.
// EBP will take 4 bytes if m_base_frame is enabled
#define ALIGN_STACK(v) xADD(esp, v)
#else
#define ALIGN_STACK(v)
#endif
static void stackAlign(int offset, bool moveDown)
{
int needed = (16 - (offset % 16)) % 16;
@@ -1250,8 +1211,6 @@ const xRegister32
m_offset += sizeof(void*);
}
#ifdef __M_X86_64
xPUSH(rbx);
xPUSH(r12);
xPUSH(r13);
@@ -1265,16 +1224,6 @@ const xRegister32
m_offset += 48;
#endif
#else
// Save the register context
xPUSH(edi);
xPUSH(esi);
xPUSH(ebx);
m_offset += 12;
#endif
stackAlign(m_offset, true);
}
@@ -1282,8 +1231,6 @@ const xRegister32
{
stackAlign(m_offset, false);
#ifdef __M_X86_64
// Restore the register context
#ifdef _WIN32
xADD(rsp, 32);
@@ -1296,15 +1243,6 @@ const xRegister32
xPOP(r12);
xPOP(rbx);
#else
// Restore the register context
xPOP(ebx);
xPOP(esi);
xPOP(edi);
#endif
// Destroy the frame
if (m_base_frame)
{
@@ -1352,7 +1290,6 @@ const xRegister32
void xLoadFarAddr(const xAddressReg& dst, void* addr)
{
#ifdef __M_X86_64
sptr iaddr = (sptr)addr;
sptr rip = (sptr)xGetPtr() + 7; // LEA will be 7 bytes
sptr disp = iaddr - rip;
@@ -1364,19 +1301,11 @@ const xRegister32
{
xMOV64(dst, iaddr);
}
#else
xMOV(dst, (sptr)addr);
#endif
}
void xWriteImm64ToMem(u64* addr, const xAddressReg& tmp, u64 imm)
{
#ifdef __M_X86_64
xImm64Op(xMOV, ptr64[addr], tmp, imm);
#else
xMOV(ptr32[(u32*)addr], (u32)(imm & 0xFFFFFFFF));
xMOV(ptr32[(u32*)addr + 1], (u32)(imm >> 32));
#endif
}
} // End namespace x86Emitter
-21
View File
@@ -17,14 +17,8 @@
#include "common/Threading.h"
#ifdef __M_X86_64
static const uint iREGCNT_XMM = 16;
static const uint iREGCNT_GPR = 16;
#else
// Register counts for x86/32 mode:
static const uint iREGCNT_XMM = 8;
static const uint iREGCNT_GPR = 8;
#endif
enum XMMSSEType
{
@@ -313,17 +307,10 @@ namespace x86Emitter
bool IsSIMD() const { return GetOperandSize() == 16; }
// IsWide: return true if the register is 64 bits (requires a wide op on the rex prefix)
#ifdef __M_X86_64
bool IsWide() const
{
return GetOperandSize() == 8;
}
#else
bool IsWide() const
{
return false;
} // no 64 bits GPR
#endif
// return true if the register is a valid YMM register
bool IsWideSIMD() const { return GetOperandSize() == 32; }
@@ -498,11 +485,7 @@ namespace x86Emitter
// more sense and allows the programmer a little more type protection if needed.
//
#ifdef __M_X86_64
#define xRegisterLong xRegister64
#else
#define xRegisterLong xRegister32
#endif
static const int wordsize = sizeof(sptr);
class xAddressReg : public xRegisterLong
@@ -854,11 +837,7 @@ extern const xRegister32
typedef xIndirect<u32> xIndirect32;
typedef xIndirect<u16> xIndirect16;
typedef xIndirect<u8> xIndirect8;
#ifdef __M_X86_64
typedef xIndirect<u64> xIndirectNative;
#else
typedef xIndirect<u32> xIndirectNative;
#endif
// --------------------------------------------------------------------------------------
// xIndirect64orLess - base class 64, 32, 16, and 8 bit operand types
-12
View File
@@ -1,26 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Devel|Win32">
<Configuration>Devel</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Devel|x64">
<Configuration>Devel</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
+1 -2
View File
@@ -9,8 +9,7 @@
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)\3rdparty\wxwidgets3.0\include;$(SolutionDir)\3rdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;_M_X86_64;__M_X86_64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Platform)'=='Win32'">_ARCH_32=1;_M_X86_32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StructMemberAlignment>16Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
-12
View File
@@ -1,26 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug AVX2|Win32">
<Configuration>Debug AVX2</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug AVX2|x64">
<Configuration>Debug AVX2</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Devel AVX2|Win32">
<Configuration>Devel AVX2</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Devel AVX2|x64">
<Configuration>Devel AVX2</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release AVX2|Win32">
<Configuration>Release AVX2</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release AVX2|x64">
<Configuration>Release AVX2</Configuration>
<Platform>x64</Platform>
+1 -2
View File
@@ -26,8 +26,7 @@
<PrecompiledHeaderOutputFile>$(IntDir)pcsx2.pch</PrecompiledHeaderOutputFile>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;_M_X86_64;__M_X86_64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Platform)'=='Win32'">_ARCH_32=1;_M_X86_32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>setupapi.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
-188
View File
@@ -1,188 +0,0 @@
// GH: AMD memcpy was removed. The remaining part (memcmp_mmx) is likely from Zerofrog.
// Hopefully memcmp_mmx will be dropped in the future.
#if defined(_WIN32) && !defined(_M_AMD64)
#include "common/MemcpyFast.h"
#include "common/Assertions.h"
#ifdef _MSC_VER
#pragma warning(disable : 4414)
#endif
// Inline assembly syntax for use with Visual C++
// mmx mem-compare implementation, size has to be a multiple of 8
// returns 0 is equal, nonzero value if not equal
// ~10 times faster than standard memcmp
// (zerofrog)
u8 memcmp_mmx(const void *src1, const void *src2, int cmpsize)
{
pxAssert((cmpsize & 7) == 0);
__asm {
mov ecx, cmpsize
mov edx, src1
mov esi, src2
cmp ecx, 32
jl Done4
// custom test first 8 to make sure things are ok
movq mm0, [esi]
movq mm1, [esi+8]
pcmpeqd mm0, [edx]
pcmpeqd mm1, [edx+8]
pand mm0, mm1
movq mm2, [esi+16]
pmovmskb eax, mm0
movq mm3, [esi+24]
// check if eq
cmp eax, 0xff
je NextComp
mov eax, 1
jmp End
NextComp:
pcmpeqd mm2, [edx+16]
pcmpeqd mm3, [edx+24]
pand mm2, mm3
pmovmskb eax, mm2
sub ecx, 32
add esi, 32
add edx, 32
// check if eq
cmp eax, 0xff
je ContinueTest
mov eax, 1
jmp End
cmp ecx, 64
jl Done8
Cmp8:
movq mm0, [esi]
movq mm1, [esi+8]
movq mm2, [esi+16]
movq mm3, [esi+24]
movq mm4, [esi+32]
movq mm5, [esi+40]
movq mm6, [esi+48]
movq mm7, [esi+56]
pcmpeqd mm0, [edx]
pcmpeqd mm1, [edx+8]
pcmpeqd mm2, [edx+16]
pcmpeqd mm3, [edx+24]
pand mm0, mm1
pcmpeqd mm4, [edx+32]
pand mm0, mm2
pcmpeqd mm5, [edx+40]
pand mm0, mm3
pcmpeqd mm6, [edx+48]
pand mm0, mm4
pcmpeqd mm7, [edx+56]
pand mm0, mm5
pand mm0, mm6
pand mm0, mm7
pmovmskb eax, mm0
// check if eq
cmp eax, 0xff
je Continue
mov eax, 1
jmp End
Continue:
sub ecx, 64
add esi, 64
add edx, 64
ContinueTest:
cmp ecx, 64
jge Cmp8
Done8:
test ecx, 0x20
jz Done4
movq mm0, [esi]
movq mm1, [esi+8]
movq mm2, [esi+16]
movq mm3, [esi+24]
pcmpeqd mm0, [edx]
pcmpeqd mm1, [edx+8]
pcmpeqd mm2, [edx+16]
pcmpeqd mm3, [edx+24]
pand mm0, mm1
pand mm0, mm2
pand mm0, mm3
pmovmskb eax, mm0
sub ecx, 32
add esi, 32
add edx, 32
// check if eq
cmp eax, 0xff
je Done4
mov eax, 1
jmp End
Done4:
cmp ecx, 24
jne Done2
movq mm0, [esi]
movq mm1, [esi+8]
movq mm2, [esi+16]
pcmpeqd mm0, [edx]
pcmpeqd mm1, [edx+8]
pcmpeqd mm2, [edx+16]
pand mm0, mm1
pand mm0, mm2
pmovmskb eax, mm0
// check if eq
cmp eax, 0xff
setne al
jmp End
Done2:
cmp ecx, 16
jne Done1
movq mm0, [esi]
movq mm1, [esi+8]
pcmpeqd mm0, [edx]
pcmpeqd mm1, [edx+8]
pand mm0, mm1
pmovmskb eax, mm0
// check if eq
cmp eax, 0xff
setne al
jmp End
Done1:
cmp ecx, 8
jne Done
mov eax, [esi]
mov esi, [esi+4]
cmp eax, [edx]
je Next
mov eax, 1
jmp End
Next:
cmp esi, [edx+4]
setne al
jmp End
Done:
xor eax, eax
End:
emms
}
}
#endif
+8
View File
@@ -55,6 +55,9 @@ target_sources(pcsx2-qt PRIVATE
Settings/ControllerSettingsDialog.cpp
Settings/ControllerSettingsDialog.h
Settings/ControllerSettingsDialog.ui
Settings/CreateMemoryCardDialog.cpp
Settings/CreateMemoryCardDialog.h
Settings/CreateMemoryCardDialog.ui
Settings/EmulationSettingsWidget.cpp
Settings/EmulationSettingsWidget.h
Settings/EmulationSettingsWidget.ui
@@ -83,6 +86,11 @@ target_sources(pcsx2-qt PRIVATE
Settings/MemoryCardSettingsWidget.cpp
Settings/MemoryCardSettingsWidget.h
Settings/MemoryCardSettingsWidget.ui
Settings/DEV9SettingsWidget.cpp
Settings/DEV9SettingsWidget.h
Settings/DEV9SettingsWidget.ui
Settings/HddCreateQt.cpp
Settings/HddCreateQt.h
Settings/SettingsDialog.cpp
Settings/SettingsDialog.h
Settings/SettingsDialog.ui
+116 -23
View File
@@ -15,6 +15,8 @@
#include "PrecompiledHeader.h"
#include <cmath>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMessageBox>
@@ -28,6 +30,8 @@
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/Frontend/ImGuiManager.h"
#include "pcsx2/GS.h"
#include "pcsx2/GS/GS.h"
#include "pcsx2/GSDumpReplayer.h"
#include "pcsx2/HostDisplay.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "pcsx2/PerformanceMetrics.h"
@@ -103,6 +107,7 @@ void EmuThread::startVM(std::shared_ptr<VMBootParameters> boot_params)
}
pxAssertRel(!VMManager::HasValidVM(), "VM is shut down");
loadOurSettings();
emit onVMStarting();
@@ -138,27 +143,8 @@ void EmuThread::setVMPaused(bool paused)
VMManager::SetPaused(paused);
}
bool EmuThread::shutdownVM(bool allow_confirm /* = true */, bool allow_save_to_state /* = true */, bool blocking /* = false */)
bool EmuThread::shutdownVM(bool allow_save_to_state /* = true */)
{
if (!isOnEmuThread())
{
// 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)
{
// we need to yield here, since the display gets destroyed
while (VMManager::HasValidVM())
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
}
return true;
}
const VMState state = VMManager::GetState();
if (state == VMState::Paused)
m_event_loop->quit();
@@ -235,7 +221,7 @@ void EmuThread::run()
m_event_loop = new QEventLoop();
m_started_semaphore.release();
if (!VMManager::InitializeMemory())
if (!VMManager::Internal::InitializeMemory())
pxFailRel("Failed to allocate memory map");
// we need input sources ready for binding
@@ -257,7 +243,7 @@ void EmuThread::run()
stopBackgroundControllerPollTimer();
destroyBackgroundControllerPollTimer();
InputManager::CloseSources();
VMManager::ReleaseMemory();
VMManager::Internal::ReleaseMemory();
PerformanceMetrics::SetCPUThreadTimer(Common::ThreadCPUTimer());
moveToThread(m_ui_thread);
deleteLater();
@@ -265,6 +251,11 @@ void EmuThread::run()
void EmuThread::destroyVM()
{
m_last_speed = 0.0f;
m_last_game_fps = 0.0f;
m_last_video_fps = 0.0f;
m_last_internal_width = 0;
m_last_internal_height = 0;
VMManager::Shutdown();
}
@@ -390,6 +381,11 @@ void EmuThread::reloadGameSettings()
}
}
void EmuThread::loadOurSettings()
{
m_verbose_status = QtHost::GetBaseBoolSettingValue("UI", "VerboseStatusBar", false);
}
void EmuThread::checkForSettingChanges()
{
if (VMManager::HasValidVM())
@@ -402,6 +398,13 @@ void EmuThread::checkForSettingChanges()
GetMTGS().WaitGS();
}
}
const bool last_verbose_status = m_verbose_status;
loadOurSettings();
if (m_verbose_status != last_verbose_status)
updatePerformanceMetrics(true);
}
void EmuThread::toggleSoftwareRendering()
@@ -549,7 +552,7 @@ void EmuThread::connectDisplaySignals(DisplayWidget* widget)
connect(widget, &DisplayWidget::windowFocusEvent, this, &EmuThread::onDisplayWindowFocused);
connect(widget, &DisplayWidget::windowResizedEvent, this, &EmuThread::onDisplayWindowResized);
// connect(widget, &DisplayWidget::windowRestoredEvent, this, &EmuThread::redrawDisplayWindow);
connect(widget, &DisplayWidget::windowClosedEvent, []() { g_emu_thread->shutdownVM(true, true); });
connect(widget, &DisplayWidget::windowClosedEvent, []() { g_main_window->requestShutdown(); });
connect(widget, &DisplayWidget::windowKeyEvent, this, &EmuThread::onDisplayWindowKeyEvent);
connect(widget, &DisplayWidget::windowMouseMoveEvent, this, &EmuThread::onDisplayWindowMouseMoveEvent);
connect(widget, &DisplayWidget::windowMouseButtonEvent, this, &EmuThread::onDisplayWindowMouseButtonEvent);
@@ -677,6 +680,9 @@ bool Host::BeginPresentFrame(bool frame_skip)
void Host::EndPresentFrame()
{
if (GSDumpReplayer::IsReplayingDump())
GSDumpReplayer::RenderUI();
ImGuiManager::RenderOSD();
s_host_display->EndPresent();
ImGuiManager::NewFrame();
@@ -737,6 +743,85 @@ void Host::OnGameChanged(const std::string& disc_path, const std::string& game_s
QString::fromStdString(game_name), game_crc);
}
void EmuThread::updatePerformanceMetrics(bool force)
{
QString fps_stat, gs_stat;
bool changed = force;
if (m_verbose_status && VMManager::HasValidVM())
{
std::string gs_stat_str;
GSgetTitleStats(gs_stat_str);
changed = true;
if (THREAD_VU1)
{
gs_stat =
QStringLiteral("%1 | EE: %2% | VU: %3% | GS: %4%")
.arg(gs_stat_str.c_str())
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetVUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetGSThreadUsage(), 0, 'f', 0);
}
else
{
gs_stat = QStringLiteral("%1 | EE: %2% | GS: %3%")
.arg(gs_stat_str.c_str())
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetGSThreadUsage(), 0, 'f', 0);
}
}
const float speed = std::round(PerformanceMetrics::GetSpeed());
const float gfps = std::round(PerformanceMetrics::GetInternalFPS());
const float vfps = std::round(PerformanceMetrics::GetFPS());
int iwidth, iheight;
GSgetInternalResolution(&iwidth, &iheight);
if (iwidth != m_last_internal_width || iheight != m_last_internal_height ||
speed != m_last_speed || gfps != m_last_game_fps || vfps != m_last_video_fps ||
changed)
{
m_last_internal_width = iwidth;
m_last_internal_height = iheight;
m_last_speed = speed;
m_last_game_fps = gfps;
m_last_video_fps = vfps;
changed = true;
if (iwidth == 0 && iheight == 0)
{
// if we don't have width/height yet, we're not going to have fps either.
// and we'll probably be <100% due to compiling. so just leave it blank for now.
}
else if (PerformanceMetrics::IsInternalFPSValid())
{
fps_stat = QStringLiteral("%1x%2 | G: %3 | V: %4 | %5%")
.arg(iwidth)
.arg(iheight)
.arg(gfps, 0, 'f', 0)
.arg(vfps, 0, 'f', 0)
.arg(speed, 0, 'f', 0);
}
else
{
fps_stat = QStringLiteral("%1x%2 | V: %3 | %4%")
.arg(iwidth)
.arg(iheight)
.arg(vfps, 0, 'f', 0)
.arg(speed, 0, 'f', 0);
}
}
if (changed)
emit onPerformanceMetricsUpdated(fps_stat, gs_stat);
}
void Host::OnPerformanceMetricsUpdated()
{
g_emu_thread->updatePerformanceMetrics(false);
}
void Host::OnSaveStateLoading(const std::string_view& filename)
{
emit g_emu_thread->onSaveStateLoading(QtUtils::StringViewToQString(filename));
@@ -788,6 +873,14 @@ DEFINE_HOTKEY("Screenshot", "General", "Save Screenshot", [](bool pressed) {
// TODO
}
})
DEFINE_HOTKEY("ShutdownVM", "System", "Shut Down Virtual Machine", [](bool pressed) {
if (!pressed)
{
// run it on the host thread, that way we get the confirm prompt (if enabled)
QMetaObject::invokeMethod(g_main_window, "requestShutdown", Qt::QueuedConnection,
Q_ARG(bool, true), Q_ARG(bool, true), Q_ARG(bool, true));
}
})
DEFINE_HOTKEY("TogglePause", "System", "Toggle Pause", [](bool pressed) {
if (!pressed)
g_emu_thread->setVMPaused(VMManager::GetState() != VMState::Paused);
+13 -1
View File
@@ -52,12 +52,13 @@ public:
void startBackgroundControllerPollTimer();
void stopBackgroundControllerPollTimer();
void updatePerformanceMetrics(bool force);
public Q_SLOTS:
void startVM(std::shared_ptr<VMBootParameters> boot_params);
void resetVM();
void setVMPaused(bool paused);
bool shutdownVM(bool allow_confirm = true, bool allow_save_to_state = true, bool blocking = false);
bool shutdownVM(bool allow_save_to_state = true);
void loadState(const QString& filename);
void loadStateFromSlot(qint32 slot);
void saveState(const QString& filename);
@@ -100,6 +101,9 @@ Q_SIGNALS:
/// Provided by the host; called when the running executable changes.
void onGameChanged(const QString& path, const QString& serial, const QString& name, quint32 crc);
/// Called when performance metrics are changed, approx. once a second.
void onPerformanceMetricsUpdated(const QString& fps_stats, const QString& gs_stats);
void onInputDevicesEnumerated(const QList<QPair<QString, QString>>& devices);
void onInputDeviceConnected(const QString& identifier, const QString& device_name);
void onInputDeviceDisconnected(const QString& identifier);
@@ -129,6 +133,7 @@ private:
void createBackgroundControllerPollTimer();
void destroyBackgroundControllerPollTimer();
void loadOurSettings();
private Q_SLOTS:
void stopInThread();
@@ -148,8 +153,15 @@ private:
std::atomic_bool m_shutdown_flag{false};
bool m_verbose_status = false;
bool m_is_rendering_to_main = false;
bool m_is_fullscreen = false;
float m_last_speed = 0.0f;
float m_last_game_fps = 0.0f;
float m_last_video_fps = 0.0f;
int m_last_internal_width = 0;
int m_last_internal_height = 0;
};
/// <summary>
+13 -9
View File
@@ -41,7 +41,9 @@ static void PrintCommandLineHelp(const char* progname)
std::fprintf(stderr, "\n");
std::fprintf(stderr, " -help: Displays this information and exits.\n");
std::fprintf(stderr, " -version: Displays version information and exits.\n");
std::fprintf(stderr, " -batch: Enables batch mode (exits after powering off).\n");
std::fprintf(stderr, " -batch: Enables batch mode (exits after shutting down).\n");
std::fprintf(stderr, " -elf <file>: Overrides the boot ELF with the specified filename.\n");
std::fprintf(stderr, " -disc <path>: Uses the specified host DVD drive as a source.\n");
std::fprintf(stderr, " -fastboot: Force fast boot for provided filename.\n");
std::fprintf(stderr, " -slowboot: Force slow boot for provided filename.\n");
std::fprintf(stderr, " -resume: Load resume save state. If a boot filename is provided,\n"
@@ -64,10 +66,8 @@ static void PrintCommandLineHelp(const char* progname)
static std::shared_ptr<VMBootParameters>& AutoBoot(std::shared_ptr<VMBootParameters>& autoboot)
{
if (!autoboot)
{
autoboot = std::make_shared<VMBootParameters>();
autoboot->source_type = CDVD_SourceType::NoDisc;
}
return autoboot;
}
@@ -134,6 +134,12 @@ static bool ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr<VMBo
AutoBoot(autoboot)->elf_override = argv[++i];
continue;
}
else if (CHECK_ARG_PARAM("-disc"))
{
AutoBoot(autoboot)->source_type = CDVD_SourceType::Disc;
AutoBoot(autoboot)->filename = argv[++i];
continue;
}
else if (CHECK_ARG("-fullscreen"))
{
Console.WriteLn("Going fullscreen after booting.");
@@ -172,12 +178,10 @@ static bool ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr<VMBo
#undef CHECK_ARG_PARAM
}
if (!AutoBoot(autoboot)->source.empty())
AutoBoot(autoboot)->source += ' ';
else
AutoBoot(autoboot)->source_type = CDVD_SourceType::Iso;
if (!AutoBoot(autoboot)->filename.empty())
AutoBoot(autoboot)->filename += ' ';
AutoBoot(autoboot)->source += argv[i];
AutoBoot(autoboot)->filename += argv[i];
}
return true;
+139 -32
View File
@@ -27,7 +27,9 @@
#include "pcsx2/CDVD/CDVDaccess.h"
#include "pcsx2/Frontend/GameList.h"
#include "pcsx2/GSDumpReplayer.h"
#include "pcsx2/HostDisplay.h"
#include "pcsx2/PerformanceMetrics.h"
#include "AboutDialog.h"
#include "DisplayWidget.h"
@@ -44,9 +46,15 @@
#include "svnrev.h"
static constexpr char DISC_IMAGE_FILTER[] =
QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.chd *.cso *.elf *.irx *.m3u);;Single-Track Raw Images (*.bin "
"*.iso);;Cue Sheets (*.cue);;MAME CHD Images (*.chd);;CSO Images (*.cso);;"
"ELF Executables (*.elf);;IRX Executables (*.irx);;Playlists (*.m3u)");
QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.chd *.cso *.elf *.irx *.m3u *.gs *.gs.xz);;"
"Single-Track Raw Images (*.bin *.iso);;"
"Cue Sheets (*.cue);;"
"MAME CHD Images (*.chd);;"
"CSO Images (*.cso);;"
"ELF Executables (*.elf);;"
"IRX Executables (*.irx);;"
"Playlists (*.m3u);;"
"GS Dumps (*.gs *.gs.xz)");
const char* MainWindow::DEFAULT_THEME_NAME = "darkfusion";
@@ -106,6 +114,16 @@ void MainWindow::setupAdditionalUi()
m_status_progress_widget->setFixedSize(140, 16);
m_status_progress_widget->hide();
m_status_gs_widget = new QLabel(m_ui.statusBar);
m_status_gs_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_status_gs_widget->setFixedHeight(16);
m_status_gs_widget->hide();
m_status_fps_widget = new QLabel(m_ui.statusBar);
m_status_fps_widget->setAlignment(Qt::AlignRight);
m_status_fps_widget->setFixedHeight(16);
m_status_fps_widget->hide();
for (u32 scale = 0; scale <= 10; scale++)
{
QAction* action = m_ui.menuWindowSize->addAction((scale == 0) ? tr("Internal Resolution") : tr("%1x Scale").arg(scale));
@@ -125,7 +143,7 @@ void MainWindow::connectSignals()
connect(m_ui.actionChangeDiscFromGameList, &QAction::triggered, this, &MainWindow::onChangeDiscFromGameListActionTriggered);
connect(m_ui.menuChangeDisc, &QMenu::aboutToShow, this, &MainWindow::onChangeDiscMenuAboutToShow);
connect(m_ui.menuChangeDisc, &QMenu::aboutToHide, this, &MainWindow::onChangeDiscMenuAboutToHide);
connect(m_ui.actionPowerOff, &QAction::triggered, []() { g_emu_thread->shutdownVM(); });
connect(m_ui.actionPowerOff, &QAction::triggered, this, [this]() { requestShutdown(); });
connect(m_ui.actionLoadState, &QAction::triggered, this, [this]() { m_ui.menuLoadState->exec(QCursor::pos()); });
connect(m_ui.actionSaveState, &QAction::triggered, this, [this]() { m_ui.menuSaveState->exec(QCursor::pos()); });
connect(m_ui.actionExit, &QAction::triggered, this, &MainWindow::close);
@@ -139,7 +157,8 @@ void MainWindow::connectSignals()
connect(m_ui.actionSystemSettings, &QAction::triggered, [this]() { doSettings("System"); });
connect(m_ui.actionGraphicsSettings, &QAction::triggered, [this]() { doSettings("Graphics"); });
connect(m_ui.actionAudioSettings, &QAction::triggered, [this]() { doSettings("Audio"); });
connect(m_ui.actionMemoryCardSettings, &QAction::triggered, [this]() { doSettings("Memory Card"); });
connect(m_ui.actionMemoryCardSettings, &QAction::triggered, [this]() { doSettings("Memory Cards"); });
connect(m_ui.actionDEV9Settings, &QAction::triggered, [this]() { doSettings("Network & HDD"); });
connect(
m_ui.actionControllerSettings, &QAction::triggered, [this]() { doControllerSettings(ControllerSettingsDialog::Category::GlobalSettings); });
connect(m_ui.actionHotkeySettings, &QAction::triggered, [this]() { doControllerSettings(ControllerSettingsDialog::Category::HotkeySettings); });
@@ -172,6 +191,8 @@ void MainWindow::connectSignals()
});
connect(m_ui.actionGridViewRefreshCovers, &QAction::triggered, m_game_list_widget, &GameListWidget::refreshGridCovers);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionViewStatusBarVerbose, "UI", "VerboseStatusBar", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableSystemConsole, "Logging", "EnableSystemConsole", false);
connect(m_ui.actionEnableSystemConsole, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
#ifndef PCSX2_DEVBUILD
@@ -182,9 +203,9 @@ void MainWindow::connectSignals()
m_ui.actionEnableVerboseLogging->setChecked(true);
m_ui.actionEnableVerboseLogging->setEnabled(false);
#endif
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableEEConsoleLogging, "Logging", "EnableEEConsole", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableEEConsoleLogging, "Logging", "EnableEEConsole", true);
connect(m_ui.actionEnableEEConsoleLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableIOPConsoleLogging, "Logging", "EnableIOPConsole", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableIOPConsoleLogging, "Logging", "EnableIOPConsole", true);
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.
@@ -208,6 +229,7 @@ void MainWindow::connectVMThreadSignals(EmuThread* thread)
connect(thread, &EmuThread::onVMResumed, this, &MainWindow::onVMResumed);
connect(thread, &EmuThread::onVMStopped, this, &MainWindow::onVMStopped);
connect(thread, &EmuThread::onGameChanged, this, &MainWindow::onGameChanged);
connect(thread, &EmuThread::onPerformanceMetricsUpdated, this, &MainWindow::onPerformanceMetricsUpdated);
connect(m_ui.actionReset, &QAction::triggered, thread, &EmuThread::resetVM);
connect(m_ui.actionPause, &QAction::toggled, thread, &EmuThread::setVMPaused);
@@ -230,7 +252,7 @@ void MainWindow::connectVMThreadSignals(EmuThread* thread)
void MainWindow::recreate()
{
if (m_vm_valid)
g_emu_thread->shutdownVM(false, true, true);
requestShutdown(false, true, true);
close();
g_main_window = nullptr;
@@ -557,6 +579,27 @@ void MainWindow::updateEmulationActions(bool starting, bool running)
m_game_list_widget->setDisabled(starting && !running);
}
void MainWindow::updateStatusBarWidgetVisibility()
{
auto Update = [this](QWidget* widget, bool visible, int stretch)
{
if (widget->isVisible())
{
m_ui.statusBar->removeWidget(widget);
widget->hide();
}
if (visible)
{
m_ui.statusBar->addPermanentWidget(widget, stretch);
widget->show();
}
};
Update(m_status_gs_widget, m_vm_valid && !m_vm_paused, 1);
Update(m_status_fps_widget, m_vm_valid, 0);
}
void MainWindow::updateWindowTitle()
{
QString title;
@@ -602,7 +645,10 @@ void MainWindow::clearProgressBar()
m_ui.statusBar->removeWidget(m_status_progress_widget);
}
bool MainWindow::isShowingGameList() const { return m_ui.mainContainer->currentIndex() == 0; }
bool MainWindow::isShowingGameList() const
{
return m_ui.mainContainer->currentIndex() == 0;
}
void MainWindow::switchToGameListView()
{
@@ -635,32 +681,62 @@ void MainWindow::switchToEmulationView()
m_display_widget->setFocus();
}
void MainWindow::refreshGameList(bool invalidate_cache) { m_game_list_widget->refresh(invalidate_cache); }
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()
void MainWindow::refreshGameList(bool invalidate_cache)
{
if (!m_vm_valid || !QtHost::GetBaseBoolSettingValue("UI", "ConfirmShutdown", true))
m_game_list_widget->refresh(invalidate_cache);
}
void MainWindow::invalidateSaveStateCache()
{
m_save_states_invalidated = true;
}
void MainWindow::reportError(const QString& title, const QString& message)
{
QMessageBox::critical(this, title, message);
}
bool MainWindow::requestShutdown(bool allow_confirm /* = true */, bool allow_save_to_state /* = true */, bool block_until_done /* = false */)
{
if (!VMManager::HasValidVM())
return true;
ScopedVMPause pauser(m_vm_paused);
// only confirm on UI thread because we need to display a msgbox
if (allow_confirm && !GSDumpReplayer::IsReplayingDump() && QtHost::GetBaseBoolSettingValue("UI", "ConfirmShutdown", true))
{
ScopedVMPause pauser(m_vm_paused);
if (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)
{
return false;
}
}
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);
g_emu_thread->shutdownVM(allow_save_to_state);
if (block_until_done)
{
// we need to yield here, since the display gets destroyed
while (VMManager::HasValidVM())
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
}
return true;
}
void MainWindow::requestExit()
{
if (!g_emu_thread->shutdownVM(true, true, false))
// this is block, because otherwise closeEvent() will also prompt
if (!requestShutdown(true, true, true))
return;
close();
}
void Host::InvalidateSaveStateCache() { QMetaObject::invokeMethod(g_main_window, &MainWindow::invalidateSaveStateCache, Qt::QueuedConnection); }
void Host::InvalidateSaveStateCache()
{
QMetaObject::invokeMethod(g_main_window, &MainWindow::invalidateSaveStateCache, Qt::QueuedConnection);
}
void MainWindow::onGameListRefreshProgress(const QString& status, int current, int total)
{
@@ -668,7 +744,10 @@ void MainWindow::onGameListRefreshProgress(const QString& status, int current, i
setProgressBar(current, total);
}
void MainWindow::onGameListRefreshComplete() { clearProgressBar(); }
void MainWindow::onGameListRefreshComplete()
{
clearProgressBar();
}
void MainWindow::onGameListSelectionChanged()
{
@@ -779,14 +858,13 @@ void MainWindow::onStartFileActionTriggered()
return;
std::shared_ptr<VMBootParameters> params = std::make_shared<VMBootParameters>();
VMManager::SetBootParametersForPath(filename.toStdString(), params.get());
params->filename = filename.toStdString();
g_emu_thread->startVM(std::move(params));
}
void MainWindow::onStartBIOSActionTriggered()
{
std::shared_ptr<VMBootParameters> params = std::make_shared<VMBootParameters>();
params->source_type = CDVD_SourceType::NoDisc;
g_emu_thread->startVM(std::move(params));
}
@@ -801,7 +879,10 @@ void MainWindow::onChangeDiscFromFileActionTriggered()
g_emu_thread->changeDisc(filename);
}
void MainWindow::onChangeDiscFromGameListActionTriggered() { switchToGameListView(); }
void MainWindow::onChangeDiscFromGameListActionTriggered()
{
switchToGameListView();
}
void MainWindow::onChangeDiscFromDeviceActionTriggered()
{
@@ -885,11 +966,20 @@ void MainWindow::onViewGamePropertiesActionTriggered()
SettingsDialog::openGamePropertiesDialog(nullptr, m_current_game_crc);
}
void MainWindow::onGitHubRepositoryActionTriggered() { QtUtils::OpenURL(this, AboutDialog::getGitHubRepositoryUrl()); }
void MainWindow::onGitHubRepositoryActionTriggered()
{
QtUtils::OpenURL(this, AboutDialog::getGitHubRepositoryUrl());
}
void MainWindow::onSupportForumsActionTriggered() { QtUtils::OpenURL(this, AboutDialog::getSupportForumsUrl()); }
void MainWindow::onSupportForumsActionTriggered()
{
QtUtils::OpenURL(this, AboutDialog::getSupportForumsUrl());
}
void MainWindow::onDiscordServerActionTriggered() { QtUtils::OpenURL(this, AboutDialog::getDiscordServerUrl()); }
void MainWindow::onDiscordServerActionTriggered()
{
QtUtils::OpenURL(this, AboutDialog::getDiscordServerUrl());
}
void MainWindow::onAboutActionTriggered()
{
@@ -939,6 +1029,7 @@ void MainWindow::onVMStarted()
m_vm_valid = true;
updateEmulationActions(true, true);
updateWindowTitle();
updateStatusBarWidgetVisibility();
}
void MainWindow::onVMPaused()
@@ -951,6 +1042,8 @@ void MainWindow::onVMPaused()
m_vm_paused = true;
updateWindowTitle();
updateStatusBarWidgetVisibility();
m_status_fps_widget->setText(tr("Paused"));
}
void MainWindow::onVMResumed()
@@ -963,14 +1056,18 @@ void MainWindow::onVMResumed()
m_vm_paused = false;
updateWindowTitle();
updateStatusBarWidgetVisibility();
m_status_fps_widget->setText(m_last_fps_status);
}
void MainWindow::onVMStopped()
{
m_vm_valid = false;
m_vm_paused = false;
m_last_fps_status = QString();
updateEmulationActions(false, false);
updateWindowTitle();
updateStatusBarWidgetVisibility();
switchToGameListView();
}
@@ -984,9 +1081,16 @@ void MainWindow::onGameChanged(const QString& path, const QString& serial, const
updateSaveStateMenus(path, serial, crc);
}
void MainWindow::onPerformanceMetricsUpdated(const QString& fps_stat, const QString& gs_stat)
{
m_last_fps_status = fps_stat;
m_status_fps_widget->setText(m_last_fps_status);
m_status_gs_widget->setText(gs_stat);
}
void MainWindow::closeEvent(QCloseEvent* event)
{
if (!g_emu_thread->shutdownVM(true, true, true))
if (!requestShutdown(true, true, true))
{
event->ignore();
return;
@@ -1191,7 +1295,10 @@ void MainWindow::displayResizeRequested(qint32 width, qint32 height)
resize(QSize(std::max<qint32>(width, 1), std::max<qint32>(height + extra_height, 1)));
}
void MainWindow::destroyDisplay() { destroyDisplayWidget(); }
void MainWindow::destroyDisplay()
{
destroyDisplayWidget();
}
void MainWindow::focusDisplayWidget()
{
@@ -1398,7 +1505,7 @@ void MainWindow::loadSaveStateFile(const QString& filename, const QString& state
else
{
std::shared_ptr<VMBootParameters> params = std::make_shared<VMBootParameters>();
VMManager::SetBootParametersForPath(filename.toStdString(), params.get());
params->filename = filename.toStdString();
params->save_state = state_filename.toStdString();
g_emu_thread->startVM(std::move(params));
}
+8 -1
View File
@@ -15,6 +15,7 @@
#pragma once
#include <QtWidgets/QLabel>
#include <QtWidgets/QMainWindow>
#include <optional>
@@ -54,7 +55,7 @@ public Q_SLOTS:
void refreshGameList(bool invalidate_cache);
void invalidateSaveStateCache();
void reportError(const QString& title, const QString& message);
bool confirmShutdown();
bool requestShutdown(bool allow_confirm = true, bool allow_save_to_state = true, bool block_until_done = false);
void requestExit();
private Q_SLOTS:
@@ -103,6 +104,7 @@ private Q_SLOTS:
void onVMStopped();
void onGameChanged(const QString& path, const QString& serial, const QString& name, quint32 crc);
void onPerformanceMetricsUpdated(const QString& fps_stat, const QString& gs_stat);
void recreate();
@@ -124,6 +126,7 @@ private:
void restoreStateFromConfig();
void updateEmulationActions(bool starting, bool running);
void updateStatusBarWidgetVisibility();
void updateWindowTitle();
void setProgressBar(int current, int total);
void clearProgressBar();
@@ -166,6 +169,8 @@ private:
ControllerSettingsDialog* m_controller_settings_dialog = nullptr;
QProgressBar* m_status_progress_widget = nullptr;
QLabel* m_status_gs_widget = nullptr;
QLabel* m_status_fps_widget = nullptr;
QString m_current_disc_path;
QString m_current_game_serial;
@@ -175,6 +180,8 @@ private:
bool m_vm_paused = false;
bool m_save_states_invalidated = false;
bool m_was_focused_on_container_switch = false;
QString m_last_fps_status;
};
extern MainWindow* g_main_window;
+27
View File
@@ -111,6 +111,7 @@
<addaction name="actionGraphicsSettings"/>
<addaction name="actionAudioSettings"/>
<addaction name="actionMemoryCardSettings"/>
<addaction name="actionDEV9Settings"/>
<addaction name="actionControllerSettings"/>
<addaction name="actionHotkeySettings"/>
<addaction name="separator"/>
@@ -167,6 +168,7 @@
<addaction name="actionViewToolbar"/>
<addaction name="actionViewLockToolbar"/>
<addaction name="actionViewStatusBar"/>
<addaction name="actionViewStatusBarVerbose"/>
<addaction name="separator"/>
<addaction name="actionViewGameList"/>
<addaction name="actionViewGameGrid"/>
@@ -555,6 +557,14 @@
<string>&amp;Memory Cards</string>
</property>
</action>
<action name="actionDEV9Settings">
<property name="text">
<string>&amp;Network &amp;&amp; HDD</string>
</property>
<property name="icon">
<iconset theme="dashboard-line"/>
</property>
</action>
<action name="actionViewToolbar">
<property name="checkable">
<bool>true</bool>
@@ -588,6 +598,17 @@
<string>&amp;Status Bar</string>
</property>
</action>
<action name="actionViewStatusBarVerbose">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>Verbose Status</string>
</property>
</action>
<action name="actionViewGameList">
<property name="icon">
<iconset theme="list-check">
@@ -699,11 +720,17 @@
</property>
</action>
<action name="actionEnableEEConsoleLogging">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Enable EE Console Logging</string>
</property>
</action>
<action name="actionEnableIOPConsoleLogging">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Enable IOP Console Logging</string>
</property>
+10 -3
View File
@@ -54,7 +54,6 @@ static bool InitializeConfig();
static void HookSignals();
static bool SetCriticalFolders();
static void SetDefaultConfig();
static void QueueSettingsSave();
static void SaveSettings();
}
@@ -82,6 +81,9 @@ bool QtHost::Initialize()
return false;
}
if (!VMManager::Internal::InitializeGlobals())
return false;
HookSignals();
return true;
}
@@ -174,6 +176,11 @@ void QtHost::SetDefaultConfig()
PAD::SetDefaultConfig(si);
}
SettingsInterface* QtHost::GetBaseSettingsInterface()
{
return s_base_settings_interface.get();
}
std::string QtHost::GetBaseStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
{
auto lock = Host::GetSettingsLock();
@@ -313,13 +320,13 @@ void Host::ReportErrorAsync(const std::string_view& title, const std::string_vie
{
if (!title.empty() && !message.empty())
{
Console.Error("ReportErrorAsync: %*s: %*s",
Console.Error("ReportErrorAsync: %.*s: %.*s",
static_cast<int>(title.size()), title.data(),
static_cast<int>(message.size()), message.data());
}
else if (!message.empty())
{
Console.Error("ReportErrorAsync: %*s",
Console.Error("ReportErrorAsync: %.*s",
static_cast<int>(message.size()), message.data());
}
+2
View File
@@ -38,6 +38,7 @@ namespace QtHost
void UpdateLogging();
/// Thread-safe settings access.
SettingsInterface* GetBaseSettingsInterface();
std::string GetBaseStringSettingValue(const char* section, const char* key, const char* default_value = "");
bool GetBaseBoolSettingValue(const char* section, const char* key, bool default_value = false);
int GetBaseIntSettingValue(const char* section, const char* key, int default_value = 0);
@@ -51,4 +52,5 @@ namespace QtHost
bool AddBaseValueToStringList(const char* section, const char* key, const char* value);
bool RemoveBaseValueFromStringList(const char* section, const char* key, const char* value);
void RemoveBaseSettingValue(const char* section, const char* key);
void QueueSettingsSave();
} // namespace QtHost
+4 -4
View File
@@ -435,7 +435,7 @@ namespace SettingWidgetBinder
int sif_value;
if (sif->GetIntValue(section.c_str(), key.c_str(), &sif_value))
Accessor::setNullableIntValue(widget, sif_value);
Accessor::setNullableIntValue(widget, sif_value - option_offset);
else
Accessor::setNullableIntValue(widget, std::nullopt);
@@ -735,7 +735,7 @@ namespace SettingWidgetBinder
{
for (int i = 0; enum_values[i] != nullptr; i++)
{
if (value == enum_values[i])
if (sif_value == enum_values[i])
{
sif_int_value = i;
break;
@@ -744,9 +744,9 @@ namespace SettingWidgetBinder
}
Accessor::setNullableIntValue(widget, sif_int_value);
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key), enum_names]() {
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key), enum_values]() {
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()]);
sif->SetStringValue(section.c_str(), key.c_str(), enum_values[new_value.value()]);
else
sif->DeleteValue(section.c_str(), key.c_str());
@@ -42,7 +42,7 @@ AdvancedSystemSettingsWidget::AdvancedSystemSettingsWidget(SettingsDialog* dialo
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.iopRecompiler, "EmuCore/CPU/Recompiler", "EnableIOP", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.gameFixes, "", "EnableGameFixes", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.gameFixes, "EmuCore", "EnableGameFixes", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.patches, "EmuCore", "EnablePatches", true);
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.ntscFrameRate, "EmuCore/GS", "FramerateNTSC", 59.94f);
+84 -1
View File
@@ -24,12 +24,95 @@
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"
static constexpr s32 DEFAULT_INTERPOLATION_MODE = 5;
static constexpr s32 DEFAULT_SYNCHRONIZATION_MODE = 0;
static constexpr s32 DEFAULT_EXPANSION_MODE = 0;
static const char* DEFAULT_OUTPUT_MODULE = "cubeb";
static constexpr s32 DEFAULT_OUTPUT_LATENCY = 100;
static constexpr s32 DEFAULT_VOLUME = 100;
static constexpr s32 DEFAULT_SOUNDTOUCH_SEQUENCE_LENGTH = 30;
static constexpr s32 DEFAULT_SOUNDTOUCH_SEEK_WINDOW = 20;
static constexpr s32 DEFAULT_SOUNDTOUCH_OVERLAP = 10;
static const char* s_output_module_entries[] = {
QT_TRANSLATE_NOOP("AudioSettingsWidget", "No Sound (Emulate SPU2 only)"),
QT_TRANSLATE_NOOP("AudioSettingsWidget", "Cubeb (Cross-platform)"),
#ifdef _WIN32
QT_TRANSLATE_NOOP("AudioSettingsWidget", "XAudio2"),
#endif
nullptr
};
static const char* s_output_module_values[] = {
"nullout",
"cubeb",
#ifdef _WIN32
"xaudio2",
#endif
nullptr
};
AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent)
: QWidget(parent)
{
// SettingsInterface* sif = dialog->getSettingsInterface();
SettingsInterface* sif = dialog->getSettingsInterface();
m_ui.setupUi(this);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.interpolation, "SPU2/Mixing", "Interpolation", DEFAULT_INTERPOLATION_MODE);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.syncMode, "SPU2/Output", "SynchMode", DEFAULT_SYNCHRONIZATION_MODE);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.expansionMode, "SPU2/Output", "SpeakerConfiguration", DEFAULT_EXPANSION_MODE);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.outputModule, "SPU2/Output", "OutputModule", s_output_module_entries, s_output_module_values, DEFAULT_OUTPUT_MODULE);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.latency, "SPU2/Output", "Latency", DEFAULT_OUTPUT_LATENCY);
connect(m_ui.latency, &QSlider::valueChanged, this, &AudioSettingsWidget::updateLatencyLabel);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.volume, "SPU2/Mixing", "FinalVolume", DEFAULT_VOLUME);
connect(m_ui.volume, &QSlider::valueChanged, this, &AudioSettingsWidget::updateVolumeLabel);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.sequenceLength, "Soundtouch", "SequenceLengthMS", DEFAULT_SOUNDTOUCH_SEQUENCE_LENGTH);
connect(m_ui.sequenceLength, &QSlider::valueChanged, this, &AudioSettingsWidget::updateTimestretchSequenceLengthLabel);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.seekWindowSize, "Soundtouch", "SeekWindowMS", DEFAULT_SOUNDTOUCH_SEEK_WINDOW);
connect(m_ui.seekWindowSize, &QSlider::valueChanged, this, &AudioSettingsWidget::updateTimestretchSeekwindowLengthLabel);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.overlap, "Soundtouch", "OverlapMS", DEFAULT_SOUNDTOUCH_OVERLAP);
connect(m_ui.overlap, &QSlider::valueChanged, this, &AudioSettingsWidget::updateTimestretchOverlapLabel);
updateVolumeLabel();
updateLatencyLabel();
updateTimestretchSequenceLengthLabel();
updateTimestretchSeekwindowLengthLabel();
updateTimestretchOverlapLabel();
}
AudioSettingsWidget::~AudioSettingsWidget() = default;
void AudioSettingsWidget::updateVolumeLabel()
{
m_ui.volumeLabel->setText(tr("%1%").arg(m_ui.volume->value()));
}
void AudioSettingsWidget::updateLatencyLabel()
{
m_ui.latencyLabel->setText(tr("%1 ms (avg)").arg(m_ui.latency->value()));
}
void AudioSettingsWidget::updateTimestretchSequenceLengthLabel()
{
m_ui.sequenceLengthLabel->setText(tr("%1 ms").arg(m_ui.sequenceLength->value()));
}
void AudioSettingsWidget::updateTimestretchSeekwindowLengthLabel()
{
m_ui.seekWindowSizeLabel->setText(tr("%1 ms").arg(m_ui.seekWindowSize->value()));
}
void AudioSettingsWidget::updateTimestretchOverlapLabel()
{
m_ui.overlapLabel->setText(tr("%1 ms").arg(m_ui.overlap->value()));
}
void AudioSettingsWidget::resetTimestretchDefaults()
{
m_ui.sequenceLength->setValue(DEFAULT_SOUNDTOUCH_SEQUENCE_LENGTH);
m_ui.seekWindowSize->setValue(DEFAULT_SOUNDTOUCH_SEEK_WINDOW);
m_ui.overlap->setValue(DEFAULT_SOUNDTOUCH_OVERLAP);
}
+8
View File
@@ -29,6 +29,14 @@ public:
AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent);
~AudioSettingsWidget();
private Q_SLOTS:
void updateVolumeLabel();
void updateLatencyLabel();
void updateTimestretchSequenceLengthLabel();
void updateTimestretchSeekwindowLengthLabel();
void updateTimestretchOverlapLabel();
void resetTimestretchDefaults();
private:
Ui::AudioSettingsWidget m_ui;
};
+394 -2
View File
@@ -6,13 +6,405 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<width>752</width>
<height>430</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Mixing Settings</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Interpolation:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="interpolation">
<item>
<property name="text">
<string>Nearest (Fastest / worst quality)</string>
</property>
</item>
<item>
<property name="text">
<string>Linear (Simple / okay sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Cubic (Fake highs / okay sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Hermite (Better highs / okay sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Catmull-Rom (PS2-like / good sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Gaussian (PS2-like / great sound)</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Synchronization:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="syncMode">
<item>
<property name="text">
<string>TimeStretch (Recommended)</string>
</property>
</item>
<item>
<property name="text">
<string>Async Mix (Breaks some games!)</string>
</property>
</item>
<item>
<property name="text">
<string>None (Audio can skip.)</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Expansion:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="expansionMode">
<item>
<property name="text">
<string>Stereo (None, Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Quadrafonic</string>
</property>
</item>
<item>
<property name="text">
<string>Surround 5.1</string>
</property>
</item>
<item>
<property name="text">
<string>Surround 7.1</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Output Settings</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Output Module:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="outputModule" />
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Latency:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSlider" name="latency">
<property name="minimum">
<number>15</number>
</property>
<property name="maximum">
<number>200</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>200</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="latencyLabel">
<property name="text">
<string>100 ms (avg)</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Timestretch Settings</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Sequence Length:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSlider" name="sequenceLength">
<property name="minimum">
<number>20</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="sequenceLengthLabel">
<property name="text">
<string>100</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Seekwindow Size:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSlider" name="seekWindowSize">
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>30</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seekWindowSizeLabel">
<property name="text">
<string>100</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Overlap:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QSlider" name="overlap">
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>15</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="overlapLabel">
<property name="text">
<string>100</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Reset Defaults</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1" rowspan="4">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Volume</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QSlider" name="volume">
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="volumeLabel">
<property name="text">
<string>100%</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
+56 -7
View File
@@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include <QtWidgets/QMenu>
#include <QtWidgets/QMessageBox>
#include <algorithm>
@@ -39,13 +40,11 @@ ControllerBindingWidget::ControllerBindingWidget(QWidget* parent, ControllerSett
onTypeChanged();
SettingWidgetBinder::BindWidgetToStringSetting(nullptr, m_ui.controllerType, m_config_section, "Type", "None");
connect(m_ui.controllerType, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&ControllerBindingWidget::onTypeChanged);
connect(m_ui.controllerType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ControllerBindingWidget::onTypeChanged);
connect(m_ui.automaticBinding, &QPushButton::clicked, this, &ControllerBindingWidget::doAutomaticBinding);
}
ControllerBindingWidget::~ControllerBindingWidget()
{
}
ControllerBindingWidget::~ControllerBindingWidget() = default;
void ControllerBindingWidget::populateControllerTypes()
{
@@ -80,6 +79,56 @@ void ControllerBindingWidget::onTypeChanged()
m_ui.verticalLayout->addWidget(m_current_widget, 1);
}
void ControllerBindingWidget::doAutomaticBinding()
{
QMenu menu(this);
bool added = false;
for (const QPair<QString, QString>& dev : m_dialog->getDeviceList())
{
// we set it as data, because the device list could get invalidated while the menu is up
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(dev.first).arg(dev.second));
action->setData(dev.first);
connect(action, &QAction::triggered, this, [this, action]() {
doDeviceAutomaticBinding(action->data().toString());
});
added = true;
}
if (!added)
{
QAction* action = menu.addAction(tr("No devices available"));
action->setEnabled(false);
}
menu.exec(QCursor::pos());
}
void ControllerBindingWidget::doDeviceAutomaticBinding(const QString& device)
{
std::vector<std::pair<GenericInputBinding, std::string>> mapping = InputManager::GetGenericBindingMapping(device.toStdString());
if (mapping.empty())
{
QMessageBox::critical(QtUtils::GetRootWidget(this), tr("Automatic Binding"),
tr("No generic bindings were generated for device '%1'").arg(device));
return;
}
bool result;
{
auto lock = Host::GetSettingsLock();
result = PAD::MapController(*QtHost::GetBaseSettingsInterface(), m_port_number, mapping);
}
if (result)
{
// force a refresh after mapping
onTypeChanged();
QtHost::QueueSettingsSave();
g_emu_thread->applySettings();
}
}
//////////////////////////////////////////////////////////////////////////
ControllerBindingWidget_Base::ControllerBindingWidget_Base(ControllerBindingWidget* parent)
@@ -102,7 +151,7 @@ void ControllerBindingWidget_Base::initBindingWidgets()
InputBindingWidget* widget = findChild<InputBindingWidget*>(QString::fromStdString(binding));
if (!widget)
{
Console.Error("(ControllerBindingWidget_Base) No widget found for '%s' (%*s)",
Console.Error("(ControllerBindingWidget_Base) No widget found for '%s' (%.*s)",
binding.c_str(), static_cast<int>(type.size()), type.data());
continue;
}
@@ -155,4 +204,4 @@ ControllerBindingWidget_Base* ControllerBindingWidget_DualShock2::createInstance
return new ControllerBindingWidget_DualShock2(parent);
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -39,9 +39,11 @@ public:
private Q_SLOTS:
void onTypeChanged();
void doAutomaticBinding();
private:
void populateControllerTypes();
void doDeviceAutomaticBinding(const QString& device);
Ui::ControllerBindingWidget m_ui;
@@ -89,18 +89,29 @@ void ControllerSettingsDialog::onCategoryCurrentRowChanged(int row)
void ControllerSettingsDialog::onInputDevicesEnumerated(const QList<QPair<QString, QString>>& devices)
{
m_device_list = devices;
for (const QPair<QString, QString>& device : devices)
m_global_settings->addDeviceToList(device.first, device.second);
}
void ControllerSettingsDialog::onInputDeviceConnected(const QString& identifier, const QString& device_name)
{
m_device_list.emplace_back(identifier, device_name);
m_global_settings->addDeviceToList(identifier, device_name);
g_emu_thread->enumerateVibrationMotors();
}
void ControllerSettingsDialog::onInputDeviceDisconnected(const QString& identifier)
{
for (auto iter = m_device_list.begin(); iter != m_device_list.end(); ++iter)
{
if (iter->first == identifier)
{
m_device_list.erase(iter);
break;
}
}
m_global_settings->removeDeviceFromList(identifier);
g_emu_thread->enumerateVibrationMotors();
}
@@ -50,6 +50,7 @@ public:
HotkeySettingsWidget* getHotkeySettingsWidget() const { return m_hotkey_settings; }
__fi const QList<QPair<QString, QString>>& getDeviceList() const { return m_device_list; }
__fi const QStringList& getVibrationMotors() const { return m_vibration_motors; }
public Q_SLOTS:
@@ -70,5 +71,6 @@ private:
std::array<ControllerBindingWidget*, MAX_PORTS> m_port_bindings{};
HotkeySettingsWidget* m_hotkey_settings = nullptr;
QList<QPair<QString, QString>> m_device_list;
QStringList m_vibration_motors;
};
@@ -0,0 +1,136 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "common/StringUtil.h"
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QPushButton>
#include "Settings/CreateMemoryCardDialog.h"
#include "pcsx2/MemoryCardFile.h"
#include "pcsx2/System.h"
CreateMemoryCardDialog::CreateMemoryCardDialog(QWidget* parent /* = nullptr */)
: QDialog(parent)
{
m_ui.setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
connect(m_ui.name, &QLineEdit::textChanged, this, &CreateMemoryCardDialog::nameTextChanged);
connect(m_ui.size8MB, &QRadioButton::clicked, this, [this]() { setType(MemoryCardType::File, MemoryCardFileType::PS2_8MB); });
connect(m_ui.size16MB, &QRadioButton::clicked, this, [this]() { setType(MemoryCardType::File, MemoryCardFileType::PS2_16MB); });
connect(m_ui.size32MB, &QRadioButton::clicked, this, [this]() { setType(MemoryCardType::File, MemoryCardFileType::PS2_32MB); });
connect(m_ui.size64MB, &QRadioButton::clicked, this, [this]() { setType(MemoryCardType::File, MemoryCardFileType::PS2_64MB); });
connect(m_ui.size128KB, &QRadioButton::clicked, this, [this]() { setType(MemoryCardType::File, MemoryCardFileType::PS1); });
connect(m_ui.sizeFolder, &QRadioButton::clicked, this, [this]() { setType(MemoryCardType::Folder, MemoryCardFileType::Unknown); });
disconnect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, nullptr);
connect(m_ui.buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &CreateMemoryCardDialog::createCard);
connect(m_ui.buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &CreateMemoryCardDialog::close);
connect(m_ui.buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, this, &CreateMemoryCardDialog::restoreDefaults);
#ifdef _WIN32
m_ui.ntfsCompression->setEnabled(false);
#endif
updateState();
}
CreateMemoryCardDialog::~CreateMemoryCardDialog() = default;
void CreateMemoryCardDialog::nameTextChanged()
{
const QString controlName(m_ui.name->text());
const int cursorPos = m_ui.name->cursorPosition();
QString nameWithoutExtension;
if (controlName.endsWith(QStringLiteral(".ps2")))
nameWithoutExtension = controlName.left(controlName.size() - 4);
else
nameWithoutExtension = controlName;
QSignalBlocker sb(m_ui.name);
if (nameWithoutExtension.isEmpty())
m_ui.name->setText(QString());
else
m_ui.name->setText(nameWithoutExtension + QStringLiteral(".ps2"));
m_ui.name->setCursorPosition(cursorPos);
updateState();
}
void CreateMemoryCardDialog::setType(MemoryCardType type, MemoryCardFileType fileType)
{
m_type = type;
m_fileType = fileType;
updateState();
}
void CreateMemoryCardDialog::restoreDefaults()
{
setType(MemoryCardType::File, MemoryCardFileType::PS2_8MB);
m_ui.size8MB->setChecked(true);
m_ui.size16MB->setChecked(false);
m_ui.size32MB->setChecked(false);
m_ui.size64MB->setChecked(false);
m_ui.size128KB->setChecked(false);
m_ui.sizeFolder->setChecked(false);
}
void CreateMemoryCardDialog::updateState()
{
const bool okay = (m_ui.name->text().length() > 4);
m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(okay);
#ifdef _WIN32
m_ui.ntfsCompression->setEnabled(m_type == MemoryCardType::File);
#endif
}
void CreateMemoryCardDialog::createCard()
{
const QString name(m_ui.name->text());
const std::string nameStr(name.toStdString());
if (FileMcd_GetCardInfo(nameStr).has_value())
{
QMessageBox::critical(this, tr("Create Memory Card"),
tr("Failed to create the memory card, because another card with the name '%1' already exists.").arg(name));
return;
}
if (!FileMcd_CreateNewCard(nameStr, m_type, m_fileType))
{
QMessageBox::critical(this, tr("Create Memory Card"),
tr("Failed to create the memory card, the log may contain more information."));
return;
}
#ifdef _WIN32
if (m_ui.ntfsCompression->isChecked() && m_type == MemoryCardType::File)
{
const std::string fullPath(Path::CombineStdString(EmuFolders::MemoryCards, nameStr));
NTFS_CompressFile(StringUtil::UTF8StringToWxString(fullPath), true);
}
#endif
QMessageBox::information(this, tr("Create Memory Card"), tr("Memory card '%1' created.").arg(name));
accept();
}
@@ -0,0 +1,45 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QtWidgets/QDialog>
#include "ui_CreateMemoryCardDialog.h"
#include "pcsx2/Config.h"
class CreateMemoryCardDialog final : public QDialog
{
Q_OBJECT
public:
explicit CreateMemoryCardDialog(QWidget* parent = nullptr);
~CreateMemoryCardDialog();
private Q_SLOTS:
void nameTextChanged();
void createCard();
private:
void setType(MemoryCardType type, MemoryCardFileType fileType);
void restoreDefaults();
void updateState();
Ui::CreateMemoryCardDialog m_ui;
MemoryCardType m_type = MemoryCardType::File;
MemoryCardFileType m_fileType = MemoryCardFileType::PS2_8MB;
};
+312
View File
@@ -0,0 +1,312 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CreateMemoryCardDialog</class>
<widget class="QDialog" name="CreateMemoryCardDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>593</width>
<height>545</height>
</rect>
</property>
<property name="windowTitle">
<string>Create Memory Card</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="minimumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="pixmap">
<pixmap resource="../resources/resources.qrc">:/icons/black/48/sd-card-line.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:700;&quot;&gt;Create Memory Card&lt;/span&gt;&lt;br /&gt;Enter the name of the memory card you wish to create, and choose a size. We recommend either using 8MB memory cards, or folder memory cards for best compatibility.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Memory Card Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="name"/>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="size8MB">
<property name="text">
<string>8 MB [Most Compatible]</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>This is the standard Sony-provisioned size, and is supported by all games and BIOS versions.</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QRadioButton" name="size16MB">
<property name="text">
<string>16 MB</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>A typical size for third-party memory cards which should work with most games.</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QRadioButton" name="size32MB">
<property name="text">
<string>32 MB</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>A typical size for third-party memory cards which should work with most games.</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QRadioButton" name="size64MB">
<property name="text">
<string>64 MB</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Low compatiblity warning: yes, it's very big, but may not work with many games.</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QRadioButton" name="sizeFolder">
<property name="text">
<string>Folder [Recommended]</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>Store memory card contents in the host filesystem instead of a file.</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QRadioButton" name="size128KB">
<property name="text">
<string>128 KB (PS1)</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>This is the standard Sony-provisioned size PS1 memory card, and only compatible with PS1 games.</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QCheckBox" name="ntfsCompression">
<property name="text">
<string>Use NTFS Compression</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>NTFS compression is built-in, fast, and completely reliable. Typically compresses memory cards (highly recommended).</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../resources/resources.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>CreateMemoryCardDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>CreateMemoryCardDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+868
View File
@@ -0,0 +1,868 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QFileDialog>
#include <algorithm>
#include "common/StringUtil.h"
#include "DEV9SettingsWidget.h"
#include "EmuThread.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"
#include "HddCreateQt.h"
#include "DEV9/pcap_io.h"
#ifdef _WIN32
#include "DEV9/Win32/tap.h"
#endif
#include "DEV9/sockets.h"
static const char* s_api_name[] = {
QT_TRANSLATE_NOOP("DEV9SettingsWidget", " "),
QT_TRANSLATE_NOOP("DEV9SettingsWidget", "PCAP Bridged"),
QT_TRANSLATE_NOOP("DEV9SettingsWidget", "PCAP Switched"),
QT_TRANSLATE_NOOP("DEV9SettingsWidget", "TAP"),
QT_TRANSLATE_NOOP("DEV9SettingsWidget", "Sockets"),
nullptr,
};
static const char* s_dns_name[] = {
QT_TRANSLATE_NOOP("DEV9SettingsWidget", "Manual"),
QT_TRANSLATE_NOOP("DEV9SettingsWidget", "Auto"),
QT_TRANSLATE_NOOP("DEV9SettingsWidget", "Internal"),
nullptr,
};
using PacketReader::IP::IP_Address;
#define IP_RANGE_INTER "([0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]|)"
#define IP_RANGE_FINAL "([0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"
// clang-format off
const QRegularExpression IPValidator::intermediateRegex{QStringLiteral("^" IP_RANGE_INTER "\\." IP_RANGE_INTER "\\." IP_RANGE_INTER "\\." IP_RANGE_INTER "$")};
const QRegularExpression IPValidator::finalRegex {QStringLiteral("^" IP_RANGE_FINAL "\\." IP_RANGE_FINAL "\\." IP_RANGE_FINAL "\\." IP_RANGE_FINAL "$")};
// clang-format on
IPValidator::IPValidator(QObject* parent, bool allowEmpty)
: QValidator(parent)
, m_allowEmpty{allowEmpty}
{
}
QValidator::State IPValidator::validate(QString& input, int& pos) const
{
if (input.isEmpty())
return m_allowEmpty ? Acceptable : Intermediate;
QRegularExpressionMatch m = finalRegex.match(input, 0, QRegularExpression::NormalMatch);
if (m.hasMatch())
return Acceptable;
m = intermediateRegex.match(input, 0, QRegularExpression::PartialPreferCompleteMatch);
if (m.hasMatch() || m.hasPartialMatch())
return Intermediate;
else
{
pos = input.size();
return Invalid;
}
}
IPItemDelegate::IPItemDelegate(QObject* parent)
: QItemDelegate(parent)
{
}
QWidget* IPItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QLineEdit* editor = new QLineEdit(parent);
editor->setValidator(new IPValidator());
return editor;
}
void IPItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
QString value = index.model()->data(index, Qt::EditRole).toString();
QLineEdit* line = static_cast<QLineEdit*>(editor);
line->setText(value);
}
void IPItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
QLineEdit* line = static_cast<QLineEdit*>(editor);
QString value = line->text();
model->setData(index, value);
}
void IPItemDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
editor->setGeometry(option.rect);
}
DEV9SettingsWidget::DEV9SettingsWidget(SettingsDialog* dialog, QWidget* parent)
: QWidget(parent)
, m_dialog{dialog}
{
SettingsInterface* sif = dialog->getSettingsInterface();
m_ui.setupUi(this);
//////////////////////////////////////////////////////////////////////////
// Eth Enabled
//////////////////////////////////////////////////////////////////////////
//Connect needs to be after BindWidgetToBoolSetting to ensure correct order of execution for disabling a per game setting
//but we then need to manually call onEthAutoChanged to update the UI on fist load
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.ethEnabled, "DEV9/Eth", "EthEnable", false);
onEthEnabledChanged(m_ui.ethEnabled->checkState());
connect(m_ui.ethEnabled, QOverload<int>::of(&QCheckBox::stateChanged), this, &DEV9SettingsWidget::onEthEnabledChanged);
//////////////////////////////////////////////////////////////////////////
// Eth Device Settings
//////////////////////////////////////////////////////////////////////////
connect(m_ui.ethDevType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DEV9SettingsWidget::onEthDeviceTypeChanged);
m_api_list.push_back(Pcsx2Config::DEV9Options::NetApi::Unset);
for (const AdapterEntry& adapter : PCAPAdapter::GetAdapters())
AddAdapter(adapter);
#ifdef _WIN32
for (const AdapterEntry& adapter : TAPAdapter::GetAdapters())
AddAdapter(adapter);
#endif
for (const AdapterEntry& adapter : SocketAdapter::GetAdapters())
AddAdapter(adapter);
std::sort(m_api_list.begin(), m_api_list.end());
for (auto& list : m_adapter_list)
std::sort(list.begin(), list.end(), [](const AdapterEntry& a, AdapterEntry& b) { return a.name < b.name; });
for (const Pcsx2Config::DEV9Options::NetApi& na : m_api_list)
{
m_api_namelist.push_back(s_api_name[static_cast<int>(na)]);
m_api_valuelist.push_back(Pcsx2Config::DEV9Options::NetApiNames[static_cast<int>(na)]);
}
m_api_namelist.push_back(nullptr);
m_api_valuelist.push_back(nullptr);
//We replace the blank entry with one for global settings
if (m_dialog->isPerGameSettings())
{
const std::string valueAPI = QtHost::GetBaseStringSettingValue("DEV9/Eth", "EthApi", Pcsx2Config::DEV9Options::NetApiNames[static_cast<int>(Pcsx2Config::DEV9Options::NetApi::Unset)]);
for (int i = 0; Pcsx2Config::DEV9Options::NetApiNames[i] != nullptr; i++)
{
if (valueAPI == Pcsx2Config::DEV9Options::NetApiNames[i])
{
m_global_api = static_cast<Pcsx2Config::DEV9Options::NetApi>(i);
break;
}
}
std::vector<AdapterEntry> baseList = m_adapter_list[static_cast<u32>(m_global_api)];
std::string baseAdapter = " ";
const std::string valueGUID = QtHost::GetBaseStringSettingValue("DEV9/Eth", "EthDevice", "");
for (size_t i = 0; i < baseList.size(); i++)
{
if (baseList[i].guid == valueGUID)
{
baseAdapter = baseList[i].name;
break;
}
}
m_adapter_list[static_cast<u32>(Pcsx2Config::DEV9Options::NetApi::Unset)][0].name = baseAdapter;
}
if (m_dialog->isPerGameSettings())
m_ui.ethDevType->addItem(tr("Use Global Setting [%1]").arg(QString::fromUtf8(Pcsx2Config::DEV9Options::NetApiNames[static_cast<u32>(m_global_api)])));
else
m_ui.ethDevType->addItem(QString::fromUtf8(m_api_namelist[0]));
for (int i = 1; m_api_namelist[i] != nullptr; i++)
m_ui.ethDevType->addItem(QString::fromUtf8(m_api_namelist[i]));
const std::string value = m_dialog->getStringValue("DEV9/Eth", "EthApi", Pcsx2Config::DEV9Options::NetApiNames[static_cast<int>(Pcsx2Config::DEV9Options::NetApi::Unset)]).value();
for (int i = 0; m_api_namelist[i] != nullptr; i++)
{
if (value == m_api_valuelist[i])
{
m_ui.ethDevType->setCurrentIndex(i);
break;
}
}
//onEthDeviceTypeChanged gets called automatically
connect(m_ui.ethDev, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DEV9SettingsWidget::onEthDeviceChanged);
//////////////////////////////////////////////////////////////////////////
// DHCP Settings
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.ethInterceptDHCP, "DEV9/Eth", "InterceptDHCP", false);
onEthDHCPInterceptChanged(m_ui.ethInterceptDHCP->checkState());
connect(m_ui.ethInterceptDHCP, QOverload<int>::of(&QCheckBox::stateChanged), this, &DEV9SettingsWidget::onEthDHCPInterceptChanged);
//IP settings
const IPValidator* ipValidator = new IPValidator(this, m_dialog->isPerGameSettings());
// clang-format off
m_ui.ethPS2Addr ->setValidator(ipValidator);
m_ui.ethNetMask ->setValidator(ipValidator);
m_ui.ethGatewayAddr->setValidator(ipValidator);
m_ui.ethDNS1Addr ->setValidator(ipValidator);
m_ui.ethDNS2Addr ->setValidator(ipValidator);
if (m_dialog->isPerGameSettings())
{
m_ui.ethPS2Addr ->setText(QString::fromUtf8(m_dialog->getStringValue("DEV9/Eth", "PS2IP", "").value().c_str()));
m_ui.ethNetMask ->setText(QString::fromUtf8(m_dialog->getStringValue("DEV9/Eth", "Mask", "").value().c_str()));
m_ui.ethGatewayAddr->setText(QString::fromUtf8(m_dialog->getStringValue("DEV9/Eth", "Gateway", "").value().c_str()));
m_ui.ethDNS1Addr ->setText(QString::fromUtf8(m_dialog->getStringValue("DEV9/Eth", "DNS1", "").value().c_str()));
m_ui.ethDNS2Addr ->setText(QString::fromUtf8(m_dialog->getStringValue("DEV9/Eth", "DNS2", "").value().c_str()));
m_ui.ethPS2Addr ->setPlaceholderText(QString::fromUtf8(QtHost::GetBaseStringSettingValue("DEV9/Eth", "PS2IP", "0.0.0.0").c_str()));
m_ui.ethNetMask ->setPlaceholderText(QString::fromUtf8(QtHost::GetBaseStringSettingValue("DEV9/Eth", "Mask", "0.0.0.0").c_str()));
m_ui.ethGatewayAddr->setPlaceholderText(QString::fromUtf8(QtHost::GetBaseStringSettingValue("DEV9/Eth", "Gateway", "0.0.0.0").c_str()));
m_ui.ethDNS1Addr ->setPlaceholderText(QString::fromUtf8(QtHost::GetBaseStringSettingValue("DEV9/Eth", "DNS1", "0.0.0.0").c_str()));
m_ui.ethDNS2Addr ->setPlaceholderText(QString::fromUtf8(QtHost::GetBaseStringSettingValue("DEV9/Eth", "DNS2", "0.0.0.0").c_str()));
}
else
{
m_ui.ethPS2Addr ->setText(QString::fromUtf8(m_dialog->getStringValue("DEV9/Eth", "PS2IP", "0.0.0.0").value().c_str()));
m_ui.ethNetMask ->setText(QString::fromUtf8(m_dialog->getStringValue("DEV9/Eth", "Mask", "0.0.0.0").value().c_str()));
m_ui.ethGatewayAddr->setText(QString::fromUtf8(m_dialog->getStringValue("DEV9/Eth", "Gateway", "0.0.0.0").value().c_str()));
m_ui.ethDNS1Addr ->setText(QString::fromUtf8(m_dialog->getStringValue("DEV9/Eth", "DNS1", "0.0.0.0").value().c_str()));
m_ui.ethDNS2Addr ->setText(QString::fromUtf8(m_dialog->getStringValue("DEV9/Eth", "DNS2", "0.0.0.0").value().c_str()));
}
connect(m_ui.ethPS2Addr, &QLineEdit::editingFinished, this, [&]() { onEthIPChanged(m_ui.ethPS2Addr, "DEV9/Eth", "PS2IP" ); });
connect(m_ui.ethNetMask, &QLineEdit::editingFinished, this, [&]() { onEthIPChanged(m_ui.ethNetMask, "DEV9/Eth", "Mask" ); });
connect(m_ui.ethGatewayAddr, &QLineEdit::editingFinished, this, [&]() { onEthIPChanged(m_ui.ethGatewayAddr, "DEV9/Eth", "Gateway"); });
connect(m_ui.ethDNS1Addr, &QLineEdit::editingFinished, this, [&]() { onEthIPChanged(m_ui.ethDNS1Addr, "DEV9/Eth", "DNS1" ); });
connect(m_ui.ethDNS2Addr, &QLineEdit::editingFinished, this, [&]() { onEthIPChanged(m_ui.ethDNS2Addr, "DEV9/Eth", "DNS2" ); });
// clang-format on
//Auto
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.ethNetMaskAuto, "DEV9/Eth", "AutoMask", true);
onEthAutoChanged(m_ui.ethNetMaskAuto, m_ui.ethNetMaskAuto->checkState(), m_ui.ethNetMask, "DEV9/Eth", "AutoMask");
connect(m_ui.ethNetMaskAuto, QOverload<int>::of(&QCheckBox::stateChanged), this, [&](int state) { onEthAutoChanged(m_ui.ethNetMaskAuto, state, m_ui.ethNetMask, "DEV9/Eth", "AutoMask"); });
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.ethGatewayAuto, "DEV9/Eth", "AutoGateway", true);
onEthAutoChanged(m_ui.ethGatewayAuto, m_ui.ethGatewayAuto->checkState(), m_ui.ethGatewayAddr, "DEV9/Eth", "AutoGateway");
connect(m_ui.ethGatewayAuto, QOverload<int>::of(&QCheckBox::stateChanged), this, [&](int state) { onEthAutoChanged(m_ui.ethGatewayAuto, state, m_ui.ethGatewayAddr, "DEV9/Eth", "AutoGateway"); });
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.ethDNS1Mode, "DEV9/Eth", "ModeDNS1",
s_dns_name, Pcsx2Config::DEV9Options::DnsModeNames, Pcsx2Config::DEV9Options::DnsModeNames[static_cast<int>(Pcsx2Config::DEV9Options::DnsMode::Auto)]);
onEthDNSModeChanged(m_ui.ethDNS1Mode, m_ui.ethDNS1Mode->currentIndex(), m_ui.ethDNS1Addr, "DEV9/Eth", "ModeDNS1");
connect(m_ui.ethDNS1Mode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [&](int index) { onEthDNSModeChanged(m_ui.ethDNS1Mode, index, m_ui.ethDNS1Addr, "DEV9/Eth", "ModeDNS1"); });
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.ethDNS2Mode, "DEV9/Eth", "ModeDNS2",
s_dns_name, Pcsx2Config::DEV9Options::DnsModeNames, Pcsx2Config::DEV9Options::DnsModeNames[static_cast<int>(Pcsx2Config::DEV9Options::DnsMode::Auto)]);
onEthDNSModeChanged(m_ui.ethDNS2Mode, m_ui.ethDNS2Mode->currentIndex(), m_ui.ethDNS2Addr, "DEV9/Eth", "ModeDNS2");
connect(m_ui.ethDNS2Mode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [&](int index) { onEthDNSModeChanged(m_ui.ethDNS2Mode, index, m_ui.ethDNS2Addr, "DEV9/Eth", "ModeDNS2"); });
//////////////////////////////////////////////////////////////////////////
// DNS Settings
//////////////////////////////////////////////////////////////////////////
m_ethHost_model = new QStandardItemModel(0, 4, m_ui.ethHosts);
QStringList headers;
headers.push_back(tr("Name"));
headers.push_back(tr("Url"));
headers.push_back(tr("Address"));
headers.push_back(tr("Enabled"));
m_ethHost_model->setHorizontalHeaderLabels(headers);
connect(m_ethHost_model, QOverload<QStandardItem*>::of(&QStandardItemModel::itemChanged), this, &DEV9SettingsWidget::onEthHostEdit);
m_ethHosts_proxy = new QSortFilterProxyModel(m_ui.ethHosts);
m_ethHosts_proxy->setSourceModel(m_ethHost_model);
m_ui.ethHosts->setModel(m_ethHosts_proxy);
m_ui.ethHosts->setItemDelegateForColumn(2, new IPItemDelegate(m_ui.ethHosts));
RefreshHostList();
m_ui.ethHosts->installEventFilter(this);
connect(m_ui.ethHostAdd, &QPushButton::clicked, this, &DEV9SettingsWidget::onEthHostAdd);
connect(m_ui.ethHostDel, &QPushButton::clicked, this, &DEV9SettingsWidget::onEthHostDel);
if (m_dialog->isPerGameSettings())
m_ui.ethTabWidget->setTabEnabled(1, false);
//////////////////////////////////////////////////////////////////////////
// HDD Settings
//////////////////////////////////////////////////////////////////////////
connect(m_ui.hddEnabled, QOverload<int>::of(&QCheckBox::stateChanged), this, &DEV9SettingsWidget::onHddEnabledChanged);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.hddEnabled, "DEV9/Hdd", "HddEnable", false);
connect(m_ui.hddFile, &QLineEdit::editingFinished, this, &DEV9SettingsWidget::onHddFileEdit);
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.hddFile, "DEV9/Hdd", "HddFile", "DEV9hdd.raw");
if (m_dialog->isPerGameSettings())
m_ui.hddFile->setPlaceholderText(QString::fromUtf8(QtHost::GetBaseStringSettingValue("DEV9/Hdd", "HddFile", "DEV9hdd.raw")));
connect(m_ui.hddBrowseFile, &QPushButton::clicked, this, &DEV9SettingsWidget::onHddBrowseFileClicked);
//TODO: need a getUintValue for if 48bit support occurs
const int size = (u64)m_dialog->getIntValue("DEV9/Hdd", "HddSizeSectors", 0).value() * 512 / (1024 * 1024 * 1024);
if (m_dialog->isPerGameSettings())
{
const int sizeGlobal = (u64)QtHost::GetBaseIntSettingValue("DEV9/Hdd", "HddSizeSectors", 0) * 512 / (1024 * 1024 * 1024);
m_ui.hddSizeSpinBox->setMinimum(39);
m_ui.hddSizeSpinBox->setSpecialValueText(tr("Global [%1]").arg(sizeGlobal));
}
// clang-format off
m_ui.hddSizeSlider ->setValue(size);
m_ui.hddSizeSpinBox->setValue(size);
connect(m_ui.hddSizeSlider, QOverload<int>::of(&QSlider ::valueChanged), this, &DEV9SettingsWidget::onHddSizeSlide);
connect(m_ui.hddSizeSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &DEV9SettingsWidget::onHddSizeSpin );
// clang-format on
connect(m_ui.hddCreate, &QPushButton::clicked, this, &DEV9SettingsWidget::onHddCreateClicked);
}
void DEV9SettingsWidget::onEthEnabledChanged(int state)
{
const bool enabled = state == Qt::CheckState::PartiallyChecked ? QtHost::GetBaseBoolSettingValue("DEV9/Eth", "EthEnable", false) : state;
m_ui.ethDevType->setEnabled(enabled);
m_ui.ethDevTypeLabel->setEnabled(enabled);
m_ui.ethDevLabel->setEnabled(enabled);
m_ui.ethDev->setEnabled(enabled);
m_ui.ethTabWidget->setEnabled(enabled);
}
void DEV9SettingsWidget::onEthDeviceTypeChanged(int index)
{
{
QSignalBlocker sb(m_ui.ethDev);
m_ui.ethDev->clear();
}
Pcsx2Config::DEV9Options::NetApi selectedApi{Pcsx2Config::DEV9Options::NetApi ::Unset};
if (index > 0)
{
std::vector<AdapterEntry> list = m_adapter_list[static_cast<u32>(m_api_list[index])];
const std::string value = m_dialog->getEffectiveStringValue("DEV9/Eth", "EthDevice", "");
for (size_t i = 0; i < list.size(); i++)
{
m_ui.ethDev->addItem(QString::fromUtf8(list[i].name));
if (list[i].guid == value)
m_ui.ethDev->setCurrentIndex(i);
}
selectedApi = m_api_list[index];
}
if (m_dialog->isPerGameSettings())
{
if (index == 0)
{
std::vector<AdapterEntry> list = m_adapter_list[static_cast<u32>(m_api_list[index])];
m_ui.ethDev->addItem(tr("Use Global Setting [%1]").arg(QString::fromUtf8(list[0].name)));
m_ui.ethDev->setCurrentIndex(0);
m_ui.ethDev->setEnabled(false);
selectedApi = m_global_api;
}
else
m_ui.ethDev->setEnabled(true);
}
switch (selectedApi)
{
#ifdef _WIN32
case Pcsx2Config::DEV9Options::NetApi::TAP:
m_adapter_options = TAPAdapter::GetAdapterOptions();
break;
#endif
case Pcsx2Config::DEV9Options::NetApi::PCAP_Bridged:
case Pcsx2Config::DEV9Options::NetApi::PCAP_Switched:
m_adapter_options = PCAPAdapter::GetAdapterOptions();
break;
case Pcsx2Config::DEV9Options::NetApi::Sockets:
m_adapter_options = SocketAdapter::GetAdapterOptions();
break;
default:
m_adapter_options = AdapterOptions::None;
break;
}
m_ui.ethInterceptDHCP->setEnabled((m_adapter_options & AdapterOptions::DHCP_ForcedOn) == AdapterOptions::None);
onEthDHCPInterceptChanged(m_ui.ethInterceptDHCP->checkState());
}
void DEV9SettingsWidget::onEthDeviceChanged(int index)
{
if (index > 0)
{
const AdapterEntry& adapter = m_adapter_list[static_cast<u32>(m_api_list[m_ui.ethDevType->currentIndex()])][index];
m_dialog->setStringSettingValue("DEV9/Eth", "EthApi", Pcsx2Config::DEV9Options::NetApiNames[static_cast<int>(adapter.type)]);
m_dialog->setStringSettingValue("DEV9/Eth", "EthDevice", adapter.guid.c_str());
}
else if (m_dialog->isPerGameSettings() && m_ui.ethDevType->currentIndex() == 0 && index == 0)
{
m_dialog->setStringSettingValue("DEV9/Eth", "EthApi", std::nullopt);
m_dialog->setStringSettingValue("DEV9/Eth", "EthDevice", std::nullopt);
}
}
void DEV9SettingsWidget::onEthDHCPInterceptChanged(int state)
{
const bool enabled = (state == Qt::CheckState::PartiallyChecked ? QtHost::GetBaseBoolSettingValue("DEV9/Eth", "InterceptDHCP", false) : state) ||
((m_adapter_options & AdapterOptions::DHCP_ForcedOn) == AdapterOptions::DHCP_ForcedOn);
// clang-format off
const bool ipOverride = (m_adapter_options & AdapterOptions::DHCP_OverrideIP) == AdapterOptions::DHCP_OverrideIP;
const bool snOverride = (m_adapter_options & AdapterOptions::DHCP_OverideSubnet) == AdapterOptions::DHCP_OverideSubnet;
const bool gwOverride = (m_adapter_options & AdapterOptions::DHCP_OverideGateway) == AdapterOptions::DHCP_OverideGateway;
// clang-format on
m_ui.ethPS2Addr->setEnabled(enabled && !ipOverride);
m_ui.ethPS2AddrLabel->setEnabled(enabled && !ipOverride);
m_ui.ethNetMaskLabel->setEnabled(enabled && !snOverride);
m_ui.ethNetMaskAuto->setEnabled(enabled && !snOverride);
onEthAutoChanged(m_ui.ethNetMaskAuto, m_ui.ethNetMaskAuto->checkState(), m_ui.ethNetMask, "DEV9/Eth", "AutoMask");
m_ui.ethGatewayAddrLabel->setEnabled(enabled && !gwOverride);
m_ui.ethGatewayAuto->setEnabled(enabled && !gwOverride);
onEthAutoChanged(m_ui.ethGatewayAuto, m_ui.ethGatewayAuto->checkState(), m_ui.ethGatewayAddr, "DEV9/Eth", "AutoGateway");
m_ui.ethDNS1AddrLabel->setEnabled(enabled);
m_ui.ethDNS1Mode->setEnabled(enabled);
onEthDNSModeChanged(m_ui.ethDNS1Mode, m_ui.ethDNS1Mode->currentIndex(), m_ui.ethDNS1Addr, "DEV9/Eth", "ModeDNS1");
m_ui.ethDNS2AddrLabel->setEnabled(enabled);
m_ui.ethDNS2Mode->setEnabled(enabled);
onEthDNSModeChanged(m_ui.ethDNS2Mode, m_ui.ethDNS2Mode->currentIndex(), m_ui.ethDNS2Addr, "DEV9/Eth", "ModeDNS2");
}
void DEV9SettingsWidget::onEthIPChanged(QLineEdit* sender, const char* section, const char* key)
{
//Alow clearing a per-game ip setting
if (sender->text().isEmpty())
{
if (m_dialog->getStringValue(section, key, std::nullopt).has_value())
m_dialog->setStringSettingValue(section, key, std::nullopt);
return;
}
//should already be validated
u8 bytes[4];
std::string inputString = sender->text().toUtf8().constData();
sscanf(inputString.c_str(), "%hhu.%hhu.%hhu.%hhu", &bytes[0], &bytes[1], &bytes[2], &bytes[3]);
std::string neatStr = StringUtil::StdStringFromFormat("%u.%u.%u.%u", bytes[0], bytes[1], bytes[2], bytes[3]);
sender->setText(QString::fromUtf8(neatStr.c_str()));
std::string oldval = m_dialog->getStringValue(section, key, "0.0.0.0").value();
if (neatStr != oldval)
m_dialog->setStringSettingValue(section, key, neatStr.c_str());
}
void DEV9SettingsWidget::onEthAutoChanged(QCheckBox* sender, int state, QLineEdit* input, const char* section, const char* key)
{
if (sender->isEnabled())
{
const bool manual = !(state == Qt::CheckState::PartiallyChecked ? QtHost::GetBaseBoolSettingValue(section, key, true) : state);
input->setEnabled(manual);
}
else
input->setEnabled(false);
}
void DEV9SettingsWidget::onEthDNSModeChanged(QComboBox* sender, int index, QLineEdit* input, const char* section, const char* key)
{
if (sender->isEnabled())
{
if (m_dialog->isPerGameSettings())
{
if (index == 0)
{
const std::string value = QtHost::GetBaseStringSettingValue(section, key, Pcsx2Config::DEV9Options::DnsModeNames[static_cast<int>(Pcsx2Config::DEV9Options::DnsMode::Auto)]);
for (int i = 0; Pcsx2Config::DEV9Options::DnsModeNames[i] != nullptr; i++)
{
if (value == Pcsx2Config::DEV9Options::DnsModeNames[i])
{
index = i;
break;
}
}
}
else
index--;
}
const bool manual = index == static_cast<int>(Pcsx2Config::DEV9Options::DnsMode::Manual);
input->setEnabled(manual);
}
else
input->setEnabled(false);
}
void DEV9SettingsWidget::onEthHostAdd()
{
HostEntryUi host;
host.Desc = "New Host";
host.Enabled = false;
AddNewHostConfig(host);
//Select new Item
const QModelIndex viewIndex = m_ethHosts_proxy->mapFromSource(m_ethHost_model->index(m_ethHost_model->rowCount() - 1, 1));
m_ui.ethHosts->scrollTo(viewIndex, QAbstractItemView::EnsureVisible);
m_ui.ethHosts->selectionModel()->setCurrentIndex(viewIndex, QItemSelectionModel::ClearAndSelect);
}
void DEV9SettingsWidget::onEthHostDel()
{
if (m_ui.ethHosts->selectionModel()->hasSelection())
{
const QModelIndex selectedIndex = m_ui.ethHosts->selectionModel()->currentIndex();
const int modelRow = m_ethHosts_proxy->mapToSource(selectedIndex).row();
DeleteHostConfig(modelRow);
}
}
void DEV9SettingsWidget::onEthHostEdit(QStandardItem* item)
{
const int row = item->row();
std::string section = "DEV9/Eth/Hosts/Host" + std::to_string(row);
switch (item->column())
{
case 0: //Name
m_dialog->setStringSettingValue(section.c_str(), "Desc", item->text().toUtf8().constData());
break;
case 1: //URL
m_dialog->setStringSettingValue(section.c_str(), "Url", item->text().toUtf8().constData());
break;
case 2: //IP
m_dialog->setStringSettingValue(section.c_str(), "Address", item->text().toUtf8().constData());
break;
case 3: //Enabled
m_dialog->setBoolSettingValue(section.c_str(), "Enabled", item->checkState() == Qt::CheckState::Checked);
break;
default:
break;
}
}
void DEV9SettingsWidget::onHddEnabledChanged(int state)
{
const bool enabled = state == Qt::CheckState::PartiallyChecked ? m_dialog->getEffectiveBoolValue("DEV9/Hdd", "HddEnable", false) : state;
m_ui.hddFile->setEnabled(enabled);
m_ui.hddFileLabel->setEnabled(enabled);
m_ui.hddBrowseFile->setEnabled(enabled);
m_ui.hddSizeLabel->setEnabled(enabled);
m_ui.hddSizeSlider->setEnabled(enabled);
m_ui.hddSizeMaxLabel->setEnabled(enabled);
m_ui.hddSizeMinLabel->setEnabled(enabled);
m_ui.hddSizeSpinBox->setEnabled(enabled);
m_ui.hddCreate->setEnabled(enabled);
}
void DEV9SettingsWidget::onHddBrowseFileClicked()
{
QString path =
QDir::toNativeSeparators(QFileDialog::getSaveFileName(QtUtils::GetRootWidget(this), tr("HDD Image File"),
!m_ui.hddFile->text().isEmpty() ? m_ui.hddFile->text() : "DEV9hdd.raw", tr("HDD (*.raw)"), nullptr,
QFileDialog::DontConfirmOverwrite));
if (path.isEmpty())
return;
m_ui.hddFile->setText(path);
m_ui.hddFile->editingFinished();
}
void DEV9SettingsWidget::onHddFileEdit()
{
//Check if file exists, if so set HddSize to correct value
//GHC uses UTF8 on all platforms
fs::path hddPath(m_ui.hddFile->text().toUtf8().constData());
if (hddPath.empty())
return;
if (hddPath.is_relative())
{
fs::path path(EmuFolders::Settings.ToString().wx_str());
hddPath = path / hddPath;
}
if (!fs::exists(hddPath))
return;
const uintmax_t size = fs::file_size(hddPath);
const u32 sizeSectors = (size / 512);
const int sizeGB = size / 1024 / 1024 / 1024;
QSignalBlocker sb1(m_ui.hddSizeSpinBox);
QSignalBlocker sb2(m_ui.hddSizeSlider);
m_ui.hddSizeSpinBox->setValue(sizeGB);
m_ui.hddSizeSlider->setValue(sizeGB);
m_dialog->setIntSettingValue("DEV9/Hdd", "HddSizeSectors", (int)sizeSectors);
}
void DEV9SettingsWidget::onHddSizeSlide(int i)
{
QSignalBlocker sb(m_ui.hddSizeSpinBox);
m_ui.hddSizeSpinBox->setValue(i);
m_dialog->setIntSettingValue("DEV9/Hdd", "HddSizeSectors", (int)((s64)i * 1024 * 1024 * 1024 / 512));
}
void DEV9SettingsWidget::onHddSizeSpin(int i)
{
QSignalBlocker sb(m_ui.hddSizeSlider);
m_ui.hddSizeSlider->setValue(i);
//TODO: need a setUintSettingValue for if 48bit support occurs
if (i == 39)
m_dialog->setIntSettingValue("DEV9/Hdd", "HddSizeSectors", std::nullopt);
else
m_dialog->setIntSettingValue("DEV9/Hdd", "HddSizeSectors", i * (1024 * 1024 * 1024 / 512));
}
void DEV9SettingsWidget::onHddCreateClicked()
{
//Do the thing
fs::path hddPath(m_ui.hddFile->text().toUtf8().constData());
u64 sizeBytes = (u64)m_dialog->getEffectiveIntValue("DEV9/Hdd", "HddSizeSectors", 0) * 512;
if (sizeBytes == 0 || hddPath.empty())
{
QMessageBox::warning(this, QObject::tr("HDD Creator"),
QObject::tr("Failed to create HDD image"),
QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
return;
}
if (hddPath.is_relative())
{
//Note, EmuFolders is still wx strings
fs::path path(EmuFolders::Settings.ToString().wx_str());
hddPath = path / hddPath;
}
if (fs::exists(hddPath))
{
//GHC uses UTF8 on all platforms
QMessageBox::StandardButton selection =
QMessageBox::question(this, tr("Overwrite File?"),
tr("HDD image \"%1\" already exists?\n\n"
"Do you want to overwrite?")
.arg(QString::fromUtf8(hddPath.u8string().c_str())),
QMessageBox::Yes | QMessageBox::No);
if (selection == QMessageBox::No)
return;
else
fs::remove(hddPath);
}
HddCreateQt hddCreator(this);
hddCreator.filePath = hddPath;
hddCreator.neededSize = sizeBytes;
hddCreator.Start();
if (!hddCreator.errored)
{
QMessageBox::information(this, tr("HDD Creator"),
tr("HDD image created"),
QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
}
}
void DEV9SettingsWidget::showEvent(QShowEvent* event)
{
QWidget::showEvent(event);
//The API combobox dosn't set the EthApi field, that is performed by the device combobox (in addition to saving the device)
//This means that this setting can get out of sync with true value, so revert to that if the ui is closed and opened
const std::string value = m_dialog->getStringValue("DEV9/Eth", "EthApi", Pcsx2Config::DEV9Options::NetApiNames[static_cast<int>(Pcsx2Config::DEV9Options::NetApi::Unset)]).value();
//disconnect temporally to prevent saving a vaule already in the config file
disconnect(m_ui.ethDev, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DEV9SettingsWidget::onEthDeviceChanged);
for (int i = 0; m_api_namelist[i] != nullptr; i++)
{
if (value == m_api_valuelist[i])
{
m_ui.ethDevType->setCurrentIndex(i);
break;
}
}
connect(m_ui.ethDev, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DEV9SettingsWidget::onEthDeviceChanged);
}
/*
* QtUtils::ResizeColumnsForTableView() needs the widget to already be the correct size
* Doing this in our resizeEvent (like GameListWidget does) dosn't work if the ui is
* hidden, maybe because our table is nested within group & tab widgets
* We could also listern to out show event, but we also need to listern to the tab
* changed signal, in the event that another tab is selected when our ui is shown
*
* Instead, lets use an eventFilter to determine exactly when the host table is shown
* However, the eventFilter is ran before the widgets event handler, meaning the table
* is still the wrong size, so we also need to check the show event
*/
bool DEV9SettingsWidget::eventFilter(QObject* object, QEvent* event)
{
if (object == m_ui.ethHosts)
{
//Check isVisible to avoind an unnessecery call to ResizeColumnsForTableView()
if (event->type() == QEvent::Resize && m_ui.ethHosts->isVisible())
QtUtils::ResizeColumnsForTableView(m_ui.ethHosts, {-1, 170, 90, 80});
else if (event->type() == QEvent::Show)
QtUtils::ResizeColumnsForTableView(m_ui.ethHosts, {-1, 170, 90, 80});
}
return false;
}
void DEV9SettingsWidget::AddAdapter(const AdapterEntry& adapter)
{
//divide into seperate adapter lists
if (std::find(m_api_list.begin(), m_api_list.end(), adapter.type) == m_api_list.end())
m_api_list.push_back(adapter.type);
const u32 idx = static_cast<u32>(adapter.type);
while (m_adapter_list.size() <= idx)
{
//Add blank adapter
AdapterEntry blankAdapter;
blankAdapter.guid = "";
blankAdapter.name = "";
blankAdapter.type = static_cast<Pcsx2Config::DEV9Options::NetApi>(m_adapter_list.size());
m_adapter_list.push_back({blankAdapter});
}
m_adapter_list[idx].push_back(adapter);
}
void DEV9SettingsWidget::RefreshHostList()
{
while (m_ethHost_model->rowCount() > 0)
m_ethHost_model->removeRow(0);
//Load list
std::vector<HostEntryUi> hosts;
const int hostLength = CountHostsConfig();
for (int i = 0; i < hostLength; i++)
{
std::string section = "DEV9/Eth/Hosts/Host" + std::to_string(i);
HostEntryUi entry;
entry.Url = m_dialog->getStringValue(section.c_str(), "Url", "").value();
entry.Desc = m_dialog->getStringValue(section.c_str(), "Desc", "").value();
entry.Address = m_dialog->getStringValue(section.c_str(), "Address", "").value();
entry.Enabled = m_dialog->getBoolValue(section.c_str(), "Enabled", false).value();
hosts.push_back(entry);
}
for (int i = 0; i < hostLength; i++)
{
HostEntryUi entry = hosts[i];
const int row = m_ethHost_model->rowCount();
m_ethHost_model->insertRow(row);
QSignalBlocker sb(m_ethHost_model);
QStandardItem* nameItem = new QStandardItem();
nameItem->setText(QString::fromStdString(entry.Desc));
m_ethHost_model->setItem(row, 0, nameItem);
QStandardItem* urlItem = new QStandardItem();
urlItem->setText(QString::fromStdString(entry.Url));
m_ethHost_model->setItem(row, 1, urlItem);
QStandardItem* addressItem = new QStandardItem();
addressItem->setText(QString::fromStdString(entry.Address));
m_ethHost_model->setItem(row, 2, addressItem);
QStandardItem* enabledItem = new QStandardItem();
enabledItem->setEditable(false);
enabledItem->setCheckable(true);
enabledItem->setCheckState(entry.Enabled ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
m_ethHost_model->setItem(row, 3, enabledItem);
}
m_ui.ethHosts->sortByColumn(0, Qt::AscendingOrder);
}
int DEV9SettingsWidget::CountHostsConfig()
{
return m_dialog->getIntValue("DEV9/Eth/Hosts", "Count", 0).value();
}
void DEV9SettingsWidget::AddNewHostConfig(const HostEntryUi& host)
{
const int hostLength = CountHostsConfig();
std::string section = "DEV9/Eth/Hosts/Host" + std::to_string(hostLength);
// clang-format off
m_dialog->setStringSettingValue(section.c_str(), "Url", host.Url.c_str());
m_dialog->setStringSettingValue(section.c_str(), "Desc", host.Desc.c_str());
m_dialog->setStringSettingValue(section.c_str(), "Address", host.Address.c_str());
m_dialog->setBoolSettingValue (section.c_str(), "Enabled", host.Enabled);
// clang-format on
m_dialog->setIntSettingValue("DEV9/Eth/Hosts", "Count", hostLength + 1);
RefreshHostList();
}
void DEV9SettingsWidget::DeleteHostConfig(int index)
{
const int hostLength = CountHostsConfig();
//Shuffle entries down to ovewrite deleted entry
for (int i = index; i < hostLength - 1; i++)
{
std::string section = "DEV9/Eth/Hosts/Host" + std::to_string(i);
std::string sectionAhead = "DEV9/Eth/Hosts/Host" + std::to_string(i + 1);
// clang-format off
m_dialog->setStringSettingValue(section.c_str(), "Url", m_dialog->getStringValue(sectionAhead.c_str(), "Url", "").value().c_str());
m_dialog->setStringSettingValue(section.c_str(), "Desc", m_dialog->getStringValue(sectionAhead.c_str(), "Desc", "").value().c_str());
m_dialog->setStringSettingValue(section.c_str(), "Address", m_dialog->getStringValue(sectionAhead.c_str(), "Address", "0.0.0.0").value().c_str());
m_dialog->setBoolSettingValue (section.c_str(), "Enabled", m_dialog->getBoolValue (sectionAhead.c_str(), "Enabled", false).value());
// clang-format on
}
//Delete last entry
std::string section = "DEV9/Eth/Hosts/Host" + std::to_string(hostLength - 1);
//Specifying a value of nullopt will delete the key
//if the key is a nullptr, the whole section is deleted
m_dialog->setStringSettingValue(section.c_str(), nullptr, std::nullopt);
m_dialog->setIntSettingValue("DEV9/Eth/Hosts", "Count", hostLength - 1);
RefreshHostList();
}
DEV9SettingsWidget::~DEV9SettingsWidget() = default;
+119
View File
@@ -0,0 +1,119 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QtWidgets/QWidget>
#include <QtWidgets/QItemDelegate>
#include <QtGui/QStandardItemModel>
#include "ui_DEV9SettingsWidget.h"
#include "DEV9/net.h"
class SettingsDialog;
class IPValidator : public QValidator
{
Q_OBJECT
public:
explicit IPValidator(QObject* parent = nullptr, bool allowEmpty = false);
virtual State validate(QString& input, int& pos) const override;
private:
static const QRegularExpression intermediateRegex;
static const QRegularExpression finalRegex;
bool m_allowEmpty;
};
class IPItemDelegate : public QItemDelegate
{
Q_OBJECT
public:
explicit IPItemDelegate(QObject* parent = nullptr);
protected:
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
void setEditorData(QWidget* editor, const QModelIndex& index) const;
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const;
};
class DEV9SettingsWidget : public QWidget
{
Q_OBJECT
private Q_SLOTS:
void onEthEnabledChanged(int state);
void onEthDeviceTypeChanged(int index);
void onEthDeviceChanged(int index);
void onEthDHCPInterceptChanged(int state);
void onEthIPChanged(QLineEdit* sender, const char* section, const char* key);
void onEthAutoChanged(QCheckBox* sender, int state, QLineEdit* input, const char* section, const char* key);
void onEthDNSModeChanged(QComboBox* sender, int index, QLineEdit* input, const char* section, const char* key);
void onEthHostAdd();
void onEthHostDel();
void onEthHostEdit(QStandardItem* item);
void onHddEnabledChanged(int state);
void onHddBrowseFileClicked();
void onHddFileEdit();
void onHddSizeSlide(int i);
void onHddSizeSpin(int i);
void onHddCreateClicked();
public:
DEV9SettingsWidget(SettingsDialog* dialog, QWidget* parent);
~DEV9SettingsWidget();
protected:
void showEvent(QShowEvent* event);
bool eventFilter(QObject* object, QEvent* event);
private:
struct HostEntryUi
{
std::string Url;
std::string Desc;
std::string Address = "0.0.0.0";
bool Enabled;
};
void AddAdapter(const AdapterEntry& adapter);
void RefreshHostList();
int CountHostsConfig();
void AddNewHostConfig(const HostEntryUi& host);
void DeleteHostConfig(int index);
SettingsDialog* m_dialog;
Ui::DEV9SettingsWidget m_ui;
QStandardItemModel* m_ethHost_model;
QSortFilterProxyModel* m_ethHosts_proxy;
std::vector<Pcsx2Config::DEV9Options::NetApi> m_api_list;
std::vector<const char*> m_api_namelist;
std::vector<const char*> m_api_valuelist;
std::vector<std::vector<AdapterEntry>> m_adapter_list;
AdapterOptions m_adapter_options{AdapterOptions::None};
//Use by per-game ui only
Pcsx2Config::DEV9Options::NetApi m_global_api{Pcsx2Config::DEV9Options::NetApi::Unset};
};
+370
View File
@@ -0,0 +1,370 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DEV9SettingsWidget</class>
<widget class="QWidget" name="DEV9SettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>500</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Ethernet</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1" colspan="2">
<widget class="QComboBox" name="ethDev"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="ethDevLabel">
<property name="text">
<string>Ethernet Device:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="ethDevTypeLabel">
<property name="text">
<string>Ethernet Device Type:</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QTabWidget" name="ethTabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<property name="documentMode">
<bool>true</bool>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Intercept DHCP</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="4" column="2">
<widget class="QComboBox" name="ethDNS1Mode"/>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="ethInterceptDHCP">
<property name="text">
<string>Enabled</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="ethNetMask">
<property name="inputMask">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="ethNetMaskLabel">
<property name="text">
<string>Subnet Mask:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="ethGatewayAddrLabel">
<property name="text">
<string>Gateway Address:</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QCheckBox" name="ethGatewayAuto">
<property name="text">
<string>Auto</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Intercept DHCP:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="ethPS2Addr">
<property name="inputMask">
<string/>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="ethNetMaskAuto">
<property name="text">
<string>Auto</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="ethPS2AddrLabel">
<property name="text">
<string>PS2 Address:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="ethGatewayAddr">
<property name="inputMask">
<string/>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="ethDNS1AddrLabel">
<property name="text">
<string>DNS1 Address:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="ethDNS1Addr">
<property name="inputMask">
<string/>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="ethDNS2AddrLabel">
<property name="text">
<string>DNS2 Address:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="ethDNS2Addr">
<property name="inputMask">
<string/>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QComboBox" name="ethDNS2Mode"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Internal DNS</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="ethHostAdd">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ethHostDel">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Internal DNS can be selected using the DNS1/2 dropdowns, or by setting them to 192.0.2.1</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTableView" name="ethHosts">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="ethDevType"/>
</item>
<item row="0" column="0" colspan="3">
<widget class="QCheckBox" name="ethEnabled">
<property name="text">
<string>Enabled</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Hard Disk Drive</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<widget class="QLabel" name="hddFileLabel">
<property name="text">
<string>HDD File:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="hddSizeMinLabel">
<property name="text">
<string>40</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="hddSizeSlider">
<property name="minimum">
<number>40</number>
</property>
<property name="maximum">
<number>120</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>5</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="hddSizeMaxLabel">
<property name="text">
<string>120</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="hddSizeSpinBox">
<property name="minimum">
<number>40</number>
</property>
<property name="maximum">
<number>120</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="hddSizeLabel">
<property name="text">
<string>HDD Size (GiB):</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="hddEnabled">
<property name="text">
<string>Enabled</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="hddBrowseFile">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="hddFile"/>
</item>
<item row="4" column="2">
<widget class="QPushButton" name="hddCreate">
<property name="text">
<string>Create Image</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>68</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -87,7 +87,7 @@ void EmulationSettingsWidget::initializeSpeedCombo(QComboBox* cb, const char* se
}
}
static const int speeds[] = {1, 10, 25, 50, 75, 90, 100, 110, 120, 150, 175, 200, 300, 400, 500, 1000};
static const int speeds[] = {2, 10, 25, 50, 75, 90, 100, 110, 120, 150, 175, 200, 300, 400, 500, 1000};
for (const int speed : speeds)
{
cb->addItem(tr("%1% [%2 FPS (NTSC) / %3 FPS (PAL)]")
+13 -7
View File
@@ -60,7 +60,8 @@
<string>Add</string>
</property>
<property name="icon">
<iconset theme="folder-add-line" />
<iconset theme="folder-add-line">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
@@ -76,7 +77,8 @@
<string>Remove</string>
</property>
<property name="icon">
<iconset theme="folder-reduce-line" />
<iconset theme="folder-reduce-line">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
@@ -130,7 +132,8 @@
<string>Add</string>
</property>
<property name="icon">
<iconset theme="file-add-line" />
<iconset theme="file-add-line">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
@@ -146,7 +149,8 @@
<string>Remove</string>
</property>
<property name="icon">
<iconset theme="file-reduce-line" />
<iconset theme="file-reduce-line">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
@@ -182,7 +186,8 @@
<string>Scan For New Games</string>
</property>
<property name="icon">
<iconset theme="file-search-line" />
<iconset theme="file-search-line">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
@@ -198,7 +203,8 @@
<string>Rescan All Games</string>
</property>
<property name="icon">
<iconset theme="refresh-line" />
<iconset theme="refresh-line">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
@@ -207,7 +213,7 @@
</layout>
</widget>
<resources>
<include location="resources/resources.qrc"/>
<include location="../resources/resources.qrc"/>
</resources>
<connections/>
</ui>
+57 -13
View File
@@ -56,7 +56,7 @@ static constexpr RendererInfo s_renderer_info[] = {
static const char* s_anisotropic_filtering_entries[] = {QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "Off (Default)"),
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "2x"), QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "4x"),
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "8x"), QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "16x"), nullptr};
static const char* s_anisotropic_filtering_values[] = {"1", "2", "4", "8", "16", nullptr};
static const char* s_anisotropic_filtering_values[] = {"0", "2", "4", "8", "16", nullptr};
static constexpr int DEFAULT_INTERLACE_MODE = 7;
@@ -83,7 +83,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.fmvAspectRatio, "EmuCore/GS", "FMVAspectRatioSwitch",
Pcsx2Config::GSOptions::FMVAspectRatioSwitchNames, FMVAspectRatioSwitchType::Off);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.interlacing, "EmuCore/GS", "interlace", DEFAULT_INTERLACE_MODE);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.bilinearFiltering, "EmuCore/GS", "LinearPresent", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.bilinearFiltering, "EmuCore/GS", "linear_present", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.integerScaling, "EmuCore/GS", "IntegerScaling", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.internalResolutionScreenshots, "EmuCore/GS", "InternalResolutionScreenshots", false);
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.zoom, "EmuCore/GS", "Zoom", 100.0f);
@@ -104,9 +104,18 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowSpeed, "EmuCore/GS", "OsdShowSpeed", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowFPS, "EmuCore/GS", "OsdShowFPS", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowCPU, "EmuCore/GS", "OsdShowCPU", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowGPU, "EmuCore/GS", "OsdShowGPU", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowResolution, "EmuCore/GS", "OsdShowResolution", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowGSStats, "EmuCore/GS", "OsdShowGSStats", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowIndicators, "EmuCore/GS", "OsdShowIndicators", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.fxaa, "EmuCore/GS", "fxaa", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.shadeBoost, "EmuCore/GS", "ShadeBoost", false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.shadeBoostBrightness, "EmuCore/GS", "ShadeBoost_Brightness", false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.shadeBoostContrast, "EmuCore/GS", "ShadeBoost_Contrast", false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.shadeBoostSaturation, "EmuCore/GS", "ShadeBoost_Saturation", false);
connect(m_ui.shadeBoost, QOverload<int>::of(&QCheckBox::stateChanged), this, &GraphicsSettingsWidget::onShadeBoostChanged);
onShadeBoostChanged();
dialog->registerWidgetHelp(m_ui.osdShowMessages, tr("Show OSD Messages"), tr("Checked"),
tr("Shows on-screen-display messages when events occur such as save states being "
@@ -121,10 +130,10 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
//////////////////////////////////////////////////////////////////////////
// HW Settings
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.upscaleMultiplier, "EmuCore/GS", "upscale_multiplier", 1);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.upscaleMultiplier, "EmuCore/GS", "upscale_multiplier", 1, 1);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureFiltering, "EmuCore/GS", "filter", static_cast<int>(BiFiltering::PS2));
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_ui.trilinearFiltering, "EmuCore/GS", "UserHacks_TriFilter", static_cast<int>(TriFiltering::Off));
sif, m_ui.trilinearFiltering, "EmuCore/GS", "UserHacks_TriFilter", static_cast<int>(TriFiltering::Automatic), -1);
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.anisotropicFiltering, "EmuCore/GS", "MaxAnisotropy", s_anisotropic_filtering_entries, s_anisotropic_filtering_values, "1");
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.dithering, "EmuCore/GS", "dithering_ps2", 2);
@@ -137,26 +146,31 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.texturePreloading, "EmuCore/GS", "texture_preloading",
static_cast<int>(TexturePreloadingLevel::Off));
connect(m_ui.trilinearFiltering, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &GraphicsSettingsWidget::onTrilinearFilteringChanged);
connect(m_ui.gpuPaletteConversion, QOverload<int>::of(&QCheckBox::stateChanged), this, &GraphicsSettingsWidget::onGpuPaletteConversionChanged);
onTrilinearFilteringChanged();
onGpuPaletteConversionChanged(m_ui.gpuPaletteConversion->checkState());
//////////////////////////////////////////////////////////////////////////
// HW Renderer Fixes
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfScreenFix, "EmuCore/GS", "UserHacks_Half_Bottom_Override", -1, -1);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawRangeStart, "EmuCore/GS", "UserHacks_SkipDraw", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawRangeCount, "EmuCore/GS", "UserHacks_SkipDraw_Offset", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawStart, "EmuCore/GS", "UserHacks_SkipDraw_Start", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawEnd, "EmuCore/GS", "UserHacks_SkipDraw_End", 0);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.hwAutoFlush, "EmuCore/GS", "UserHacks_AutoFlush", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.frameBufferConversion, "EmuCore/GS", "UserHacks_CPU_FB_Conversion", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDepthEmulation, "EmuCore/GS", "UserHacks_DisableDepthSupport", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.memoryWrapping, "EmuCore/GS", "wrap_gs_mem", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableSafeFeatures, "EmuCore/GS", "UserHacks_Disable_Safe_Features", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.preloadFrameData, "EmuCore/GS", "preload_frame_with_gs_data", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.fastTextureInvalidation, "EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disablePartialInvalidation, "EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.textureInsideRt, "EmuCore/GS", "UserHacks_TextureInsideRt", false);
//////////////////////////////////////////////////////////////////////////
// HW Upscaling Fixes
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfPixelOffset, "EmuCore/GS", "UserHacks_HalfPixelOffset", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.roundSprite, "EmuCore/GS", "UserHacks_RoundSprite", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.roundSprite, "EmuCore/GS", "UserHacks_round_sprite_offset", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureOffsetX, "EmuCore/GS", "UserHacks_TCOffsetX", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureOffsetY, "EmuCore/GS", "UserHacks_TCOffsetY", 0);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.alignSprite, "EmuCore/GS", "UserHacks_align_sprite_X", false);
@@ -178,6 +192,10 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useBlitSwapChain, "EmuCore/GS", "UseBlitSwapChain", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useDebugDevice, "EmuCore/GS", "UseDebugDevice", false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.overrideTextureBarriers, "EmuCore/GS", "OverrideTextureBarriers", -1, -1);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.overrideGeometryShader, "EmuCore/GS", "OverrideGeometryShaders", -1, -1);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableFramebufferFetch, "EmuCore/GS", "DisableFramebufferFetch", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDualSource, "EmuCore/GS", "DisableDualSourceBlend", false);
//////////////////////////////////////////////////////////////////////////
// SW Settings
@@ -201,18 +219,18 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
// per-game override for renderer is slightly annoying, since we need to populate the global setting field
if (sif)
{
const int global_renderer = QtHost::GetBaseIntSettingValue("EmuCore/GS", "Renderer", static_cast<int>(GSRendererType::Auto));
QString global_renderer_name;
for (const RendererInfo& ri : s_renderer_info)
{
if (renderer == static_cast<int>(ri.type))
if (global_renderer == static_cast<int>(ri.type))
global_renderer_name = qApp->translate("GraphicsSettingsWidget", ri.name);
}
m_ui.renderer->insertItem(0, tr("Use Global Setting [%1]").arg(global_renderer_name));
// Effective Index already selected, set to global if setting is not per-game
int override_renderer;
if (sif->GetIntValue("EmuCore/GS", "Renderer", &override_renderer))
m_ui.renderer->setCurrentIndex(override_renderer + 1);
else
if (!sif->GetIntValue("EmuCore/GS", "Renderer", &override_renderer))
m_ui.renderer->setCurrentIndex(0);
}
@@ -274,7 +292,33 @@ void GraphicsSettingsWidget::onFullscreenModeChanged(int index)
g_emu_thread->applySettings();
}
void GraphicsSettingsWidget::onIntegerScalingChanged() { m_ui.bilinearFiltering->setEnabled(!m_ui.integerScaling->isChecked()); }
void GraphicsSettingsWidget::onIntegerScalingChanged()
{
m_ui.bilinearFiltering->setEnabled(!m_ui.integerScaling->isChecked());
}
void GraphicsSettingsWidget::onTrilinearFilteringChanged()
{
const bool forced_bilinear =
(m_dialog->getEffectiveIntValue("EmuCore/GS", "UserHacks_TriFilter", static_cast<int>(TriFiltering::Automatic))
>= static_cast<int>(TriFiltering::Forced));
m_ui.textureFiltering->setDisabled(forced_bilinear);
}
void GraphicsSettingsWidget::onShadeBoostChanged()
{
const bool enabled = m_dialog->getEffectiveBoolValue("EmuCore/GS", "ShadeBoost", false);
m_ui.shadeBoostBrightness->setEnabled(enabled);
m_ui.shadeBoostContrast->setEnabled(enabled);
m_ui.shadeBoostSaturation->setEnabled(enabled);
}
void GraphicsSettingsWidget::onGpuPaletteConversionChanged(int state)
{
const bool enabled = state == Qt::CheckState::PartiallyChecked ? QtHost::GetBaseBoolSettingValue("EmuCore/GS", "paltex", false) : state;
m_ui.anisotropicFiltering->setEnabled(!enabled);
}
void GraphicsSettingsWidget::onEnableHardwareFixesChanged()
{
@@ -41,7 +41,10 @@ private Q_SLOTS:
void onAdapterChanged(int index);
void onEnableHardwareFixesChanged();
void onIntegerScalingChanged();
void onTrilinearFilteringChanged();
void onGpuPaletteConversionChanged(int state);
void onFullscreenModeChanged(int index);
void onShadeBoostChanged();
private:
GSRendererType getEffectiveRenderer() const;
+292 -86
View File
@@ -307,11 +307,6 @@
</item>
<item row="0" column="1">
<widget class="QComboBox" name="upscaleMultiplier">
<item>
<property name="text">
<string>Custom</string>
</property>
</item>
<item>
<property name="text">
<string>Native (PS2)</string>
@@ -349,7 +344,7 @@
</item>
<item>
<property name="text">
<string>8x Native (~2280p)</string>
<string>8x Native (~2880p)</string>
</property>
</item>
</widget>
@@ -427,7 +422,12 @@
<widget class="QComboBox" name="trilinearFiltering">
<item>
<property name="text">
<string>None (Default)</string>
<string>Automatic (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Off (None)</string>
</property>
</item>
<item>
@@ -586,7 +586,7 @@
<item row="1" column="1">
<widget class="QCheckBox" name="enableHWFixes">
<property name="text">
<string>Enable Hardware Renderer Fixes</string>
<string>Manual Hardware Renderer Fixes</string>
</property>
</widget>
</item>
@@ -661,10 +661,18 @@
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="skipDrawRangeStart"/>
<widget class="QSpinBox" name="skipDrawStart">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="skipDrawRangeCount"/>
<widget class="QSpinBox" name="skipDrawEnd">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
</layout>
</item>
@@ -713,9 +721,9 @@
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="fastTextureInvalidation">
<widget class="QCheckBox" name="disablePartialInvalidation">
<property name="text">
<string>Fast Texture Invalidation</string>
<string>Disable Partial Invalidation</string>
</property>
</widget>
</item>
@@ -809,7 +817,11 @@
</widget>
</item>
<item>
<widget class="QSpinBox" name="textureOffsetX"/>
<widget class="QSpinBox" name="textureOffsetX">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_18">
@@ -819,7 +831,11 @@
</widget>
</item>
<item>
<widget class="QSpinBox" name="textureOffsetY"/>
<widget class="QSpinBox" name="textureOffsetY">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
</layout>
</item>
@@ -854,79 +870,199 @@
<attribute name="title">
<string>On-Screen Display</string>
</attribute>
<layout class="QFormLayout" name="formLayout_8">
<item row="0" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>OSD Scale:</string>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>On-Screen Display</string>
</property>
<layout class="QFormLayout" name="formLayout_8">
<item row="0" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>OSD Scale:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="osdScale">
<property name="suffix">
<string>%</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>500</number>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QCheckBox" name="osdShowMessages">
<property name="text">
<string>Show Notifications</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="osdShowSpeed">
<property name="text">
<string>Show Speed</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="osdShowFPS">
<property name="text">
<string>Show FPS</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="osdShowResolution">
<property name="text">
<string>Show Resolution</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="osdShowCPU">
<property name="text">
<string>Show CPU Usage</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="osdShowGPU">
<property name="text">
<string>Show GPU Usage</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="osdShowGSStats">
<property name="text">
<string>Show Statistics</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="osdShowIndicators">
<property name="text">
<string>Show Indicators</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="osdScale">
<property name="suffix">
<string>%</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>500</number>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Post-Processing</string>
</property>
<layout class="QFormLayout" name="formLayout_9">
<item row="0" column="0">
<widget class="QCheckBox" name="shadeBoost">
<property name="text">
<string>Shade Boost</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_31">
<property name="text">
<string>Brightness:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="shadeBoostBrightness">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_32">
<property name="text">
<string>Contrast:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="shadeBoostContrast">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_33">
<property name="text">
<string>Saturation</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="shadeBoostSaturation">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="fxaa">
<property name="text">
<string>FXAA</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QCheckBox" name="osdShowMessages">
<property name="text">
<string>Show Notifications</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="osdShowSpeed">
<property name="text">
<string>Show Speed</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="osdShowFPS">
<property name="text">
<string>Show FPS</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="osdShowResolution">
<property name="text">
<string>Show Resolution</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="osdShowCPU">
<property name="text">
<string>Show CPU Usage</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="osdShowGSStats">
<property name="text">
<string>Show Statistics</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="osdShowIndicators">
<property name="text">
<string>Show Indicators</string>
</property>
</widget>
</item>
</layout>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
@@ -940,21 +1076,91 @@
<property name="title">
<string>Debug Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<layout class="QFormLayout" name="formLayout_6">
<item row="0" column="0">
<widget class="QCheckBox" name="useBlitSwapChain">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Use Blit Swap Chain</string>
<string>Override Texture Barriers:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="useDebugDevice">
<widget class="QComboBox" name="overrideTextureBarriers">
<item>
<property name="text">
<string>Automatic (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Force Disabled</string>
</property>
</item>
<item>
<property name="text">
<string>Force Enabled</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_30">
<property name="text">
<string>Use Debug Device</string>
<string>Override Geometry Shader:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="overrideGeometryShader">
<item>
<property name="text">
<string>Automatic (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Force Disabled</string>
</property>
</item>
<item>
<property name="text">
<string>Force Enabled</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QCheckBox" name="useBlitSwapChain">
<property name="text">
<string>Use Blit Swap Chain</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="useDebugDevice">
<property name="text">
<string>Use Debug Device</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="disableDualSource">
<property name="text">
<string>Disable Dual Source Blending</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="disableFramebufferFetch">
<property name="text">
<string>Disable Framebuffer Fetch</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
+55
View File
@@ -0,0 +1,55 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include <QtWidgets/QMessageBox>
#include "HddCreateQt.h"
HddCreateQt::HddCreateQt(QWidget* parent)
: m_parent{parent}
, progressDialog{nullptr}
{
}
void HddCreateQt::Init()
{
reqMiB = (neededSize + ((1024 * 1024) - 1)) / (1024 * 1024);
progressDialog = new QProgressDialog(QObject::tr("Creating HDD file \n %1 / %2 MiB").arg(0).arg(reqMiB), QObject::tr("Cancel"), 0, reqMiB, m_parent);
progressDialog->setWindowTitle("HDD Creator");
progressDialog->setWindowModality(Qt::WindowModal);
}
void HddCreateQt::SetFileProgress(u64 currentSize)
{
const int writtenMB = (currentSize + ((1024 * 1024) - 1)) / (1024 * 1024);
progressDialog->setValue(writtenMB);
progressDialog->setLabelText(QObject::tr("Creating HDD file \n %1 / %2 MiB").arg(writtenMB).arg(reqMiB));
if (progressDialog->wasCanceled())
SetCanceled();
}
void HddCreateQt::SetError()
{
QMessageBox::warning(progressDialog, QObject::tr("HDD Creator"),
QObject::tr("Failed to create HDD image"),
QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
}
void HddCreateQt::Cleanup()
{
delete progressDialog;
}
+39
View File
@@ -0,0 +1,39 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QtWidgets/QProgressDialog>
#include "DEV9/ATA/HddCreate.h"
class HddCreateQt : public HddCreate
{
public:
HddCreateQt(QWidget* parent);
virtual ~HddCreateQt(){};
private:
QWidget* m_parent;
QProgressDialog* progressDialog;
int reqMiB;
protected:
virtual void Init();
virtual void Cleanup();
virtual void SetFileProgress(u64 currentSize);
virtual void SetError();
};
+430 -1
View File
@@ -15,21 +15,450 @@
#include "PrecompiledHeader.h"
#include <QtGui/QDrag>
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMessageBox>
#include <algorithm>
#include "common/StringUtil.h"
#include "MemoryCardSettingsWidget.h"
#include "CreateMemoryCardDialog.h"
#include "EmuThread.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"
#include "pcsx2/MemoryCardFile.h"
static std::string getSlotFilenameKey(u32 slot)
{
return StringUtil::StdStringFromFormat("Slot%u_Filename", slot + 1);
}
MemoryCardSettingsWidget::MemoryCardSettingsWidget(SettingsDialog* dialog, QWidget* parent)
: QWidget(parent)
, m_dialog(dialog)
{
// SettingsInterface* sif = dialog->getSettingsInterface();
SettingsInterface* sif = m_dialog->getSettingsInterface();
m_ui.setupUi(this);
// this is a bit lame, but resizeEvent() isn't good enough to autosize our columns,
// since the group box hasn't been resized at that point.
m_ui.cardGroupBox->installEventFilter(this);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.autoEject, "EmuCore", "McdEnableEjection", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.automaticManagement, "EmuCore", "McdFolderAutoManage", true);
for (u32 i = 0; i < static_cast<u32>(m_slots.size()); i++)
createSlotWidgets(&m_slots[i], i);
m_ui.cardList->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_ui.cardList, &MemoryCardListWidget::itemSelectionChanged, this, &MemoryCardSettingsWidget::updateCardActions);
connect(m_ui.cardList, &MemoryCardListWidget::customContextMenuRequested, this, &MemoryCardSettingsWidget::listContextMenuRequested);
connect(m_ui.refreshCard, &QPushButton::clicked, this, &MemoryCardSettingsWidget::refresh);
connect(m_ui.createCard, &QPushButton::clicked, this, &MemoryCardSettingsWidget::createCard);
connect(m_ui.duplicateCard, &QPushButton::clicked, this, &MemoryCardSettingsWidget::duplicateCard);
connect(m_ui.renameCard, &QPushButton::clicked, this, &MemoryCardSettingsWidget::renameCard);
connect(m_ui.convertCard, &QPushButton::clicked, this, &MemoryCardSettingsWidget::convertCard);
connect(m_ui.deleteCard, &QPushButton::clicked, this, &MemoryCardSettingsWidget::deleteCard);
refresh();
}
MemoryCardSettingsWidget::~MemoryCardSettingsWidget() = default;
void MemoryCardSettingsWidget::resizeEvent(QResizeEvent* event)
{
QWidget::resizeEvent(event);
autoSizeUI();
}
bool MemoryCardSettingsWidget::eventFilter(QObject* watched, QEvent* event)
{
if (watched == m_ui.cardGroupBox && event->type() == QEvent::Resize)
autoSizeUI();
return QWidget::eventFilter(watched, event);
}
void MemoryCardSettingsWidget::createSlotWidgets(SlotGroup* port, u32 slot)
{
port->root = new QWidget(m_ui.portGroupBox);
SettingsInterface* sif = m_dialog->getSettingsInterface();
port->enable = new QCheckBox(tr("Port %1").arg(slot + 1), port->root);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, port->enable, "MemoryCards", StringUtil::StdStringFromFormat("Slot%u_Enable", slot + 1), true);
connect(port->enable, &QCheckBox::stateChanged, this, &MemoryCardSettingsWidget::refresh);
port->eject = new QToolButton(port->root);
port->eject->setIcon(QIcon::fromTheme("eject-line"));
port->eject->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
connect(port->eject, &QToolButton::clicked, this, [this, slot]() { ejectSlot(slot); });
port->slot = new MemoryCardSlotWidget(port->root);
connect(port->slot, &MemoryCardSlotWidget::cardDropped, this, [this, slot](const QString& card) { tryInsertCard(slot, card); });
QHBoxLayout* bottom_layout = new QHBoxLayout();
bottom_layout->setContentsMargins(0, 0, 0, 0);
bottom_layout->addWidget(port->slot, 1);
bottom_layout->addWidget(port->eject, 0);
QVBoxLayout* vert_layout = new QVBoxLayout(port->root);
vert_layout->setContentsMargins(0, 0, 0, 0);
vert_layout->addWidget(port->enable, 0);
vert_layout->addLayout(bottom_layout, 1);
static_cast<QGridLayout*>(m_ui.portGroupBox->layout())->addWidget(port->root, 0, slot);
}
void MemoryCardSettingsWidget::autoSizeUI()
{
QtUtils::ResizeColumnsForTreeView(m_ui.cardList, {-1, 100, 80, 150});
}
void MemoryCardSettingsWidget::tryInsertCard(u32 slot, const QString& newCard)
{
// handle where the card is dragged in from explorer or something
const int lastSlashPos = std::max(newCard.lastIndexOf('/'), newCard.lastIndexOf('\\'));
const std::string newCardStr((lastSlashPos >= 0) ? newCard.mid(0, lastSlashPos).toStdString() : newCard.toStdString());
if (newCardStr.empty())
return;
// make sure it's a card in the directory
const std::vector<AvailableMcdInfo> mcds(FileMcd_GetAvailableCards(true));
if (std::none_of(mcds.begin(), mcds.end(), [&newCardStr](const AvailableMcdInfo& mcd) { return mcd.name == newCardStr; }))
{
QMessageBox::critical(this, tr("Error"), tr("This memory card is unknown."));
return;
}
m_dialog->setStringSettingValue("MemoryCards", getSlotFilenameKey(slot).c_str(), newCardStr.c_str());
refresh();
}
void MemoryCardSettingsWidget::ejectSlot(u32 slot)
{
m_dialog->setStringSettingValue("MemoryCards", getSlotFilenameKey(slot).c_str(), m_dialog->isPerGameSettings() ? nullptr : "");
refresh();
}
void MemoryCardSettingsWidget::createCard()
{
CreateMemoryCardDialog dialog(QtUtils::GetRootWidget(this));
if (dialog.exec() == QDialog::Accepted)
refresh();
}
QString MemoryCardSettingsWidget::getSelectedCard() const
{
QString ret;
const QList<QTreeWidgetItem*> selection(m_ui.cardList->selectedItems());
if (!selection.empty())
ret = selection[0]->text(0);
return ret;
}
void MemoryCardSettingsWidget::updateCardActions()
{
const bool hasSelection = !getSelectedCard().isEmpty();
m_ui.convertCard->setEnabled(hasSelection);
m_ui.duplicateCard->setEnabled(hasSelection);
m_ui.renameCard->setEnabled(hasSelection);
m_ui.deleteCard->setEnabled(hasSelection);
}
void MemoryCardSettingsWidget::duplicateCard()
{
const QString selectedCard(getSelectedCard());
if (selectedCard.isEmpty())
return;
QMessageBox::critical(this, tr("Error"), tr("Not yet implemented."));
}
void MemoryCardSettingsWidget::deleteCard()
{
const QString selectedCard(getSelectedCard());
if (selectedCard.isEmpty())
return;
if (QMessageBox::question(QtUtils::GetRootWidget(this), tr("Delete Memory Card"),
tr("Are you sure you wish to delete the memory card '%1'?\n\n"
"This action cannot be reversed, and you will lose any saves on the card.")
.arg(selectedCard)) != QMessageBox::Yes)
{
return;
}
if (!FileMcd_DeleteCard(selectedCard.toStdString()))
{
QMessageBox::critical(QtUtils::GetRootWidget(this), tr("Delete Memory Card"),
tr("Failed to delete the memory card. The log may have more information."));
return;
}
refresh();
}
void MemoryCardSettingsWidget::renameCard()
{
const QString selectedCard(getSelectedCard());
if (selectedCard.isEmpty())
return;
const QString newName(QInputDialog::getText(QtUtils::GetRootWidget(this),
tr("Rename Memory Card"), tr("New Card Name"), QLineEdit::Normal, selectedCard));
if (newName.isEmpty() || newName == selectedCard)
return;
if (!newName.endsWith(QStringLiteral(".ps2")) || newName.length() <= 4)
{
QMessageBox::critical(QtUtils::GetRootWidget(this), tr("Rename Memory Card"),
tr("New name is invalid, it must end with .ps2"));
return;
}
const std::string newNameStr(newName.toStdString());
if (FileMcd_GetCardInfo(newNameStr).has_value())
{
QMessageBox::critical(QtUtils::GetRootWidget(this), tr("Rename Memory Card"),
tr("New name is invalid, a card with this name already exists."));
return;
}
if (!FileMcd_RenameCard(selectedCard.toStdString(), newNameStr))
{
QMessageBox::critical(QtUtils::GetRootWidget(this), tr("Rename Memory Card"),
tr("Failed to rename memory card. The log may contain more information."));
return;
}
refresh();
}
void MemoryCardSettingsWidget::convertCard()
{
const QString selectedCard(getSelectedCard());
if (selectedCard.isEmpty())
return;
QMessageBox::critical(this, tr("Error"), tr("Not yet implemented."));
}
void MemoryCardSettingsWidget::listContextMenuRequested(const QPoint& pos)
{
QMenu menu(this);
const QString selectedCard(getSelectedCard());
if (!selectedCard.isEmpty())
{
for (u32 slot = 0; slot < MAX_SLOTS; slot++)
{
connect(menu.addAction(tr("Use for Port %1").arg(slot + 1)), &QAction::triggered,
this, [this, &selectedCard, slot]() { tryInsertCard(slot, selectedCard); });
}
menu.addSeparator();
connect(menu.addAction(tr("Duplicate")), &QAction::triggered, this, &MemoryCardSettingsWidget::duplicateCard);
connect(menu.addAction(tr("Rename")), &QAction::triggered, this, &MemoryCardSettingsWidget::renameCard);
connect(menu.addAction(tr("Convert")), &QAction::triggered, this, &MemoryCardSettingsWidget::convertCard);
connect(menu.addAction(tr("Delete")), &QAction::triggered, this, &MemoryCardSettingsWidget::deleteCard);
menu.addSeparator();
}
connect(menu.addAction("Create"), &QAction::triggered, this, &MemoryCardSettingsWidget::createCard);
menu.exec(m_ui.cardList->mapToGlobal(pos));
}
void MemoryCardSettingsWidget::refresh()
{
for (u32 slot = 0; slot < static_cast<u32>(m_slots.size()); slot++)
{
const bool enabled = m_slots[slot].enable->isChecked();
const std::optional<std::string> name(
m_dialog->getStringValue("MemoryCards", getSlotFilenameKey(slot).c_str(),
FileMcd_GetDefaultName(slot).c_str()));
m_slots[slot].slot->setCard(name);
m_slots[slot].slot->setEnabled(enabled);
m_slots[slot].eject->setEnabled(enabled);
}
m_ui.cardList->refresh(m_dialog);
updateCardActions();
}
static QString getSizeSummary(const AvailableMcdInfo& mcd)
{
if (mcd.type == MemoryCardType::File)
{
switch (mcd.file_type)
{
case MemoryCardFileType::PS2_8MB:
return qApp->translate("MemoryCardSettingsWidget", "PS2 (8MB)");
case MemoryCardFileType::PS2_16MB:
return qApp->translate("MemoryCardSettingsWidget", "PS2 (16MB)");
case MemoryCardFileType::PS2_32MB:
return qApp->translate("MemoryCardSettingsWidget", "PS2 (32MB)");
case MemoryCardFileType::PS2_64MB:
return qApp->translate("MemoryCardSettingsWidget", "PS2 (64MB)");
case MemoryCardFileType::PS1:
return qApp->translate("MemoryCardSettingsWidget", "PS1 (128KB)");
case MemoryCardFileType::Unknown:
default:
return qApp->translate("MemoryCardSettingsWidget", "Unknown");
}
}
else if (mcd.type == MemoryCardType::Folder)
{
return qApp->translate("MemoryCardSettingsWidget", "PS2 (Folder)");
}
else
{
return qApp->translate("MemoryCardSettingsWidget", "Unknown");
}
}
static QIcon getCardIcon(const AvailableMcdInfo& mcd)
{
if (mcd.type == MemoryCardType::File)
return QIcon::fromTheme(QStringLiteral("sd-card-line"));
else
return QIcon::fromTheme(QStringLiteral("folder-open-line"));
}
MemoryCardListWidget::MemoryCardListWidget(QWidget* parent)
: QTreeWidget(parent)
{
}
MemoryCardListWidget::~MemoryCardListWidget() = default;
void MemoryCardListWidget::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton)
m_dragStartPos = event->pos();
QTreeWidget::mousePressEvent(event);
}
void MemoryCardListWidget::mouseMoveEvent(QMouseEvent* event)
{
if (!(event->buttons() & Qt::LeftButton) ||
(event->pos() - m_dragStartPos).manhattanLength() < QApplication::startDragDistance())
{
QTreeWidget::mouseMoveEvent(event);
return;
}
const QList<QTreeWidgetItem*> selection(selectedItems());
if (selection.empty())
return;
QDrag* drag = new QDrag(this);
QMimeData* mimeData = new QMimeData();
mimeData->setText(selection[0]->text(0));
drag->setMimeData(mimeData);
drag->exec(Qt::CopyAction);
}
void MemoryCardListWidget::refresh(SettingsDialog* dialog)
{
clear();
// we can't use the in use flag here anyway, because the config may not be in line with per game settings.
const std::vector<AvailableMcdInfo> mcds(FileMcd_GetAvailableCards(true));
if (mcds.empty())
return;
std::array<std::string, MemoryCardSettingsWidget::MAX_SLOTS> currentCards;
for (u32 i = 0; i < static_cast<u32>(currentCards.size()); i++)
{
const std::optional<std::string> filename = dialog->getStringValue("MemoryCards",
getSlotFilenameKey(i).c_str(), FileMcd_GetDefaultName(i).c_str());
if (filename.has_value())
currentCards[i] = std::move(filename.value());
}
for (const AvailableMcdInfo& mcd : mcds)
{
QTreeWidgetItem* item = new QTreeWidgetItem();
const QDateTime mtime(QDateTime::fromSecsSinceEpoch(static_cast<qint64>(mcd.modified_time)));
const bool inUse = (std::find(currentCards.begin(), currentCards.end(), mcd.name) != currentCards.end());
item->setDisabled(inUse);
item->setIcon(0, getCardIcon(mcd));
item->setText(0, QString::fromStdString(mcd.name));
item->setText(1, getSizeSummary(mcd));
item->setText(2, mcd.formatted ? tr("Yes") : tr("No"));
item->setText(3, mtime.toString(QLocale::system().dateTimeFormat(QLocale::ShortFormat)));
addTopLevelItem(item);
}
}
MemoryCardSlotWidget::MemoryCardSlotWidget(QWidget* parent)
: QListWidget(parent)
{
setAcceptDrops(true);
setSelectionMode(NoSelection);
}
MemoryCardSlotWidget::~MemoryCardSlotWidget() = default;
void MemoryCardSlotWidget::dragEnterEvent(QDragEnterEvent* event)
{
if (event->mimeData()->hasFormat("text/plain"))
event->acceptProposedAction();
}
void MemoryCardSlotWidget::dragMoveEvent(QDragMoveEvent* event)
{
}
void MemoryCardSlotWidget::dropEvent(QDropEvent* event)
{
const QMimeData* data = event->mimeData();
const QString text(data ? data->text() : QString());
if (text.isEmpty())
{
event->ignore();
return;
}
event->acceptProposedAction();
emit cardDropped(text);
}
void MemoryCardSlotWidget::setCard(const std::optional<std::string>& name)
{
clear();
if (!name.has_value() || name->empty())
return;
const std::optional<AvailableMcdInfo> mcd(FileMcd_GetCardInfo(name.value()));
QListWidgetItem* item = new QListWidgetItem(this);
if (mcd.has_value())
{
item->setIcon(getCardIcon(mcd.value()));
item->setText(tr("%1 [%2]").arg(QString::fromStdString(mcd->name)).arg(getSizeSummary(mcd.value())));
}
else
{
item->setIcon(QIcon::fromTheme("close-line"));
item->setText(tr("%1 [Missing]").arg(QString::fromStdString(name.value())));
}
}
+88 -2
View File
@@ -15,20 +15,106 @@
#pragma once
#include <QtWidgets/QWidget>
#include <array>
#include <optional>
#include <string>
#include "ui_MemoryCardSettingsWidget.h"
#include <QtGui/QResizeEvent>
#include <QtWidgets/QWidget>
#include <QtWidgets/QTreeWidget>
#include <QtWidgets/QToolButton>
#include <QtWidgets/QListWidget>
class SettingsDialog;
struct AvailableMcdInfo;
class MemoryCardListWidget final : public QTreeWidget
{
Q_OBJECT
public:
explicit MemoryCardListWidget(QWidget* parent);
~MemoryCardListWidget() override;
void refresh(SettingsDialog* dialog);
protected:
void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
private:
QPoint m_dragStartPos = {};
};
class MemoryCardSlotWidget final : public QListWidget
{
Q_OBJECT
public:
explicit MemoryCardSlotWidget(QWidget* parent);
~MemoryCardSlotWidget() override;
Q_SIGNALS:
void cardDropped(const QString& newCard);
public:
void setCard(const std::optional<std::string>& name);
protected:
void dragEnterEvent(QDragEnterEvent* event) override;
void dragMoveEvent(QDragMoveEvent* event) override;
void dropEvent(QDropEvent* event) override;
};
// Must be included *after* the custom widgets.
#include "ui_MemoryCardSettingsWidget.h"
class MemoryCardSettingsWidget : public QWidget
{
Q_OBJECT
public:
enum : u32
{
MAX_SLOTS = 2
};
MemoryCardSettingsWidget(SettingsDialog* dialog, QWidget* parent);
~MemoryCardSettingsWidget();
protected:
void resizeEvent(QResizeEvent* event);
bool eventFilter(QObject* watched, QEvent* event);
private Q_SLOTS:
void listContextMenuRequested(const QPoint& pos);
void refresh();
private:
struct SlotGroup
{
QWidget* root;
QCheckBox* enable;
QToolButton* eject;
MemoryCardSlotWidget* slot;
};
void createSlotWidgets(SlotGroup* port, u32 slot);
void autoSizeUI();
void tryInsertCard(u32 slot, const QString& newCard);
void ejectSlot(u32 slot);
void createCard();
QString getSelectedCard() const;
void updateCardActions();
void duplicateCard();
void deleteCard();
void renameCard();
void convertCard();
SettingsDialog* m_dialog;
Ui::MemoryCardSettingsWidget m_ui;
std::array<SlotGroup, MAX_SLOTS> m_slots;
};
+167 -2
View File
@@ -6,14 +6,179 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<width>796</width>
<height>443</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="portGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>100</height>
</size>
</property>
<property name="title">
<string>Console Ports</string>
</property>
<layout class="QGridLayout" name="gridLayout"/>
</widget>
</item>
<item>
<widget class="QGroupBox" name="cardGroupBox">
<property name="title">
<string>Memory Cards</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="MemoryCardListWidget" name="cardList">
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
<column>
<property name="text">
<string>Formatted</string>
</property>
</column>
<column>
<property name="text">
<string>Last Modified</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="refreshCard">
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="createCard">
<property name="text">
<string>Create</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="duplicateCard">
<property name="text">
<string>Duplicate</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="renameCard">
<property name="text">
<string>Rename</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="convertCard">
<property name="text">
<string>Convert</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteCard">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="settingsGroupBox">
<property name="title">
<string>Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QCheckBox" name="automaticManagement">
<property name="text">
<string>Automatically manage saves based on running game</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="autoEject">
<property name="text">
<string>Auto-eject memory cards when loading save states</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>MemoryCardListWidget</class>
<extends>QTreeWidget</extends>
<header>Settings/MemoryCardSettingsWidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
-121
View File
@@ -1,121 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OSDSettingsWidget</class>
<widget class="QWidget" name="OSDSettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>604</width>
<height>469</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>On-Screen Display</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>OSD Scale:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="osdScale">
<property name="suffix">
<string>%</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>500</number>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="osdShowMessages">
<property name="text">
<string>Show Notifications</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="osdShowSpeed">
<property name="text">
<string>Show Speed</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="osdShowFPS">
<property name="text">
<string>Show FPS</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="osdShowResolution">
<property name="text">
<string>Show Resolution</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="osdShowCPU">
<property name="text">
<string>Show CPU Usage</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="osdShowGSStats">
<property name="text">
<string>Show Statistics</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+16 -4
View File
@@ -26,14 +26,17 @@
#include "SettingsDialog.h"
#include "AdvancedSystemSettingsWidget.h"
#include "AudioSettingsWidget.h"
#include "BIOSSettingsWidget.h"
#include "EmulationSettingsWidget.h"
#include "GameSummaryWidget.h"
#include "GameFixSettingsWidget.h"
#include "GameListSettingsWidget.h"
#include "GraphicsSettingsWidget.h"
#include "DEV9SettingsWidget.h"
#include "HotkeySettingsWidget.h"
#include "InterfaceSettingsWidget.h"
#include "MemoryCardSettingsWidget.h"
#include "SystemSettingsWidget.h"
#include <QtWidgets/QMessageBox>
@@ -114,11 +117,20 @@ void SettingsDialog::setupUi(const GameList::Entry* game)
addWidget(m_graphics_settings = new GraphicsSettingsWidget(this, m_ui.settingsContainer), tr("Graphics"), QStringLiteral("brush-line"),
tr("<strong>Graphics Settings</strong><hr>"));
addWidget(new QWidget(m_ui.settingsContainer), tr("Audio"), QStringLiteral("volume-up-line"),
addWidget(m_audio_settings = new AudioSettingsWidget(this, m_ui.settingsContainer), tr("Audio"), QStringLiteral("volume-up-line"),
tr("<strong>Audio Settings</strong><hr>These options control the audio output of the console. Mouse over an option for additional "
"information."));
addWidget(
new QWidget(m_ui.settingsContainer), tr("Memory Cards"), QStringLiteral("sd-card-line"), tr("<strong>Memory Card Settings</strong><hr>"));
// for now, memory cards aren't settable per-game
if (!isPerGameSettings())
{
addWidget(m_memory_card_settings = new MemoryCardSettingsWidget(this, m_ui.settingsContainer), tr("Memory Cards"),
QStringLiteral("sd-card-line"), tr("<strong>Memory Card Settings</strong><hr>"));
}
addWidget(m_dev9_settings = new DEV9SettingsWidget(this, m_ui.settingsContainer), tr("Network & HDD"), QStringLiteral("dashboard-line"),
tr("<strong>Network & HDD Settings</strong><hr>These options control the network connectivity and internal HDD storage of the console.<br><br>"
"Mouse over an option for additional information."));
m_ui.settingsCategory->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
m_ui.settingsCategory->setCurrentRow(0);
@@ -390,7 +402,7 @@ void SettingsDialog::setStringSettingValue(const char* section, const char* key,
{
if (m_sif)
{
value.has_value() ? m_sif->SetBoolValue(section, key, value.value()) : m_sif->DeleteValue(section, key);
value.has_value() ? m_sif->SetStringValue(section, key, value.value()) : m_sif->DeleteValue(section, key);
m_sif->Save();
}
else
+4 -1
View File
@@ -38,6 +38,7 @@ class GameFixSettingsWidget;
class GraphicsSettingsWidget;
class AudioSettingsWidget;
class MemoryCardSettingsWidget;
class DEV9SettingsWidget;
class SettingsDialog final : public QDialog
{
@@ -63,6 +64,7 @@ public:
__fi GraphicsSettingsWidget* getGraphicsSettingsWidget() const { return m_graphics_settings; }
__fi AudioSettingsWidget* getAudioSettingsWidget() const { return m_audio_settings; }
__fi MemoryCardSettingsWidget* getMemoryCardSettingsWidget() const { return m_memory_card_settings; }
__fi DEV9SettingsWidget* getDEV9SettingsWidget() const { return m_dev9_settings; }
void registerWidgetHelp(QObject* object, QString title, QString recommended_value, QString text);
bool eventFilter(QObject* object, QEvent* event) override;
@@ -98,7 +100,7 @@ protected:
private:
enum : u32
{
MAX_SETTINGS_WIDGETS = 10
MAX_SETTINGS_WIDGETS = 11
};
void setupUi(const GameList::Entry* game);
@@ -119,6 +121,7 @@ private:
GraphicsSettingsWidget* m_graphics_settings = nullptr;
AudioSettingsWidget* m_audio_settings = nullptr;
MemoryCardSettingsWidget* m_memory_card_settings = nullptr;
DEV9SettingsWidget* m_dev9_settings = nullptr;
std::array<QString, MAX_SETTINGS_WIDGETS> m_category_help_text;

Some files were not shown because too many files have changed in this diff Show More