Compare commits

...
196 Commits
Author SHA1 Message Date
PCSX2 Botandlightningterror b5eadb158c PAD: Update to latest controller database. 2023-08-22 21:19:02 +02:00
RedPanda4552andrefractionpcsx2 e94912cdb9 Pad: Only consider LSB for small motor vibration 2023-08-20 06:30:53 +01:00
lightningterror dfb967834f GS/HW: Cleanup draw when pixels fail on alpha test/date.
Also make CleanupDraw use it's own function.
2023-08-19 19:36:07 +02:00
Stenzekandrefractionpcsx2 98f7c29683 GS/Vulkan: Avoid incorrect-layout RT descriptor 2023-08-19 16:16:05 +01:00
RedDevilusandrefractionpcsx2 0998c5539a GameDB: SoulCalibur III
Normal (Vertex) causes align sprite artifacting, also Special aggressive reduces blurriness even more.
2023-08-19 16:15:43 +01:00
lightningterror 1a79e23b12 GS/HW: Further adjust how we handle RT alpha in blending.
Check whenever RT alpha min is equal or higher than RT alpha max / 2.
This will allow us to use the min value as a more accurate option than
the actual value since it will be less accurate.
2023-08-18 21:44:11 +02:00
refractionpcsx2 d49323c7c4 GS/HW: Skip DATE/draw if not required 2023-08-18 11:34:54 +01:00
refractionpcsx2 98eb3cb7f0 GameDB: Add COP2 patch for Initial D - Special Stage (SLPM-65268) 2023-08-17 12:44:10 +01:00
RedDevilusandrefractionpcsx2 c75ae73814 GameDB: Naruto Ultimate Ninja 5 + same for 4th
Games have the same issues and fixes, also normal vertex introduces some texture gaps whilst full roundsprite looks to be better, also add Vu0clampmode for some of the bad dialog backgrounds.

See also: https://github.com/PCSX2/pcsx2/pull/9803
2023-08-17 02:11:03 +01:00
PCSX2 Botandrefractionpcsx2 07519b7c28 Qt: Update Base Translation 2023-08-17 01:48:56 +01:00
ElTioRataandGitHub 4c62c82dab GameDB: Hardware Fixes for Burnout 2 (#9770) 2023-08-17 01:46:58 +01:00
refractionpcsx2 92a9554240 GameDB: Add VU0 clamping to Naruto Ultimate Ninja 5 (Accel 2) 2023-08-16 17:01:02 +01:00
refractionpcsx2 324a700fb7 GS/TC: Don't allow tex is rt for PSMT8 on 16bit targets 2023-08-16 09:48:23 +01:00
refractionpcsx2 a6b934758b GS/HW: Only preserve valid channels on target overlap 2023-08-16 01:13:01 +01:00
Stenzek cd5ec59f6a GS/DX11: Commit clear before clearing stencil
Stops the discard happening later, and blowing away the cleared value.
2023-08-15 13:08:51 +10:00
RedPanda4552andConnor McLaughlin 80fe813116 [SAVEVERSION+] Remove old trigger deadzone references, replace with button deadzone
Was removed from UI but not the backend
2023-08-14 20:06:47 +10:00
Stenzek 1262afef63 GS/DX12: Use WinPixEventRuntime for debug messages 2023-08-14 20:06:16 +10:00
Stenzek 987489b34a 3rdparty: Add WinPixEventRuntime 2023-08-14 20:06:16 +10:00
TellowKrinkleandConnor McLaughlin 9310861cc2 GS:MTL: Properly set stencil reference on draw encoders 2023-08-14 20:06:04 +10:00
kamfretozandrefractionpcsx2 53f0db99ca GameDB: Various Fixes 2023-08-14 09:09:43 +01:00
Christian Kennyandrefractionpcsx2 2eb125f6e2 gitignore: Don't include TXT files generated by crash dumps 2023-08-12 23:02:33 +01:00
Mrlinkwiiandrefractionpcsx2 f805d9432e UI: remove mention of Half Screen Fix 2023-08-12 23:02:14 +01:00
refractionpcsx2 054cb9e9fa GS/HW: Correctly remove offset when detecting shuffle coords 2023-08-12 19:39:25 +01:00
refractionpcsx2 1f77e7d90a GS/CRC: Fix the sizing on Sonic Unleashed copy CRC 2023-08-12 19:34:06 +01:00
lightningterror 7ed33832b8 GS/HW: Isolate early returns for blending.
Optimization.
2023-08-12 18:14:37 +02:00
lightningterror d19e9cc662 GS: Bump shader cache version. 2023-08-12 18:14:37 +02:00
lightningterror 846c9cec6a GS/HW: Adjust how we handle RT alpha in blending.
When both rt min and max are equal then we know what Ad value is,
if so use Af bit instead and set AFIX value from rt alpha value that we know.

On OpenGL when BLEND C == 1 but reading the rt is disabled, set the value to 0 instead
of reading an undefined value.
2023-08-12 18:14:37 +02:00
Sanjay Govindandrefractionpcsx2 460e4b8bb3 USB-Turntable: Default multiplier to 1 2023-08-12 14:07:37 +01:00
Stenzek 2e6bd23f22 Qt: Fix arrow key handling on macOS 2023-08-12 16:17:47 +10:00
refractionpcsx2 7763948fe4 GS/HW: Restrict double buffer detection to widths greater than 256 2023-08-12 01:54:31 +01:00
refractionpcsx2 2a0f001902 GIF: Adjust run length of split in intermittent packets 2023-08-12 00:28:28 +01:00
refractionpcsx2 14df69e180 GS/HW: Fix crash where it could process a texture with no RT 2023-08-12 00:28:28 +01:00
refractionpcsx2 28b6389b36 GS/HW: Stop errantly halfing normal height 2023-08-12 00:28:28 +01:00
lightningterror 905c0b8c7a GS: Fix warnings.
GSRendererHW:
Fix Wtautological-constant-out-of-range-compare.

GSSstate:
Fix Wunused-variable.
Fix Wsign-compare.
2023-08-11 21:46:29 +02:00
lightningterror b674cc95ac Qt: Fix Wreorder-ctor warning. 2023-08-11 21:46:29 +02:00
Mrlinkwiiandlightningterror bccb2509b5 GameDB: Fixes for Ghost Recon - Advanced Warfighter & Battlefield 2 2023-08-11 18:16:33 +02:00
refractionpcsx2 cd980c6604 GS/TC: Fix crash in debug message (only affects debug device) 2023-08-11 16:08:38 +01:00
lightningterror ddff4ec083 GameDB: Add full mipmap plus triliear ps2 to The Godfather.
Improves building textures to match sw renderer.
2023-08-11 17:05:21 +02:00
kamfretozandrefractionpcsx2 5bf97be8ef Qt: Even further icon refinement 2023-08-11 15:24:04 +01:00
lightningterrorandrefractionpcsx2 7fadb6ed05 GS/HW: Cleanup texture shuffle shaders. 2023-08-11 15:23:50 +01:00
lightningterrorandrefractionpcsx2 89688d67dd GS: Bump shader cache version. 2023-08-11 15:23:50 +01:00
refractionpcsx2 279007544a GS/HW: Allow double clear when src is lowest bitsize denominator 2023-08-11 14:28:34 +01:00
lightningterrorandrefractionpcsx2 1c0f0e1423 GS: Bump shader cache version. 2023-08-11 13:14:19 +01:00
lightningterrorandrefractionpcsx2 1ab909addc Config/gamedb: Remove screen fix from config entirely.
No longer needed.
2023-08-11 13:14:19 +01:00
lightningterrorandrefractionpcsx2 99dfd15469 ImGui: Remove Half Screen Fix from the ui.
No longer needed.
2023-08-11 13:14:19 +01:00
lightningterrorandrefractionpcsx2 be18ecf74e Qt: Remove Half Screen Fix from the ui.
No longer needed.
2023-08-11 13:14:19 +01:00
lightningterrorandrefractionpcsx2 713bd132dc GS/D3D: Add initial support for complex shuffles. 2023-08-11 13:14:19 +01:00
refractionpcsx2 20f03e237e GameDB: Add Autoflush to Minority Report 2023-08-11 13:14:19 +01:00
refractionpcsx2 7d3c3911ea GS/HW: Update BigMuthaTruckers hack to a GSC 2023-08-11 13:14:19 +01:00
refractionpcsx2 ccfee2be83 GameDB: Add Tex in RT to Godfather + remove skipdraw 2023-08-11 13:14:19 +01:00
refractionpcsx2 1193b0b990 GS/TC: Delete old targets which aren't preserved and don't match size 2023-08-11 13:14:19 +01:00
refractionpcsx2 5a3ba4e563 GS/HW: Add support for complex offset shuffles 2023-08-11 13:14:19 +01:00
refractionpcsx2 e9c342ef74 GS/Autoflush: Account for CLAMP & better handle different formats 2023-08-11 12:35:42 +01:00
refractionpcsx2 8927ffa035 GS: Fix autoflush behaviour when using Z + C formats together 2023-08-11 12:35:42 +01:00
Ty Lamontagneandrefractionpcsx2 fdb0312326 Dis5900: Mask and extend the pmfhl & pmthl LUT
Fixes an OOB access when disassembling an invalid opcode (71756972h)
2023-08-11 00:09:25 +01:00
refractionpcsx2 2f21caa41c GameDB: Add Instant DMA to Jak X Combat Racing 2023-08-10 10:40:43 +01:00
Stenzekandrefractionpcsx2 51a35d40e5 3rdparty: Bump rcheevos to 3af1e2fc5188d6e932ee379942f4049ea877e648 2023-08-10 01:27:20 +01:00
Stenzekandrefractionpcsx2 6ec524adec USB/GunCon2: Fix cursor not starting in center 2023-08-10 01:27:10 +01:00
Stenzekandrefractionpcsx2 7d4a7ec8c7 ImGuiManager: Fix window width/height not being initialized 2023-08-10 01:27:10 +01:00
Silentandrefractionpcsx2 0256c4521d GameList: Support adding custom title and region to files 2023-08-10 01:26:06 +01:00
Silentandrefractionpcsx2 be3ed181c1 SettingsInterface: Fix constness of a few methods 2023-08-10 01:26:06 +01:00
PCSX2 BotandConnor McLaughlin 38cf7884fe Qt: Update Base Translation 2023-08-09 21:37:15 +10:00
JordanTheToasterandConnor McLaughlin 25d426e8b2 GameDB: Various fixes
Fixes for missing recommended blending on MGS 2 Sub and post processing positioning on Project Snowblind.
2023-08-09 21:35:34 +10:00
TellowKrinkleandConnor McLaughlin edff9ae684 GS:MTL: Include full error messages in aborts 2023-08-09 21:34:38 +10:00
TellowKrinkleandConnor McLaughlin a622e3bda6 Mac: Mark crash info as used so it doesn't get DCE'd 2023-08-09 21:34:38 +10:00
MrlinkwiiandConnor McLaughlin 4d54e28e63 GameDB: remove all god hand getSkipCount 2023-08-09 21:34:07 +10:00
MrlinkwiiandConnor McLaughlin c89d023f91 CRC/HW: remove god hand GSC 2023-08-09 21:34:07 +10:00
Stenzek c7cfea1daa GS/Vulkan: Make VK_EXT_provoking_vertex optional again
RenderDoc doesn't support it.
2023-08-09 21:33:45 +10:00
Stenzek beb07365a0 Build: Disable Vulkan on macOS builds
MoltenVK does not support the extensions we now require.
2023-08-09 19:34:23 +10:00
Stenzek 0787c65e51 GS/Vulkan: Mandate well-supported extensions
- VK_EXT_provoking_vertex and provokingVertexLast
 - VK_EXT_line_rasterization and bresenhamLines
 - VK_KHR_shader_draw_parameters

Lack of these would cause rendering issues anyway.
2023-08-09 19:34:23 +10:00
Stenzek d48dea7273 GS/Vulkan: Don't track vertex buffer state
It never changes.
2023-08-09 19:34:23 +10:00
Stenzek 2432cc6ed2 GS/Vulkan: clang-format 2023-08-09 19:34:23 +10:00
Stenzek cf523d4215 GS/Vulkan: Use push descriptors instead of per-frame allocations 2023-08-09 19:34:23 +10:00
lightningterror 906d87c4b8 GS/HW: Fix nfs undercover crashing on dev/debug builds.
We were reading the wrong value.
2023-08-09 10:23:47 +02:00
Connor McLaughlinandTellowKrinkle 9c4a92c015 GS/Metal: Fix crash when Z write is on second pass 2023-08-08 18:27:54 -05:00
lightningterror 0c056ba691 USB: Fix function parameter should be passed by const reference warnings.
Codacy.
2023-08-08 21:27:36 +02:00
lightningterror 424158b28d DEV9: Fix function parameter should be passed by const reference warnings.
Codacy.
2023-08-08 21:27:36 +02:00
JordanTheToasterandrefractionpcsx2 57f118a5b5 GameDB: Various fixes
Fixes line across the screen and offset blur in Samurai Westerner and corrects region of Chinese entry's to properly use the flag included in the icons folder.
2023-08-08 08:58:55 +01:00
refractionpcsx2 65e75f3da2 GS/TC: Ignore linear part of rect when translating 2023-08-08 08:57:09 +01:00
refractionpcsx2 41174cde45 GS: Elide flushes on GS transfer if not required 2023-08-08 08:57:09 +01:00
refractionpcsx2 cb7d01fb36 GameDB: Improve Myst 3 patch 2023-08-08 08:56:52 +01:00
refractionpcsx2 3e78f8e87d IPU: Improve DMA/IPU call locations to reduce looping 2023-08-08 08:56:52 +01:00
BacklogOdysseyandConnor McLaughlin f2c032ba07 RetroAchievements/Qt: Add configurable achievement notification duration 2023-08-08 13:17:28 +10:00
refractionpcsx2 2ef1589e76 GameDB: Remove NFS HP2 GS fix which did nothing. 2023-08-07 23:03:11 +01:00
refractionpcsx2 5c394557e3 GS/HW: Handle split shuffles with a width of 1 2023-08-07 23:03:11 +01:00
PCSX2 Botandrefractionpcsx2 5c4a5b0a61 PAD: Update to latest controller database. 2023-08-07 17:10:55 +01:00
Silentandrefractionpcsx2 be22b7349d GameList: Add an option to exclude entire directories 2023-08-07 16:50:15 +01:00
refractionpcsx2 023e4774a1 UI: Only allow relative memcard files in memcard interface 2023-08-07 16:49:45 +01:00
Stenzekandrefractionpcsx2 56b706f25e Achievements: Tag a few missing strings for translation 2023-08-07 16:49:34 +01:00
Stenzekandrefractionpcsx2 9d07ee43eb VMManager: Fix achievements HC mode not applying on reset 2023-08-07 16:49:34 +01:00
Connor McLaughlinandTellowKrinkle 147a6c81a1 GS/Metal: Don't end up with two encoders on readback 2023-08-06 16:38:59 -05:00
RedPanda4552andrefractionpcsx2 5972f4947d InputManager: Fix incorrect compare for multitap enabled 2023-08-06 00:45:58 +01:00
refractionpcsx2 9c99a624d7 GS/HW: Optimise usage of 24bit alphas 2023-08-05 22:01:59 +01:00
refractionpcsx2 d812d83dda GS/HW: Limit alpha range on 16bit targets 2023-08-05 22:01:59 +01:00
refractionpcsx2 f81c5c2455 GS/HW: Guess alpha values when using 16bit RT as TEX = RT 2023-08-05 22:01:59 +01:00
refractionpcsx2 dc8c5e6209 GS/HW: Use texture alpha for 16bit textures in CalcAlphaMinMax 2023-08-05 22:01:59 +01:00
Stenzekandrefractionpcsx2 14833582b2 GS/HW: Re-optimize alpha test after updating direct alpha range 2023-08-05 22:01:59 +01:00
Mrlinkwiiandrefractionpcsx2 cca813fd1d GameDB: fixes for Panzer Elite Action & Totally Spies 2023-08-04 16:30:19 +01:00
lightningterror d4102e75c5 Readme: Update requirements.
Minimum: Lower STR requirements to 1500 from 1800.
Recommended: Lower STR requirements to 2000 from 2500.
Add Heavy category with STR requirements 2600.
2023-08-04 16:32:16 +02:00
Tyler Wildingandrefractionpcsx2 76a04efc5c ci: properly fetch release info to make announcement 2023-08-03 21:41:46 +01:00
JordanTheToasterandrefractionpcsx2 a34e139843 GameDB: Remove CCLUT from Raw Danger
Doesn't appear to do anything currently and causes the game to do almost 100 readbacks totally killing performance in hardware mode.
2023-08-03 11:59:09 +01:00
Tyler Wildingandrefractionpcsx2 a1727a2ac7 ci: announce release after it's published
It's no longer working because workflows will not implicitly trigger from another workflow when initiated by the default token.

You must explicitly call them via a `workflow_dispatch` or use a distinct PAT.

The announce workflow isn't really used anywhere else so simplifying and consolidating the steps feels appropriate.
2023-08-03 01:51:58 +01:00
Stenzekandrefractionpcsx2 7ac224adf3 MemoryCardFolder: Initialize hostFilePath 2023-08-02 16:06:37 +01:00
RedDevilusandrefractionpcsx2 d5e3d02a98 GameDB: Missing Korean entries + maintenance
Based on:
https://github.com/PCSX2/pcsx2/pull/9671#issuecomment-1657337888

I do see a lot of the missing entries actually come from the PCSX2 wiki, and the csv was mostly duplicates but I checked and cleaned it up while looking at other things to potentially fix.

GGeneration is faulty naming though, G Genereration needs a space.

There are also 2 reasons why we don't fully follow redump:
For starters Windows uses specific characters in their code and following that would make it impossible to make covers for them and some other things
The other thing is when The blablabla  turns into blablabla, The for filtering purposes.

In future we should probably have a display language for specific languages, ex. Korean entries show Japanese, English or others
2023-08-02 16:02:53 +01:00
Connor McLaughlin 68ad3e8db4 FileSystem: Partial revert of c82f800
Mixing stdio and raw FD access is a bad thing, filelength() isn't going to return correct results when extending a file has been buffered.
2023-08-02 18:45:52 +10:00
Stenzek 31029b2fe4 InputManager: Don't connect bindings for disabled multitap ports 2023-08-02 12:44:31 +10:00
Stenzek 8b0c101768 Pad: Move multitap into its own config section
And more config cleanups.
2023-08-02 12:44:31 +10:00
JordanTheToasterandrefractionpcsx2 50b66f526b GameDB: Various fixes
Fixes menu corruption and likely other issues the game may have had similar to all future entry's.
2023-08-02 01:07:45 +01:00
RedDevilusandrefractionpcsx2 f3fcf010fb GameDB: Remove accidental addition Growlanser 5+6
Texture Inside RT was fixed in https://github.com/PCSX2/pcsx2/pull/9187
2023-08-01 17:31:47 +01:00
PCSX2 Botandrefractionpcsx2 4da53bd00d Qt: Update Base Translation 2023-08-01 17:18:23 +01:00
Mrlinkwiiandrefractionpcsx2 c6cef45f0e Inputmanager: fix possible build issue 2023-08-01 17:07:51 +01:00
Mrlinkwiiandrefractionpcsx2 e36cd7fe5c Build: remove -32 notation from core filenames 2023-08-01 16:09:09 +01:00
Stenzek 0c24f2db7b GS/HW: Don't discard target when SCANMSK is set 2023-08-01 13:31:42 +10:00
Stenzek 8866faa8d5 GS: Remove GSCrc
Finally!
2023-08-01 12:42:06 +10:00
Stenzek b2dc31ba80 GS/HW: Move Tekken 5 CRC hack to the GSC 2023-08-01 12:42:06 +10:00
pgertandrefractionpcsx2 061ea30199 GameDB: entry correction 2023-07-31 22:36:56 +01:00
refractionpcsx2 0e9e94d090 UI: Delete rogue quote breaking HTML in Memcard Convert dialog 2023-07-31 16:36:14 +01:00
Stenzek 3321cb37ef GS/HW: Don't invalidate alpha on display target lookup 2023-07-31 21:08:33 +10:00
JordanTheToasterandrefractionpcsx2 d60a818791 GameDB: Go Go Golf Fixes
Fixes for the pretty awful brightness on pretty PS1 looking textures.
2023-07-31 10:59:54 +01:00
PCSX2 BotandConnor McLaughlin 3937a52b4f Qt: Update Base Translation 2023-07-31 19:28:43 +10:00
Stenzek 2c3902b1a1 GS/HW: Fix bilinear-over-self targets getting discarded 2023-07-31 19:24:08 +10:00
RedPanda4552andrefractionpcsx2 f43b5ee76f Pad: Respect non-standard vibration mappings and pure digital button query 2023-07-30 23:48:12 +01:00
refractionpcsx2 bab16a5251 UI: Update glyphs for asian languages. 2023-07-30 19:20:29 +01:00
Mrlinkwiiandrefractionpcsx2 08c734d7fd GameDB: various fixes 2023-07-30 14:23:45 +01:00
Connor McLaughlin 36126a3ad9 GS: Drop alignment from ClearValue 2023-07-30 21:44:44 +10:00
kamfretozandConnor McLaughlin ce505d33bd Qt: Make incompatible savestate message translateable 2023-07-30 20:28:50 +10:00
Stenzek de0d859502 Qt: Fix changing cover file formats 2023-07-30 19:25:51 +10:00
Stenzek ce96d4bcc5 SaveState: Store the current PCSX2 version in the save state 2023-07-30 18:13:25 +10:00
ChromaryuandConnor McLaughlin fb242274d5 GameDB: Fix PoPoLoCrois Naming 2023-07-30 16:18:55 +10:00
Stenzek 938bc7cdd7 GS/HW: Allow fast clears even when expanding
Doesn't make sense not to.
2023-07-30 16:18:04 +10:00
Stenzek 36865f2930 GS/HW: Skip target conversion when alpha doesn't exist 2023-07-30 16:18:04 +10:00
refractionpcsx2 12e79cccf6 GS/HW: Improve detection of reverse texture shuffles 2023-07-30 07:04:39 +01:00
PCSX2 BotandConnor McLaughlin 6180f12ba3 Qt: Update Base Translation 2023-07-30 12:26:53 +10:00
refractionpcsx2 c00b6c6237 GameDB: Sort and append missing entried from Redump 2023-07-30 02:37:18 +01:00
RedPanda4552andrefractionpcsx2 dbdc74fdef Memcard: Remove erroneous auto eject decrement 2023-07-29 19:11:33 +01:00
pgertandrefractionpcsx2 5bb0a07164 GameDB: correct an entry 2023-07-29 18:32:26 +01:00
Stenzek 543f09999f GS/HW: Fix target memory usage underflowing 2023-07-30 01:03:46 +10:00
Connor McLaughlinandGitHub 812f32efdd README: Update DirectX Requirements 2023-07-29 22:32:20 +10:00
Stenzek 784264eba4 GS: Drop alpha gather from FXAA
It's not used by any backends.
2023-07-29 22:28:49 +10:00
Stenzek ff9ca059c7 GS/DX11: Require feature level 11.0
Feature level 11.0 GPUs were first released in 2009, almost 14 years ago
now. Older GPUs have not had drivers released in a long time, and are
known to be buggy.

None of us have hardware this old, so it's impossible for us to support
it.
2023-07-29 22:28:49 +10:00
SilentandConnor McLaughlin d4b0c39485 Achievements: Fix Leaderboard submission UI when multiple leaderboards update at once 2023-07-29 22:23:11 +10:00
Ty Lamontagneandrefractionpcsx2 87c42aeaf4 Debugger: Fix mismatch sign compare & bitwise on different enum warnings 2023-07-28 22:00:08 +01:00
Ty Lamontagneandrefractionpcsx2 5ba6e57c71 CDVD: Fix unused qualifier warning 2023-07-28 22:00:08 +01:00
Ty Lamontagneandrefractionpcsx2 6d2ba5c2d0 Common | TextureDecompress: Fix unused variable warning 2023-07-28 22:00:08 +01:00
Ty Lamontagneandrefractionpcsx2 0d42b81285 Debugger: Fix 'run-to-cursor' context action 2023-07-28 22:00:08 +01:00
Stenzek 9ce2ae613b GS/HW: Update vertex trace in ReplaceVerticesWithSprite() 2023-07-29 02:56:59 +10:00
PCSX2 Botandrefractionpcsx2 13c9e0e666 Qt: Update Base Translation 2023-07-28 16:32:23 +01:00
Stenzekandrefractionpcsx2 784118e9c1 GS/HW: Don't drop fractional colour before modulating
Fixes banding in Xenosaga, Tales of the Abyss, Beyond Good and Evil.
2023-07-28 16:31:35 +01:00
Mrlinkwiiandrefractionpcsx2 df32a32d99 GameDB: add missing serials 2023-07-28 16:29:25 +01:00
JordanTheToasterandrefractionpcsx2 655241aed3 Translations: Add Latvija to the menu
Adds missing Latvija option to the menu of selectable languages.
2023-07-28 16:28:29 +01:00
refractionpcsx2 60a2b246e2 GS: Correct alpha test for RGB Only and non-32bit colours 2023-07-28 15:57:28 +01:00
Tyler WildingandGitHub ebd60d93f3 translations: Syncing Crowdin translations (#9655) 2023-07-28 14:50:23 +01:00
Connor McLaughlinandGitHub cc4ba935b5 CI/Linux: Fetch tags for Flatpak scheduled builds
Regression from #9224.
2023-07-28 21:48:35 +10:00
RedPanda4552andrefractionpcsx2 824147fd7d [SAVEVERSION+] Fix vibration motors backwards and too low power delivery to small motor
Also fix inconsequential but (technically) incorrect return values for vibration mapping command
2023-07-28 11:27:51 +01:00
refractionpcsx2 c3446a16cc GS: Kill SMT Nocturne CRC hack 2023-07-28 01:48:45 +01:00
Stenzekandrefractionpcsx2 82135d1892 GS/OGL: Fix depth state in MultiStretchRects 2023-07-28 01:48:27 +01:00
refractionpcsx2 1cff63bc01 UI: Add some missing string translations 2023-07-27 20:25:17 +01:00
refractionpcsx2 e488e74313 UI: Fix minor typo 2023-07-27 20:25:17 +01:00
refractionpcsx2 1a17c9da86 GameDB: Add Preload Frame to remaining versions of Keroro Gunsou 2023-07-27 20:25:17 +01:00
refractionpcsx2 20e1f773fc GS/HW: Mark alpha invalid on framebuffer resize. 2023-07-27 20:25:17 +01:00
refractionpcsx2 56d80ff293 GS/HW: Update Blue Tongue CRC and remove frame width hacks 2023-07-27 20:25:17 +01:00
refractionpcsx2 80e176136a GS/HW: Adjust Burnout bloom CRC to work better with upscaling 2023-07-27 20:23:21 +01:00
RedPanda4552andrefractionpcsx2 0ae66d3e24 Pad: Set data low when no pad present
Fixes uLaunchELF spinning waiting for second pad to come online.
2023-07-27 20:19:45 +01:00
RedDevilusandrefractionpcsx2 802ab8238e GameDB: Beeg fixing about everything
Sims M6 to M8 (more languages)
Tarzan (Slight Blurring)
Winnie Poo (Misaligned sprites and models)
Blood Will Tell: More vibrant text with medium blending
Recommended blending for SSX series

etc Because I keep forgetting to PR this otherwise
2023-07-27 17:09:31 +01:00
refractionpcsx2 ec9c07a646 GS/HW: Tweak Burnout bloom CRC coords 2023-07-27 14:50:29 +01:00
refractionpcsx2 b75ad663f2 USB/UI: Fix small typo 2023-07-27 13:08:08 +01:00
Stenzek e4a017fc00 Qt: Add callback for forcing achievements re-login 2023-07-27 20:40:58 +10:00
SilentandConnor McLaughlin 5b486ca6b8 Achievements: Log-in explicitly on startup to refresh the token 2023-07-27 20:40:58 +10:00
PCSX2 BotandConnor McLaughlin 1c39ed6130 Qt: Update Base Translation 2023-07-27 12:50:26 +10:00
lightningterror a47563b12f GSRunner: Fixes runner compile.
Pad include from previous refactor.
2023-07-26 21:56:56 +02:00
refractionpcsx2 84491ff655 GS/HW: Modify Burnout IO CRC hack to not affect online mode screen 2023-07-26 20:23:37 +01:00
refractionpcsx2 e5991a4379 GameDB: Add Partial Target Invalidation to Racing Simulation 3 2023-07-26 16:07:57 +01:00
JordanTheToasterandrefractionpcsx2 0b3d4615b8 ImGuiOverlays: Fix missing space
Text gets bunched up otherwise with no space.
2023-07-26 14:38:18 +01:00
JordanTheToasterandrefractionpcsx2 a8f6336b47 GameDB: Various fixes
Fixes for flickering lights in Area 51 and missing fixes for Burnout Revenge and Dominator.
2023-07-26 14:38:18 +01:00
RedPanda4552andConnor McLaughlin 0b33df3341 Pad: Change button query response depending on current mode
Fixes CoD 3 not understanding which buttons the controller has available
2023-07-26 21:23:21 +10:00
kamfretozandConnor McLaughlin 744cc4b705 Qt: Add an instruction to the autoupdater pop up. 2023-07-26 15:03:11 +10:00
kamfretozandConnor McLaughlin 9d3cd5784f Qt: Further icon refinement and additions 2023-07-26 13:28:23 +10:00
Stenzek 06ea58198a GameDB: Use nearest dirty upload for Burnout 3 and Onimusha 3
Burnout 3: Fixes sun banding in some stages.
Onimusha 3: Fixes vertical line down screen.
2023-07-26 13:21:35 +10:00
Stenzek 3692d7d090 GS/HW: Extend bilinear dirty upscale fix to force nearest 2023-07-26 13:21:35 +10:00
Stenzek 460a2dbbd3 Qt: Add custom binding widget for GunCon2 2023-07-26 13:20:44 +10:00
Stenzek 228f4f1010 USB-GunCon2: Support binding to controller 2023-07-26 13:20:44 +10:00
Stenzek 2703b91e41 USB: Add ConfigKeyExists() 2023-07-26 13:20:44 +10:00
Stenzek 24171787f8 ImGuiManager: Add software cursor support
Can be used to render a crosshair for GunCon.
2023-07-26 13:20:44 +10:00
PCSX2 BotandConnor McLaughlin 49d3338d4a Qt: Update Base Translation 2023-07-26 13:19:37 +10:00
Stenzek a9d693e1c3 GS/HW: Improve readback-avoiding CLUT heuristics
Use target overlap instead of exact match.
2023-07-26 13:18:04 +10:00
Stenzek 4ef69248d0 GSRunner: Add readbacks to stats 2023-07-26 13:18:04 +10:00
Stenzek 247b3ed740 GS/HW: HLE the Burnout games bloom effect 2023-07-26 13:18:04 +10:00
Stenzekandrefractionpcsx2 1edca6235c Sio: Migrate to StateWrapper
Also fixes the crash due to serializing pointers.

[SAVEVERSION+] and actually bump the save version.
2023-07-26 01:22:11 +01:00
Connor McLaughlinandGitHub ab5c03b1d9 Pad: Fixes and cleanup (#9623)
* Pad: Get rid of redundant object lookup

* Pad: Serialize 'stage' state

[SAVEVERSION+]

* Pad: Reduce Freeze duplication and add markers

Catch any possible unhandled device type change.

[SAVEVERSION+]

* Pad: Localize controller type names

* Pad: Handle mismatch between state and current config

* Misc: Drop .at() from vector/array access

We don't use exceptions.

* Pad: Remove redundant GetUnifiedSlot()

Sio has routines for converting these.

* Sio2: Remove redundant optional in Pad()

* Pad: Constify and finalize controller classes

* Pad: Move PadManager to Pad namespace

No point having a class when there's only a single instance.

* Pad: Move PadConfig to Pad namespace

* Pad: Move PadMacros to Pad namespace

* Pad: Re-localize controller bindings/settings

* Pad: Make controller info local

Don't want to create duplicates.

* Pad: Use span for ControllerInfo settings/bindings

* Pad: Fix auto-toggled macro buttons

* Pad: Fix pressure for macros

* Pad: Merge PadConfig/PadManager/PadMacros

Faster compile time.

* Pad: Fix incorrect condition in Sio0::SetTxData()

* Pad: Add deadzone for macro triggers
2023-07-26 01:10:02 +10:00
TheLastRarandrefractionpcsx2 d4cb35469d DEV9: Perform a null check on ifa_addr when searching adapters 2023-07-25 13:23:01 +01:00
Stenzek fd1b1d0c24 GS/HW: Improve Basic blending
- Don't assume no overlap = free. Reduces a number of barriers.
 - Prefer SW blend for Ad blends, except when it's constant. It's
   impossible to emulate accurately in HW, because 128 is 1, not 255.
 - Prefer SW blend for AFIX > 128 on no-overlap sprites.
2023-07-25 13:04:45 +10:00
Stenzek bf96ceeacc GS/HW: Assume primitive does not overlap if it is a single quad
Enables one-barrier software blending for fullscreen quads.
We can also use tex-is-fb safely in these scenarios too.

Fixes Persona 4 menu background, Hard Hitter Tennis shadows at
Basic blending.
2023-07-25 13:04:45 +10:00
RedPanda4552andrefractionpcsx2 2c08b385e5 Pad: Revert back to old Constant 1 behavior
Fixes pad detection in NBA 2K7, possibly others.
2023-07-25 00:27:53 +01:00
JordanTheToasterandrefractionpcsx2 051d13ec7a GameDB: Various fixes
Adds missing fixes and game entry's for guitar hero and re fixes LOTR Third Age.
2023-07-24 23:18:30 +01:00
refractionpcsx2 a2a9643123 GameDB: Move Haunting Ground over to HPO Special + Round Sprite Half 2023-07-24 21:44:24 +01:00
refractionpcsx2 1286bfe75b UI/UX: Added popup when updating if savestate version changes 2023-07-24 19:42:36 +01:00
241 changed files with 125535 additions and 60766 deletions
@@ -37,5 +37,6 @@ jobs:
cmakeflags: ""
publish: true
branch: stable
fetchTags: true
secrets: inherit
+1
View File
@@ -105,6 +105,7 @@ jobs:
cmake -DCMAKE_PREFIX_PATH="$HOME/deps" \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_OPENGL=OFF \
-DUSE_VULKAN=OFF \
-DDISABLE_ADVANCE_SIMD=ON \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
-DUSE_SYSTEM_LIBS=OFF \
-24
View File
@@ -1,24 +0,0 @@
name: 📢 Announce Release
on:
release:
types: [published]
jobs:
announce:
if: github.repository == 'PCSX2/pcsx2'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Announce Release
env:
DISCORD_BUILD_WEBHOOK: ${{ secrets.DISCORD_BUILD_WEBHOOK }}
run: |
cd ./.github/workflows/scripts/releases/announce-release
npm ci
node index.js
+22 -7
View File
@@ -27,8 +27,10 @@ permissions:
jobs:
cut-release:
if: github.repository == 'PCSX2/pcsx2'
runs-on: ubuntu-latest
name: "Create Tag and Release"
runs-on: ubuntu-latest
outputs:
new_tag: ${{ steps.tag_version.outputs.new_tag }}
steps:
- uses: actions/checkout@v3
@@ -131,6 +133,7 @@ jobs:
upload_artifacts:
if: github.repository == 'PCSX2/pcsx2'
needs:
- cut-release
- build_linux_flatpak
- build_linux_qt
- build_windows_qt
@@ -140,10 +143,6 @@ jobs:
steps:
- uses: actions/checkout@v3
# actions/checkout elides tags, fetch them primarily for releases
- name: Fetch Tags
run: git fetch --tags --no-recurse-submodules
- name: Prepare Artifact Folder
run: mkdir ./ci-artifacts/
@@ -169,7 +168,7 @@ jobs:
SCAN_DIR: ${{ github.WORKSPACE }}/ci-artifacts
OUT_DIR: ${{ github.WORKSPACE }}/ci-artifacts/out
run: |
TAG_VAL=$(git tag --points-at HEAD)
TAG_VAL=${{needs.cut-release.outputs.new_tag}}
echo "TAG_VAL=${TAG_VAL}"
gh release list --repo PCSX2/pcsx2
mkdir -p ${{ github.WORKSPACE }}/ci-artifacts/out
@@ -181,6 +180,22 @@ jobs:
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
TAG_VAL=$(git tag --points-at HEAD)
TAG_VAL=${{needs.cut-release.outputs.new_tag}}
echo "TAG_VAL=${TAG_VAL}"
gh release edit ${TAG_VAL} --draft=false --repo PCSX2/pcsx2
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Announce Release
env:
OWNER: PCSX2
REPO: pcsx2
DISCORD_BUILD_WEBHOOK: ${{ secrets.DISCORD_BUILD_WEBHOOK }}
GITHUB_TOKEN: ${{ github.token }}
run: |
TAG_VAL=${{needs.cut-release.outputs.new_tag}}
cd ./.github/workflows/scripts/releases/announce-release
npm ci
TAG_VAL=${TAG_VAL} node index.js
@@ -1,7 +1,58 @@
import { MessageEmbed, WebhookClient } from "discord.js";
import * as github from '@actions/github';
import { Octokit } from "@octokit/rest";
import { throttling } from "@octokit/plugin-throttling";
import { retry } from "@octokit/plugin-retry";
const releaseInfo = github.context.payload.release;
let owner = process.env.OWNER;
let repo = process.env.REPO;
Octokit.plugin(throttling);
Octokit.plugin(retry);
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
userAgent: `${owner}/${repo}`,
log: {
debug: () => { },
info: () => { },
warn: console.warn,
error: console.error
},
throttle: {
onRateLimit: (retryAfter, options) => {
octokit.log.warn(
`Request quota exhausted for request ${options.method} ${options.url}`
);
// Retry twice after hitting a rate limit error, then give up
if (options.request.retryCount <= 2) {
console.log(`Retrying after ${retryAfter} seconds!`);
return true;
}
},
onAbuseLimit: (retryAfter, options) => {
// does not retry, only logs a warning
octokit.log.warn(
`Abuse detected for request ${options.method} ${options.url}`
);
},
}
});
if (process.env.TAG_VAL === undefined || process.env.TAG_VAL === "") {
console.log(`Not announcing - TAG_VAL not defined`);
process.exit(1);
}
const { data: releaseInfo } = await octokit.rest.repos.getReleaseByTag({
owner: owner,
repo: repo,
tag: process.env.TAG_VAL,
});
if (releaseInfo === undefined) {
console.log(`Not announcing - could not locate release with tag ${process.env.TAG_VAL}`);
process.exit(1);
}
if (!releaseInfo.prerelease) {
console.log("Not announcing - release was not a pre-release (aka a Nightly)");
@@ -18,6 +69,7 @@ const embed = new MessageEmbed()
{ 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 }
);
console.log(embed);
// Get all webhooks, simple comma-sep string
const webhookUrls = process.env.DISCORD_BUILD_WEBHOOK.split(",");
@@ -5,32 +5,16 @@
"requires": true,
"packages": {
"": {
"name": "announce-release",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@actions/github": "^5.0.0",
"@octokit/plugin-retry": "^3.0.9",
"@octokit/plugin-throttling": "^3.5.2",
"@octokit/rest": "^18.12.0",
"discord.js": "^13.2.0"
}
},
"node_modules/@actions/github": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz",
"integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==",
"dependencies": {
"@actions/http-client": "^1.0.11",
"@octokit/core": "^3.4.0",
"@octokit/plugin-paginate-rest": "^2.13.3",
"@octokit/plugin-rest-endpoint-methods": "^5.1.1"
}
},
"node_modules/@actions/http-client": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz",
"integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==",
"dependencies": {
"tunnel": "0.0.6"
}
},
"node_modules/@discordjs/builders": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.6.0.tgz",
@@ -131,6 +115,14 @@
"@octokit/types": "^6.33.0"
}
},
"node_modules/@octokit/plugin-request-log": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
"peerDependencies": {
"@octokit/core": ">=3"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "5.12.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
@@ -140,6 +132,27 @@
"deprecation": "^2.3.1"
}
},
"node_modules/@octokit/plugin-retry": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
"dependencies": {
"@octokit/types": "^6.0.3",
"bottleneck": "^2.15.3"
}
},
"node_modules/@octokit/plugin-throttling": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.7.0.tgz",
"integrity": "sha512-qrKT1Yl/KuwGSC6/oHpLBot3ooC9rq0/ryDYBCpkRtoj+R8T47xTMDT6Tk2CxWopFota/8Pi/2SqArqwC0JPow==",
"dependencies": {
"@octokit/types": "^6.0.1",
"bottleneck": "^2.15.3"
},
"peerDependencies": {
"@octokit/core": "^3.5.0"
}
},
"node_modules/@octokit/request": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
@@ -163,6 +176,17 @@
"once": "^1.4.0"
}
},
"node_modules/@octokit/rest": {
"version": "18.12.0",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
"dependencies": {
"@octokit/core": "^3.5.1",
"@octokit/plugin-paginate-rest": "^2.16.8",
"@octokit/plugin-request-log": "^1.0.4",
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
}
},
"node_modules/@octokit/types": {
"version": "6.33.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
@@ -214,6 +238,11 @@
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
},
"node_modules/bottleneck": {
"version": "2.19.5",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -388,14 +417,6 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
},
"node_modules/type-fest": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
@@ -461,25 +482,6 @@
}
},
"dependencies": {
"@actions/github": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz",
"integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==",
"requires": {
"@actions/http-client": "^1.0.11",
"@octokit/core": "^3.4.0",
"@octokit/plugin-paginate-rest": "^2.13.3",
"@octokit/plugin-rest-endpoint-methods": "^5.1.1"
}
},
"@actions/http-client": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz",
"integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==",
"requires": {
"tunnel": "0.0.6"
}
},
"@discordjs/builders": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.6.0.tgz",
@@ -569,6 +571,12 @@
"@octokit/types": "^6.33.0"
}
},
"@octokit/plugin-request-log": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
"requires": {}
},
"@octokit/plugin-rest-endpoint-methods": {
"version": "5.12.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
@@ -578,6 +586,24 @@
"deprecation": "^2.3.1"
}
},
"@octokit/plugin-retry": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
"requires": {
"@octokit/types": "^6.0.3",
"bottleneck": "^2.15.3"
}
},
"@octokit/plugin-throttling": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.7.0.tgz",
"integrity": "sha512-qrKT1Yl/KuwGSC6/oHpLBot3ooC9rq0/ryDYBCpkRtoj+R8T47xTMDT6Tk2CxWopFota/8Pi/2SqArqwC0JPow==",
"requires": {
"@octokit/types": "^6.0.1",
"bottleneck": "^2.15.3"
}
},
"@octokit/request": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
@@ -601,6 +627,17 @@
"once": "^1.4.0"
}
},
"@octokit/rest": {
"version": "18.12.0",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
"requires": {
"@octokit/core": "^3.5.1",
"@octokit/plugin-paginate-rest": "^2.16.8",
"@octokit/plugin-request-log": "^1.0.4",
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
}
},
"@octokit/types": {
"version": "6.33.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
@@ -642,6 +679,11 @@
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
},
"bottleneck": {
"version": "2.19.5",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
},
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -765,11 +807,6 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"type-fest": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
@@ -10,7 +10,9 @@
"author": "",
"license": "ISC",
"dependencies": {
"@actions/github": "^5.0.0",
"@octokit/plugin-retry": "^3.0.9",
"@octokit/plugin-throttling": "^3.5.2",
"@octokit/rest": "^18.12.0",
"discord.js": "^13.2.0"
}
}
+1
View File
@@ -44,6 +44,7 @@ Thumbs.db
Debug.txt
install_log.txt
bad_shader_*
crash-*.txt
Debug
Release
+37
View File
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="UserMacros">
<BinaryOutputDir>$(SolutionDir)bin\</BinaryOutputDir>
<WinPixEventRuntimeDir>$(SolutionDir)3rdparty\winpixeventruntime\</WinPixEventRuntimeDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(WinPixEventRuntimeDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link Condition="'$(Platform)'=='x64'">
<AdditionalLibraryDirectories>$(WinPixEventRuntimeDir)lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>WinPixEventRuntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Lib Condition="'$(Platform)'=='x64'">
<AdditionalLibraryDirectories>$(WinPixEventRuntimeDir)lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>WinPixEventRuntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<!--Copy the needed dlls-->
<ItemGroup>
<WinPixEventRuntimeDlls Condition="'$(Platform)'=='x64'" Include="$(WinPixEventRuntimeDir)bin\WinPixEventRuntime.dll" />
</ItemGroup>
<Target Name="WinPixEventRuntimeCopyBinaries"
AfterTargets="Build"
Condition="'$(Platform)'=='x64'"
Inputs="@(WinPixEventRuntimeDlls)"
Outputs="@(WinPixEventRuntimeDlls -> '$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(Extension)')">
<Message Text="Copying WinPixEventRuntime .dlls" Importance="High" />
<Copy
SourceFiles="@(WinPixEventRuntimeDlls)"
DestinationFolder="$(BinaryOutputDir)"
SkipUnchangedFiles="true"
/>
</Target>
</Project>
Binary file not shown.
@@ -0,0 +1,661 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
/*==========================================================================;
*
* Copyright (C) Microsoft Corporation. All Rights Reserved.
*
* File: PIXEvents.h
* Content: PIX include file
* Don't include this file directly - use pix3.h
*
****************************************************************************/
#pragma once
#ifndef _PixEvents_H_
#define _PixEvents_H_
#ifndef _PIX3_H_
# error Do not include this file directly - use pix3.h
#endif
#include "PIXEventsCommon.h"
#if _MSC_VER < 1800
# error This version of pix3.h is only supported on Visual Studio 2013 or higher
#elif _MSC_VER < 1900
# ifndef constexpr // Visual Studio 2013 doesn't support constexpr
# define constexpr
# define PIX3__DEFINED_CONSTEXPR
# endif
#endif
// Xbox does not support CPU events for retail scenarios
#if defined(USE_PIX) || !defined(PIX_XBOX)
#define PIX_CONTEXT_EMIT_CPU_EVENTS
#endif
namespace PIXEventsDetail
{
template<typename... ARGS>
struct PIXEventTypeInferer
{
static constexpr PIXEventType Begin() { return PIXEvent_BeginEvent_VarArgs; }
static constexpr PIXEventType SetMarker() { return PIXEvent_SetMarker_VarArgs; }
static constexpr PIXEventType BeginOnContext() { return PIXEvent_BeginEvent_OnContext_VarArgs; }
static constexpr PIXEventType SetMarkerOnContext() { return PIXEvent_SetMarker_OnContext_VarArgs; }
// Xbox and Windows store different types of events for context events.
// On Xbox these include a context argument, while on Windows they do
// not. It is important not to change the event types used on the
// Windows version as there are OS components (eg debug layer & DRED)
// that decode event structs.
#ifdef PIX_XBOX
static constexpr PIXEventType GpuBeginOnContext() { return PIXEvent_BeginEvent_OnContext_VarArgs; }
static constexpr PIXEventType GpuSetMarkerOnContext() { return PIXEvent_SetMarker_OnContext_VarArgs; }
#else
static constexpr PIXEventType GpuBeginOnContext() { return PIXEvent_BeginEvent_VarArgs; }
static constexpr PIXEventType GpuSetMarkerOnContext() { return PIXEvent_SetMarker_VarArgs; }
#endif
};
template<>
struct PIXEventTypeInferer<>
{
static constexpr PIXEventType Begin() { return PIXEvent_BeginEvent_NoArgs; }
static constexpr PIXEventType SetMarker() { return PIXEvent_SetMarker_NoArgs; }
static constexpr PIXEventType BeginOnContext() { return PIXEvent_BeginEvent_OnContext_NoArgs; }
static constexpr PIXEventType SetMarkerOnContext() { return PIXEvent_SetMarker_OnContext_NoArgs; }
#ifdef PIX_XBOX
static constexpr PIXEventType GpuBeginOnContext() { return PIXEvent_BeginEvent_OnContext_NoArgs; }
static constexpr PIXEventType GpuSetMarkerOnContext() { return PIXEvent_SetMarker_OnContext_NoArgs; }
#else
static constexpr PIXEventType GpuBeginOnContext() { return PIXEvent_BeginEvent_NoArgs; }
static constexpr PIXEventType GpuSetMarkerOnContext() { return PIXEvent_SetMarker_NoArgs; }
#endif
};
inline void PIXCopyEventArguments(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit)
{
// nothing
UNREFERENCED_PARAMETER(destination);
UNREFERENCED_PARAMETER(limit);
}
template<typename ARG, typename... ARGS>
void PIXCopyEventArguments(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, ARG const& arg, ARGS const&... args)
{
PIXCopyEventArgument(destination, limit, arg);
PIXCopyEventArguments(destination, limit, args...);
}
template<typename STR, typename... ARGS>
__declspec(noinline) void PIXBeginEventAllocate(PIXEventsThreadInfo* threadInfo, UINT64 color, STR formatString, ARGS... args)
{
#ifdef PIX_XBOX
UINT64 time = PIXEventsReplaceBlock(false);
#else
UINT64 time = PIXEventsReplaceBlock(threadInfo, false);
#endif
if (!time)
return;
UINT64* destination = threadInfo->destination;
UINT64* limit = threadInfo->biasedLimit;
if (destination >= limit)
return;
limit += PIXEventsSafeFastCopySpaceQwords;
*destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::Begin());
*destination++ = color;
PIXCopyEventArguments(destination, limit, formatString, args...);
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
template<typename STR, typename... ARGS>
void PIXBeginEvent(UINT64 color, STR formatString, ARGS... args)
{
PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo();
UINT64* limit = threadInfo->biasedLimit;
if (limit != nullptr)
{
UINT64* destination = threadInfo->destination;
if (destination < limit)
{
limit += PIXEventsSafeFastCopySpaceQwords;
UINT64 time = PIXGetTimestampCounter();
*destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::Begin());
*destination++ = color;
PIXCopyEventArguments(destination, limit, formatString, args...);
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
else
{
PIXBeginEventAllocate(threadInfo, color, formatString, args...);
}
}
}
template<typename STR, typename... ARGS>
__declspec(noinline) void PIXSetMarkerAllocate(PIXEventsThreadInfo* threadInfo, UINT64 color, STR formatString, ARGS... args)
{
#ifdef PIX_XBOX
UINT64 time = PIXEventsReplaceBlock(false);
#else
UINT64 time = PIXEventsReplaceBlock(threadInfo, false);
#endif
if (!time)
return;
UINT64* destination = threadInfo->destination;
UINT64* limit = threadInfo->biasedLimit;
if (destination >= limit)
return;
limit += PIXEventsSafeFastCopySpaceQwords;
*destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::SetMarker());
*destination++ = color;
PIXCopyEventArguments(destination, limit, formatString, args...);
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
template<typename STR, typename... ARGS>
void PIXSetMarker(UINT64 color, STR formatString, ARGS... args)
{
PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo();
UINT64* limit = threadInfo->biasedLimit;
if (limit != nullptr)
{
UINT64* destination = threadInfo->destination;
if (destination < limit)
{
limit += PIXEventsSafeFastCopySpaceQwords;
UINT64 time = PIXGetTimestampCounter();
*destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::SetMarker());
*destination++ = color;
PIXCopyEventArguments(destination, limit, formatString, args...);
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
else
{
PIXSetMarkerAllocate(threadInfo, color, formatString, args...);
}
}
}
template<typename STR, typename... ARGS>
__declspec(noinline) void PIXBeginEventOnContextCpuAllocate(PIXEventsThreadInfo* threadInfo, void* context, UINT64 color, STR formatString, ARGS... args)
{
#ifdef PIX_XBOX
UINT64 time = PIXEventsReplaceBlock(false);
#else
UINT64 time = PIXEventsReplaceBlock(threadInfo, false);
#endif
if (!time)
return;
UINT64* destination = threadInfo->destination;
UINT64* limit = threadInfo->biasedLimit;
if (destination >= limit)
return;
limit += PIXEventsSafeFastCopySpaceQwords;
*destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::BeginOnContext());
*destination++ = color;
#ifdef PIX_XBOX
UNREFERENCED_PARAMETER(context);
PIXCopyEventArguments(destination, limit, formatString, args...);
#else
PIXCopyEventArguments(destination, limit, context, formatString, args...);
#endif
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
template<typename STR, typename... ARGS>
void PIXBeginEventOnContextCpu(void* context, UINT64 color, STR formatString, ARGS... args)
{
PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo();
UINT64* limit = threadInfo->biasedLimit;
if (limit != nullptr)
{
UINT64* destination = threadInfo->destination;
if (destination < limit)
{
limit += PIXEventsSafeFastCopySpaceQwords;
UINT64 time = PIXGetTimestampCounter();
*destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::BeginOnContext());
*destination++ = color;
#ifdef PIX_XBOX
PIXCopyEventArguments(destination, limit, formatString, args...);
#else
PIXCopyEventArguments(destination, limit, context, formatString, args...);
#endif
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
else
{
PIXBeginEventOnContextCpuAllocate(threadInfo, context, color, formatString, args...);
}
}
}
template<typename CONTEXT, typename STR, typename... ARGS>
void PIXBeginEvent(CONTEXT* context, UINT64 color, STR formatString, ARGS... args)
{
#ifdef PIX_CONTEXT_EMIT_CPU_EVENTS
PIXBeginEventOnContextCpu(context, color, formatString, args...);
#endif
// TODO: we've already encoded this once for the CPU event - figure out way to avoid doing it again
UINT64 buffer[PIXEventsGraphicsRecordSpaceQwords];
UINT64* destination = buffer;
UINT64* limit = buffer + PIXEventsGraphicsRecordSpaceQwords - PIXEventsReservedTailSpaceQwords;
*destination++ = PIXEncodeEventInfo(0, PIXEventTypeInferer<ARGS...>::GpuBeginOnContext());
*destination++ = color;
PIXCopyEventArguments(destination, limit, formatString, args...);
*destination = 0ull;
PIXBeginGPUEventOnContext(context, static_cast<void*>(buffer), static_cast<UINT>(reinterpret_cast<BYTE*>(destination) - reinterpret_cast<BYTE*>(buffer)));
}
template<typename STR, typename... ARGS>
__declspec(noinline) void PIXSetMarkerOnContextCpuAllocate(PIXEventsThreadInfo* threadInfo, void* context, UINT64 color, STR formatString, ARGS... args)
{
#ifdef PIX_XBOX
UINT64 time = PIXEventsReplaceBlock(false);
#else
UINT64 time = PIXEventsReplaceBlock(threadInfo, false);
#endif
if (!time)
return;
UINT64* destination = threadInfo->destination;
UINT64* limit = threadInfo->biasedLimit;
if (destination >= limit)
return;
limit += PIXEventsSafeFastCopySpaceQwords;
*destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::SetMarkerOnContext());
*destination++ = color;
#ifdef PIX_XBOX
UNREFERENCED_PARAMETER(context);
PIXCopyEventArguments(destination, limit, formatString, args...);
#else
PIXCopyEventArguments(destination, limit, context, formatString, args...);
#endif
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
template<typename STR, typename... ARGS>
void PIXSetMarkerOnContextCpu(void* context, UINT64 color, STR formatString, ARGS... args)
{
PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo();
UINT64* limit = threadInfo->biasedLimit;
if (limit != nullptr)
{
UINT64* destination = threadInfo->destination;
if (destination < limit)
{
limit += PIXEventsSafeFastCopySpaceQwords;
UINT64 time = PIXGetTimestampCounter();
*destination++ = PIXEncodeEventInfo(time, PIXEventTypeInferer<ARGS...>::SetMarkerOnContext());
*destination++ = color;
#ifdef PIX_XBOX
PIXCopyEventArguments(destination, limit, formatString, args...);
#else
PIXCopyEventArguments(destination, limit, context, formatString, args...);
#endif
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
else
{
PIXSetMarkerOnContextCpuAllocate(threadInfo, context, color, formatString, args...);
}
}
}
template<typename CONTEXT, typename STR, typename... ARGS>
void PIXSetMarker(CONTEXT* context, UINT64 color, STR formatString, ARGS... args)
{
#ifdef PIX_CONTEXT_EMIT_CPU_EVENTS
PIXSetMarkerOnContextCpu(context, color, formatString, args...);
#endif
UINT64 buffer[PIXEventsGraphicsRecordSpaceQwords];
UINT64* destination = buffer;
UINT64* limit = buffer + PIXEventsGraphicsRecordSpaceQwords - PIXEventsReservedTailSpaceQwords;
*destination++ = PIXEncodeEventInfo(0, PIXEventTypeInferer<ARGS...>::GpuSetMarkerOnContext());
*destination++ = color;
PIXCopyEventArguments(destination, limit, formatString, args...);
*destination = 0ull;
PIXSetGPUMarkerOnContext(context, static_cast<void*>(buffer), static_cast<UINT>(reinterpret_cast<BYTE*>(destination) - reinterpret_cast<BYTE*>(buffer)));
}
__declspec(noinline) inline void PIXEndEventAllocate(PIXEventsThreadInfo* threadInfo)
{
#ifdef PIX_XBOX
UINT64 time = PIXEventsReplaceBlock(true);
#else
UINT64 time = PIXEventsReplaceBlock(threadInfo, true);
#endif
if (!time)
return;
UINT64* destination = threadInfo->destination;
UINT64* limit = threadInfo->biasedLimit;
if (destination >= limit)
return;
limit += PIXEventsSafeFastCopySpaceQwords;
*destination++ = PIXEncodeEventInfo(time, PIXEvent_EndEvent);
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
inline void PIXEndEvent()
{
PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo();
UINT64* limit = threadInfo->biasedLimit;
if (limit != nullptr)
{
UINT64* destination = threadInfo->destination;
if (destination < limit)
{
limit += PIXEventsSafeFastCopySpaceQwords;
UINT64 time = PIXGetTimestampCounter();
*destination++ = PIXEncodeEventInfo(time, PIXEvent_EndEvent);
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
else
{
PIXEndEventAllocate(threadInfo);
}
}
}
__declspec(noinline) inline void PIXEndEventOnContextCpuAllocate(PIXEventsThreadInfo* threadInfo, void* context)
{
#ifdef PIX_XBOX
UINT64 time = PIXEventsReplaceBlock(true);
#else
UINT64 time = PIXEventsReplaceBlock(threadInfo, true);
#endif
if (!time)
return;
UINT64* destination = threadInfo->destination;
UINT64* limit = threadInfo->biasedLimit;
if (destination >= limit)
return;
limit += PIXEventsSafeFastCopySpaceQwords;
*destination++ = PIXEncodeEventInfo(time, PIXEvent_EndEvent_OnContext);
#ifdef PIX_XBOX
UNREFERENCED_PARAMETER(context);
#else
PIXCopyEventArgument(destination, limit, context);
#endif
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
inline void PIXEndEventOnContextCpu(void* context)
{
PIXEventsThreadInfo* threadInfo = PIXGetThreadInfo();
UINT64* limit = threadInfo->biasedLimit;
if (limit != nullptr)
{
UINT64* destination = threadInfo->destination;
if (destination < limit)
{
limit += PIXEventsSafeFastCopySpaceQwords;
UINT64 time = PIXGetTimestampCounter();
*destination++ = PIXEncodeEventInfo(time, PIXEvent_EndEvent_OnContext);
#ifndef PIX_XBOX
PIXCopyEventArgument(destination, limit, context);
#endif
*destination = PIXEventsBlockEndMarker;
threadInfo->destination = destination;
}
else
{
PIXEndEventOnContextCpuAllocate(threadInfo, context);
}
}
}
template<typename CONTEXT>
void PIXEndEvent(CONTEXT* context)
{
#ifdef PIX_CONTEXT_EMIT_CPU_EVENTS
PIXEndEventOnContextCpu(context);
#endif
PIXEndGPUEventOnContext(context);
}
}
#if defined(USE_PIX)
template<typename... ARGS>
void PIXBeginEvent(UINT64 color, PCWSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXBeginEvent(color, formatString, args...);
}
template<typename... ARGS>
void PIXBeginEvent(UINT64 color, PCSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXBeginEvent(color, formatString, args...);
}
template<typename... ARGS>
void PIXSetMarker(UINT64 color, PCWSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXSetMarker(color, formatString, args...);
}
template<typename... ARGS>
void PIXSetMarker(UINT64 color, PCSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXSetMarker(color, formatString, args...);
}
template<typename CONTEXT, typename... ARGS>
void PIXBeginEvent(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...);
}
template<typename CONTEXT, typename... ARGS>
void PIXBeginEvent(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...);
}
template<typename CONTEXT, typename... ARGS>
void PIXSetMarker(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXSetMarker(context, color, formatString, args...);
}
template<typename CONTEXT, typename... ARGS>
void PIXSetMarker(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXSetMarker(context, color, formatString, args...);
}
inline void PIXEndEvent()
{
PIXEventsDetail::PIXEndEvent();
}
template<typename CONTEXT>
void PIXEndEvent(CONTEXT* context)
{
PIXEventsDetail::PIXEndEvent(context);
}
#else // USE_PIX_RETAIL
inline void PIXBeginEvent(UINT64, _In_ PCSTR, ...) {}
inline void PIXBeginEvent(UINT64, _In_ PCWSTR, ...) {}
inline void PIXBeginEvent(void*, UINT64, _In_ PCSTR, ...) {}
inline void PIXBeginEvent(void*, UINT64, _In_ PCWSTR, ...) {}
inline void PIXEndEvent() {}
inline void PIXEndEvent(void*) {}
inline void PIXSetMarker(UINT64, _In_ PCSTR, ...) {}
inline void PIXSetMarker(UINT64, _In_ PCWSTR, ...) {}
inline void PIXSetMarker(void*, UINT64, _In_ PCSTR, ...) {}
inline void PIXSetMarker(void*, UINT64, _In_ PCWSTR, ...) {}
#endif // USE_PIX
template<typename CONTEXT, typename... ARGS>
void PIXBeginRetailEvent(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...);
}
template<typename CONTEXT, typename... ARGS>
void PIXBeginRetailEvent(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXBeginEvent(context, color, formatString, args...);
}
template<typename CONTEXT, typename... ARGS>
void PIXSetRetailMarker(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXSetMarker(context, color, formatString, args...);
}
template<typename CONTEXT, typename... ARGS>
void PIXSetRetailMarker(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
{
PIXEventsDetail::PIXSetMarker(context, color, formatString, args...);
}
template<typename CONTEXT>
void PIXEndRetailEvent(CONTEXT* context)
{
PIXEventsDetail::PIXEndEvent(context);
}
template<typename CONTEXT>
class PIXScopedEventObject
{
CONTEXT* m_context;
public:
template<typename... ARGS>
PIXScopedEventObject(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
: m_context(context)
{
PIXBeginEvent(m_context, color, formatString, args...);
}
template<typename... ARGS>
PIXScopedEventObject(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
: m_context(context)
{
PIXBeginEvent(m_context, color, formatString, args...);
}
~PIXScopedEventObject()
{
PIXEndEvent(m_context);
}
};
template<typename CONTEXT>
class PIXScopedRetailEventObject
{
CONTEXT* m_context;
public:
template<typename... ARGS>
PIXScopedRetailEventObject(CONTEXT* context, UINT64 color, PCWSTR formatString, ARGS... args)
: m_context(context)
{
PIXBeginRetailEvent(m_context, color, formatString, args...);
}
template<typename... ARGS>
PIXScopedRetailEventObject(CONTEXT* context, UINT64 color, PCSTR formatString, ARGS... args)
: m_context(context)
{
PIXBeginRetailEvent(m_context, color, formatString, args...);
}
~PIXScopedRetailEventObject()
{
PIXEndRetailEvent(m_context);
}
};
template<>
class PIXScopedEventObject<void>
{
public:
template<typename... ARGS>
PIXScopedEventObject(UINT64 color, PCWSTR formatString, ARGS... args)
{
PIXBeginEvent(color, formatString, args...);
}
template<typename... ARGS>
PIXScopedEventObject(UINT64 color, PCSTR formatString, ARGS... args)
{
PIXBeginEvent(color, formatString, args...);
}
~PIXScopedEventObject()
{
PIXEndEvent();
}
};
#define PIXConcatenate(a, b) a ## b
#define PIXGetScopedEventVariableName(a, b) PIXConcatenate(a, b)
#define PIXScopedEvent(context, ...) PIXScopedEventObject<PIXInferScopedEventType<decltype(context)>::Type> PIXGetScopedEventVariableName(pixEvent, __LINE__)(context, __VA_ARGS__)
#ifdef PIX3__DEFINED_CONSTEXPR
#undef constexpr
#undef PIX3__DEFINED_CONSTEXPR
#endif
#endif // _PIXEvents_H__
@@ -0,0 +1,605 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
/*==========================================================================;
*
* Copyright (C) Microsoft Corporation. All Rights Reserved.
*
* File: PIXEventsCommon.h
* Content: PIX include file
* Don't include this file directly - use pix3.h
*
****************************************************************************/
#pragma once
#ifndef _PIXEventsCommon_H_
#define _PIXEventsCommon_H_
#if defined(XBOX) || defined(_XBOX_ONE) || defined(_DURANGO) || defined(_GAMING_XBOX) || defined(_GAMING_XBOX_SCARLETT)
#define PIX_XBOX
#endif
#include <cstdint>
#if defined(_M_X64) || defined(_M_IX86)
#include <emmintrin.h>
#endif
//
// The PIXBeginEvent and PIXSetMarker functions have an optimized path for
// copying strings that work by copying 128-bit or 64-bits at a time. In some
// circumstances this may result in PIX logging the remaining memory after the
// null terminator.
//
// By default this optimization is enabled unless Address Sanitizer is enabled,
// since this optimization can trigger a global-buffer-overflow when copying
// string literals.
//
// The PIX_ENABLE_BLOCK_ARGUMENT_COPY controls whether or not this optimization
// is enabled. Applications may also explicitly set this macro to 0 to disable
// the optimization if necessary.
//
// Check for Address Sanitizer on either Clang or MSVC
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
#define PIX_ASAN_ENABLED
#endif
#elif defined(__SANITIZE_ADDRESS__)
#define PIX_ASAN_ENABLED
#endif
#if defined(PIX_ENABLE_BLOCK_ARGUMENT_COPY)
// Previously set values override everything
# define PIX_ENABLE_BLOCK_ARGUMENT_COPY_SET 0
#elif defined(PIX_ASAN_ENABLED)
// Disable block argument copy when address sanitizer is enabled
#define PIX_ENABLE_BLOCK_ARGUMENT_COPY 0
#define PIX_ENABLE_BLOCK_ARGUMENT_COPY_SET 1
#endif
#if !defined(PIX_ENABLE_BLOCK_ARGUMENT_COPY)
// Default to enabled.
#define PIX_ENABLE_BLOCK_ARGUMENT_COPY 1
#define PIX_ENABLE_BLOCK_ARGUMENT_COPY_SET 1
#endif
struct PIXEventsBlockInfo;
struct PIXEventsThreadInfo
{
PIXEventsBlockInfo* block;
UINT64* biasedLimit;
UINT64* destination;
};
#ifdef PIX_XBOX
extern "C" UINT64 WINAPI PIXEventsReplaceBlock(bool getEarliestTime) noexcept;
#else
extern "C" UINT64 WINAPI PIXEventsReplaceBlock(PIXEventsThreadInfo * threadInfo, bool getEarliestTime) noexcept;
#endif
enum PIXEventType
{
PIXEvent_EndEvent = 0x000,
PIXEvent_BeginEvent_VarArgs = 0x001,
PIXEvent_BeginEvent_NoArgs = 0x002,
PIXEvent_SetMarker_VarArgs = 0x007,
PIXEvent_SetMarker_NoArgs = 0x008,
PIXEvent_EndEvent_OnContext = 0x010,
PIXEvent_BeginEvent_OnContext_VarArgs = 0x011,
PIXEvent_BeginEvent_OnContext_NoArgs = 0x012,
PIXEvent_SetMarker_OnContext_VarArgs = 0x017,
PIXEvent_SetMarker_OnContext_NoArgs = 0x018,
};
static const UINT64 PIXEventsReservedRecordSpaceQwords = 64;
//this is used to make sure SSE string copy always will end 16-byte write in the current block
//this way only a check if destination < limit can be performed, instead of destination < limit - 1
//since both these are UINT64* and SSE writes in 16 byte chunks, 8 bytes are kept in reserve
//so even if SSE overwrites 8 extra bytes, those will still belong to the correct block
//on next iteration check destination will be greater than limit
//this is used as well for fixed size UMD events and PIXEndEvent since these require less space
//than other variable length user events and do not need big reserved space
static const UINT64 PIXEventsReservedTailSpaceQwords = 2;
static const UINT64 PIXEventsSafeFastCopySpaceQwords = PIXEventsReservedRecordSpaceQwords - PIXEventsReservedTailSpaceQwords;
static const UINT64 PIXEventsGraphicsRecordSpaceQwords = 64;
//Bits 7-19 (13 bits)
static const UINT64 PIXEventsBlockEndMarker = 0x00000000000FFF80;
//Bits 10-19 (10 bits)
static const UINT64 PIXEventsTypeReadMask = 0x00000000000FFC00;
static const UINT64 PIXEventsTypeWriteMask = 0x00000000000003FF;
static const UINT64 PIXEventsTypeBitShift = 10;
//Bits 20-63 (44 bits)
static const UINT64 PIXEventsTimestampReadMask = 0xFFFFFFFFFFF00000;
static const UINT64 PIXEventsTimestampWriteMask = 0x00000FFFFFFFFFFF;
static const UINT64 PIXEventsTimestampBitShift = 20;
inline UINT64 PIXEncodeEventInfo(UINT64 timestamp, PIXEventType eventType)
{
return ((timestamp & PIXEventsTimestampWriteMask) << PIXEventsTimestampBitShift) |
(((UINT64)eventType & PIXEventsTypeWriteMask) << PIXEventsTypeBitShift);
}
//Bits 60-63 (4)
static const UINT64 PIXEventsStringAlignmentWriteMask = 0x000000000000000F;
static const UINT64 PIXEventsStringAlignmentReadMask = 0xF000000000000000;
static const UINT64 PIXEventsStringAlignmentBitShift = 60;
//Bits 55-59 (5)
static const UINT64 PIXEventsStringCopyChunkSizeWriteMask = 0x000000000000001F;
static const UINT64 PIXEventsStringCopyChunkSizeReadMask = 0x0F80000000000000;
static const UINT64 PIXEventsStringCopyChunkSizeBitShift = 55;
//Bit 54
static const UINT64 PIXEventsStringIsANSIWriteMask = 0x0000000000000001;
static const UINT64 PIXEventsStringIsANSIReadMask = 0x0040000000000000;
static const UINT64 PIXEventsStringIsANSIBitShift = 54;
//Bit 53
static const UINT64 PIXEventsStringIsShortcutWriteMask = 0x0000000000000001;
static const UINT64 PIXEventsStringIsShortcutReadMask = 0x0020000000000000;
static const UINT64 PIXEventsStringIsShortcutBitShift = 53;
inline UINT64 PIXEncodeStringInfo(UINT64 alignment, UINT64 copyChunkSize, BOOL isANSI, BOOL isShortcut)
{
return ((alignment & PIXEventsStringAlignmentWriteMask) << PIXEventsStringAlignmentBitShift) |
((copyChunkSize & PIXEventsStringCopyChunkSizeWriteMask) << PIXEventsStringCopyChunkSizeBitShift) |
(((UINT64)isANSI & PIXEventsStringIsANSIWriteMask) << PIXEventsStringIsANSIBitShift) |
(((UINT64)isShortcut & PIXEventsStringIsShortcutWriteMask) << PIXEventsStringIsShortcutBitShift);
}
template<UINT alignment, class T>
inline bool PIXIsPointerAligned(T* pointer)
{
return !(((UINT64)pointer) & (alignment - 1));
}
// Generic template version slower because of the additional clear write
template<class T>
inline void PIXCopyEventArgument(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, T argument)
{
if (destination < limit)
{
*destination = 0ull;
*((T*)destination) = argument;
++destination;
}
}
// int32 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<INT32>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, INT32 argument)
{
if (destination < limit)
{
*reinterpret_cast<INT64*>(destination) = static_cast<INT64>(argument);
++destination;
}
}
// unsigned int32 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<UINT32>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, UINT32 argument)
{
if (destination < limit)
{
*destination = static_cast<UINT64>(argument);
++destination;
}
}
// int64 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<INT64>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, INT64 argument)
{
if (destination < limit)
{
*reinterpret_cast<INT64*>(destination) = argument;
++destination;
}
}
// unsigned int64 specialization to avoid slower double memory writes
template<>
inline void PIXCopyEventArgument<UINT64>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, UINT64 argument)
{
if (destination < limit)
{
*destination = argument;
++destination;
}
}
//floats must be cast to double during writing the data to be properly printed later when reading the data
//this is needed because when float is passed to varargs function it's cast to double
template<>
inline void PIXCopyEventArgument<float>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, float argument)
{
if (destination < limit)
{
*reinterpret_cast<double*>(destination) = static_cast<double>(argument);
++destination;
}
}
//char has to be cast to a longer signed integer type
//this is due to printf not ignoring correctly the upper bits of unsigned long long for a char format specifier
template<>
inline void PIXCopyEventArgument<char>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, char argument)
{
if (destination < limit)
{
*reinterpret_cast<INT64*>(destination) = static_cast<INT64>(argument);
++destination;
}
}
//unsigned char has to be cast to a longer unsigned integer type
//this is due to printf not ignoring correctly the upper bits of unsigned long long for a char format specifier
template<>
inline void PIXCopyEventArgument<unsigned char>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, unsigned char argument)
{
if (destination < limit)
{
*destination = static_cast<UINT64>(argument);
++destination;
}
}
//bool has to be cast to an integer since it's not explicitly supported by string format routines
//there's no format specifier for bool type, but it should work with integer format specifiers
template<>
inline void PIXCopyEventArgument<bool>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, bool argument)
{
if (destination < limit)
{
*destination = static_cast<UINT64>(argument);
++destination;
}
}
inline void PIXCopyEventArgumentSlowest(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
{
*destination++ = PIXEncodeStringInfo(0, 8, TRUE, FALSE);
while (destination < limit)
{
UINT64 c = static_cast<uint8_t>(argument[0]);
if (!c)
{
*destination++ = 0;
return;
}
UINT64 x = c;
c = static_cast<uint8_t>(argument[1]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 8;
c = static_cast<uint8_t>(argument[2]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 16;
c = static_cast<uint8_t>(argument[3]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 24;
c = static_cast<uint8_t>(argument[4]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 32;
c = static_cast<uint8_t>(argument[5]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 40;
c = static_cast<uint8_t>(argument[6]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 48;
c = static_cast<uint8_t>(argument[7]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 56;
*destination++ = x;
argument += 8;
}
}
inline void PIXCopyEventArgumentSlow(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
{
#if PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<8>(argument))
{
*destination++ = PIXEncodeStringInfo(0, 8, TRUE, FALSE);
UINT64* source = (UINT64*)argument;
while (destination < limit)
{
UINT64 qword = *source++;
*destination++ = qword;
//check if any of the characters is a terminating zero
if (!((qword & 0xFF00000000000000) &&
(qword & 0xFF000000000000) &&
(qword & 0xFF0000000000) &&
(qword & 0xFF00000000) &&
(qword & 0xFF000000) &&
(qword & 0xFF0000) &&
(qword & 0xFF00) &&
(qword & 0xFF)))
{
break;
}
}
}
else
#endif // PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
PIXCopyEventArgumentSlowest(destination, limit, argument);
}
}
template<>
inline void PIXCopyEventArgument<PCSTR>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCSTR argument)
{
if (destination < limit)
{
if (argument != nullptr)
{
#if (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<16>(argument))
{
*destination++ = PIXEncodeStringInfo(0, 16, TRUE, FALSE);
__m128i zero = _mm_setzero_si128();
if (PIXIsPointerAligned<16>(destination))
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_store_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi8(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 16;
}
}
else
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_storeu_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi8(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 16;
}
}
}
else
#endif // (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
PIXCopyEventArgumentSlow(destination, limit, argument);
}
}
else
{
*destination++ = 0ull;
}
}
}
template<>
inline void PIXCopyEventArgument<PSTR>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PSTR argument)
{
PIXCopyEventArgument(destination, limit, (PCSTR)argument);
}
inline void PIXCopyEventArgumentSlowest(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
{
*destination++ = PIXEncodeStringInfo(0, 8, FALSE, FALSE);
while (destination < limit)
{
UINT64 c = static_cast<uint16_t>(argument[0]);
if (!c)
{
*destination++ = 0;
return;
}
UINT64 x = c;
c = static_cast<uint16_t>(argument[1]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 16;
c = static_cast<uint16_t>(argument[2]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 32;
c = static_cast<uint16_t>(argument[3]);
if (!c)
{
*destination++ = x;
return;
}
x |= c << 48;
*destination++ = x;
argument += 4;
}
}
inline void PIXCopyEventArgumentSlow(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
{
#if PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<8>(argument))
{
*destination++ = PIXEncodeStringInfo(0, 8, FALSE, FALSE);
UINT64* source = (UINT64*)argument;
while (destination < limit)
{
UINT64 qword = *source++;
*destination++ = qword;
//check if any of the characters is a terminating zero
//TODO: check if reversed condition is faster
if (!((qword & 0xFFFF000000000000) &&
(qword & 0xFFFF00000000) &&
(qword & 0xFFFF0000) &&
(qword & 0xFFFF)))
{
break;
}
}
}
else
#endif // PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
PIXCopyEventArgumentSlowest(destination, limit, argument);
}
}
template<>
inline void PIXCopyEventArgument<PCWSTR>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PCWSTR argument)
{
if (destination < limit)
{
if (argument != nullptr)
{
#if (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
if (PIXIsPointerAligned<16>(argument))
{
*destination++ = PIXEncodeStringInfo(0, 16, FALSE, FALSE);
__m128i zero = _mm_setzero_si128();
if (PIXIsPointerAligned<16>(destination))
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_store_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi16(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 8;
}
}
else
{
while (destination < limit)
{
__m128i mem = _mm_load_si128((__m128i*)argument);
_mm_storeu_si128((__m128i*)destination, mem);
//check if any of the characters is a terminating zero
__m128i res = _mm_cmpeq_epi16(mem, zero);
destination += 2;
if (_mm_movemask_epi8(res))
break;
argument += 8;
}
}
}
else
#endif // (defined(_M_X64) || defined(_M_IX86)) && PIX_ENABLE_BLOCK_ARGUMENT_COPY
{
PIXCopyEventArgumentSlow(destination, limit, argument);
}
}
else
{
*destination++ = 0ull;
}
}
}
template<>
inline void PIXCopyEventArgument<PWSTR>(_Out_writes_to_ptr_(limit) UINT64*& destination, _In_ const UINT64* limit, _In_ PWSTR argument)
{
PIXCopyEventArgument(destination, limit, (PCWSTR)argument);
};
#if defined(__d3d12_x_h__) || defined(__d3d12_xs_h__) || defined(__d3d12_h__)
inline void PIXSetGPUMarkerOnContext(_In_ ID3D12GraphicsCommandList* commandList, _In_reads_bytes_(size) void* data, UINT size)
{
commandList->SetMarker(D3D12_EVENT_METADATA, data, size);
}
inline void PIXSetGPUMarkerOnContext(_In_ ID3D12CommandQueue* commandQueue, _In_reads_bytes_(size) void* data, UINT size)
{
commandQueue->SetMarker(D3D12_EVENT_METADATA, data, size);
}
inline void PIXBeginGPUEventOnContext(_In_ ID3D12GraphicsCommandList* commandList, _In_reads_bytes_(size) void* data, UINT size)
{
commandList->BeginEvent(D3D12_EVENT_METADATA, data, size);
}
inline void PIXBeginGPUEventOnContext(_In_ ID3D12CommandQueue* commandQueue, _In_reads_bytes_(size) void* data, UINT size)
{
commandQueue->BeginEvent(D3D12_EVENT_METADATA, data, size);
}
inline void PIXEndGPUEventOnContext(_In_ ID3D12GraphicsCommandList* commandList)
{
commandList->EndEvent();
}
inline void PIXEndGPUEventOnContext(_In_ ID3D12CommandQueue* commandQueue)
{
commandQueue->EndEvent();
}
#endif //__d3d12_h__
template<class T> struct PIXInferScopedEventType { typedef T Type; };
template<class T> struct PIXInferScopedEventType<const T> { typedef T Type; };
template<class T> struct PIXInferScopedEventType<T*> { typedef T Type; };
template<class T> struct PIXInferScopedEventType<T* const> { typedef T Type; };
template<> struct PIXInferScopedEventType<UINT64> { typedef void Type; };
template<> struct PIXInferScopedEventType<const UINT64> { typedef void Type; };
template<> struct PIXInferScopedEventType<INT64> { typedef void Type; };
template<> struct PIXInferScopedEventType<const INT64> { typedef void Type; };
template<> struct PIXInferScopedEventType<UINT> { typedef void Type; };
template<> struct PIXInferScopedEventType<const UINT> { typedef void Type; };
template<> struct PIXInferScopedEventType<INT> { typedef void Type; };
template<> struct PIXInferScopedEventType<const INT> { typedef void Type; };
#if PIX_ENABLE_BLOCK_ARGUMENT_COPY_SET
#undef PIX_ENABLE_BLOCK_ARGUMENT_COPY
#endif
#undef PIX_ENABLE_BLOCK_ARGUMENT_COPY_SET
#endif //_PIXEventsCommon_H_
@@ -0,0 +1,175 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
/*==========================================================================;
*
* Copyright (C) Microsoft Corporation. All Rights Reserved.
*
* File: pix3.h
* Content: PIX include file
*
****************************************************************************/
#pragma once
#ifndef _PIX3_H_
#define _PIX3_H_
#include <sal.h>
#ifndef __cplusplus
#error "Only C++ files can include pix3.h. C is not supported."
#endif
#if !defined(USE_PIX_SUPPORTED_ARCHITECTURE)
#if defined(_M_X64) || defined(USE_PIX_ON_ALL_ARCHITECTURES) || defined(_M_ARM64)
#define USE_PIX_SUPPORTED_ARCHITECTURE
#endif
#endif
#if !defined(USE_PIX)
#if defined(USE_PIX_SUPPORTED_ARCHITECTURE) && (defined(_DEBUG) || DBG || defined(PROFILE) || defined(PROFILE_BUILD)) && !defined(_PREFAST_)
#define USE_PIX
#endif
#endif
#if defined(USE_PIX) && !defined(USE_PIX_SUPPORTED_ARCHITECTURE)
#pragma message("Warning: Pix markers are only supported on AMD64 and ARM64")
#endif
// These flags are used by both PIXBeginCapture and PIXGetCaptureState
#define PIX_CAPTURE_TIMING (1 << 0)
#define PIX_CAPTURE_GPU (1 << 1)
#define PIX_CAPTURE_FUNCTION_SUMMARY (1 << 2)
#define PIX_CAPTURE_FUNCTION_DETAILS (1 << 3)
#define PIX_CAPTURE_CALLGRAPH (1 << 4)
#define PIX_CAPTURE_INSTRUCTION_TRACE (1 << 5)
#define PIX_CAPTURE_SYSTEM_MONITOR_COUNTERS (1 << 6)
#define PIX_CAPTURE_VIDEO (1 << 7)
#define PIX_CAPTURE_AUDIO (1 << 8)
#define PIX_CAPTURE_RESERVED (1 << 15)
union PIXCaptureParameters
{
enum PIXCaptureStorage
{
Memory = 0,
};
struct GpuCaptureParameters
{
PCWSTR FileName;
} GpuCaptureParameters;
struct TimingCaptureParameters
{
PCWSTR FileName;
UINT32 MaximumToolingMemorySizeMb;
PIXCaptureStorage CaptureStorage;
BOOL CaptureGpuTiming;
BOOL CaptureCallstacks;
BOOL CaptureCpuSamples;
UINT32 CpuSamplesPerSecond;
BOOL CaptureFileIO;
BOOL CaptureVirtualAllocEvents;
BOOL CaptureHeapAllocEvents;
BOOL CaptureXMemEvents; // Xbox only
BOOL CapturePixMemEvents; // Xbox only
} TimingCaptureParameters;
};
typedef PIXCaptureParameters* PPIXCaptureParameters;
#if defined(XBOX) || defined(_XBOX_ONE) || defined(_DURANGO) || defined(_GAMING_XBOX) || defined(_GAMING_XBOX_SCARLETT)
#include "pix3_xbox.h"
#else
#include "pix3_win.h"
#endif
#if defined(USE_PIX_SUPPORTED_ARCHITECTURE) && (defined(USE_PIX) || defined(USE_PIX_RETAIL))
#define PIX_EVENTS_ARE_TURNED_ON
#include "PIXEventsCommon.h"
#include "PIXEvents.h"
#ifdef USE_PIX
// Starts a programmatically controlled capture.
// captureFlags uses the PIX_CAPTURE_* family of flags to specify the type of capture to take
extern "C" HRESULT WINAPI PIXBeginCapture2(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters);
inline HRESULT PIXBeginCapture(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters) { return PIXBeginCapture2(captureFlags, captureParameters); }
// Stops a programmatically controlled capture
// If discard == TRUE, the captured data is discarded
// If discard == FALSE, the captured data is saved
// discard parameter is not supported on Windows
extern "C" HRESULT WINAPI PIXEndCapture(BOOL discard);
extern "C" DWORD WINAPI PIXGetCaptureState();
extern "C" void WINAPI PIXReportCounter(_In_ PCWSTR name, float value);
#endif // USE_PIX
#endif // (USE_PIX_SUPPORTED_ARCHITECTURE) && (USE_PIX || USE_PIX_RETAIL)
#if !defined(USE_PIX_SUPPORTED_ARCHITECTURE) || !defined(USE_PIX)
// Eliminate these APIs when not using PIX
inline HRESULT PIXBeginCapture2(DWORD, _In_opt_ const PIXCaptureParameters*) { return S_OK; }
inline HRESULT PIXBeginCapture(DWORD, _In_opt_ const PIXCaptureParameters*) { return S_OK; }
inline HRESULT PIXEndCapture(BOOL) { return S_OK; }
inline HRESULT PIXGpuCaptureNextFrames(PCWSTR, UINT32) { return S_OK; }
inline HRESULT PIXSetTargetWindow(HWND) { return S_OK; }
inline HRESULT PIXForceD3D11On12() { return S_OK; }
inline HRESULT WINAPI PIXSetHUDOptions(PIXHUDOptions) { return S_OK; }
inline bool WINAPI PIXIsAttachedForGpuCapture() { return false; }
inline HINSTANCE WINAPI PIXOpenCaptureInUI(PCWSTR) { return 0; }
inline HMODULE PIXLoadLatestWinPixGpuCapturerLibrary() { return nullptr; }
inline HMODULE PIXLoadLatestWinPixTimingCapturerLibrary() { return nullptr; }
inline DWORD PIXGetCaptureState() { return 0; }
inline void PIXReportCounter(_In_ PCWSTR, float) {}
inline void PIXNotifyWakeFromFenceSignal(_In_ HANDLE) {}
#if !defined(USE_PIX_RETAIL)
inline void PIXBeginEvent(UINT64, _In_ PCSTR, ...) {}
inline void PIXBeginEvent(UINT64, _In_ PCWSTR, ...) {}
inline void PIXBeginEvent(void*, UINT64, _In_ PCSTR, ...) {}
inline void PIXBeginEvent(void*, UINT64, _In_ PCWSTR, ...) {}
inline void PIXEndEvent() {}
inline void PIXEndEvent(void*) {}
inline void PIXSetMarker(UINT64, _In_ PCSTR, ...) {}
inline void PIXSetMarker(UINT64, _In_ PCWSTR, ...) {}
inline void PIXSetMarker(void*, UINT64, _In_ PCSTR, ...) {}
inline void PIXSetMarker(void*, UINT64, _In_ PCWSTR, ...) {}
inline void PIXBeginRetailEvent(void*, UINT64, _In_ PCSTR, ...) {}
inline void PIXBeginRetailEvent(void*, UINT64, _In_ PCWSTR, ...) {}
inline void PIXEndRetailEvent(void*) {}
inline void PIXSetRetailMarker(void*, UINT64, _In_ PCSTR, ...) {}
inline void PIXSetRetailMarker(void*, UINT64, _In_ PCWSTR, ...) {}
inline void PIXScopedEvent(UINT64, _In_ PCSTR, ...) {}
inline void PIXScopedEvent(UINT64, _In_ PCWSTR, ...) {}
inline void PIXScopedEvent(void*, UINT64, _In_ PCSTR, ...) {}
inline void PIXScopedEvent(void*, UINT64, _In_ PCWSTR, ...) {}
#endif // !USE_PIX_RETAIL
// don't show warnings about expressions with no effect
#pragma warning(disable:4548)
#pragma warning(disable:4555)
#endif // !USE_PIX_SUPPORTED_ARCHITECTURE || !USE_PIX
// Use these functions to specify colors to pass as metadata to a PIX event/marker API.
// Use PIX_COLOR() to specify a particular color for an event.
// Or, use PIX_COLOR_INDEX() to specify a set of unique event categories, and let PIX choose
// the colors to represent each category.
inline UINT PIX_COLOR(BYTE r, BYTE g, BYTE b) { return 0xff000000 | (r << 16) | (g << 8) | b; }
inline UINT PIX_COLOR_INDEX(BYTE i) { return i; }
const UINT PIX_COLOR_DEFAULT = PIX_COLOR_INDEX(0);
#endif // _PIX3_H_
@@ -0,0 +1,439 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
/*==========================================================================;
*
* Copyright (C) Microsoft Corporation. All Rights Reserved.
*
* File: PIX3_win.h
* Content: PIX include file
* Don't include this file directly - use pix3.h
*
****************************************************************************/
#pragma once
#ifndef _PIX3_H_
#error Don't include this file directly - use pix3.h
#endif
#ifndef _PIX3_WIN_H_
#define _PIX3_WIN_H_
// PIXEventsThreadInfo is defined in PIXEventsCommon.h
struct PIXEventsThreadInfo;
extern "C" PIXEventsThreadInfo* WINAPI PIXGetThreadInfo() noexcept;
#if defined(USE_PIX) && defined(USE_PIX_SUPPORTED_ARCHITECTURE)
// Notifies PIX that an event handle was set as a result of a D3D12 fence being signaled.
// The event specified must have the same handle value as the handle
// used in ID3D12Fence::SetEventOnCompletion.
extern "C" void WINAPI PIXNotifyWakeFromFenceSignal(_In_ HANDLE event);
// Notifies PIX that a block of memory was allocated
extern "C" void WINAPI PIXRecordMemoryAllocationEvent(USHORT allocatorId, void* baseAddress, size_t size, UINT64 metadata);
// Notifies PIX that a block of memory was freed
extern "C" void WINAPI PIXRecordMemoryFreeEvent(USHORT allocatorId, void* baseAddress, size_t size, UINT64 metadata);
#else
// Eliminate these APIs when not using PIX
inline void PIXRecordMemoryAllocationEvent(USHORT, void*, size_t, UINT64) {}
inline void PIXRecordMemoryFreeEvent(USHORT, void*, size_t, UINT64) {}
#endif
// The following defines denote the different metadata values that have been used
// by tools to denote how to parse pix marker event data. The first two values
// are legacy values.
#define WINPIX_EVENT_UNICODE_VERSION 0
#define WINPIX_EVENT_ANSI_VERSION 1
#define WINPIX_EVENT_PIX3BLOB_VERSION 2
#define D3D12_EVENT_METADATA WINPIX_EVENT_PIX3BLOB_VERSION
__forceinline UINT64 PIXGetTimestampCounter()
{
LARGE_INTEGER time = {};
QueryPerformanceCounter(&time);
return static_cast<UINT64>(time.QuadPart);
}
enum PIXHUDOptions
{
PIX_HUD_SHOW_ON_ALL_WINDOWS = 0x1,
PIX_HUD_SHOW_ON_TARGET_WINDOW_ONLY = 0x2,
PIX_HUD_SHOW_ON_NO_WINDOWS = 0x4
};
DEFINE_ENUM_FLAG_OPERATORS(PIXHUDOptions);
#if defined(USE_PIX_SUPPORTED_ARCHITECTURE) && defined(USE_PIX)
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
#include <shlobj.h>
#include <strsafe.h>
#include <knownfolders.h>
#include <shellapi.h>
#define PIXERRORCHECK(value) do { \
if (FAILED(value)) \
return nullptr; \
} while(0)
namespace PixImpl
{
#ifndef PIX3_WIN_UNIT_TEST
__forceinline BOOL GetModuleHandleExW(
DWORD dwFlags,
LPCWSTR lpModuleName,
HMODULE* phModule)
{
return ::GetModuleHandleExW(dwFlags, lpModuleName, phModule);
}
__forceinline HRESULT SHGetKnownFolderPath(
REFKNOWNFOLDERID rfid,
DWORD dwFlags,
HANDLE hToken,
PWSTR* ppszPath)
{
return ::SHGetKnownFolderPath(rfid, dwFlags, hToken, ppszPath);
}
__forceinline void CoTaskMemFree(LPVOID pv)
{
return ::CoTaskMemFree(pv);
}
__forceinline HANDLE FindFirstFileW(
LPCWSTR lpFileName,
LPWIN32_FIND_DATAW lpFindFileData)
{
return ::FindFirstFileW(lpFileName, lpFindFileData);
}
__forceinline DWORD GetFileAttributesW(LPCWSTR lpFileName)
{
return ::GetFileAttributesW(lpFileName);
}
__forceinline BOOL FindNextFileW(
HANDLE hFindFile,
LPWIN32_FIND_DATAW lpFindFileData)
{
return ::FindNextFileW(hFindFile, lpFindFileData);
}
__forceinline BOOL FindClose(HANDLE hFindFile)
{
return ::FindClose(hFindFile);
}
__forceinline HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, DWORD flags)
{
return ::LoadLibraryExW(lpLibFileName, NULL, flags);
}
#endif // !PIX3_WIN_UNIT_TESTS
__forceinline void * GetGpuCaptureFunctionPtr(LPCSTR fnName) noexcept
{
HMODULE module = GetModuleHandleW(L"WinPixGpuCapturer.dll");
if (module == NULL)
{
return nullptr;
}
auto fn = (void*)GetProcAddress(module, fnName);
if (fn == nullptr)
{
return nullptr;
}
return fn;
}
__forceinline void* GetTimingCaptureFunctionPtr(LPCSTR fnName) noexcept
{
HMODULE module = GetModuleHandleW(L"WinPixTimingCapturer.dll");
if (module == NULL)
{
return nullptr;
}
auto fn = (void*)GetProcAddress(module, fnName);
if (fn == nullptr)
{
return nullptr;
}
return fn;
}
__forceinline HMODULE PIXLoadLatestCapturerLibrary(wchar_t const* capturerDllName, DWORD flags)
{
HMODULE libHandle{};
if (PixImpl::GetModuleHandleExW(0, capturerDllName, &libHandle))
{
return libHandle;
}
LPWSTR programFilesPath = nullptr;
if (FAILED(PixImpl::SHGetKnownFolderPath(FOLDERID_ProgramFiles, KF_FLAG_DEFAULT, NULL, &programFilesPath)))
{
PixImpl::CoTaskMemFree(programFilesPath);
return nullptr;
}
wchar_t pixSearchPath[MAX_PATH];
if (FAILED(StringCchCopyW(pixSearchPath, MAX_PATH, programFilesPath)))
{
PixImpl::CoTaskMemFree(programFilesPath);
return nullptr;
}
PixImpl::CoTaskMemFree(programFilesPath);
PIXERRORCHECK(StringCchCatW(pixSearchPath, MAX_PATH, L"\\Microsoft PIX\\*"));
WIN32_FIND_DATAW findData;
bool foundPixInstallation = false;
wchar_t newestVersionFound[MAX_PATH];
wchar_t output[MAX_PATH];
wchar_t possibleOutput[MAX_PATH];
HANDLE hFind = PixImpl::FindFirstFileW(pixSearchPath, &findData);
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
if (((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) &&
(findData.cFileName[0] != '.'))
{
if (!foundPixInstallation || wcscmp(newestVersionFound, findData.cFileName) <= 0)
{
// length - 1 to get rid of the wildcard character in the search path
PIXERRORCHECK(StringCchCopyNW(possibleOutput, MAX_PATH, pixSearchPath, wcslen(pixSearchPath) - 1));
PIXERRORCHECK(StringCchCatW(possibleOutput, MAX_PATH, findData.cFileName));
PIXERRORCHECK(StringCchCatW(possibleOutput, MAX_PATH, L"\\"));
PIXERRORCHECK(StringCchCatW(possibleOutput, MAX_PATH, capturerDllName));
DWORD result = PixImpl::GetFileAttributesW(possibleOutput);
if (result != INVALID_FILE_ATTRIBUTES && !(result & FILE_ATTRIBUTE_DIRECTORY))
{
foundPixInstallation = true;
PIXERRORCHECK(StringCchCopyW(newestVersionFound, _countof(newestVersionFound), findData.cFileName));
PIXERRORCHECK(StringCchCopyW(output, _countof(possibleOutput), possibleOutput));
}
}
}
} while (PixImpl::FindNextFileW(hFind, &findData) != 0);
}
PixImpl::FindClose(hFind);
if (!foundPixInstallation)
{
SetLastError(ERROR_FILE_NOT_FOUND);
return nullptr;
}
return PixImpl::LoadLibraryExW(output, flags);
}
}
#undef PIXERRORCHECK
__forceinline HMODULE PIXLoadLatestWinPixGpuCapturerLibrary()
{
return PixImpl::PIXLoadLatestCapturerLibrary(
L"WinPixGpuCapturer.dll",
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
}
__forceinline HMODULE PIXLoadLatestWinPixTimingCapturerLibrary()
{
return PixImpl::PIXLoadLatestCapturerLibrary(
L"WinPixTimingCapturer.dll",
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
}
__forceinline HRESULT WINAPI PIXSetTargetWindow(HWND hwnd)
{
typedef void(WINAPI* SetGlobalTargetWindowFn)(HWND);
auto fn = (SetGlobalTargetWindowFn)PixImpl::GetGpuCaptureFunctionPtr("SetGlobalTargetWindow");
if (fn == nullptr)
{
return HRESULT_FROM_WIN32(GetLastError());
}
fn(hwnd);
return S_OK;
}
__forceinline HRESULT WINAPI PIXGpuCaptureNextFrames(PCWSTR fileName, UINT32 numFrames)
{
typedef HRESULT(WINAPI* CaptureNextFrameFn)(PCWSTR, UINT32);
auto fn = (CaptureNextFrameFn)PixImpl::GetGpuCaptureFunctionPtr("CaptureNextFrame");
if (fn == nullptr)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return fn(fileName, numFrames);
}
extern "C" __forceinline HRESULT WINAPI PIXBeginCapture2(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters)
{
if (captureFlags == PIX_CAPTURE_GPU)
{
typedef HRESULT(WINAPI* BeginProgrammaticGpuCaptureFn)(const PPIXCaptureParameters);
auto fn = (BeginProgrammaticGpuCaptureFn)PixImpl::GetGpuCaptureFunctionPtr("BeginProgrammaticGpuCapture");
if (fn == nullptr)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return fn(captureParameters);
}
else if (captureFlags == PIX_CAPTURE_TIMING)
{
typedef HRESULT(WINAPI* BeginProgrammaticTimingCaptureFn)(void const*, UINT64);
auto fn = (BeginProgrammaticTimingCaptureFn)PixImpl::GetTimingCaptureFunctionPtr("BeginProgrammaticTimingCapture");
if (fn == nullptr)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return fn(&captureParameters->TimingCaptureParameters, sizeof(captureParameters->TimingCaptureParameters));
}
else
{
return E_NOTIMPL;
}
}
extern "C" __forceinline HRESULT WINAPI PIXEndCapture(BOOL discard)
{
UNREFERENCED_PARAMETER(discard);
// We can't tell if the user wants to end a GPU Capture or a Timing Capture.
// The user shouldn't have both WinPixGpuCapturer and WinPixTimingCapturer loaded in the process though,
// so we can just look for one of them and call it.
typedef HRESULT(WINAPI* EndProgrammaticGpuCaptureFn)(void);
auto gpuFn = (EndProgrammaticGpuCaptureFn)PixImpl::GetGpuCaptureFunctionPtr("EndProgrammaticGpuCapture");
if (gpuFn != NULL)
{
return gpuFn();
}
typedef HRESULT(WINAPI* EndProgrammaticTimingCaptureFn)(BOOL);
auto timingFn = (EndProgrammaticTimingCaptureFn)PixImpl::GetTimingCaptureFunctionPtr("EndProgrammaticTimingCapture");
if (timingFn != NULL)
{
return timingFn(discard);
}
return HRESULT_FROM_WIN32(GetLastError());
}
__forceinline HRESULT WINAPI PIXForceD3D11On12()
{
typedef HRESULT (WINAPI* ForceD3D11On12Fn)(void);
auto fn = (ForceD3D11On12Fn)PixImpl::GetGpuCaptureFunctionPtr("ForceD3D11On12");
if (fn == NULL)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return fn();
}
__forceinline HRESULT WINAPI PIXSetHUDOptions(PIXHUDOptions hudOptions)
{
typedef HRESULT(WINAPI* SetHUDOptionsFn)(PIXHUDOptions);
auto fn = (SetHUDOptionsFn)PixImpl::GetGpuCaptureFunctionPtr("SetHUDOptions");
if (fn == NULL)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return fn(hudOptions);
}
__forceinline bool WINAPI PIXIsAttachedForGpuCapture()
{
typedef bool(WINAPI* GetIsAttachedToPixFn)(void);
auto fn = (GetIsAttachedToPixFn)PixImpl::GetGpuCaptureFunctionPtr("GetIsAttachedToPix");
if (fn == NULL)
{
OutputDebugStringW(L"WinPixEventRuntime error: Mismatched header/dll. Please ensure that pix3.h and WinPixGpuCapturer.dll match");
return false;
}
return fn();
}
__forceinline HINSTANCE WINAPI PIXOpenCaptureInUI(PCWSTR fileName)
{
return ShellExecuteW(0, 0, fileName, 0, 0, SW_SHOW);
}
#else
__forceinline HMODULE PIXLoadLatestWinPixGpuCapturerLibrary()
{
return nullptr;
}
__forceinline HMODULE PIXLoadLatestWinPixTimingCapturerLibrary()
{
return nullptr;
}
__forceinline HRESULT WINAPI PIXSetTargetWindow(HWND)
{
return E_NOTIMPL;
}
__forceinline HRESULT WINAPI PIXGpuCaptureNextFrames(PCWSTR, UINT32)
{
return E_NOTIMPL;
}
extern "C" __forceinline HRESULT WINAPI PIXBeginCapture2(DWORD, _In_opt_ const PPIXCaptureParameters)
{
return E_NOTIMPL;
}
extern "C" __forceinline HRESULT WINAPI PIXEndCapture(BOOL)
{
return E_NOTIMPL;
}
__forceinline HRESULT WINAPI PIXForceD3D11On12()
{
return E_NOTIMPL;
}
__forceinline HRESULT WINAPI PIXSetHUDOptions(PIXHUDOptions)
{
return E_NOTIMPL;
}
__forceinline bool WINAPI PIXIsAttachedForGpuCapture()
{
return false;
}
__forceinline HINSTANCE WINAPI PIXOpenCaptureInUI(PCWSTR)
{
return 0;
}
#endif // WINAPI_PARTITION
#endif // USE_PIX_SUPPORTED_ARCHITECTURE || USE_PIX
#endif //_PIX3_WIN_H_
Binary file not shown.
+10 -4
View File
@@ -22,17 +22,23 @@ Installers and binaries for both stable and development builds are available fro
| Operating System | CPU | GPU | RAM |
| ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| - Windows 10 Version 1809 or later (64-bit) <br/> - Ubuntu 22.04/Debian or newer, Arch Linux, or other distro (64-bit) <br/> - macOS 10.14 | - Supports SSE4.1 <br/> - [PassMark Thread Performance](https://www.cpubenchmark.net/CPU_mega_page.html) rating near or greater than 1800<br/> - Two physical cores, with hyperthreading | - Direct3D10 support <br/> - OpenGL 3.x support <br/> - Vulkan 1.1 support <br/> - Metal support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 3000 (Geforce GTX 750, Radeon RX 560, Intel Arc A380) <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)_
| - Windows 10 Version 1809 or later (64-bit) <br/> - Ubuntu 22.04/Debian or newer, Arch Linux, or other distro (64-bit) <br/> - macOS 10.14 | - Supports SSE4.1 <br/> - [PassMark Thread Performance](https://www.cpubenchmark.net/CPU_mega_page.html) rating near or greater than 1500<br/> - Two physical cores, with hyperthreading | - Direct3D 11 (Feature Level 11.0) support <br/> - OpenGL 3.3 support <br/> - Vulkan 1.1 support <br/> - Metal support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 3000 (Geforce GTX 750, Radeon RX 560, Intel Arc A380) <br/> - 2 GB Video Memory | 4 GB |
### Recommended
| Operating System | CPU | GPU | RAM |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| - Windows 10 22H2 (64-bit) <br/> - Ubuntu 23.04/Debian or newer, Arch Linux, or other distro (64-bit) <br/> - macOS 10.14 | - Supports AVX2 <br/> - [PassMark Single Thread Performance](https://www.cpubenchmark.net/CPU_mega_page.html) rating near or greater than 2000<br/> - Four physical cores, with or without hyperthreading | - Direct3D12 support <br/> - OpenGL 4.6 support <br/> - Vulkan 1.3 support <br/> - Metal support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 6000 (GeForce GTX 1650, Radeon RX 570) <br/> - 4 GB Video Memory | 8 GB |
### Heavy
| Operating System | CPU | GPU | RAM |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| - Windows 10 22H2 (64-bit) <br/> - Ubuntu 23.04/Debian or newer, Arch Linux, or other distro (64-bit) <br/> - macOS 10.14 | - Supports AVX2 <br/> - [PassMark Single Thread Performance](https://www.cpubenchmark.net/CPU_mega_page.html) rating near or greater than 2600<br/> - Four physical cores, with or without hyperthreading | - Direct3D12 support <br/> - OpenGL 4.6 support <br/> - Vulkan 1.3 support <br/> - Metal support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 6000 (GeForce GTX 1650, Radeon RX 570) <br/> - 4 GB Video Memory | 8 GB |
_Note: Recommended GPU is based on 3x Internal, ~1080p resolution requirements. Higher resolutions will require stronger cards; 6x Internal, ~4K resolution will require a [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 12000 (GeForce RTX 2060 Radeon RX 6600 Intel Arc A750). Just like CPU requirements, this is also highly game dependent. A quick reference for GPU **intensive games**: [Wiki](https://wiki.pcsx2.net/Category:GPU_intensive_games)_
_Note1: 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)_
_Note2: Recommended GPU is based on 3x Internal, ~1080p resolution requirements. Higher resolutions will require stronger cards; 6x Internal, ~4K resolution will require a [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 12000 (GeForce RTX 2060 Radeon RX 6600 Intel Arc A750). Just like CPU requirements, this is also highly game dependent. A quick reference for GPU **intensive games**: [Wiki](https://wiki.pcsx2.net/Category:GPU_intensive_games)_
### Technical Notes
+4569 -244
View File
File diff suppressed because it is too large Load Diff
+38 -23
View File
@@ -83,6 +83,7 @@
03000000c01100000355000000000000,Acrux,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,
03000000fa190000f0ff000000000000,Acteck AGJ 3200,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000d1180000402c000000000000,ADT1,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a3,rightx:a2,righty:a5,x:b3,y:b4,platform:Windows,
030000006f0e00008801000000000000,Afterglow Deluxe Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000341a00003608000000000000,Afterglow 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,
030000006f0e00000263000000000000,Afterglow 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,
030000006f0e00001101000000000000,Afterglow 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,
@@ -182,8 +183,9 @@
03000000101c0000181c000000000000,Essential,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b4,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
030000008f0e00000f31000000000000,EXEQ,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:b3,y:b2,platform:Windows,
03000000341a00000108000000000000,EXEQ RF Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000006f0e00008401000000000000,Faceoff Deluxe Nintendo Switch 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,
030000006f0e00008001000000000000,Faceoff Pro Nintendo Switch 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,
030000006f0e00008401000000000000,Faceoff Deluxe Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00008101000000000000,Faceoff Deluxe Pro Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00008001000000000000,Faceoff Pro Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000021000000090000000000000,FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
0300000011040000c600000000000000,FC801,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
03000000852100000201000000000000,FF GP1,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,
@@ -295,7 +297,6 @@
03000000ad1b000002f5000000000000,Hori Real Arcade Pro VX,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Windows,
030000000d0f00009c00000000000000,Hori TAC Pro,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:Windows,
030000000d0f0000c900000000000000,Hori Taiko 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,
030000000d0f0000c100000000000000,Horipad,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,
030000000d0f00006400000000000000,Horipad 3TP,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:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00001300000000000000,Horipad 3W,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:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00005500000000000000,Horipad 4 FPS,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:Windows,
@@ -304,6 +305,8 @@
030000000d0f00004200000000000000,Horipad A,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:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000ad1b000001f5000000000000,Horipad EXT2,a:b0,b:b1,back:b6,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:b7,x:b2,y:b3,platform:Windows,
030000000d0f0000ee00000000000000,Horipad Mini 4,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:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f0000c100000000000000,Horipad Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f0000f600000000000000,Horipad Nintendo Switch Controller,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,
030000000d0f00006700000000000000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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:Windows,
030000000d0f0000dc00000000000000,Horipad Switch,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,
03000000242e00000b20000000000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Windows,
@@ -315,6 +318,7 @@
03000000d81d00001000000000000000,iBuffalo BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
030000005c0a00000285000000000000,iDroidCon,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b6,platform:Windows,
03000000696400006964000000000000,iDroidCon 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,
03000000511d00000230000000000000,iGUGU Gamecore,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b1,leftstick:b4,lefttrigger:b3,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b2,platform:Windows,
03000000b50700001403000000000000,Impact Black,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
030000006f0e00002401000000000000,Injustice Fightstick PS3 Controller,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:Windows,
03000000830500005130000000000000,InterAct ActionPad,a:b0,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
@@ -454,7 +458,7 @@
03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,
03000000120c0000f60e000000000000,P4 Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
030000006f0e00008501000000000000,PDP Fightpad Pro,a:b2,b:b3,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:b1,y:b0,platform:Windows,
030000006f0e00008501000000000000,PDP Fightpad Pro GameCube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000006f0e00000901000000000000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000008f0e00004100000000000000,PlaySega,a:b1,b:b0,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b4,y:b3,platform:Windows,
03000000666600006706000000000000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,
@@ -464,9 +468,14 @@
03000000f0250000c183000000000000,PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d9040000160f000000000000,PlayStation Controller Adapter,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:Windows,
030000004c0500003713000000000000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000d620000011a7000000000000,PowerA Core Plus GameCube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000dd62000015a7000000000000,PowerA Fusion Nintendo Switch 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:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d620000012a7000000000000,PowerA Fusion Nintendo Switch Fight Pad,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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000dd62000016a7000000000000,PowerA Fusion Pro Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d620000013a7000000000000,PowerA Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d62000006dca000000000000,PowerA Pro Ex,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,
0300000062060000d570000000000000,PowerA PS3 Controller,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:b0,y:b3,platform:Windows,
03000000d620000013a7000000000000,PowerA Switch 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,
03000000d620000014a7000000000000,PowerA Spectra Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006d04000084ca000000000000,Precision,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
03000000d62000009557000000000000,Pro Elite 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,
03000000c62400001a53000000000000,Pro Ex Mini,a:b0,b:b1,back:b6,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:b7,x:b2,y:b3,platform:Windows,
@@ -583,10 +592,10 @@
030000006f0e00001f01000000000000,Rock Candy,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,
030000006f0e00004601000000000000,Rock Candy,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,
03000000c6240000fefa000000000000,Rock Candy 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:Windows,
030000006f0e00008701000000000000,Rock Candy Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
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,
030000006f0e00008701000000000000,Rock Candy Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,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,
@@ -657,8 +666,6 @@
030000001f08000001e4000000000000,Super Famicom Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000790000000418000000000000,Super Famicom Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
03000000341200001300000000000000,Super Racer,a:b2,b:b3,back:b8,leftshoulder:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b7,x:b0,y:b1,platform:Windows,
03000000d620000011a7000000000000,Switch 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,
030000000d0f0000f600000000000000,Switch Hori Pad,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,
03000000457500002211000000000000,Szmy Power PC Gamepad,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,
030000004f0400000ab1000000000000,T16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows,
030000000d0f00007b00000000000000,TAC GEAR,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:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -844,7 +851,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
030000006e0500000720000010020000,Elecom JC-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:Mac OS X,
030000006f0e00008401000003010000,Faceoff Premiere Wired Pro Controller for Nintendo Switch,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:b13,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006f0e00008401000003010000,Faceoff Deluxe Nintendo Switch 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:b13,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000151900004000000001000000,Flydigi Vader 2,a:b14,b:b15,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Mac OS X,
03000000b40400001124000001040000,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,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000b40400001224000003030000,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,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
@@ -871,7 +878,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f00004d00000000000000,Hori Gem Pad 3,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,
030000000d0f00003801000008010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Mac OS X,
030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro,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,
030000000d0f0000aa00000072050000,Hori Real Arcade Pro,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:Mac OS X,
030000000d0f0000aa00000072050000,Hori Real Arcade Pro for Nintendo Switch,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:Mac OS X,
030000000d0f00000002000015010000,Hori Switch Split Pad Pro,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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006e00000000010000,Horipad 4 PS3,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,
030000000d0f00006600000000010000,Horipad 4 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,
@@ -920,8 +927,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000632500007505000000020000,NeoGeo mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000921200004b46000003020000,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:Mac OS X,
030000001008000001e5000006010000,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:Mac OS X,
03000000d620000011a7000000020000,Nintendo Switch 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:Mac OS X,
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,
050000007e05000009200000ff070000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,platform:Mac OS X,
@@ -934,6 +939,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000666600006706000088020000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Mac OS X,
030000004c050000da0c000000010000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
030000004c0500003713000000010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000d620000011a7000000020000,PowerA Core Plus Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000d620000011a7000010050000,PowerA Nintendo Switch 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,
03000000d62000006dca000000010000,PowerA Pro Ex,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,
03000000100800000300000006010000,PS2 Adapter,a:b2,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
@@ -970,8 +977,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006b140000010d000000010000,Revolution Pro 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,
030000006b140000130d000000010000,Revolution Pro Controller 3,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,
030000004c0500006802000002100000,Rii RK707,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b2,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b3,righttrigger:b9,rightx:a2,righty:a3,start:b1,x:b15,y:b12,platform:Mac OS X,
030000006f0e00008701000005010000,Rock Candy Nintendo Switch 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:Mac OS X,
03000000c6240000fefa000000000000,Rock Candy PS3,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,
030000006f0e00008701000005010000,Rock Candy Switch 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:Mac OS X,
03000000e804000000a000001b010000,Samsung EIGP20,a:b1,b:b3,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b11,leftx:a1,lefty:a3,rightshoulder:b12,rightx:a4,righty:a5,start:b16,x:b7,y:b9,platform:Mac OS X,
03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Mac OS X,
03000000a30c00002500000006020000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Mac OS X,
@@ -1065,10 +1072,10 @@ 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,
03000000c82d00000751000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,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,
03000000c82d00000631000014010000,8BitDo Pro 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,
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,
03000000c82d00001030000011010000,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,
03000000c82d00000020000000000000,8BitDo Pro 2 for Xbox,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,
06000000c82d00000020000006010000,8BitDo Pro 2 for Xbox,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,
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,
@@ -1094,9 +1101,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000c82d00000261000000010000,8BitDo SN30 Pro Plus,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:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00001230000000010000,8BitDo Ultimate,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,
03000000c82d00001730000011010000,8BitDo Ultimate C,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,
03000000c82d00001530000011010000,8BitDo Ultimate C,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,
03000000c82d00001630000011010000,8BitDo Ultimate C,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,
03000000c82d00001730000011010000,8BitDo Ultimate C,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,
03000000c82d00001130000011010000,8BitDo Ultimate Wired,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:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000c82d00000760000011010000,8BitDo Ultimate Wireless,a:b1,b:b0,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:b4,y:b3,platform:Linux,
03000000c82d00001230000011010000,8BitDo Ultimate Wireless,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,
@@ -1109,6 +1116,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000005e040000e002000030110000,8BitDo Zero 2,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
03000000c01100000355000011010000,Acrux Gamepad,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,
030000006f0e00008801000011010000,Afterglow Deluxe Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00003901000000430000,Afterglow Prismatic 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,
030000006f0e00003901000013020000,Afterglow Prismatic Controller 048-007-NA,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,
030000006f0e00001302000000010000,Afterglow 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,
@@ -1160,6 +1168,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
030000007d0400000640000010010000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,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,
030000006f0e00008401000011010000,Faceoff Deluxe Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00008101000011010000,Faceoff Deluxe Pro Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00008001000011010000,Faceoff Pro Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03005036852100000201000010010000,Final Fantasy XIV Online 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: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,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000b40400001224000011010000,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,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
@@ -1209,18 +1220,18 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000ad1b000001f5000033050000,Hori Pad EX Turbo 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,
030000000d0f00003801000011010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Linux,
030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro,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:Linux,
030000000d0f0000aa00000011010000,Hori Real Arcade Pro,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,
030000000d0f00001100000011010000,Hori Real Arcade Pro 3,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,
030000000d0f00002200000011010000,Hori Real Arcade Pro 3,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,
030000000d0f00006a00000011010000,Hori Real Arcade Pro 4,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:Linux,
030000000d0f00006b00000011010000,Hori Real Arcade Pro 4,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,
030000000d0f00001600000000010000,Hori Real Arcade Pro EXSE,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f0000aa00000011010000,Hori Real Arcade Pro for Nintendo Switch,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,
030000000d0f00008501000015010000,Hori Switch Split Pad Pro,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,
030000000d0f00006e00000011010000,Horipad 4 PS3,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,
030000000d0f00006600000011010000,Horipad 4 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:Linux,
030000000d0f0000ee00000011010000,Horipad Mini 4,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:a5,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f0000c100000011010000,Horipad Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00006700000001010000,Horipad 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,
030000000d0f0000c100000011010000,Horipad S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,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,
050000000d0f0000f600000001000000,Horipad 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,
03000000341a000005f7000010010000,HuiJia GameCube Controller Adapter,a:b1,b:b2,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:b0,y:b3,platform:Linux,
05000000242e00000b20000001000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Linux,
@@ -1343,8 +1354,6 @@ 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,misc1:b4,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,misc1:b13,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,
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,
030000007e0500000920000000026803,Nintendo Switch Pro Controller,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,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,misc1:b4,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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
@@ -1376,9 +1385,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e00006401000001010000,PDP Battlefield 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,
030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,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,
030000006f0e00003101000000010000,PDP EA Sports 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,
030000006f0e00008001000011010000,PDP Faceoff Nintendo Switch Pro 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,
030000006f0e00008501000011010000,PDP Fightpad Pro Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000006f0e0000c802000012010000,PDP Kingdom Hearts 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,
030000006f0e00008501000011010000,PDP Nintendo Switch Fightpad Pro,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,
030000006f0e00002801000011010000,PDP PS3 Rock Candy 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:Linux,
030000006f0e00000901000011010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000ad1b000004f9000000010000,PDP Xbox 360 Versus Fighting,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,
@@ -1392,9 +1400,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000c62400000053000000010000,PowerA,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,
03000000c62400003a54000001010000,PowerA 1428124-01,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,
03000000d620000011a7000011010000,PowerA Core Plus Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000dd62000015a7000011010000,PowerA Fusion Nintendo Switch 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:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000d620000012a7000011010000,PowerA Fusion Nintendo Switch Fight Pad,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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000d62000000140000001010000,PowerA Fusion Pro 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
03000000dd62000016a7000000000000,PowerA Fusion Pro Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000c62400001a53000000010000,PowerA Mini Pro Ex,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,
03000000d620000013a7000011010000,PowerA Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000d62000006dca000011010000,PowerA Pro Ex,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,
03000000d620000014a7000011010000,PowerA Spectra Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000c62400001a58000001010000,PowerA 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,
03000000d62000000220000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
03000000d62000000228000001010000,PowerA Xbox One 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,
@@ -1462,6 +1476,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000321500000009000011010000,Razer Serval,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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
050000003215000000090000163a0000,Razer Serval,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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
0300000032150000030a000001010000,Razer Wildcat,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,
03000000321500000b10000011010000,Razer Wolverine 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:Linux,
03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux,
190000004b4800000111000000010000,RetroGame Joypad,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,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,
0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux,
@@ -1471,8 +1486,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006b140000010d000011010000,Revolution Pro 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:Linux,
030000006b140000130d000011010000,Revolution Pro Controller 3,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:Linux,
030000006f0e00001f01000000010000,Rock Candy,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,
030000006f0e00008701000011010000,Rock Candy Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00001e01000011010000,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:Linux,
030000006f0e00008701000011010000,Rock Candy Switch Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,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,
03000000c6240000fefa000000010000,Rock Candy 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,
030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,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,
03000000a306000023f6000011010000,Saitek Cyborg V1 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
+5 -69
View File
@@ -13,14 +13,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(SHADER_MODEL) || defined(FXAA_GLSL_130) || defined(FXAA_GLSL_VK) || defined(__METAL_VERSION__)
#ifndef SHADER_MODEL
#define SHADER_MODEL 0
#endif
#ifndef FXAA_HLSL_4
#define FXAA_HLSL_4 0
#endif
#ifndef FXAA_HLSL_5
#define FXAA_HLSL_5 0
#endif
@@ -51,7 +43,7 @@ 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)
#elif (FXAA_HLSL_5 == 1)
Texture2D Texture : register(t0);
SamplerState TextureSampler : register(s0);
@@ -80,26 +72,6 @@ static constexpr sampler MAIN_SAMPLER(coord::normalized, address::clamp_to_edge,
[FXAA CODE SECTION]
------------------------------------------------------------------------------*/
// We don't use gather4 for alpha/luminance because it would require an additional
// pass to compute the values, which would be slower than the extra shader loads.
#if (SHADER_MODEL >= 0x500)
#undef FXAA_HLSL_5
#define FXAA_HLSL_5 1
#define FXAA_GATHER4_ALPHA 0
#elif (SHADER_MODEL >= 0x400)
#undef FXAA_HLSL_4
#define FXAA_HLSL_4 1
#define FXAA_GATHER4_ALPHA 0
#elif (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
#define FXAA_GATHER4_ALPHA 0
#elif defined(__METAL_VERSION__)
#define FXAA_GATHER4_ALPHA 0
#endif
#if (FXAA_HLSL_5 == 1)
struct FxaaTex { SamplerState smpl; Texture2D tex; };
#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
@@ -109,13 +81,6 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; };
#define FxaaDiscard clip(-1)
#define FxaaSat(x) saturate(x)
#elif (FXAA_HLSL_4 == 1)
struct FxaaTex { SamplerState smpl; Texture2D tex; };
#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
#define FxaaDiscard clip(-1)
#define FxaaSat(x) saturate(x)
#elif (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
#define int2 ivec2
#define float2 vec2
@@ -127,12 +92,6 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; };
#define FxaaTexTop(t, p) textureLod(t, p, 0.0)
#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
#if (FXAA_GATHER4_ALPHA == 1)
// use #extension GL_ARB_gpu_shader5 : enable
#define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
#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)
@@ -221,21 +180,6 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
posM.x = pos.x;
posM.y = pos.y;
#if (FXAA_GATHER4_ALPHA == 1)
float4 rgbyM = FxaaTexTop(tex, posM);
float4 luma4A = FxaaTexAlpha4(tex, posM);
float4 luma4B = FxaaTexOffAlpha4(tex, posM, int2(-1, -1));
rgbyM.w = RGBLuminance(rgbyM.xyz);
#define lumaM rgbyM.w
#define lumaE luma4A.z
#define lumaS luma4A.x
#define lumaSE luma4A.y
#define lumaNW luma4B.w
#define lumaN luma4B.z
#define lumaW luma4B.x
#else
float4 rgbyM = FxaaTexTop(tex, posM);
rgbyM.w = RGBLuminance(rgbyM.xyz);
#define lumaM rgbyM.w
@@ -244,7 +188,6 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
float lumaE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1, 0), fxaaRcpFrame.xy));
float lumaN = FxaaLuma(FxaaTexOff(tex, posM, int2( 0,-1), fxaaRcpFrame.xy));
float lumaW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1, 0), fxaaRcpFrame.xy));
#endif
float maxSM = max(lumaS, lumaM);
float minSM = min(lumaS, lumaM);
@@ -264,15 +207,10 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
if(earlyExit) { return rgbyM; }
#endif
#if (FXAA_GATHER4_ALPHA == 0)
float lumaNW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1,-1), fxaaRcpFrame.xy));
float lumaSE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1, 1), fxaaRcpFrame.xy));
float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1,-1), fxaaRcpFrame.xy));
float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1, 1), fxaaRcpFrame.xy));
#else
float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1,-1), fxaaRcpFrame.xy));
float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1, 1), fxaaRcpFrame.xy));
#endif
float lumaNS = lumaN + lumaS;
float lumaWE = lumaW + lumaE;
@@ -518,14 +456,14 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
#if (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
float4 FxaaPass(float4 FxaaColor, float2 uv0)
#elif (SHADER_MODEL >= 0x400)
#elif (FXAA_HLSL_5 == 1)
float4 FxaaPass(float4 FxaaColor : COLOR0, float2 uv0 : TEXCOORD0)
#elif defined(__METAL_VERSION__)
float4 FxaaPass(float4 FxaaColor, float2 uv0, texture2d<float> tex)
#endif
{
#if (SHADER_MODEL >= 0x400)
#if (FXAA_HLSL_5 == 1)
FxaaTex tex;
tex.tex = Texture;
tex.smpl = TextureSampler;
@@ -559,8 +497,8 @@ void main()
SV_Target0 = float4(color.rgb, 1.0);
}
#elif (SHADER_MODEL >= 0x400)
PS_OUTPUT ps_main(VS_OUTPUT input)
#elif (FXAA_HLSL_5 == 1)
PS_OUTPUT main(VS_OUTPUT input)
{
PS_OUTPUT output;
@@ -576,5 +514,3 @@ PS_OUTPUT ps_main(VS_OUTPUT input)
// Metal main function in in fxaa.metal
#endif
#endif
-4
View File
@@ -13,8 +13,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
struct VS_INPUT
{
float4 p : POSITION;
@@ -413,5 +411,3 @@ float ps_stencil_image_init_1(PS_INPUT input) : SV_Target
c = float(0x7FFFFFFF);
return c;
}
#endif
-4
View File
@@ -13,8 +13,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
Texture2D Texture;
SamplerState Sampler;
@@ -195,5 +193,3 @@ float4 ps_main4(PS_INPUT input) : SV_Target0
return float4(0.0f, 0.0f, 0.0f, 0.0f);
}
#endif
-3
View File
@@ -13,8 +13,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
Texture2D Texture;
SamplerState Sampler;
@@ -45,4 +43,3 @@ float4 ps_main1(PS_INPUT input) : SV_Target0
c.a = BGColor.a;
return c;
}
#endif
-8
View File
@@ -13,12 +13,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
#ifndef PS_SCALE_FACTOR
#define PS_SCALE_FACTOR 1
#endif
struct VS_INPUT
{
float4 p : POSITION;
@@ -451,5 +445,3 @@ PS_OUTPUT ps_automagical_supersampling(PS_INPUT input)
output.c = float4(col / div, 1);
return output;
}
#endif
-4
View File
@@ -13,8 +13,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
Texture2D Texture;
SamplerState Sampler;
@@ -64,5 +62,3 @@ float4 ps_main(PS_INPUT input) : SV_Target0
float4 c = Texture.Sample(Sampler, input.t);
return ContrastSaturationBrightness(c);
}
#endif
+26 -21
View File
@@ -52,6 +52,7 @@
#define PS_POINT_SAMPLER 0
#define PS_REGION_RECT 0
#define PS_SHUFFLE 0
#define PS_SHUFFLE_SAME 0
#define PS_READ_BA 0
#define PS_READ16_SRC 0
#define PS_DFMT 0
@@ -661,7 +662,7 @@ float4 sample_color(float2 st, float uv_w)
float4 tfx(float4 T, float4 C)
{
float4 C_out;
float4 FxT = trunc(trunc(C) * T / 128.0f);
float4 FxT = trunc((C * T) / 128.0f);
#if (PS_TFX == 0)
C_out = FxT;
@@ -940,8 +941,17 @@ PS_OUTPUT ps_main(PS_INPUT input)
{
uint4 denorm_c = uint4(C);
uint2 denorm_TA = uint2(float2(TA.xy) * 255.0f + 0.5f);
if (PS_READ16_SRC)
// Special case for 32bit input and 16bit output, shuffle used by The Godfather
if (PS_SHUFFLE_SAME)
{
if (PS_READ_BA)
C = (float4)(float((denorm_c.b & 0x7Fu) | (denorm_c.a & 0x80u)));
else
C.ga = C.rg;
}
// Copy of a 16bit source in to this target
else if (PS_READ16_SRC)
{
C.rb = (float2)float((denorm_c.r >> 3) | (((denorm_c.g >> 3) & 0x7u) << 5));
if (denorm_c.a & 0x80u)
@@ -949,28 +959,23 @@ PS_OUTPUT ps_main(PS_INPUT input)
else
C.ga = (float2)float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.x & 0x80u));
}
// Write RB part. Mask will take care of the correct destination
else if (PS_READ_BA)
{
C.rb = C.bb;
if (denorm_c.a & 0x80u)
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.x & 0x80u)));
}
else
{
// Mask will take care of the correct destination
if (PS_READ_BA)
C.rb = C.bb;
else
C.rb = C.rr;
C.rb = C.rr;
if (denorm_c.g & 0x80u)
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.y & 0x80u)));
if (PS_READ_BA)
{
if (denorm_c.a & 0x80u)
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.x & 0x80u)));
}
else
{
if (denorm_c.g & 0x80u)
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.x & 0x80u)));
}
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.x & 0x80u)));
}
}
+21 -15
View File
@@ -614,7 +614,7 @@ vec4 sample_color(vec2 st)
vec4 tfx(vec4 T, vec4 C)
{
vec4 C_out;
vec4 FxT = trunc(trunc(C) * T / 128.0f);
vec4 FxT = trunc((C * T) / 128.0f);
#if (PS_TFX == 0)
C_out = FxT;
@@ -779,17 +779,19 @@ float As = As_rgba.a;
return;
#endif
vec3 Cs = Color.rgb;
#if SW_BLEND_NEEDS_RT
vec4 RT = trunc(fetch_rt() * 255.0f + 0.1f);
#else
// Not used, but we define it to make the selection below simpler.
vec4 RT = vec4(0.0f);
#endif
// FIXME FMT_16 case
// FIXME Ad or Ad * 2?
float Ad = RT.a / 128.0f;
// Let the compiler do its jobs !
vec3 Cd = RT.rgb;
#endif
vec3 Cs = Color.rgb;
#if PS_BLEND_A == 0
vec3 A = Cs;
@@ -950,26 +952,30 @@ void ps_main()
#if PS_SHUFFLE
uvec4 denorm_c = uvec4(C);
uvec2 denorm_TA = uvec2(vec2(TA.xy) * 255.0f + 0.5f);
#if PS_READ16_SRC
// Special case for 32bit input and 16bit output, shuffle used by The Godfather
#if PS_SHUFFLE_SAME
#if (PS_READ_BA)
C = vec4(float((denorm_c.b & 0x7Fu) | (denorm_c.a & 0x80u)));
#else
C.ga = C.rg;
#endif
// Copy of a 16bit source in to this target
#elif PS_READ16_SRC
C.rb = vec2(float((denorm_c.r >> 3) | (((denorm_c.g >> 3) & 0x7u) << 5)));
if (bool(denorm_c.a & 0x80u))
C.ga = vec2(float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.y & 0x80u)));
else
C.ga = vec2(float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.x & 0x80u)));
#else
// Write RB part. Mask will take care of the correct destination
#if PS_READ_BA
// Write RB part. Mask will take care of the correct destination
#elif PS_READ_BA
C.rb = C.bb;
#else
C.rb = C.rr;
#endif
// FIXME precompute my_TA & 0x80
// Write GA part. Mask will take care of the correct destination
// Note: GLSL 4.50/GL_EXT_shader_integer_mix support a mix instruction to select a component\n"
// However Nvidia emulate it with an if (at least on kepler arch) ...\n"
#if PS_READ_BA
// bit field operation requires GL4 HW. Could be nice to merge it with step/mix below
// uint my_ta = (bool(bitfieldExtract(denorm_c.a, 7, 1))) ? denorm_TA.y : denorm_TA.x;
// denorm_c.a = bitfieldInsert(denorm_c.a, bitfieldExtract(my_ta, 7, 1), 7, 1);
@@ -981,6 +987,7 @@ void ps_main()
C.ga = vec2(float((denorm_c.a & 0x7Fu) | (denorm_TA.x & 0x80u)));
#else
C.rb = C.rr;
if (bool(denorm_c.g & 0x80u))
C.ga = vec2(float((denorm_c.g & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
@@ -992,9 +999,8 @@ void ps_main()
// float sel = step(128.0f, c.g);
// vec2 c_shuffle = vec2((denorm_c.gg & 0x7Fu) | (denorm_TA & 0x80u));
// c.ga = mix(c_shuffle.xx, c_shuffle.yy, sel);
#endif // PS_READ_BA
#endif // READ16_SRC
#endif // PS_SHUFFLE_SAME
#endif // PS_SHUFFLE
// Must be done before alpha correction
+31 -26
View File
@@ -277,7 +277,9 @@ void main()
#define PS_TCOFFSETHACK 0
#define PS_POINT_SAMPLER 0
#define PS_SHUFFLE 0
#define PS_SHUFFLE_SAME 0
#define PS_READ_BA 0
#define PS_WRITE_RG 0
#define PS_READ16_SRC 0
#define PS_DFMT 0
#define PS_DEPTH_FMT 0
@@ -300,7 +302,7 @@ void main()
#endif
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
#define SW_BLEND_NEEDS_RT (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1)
#define SW_BLEND_NEEDS_RT (SW_BLEND && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1))
#define SW_AD_TO_HW (PS_BLEND_C == 1 && PS_A_MASKED)
#define PS_FEEDBACK_LOOP_IS_NEEDED (PS_TEX_IS_FB == 1 || PS_FBMASK || SW_BLEND_NEEDS_RT || (PS_DATE >= 5))
@@ -352,16 +354,16 @@ layout(set = 1, binding = 1) uniform texture2D Palette;
#if PS_FEEDBACK_LOOP_IS_NEEDED
#if defined(DISABLE_TEXTURE_BARRIER) || defined(HAS_FEEDBACK_LOOP_LAYOUT)
layout(set = 2, binding = 0) uniform texture2D RtSampler;
layout(set = 1, binding = 2) uniform texture2D RtSampler;
vec4 sample_from_rt() { return texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0); }
#else
layout(input_attachment_index = 0, set = 2, binding = 0) uniform subpassInput RtSampler;
layout(input_attachment_index = 0, set = 1, binding = 2) uniform subpassInput RtSampler;
vec4 sample_from_rt() { return subpassLoad(RtSampler); }
#endif
#endif
#if PS_DATE > 0
layout(set = 2, binding = 1) uniform texture2D PrimMinTexture;
layout(set = 1, binding = 3) uniform texture2D PrimMinTexture;
#endif
#if NEEDS_TEX
@@ -849,7 +851,7 @@ vec4 sample_color(vec2 st)
vec4 tfx(vec4 T, vec4 C)
{
vec4 C_out;
vec4 FxT = trunc(trunc(C) * T / 128.0f);
vec4 FxT = trunc((C * T) / 128.0f);
#if (PS_TFX == 0)
C_out = FxT;
@@ -1197,33 +1199,36 @@ void main()
#if PS_SHUFFLE
uvec4 denorm_c = uvec4(C);
uvec2 denorm_TA = uvec2(vec2(TA.xy) * 255.0f + 0.5f);
#if PS_READ16_SRC
// Special case for 32bit input and 16bit output, shuffle used by The Godfather
#if PS_SHUFFLE_SAME
#if (PS_READ_BA)
C = vec4(float((denorm_c.b & 0x7Fu) | (denorm_c.a & 0x80u)));
#else
C.ga = C.rg;
#endif
// Copy of a 16bit source in to this target
#elif PS_READ16_SRC
C.rb = vec2(float((denorm_c.r >> 3) | (((denorm_c.g >> 3) & 0x7u) << 5)));
if ((denorm_c.a & 0x80u) != 0u)
C.ga = vec2(float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.y & 0x80u)));
else
C.ga = vec2(float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.x & 0x80u)));
// Write RB part. Mask will take care of the correct destination
#elif PS_READ_BA
C.rb = C.bb;
if ((denorm_c.a & 0x80u) != 0u)
C.ga = vec2(float((denorm_c.a & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = vec2(float((denorm_c.a & 0x7Fu) | (denorm_TA.x & 0x80u)));
#else
// Mask will take care of the correct destination
#if PS_READ_BA
C.rb = C.bb;
#else
C.rb = C.rr;
#endif
#if PS_READ_BA
if ((denorm_c.a & 0x80u) != 0u)
C.ga = vec2(float((denorm_c.a & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = vec2(float((denorm_c.a & 0x7Fu) | (denorm_TA.x & 0x80u)));
#else
if ((denorm_c.g & 0x80u) != 0u)
C.ga = vec2(float((denorm_c.g & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = vec2(float((denorm_c.g & 0x7Fu) | (denorm_TA.x & 0x80u)));
#endif
#endif
#endif
C.rb = C.rr;
if ((denorm_c.g & 0x80u) != 0u)
C.ga = vec2(float((denorm_c.g & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = vec2(float((denorm_c.g & 0x7Fu) | (denorm_TA.x & 0x80u)));
#endif // PS_SHUFFLE_SAME
#endif // PS_SHUFFLE
// Must be done before alpha correction
-8
View File
@@ -748,13 +748,6 @@ s64 FileSystem::FTell64(std::FILE* fp)
s64 FileSystem::FSize64(std::FILE* fp)
{
#ifdef _WIN32
const int fd = _fileno(fp);
if (fd >= 0)
{
return _filelengthi64(fd);
}
#else
const s64 pos = FTell64(fp);
if (pos >= 0)
{
@@ -765,7 +758,6 @@ s64 FileSystem::FSize64(std::FILE* fp)
return size;
}
}
#endif
return -1;
}
+1 -1
View File
@@ -110,7 +110,7 @@ struct crash_info_t
u64 reserved;
u64 reserved2;
};
#define CRASH_ANNOTATION __attribute__((section("__DATA,__crash_info")))
#define CRASH_ANNOTATION __attribute__((used, section("__DATA,__crash_info")))
#define CRASH_VERSION 4
extern "C" crash_info_t gCRAnnotations CRASH_ANNOTATION = { CRASH_VERSION };
#endif
+5 -5
View File
@@ -92,31 +92,31 @@ public:
return value;
}
__fi std::optional<int> GetOptionalIntValue(const char* section, const char* key, std::optional<int> default_value = std::nullopt)
__fi std::optional<int> GetOptionalIntValue(const char* section, const char* key, std::optional<int> default_value = std::nullopt) const
{
int ret;
return GetIntValue(section, key, &ret) ? std::optional<int>(ret) : default_value;
}
__fi std::optional<uint> GetOptionalUIntValue(const char* section, const char* key, std::optional<uint> default_value = std::nullopt)
__fi std::optional<uint> GetOptionalUIntValue(const char* section, const char* key, std::optional<uint> default_value = std::nullopt) const
{
uint ret;
return GetUIntValue(section, key, &ret) ? std::optional<uint>(ret) : default_value;
}
__fi std::optional<float> GetOptionalFloatValue(const char* section, const char* key, std::optional<float> default_value = std::nullopt)
__fi std::optional<float> GetOptionalFloatValue(const char* section, const char* key, std::optional<float> default_value = std::nullopt) const
{
float ret;
return GetFloatValue(section, key, &ret) ? std::optional<float>(ret) : default_value;
}
__fi std::optional<double> GetOptionalDoubleValue(const char* section, const char* key, std::optional<double> default_value = std::nullopt)
__fi std::optional<double> GetOptionalDoubleValue(const char* section, const char* key, std::optional<double> default_value = std::nullopt) const
{
double ret;
return GetDoubleValue(section, key, &ret) ? std::optional<double>(ret) : default_value;
}
__fi std::optional<bool> GetOptionalBoolValue(const char* section, const char* key, std::optional<bool> default_value = std::nullopt)
__fi std::optional<bool> GetOptionalBoolValue(const char* section, const char* key, std::optional<bool> default_value = std::nullopt) const
{
bool ret;
return GetBoolValue(section, key, &ret) ? std::optional<bool>(ret) : default_value;
+4
View File
@@ -643,7 +643,9 @@ bool unpack_bc7_mode0_2(uint32_t mode, const uint64_t* data_chunks, color_rgba*
const uint32_t ENDPOINT_BITS = (mode == 0) ? 4 : 5;
const uint32_t ENDPOINT_MASK = (1 << ENDPOINT_BITS) - 1;
const uint32_t PBITS = (mode == 0) ? 6 : 0;
#ifndef BC7DECOMP_USE_SSE2
const uint32_t WEIGHT_VALS = 1 << WEIGHT_BITS;
#endif
const uint32_t PART_BITS = (mode == 0) ? 4 : 6;
const uint32_t PART_MASK = (1 << PART_BITS) - 1;
@@ -740,7 +742,9 @@ bool unpack_bc7_mode1_3_7(uint32_t mode, const uint64_t* data_chunks, color_rgba
const uint32_t ENDPOINT_MASK = (1 << ENDPOINT_BITS) - 1;
const uint32_t PBITS = (mode == 1) ? 2 : 4;
const uint32_t SHARED_PBITS = (mode == 1) ? true : false;
#ifndef BC7DECOMP_USE_SSE2
const uint32_t WEIGHT_VALS = 1 << WEIGHT_BITS;
#endif
const uint64_t low_chunk = data_chunks[0];
const uint64_t high_chunk = data_chunks[1];
+12 -5
View File
@@ -48,7 +48,7 @@
#include "pcsx2/Input/InputManager.h"
#include "pcsx2/LogSink.h"
#include "pcsx2/MTGS.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "pcsx2/SIO/Pad/Pad.h"
#include "pcsx2/PerformanceMetrics.h"
#include "pcsx2/VMManager.h"
@@ -85,11 +85,13 @@ static double s_last_render_passes = 0;
static double s_last_barriers = 0;
static double s_last_copies = 0;
static double s_last_uploads = 0;
static double s_last_readbacks = 0;
static u64 s_total_draws = 0;
static u64 s_total_render_passes = 0;
static u64 s_total_barriers = 0;
static u64 s_total_copies = 0;
static u64 s_total_uploads = 0;
static u64 s_total_readbacks = 0;
static u32 s_total_frames = 0;
bool GSRunner::InitializeConfig()
@@ -115,7 +117,7 @@ bool GSRunner::InitializeConfig()
si.SetStringValue("SPU2/Output", "OutputModule", "nullout");
// none of the bindings are going to resolve to anything
PAD::ClearPortBindings(si, 0);
Pad::ClearPortBindings(si, 0);
si.ClearSection("Hotkeys");
// make sure any gamesettings inis in your tree don't get loaded
@@ -255,7 +257,7 @@ void Host::OnInputDeviceDisconnected(const std::string_view& identifier)
{
}
void Host::SetRelativeMouseMode(bool enabled)
void Host::SetMouseMode(bool relative_mode, bool hide_cursor)
{
}
@@ -293,6 +295,7 @@ void Host::BeginPresentFrame()
update_stat(GSPerfMon::Barriers, s_total_barriers, s_last_barriers);
update_stat(GSPerfMon::TextureCopies, s_total_copies, s_last_copies);
update_stat(GSPerfMon::TextureUploads, s_total_uploads, s_last_uploads);
update_stat(GSPerfMon::Readbacks, s_total_readbacks, s_last_readbacks);
s_total_frames++;
std::atomic_thread_fence(std::memory_order_release);
}
@@ -382,12 +385,15 @@ void Host::RequestVMShutdown(bool allow_confirm, bool allow_save_state, bool def
VMManager::SetState(VMState::Stopping);
}
#ifdef ENABLE_ACHIEVEMENTS
void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason)
{
// noop
}
void Host::OnAchievementsRefreshed()
{
// noop
}
#endif
std::optional<u32> InputManager::ConvertHostKeyboardStringToCode(const std::string_view& str)
{
@@ -641,6 +647,7 @@ void GSRunner::DumpStats()
Console.WriteLn(fmt::format("@HWSTAT@ Barriers: {} (avg {})", s_total_barriers, static_cast<u64>(std::ceil(s_total_barriers / static_cast<double>(s_total_frames)))));
Console.WriteLn(fmt::format("@HWSTAT@ Copies: {} (avg {})", s_total_copies, static_cast<u64>(std::ceil(s_total_copies / static_cast<double>(s_total_frames)))));
Console.WriteLn(fmt::format("@HWSTAT@ Uploads: {} (avg {})", s_total_uploads, static_cast<u64>(std::ceil(s_total_uploads / static_cast<double>(s_total_frames)))));
Console.WriteLn(fmt::format("@HWSTAT@ Readbacks: {} (avg {})", s_total_readbacks, static_cast<u64>(std::ceil(s_total_readbacks / static_cast<double>(s_total_frames)))));
Console.WriteLn("============================================");
}
+19
View File
@@ -380,6 +380,8 @@ void AutoUpdaterDialog::getChangesComplete(QNetworkReply* reply)
changes_html.prepend(tr("<h2>Save State Warning</h2><p>Installing this update will make your save states "
"<b>incompatible</b>. Please ensure you have saved your games to a Memory Card "
"before installing this update or you will lose progress.</p>"));
m_update_will_break_save_states = true;
}
if (update_increases_settings_version)
@@ -407,6 +409,23 @@ void AutoUpdaterDialog::getChangesComplete(QNetworkReply* reply)
void AutoUpdaterDialog::downloadUpdateClicked()
{
if (m_update_will_break_save_states)
{
QMessageBox msgbox;
msgbox.setIcon(QMessageBox::Critical);
msgbox.setWindowTitle(tr("Savestate Warning"));
msgbox.setText(tr("<h1>WARNING</h1><p style='font-size:12pt;'>Installing this update will make your <b>save states incompatible</b>, <i>be sure to save any progress to your memory cards before proceeding</i>.</p><p>Do you wish to continue?</p>"));
msgbox.addButton(QMessageBox::Yes);
msgbox.addButton(QMessageBox::No);
msgbox.setDefaultButton(QMessageBox::No);
// This makes the box wider, for some reason sizing boxes in Qt is hard - Source: The internet.
QSpacerItem* horizontalSpacer = new QSpacerItem(500, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
QGridLayout* layout = (QGridLayout*)msgbox.layout();
layout->addItem(horizontalSpacer, layout->rowCount(), 0, 1, layout->columnCount());
if (msgbox.exec() != QMessageBox::Yes)
return;
}
m_display_messages = true;
QUrl url(m_download_url);
QNetworkRequest request(url);
+1
View File
@@ -134,6 +134,7 @@ target_sources(pcsx2-qt PRIVATE
Settings/SettingsDialog.ui
Settings/USBBindingWidget_DrivingForce.ui
Settings/USBBindingWidget_GTForce.ui
Settings/USBBindingWidget_GunCon2.ui
Debugger/CpuWidget.cpp
Debugger/CpuWidget.h
Debugger/CpuWidget.ui
+1 -1
View File
@@ -589,7 +589,7 @@ static std::vector<u32> searchWorkerByteArray(DebugInterface* cpu, u32 start, u3
bool hit = true;
for (qsizetype i = 0; i < value.length(); i++)
{
if (cpu->read8(addr + i) != value[i])
if (static_cast<char>(cpu->read8(addr + i)) != value[i])
{
hit = false;
break;
+4 -3
View File
@@ -151,9 +151,10 @@ void DisassemblyWidget::contextNoopInstruction()
void DisassemblyWidget::contextRunToCursor()
{
Host::RunOnCPUThread([&] { CBreakPoints::AddBreakPoint(m_cpu->getCpuType(), m_selectedAddressStart); });
m_cpu->resumeCpu();
Host::RunOnCPUThread([&] {
CBreakPoints::AddBreakPoint(m_cpu->getCpuType(), m_selectedAddressStart, true);
m_cpu->resumeCpu();
});
}
void DisassemblyWidget::contextJumpToCursor()
+1 -1
View File
@@ -78,7 +78,7 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
{
QString type("");
type += (mc->cond & MEMCHECK_READ) ? tr("Read") : "";
type += ((mc->cond & MEMCHECK_BOTH) == MEMCHECK_BOTH) ? ", " : " ";
type += ((mc->cond & MEMCHECK_READWRITE) == MEMCHECK_READWRITE) ? ", " : " ";
//: (C) = changes, as in "look for changes".
type += (mc->cond & MEMCHECK_WRITE) ? (mc->cond & MEMCHECK_WRITE_ONCHANGE) ? tr("Write(C)") : tr("Write") : "";
return type;
+25 -6
View File
@@ -25,6 +25,7 @@
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "Settings/AchievementLoginDialog.h"
#include "Settings/ControllerSettingsDialog.h"
#include "Settings/GameListSettingsWidget.h"
#include "Settings/InterfaceSettingsWidget.h"
@@ -414,7 +415,7 @@ void MainWindow::connectVMThreadSignals(EmuThread* thread)
connect(thread, &EmuThread::onAcquireRenderWindowRequested, this, &MainWindow::acquireRenderWindow, Qt::BlockingQueuedConnection);
connect(thread, &EmuThread::onReleaseRenderWindowRequested, this, &MainWindow::releaseRenderWindow, Qt::BlockingQueuedConnection);
connect(thread, &EmuThread::onResizeRenderWindowRequested, this, &MainWindow::displayResizeRequested);
connect(thread, &EmuThread::onRelativeMouseModeRequested, this, &MainWindow::relativeMouseModeRequested);
connect(thread, &EmuThread::onMouseModeRequested, this, &MainWindow::mouseModeRequested);
connect(thread, &EmuThread::onVMStarting, this, &MainWindow::onVMStarting);
connect(thread, &EmuThread::onVMStarted, this, &MainWindow::onVMStarted);
connect(thread, &EmuThread::onVMPaused, this, &MainWindow::onVMPaused);
@@ -423,6 +424,7 @@ void MainWindow::connectVMThreadSignals(EmuThread* thread)
connect(thread, &EmuThread::onGameChanged, this, &MainWindow::onGameChanged);
connect(thread, &EmuThread::onCaptureStarted, this, &MainWindow::onCaptureStarted);
connect(thread, &EmuThread::onCaptureStopped, this, &MainWindow::onCaptureStopped);
connect(thread, &EmuThread::onAchievementsLoginRequested, this, &MainWindow::onAchievementsLoginRequested);
connect(m_ui.actionReset, &QAction::triggered, thread, &EmuThread::resetVM);
connect(m_ui.actionPause, &QAction::toggled, thread, &EmuThread::setVMPaused);
@@ -628,6 +630,14 @@ void MainWindow::onCaptureStopped()
m_ui.actionToolsVideoCapture->setChecked(false);
}
void MainWindow::onAchievementsLoginRequested(Achievements::LoginRequestReason reason)
{
auto lock = pauseAndLockVM();
AchievementLoginDialog dlg(this, reason);
dlg.exec();
}
void MainWindow::onSettingsTriggeredFromToolbar()
{
if (s_vm_valid)
@@ -887,7 +897,8 @@ bool MainWindow::isRenderingToMain() const
bool MainWindow::shouldHideMouseCursor() const
{
return (isRenderingFullscreen() && Host::GetBoolSettingValue("UI", "HideMouseCursor", false)) || m_relative_mouse_mode;
return ((isRenderingFullscreen() && Host::GetBoolSettingValue("UI", "HideMouseCursor", false)) ||
m_relative_mouse_mode || m_hide_mouse_cursor);
}
bool MainWindow::shouldHideMainWindow() const
@@ -2003,12 +2014,13 @@ void MainWindow::displayResizeRequested(qint32 width, qint32 height)
QtUtils::ResizePotentiallyFixedSizeWindow(this, width, height + extra_height);
}
void MainWindow::relativeMouseModeRequested(bool enabled)
void MainWindow::mouseModeRequested(bool relative_mode, bool hide_cursor)
{
if (m_relative_mouse_mode == enabled)
if (m_relative_mouse_mode == relative_mode && m_hide_mouse_cursor == hide_cursor)
return;
m_relative_mouse_mode = enabled;
m_relative_mouse_mode = relative_mode;
m_hide_mouse_cursor = hide_cursor;
if (m_display_widget && !s_vm_paused)
updateDisplayWidgetCursor();
}
@@ -2273,7 +2285,8 @@ void MainWindow::setGameListEntryCoverImage(const GameList::Entry* entry)
if (filename.isEmpty())
return;
if (!GameList::GetCoverImagePathForEntry(entry).empty())
const QString old_filename = QString::fromStdString(GameList::GetCoverImagePathForEntry(entry));
if (!old_filename.isEmpty())
{
if (QMessageBox::question(this, tr("Cover Already Exists"),
tr("A cover image for this game already exists, do you wish to replace it?"), QMessageBox::Yes,
@@ -2299,6 +2312,12 @@ void MainWindow::setGameListEntryCoverImage(const GameList::Entry* entry)
return;
}
if (!old_filename.isEmpty() && old_filename != new_filename && !QFile::remove(old_filename))
{
QMessageBox::critical(this, tr("Copy Error"), tr("Failed to remove '%1'").arg(old_filename));
return;
}
m_game_list_widget->refreshGridCovers();
}
+9 -1
View File
@@ -39,6 +39,11 @@ class ControllerSettingsDialog;
class EmuThread;
namespace Achievements
{
enum class LoginRequestReason;
}
namespace GameList
{
struct Entry;
@@ -124,7 +129,7 @@ private Q_SLOTS:
std::optional<WindowInfo> acquireRenderWindow(bool recreate_window, bool fullscreen, bool render_to_main, bool surfaceless);
void displayResizeRequested(qint32 width, qint32 height);
void relativeMouseModeRequested(bool enabled);
void mouseModeRequested(bool relative_mode, bool hide_cursor);
void releaseRenderWindow();
void focusDisplayWidget();
@@ -186,6 +191,8 @@ private Q_SLOTS:
void onCaptureStarted(const QString& filename);
void onCaptureStopped();
void onAchievementsLoginRequested(Achievements::LoginRequestReason reason);
protected:
void showEvent(QShowEvent* event) override;
void closeEvent(QCloseEvent* event) override;
@@ -293,6 +300,7 @@ private:
bool m_display_created = false;
bool m_relative_mouse_mode = false;
bool m_hide_mouse_cursor = false;
bool m_was_paused_on_surface_loss = false;
bool m_was_disc_change_request = false;
bool m_is_closing = false;
+16
View File
@@ -184,6 +184,10 @@
<property name="title">
<string>Input Recording</string>
</property>
<property name="icon">
<iconset theme="keyboard-line">
<normaloff>.</normaloff>.</iconset>
</property>
<addaction name="actionInputRecNew"/>
<addaction name="actionInputRecPlay"/>
<addaction name="actionInputRecStop"/>
@@ -863,6 +867,10 @@
<property name="text">
<string>Toggle Software Rendering</string>
</property>
<property name="icon">
<iconset theme="brush-line">
<normaloff>.</normaloff>.</iconset>
</property>
</action>
<action name="actionDebugger">
<property name="icon">
@@ -877,6 +885,10 @@
<property name="text">
<string>Reload Cheats/Patches</string>
</property>
<property name="icon">
<iconset theme="refresh-line">
<normaloff>.</normaloff>.</iconset>
</property>
</action>
<action name="actionEnableSystemConsole">
<property name="checkable">
@@ -914,6 +926,10 @@
<property name="text">
<string>Save Single Frame GS Dump</string>
</property>
<property name="icon">
<iconset theme="save-3-line">
<normaloff>.</normaloff>.</iconset>
</property>
</action>
<action name="actionInputRecNew">
<property name="enabled">
+8 -2
View File
@@ -1079,6 +1079,11 @@ void Host::OnSaveStateSaved(const std::string_view& filename)
}
#ifdef ENABLE_ACHIEVEMENTS
void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason)
{
emit g_emu_thread->onAchievementsLoginRequested(reason);
}
void Host::OnAchievementsRefreshed()
{
u32 game_id = 0;
@@ -1468,9 +1473,9 @@ void Host::OnInputDeviceDisconnected(const std::string_view& identifier)
emit g_emu_thread->onInputDeviceDisconnected(identifier.empty() ? QString() : QString::fromUtf8(identifier.data(), identifier.size()));
}
void Host::SetRelativeMouseMode(bool enabled)
void Host::SetMouseMode(bool relative_mode, bool hide_cursor)
{
emit g_emu_thread->onRelativeMouseModeRequested(enabled);
emit g_emu_thread->onMouseModeRequested(relative_mode, hide_cursor);
}
//////////////////////////////////////////////////////////////////////////
@@ -1778,6 +1783,7 @@ void QtHost::RegisterTypes()
qRegisterMetaType<InputBindingKey>();
qRegisterMetaType<CDVD_SourceType>();
qRegisterMetaType<const GameList::Entry*>();
qRegisterMetaType<Achievements::LoginRequestReason>();
}
bool QtHost::RunSetupWizard()
+10 -1
View File
@@ -41,11 +41,17 @@ struct VMBootParameters;
enum class CDVD_SourceType : uint8_t;
namespace Achievements
{
enum class LoginRequestReason;
}
Q_DECLARE_METATYPE(std::shared_ptr<VMBootParameters>);
Q_DECLARE_METATYPE(std::optional<bool>);
Q_DECLARE_METATYPE(GSRendererType);
Q_DECLARE_METATYPE(InputBindingKey);
Q_DECLARE_METATYPE(CDVD_SourceType);
Q_DECLARE_METATYPE(Achievements::LoginRequestReason);
class EmuThread : public QThread
{
@@ -119,7 +125,7 @@ Q_SIGNALS:
std::optional<WindowInfo> onAcquireRenderWindowRequested(bool recreate_window, bool fullscreen, bool render_to_main, bool surfaceless);
void onResizeRenderWindowRequested(qint32 width, qint32 height);
void onReleaseRenderWindowRequested();
void onRelativeMouseModeRequested(bool enabled);
void onMouseModeRequested(bool relative_mode, bool hide_cursor);
/// Called when the VM is starting initialization, but has not been completed yet.
void onVMStarting();
@@ -155,6 +161,9 @@ Q_SIGNALS:
/// just signifies that the save has started, not necessarily completed.
void onSaveStateSaved(const QString& path);
/// Called when achievements login is requested.
void onAchievementsLoginRequested(Achievements::LoginRequestReason reason);
/// Called when achievements are reloaded/refreshed (e.g. game change, login, option change).
void onAchievementsRefreshed(quint32 id, const QString& game_info_string, quint32 total, quint32 points);
+18 -1
View File
@@ -513,5 +513,22 @@ std::optional<std::string> InputManager::ConvertHostKeyboardCodeToString(u32 cod
u32 QtUtils::KeyEventToCode(const QKeyEvent* ev)
{
return static_cast<u32>(ev->key()) | (static_cast<u32>(ev->modifiers()) & static_cast<u32>(Qt::KeypadModifier));
int key = ev->key();
Qt::KeyboardModifiers modifiers = ev->modifiers();
#ifdef __APPLE__
// On macOS, Qt applies the Keypad modifier regardless of whether the arrow keys, or numpad was pressed.
// The only way to differentiate between the keypad and the arrow keys is by the text.
// Hopefully some keyboard layouts don't change the numpad positioning...
if (modifiers & Qt::KeypadModifier && key >= Qt::Key_Insert && key <= Qt::Key_PageDown)
{
if (ev->text().isEmpty())
{
// Drop the modifier, because it's probably not actually a numpad push.
modifiers &= ~Qt::KeypadModifier;
}
}
#endif
return static_cast<u32>(key) | (static_cast<u32>(modifiers) & static_cast<u32>(Qt::KeypadModifier));
}
+11 -4
View File
@@ -1078,7 +1078,10 @@ namespace SettingWidgetBinder
static inline void BindSliderToIntSetting(SettingsInterface* sif, QSlider* slider, QLabel* label, const QString& label_suffix,
std::string section, std::string key, s32 default_value)
{
const s32 global_value = Host::GetBaseIntSettingValue(section.c_str(), key.c_str(), default_value);
s32 global_value = Host::GetBaseIntSettingValue(section.c_str(), key.c_str(), default_value);
//Clamp in case setting was updated manually using INI
global_value = std::clamp(global_value, slider->minimum(), slider->maximum());
if (sif)
{
@@ -1086,7 +1089,9 @@ namespace SettingWidgetBinder
QFont bold_font(orig_font);
bold_font.setBold(true);
const s32 current_value = sif->GetOptionalIntValue(section.c_str(), key.c_str()).value_or(global_value);
s32 current_value = sif->GetOptionalIntValue(section.c_str(), key.c_str()).value_or(global_value);
current_value = std::clamp(current_value, slider->minimum(), slider->maximum());
slider->setValue(current_value);
label->setText(QStringLiteral("%1%2").arg(current_value).arg(label_suffix));
@@ -1100,8 +1105,10 @@ namespace SettingWidgetBinder
[sif, slider, label, label_suffix, orig_font = std::move(orig_font), section, key, default_value](const QPoint& pt) {
QMenu menu(slider);
slider->connect(menu.addAction(qApp->translate("SettingWidgetBinder", "Reset")), &QAction::triggered, slider,
[sif, label, label_suffix, orig_font, section, key, default_value]() {
const s32 global_value = Host::GetBaseIntSettingValue(section.c_str(), key.c_str(), default_value);
[sif, slider, label, label_suffix, orig_font, section, key, default_value]() {
s32 global_value = Host::GetBaseIntSettingValue(section.c_str(), key.c_str(), default_value);
global_value = std::clamp(global_value, slider->minimum(), slider->maximum());
label->setText(QStringLiteral("%1%2").arg(global_value).arg(label_suffix));
label->setFont(orig_font);
+10 -1
View File
@@ -22,13 +22,22 @@
#include <QtWidgets/QMessageBox>
AchievementLoginDialog::AchievementLoginDialog(QWidget* parent)
AchievementLoginDialog::AchievementLoginDialog(QWidget* parent, Achievements::LoginRequestReason reason)
: QDialog(parent)
{
m_ui.setupUi(this);
m_ui.loginIcon->setPixmap(QIcon::fromTheme("login-box-line").pixmap(32));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
// Adjust text if needed based on reason.
if (reason == Achievements::LoginRequestReason::TokenInvalid)
{
m_ui.instructionText->setText(
tr("<strong>Your RetroAchievements login token is no longer valid.</strong> You must re-enter your "
"credentials for achievements to be tracked. Your password will not be saved in PCSX2, an access token "
"will be generated and used instead."));
}
m_login = m_ui.buttonBox->addButton(tr("&Login"), QDialogButtonBox::AcceptRole);
m_login->setEnabled(false);
connectUi();
+7 -1
View File
@@ -18,12 +18,17 @@
#include <QtWidgets/QDialog>
#include <QtWidgets/QPushButton>
namespace Achievements
{
enum class LoginRequestReason;
}
class AchievementLoginDialog : public QDialog
{
Q_OBJECT
public:
AchievementLoginDialog(QWidget* parent);
AchievementLoginDialog(QWidget* parent, Achievements::LoginRequestReason reason);
~AchievementLoginDialog();
private Q_SLOTS:
@@ -38,4 +43,5 @@ private:
Ui::AchievementLoginDialog m_ui;
QPushButton* m_login;
Achievements::LoginRequestReason m_reason;
};
+1 -1
View File
@@ -51,7 +51,7 @@
</layout>
</item>
<item>
<widget class="QLabel" name="label_3">
<widget class="QLabel" name="instructionText">
<property name="text">
<string>Please enter user name and password for retroachievements.org below. Your password will not be saved in PCSX2, an access token will be generated and used instead.</string>
</property>
@@ -30,6 +30,8 @@
#include <QtCore/QDateTime>
#include <QtWidgets/QMessageBox>
static constexpr s32 DEFAULT_NOTIFICATIONS_DURATION = 5;
AchievementSettingsWidget::AchievementSettingsWidget(SettingsDialog* dialog, QWidget* parent)
: QWidget(parent)
, m_dialog(dialog)
@@ -48,6 +50,9 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsDialog* dialog, QWi
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.soundEffects, "Achievements", "SoundEffects", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.primedIndicators, "Achievements", "PrimedIndicators", true);
SettingWidgetBinder::BindSliderToIntSetting(sif, m_ui.notifications_duration, m_ui.notifications_duration_seconds,
tr(" seconds"), "Achievements", "NotificationsDuration", DEFAULT_NOTIFICATIONS_DURATION);
dialog->registerWidgetHelp(m_ui.enable, tr("Enable Achievements"), tr("Unchecked"),
tr("When enabled and logged in, PCSX2 will scan for achievements on game load."));
dialog->registerWidgetHelp(m_ui.testMode, tr("Enable Test Mode"), tr("Unchecked"),
@@ -70,10 +75,18 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsDialog* dialog, QWi
dialog->registerWidgetHelp(m_ui.primedIndicators, tr("Show Challenge Indicators"), tr("Checked"),
tr("Shows icons in the lower-right corner of the screen when a challenge/primed achievement is active."));
dialog->registerWidgetHelp(m_ui.notifications_duration, tr("Notification Duration"),
tr("5 seconds"), tr("The duration, in seconds, an achievement popup notification will remain on screen."));
dialog->registerWidgetHelp(m_ui.notifications_duration_label, tr("Notification Duration"),
tr("5 seconds"), tr("The duration, in seconds, an achievement popup notification will remain on screen."));
dialog->registerWidgetHelp(m_ui.notifications_duration_seconds, tr("Notification Duration"),
tr("5 seconds"), tr("The duration, in seconds, an achievement popup notification will remain on screen."));
connect(m_ui.enable, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::updateEnableState);
connect(m_ui.notifications, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::updateEnableState);
connect(m_ui.challengeMode, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::updateEnableState);
connect(m_ui.challengeMode, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::onChallengeModeStateChanged);
connect(m_ui.notifications_duration, &QSlider::valueChanged, this, &AchievementSettingsWidget::onNotificationsDurationChanged);
if (!m_dialog->isPerGameSettings())
{
@@ -105,6 +118,8 @@ void AchievementSettingsWidget::updateEnableState()
{
const bool enabled = m_dialog->getEffectiveBoolValue("Achievements", "Enabled", false);
const bool challenge = m_dialog->getEffectiveBoolValue("Achievements", "ChallengeMode", false);
const bool notifications = m_dialog->getEffectiveBoolValue("Achievements", "Notifications", true);
m_ui.testMode->setEnabled(enabled);
m_ui.unofficialTestMode->setEnabled(enabled);
m_ui.richPresence->setEnabled(enabled);
@@ -113,6 +128,10 @@ void AchievementSettingsWidget::updateEnableState()
m_ui.notifications->setEnabled(enabled);
m_ui.soundEffects->setEnabled(enabled);
m_ui.primedIndicators->setEnabled(enabled);
m_ui.notifications_duration->setEnabled(enabled && notifications);
m_ui.notifications_duration_label->setEnabled(enabled && notifications);
m_ui.notifications_duration_seconds->setEnabled(enabled && notifications);
}
void AchievementSettingsWidget::onChallengeModeStateChanged()
@@ -173,7 +192,7 @@ void AchievementSettingsWidget::onLoginLogoutPressed()
return;
}
AchievementLoginDialog login(this);
AchievementLoginDialog login(this, Achievements::LoginRequestReason::UserInitiated);
int res = login.exec();
if (res != 0)
return;
@@ -196,3 +215,9 @@ void AchievementSettingsWidget::onAchievementsRefreshed(quint32 id, const QStrin
{
m_ui.gameInfo->setText(game_info_string);
}
void AchievementSettingsWidget::onNotificationsDurationChanged()
{
m_ui.notifications_duration_seconds->setText(tr("%1 seconds")
.arg(m_ui.notifications_duration->value()));
}
@@ -33,6 +33,7 @@ private Q_SLOTS:
void onLoginLogoutPressed();
void onViewProfilePressed();
void onAchievementsRefreshed(quint32 id, const QString& game_info_string, quint32 total, quint32 points);
void onNotificationsDurationChanged();
private:
void updateLoginState();
+83 -16
View File
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>658</width>
<height>496</height>
<width>829</width>
<height>641</height>
</rect>
</property>
<property name="windowTitle">
@@ -39,13 +39,6 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="primedIndicators">
<property name="text">
<string>Show Challenge Indicators</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="richPresence">
<property name="text">
@@ -74,13 +67,6 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="testMode">
<property name="text">
<string>Enable Test Mode</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="soundEffects">
<property name="text">
@@ -89,12 +75,93 @@
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="primedIndicators">
<property name="text">
<string>Show Challenge Indicators</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="testMode">
<property name="text">
<string>Enable Test Mode</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="notificationBox">
<property name="title">
<string>Notifications</string>
</property>
<layout class="QVBoxLayout" name="notifications_box_layout" stretch="0,0">
<item>
<widget class="QCheckBox" name="notifications">
<property name="text">
<string>Show Notifications</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="notifications_duration_layout" stretch="0,0,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="QLabel" name="notifications_duration_label">
<property name="text">
<string>Duration</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="notifications_duration">
<property name="minimum">
<number>3</number>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="notifications_duration_seconds">
<property name="text">
<string>5 seconds</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
+47 -28
View File
@@ -26,7 +26,7 @@
#include "common/StringUtil.h"
#include "pcsx2/Host.h"
#include "pcsx2/SIO/Pad/PadConfig.h"
#include "pcsx2/SIO/Pad/Pad.h"
#include "Settings/ControllerBindingWidgets.h"
#include "Settings/ControllerSettingsDialog.h"
@@ -38,6 +38,7 @@
#include "ui_USBBindingWidget_DrivingForce.h"
#include "ui_USBBindingWidget_GTForce.h"
#include "ui_USBBindingWidget_GunCon2.h"
ControllerBindingWidget::ControllerBindingWidget(QWidget* parent, ControllerSettingsDialog* dialog, u32 port)
: QWidget(parent)
@@ -51,8 +52,8 @@ ControllerBindingWidget::ControllerBindingWidget(QWidget* parent, ControllerSett
populateControllerTypes();
onTypeChanged();
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(
m_dialog->getProfileSettingsInterface(), m_ui.controllerType, m_config_section, "Type", g_PadConfig.GetDefaultPadType(port));
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(m_dialog->getProfileSettingsInterface(),
m_ui.controllerType, m_config_section, "Type", Pad::GetControllerInfo(Pad::GetDefaultPadType(port))->name);
connect(m_ui.controllerType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ControllerBindingWidget::onTypeChanged);
connect(m_ui.bindings, &QPushButton::clicked, this, &ControllerBindingWidget::onBindingsClicked);
@@ -71,14 +72,22 @@ QIcon ControllerBindingWidget::getIcon() const
void ControllerBindingWidget::populateControllerTypes()
{
for (const auto& [name, display_name] : g_PadConfig.GetControllerTypeNames())
m_ui.controllerType->addItem(qApp->translate("Pad", display_name), QString::fromStdString(name));
for (const auto& [name, display_name] : Pad::GetControllerTypeNames())
m_ui.controllerType->addItem(QString::fromUtf8(display_name), QString::fromUtf8(name));
}
void ControllerBindingWidget::onTypeChanged()
{
const bool is_initializing = (m_ui.stackedWidget->count() == 0);
m_controller_type = m_dialog->getStringValue(m_config_section.c_str(), "Type", g_PadConfig.GetDefaultPadType(m_port_number));
const std::string type_name = m_dialog->getStringValue(
m_config_section.c_str(), "Type", Pad::GetControllerInfo(Pad::GetDefaultPadType(m_port_number))->name);
const Pad::ControllerInfo* cinfo = Pad::GetControllerInfoByName(type_name);
if (!cinfo)
{
Console.Error(fmt::format("Invalid controller type name '{}' in config, ignoring.", type_name));
cinfo = Pad::GetControllerInfo(Pad::ControllerType::NotConnected);
}
m_controller_type = cinfo->type;
if (m_bindings_widget)
{
@@ -99,17 +108,16 @@ void ControllerBindingWidget::onTypeChanged()
m_macros_widget = nullptr;
}
const PadConfig::ControllerInfo* cinfo = g_PadConfig.GetControllerInfo(m_controller_type);
const bool has_settings = (cinfo && cinfo->num_settings > 0);
const bool has_macros = (cinfo && cinfo->num_bindings > 0);
const bool has_settings = (!cinfo->settings.empty());
const bool has_macros = (!cinfo->bindings.empty());
m_ui.settings->setEnabled(has_settings);
m_ui.macros->setEnabled(has_macros);
if (m_controller_type == "DualShock2")
if (cinfo->type == Pad::ControllerType::DualShock2)
{
m_bindings_widget = ControllerBindingWidget_DualShock2::createInstance(this);
}
else if (m_controller_type == "Guitar")
else if (cinfo->type == Pad::ControllerType::Guitar)
{
m_bindings_widget = ControllerBindingWidget_Guitar::createInstance(this);
}
@@ -123,9 +131,8 @@ void ControllerBindingWidget::onTypeChanged()
if (has_settings)
{
const std::span<const SettingInfo> settings(cinfo->settings, cinfo->num_settings);
m_settings_widget = new ControllerCustomSettingsWidget(
settings, m_config_section, std::string(), "Pad", getDialog(), m_ui.stackedWidget);
cinfo->settings, m_config_section, std::string(), "Pad", getDialog(), m_ui.stackedWidget);
m_ui.stackedWidget->addWidget(m_settings_widget);
}
@@ -218,13 +225,13 @@ void ControllerBindingWidget::onClearBindingsClicked()
{
{
auto lock = Host::GetSettingsLock();
g_PadConfig.ClearPortBindings(*Host::Internal::GetBaseSettingsLayer(), m_port_number);
Pad::ClearPortBindings(*Host::Internal::GetBaseSettingsLayer(), m_port_number);
}
Host::CommitBaseSettingChanges();
}
else
{
g_PadConfig.ClearPortBindings(*m_dialog->getProfileSettingsInterface(), m_port_number);
Pad::ClearPortBindings(*m_dialog->getProfileSettingsInterface(), m_port_number);
m_dialog->getProfileSettingsInterface()->Save();
}
@@ -248,14 +255,14 @@ void ControllerBindingWidget::doDeviceAutomaticBinding(const QString& device)
{
{
auto lock = Host::GetSettingsLock();
result = g_PadConfig.MapController(*Host::Internal::GetBaseSettingsLayer(), m_port_number, mapping);
result = Pad::MapController(*Host::Internal::GetBaseSettingsLayer(), m_port_number, mapping);
}
if (result)
Host::CommitBaseSettingChanges();
}
else
{
result = g_PadConfig.MapController(*m_dialog->getProfileSettingsInterface(), m_port_number, mapping);
result = Pad::MapController(*m_dialog->getProfileSettingsInterface(), m_port_number, mapping);
if (result)
{
m_dialog->getProfileSettingsInterface()->Save();
@@ -320,7 +327,7 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare
ControllerSettingsDialog* dialog = m_bwidget->getDialog();
const std::string& section = m_bwidget->getConfigSection();
const PadConfig::ControllerInfo* cinfo = g_PadConfig.GetControllerInfo(m_bwidget->getControllerType());
const Pad::ControllerInfo* cinfo = Pad::GetControllerInfo(m_bwidget->getControllerType());
if (!cinfo)
{
// Shouldn't ever happen.
@@ -333,20 +340,19 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare
for (const std::string_view& button : buttons_split)
{
for (u32 i = 0; i < cinfo->num_bindings; i++)
for (const InputBindingInfo& bi : cinfo->bindings)
{
if (button == cinfo->bindings[i].name)
if (button == bi.name)
{
m_binds.push_back(&cinfo->bindings[i]);
m_binds.push_back(&bi);
break;
}
}
}
// populate list view
for (u32 i = 0; i < cinfo->num_bindings; i++)
for (const InputBindingInfo& bi : cinfo->bindings)
{
const InputBindingInfo& bi = cinfo->bindings[i];
if (bi.bind_type == InputBindingInfo::Type::Motor)
continue;
@@ -358,8 +364,12 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare
ControllerSettingWidgetBinder::BindWidgetToInputProfileNormalized(
dialog->getProfileSettingsInterface(), m_ui.pressure, section, fmt::format("Macro{}Pressure", index + 1u), 100.0f, 1.0f);
ControllerSettingWidgetBinder::BindWidgetToInputProfileNormalized(
dialog->getProfileSettingsInterface(), m_ui.deadzone, section, fmt::format("Macro{}Deadzone", index + 1u), 100.0f, 0.0f);
connect(m_ui.pressure, &QSlider::valueChanged, this, &ControllerMacroEditWidget::onPressureChanged);
connect(m_ui.deadzone, &QSlider::valueChanged, this, &ControllerMacroEditWidget::onDeadzoneChanged);
onPressureChanged();
onDeadzoneChanged();
m_frequency = dialog->getIntValue(section.c_str(), fmt::format("Macro{}Frequency", index + 1u).c_str(), 0);
updateFrequencyText();
@@ -392,6 +402,11 @@ void ControllerMacroEditWidget::onPressureChanged()
m_ui.pressureValue->setText(tr("%1%").arg(m_ui.pressure->value()));
}
void ControllerMacroEditWidget::onDeadzoneChanged()
{
m_ui.deadzoneValue->setText(tr("%1%").arg(m_ui.deadzone->value()));
}
void ControllerMacroEditWidget::onSetFrequencyClicked()
{
bool okay;
@@ -431,12 +446,12 @@ void ControllerMacroEditWidget::updateFrequencyText()
void ControllerMacroEditWidget::updateBinds()
{
ControllerSettingsDialog* dialog = m_bwidget->getDialog();
const PadConfig::ControllerInfo* cinfo = g_PadConfig.GetControllerInfo(m_bwidget->getControllerType());
const Pad::ControllerInfo* cinfo = Pad::GetControllerInfo(m_bwidget->getControllerType());
if (!cinfo)
return;
std::vector<const InputBindingInfo*> new_binds;
for (u32 i = 0, bind_index = 0; i < cinfo->num_bindings; i++)
for (u32 i = 0, bind_index = 0; i < static_cast<u32>(cinfo->bindings.size()); i++)
{
const InputBindingInfo& bi = cinfo->bindings[i];
if (bi.bind_type == InputBindingInfo::Type::Motor)
@@ -801,16 +816,15 @@ QIcon ControllerBindingWidget_Base::getIcon() const
void ControllerBindingWidget_Base::initBindingWidgets()
{
const PadConfig::ControllerInfo* cinfo = g_PadConfig.GetControllerInfo(getControllerType());
const Pad::ControllerInfo* cinfo = Pad::GetControllerInfo(getControllerType());
if (!cinfo)
return;
const std::string& config_section = getConfigSection();
SettingsInterface* sif = getDialog()->getProfileSettingsInterface();
for (u32 i = 0; i < cinfo->num_bindings; i++)
for (const InputBindingInfo& bi : cinfo->bindings)
{
const InputBindingInfo& bi = cinfo->bindings[i];
if (bi.bind_type == InputBindingInfo::Type::Axis || bi.bind_type == InputBindingInfo::Type::HalfAxis ||
bi.bind_type == InputBindingInfo::Type::Button || bi.bind_type == InputBindingInfo::Type::Pointer ||
bi.bind_type == InputBindingInfo::Type::Device)
@@ -1269,6 +1283,11 @@ USBBindingWidget* USBBindingWidget::createInstance(
has_template = true;
}
}
else if (type == "guncon2")
{
Ui::USBBindingWidget_GunCon2().setupUi(widget);
has_template = true;
}
if (has_template)
widget->bindWidgets(bindings);
+6 -5
View File
@@ -15,7 +15,7 @@
#pragma once
#include "pcsx2/SIO/Pad/PadMacros.h"
#include "pcsx2/SIO/Pad/PadTypes.h"
#include <QtWidgets/QWidget>
@@ -49,7 +49,7 @@ public:
__fi ControllerSettingsDialog* getDialog() const { return m_dialog; }
__fi const std::string& getConfigSection() const { return m_config_section; }
__fi const std::string& getControllerType() const { return m_controller_type; }
__fi Pad::ControllerType getControllerType() const { return m_controller_type; }
__fi u32 getPortNumber() const { return m_port_number; }
private Q_SLOTS:
@@ -70,7 +70,7 @@ private:
ControllerSettingsDialog* m_dialog;
std::string m_config_section;
std::string m_controller_type;
Pad::ControllerType m_controller_type;
u32 m_port_number;
ControllerBindingWidget_Base* m_bindings_widget = nullptr;
@@ -92,7 +92,7 @@ public:
void updateListItem(u32 index);
private:
static constexpr u32 NUM_MACROS = PadMacros::NUM_MACRO_BUTTONS_PER_CONTROLLER;
static constexpr u32 NUM_MACROS = Pad::NUM_MACRO_BUTTONS_PER_CONTROLLER;
void createWidgets(ControllerBindingWidget* parent);
@@ -115,6 +115,7 @@ public:
private Q_SLOTS:
void onPressureChanged();
void onDeadzoneChanged();
void onSetFrequencyClicked();
void updateBinds();
@@ -169,7 +170,7 @@ public:
__fi ControllerSettingsDialog* getDialog() const { return static_cast<ControllerBindingWidget*>(parent())->getDialog(); }
__fi const std::string& getConfigSection() const { return static_cast<ControllerBindingWidget*>(parent())->getConfigSection(); }
__fi const std::string& getControllerType() const { return static_cast<ControllerBindingWidget*>(parent())->getControllerType(); }
__fi Pad::ControllerType getControllerType() const { return static_cast<ControllerBindingWidget*>(parent())->getControllerType(); }
__fi u32 getPortNumber() const { return static_cast<ControllerBindingWidget*>(parent())->getPortNumber(); }
virtual QIcon getIcon() const;
+44 -1
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>691</width>
<height>547</height>
<height>433</height>
</rect>
</property>
<property name="windowTitle">
@@ -83,6 +83,9 @@
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
<item>
@@ -123,6 +126,46 @@
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="deadzoneLayout" stretch="0,1,0">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Deadzone:</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="deadzone">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>100</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>10</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="deadzoneValue">
<property name="text">
<string>100%</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
@@ -22,7 +22,7 @@
#include "Settings/HotkeySettingsWidget.h"
#include "pcsx2/INISettingsInterface.h"
#include "pcsx2/SIO/Pad/PadConfig.h"
#include "pcsx2/SIO/Pad/Pad.h"
#include "pcsx2/SIO/Sio.h"
#include "pcsx2/VMManager.h"
@@ -130,7 +130,7 @@ void ControllerSettingsDialog::onNewProfileClicked()
{
// from global
auto lock = Host::GetSettingsLock();
g_PadConfig.CopyConfiguration(&temp_si, *Host::Internal::GetBaseSettingsLayer(), true, true, false);
Pad::CopyConfiguration(&temp_si, *Host::Internal::GetBaseSettingsLayer(), true, true, false);
USB::CopyConfiguration(&temp_si, *Host::Internal::GetBaseSettingsLayer(), true, true);
}
else
@@ -138,7 +138,7 @@ void ControllerSettingsDialog::onNewProfileClicked()
// from profile
const bool copy_hotkey_bindings = m_profile_interface->GetBoolValue("Pad", "UseProfileHotkeyBindings", false);
temp_si.SetBoolValue("Pad", "UseProfileHotkeyBindings", copy_hotkey_bindings);
g_PadConfig.CopyConfiguration(&temp_si, *m_profile_interface, true, true, copy_hotkey_bindings);
Pad::CopyConfiguration(&temp_si, *m_profile_interface, true, true, copy_hotkey_bindings);
USB::CopyConfiguration(&temp_si, *m_profile_interface, true, true);
}
}
@@ -167,7 +167,7 @@ void ControllerSettingsDialog::onLoadProfileClicked()
{
auto lock = Host::GetSettingsLock();
g_PadConfig.CopyConfiguration(Host::Internal::GetBaseSettingsLayer(), *m_profile_interface, true, true, false);
Pad::CopyConfiguration(Host::Internal::GetBaseSettingsLayer(), *m_profile_interface, true, true, false);
USB::CopyConfiguration(Host::Internal::GetBaseSettingsLayer(), *m_profile_interface, true, true);
}
Host::CommitBaseSettingChanges();
@@ -403,8 +403,8 @@ void ControllerSettingsDialog::createWidgets()
m_port_bindings[global_slot] = new ControllerBindingWidget(m_ui.settingsContainer, this, global_slot);
m_ui.settingsContainer->addWidget(m_port_bindings[global_slot]);
const PadConfig::ControllerInfo* ci = g_PadConfig.GetControllerInfo(m_port_bindings[global_slot]->getControllerType());
const QString display_name(ci ? qApp->translate("Pad", ci->display_name) : QStringLiteral("Unknown"));
const Pad::ControllerInfo* ci = Pad::GetControllerInfo(m_port_bindings[global_slot]->getControllerType());
const QString display_name(QString::fromUtf8(ci ? ci->GetLocalizedName() : "Unknown"));
QListWidgetItem* item = new QListWidgetItem();
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
@@ -459,8 +459,8 @@ void ControllerSettingsDialog::updateListDescription(u32 global_slot, Controller
const auto [port, slot] = sioConvertPadToPortAndSlot(global_slot);
const bool mtap_enabled = getBoolValue("Pad", (port == 0) ? "MultitapPort1" : "MultitapPort2", false);
const PadConfig::ControllerInfo* ci = g_PadConfig.GetControllerInfo(widget->getControllerType());
const QString display_name(ci ? qApp->translate("Pad", ci->display_name) : QStringLiteral("Unknown"));
const Pad::ControllerInfo* ci = Pad::GetControllerInfo(widget->getControllerType());
const QString display_name = QString::fromUtf8(ci ? ci->GetLocalizedName() : "Unknown");
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
item->setText(mtap_enabled ? (tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name)) :
@@ -492,7 +492,7 @@ void ControllerSettingsDialog::updateListDescription(u32 port, USBDeviceWidget*
void ControllerSettingsDialog::refreshProfileList()
{
const std::vector<std::string> names(g_PadConfig.GetInputProfileNames());
const std::vector<std::string> names = Pad::GetInputProfileNames();
QSignalBlocker sb(m_ui.currentProfile);
m_ui.currentProfile->clear();
+13 -1
View File
@@ -51,6 +51,7 @@ GameListSettingsWidget::GameListSettingsWidget(SettingsDialog* dialog, QWidget*
&GameListSettingsWidget::onAddSearchDirectoryButtonClicked);
connect(m_ui.removeSearchDirectoryButton, &QPushButton::clicked, this,
&GameListSettingsWidget::onRemoveSearchDirectoryButtonClicked);
connect(m_ui.addExcludedFile, &QPushButton::clicked, this, &GameListSettingsWidget::onAddExcludedFileButtonClicked);
connect(m_ui.addExcludedPath, &QPushButton::clicked, this, &GameListSettingsWidget::onAddExcludedPathButtonClicked);
connect(m_ui.removeExcludedPath, &QPushButton::clicked, this,
&GameListSettingsWidget::onRemoveExcludedPathButtonClicked);
@@ -215,10 +216,21 @@ void GameListSettingsWidget::onRemoveSearchDirectoryButtonClicked()
delete item;
}
void GameListSettingsWidget::onAddExcludedFileButtonClicked()
{
QString path =
QDir::toNativeSeparators(QFileDialog::getOpenFileName(QtUtils::GetRootWidget(this), tr("Select File")));
if (path.isEmpty())
return;
addExcludedPath(path.toStdString());
}
void GameListSettingsWidget::onAddExcludedPathButtonClicked()
{
QString path =
QDir::toNativeSeparators(QFileDialog::getOpenFileName(QtUtils::GetRootWidget(this), tr("Select Path")));
QDir::toNativeSeparators(QFileDialog::getExistingDirectory(QtUtils::GetRootWidget(this), tr("Select Directory")));
if (path.isEmpty())
return;
@@ -39,6 +39,7 @@ private Q_SLOTS:
void onDirectoryListContextMenuRequested(const QPoint& point);
void onAddSearchDirectoryButtonClicked();
void onRemoveSearchDirectoryButtonClicked();
void onAddExcludedFileButtonClicked();
void onAddExcludedPathButtonClicked();
void onRemoveExcludedPathButtonClicked();
void onScanForNewGamesClicked();
+34 -2
View File
@@ -57,12 +57,15 @@
</sizepolicy>
</property>
<property name="text">
<string>Add</string>
<string>Add...</string>
</property>
<property name="icon">
<iconset theme="folder-add-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
@@ -80,6 +83,9 @@
<iconset theme="folder-reduce-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
</layout>
@@ -129,12 +135,35 @@
</sizepolicy>
</property>
<property name="text">
<string>Add</string>
<string>Directory...</string>
</property>
<property name="icon">
<iconset theme="folder-add-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="addExcludedFile">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>File...</string>
</property>
<property name="icon">
<iconset theme="file-add-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
@@ -152,6 +181,9 @@
<iconset theme="file-reduce-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
</layout>
+54 -9
View File
@@ -15,7 +15,7 @@
#include "PrecompiledHeader.h"
#include "pcsx2/SIO/Pad/PadConfig.h"
#include "pcsx2/SIO/Pad/Pad.h"
#include "GameSummaryWidget.h"
#include "SettingsDialog.h"
#include "MainWindow.h"
@@ -63,13 +63,18 @@ GameSummaryWidget::GameSummaryWidget(const GameList::Entry* entry, SettingsDialo
connect(m_ui.inputProfile, &QComboBox::currentIndexChanged, this, &GameSummaryWidget::onInputProfileChanged);
connect(m_ui.verify, &QAbstractButton::clicked, this, &GameSummaryWidget::onVerifyClicked);
connect(m_ui.searchHash, &QAbstractButton::clicked, this, &GameSummaryWidget::onSearchHashClicked);
bool has_custom_title = false, has_custom_region = false;
GameList::CheckCustomAttributesForPath(m_entry_path, has_custom_title, has_custom_region);
m_ui.restoreTitle->setEnabled(has_custom_title);
m_ui.restoreRegion->setEnabled(has_custom_region);
}
GameSummaryWidget::~GameSummaryWidget() = default;
void GameSummaryWidget::populateInputProfiles()
{
for (const std::string& name : g_PadConfig.GetInputProfileNames())
for (const std::string& name : Pad::GetInputProfileNames())
m_ui.inputProfile->addItem(QString::fromStdString(name));
}
@@ -88,6 +93,24 @@ void GameSummaryWidget::populateDetails(const GameList::Entry* entry)
m_ui.inputProfile->setCurrentIndex(m_ui.inputProfile->findText(QString::fromStdString(profile.value())));
else
m_ui.inputProfile->setCurrentIndex(0);
connect(m_ui.title, &QLineEdit::editingFinished, this, [this]() {
if (m_ui.title->isModified())
{
setCustomTitle(m_ui.title->text().toStdString());
m_ui.title->setModified(false);
}
});
connect(m_ui.restoreTitle, &QAbstractButton::clicked, this, [this]() {
setCustomTitle("");
});
connect(m_ui.region, &QComboBox::currentIndexChanged, this, [this](int index) {
setCustomRegion(index);
});
connect(m_ui.restoreRegion, &QAbstractButton::clicked, this, [this]() {
setCustomRegion(-1);
});
}
void GameSummaryWidget::populateDiscPath(const GameList::Entry* entry)
@@ -129,12 +152,7 @@ void GameSummaryWidget::onDiscPathChanged(const QString& value)
// force rescan of elf to update the serial
g_main_window->rescanFile(m_entry_path);
// and re-fill our details (mainly the serial)
auto lock = GameList::GetLock();
const GameList::Entry* entry = GameList::GetEntryForPath(m_entry_path.c_str());
if (entry)
populateDetails(entry);
repopulateCurrentDetails();
}
void GameSummaryWidget::onDiscPathBrowseClicked()
@@ -352,4 +370,31 @@ void GameSummaryWidget::setVerifyResult(QString error)
m_ui.verifyResult->setPlainText(error);
m_ui.verifyResult->setVisible(true);
m_ui.searchHash->setVisible(true);
}
}
void GameSummaryWidget::repopulateCurrentDetails()
{
auto lock = GameList::GetLock();
const GameList::Entry* entry = GameList::GetEntryForPath(m_entry_path.c_str());
if (entry)
{
populateDetails(entry);
m_dialog->setWindowTitle(QString::fromStdString(entry->title));
}
}
void GameSummaryWidget::setCustomTitle(const std::string& text)
{
m_ui.restoreTitle->setEnabled(!text.empty());
GameList::SaveCustomTitleForPath(m_entry_path, text);
repopulateCurrentDetails();
}
void GameSummaryWidget::setCustomRegion(int region)
{
m_ui.restoreRegion->setEnabled(region >= 0);
GameList::SaveCustomRegionForPath(m_entry_path, region);
repopulateCurrentDetails();
}
+4
View File
@@ -47,6 +47,10 @@ private:
void populateDiscPath(const GameList::Entry* entry);
void populateTrackList(const GameList::Entry* entry);
void setVerifyResult(QString error);
void repopulateCurrentDetails();
void setCustomTitle(const std::string& text);
void setCustomRegion(int region);
Ui::GameSummaryWidget m_ui;
SettingsDialog* m_dialog;
+196 -174
View File
@@ -34,11 +34,25 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="title">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLineEdit" name="title">
<property name="placeholderText">
<string>Clear the line to restore the original title...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="restoreTitle">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Restore</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
@@ -140,170 +154,178 @@
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="region">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-B (Brazil)</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QComboBox" name="region">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-B (Brazil)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-C (China)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-HK (Hong Kong)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-J (Japan)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-K (Korea)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-T (Taiwan)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-U (US)</string>
</property>
</item>
<item>
<property name="text">
<string>Other</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-A (Australia)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-AF (South Africa)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-AU (Austria)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-BE (Belgium)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-E (Europe/Australia)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-F (France)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-FI (Finland)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-G (Germany)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-GR (Greece)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-I (Italy)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-IN (India)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-M (Europe/Australia)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-NL (Netherlands)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-NO (Norway)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-P (Portugal)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-PL (Poland)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-R (Russia)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-S (Spain)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-SC (Scandinavia)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-SW (Sweden)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-SWI (Switzerland)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-UK (United Kingdom)</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="restoreRegion">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Restore</string>
</property>
</widget>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-C (China)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-HK (Hong Kong)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-J (Japan)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-K (Korea)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-T (Taiwan)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">NTSC-U (US)</string>
</property>
</item>
<item>
<property name="text">
<string>Other</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-A (Australia)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-AF (South Africa)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-AU (Austria)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-BE (Belgium)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-E (Europe/Australia)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-F (France)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-FI (Finland)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-G (Germany)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-GR (Greece)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-I (Italy)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-IN (India)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-M (Europe/Australia)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-NL (Netherlands)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-NO (Norway)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-P (Portugal)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-PL (Poland)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-R (Russia)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-S (Spain)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-SC (Scandinavia)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-SW (Sweden)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-SWI (Switzerland)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-UK (United Kingdom)</string>
</property>
</item>
</widget>
</layout>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
@@ -488,22 +510,22 @@
<height>60</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="visible">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="searchHash">
<property name="text">
<string>Search on Redump.org...</string>
</property>
<property name="visible">
<bool>false</bool>
</property>
<property name="text">
<string>Search on Redump.org...</string>
</property>
</widget>
</item>
</layout>
+1 -6
View File
@@ -181,7 +181,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
//////////////////////////////////////////////////////////////////////////
// HW Renderer Fixes
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfScreenFix, "EmuCore/GS", "UserHacks_Half_Bottom_Override", -1, -1);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cpuSpriteRenderBW, "EmuCore/GS", "UserHacks_CPUSpriteRenderBW", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cpuSpriteRenderLevel, "EmuCore/GS", "UserHacks_CPUSpriteRenderLevel", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cpuCLUTRender, "EmuCore/GS", "UserHacks_CPUCLUTRender", 0);
@@ -218,12 +217,12 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfPixelOffset, "EmuCore/GS", "UserHacks_HalfPixelOffset", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.roundSprite, "EmuCore/GS", "UserHacks_round_sprite_offset", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.bilinearHack, "EmuCore/GS", "UserHacks_BilinearHack", 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);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.mergeSprite, "EmuCore/GS", "UserHacks_merge_pp_sprite", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.wildHack, "EmuCore/GS", "UserHacks_WildHack", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.bilinearHack, "EmuCore/GS", "UserHacks_BilinearHack", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.nativePaletteDraw, "EmuCore/GS", "UserHacks_NativePaletteDraw", false);
//////////////////////////////////////////////////////////////////////////
// Texture Replacements
@@ -515,9 +514,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
// Hardware Fixes tab
{
dialog->registerWidgetHelp(m_ui.halfScreenFix, tr("Half Screen Fix"), tr("Automatic (Default)"),
tr("Control the half-screen fix detection on texture shuffling."));
dialog->registerWidgetHelp(m_ui.cpuSpriteRenderBW, tr("CPU Sprite Renderer Size"), tr("0 (Disabled)"), tr(""));
dialog->registerWidgetHelp(m_ui.cpuCLUTRender, tr("Software CLUT Render"), tr("0 (Disabled)"), tr(""));
@@ -1050,7 +1046,6 @@ void GraphicsSettingsWidget::resetManualHardwareFixes()
check_bool("EmuCore/GS", "UserHacks", false);
check_int("EmuCore/GS", "UserHacks_Half_Bottom_Override", -1);
check_int("EmuCore/GS", "UserHacks_CPUSpriteRenderBW", 0);
check_int("EmuCore/GS", "UserHacks_CPUCLUTRender", 0);
check_int("EmuCore/GS", "UserHacks_GPUTargetCLUTMode", 0);
+36 -43
View File
@@ -780,32 +780,6 @@
<string>Hardware Fixes</string>
</attribute>
<layout class="QFormLayout" name="hardwareFixesLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Half Screen Fix:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="halfScreenFix">
<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_36">
<property name="text">
@@ -1168,14 +1142,14 @@
</item>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="textureOffsetLabel">
<property name="text">
<string>Texture Offsets:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<layout class="QHBoxLayout" name="textureOffsetLayout" stretch="0,1,0,1">
<item>
<widget class="QLabel" name="textureOffsetXLabel">
@@ -1207,7 +1181,7 @@
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<item row="4" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QCheckBox" name="alignSprite">
@@ -1216,20 +1190,6 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="bilinearHack">
<property name="text">
<string>Bilinear Dirty Upscale</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="mergeSprite">
<property name="text">
<string>Merge Sprite</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="nativePaletteDraw">
<property name="text">
@@ -1244,8 +1204,41 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="mergeSprite">
<property name="text">
<string>Merge Sprite</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Bilinear Dirty Upscale:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="bilinearHack">
<item>
<property name="text">
<string>Automatic (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Force Bilinear</string>
</property>
</item>
<item>
<property name="text">
<string>Force Nearest</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
+1 -1
View File
@@ -86,7 +86,7 @@
</size>
</property>
<property name="text">
<string>&lt;center&gt;&lt;strong&gt;Note:&lt;/strong&gt; Converting a Memory Card creates a &lt;strong&gt;COPY&lt;/strong&gt; of your existing Memory Card. It does &lt;strong&quot;&gt;NOT delete, modify, or replace&lt;/strong&gt; your existing Memory Card.&lt;/center&gt;</string>
<string>&lt;center&gt;&lt;strong&gt;Note:&lt;/strong&gt; Converting a Memory Card creates a &lt;strong&gt;COPY&lt;/strong&gt; of your existing Memory Card. It does &lt;strong&gt;NOT delete, modify, or replace&lt;/strong&gt; your existing Memory Card.&lt;/center&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+22 -13
View File
@@ -12,7 +12,7 @@
* 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 "MainWindow.h"
@@ -59,9 +59,10 @@ SettingsDialog::SettingsDialog(QWidget* parent)
}
SettingsDialog::SettingsDialog(QWidget* parent, std::unique_ptr<SettingsInterface> sif, const GameList::Entry* game,
std::string serial, u32 disc_crc)
std::string serial, u32 disc_crc, QString filename)
: QDialog(parent)
, m_sif(std::move(sif))
, m_filename(std::move(filename))
, m_serial(std::move(serial))
, m_disc_crc(disc_crc)
{
@@ -80,9 +81,9 @@ void SettingsDialog::setupUi(const GameList::Entry* game)
if (isPerGameSettings())
{
QString summary = tr("<strong>Summary</strong><hr>This page shows details about the selected game. Changing the Input "
"Profile will set the controller binding scheme for this game to whichever profile is chosen, instead "
"of the default (Shared) configuration. The track list and dump verification can be used to determine "
"if your disc image matches a known good dump. If it does not match, the game may be broken.");
"Profile will set the controller binding scheme for this game to whichever profile is chosen, instead "
"of the default (Shared) configuration. The track list and dump verification can be used to determine "
"if your disc image matches a known good dump. If it does not match, the game may be broken.");
if (game)
{
addWidget(new GameSummaryWidget(game, this, m_ui.settingsContainer), tr("Summary"),
@@ -153,7 +154,7 @@ void SettingsDialog::setupUi(const GameList::Entry* game)
addWidget(m_memory_card_settings = new MemoryCardSettingsWidget(this, m_ui.settingsContainer), tr("Memory Cards"),
QStringLiteral("memcard-line"),
tr("<strong>Memory Card Settings</strong><hr>Create and configure Memory Cards here.<br><br>Mouse over an option for "
"additional information."));
"additional information."));
addWidget(m_dev9_settings = new DEV9SettingsWidget(this, m_ui.settingsContainer), tr("Network & HDD"), QStringLiteral("global-line"),
tr("<strong>Network & HDD Settings</strong><hr>These options control the network connectivity and internal HDD storage of the "
@@ -330,6 +331,18 @@ bool SettingsDialog::eventFilter(QObject* object, QEvent* event)
return QDialog::eventFilter(object, event);
}
void SettingsDialog::setWindowTitle(const QString& title)
{
if (m_filename.isEmpty())
{
QDialog::setWindowTitle(title);
}
else
{
QDialog::setWindowTitle(QStringLiteral("%1 [%2]").arg(title, m_filename));
}
}
bool SettingsDialog::getEffectiveBoolValue(const char* section, const char* key, bool default_value) const
{
bool value;
@@ -544,16 +557,12 @@ void SettingsDialog::openGamePropertiesDialog(const GameList::Entry* game, const
}
std::string filename(VMManager::GetGameSettingsPath(serial, disc_crc));
std::unique_ptr<INISettingsInterface> sif = std::make_unique<INISettingsInterface>(std::move(filename));
std::unique_ptr<INISettingsInterface> sif = std::make_unique<INISettingsInterface>(filename);
if (FileSystem::FileExists(sif->GetFileName().c_str()))
sif->Load();
const QString window_title(tr("%1 [%2]")
.arg(QtUtils::StringViewToQString(title))
.arg(QtUtils::StringViewToQString(Path::GetFileName(sif->GetFileName()))));
SettingsDialog* dialog = new SettingsDialog(g_main_window, std::move(sif), game, std::move(serial), disc_crc);
dialog->setWindowTitle(window_title);
SettingsDialog* dialog = new SettingsDialog(g_main_window, std::move(sif), game, std::move(serial), disc_crc, QtUtils::StringViewToQString(Path::GetFileName(filename)));
dialog->setWindowTitle(QtUtils::StringViewToQString(title));
dialog->setModal(false);
dialog->show();
}
+5 -1
View File
@@ -51,7 +51,7 @@ class SettingsDialog final : public QDialog
public:
explicit SettingsDialog(QWidget* parent);
SettingsDialog(QWidget* parent, std::unique_ptr<SettingsInterface> sif, const GameList::Entry* game, std::string serial, u32 disc_crc);
SettingsDialog(QWidget* parent, std::unique_ptr<SettingsInterface> sif, const GameList::Entry* game, std::string serial, u32 disc_crc, QString filename = QString());
~SettingsDialog();
static void openGamePropertiesDialog(const GameList::Entry* game, const std::string_view& title, std::string serial, u32 disc_crc);
@@ -79,6 +79,8 @@ public:
void registerWidgetHelp(QObject* object, QString title, QString recommended_value, QString text);
bool eventFilter(QObject* object, QEvent* event) override;
void setWindowTitle(const QString& title);
QString getCategory() const;
void setCategory(const char* category);
@@ -145,6 +147,8 @@ private:
QObject* m_current_help_widget = nullptr;
QMap<QObject*, QString> m_widget_help_text_map;
QString m_filename;
std::string m_serial;
u32 m_disc_crc;
};
@@ -0,0 +1,779 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>USBBindingWidget_GunCon2</class>
<widget class="QWidget" name="USBBindingWidget_GunCon2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>400</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>1000</width>
<height>400</height>
</size>
</property>
<property name="windowTitle">
<string notr="true">Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_16">
<item row="2" column="2" colspan="2">
<widget class="QGroupBox" name="groupBox_16">
<property name="title">
<string>Buttons</string>
</property>
<layout class="QGridLayout" name="gridLayout_10">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_19">
<property name="title">
<string>A</string>
</property>
<layout class="QGridLayout" name="gridLayout_19">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="A">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="3">
<widget class="QGroupBox" name="groupBox_20">
<property name="title">
<string>C</string>
</property>
<layout class="QGridLayout" name="gridLayout_20">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="C">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_23">
<property name="title">
<string>Start</string>
</property>
<layout class="QGridLayout" name="gridLayout_23">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Start">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QGroupBox" name="groupBox_35">
<property name="title">
<string>Select</string>
</property>
<layout class="QGridLayout" name="gridLayout_35">
<item row="0" column="0">
<widget class="InputBindingWidget" name="Select">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QGroupBox" name="groupBox_18">
<property name="title">
<string>B</string>
</property>
<layout class="QGridLayout" name="gridLayout_18">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="B">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="3" rowspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>D-Pad</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="3" column="1" colspan="2">
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Down</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Down">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Left</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Left">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Up</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Up">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Right</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Right">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox_15">
<property name="title">
<string>Pointer Setup</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;p&gt;By default, GunCon2 will use the mouse pointer. To use the mouse, you &lt;strong&gt;do not&lt;/strong&gt; need to configure any bindings apart from the trigger and buttons.&lt;/p&gt;
&lt;p&gt;If you want to use a controller, or lightgun which simulates a controller instead of a mouse, then you should bind it to Relative Aiming. Otherwise, Relative Aiming should be &lt;strong&gt;left unbound&lt;/strong&gt;.&lt;/p&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="4" rowspan="3">
<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 row="0" column="0" rowspan="3">
<spacer name="horizontalSpacer_2">
<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 row="0" column="2" rowspan="2">
<widget class="QGroupBox" name="groupBox_10">
<property name="title">
<string extracomment="Try to use Sony's official terminology for this. A good place to start would be in the console or the DualShock 2's manual. If this element was officially translated to your language by Sony in later DualShocks, you may use that term.">Relative Aiming</string>
</property>
<layout class="QGridLayout" name="gridLayout_11">
<item row="3" column="1" colspan="2">
<widget class="QGroupBox" name="groupBox_11">
<property name="title">
<string>Down</string>
</property>
<layout class="QGridLayout" name="gridLayout_12">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="RelativeDown">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_12">
<property name="title">
<string>Left</string>
</property>
<layout class="QGridLayout" name="gridLayout_13">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="RelativeLeft">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QGroupBox" name="groupBox_13">
<property name="title">
<string>Up</string>
</property>
<layout class="QGridLayout" name="gridLayout_14">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="RelativeUp">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QGroupBox" name="groupBox_14">
<property name="title">
<string>Right</string>
</property>
<layout class="QGridLayout" name="gridLayout_15">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="RelativeRight">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="1" rowspan="2">
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Trigger</string>
</property>
<layout class="QGridLayout" name="gridLayout_9">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>Trigger</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Trigger">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox_8">
<property name="title">
<string>Shoot Offscreen</string>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="ShootOffscreen">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_9">
<property name="title">
<string>Calibration Shot</string>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="1">
<widget class="InputBindingWidget" name="Recalibrate">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">PushButton</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QLabel" name="label">
<property name="text">
<string>Calibration shot is required to pass the setup screen in some games.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0" colspan="5">
<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>
<customwidgets>
<customwidget>
<class>InputBindingWidget</class>
<extends>QPushButton</extends>
<header>Settings/InputBindingWidget.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../resources/resources.qrc"/>
</resources>
<connections/>
</ui>
+6 -6
View File
@@ -15,7 +15,7 @@
#include "PrecompiledHeader.h"
#include "pcsx2/SIO/Pad/PadConfig.h"
#include "pcsx2/SIO/Pad/Pad.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
@@ -151,7 +151,7 @@ void SetupWizardDialog::updatePageLabels(int prev_page)
void SetupWizardDialog::updatePageButtons()
{
const int page = m_ui.pages->currentIndex();
m_ui.next->setText((page == Page_Complete) ? "&Finish" : "&Next");
m_ui.next->setText((page == Page_Complete) ? tr("&Finish") : tr("&Next"));
m_ui.back->setEnabled(page > 0);
}
@@ -414,10 +414,10 @@ void SetupWizardDialog::setupControllerPage()
const std::string section = fmt::format("Pad{}", port + 1);
const PadWidgets& w = pad_widgets[port];
for (const auto& [name, display_name] : g_PadConfig.GetControllerTypeNames())
w.type_combo->addItem(qApp->translate("Pad", display_name), QString::fromStdString(name));
for (const auto& [name, display_name] : Pad::GetControllerTypeNames())
w.type_combo->addItem(QString::fromUtf8(display_name), QString::fromUtf8(name));
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(
nullptr, w.type_combo, section, "Type", g_PadConfig.GetDefaultPadType(port));
nullptr, w.type_combo, section, "Type", Pad::GetControllerInfo(Pad::GetDefaultPadType(port))->name);
w.mapping_result->setText((port == 0) ? tr("Default (Keyboard)") : tr("Default (None)"));
@@ -473,7 +473,7 @@ void SetupWizardDialog::doDeviceAutomaticBinding(u32 port, QLabel* update_label,
bool result;
{
auto lock = Host::GetSettingsLock();
result = g_PadConfig.MapController(*Host::Internal::GetBaseSettingsLayer(), port, mapping);
result = Pad::MapController(*Host::Internal::GetBaseSettingsLayer(), port, mapping);
}
if (!result)
return;
+7 -1
View File
@@ -371,12 +371,15 @@
</sizepolicy>
</property>
<property name="text">
<string>Add</string>
<string>Add...</string>
</property>
<property name="icon">
<iconset theme="folder-add-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
@@ -394,6 +397,9 @@
<iconset theme="folder-reduce-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
</layout>
+5 -4
View File
@@ -258,6 +258,7 @@ std::vector<std::pair<QString, QString>> QtHost::GetAvailableLanguageList()
{QStringLiteral("Italiano (it-IT)"), QStringLiteral("it-IT")},
{QStringLiteral("日本語 (ja-JP)"), QStringLiteral("ja-JP")},
{QStringLiteral("한국어 (ko-KR)"), QStringLiteral("ko-KR")},
{QStringLiteral("Latvija (lv-LV)"), QStringLiteral("lv-LV")},
{QStringLiteral("Nederlands (nl-NL)"), QStringLiteral("nl-NL")},
{QStringLiteral("Norsk (no-NO)"), QStringLiteral("no-NO")},
{QStringLiteral("Polski (pl-PL)"), QStringLiteral("pl-PL")},
@@ -337,22 +338,22 @@ static constexpr const QtHost::GlyphInfo s_glyph_info[] = {
{
"ja-JP", "msgothic.ttc", nullptr, "ヒラギノ角ゴシック W3.ttc",
// auto update by update_glyph_ranges.py with pcsx2-qt_ja-JP.ts
u"​□□△△◯◯✕✕、。〜〜ああいいううええおきくぐここささしすせせそそただっつてにのはびびへべほほまみめもややよれわわをんァイウコサソタチッツテニネパビロワワンンー一一上下不不中中丸丸了了互互今今他他代代仮仮作作使使保保信信修修倍倍値値停停備備像像入入全全公公内内再再出出切切別別利利制制削削副副割割力力加加効効動動勧勧化化十十南南参参反収取古古可台右右合合同名向向回回固固国国在在報報場場境境壊壊変変外外大大失失奨奨始始字存完完定定実実左左帰帰常常幅幅度度式式張張形形待待後後御御性性情情想想意意感感態態成成投投択択拡拡推推提換換敗敗数数整整新新方方既既日日明明時時更更書書替最有有期期本本果果検検標標橙橙機機止正毎毎比比況況注注消消港港湾湾準準無無照照状状率率現現璧璧環環生生用用画画異異的的直直知知確確示示種種稿稿空空索索終終緑緑編編績績能能自自般般行行表表製製複複視視覧覧解解言言設設認認語語読読赤赤起起跡跡転転軸軸込込近近追追送送通通速速進進遅遅遊遊適適選選部部長長閉閉開開関関防防限限除除隅隅集集青青非非面面韓韓音音類類香香高高黄黄++??"
u"……□□△△◯◯✕✕ 。々々「』〜〜ああいいううええおせそそたちっぬのばびびぶぶへべほぼまやょろわわをんァイウチッツテニネロワワンンー一一上下不与世世両両中中乗乗了了予予事事互互交交今介他他付付代以仮仮件件任任伸伸似似位低体体何何作作使使例例供供係係保保信信修修個個倍倍借借値値停停側側備備像像優優元元先光入入全全公公共共具典内内再再冗冗処処出出分切列列初初判別利利制刷則則削削前前副副割割力力加加効効動動勧勧化化区区十十半半南単印印即即去去参参及及反収取古古可台右右号号各各合合同名向向否否含含告告周周味味命命品品商商問問善善四四回回囲囲固固国国圧在地地均均垂垂型型域域基基報報場場境境増増壊壊声声変変外外多多大大太太央央失失奇奇奨奨好好妙妙妨妨始始子子字存安安完完定定実実容容寄寄密密対対射射小小少少尾尾展展岐岐崩崩左左巨巨己己帰帰常常幅幅平平序序度座延延式式引引弱弱張張強強当当形形彩彩影影役役待待後後得得御御復復微微心心必必応応忠忠念念急急性性悪悪情情想想意意感感態態慣慣成成戻戻所所手手打打承承投投択択抱抱押押拒拒招招拡拡拳拳持持指指振振挿挿捗捗排排接接推推提換換揮揮援援揺揺損損撃撃撮撮操操支支改改放放敗敗数数整整文文料料断断新新方方既既日日早早明明時時曲曲更更書書替最有有望望期期未本条条析析果果桁桁案案械械検検極極楽楽概概構構標標権権橙橙機機欄欄欠次止正殊残毎毎比比水水求求汎汎決決況況法法波波注注浪浪浮浮消消深深済済減減渡渡港港湾湾満満源源準準滑滑点為無無照照牲牲特特犠犠状状獲獲率率現現理理璧璧環環生生用用由由申申画画番番異異発登白白的的目目直直相相省省知知短短破破確確示示禁禁秒秒移移程程種種稿稿空空立立端端競競第第算算管管範範精精索索細細終終組組経経結結絞絞統統続続維維緑緒線線編編縦縦縮縮績績繰繰置置義義者者肢肢能能自自致致般般良良色色荷荷落落蔵蔵行行表表衰衰装装製製複複要要見見規規視視覚覚覧覧観観角角解解言言計計記記設設許許訳訳証証試試該詳認認語語誤誤説読調調識識警警象象負負責責費貼質質赤赤起起超超足足跡跡転転軸軸軽軽辞辞込込近近返返追追送送逆逆途途通通速速連連進進遅遅遊遊過過適適選選避避部部配配重量鉄鉄録録長長閉閉開開間間関関閾閾防防降降限限除除陽陽隅隅際際集集離難電電青青非非面面韓韓音音響響頂頂順順領領頻頼題題類類飾飾香香駄駄高高鮮鮮黄黄!!()//12::>?~~"
},
{
"ko-KR", "malgun.ttf", nullptr, "AppleSDGothicNeo.ttc",
// auto update by update_glyph_ranges.py with pcsx2-qt_ko-KR.ts
u""
u"“”……□□▲△▶▶▼▼◀◀◯◯✕✕んん茶茶가각간간갈갈감값강강같같개개거거건건걸걸검겁것것게게겠겠격격견견결결경경계계고곡공공과과관관교교구국군군권권귀귀규규균균그극근근글글금급긍긍기기긴긴길길깁깁깃깃깅깅깊깊까까깝깝깨깨꺼꺼께께꾸꾸끄끄끔끔끝끝나나날날남남낭낮내내낸낸냅냅너너널널넣네넬넬넷넷노녹높놓누누눈눈눌눌뉴뉴느느는는늘늘능능니닉닌닌님닙닛닛다다단단닫달담담당당대대댑댑더더덜덜덤덤덩덩덮덮데덱덴덴델델뎁뎁도독돌돌동동됐됐되되된된될될됨됩두두듀듀듈듈드득든든들들듬듭등등디디딩딩때때떠떠떤떤떨떨또또뛰뛰뛸뛸뜁뜁뜨뜨라락란란랍랍랑랑래랙랜랜램램랫랫량량러럭런런럴럴럼럽렀렀렇렉렌렌렛렛려력련련렬렬렸령로록롤롤롭롭롯롯료료루루룸룸류류률률르르른른를를름름리릭린린릴릴림립릿릿링링마막만만많많말말맞맞매매맨맨맵맵맺맺머머먼먼멀멀멈멈멋멋메메며며면면명명모목못못몽몽무무문문뮬뮬므므미믹민민밀밀밉밉밍밍및및바바반반받밝밥밥방방배백밴밴뱃뱃버버번번벌벌범법벗벗베벡벤벤벨벨벼벽변변별별병병보복본본볼볼부부분분불불붙붙뷰뷰브브블블비빅빈빈빌빌빙빙빛빛빠빠빨빨사삭산산살살삼삽상상새색샘샘생생샷샷서석선선설설성성세섹센센셀셀셈셉셋셋셔셔션션셰셰소속손손솔솔송송쇄쇄쇠쇠쇼쇼수수순순숨숨쉬쉬슈슈스스슬슬습습시식신신실실심십싱싱싶싶쌍쌍쓰쓰쓸쓸씬씬아아안안않않알알암압았앙애액앤앤앨앨앵앵야약양양어어언언얻얼업없었었에에엔엔여역연연열열영영예예오오온온올올옵옵와와완완왑왑외외왼왼요요용용우우운운울울움웁웃웃워워원원월월웨웨웹웹위위유유율율으으은은을을음음응응의의이이인인일읽임입있있자작잘잘잠잠장장재재잿잿저적전전절절점접정정제제젠젠젤젤젯젯져져조족존존종종좋좌죄죄주주준준줄줄줍줍중중즈즉즌즌즐즐즘즘증증지직진진질질짐집짝짝짧짧째째쪽쪽찌찍차착참참창찾채책챕챕처척천천철철첨첩첫첫청청체체쳐쳐초초촬촬최최추축출출춤춥충충춰춰취취츠측치칙칠칠침칩칭칭카카칸칸칼칼캐캐캔캔캘캘캠캡커커컨컨컬컬컴컴케케켓켓켜켜코코콘콘콜콜콩콩쿳쿳쿼쿼퀀퀀퀴퀴큐큐크크큰큰클클큽큽키키킨킨킬킬킵킵킹킹타타탈탈탐탐태택탠탠탬탭터터턴턴텀텀테텍텐텐텔텔템템토토톱톱통통투투툴툴트특튼튼틀틀티틱팀팀팅팅파파팔팔팝팝패패팻팻퍼퍼페펙편편평평포포폴폴폼폼표표푸푸풀풀품품풍풍퓨퓨프프픈픈플플피픽필필핑핑하하한한할할함합핫핫항항해핵했행향향허허헌헌헤헤현현형형호혹혼혼홈홈홍홍화확환환활활황황회획횟횟횡횡효효후후훨훨휠휠휴휴흐흐흔흔희희히히힌힌"
},
{
"zh-CN", "msyh.ttc", nullptr, "Hiragino Sans GB.ttc",
// auto update by update_glyph_ranges.py with pcsx2-qt_zh-CN.ts
u"‘’□□△△○○、。一丁三下不与且且世世丢丢两两个个中中丰丰串串为主么义之之乎乎乐乐乘乘也也了了事二于于互互亚些交交产产享享亮亮亲亲人人什什仅仅介介仍从他他代以们们件价任任份份伍伍休休优优会会传传估估伸伸似似但但位住佑佑体体何何余余作作佣佣佳佳使使例例供供侧侧便便俄俄保保信信修修倍倍值值倾倾假假偏偏做做停停储储像像儿儿允允元元充充先光克克免免入入全全六六兰共关关兵典兼兼内内册再写写冲决况况净净准准减减几几出击函函刀刀刃刃分切列列则则创创删删利利别别到到制刷刹刹前前剪剪副副力力功务动助势势勿勿包包化化匹区十十升升半半协协单单南南占卡卫卫印印即即压压原原去去参参及双反发发取变叠叠口古另另只只可台右右号号各各合吉同后向向吗吗否否含含启启呈呈告告员员味味命命和和哈哈响响哪哪唤唤商商善善器器四四回回因因团团围围国图圈圈在在地地场场址址均均坏坐块块坛坛垂垂型型域域基基堆堆堪堪塔塔填填增增士士声声处处备备复复外外多多够够大大天太失失头头夹夹奇奇奏奏套套奥奥奶奶好好如如始始威威娱娱婴婴媒媒子子字存它它安安完完宏宏官官定定宝实害害家家容容宽宽宿宿寄寄密密富富寸对导导封封射射将将小小少少尔尔尚尚尝尝就就尺尺尼尾局局层层屏屏展展属属崩崩工左巨巨差差己已巴巴希希带帧帮帮常常幅幅幕幕平平并并幸幸序序库底度度延延建建开开异弃弊弊式式引引张张弹强归当录录形形彩彩影影径待很很得得循循微微德德心心必忆志志忙忙快快忽忽态态性性怪怪恢恢息息您您悬悬情情惑惑惯惯意意感感慢慢戏我或或战战截截戳戳户户所扁手手打打托托执执扩扩扫扬扳扳找找技技抑抑抖抗护护拆拆拉拉拍拍拒拒拟拟拦择择括括拳拳持持指指按按挑挑挡挡挪挪振振捕捕损损换换据据掌掌排排接接控掩描提插插握握搜搜摇摇撕撕撤撤播播操擎支支收收改改放放故故效效敏敏散散数数整整文文断断斯新方方旋旋无无日日旧旧时时明明易易星映是是显显晕晕普普晰晰暂暂暗暗曲曲更更替最有有服服期期未未本本机机权权杆杆束束条条来来板板极极果果柄柄某某染染查查栅栅标栈栏栏校校样根格格框框案案档档桥桥检检棕棕榜榜模模橙橙次欧欧止步死死殊殊段段每每比比毫毫水水求求汇汇没没油油法法波波注注泻泻洲洲活活流流浅浅测测浏浏浪浪浮浮海海消消深深混混添添清清港港渲渲游游湖湖湾湾溃溃源源溢溢滑滑满满滤滤演演澳澳激激灰灰灵灵点点烈烈热热焦焦然然煞煞照照片版牌牌牙牙特特状状狂狂独独狼狼猎猎猩猩率率王王玩玩环现班班理理瑞瑞甚甚生生用用由电电画画畅畅界界留留略略疤疤登登白百的的皇皇盖盘目目直直相相省省看看真眠着着知知短短石石码码破破础础硬硬确确碌碌磁磁示示神神禁禁离离种种秒秒积称移移程程稍稍稳稳空空突突窗窗立立站站端端符符第第等等筛筛签签简简算算管管类类粉粉粘粘精精糊糊系系素素索索紫紫纠纠红红级级纯纯纳纳纹纹线线组组细终经经绑绑结结绕绕绘给络绝统统继继绪绪续续维维绿缀缓缓编编缩缩网网罗罗置置美美翻翻考考者者而而耗耗耳耳联联肩肩胖胖能能腊腊自自至致舍舍良良色色节节芬芬英英范范荐荐荷荷莱莱获获菜菜萄萄著著葡葡蓝蓝藏藏虑虑虚虚融融行行衡衡补补表表被被裁裂装装西西要要覆覆观规规视视览觉角角解解触触言言警警计计认认让让议议记记许许论论设访证证诊诊译译试试询询该详语语误误说说请诸读读调调谍谍豹豹负负败账质质贴贴费费赛赛起起超超越越足足跟跟跨跨路路跳跳踏踏踪踪身身车车轨轨转转轮软轴轴轻轻载载较较辅辅辑辑输输辨辨边边达达过过运近还这进进连迟述述追追退适选选逐逐递递通通速造遇遇道道避避那那部部都都配配醒醒采采释释里重量量针针钮钮铁铁铺铺链链销锁锐锐错错键锯镜镜长长门门闭问闲闲间间队队防防阴阴附附陆陆降降限限除除险险随隐隔隔隙隙障障雄雄集集零零雾雾需需震震静静非非靠靠面面韩韩音音顶顶项须顿顿预预频频题题颜额风风饱饱馈馈首首香香马马驱驱验验高高鬼鬼魂魂魔魔麦麦黄黄黑黑默默鼓鼓鼠鼠齐齐齿齿,,??"
u"‘’□□△△○○、。一丁三下不与且且世世丢丢两两个个中中串串为主么义之之乎乎乐乐乘乘也也了了事二于于互互亚些交交产产享享亮亮亲亲人人什什仅仅今今仍从他他代以们们件价任任份份伍伍休休优优会会传传估估伸伸似似但但位住佑佑体体何何余余作作你你佳佳使使例例供供侧侧便便俄俄保保信信修修倍倍借借值值倾倾假假偏偏做做停停储储像像儿儿允允元元充充先光克克免免入入全全六六兰共关关其兹兼兼内内册再写写冲决况况准准减减几几出击函函刀刀刃刃分切列列则则创创删删利利别别到到制刷刹刹前前剪剪副副力力功务动助势势勿勿包包化化匹区十十升升半半协协单单南南占卡卫卫印印即即卸卸压压原原去去参参及双反发发取变叠叠口古另另只只可台右右号号各各合吉同后向向吗吗否否含含启启呈呈告告员员味味命命和和哈哈响响哪哪唤唤商商善善器器四四回回因因团团围围国图圈圈在在地地场场址址均均坏坐块块坛坛垂垂型型域域基基堆堆堪堪塔塔填填增增士士声声处处备备复复外外多多够够大大天太失失头头夹夹奇奇奏奏套套奥奥奶奶好好如如始始威威娱娱婴婴媒媒子子字存它它安安完完宏宏官官定定宝实害害家家容容宽宽宿宿寄寄密密富富寸对导导封封射射将将小小少少尔尔尚尚尝尝就就尺尺尼尾局局层层屏屏展展属属崩崩工左巨巨差差己已巴巴希希带帧帮帮常常幅幅幕幕平平并并幸幸序序库底度度延延建建开开异弃弊弊式式引引张张弹强归当录录形形彩彩影影径待很很律律得得循循微微德德心心必忆志志忙忙快快忽忽态态性性怪怪恢恢息息您您悬悬情情惑惑惯惯想想愉愉意意感感慢慢戏我或或战战截截戳戳户户所扁手手才才打打托托执执扩扩扫扬扳扳找找技技抑抑抖抗护护拆拆拉拉拍拍拒拒拟拟拦择择括括拳拳持持指指按按挑挑挡挡挪挪振振捕捕损损换换据据捷捷掌掌排排接接控掩描提插插握握搜搜摇摇摘摘撕撕撤撤播播操擎支支收收改改放放故故效效敏敏散散数数整整文文断断斯新方方旋旋无无日日旧旧时时明明易易星映是是显显晕晕普普晰晰暂暂暗暗曲曲更更替最有有服服望望期期未未本本机机权权杆杆束束条条来来板板极极果果柄柄某某染染查查栅栅标栈栏栏校校样根格格框框案案档档桥桥检检棕棕榜榜槽槽模模橙橙次欧欧止步死死殊殊段段每每比比毫毫水水求求汇汇没没油油法法波波注注泻泻洲洲活活流流浅浅测测浏浏浪浪浮浮海海消消淡淡深深混混添添清清港港渲渲游游湖湖湾湾溃溃源源溢溢滑滑满满滤滤演演澳澳激激灰灰灵灵点点烈烈热热焦焦然然煞煞照照片版牌牌牙牙特特状状狂狂独独狼狼猎猎猩猩率率王王玩玩环现班班理理瑞瑞甚甚生生用用由电电画画畅畅界界留留略略疤疤登登白百的的皇皇盖盘目目直直相相省省看看真眠着着知知短短石石码码破破础础硬硬确确碌碌磁磁示示神神禁禁离离种种秒秒积称移移程程稍稍稳稳空空突突窗窗立立站站端端符符第第等等答答筛筛签签简简算算管管类类粉粉粘粘精精糊糊系系素素索索紫紫纠纠红红级级纳纳纹纹线线组组细终经经绑绑结结绕绕绘给络绝统统继继绪绪续续维维绿缀缓缓编编缩缩缺缺网网罗罗置置美美翻翻考考者者而而耗耗耳耳联联肩肩胖胖能能腊腊自自至致舍舍航航良良色色节节芬芬英英范范荐荐荷荷莱莱获获菜菜萄萄著著葡葡蓝蓝藏藏虑虑虚虚融融行行衡衡补补表表被被裁裂装装西西要要覆覆观规规视视览觉角角解解触触言言警警计计认认让让议议记记许许论论设访证证识识诊诊译译试试询询该详语语误误说说请诸读读调调谍谍豹豹负负败账质质贴贴费费赛赛赫赫起起超超越越足足跃跃跟跟跨跨路路跳跳踏踏踪踪身身车车轨轨转转轮软轴轴轻轻载载较较辅辅辑辑输输辨辨边边达达过过迎迎运近还这进进连迟述述追追退适逆逆选选逐逐递递通通速造遇遇道道避避那那邻邻部部都都配配醒醒采采释释里重量量针针钮钮铁铁铺铺链链销锁锐锐错错键锯镜镜长长门门闭问闲闲间间阅阅队队防防阴阴附陆降降限限除除险险随隐隔隔隙隙障障雄雄集集零零雾雾需需震震静静非非靠靠面面韩韩音音顶顶项须顿顿预预频频题题颜额风风饱饱馈馈首首香香马马驱驱骤骤高高鬼鬼魂魂魔魔麦麦黄黄黑黑默默鼓鼓鼠鼠齐齐齿齿,,::??"
},
{
"zh-TW", "msyh.ttc", nullptr, "Hiragino Sans GB.ttc",
// auto update by update_glyph_ranges.py with pcsx2-qt_zh-TW.ts
u""
u"、。一一上下不不且且並並中中主主了了互互今今令以件件任任位位何何使使來來係係保保個個優優儲儲免免入入內全具具兼兼冊冊再再到到創創功加助助動動務務勢勢包包協協南南及及取取只只可可合合名名和和商商問問啟啟嘗嘗器器嚮嚮在在壇壇多多失失如如始始娛娛存存它它安安完完官官定定容容密密將將對導就就尼尼局局希希幫幫序序庫庫建建後後得得從從您您情情意意態態應應成成戲戲戶戶所所持持指指接接擇擇擬擬支支改改敗敗新新方方於於是是時時更更會會有有服服望望本本果果查查樂樂標標模模機機檢檢次次歡步沒沒況況消消源源為為然然版版牌牌狀狀獲獲玩玩現現理理生生用用界界登發的的看看硬硬確確碼碼程程種種站站第第管管系系索索組組絡絡統統網網緒緒編編置置而而聯聯能能自自與與虛虛裝裝要要解解言言訪訪設設許許註註試試該該認認語語誤誤請請論論譯議費費起起載載輸輸迎迎這通連連遊遊過過選選配配釋釋重重錄錄錯錯鏈鏈開開間間關關防防附附需需面面項項題題驟驟默默"
},
};
// clang-format on
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff

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