Compare commits

...
138 Commits
Author SHA1 Message Date
Connor McLaughlin fac171fa95 CDVD: Check file actually opened before proceeding
If you loaded an invalid file, particularly with compression, the file
open may fail, leading to a division by zero (on block size), or trying
to read from nothing.
2021-12-18 13:41:56 +00:00
refractionpcsx2 fa1b6493da CDVD GZip: Correct type causing index creation to fail 2021-12-17 11:46:31 +00:00
refractionpcsx2 e58766745c Log: Restore BIOS Found message 2021-12-16 11:45:12 +00:00
Mrlinkwii d8a9c5b479 Gamedb add gamefixes to 'Titeuf Mega-compet' and patch 'Yamiyo ni Sasayaku - Tantei Sagara Kyouichirou' series 2021-12-15 17:17:18 +00:00
Mrlinkwii 9a4d8ba934 Gamedb: add more 2k games patches 2021-12-15 10:52:22 +00:00
refractionpcsx2 ab816543c8 CDVD: Fixed typo opening gzip files
Fixes #5162
2021-12-15 09:38:04 +00:00
refractionpcsx2 37ccd81985 GS: Avoid some unnecessary flushes
CLUT only updates if valid index type used in PSM
2021-12-14 18:28:21 +00:00
refractionpcsx2 42dad4ade8 GS: Check CLUT dirty write on vertex kick 2021-12-14 18:28:21 +00:00
refractionpcsx2 b2ac035862 VS: Fix location of shaders in project 2021-12-14 17:47:53 +00:00
refractionpcsx2 f42d7eec74 CDVD: Don't set as Reading when buffering. 2021-12-14 10:35:12 +00:00
refractionpcsx2 e4ef41f86a CDVD: Fix some read timing logic 2021-12-14 10:35:12 +00:00
Mrlinkwii 103dd3954a missing UI and game elements. 2021-12-14 09:22:31 +00:00
Tokman5 2f9577a28e Add "Jikkyou Powerful Pro Yakyuu 2009" to GameIndex.yaml 2021-12-14 08:06:34 +00:00
Gauvain 'GovanifY' Roussel-Tarbouriech 33ec4d9430 msvc: fix issues with size() not being correctly evaluated as const 2021-12-13 09:34:24 +00:00
Gauvain 'GovanifY' Roussel-Tarbouriech 209f09ca7a pine: send serial without gui beautification 2021-12-13 09:34:24 +00:00
Gauvain 'GovanifY' Roussel-Tarbouriech 2e6af75f1d pine: add vle replies 2021-12-13 09:34:24 +00:00
Gauvain 'GovanifY' Roussel-Tarbouriech f68122a380 ipc: rename to pine 2021-12-13 09:34:24 +00:00
TellowKrinkle d51bdccf7f CMake: Remove gio dependency on macOS 2021-12-13 03:29:16 -06:00
iMineLink 7d8377b133 GS-hw: define some consts only in debug mode. 2021-12-13 08:06:52 +01:00
iMineLink 80d3a8a757 GS-hw, TC: don't linearly interpolate downloads.
Greatly improves Burnout games clouds rendering
with even (x2, x4, ...) upscaling factors.
2021-12-13 08:06:52 +01:00
iMineLink 2e6c5cde29 GS-hw: rework surface fetching.
Factorized code.
Always clear render targets and depth stencils
when being fetched.
"force_texture_clear" OGL only config removed.
2021-12-13 08:06:52 +01:00
iMineLink 0f2768dca4 GS-hw, TC: improve LookupTarget.
allow propagation of increased target size and
correct the rescaling.
2021-12-13 08:06:52 +01:00
iMineLink d5be095482 GS-hw: fix burnout black sky and no clouds.
Achieved with a combination of OI+OO hacks that operate
during level loading to consolidate the rendering results
in the GS local memory.

* OI_BurnoutGames to perform small draws directly in local memory:
** improved OI_PointListPalette to draw clouds CLUT,
** improved SwSpriteRender to draw sky texture;
* OO_BurnoutGames used to download clouds texture from GPU.
2021-12-13 08:06:52 +01:00
iMineLink b315625a94 GS-hw: resize rt and ds before draw if necessary. 2021-12-13 08:06:52 +01:00
iMineLink 6b51462fa0 GS-hw: use CanUpscale to check for upscaling. 2021-12-13 08:06:52 +01:00
iMineLink 373e698545 GS-hw, TC: fix tex scaling for native res draws.
The GSTextureCache::ScaleTexture method did not work
correctly when an old texture with a scale factor
different from 1 was recycled for a draw which was forced at
native resolution (the old scale factor was kept).
2021-12-13 08:06:52 +01:00
iMineLink 3b309c6d4e GS: dump alpha channel too. 2021-12-13 08:06:52 +01:00
kenshen112 8e93e9f516 CMake: Switch Wayland find script and usage to use imported targets
Also clears warning about mismatched names getting sent to FIND_PACKAGE_HANDLE_STANDARD_ARGS
2021-12-13 00:23:52 -06:00
kenshen112 ac8582eca7 CMake: Set minimum version first
Makes policy enabling based on minimum version work properly
Also increases minimum version to 3.11 because we actually do use 3.11 features
2021-12-13 00:23:52 -06:00
kenshen112 e6f72fdde7 GHActions: Enable Wayland in CI builds 2021-12-13 00:23:52 -06:00
Connor McLaughlin 9166218d07 EERec: Remove zero-distance jmp in full fpu mode 2021-12-13 00:56:50 +00:00
Mrlinkwii c0b1bde94b Gamedb: add EEclamping to 'Dark cloud 2' 2021-12-12 22:31:30 +00:00
Mrlinkwii 756a679262 Gamdb:add EE clamping to 'Chou Saisoku! Zokusha King B.U.' 2021-12-12 21:35:54 +00:00
Mrlinkwii 13b19b35c0 GameDB: add patches to the 'Netsu Chu!' series and 'Samurai 7' series 2021-12-12 18:16:46 +00:00
Mrlinkwii cadb70d1e4 Gamedb: add EEtiminghack to 'MGS2' and change VU and EE rounding for 'Primal' and add missing entries 2021-12-12 12:30:47 +00:00
TellowKrinkle 4cb4844e8d AppImage: Fix resource location 2021-12-12 06:10:47 -06:00
TellowKrinkle 556c7ca080 CMake: Don't include non-windows files on non-windows 2021-12-12 06:10:47 -06:00
TellowKrinkle 962db4bfc4 Resources: Move fxaa.fx to out of dx11 directory
It was used by both DX and OGL
2021-12-12 06:10:47 -06:00
TellowKrinkle da651cabe4 Resources: Move shaders to shared shader/ directory 2021-12-12 06:10:47 -06:00
TellowKrinkle e03076c6ff CMake: Fix macOS resource packaging
Previously was just putting in empty folders
2021-12-12 06:10:47 -06:00
refractionpcsx2 122968e63a CDVD: No rotational delay for seeks less than buffered sectors
Fixes Shadow Hearts Covenant hangs
2021-12-12 06:33:01 +00:00
Connor McLaughlin 6beac26727 GS/OpenGL: Fix an unused variable warning 2021-12-12 03:27:43 +00:00
Connor McLaughlin 3073281d13 CMake: Fix package mode 2021-12-12 03:27:43 +00:00
TellowKrinkle 0e0e23eefb PAD: Use files on disk instead of embedded resources 2021-12-12 03:27:43 +00:00
Connor McLaughlin bcec38bd97 Patch: Make variables static 2021-12-12 03:27:43 +00:00
Connor McLaughlin bd706f99b2 GlobalCommands: Remove FreezeGS
This was ifdefed out anyway...
2021-12-12 03:27:43 +00:00
Connor McLaughlin 501af632f7 IopBios: Use FileSystem for host access 2021-12-12 03:27:43 +00:00
Connor McLaughlin a143122804 CI: Copy resources into AppImage 2021-12-12 03:27:43 +00:00
Connor McLaughlin 92aa426bba Move cheats_ws.zip to resources directory 2021-12-12 03:27:43 +00:00
Connor McLaughlin 96a1ce2fb2 CI: Fix path to GameIndex.yaml 2021-12-12 03:27:43 +00:00
Connor McLaughlin c203a09435 Wx: Add check for resources directory before starting 2021-12-12 03:27:43 +00:00
Connor McLaughlin c4084b4162 Add PerformanceMetrics to replace multiple sources of truth 2021-12-12 03:27:43 +00:00
Connor McLaughlin 2a7c948a57 GameDatabase: Store enums instead of strings 2021-12-12 03:27:43 +00:00
Connor McLaughlin 46912595ea GameDatabase: Move out of gui 2021-12-12 03:27:43 +00:00
Connor McLaughlin 120ee6c673 Get rid of wxChar in EnumToString 2021-12-12 03:27:43 +00:00
Connor McLaughlin 112238fbd7 Config: Add cache folder 2021-12-12 03:27:43 +00:00
Connor McLaughlin 38e288ef6a Common: Add utility classes 2021-12-12 03:27:43 +00:00
Connor McLaughlin 35322cf49b BiosTools: Add autoloader 2021-12-12 03:27:43 +00:00
Connor McLaughlin 8d44e1af0e CDVD: Remove wx from file access 2021-12-12 03:27:43 +00:00
Connor McLaughlin 16af078b3b BiosTools: Remove wx 2021-12-12 03:27:43 +00:00
Connor McLaughlin 3e968b4390 GS: Use files on disk instead of embedded resources 2021-12-12 03:27:43 +00:00
Connor McLaughlin 0029dac32d Host: Add the ability to read files from the resources directory 2021-12-12 03:27:43 +00:00
Connor McLaughlin a083343c6e Common: Add FileSystem 2021-12-12 03:27:43 +00:00
refractionpcsx2 c277ee1d34 GS: D3D11 Download texture use rect 2021-12-10 11:06:36 +00:00
refractionpcsx2 ebe8592a8d GS: Fix typo on GS download
Fixes #5131
2021-12-10 09:49:50 +00:00
lightningterror 6c3e357d9e GS-ogl: Optimize fragment shader uniform buffer.
Couple MaxDepthPS with TA and Af vector.

Vectors are free so let's use them.

Optimization.
2021-12-10 03:44:47 +01:00
TellowKrinkle 64455620e8 GS: Use actual names for GL convert shaders 2021-12-09 05:26:26 -06:00
TellowKrinkle fc799778de GS: Use actual names for DX11 convert shaders 2021-12-09 05:26:26 -06:00
TellowKrinkle e04e0e38d1 GS:GL: Move TextureOffset to vs cb
It's used by the vs, why would you put it in the ps cb?
2021-12-09 05:26:26 -06:00
TellowKrinkle 8d6569be95 GS: Remove separate GSTextureCaches 2021-12-09 05:26:26 -06:00
TellowKrinkle 8b086a3898 Common: Clean up ScopedAlloc 2021-12-09 05:26:26 -06:00
TellowKrinkle a4b8c33cf3 GS: Convert texture format to enum 2021-12-09 05:26:26 -06:00
TellowKrinkle 1d37ba47f4 GS: Make GSTexture::Type an enum class 2021-12-09 05:26:26 -06:00
TellowKrinkle 8d480c28ce GS: Remove unused virtuals from GSDevice 2021-12-09 05:26:26 -06:00
TellowKrinkle 6e38f40f96 GS: Convert ShaderConvert to enum class 2021-12-09 05:26:26 -06:00
arcum42 017c37f212 Only pass C++ flags to C++ files. (#5115) 2021-12-08 21:10:21 -08:00
TellowKrinkle 6eee4cb38a Core: Remove empty file
Had everything commented out and there's already a file with the same name and things not commented out in CDVD
2021-12-08 11:18:42 +00:00
TellowKrinkle 1f6a14261c VS: Add missing filters 2021-12-08 11:18:42 +00:00
refractionpcsx2 14e8d840ff GS SW: Handle flat prims without float conversion 2021-12-08 10:57:00 +00:00
lightningterror 125b9ea1e1 GS-hw: Purge SoTC crc hack.
No longer needed, fixed by #5110
2021-12-08 11:48:29 +01:00
lightningterror e6b1e1948e GS-d3d11: Add a condition to not enable blend_mix if sw blending is already enabled.
Not yet needed but will be useful for sw blending when prims don't overlap.
2021-12-08 11:36:22 +01:00
lightningterror ba1072f470 GS-ogl: Don't enable blend_mix if sw blend is already enabled.
Less accurate.
2021-12-08 11:36:22 +01:00
lightningterror 1fb29de082 GS-ogl: Try to use a mix of hw/sw blending in more situations.
When alpha is less than 128:
Do Cs*F or Cs*As in shader.
Do Cs*(As + 1) or Cs*(F + 1) in shader.
Do Cs*(1 - As) or Cs*(1 - F) in shader.

Optimization, might be faster as we will require less barriers.
2021-12-08 11:36:22 +01:00
lightningterror f79e5ab559 GS-d3d11: Try to use a mix of hw/sw blending in more situations.
When alpha is less than 128:
Do Cs*F or Cs*As in shader.
Do Cs*(As + 1) or Cs*(F + 1) in shader.
Do Cs*(1 - As) or Cs*(1 - F) in shader.
2021-12-08 11:36:22 +01:00
Mrlinkwii c3a9fd469e GameDB: add VU clamping to 'MVP Baseball 2003' 2021-12-08 10:29:05 +00:00
Mrlinkwii c8abc909fa GameDB:add EEclamping full to 'Shinobido Takumi' 2021-12-07 20:00:15 +00:00
Mrlinkwii 401a9f4c62 GameDB: add patches to the 'K-1 World' series games and EE clamping full to 'D1 Professional Drift Grand Prix Series' 2021-12-07 15:51:13 +00:00
lightningterror f1edb0c960 GS-ogl: Disable accumulation blend on PABE.
Requires accurate sw blending.
2021-12-07 10:12:58 +01:00
lightningterror d73335e4d3 GS-d3d11: Don't enable PABE on accumulation blend.
Requires full sw blending.
2021-12-07 10:11:02 +01:00
TellowKrinkle 7a554be7a7 GS: Fix compiler warning and possible memory leak on exception 2021-12-06 05:44:16 +01:00
TellowKrinkle 31b6ff6046 GS: Use static_assert over assert where possible 2021-12-06 05:44:16 +01:00
lightningterror 38ab0630e6 GS-ogl: Update SetupCBMisc buffer only when GXBY channel is used, and cleanup some variables.
Optimization.
2021-12-06 03:15:48 +01:00
lightningterror b5fa9deb30 GS-d3d11: Update ChannelShuffle buffer only when GXBY channel is used, and cleanup some variables.
Optimization.
2021-12-06 03:15:48 +01:00
lightningterror 4e8bae1703 GS-ogl: Sample depth on green channel. 2021-12-06 03:15:48 +01:00
lightningterror 464ce1c3cd GS-d3d11: Sample depth on green channel. 2021-12-06 03:15:48 +01:00
lightningterror bb55c320c1 GS Debugger: Fix Length of dump. 2021-12-05 10:57:24 +01:00
TheLastRar af585bffa9 DEV9: Add DEV9: prefix to "Can't open Device" log message 2021-12-05 03:53:33 +01:00
TheLastRar bde4868b67 DEV9: Enable pcap non-blocking 2021-12-05 03:53:33 +01:00
TheLastRar 3835fc5ad1 DEV9: Don't shadow return value of GetAdaptersAddresses 2021-12-04 06:09:01 +01:00
Tyler Wilding 7b815b5f07 actions: increase linux build times as well until cache is reliable
We can rely on the cache more once the following issue is resolved - https://github.com/actions/cache/issues/342#issuecomment-673371329

Once we can, we should be able to dynamically set the timeout according to the cache-hit/miss
2021-12-04 06:05:38 +01:00
Tyler Wilding 754c6126b1 actions: Only announce pre-release releases in the discord 2021-12-04 05:57:05 +01:00
Mrlinkwii 2dc2a32e45 GameDB: add 'VUKickstartHack' to 'Crash Twinsanity' 2021-12-04 02:56:22 +00:00
lightningterror 7a579303b9 GS-d3d11:fx: Split color clamp/wrap in it's own function.
Use the function for both sw blending and dithering, less code duplication.
2021-12-03 19:59:29 +01:00
lightningterror 03401e377b GS-ogl:glsl: Split color clamp/wrap in it's own function.
Use the function for both sw blending and dithering, less code duplication.
2021-12-03 19:59:29 +01:00
Ziemas ff4ec6d843 SPU: Change dummy SP check for consistency 2021-12-03 19:37:19 +01:00
Ziemas 0dc3dcd9ed SPU: Start the sample pointer at -1
This makes videos in Stolen work again.
2021-12-03 19:37:19 +01:00
Ziemas ed3237f808 SPU: Use hex values for sample pointer 2021-12-03 19:37:19 +01:00
Tyler Wilding 9321c3c334 gh: remove 32-bit Windows 11, it doesn't exist 2021-12-03 19:24:05 +01:00
Tyler Wilding adc7d41183 gh: add minimal issue template for issues that don't pertain to games
A lot of the required information we enforce is not applicable to application level bugs
2021-12-03 19:24:05 +01:00
Tyler Wilding 4ca69d8818 gh: Update issue-templates to include Win11 2021-12-03 19:24:05 +01:00
Mrlinkwii cca52e271b Gamedb: add 'VIFFIFOHack' to 'Men in Black II: Alien Escape' 2021-12-02 19:29:28 +00:00
TellowKrinkle a2e15bbc87 GHActions:macos: Install glib
Looks like GHActions changed what things they preinstall
2021-12-02 15:08:18 +01:00
Mrlinkwii 9d6ad0303c GameDB: Add fixes for 'Shadow Man - 2econd Coming' and 'Ghosthunter' games. 2021-12-02 14:01:47 +00:00
Mrlinkwii bbaa23c22d Readme : update links 2021-12-01 22:43:36 +00:00
Ziemas bacb860cc1 GUI: Allow relative elf file paths on command line. (#4451) 2021-11-30 10:06:17 +01:00
Ziemas 7a4191e16d Fix compilation with LTO on GCC 2021-11-30 02:25:06 +00:00
PCSX2 Bot 0fa620e3ba pad-linux: Update to latest controller database. 2021-11-29 17:17:26 +01:00
dependabot[bot] 96642d8bc3 Bump mathieudutour/github-tag-action from 5.6 to 6.0
Bumps [mathieudutour/github-tag-action](https://github.com/mathieudutour/github-tag-action) from 5.6 to 6.0.
- [Release notes](https://github.com/mathieudutour/github-tag-action/releases)
- [Commits](https://github.com/mathieudutour/github-tag-action/compare/v5.6...v6.0)

---
updated-dependencies:
- dependency-name: mathieudutour/github-tag-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-29 16:01:55 +01:00
dependabot[bot] 8a26c3783a Bump actions/cache from 2.1.6 to 2.1.7
Bumps [actions/cache](https://github.com/actions/cache) from 2.1.6 to 2.1.7.
- [Release notes](https://github.com/actions/cache/releases)
- [Commits](https://github.com/actions/cache/compare/v2.1.6...v2.1.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-29 13:21:27 +00:00
lightningterror d2742a177c GS-d3d11: Properly set afix in EmulateBlending.
Accumulation blend -> afix is already handled in shader, no need to set it for hw blending too.
SW blending -> done in shader.
HW blending - > set only when it is actually used, Alpha C.

GS-d3d11: Properly set afix in EmulateBlending.

Accumulation blend -> afix is already handled in shader, no need to set it for hw blending too.
SW blending -> done in shader.
HW blending - > set only when it is actually used, Alpha C.
2021-11-26 21:25:16 +01:00
TellowKrinkle 6d4713e069 GS: Alloc sw renderer things on custom heap 2021-11-26 13:44:07 -06:00
TellowKrinkle 342170b077 GS: Add new heap for SW renderer allocations 2021-11-26 13:44:07 -06:00
TellowKrinkle df02d784d6 GS: Throw from vmalloc on failure 2021-11-26 13:44:07 -06:00
tellowkrinkle 340874996e CMake: Always default CMAKE_BUILD_PO off
Git files getting modified by build is just as much of a pain in release builds as it is in devel builds
2021-11-26 13:02:25 -06:00
lightningterror 3bd89154d3 GS-wx: Fix some gui interaction.
Fix interaction of Anisotropic filtering with Nearest Texture Filtering and GPU Palette Conversion.
Fix interaction of Trilinear Filtering with selected renderer.

Options should gray out properly now.
2021-11-26 18:32:58 +00:00
Connor McLaughlin 1e198fbb83 GS/OpenGL: Use CreateRenderTarget() for temp HDR target
Probably won't change much, except maybe with sparse textures,
where it'll use less video memory.
2021-11-25 23:26:31 +01:00
TellowKrinkle 01855fc66a GHActions: Don't shallow clone submodules
Shallow clones tend to be 5-10s slower
2021-11-24 15:43:56 -06:00
refractionpcsx2 7ac045b5e2 GS: Partial revert of #5061 2021-11-24 01:01:55 +00:00
lightningterror 03f1617ff5 GS-GSState: Mask out AA1 on triangles.
AA1 is not supported on hw renderers so ignore flushing the prims on triangles.

Should provide a nice speed boost on games that use AA1 on triangle prims.
2021-11-24 00:14:03 +01:00
lightningterror c75b20e37d GS-hw: Also disable Blending when AA1 and ABE or PABE are both set on lines.
There's no need to blend them since there is no implementation.
2021-11-24 00:14:03 +01:00
lightningterror 08f72596d4 GS-hw: EmulateBlending move early return to the top.
Optimization.
2021-11-24 00:14:03 +01:00
lightningterror dcd1f90ae7 GS-hw: Disable Z writes on AA1 flag when prim are lines.
When AA1 flag is enabled Z is not written on lines since coverage is always less than 0x80.
2021-11-24 00:14:03 +01:00
lightningterror c10603d161 GS-hw: Disable alpha blending when only AA1 flag is enabled.
There is no hw implementation of AA1.

Alpha blending shouldn't be enabled by AA1 flag, only ABE and PABE flags.
2021-11-24 00:14:03 +01:00
Mrlinkwii 7ea335e59b GameDB : fix Fuuraiki 2 patch 2021-11-23 11:55:23 +00:00
lightningterror d20cb91d90 Gs-d3d11:fx: Adjust sw blend shader a bit.
Use As and Cs in pabe code, makes more sense.

Get rid of Cv vector, use Color parameter for operations instead like on gl.
2021-11-23 09:02:54 +01:00
lightningterror e38d754e86 Gs-ogl:glsl: Adjust sw blend shader a bit.
Get rid of Color_pabe vector, makes more sense to use As and Cs in pabe code.
2021-11-23 09:02:54 +01:00
refractionpcsx2 afacc47f33 CDVD: Adjust DMA timing based on PS1 timings.
Bus width is 16bit on the PS2 and 8bit on PS1, so serves to reason the DMA would be twice the speed. (PS1 is 24 cycle per word)
2021-11-22 22:18:32 +00:00
refractionpcsx2 5803cc441e GS: Improve FixedTEX0 accuracy 2021-11-22 22:17:59 +00:00
199 changed files with 6771 additions and 3907 deletions
@@ -0,0 +1,81 @@
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
name: Application Bug Report
description: Found a problem with the application itself (ie. bad file path handling, UX issue)? Help us improve it.
title: "[BUG]: "
labels: [Bug]
# assignees:
# - octocat
body:
- type: markdown
attributes:
value: |
## Important: Read First
Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only
If you need help configuring the emulator please make a request on our forums or contact us on discord
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php)
Please make an effort to make sure your issue isn't already reported
### Please Avoid Issues Pertaining to the Following:
- We are **not** accepting bug reports for **PSX mode** at this time
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use a [proper PSX emulator](https://emulation.gametechwiki.com/index.php/PlayStation_emulators)
- We do **not** accept issues relating to **upscaling** at this time
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling
- Please try your game at native resolution before creating an issue
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues
- type: textarea
id: desc
attributes:
label: Describe the Bug
description: "A clear and concise description of what the bug is"
validations:
required: true
- type: textarea
id: repro
attributes:
label: Reproduction Steps
description: "Steps to reproduce the behavior"
validations:
required: true
- type: textarea
id: expect
attributes:
label: Expected Behavior
description: "A clear and concise description of what you expected to happen"
validations:
required: false
- type: input
id: rev
attributes:
label: PCSX2 Revision
description: "Please ensure you are on the latest version before making an issue"
placeholder: "Example: v1.7.1337"
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating System
options:
- Windows 11
- Windows 10 (32bit)
- Windows 10 (64bit)
- Windows 8.1 (32bit)
- Windows 8.1 (64bit)
- Linux (32bit) - Specify Distro Below
- Linux (64bit) - Specify Distro Below
- macOS (Monteray)
- macOS (BigSur)
- macOS (Catalina)
- macOS (Mojave)
validations:
required: true
- type: input
id: os-distro
attributes:
label: If Linux - Specify Distro
placeholder: "Example: Arch"
validations:
required: false
@@ -1,6 +1,6 @@
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
name: Bug Report
description: Found a problem? Help us improve.
name: Emulation Bug Report
description: Problem in a game (ie. graphical artifacts, crashes)? Help us improve it.
title: "[BUG]: "
labels: [Bug]
# assignees:
@@ -69,7 +69,7 @@ body:
attributes:
label: PCSX2 Revision
description: "We only accept bug reports for the latest dev version. Please try upgrading before making an issue."
placeholder: "Example: dev-525"
placeholder: "Example: v1.7.1337"
validations:
required: true
- type: dropdown
@@ -77,6 +77,7 @@ body:
attributes:
label: Operating System
options:
- Windows 11
- Windows 10 (32bit)
- Windows 10 (64bit)
- Windows 8.1 (32bit)
+2 -2
View File
@@ -84,7 +84,7 @@ jobs:
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
timeout-minutes: 30
timeout-minutes: 60
env:
CCACHE_BASEDIR: ${{ github.workspace }}
@@ -118,7 +118,7 @@ jobs:
message("::set-output name=timestamp::${current_date}")
- name: ccache cache files
uses: actions/cache@v2.1.6
uses: actions/cache@v2.1.7
with:
path: .ccache
key: ${{ matrix.os }} ${{ matrix.platform }} ${{ matrix.compiler }}${{ matrix.detail }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
+1 -1
View File
@@ -99,7 +99,7 @@ jobs:
run: |
# To save time, only brew update if running the install without it fails
function do-install() {
brew install sound-touch portaudio wxmac sdl2 libsamplerate
brew install sound-touch portaudio wxwidgets sdl2 libsamplerate
}
if ! do-install; then
brew update
@@ -33,7 +33,7 @@ jobs:
# - https://github.community/t/github-actions-workflow-not-triggering-with-tag-push/17053/7
- name: Bump Version and Push Tag
id: tag_version
uses: mathieudutour/github-tag-action@v5.6
uses: mathieudutour/github-tag-action@v6.0
with:
github_token: ${{ secrets.BOT_PAT }}
tag_prefix: v
+1 -2
View File
@@ -49,9 +49,8 @@ chmod a+x ./squashfs-root/usr/optional/exec.so
echo "$name" > "$GITHUB_WORKSPACE"/squashfs-root/version.txt
mkdir -p "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app
cp -r "$GITHUB_WORKSPACE"/bin/Langs "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/
cp -r "$GITHUB_WORKSPACE"/bin/resources "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app/
cp "$GITHUB_WORKSPACE"/bin/docs/{Configuration_Guide.pdf,PCSX2_FAQ.pdf} "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app
cp "$GITHUB_WORKSPACE"/bin/cheats_ws.zip "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app
cp ./bin/GameIndex.yaml "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app/GameIndex.yaml
cp /usr/lib/$LIBARCH/libthai.so.0 "$GITHUB_WORKSPACE"/squashfs-root/usr/lib/
cp --dereference /usr/lib/"$LIBARCH"/libstdc++.so.6 "$GITHUB_WORKSPACE"/squashfs-root/usr/optional/libstdc++/libstdc++.so.6
cp --dereference /lib/"$LIBARCH"/libgcc_s.so.1 "$GITHUB_WORKSPACE"/squashfs-root/usr/optional/libgcc_s/libgcc_s.so.1
@@ -20,6 +20,7 @@ cmake \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_BUILD_TYPE=Release \
-DPACKAGE_MODE=TRUE \
-DWAYLAND_API=TRUE \
-DDISABLE_ADVANCE_SIMD=TRUE \
-DCMAKE_INSTALL_LIBDIR="/tmp/" \
-DCMAKE_INSTALL_DATADIR="/tmp/" \
@@ -1,7 +1,14 @@
import { MessageEmbed, WebhookClient } from "discord.js";
import * as github from '@actions/github';
const assets = github.context.payload.release.assets;
const releaseInfo = github.context.payload.release;
if (!releaseInfo.prerelease) {
console.log("Not announcing - release was not a pre-release (aka a Nightly)");
process.exit(0);
}
const assets = releaseInfo.assets;
let windowsAssetLinks = "";
let linuxAssetLinks = "";
@@ -34,10 +41,10 @@ const embed = new MessageEmbed()
.setColor('#FF8000')
.setTitle('New PCSX2 Nightly Build Available!')
.addFields(
{ name: 'Version', value: github.context.payload.release.tag_name, inline: true },
{ name: 'Release Link', value: `[Github Release](${github.context.payload.release.html_url})`, inline: true },
{ name: 'Version', value: releaseInfo.tag_name, inline: true },
{ name: 'Release Link', value: `[Github Release](${releaseInfo.html_url})`, inline: true },
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true },
{ name: 'Included Changes', value: github.context.payload.release.body, inline: false }
{ name: 'Included Changes', value: releaseInfo.body, inline: false }
);
if (windowsAssetLinks != "") {
@@ -1,7 +1,7 @@
import yaml
# Assumes this is ran from the root of the repository
file_path = "./bin/GameIndex.yaml"
file_path = "./bin/resources/GameIndex.yaml"
# These settings have to be manually kept in sync with the emulator code unfortunately.
# up to date validation should ALWAYS be provided via the application!
+1
View File
@@ -79,6 +79,7 @@ oprofile_data/
/bin/PCSX2-linux.sh
/bin/GS*.txt
/bin/bios
/bin/cache
/bin/dumps
/bin/help
/bin/inis
-5
View File
@@ -1,23 +1,18 @@
[submodule "3rdparty/xz/xz"]
path = 3rdparty/xz/xz
url = https://github.com/PCSX2/xz.git
shallow = true
[submodule "3rdparty/gtest"]
path = 3rdparty/gtest
url = https://github.com/google/googletest.git
shallow = true
[submodule "3rdparty/fmt/fmt"]
path = 3rdparty/fmt/fmt
url = https://github.com/fmtlib/fmt.git
shallow = true
[submodule "3rdparty/yaml-cpp/yaml-cpp"]
path = 3rdparty/yaml-cpp/yaml-cpp
url = https://github.com/jbeder/yaml-cpp.git
shallow = true
[submodule "3rdparty/libchdr/libchdr"]
path = 3rdparty/libchdr/libchdr
url = https://github.com/rtissera/libchdr.git
shallow = true
[submodule "3rdparty/wil"]
path = 3rdparty/wil
url = https://github.com/microsoft/wil.git
+4 -13
View File
@@ -1,13 +1,9 @@
# Project Name
project(Pcsx2)
# Debian-based distributions require at least 2.8.5 due to multiarch.
# Bumping up to 3.0 seems reasonable at this point, and will let us modernize
# things a bit.
#
# Setting it to a range tells it that it supports the features on the newer
# versions as well, avoiding setting policies.
cmake_minimum_required(VERSION 3.10...3.17)
cmake_minimum_required(VERSION 3.11...3.22)
# Project Name
project(Pcsx2)
# Variable to check that people use the good file
set(TOP_CMAKE_WAS_SOURCED TRUE)
@@ -58,11 +54,6 @@ endif()
# Install some files to ease package creation
if(PACKAGE_MODE)
if(NOT DISABLE_CHEATS_ZIP)
INSTALL(FILES "${CMAKE_SOURCE_DIR}/bin/cheats_ws.zip" DESTINATION "${CMAKE_INSTALL_DATADIR}/PCSX2")
endif()
INSTALL(FILES "${CMAKE_SOURCE_DIR}/bin/GameIndex.yaml" DESTINATION "${CMAKE_INSTALL_DATADIR}/PCSX2")
# set categories depending on system/distribution in pcsx2.desktop
if(openSUSE)
set(PCSX2_MENU_CATEGORIES "System;Emulator;")
+1 -1
View File
@@ -15,7 +15,7 @@ The latest officially released stable version is version 1.6.0.
Installers and binaries for both Windows and Linux are available from [our website](https://pcsx2.net/download.html).
Development builds are also available from [our website](https://pcsx2.net/download/development.html).
Development builds are also available from [Github](https://github.com/PCSX2/pcsx2/releases).
## System Requirements
-2
View File
@@ -57,8 +57,6 @@ Sys_TakeSnapshot = F8
Sys_RenderswitchToggle = F9
Sys_LoggingToggle = F10
# The FreezeGS function is currently disabled internally.
Sys_FreezeGS = F11
Sys_RecordingToggle = F12
GSwindow_CycleAspectRatio = F6
@@ -48,6 +48,12 @@ PAPX-90223:
PAPX-90231:
name: "Kaitou Sly Cooper [Demo, Taikenban]"
region: "NTSC-J"
PAPX-90506:
name: "Dark Chronicle[Demo, Taikenban]"
region: "NTSC-J"
compat: 5
clampModes:
eeClampMode: 3 # Fixes textbox.
PAPX-90512:
name: "Gran Turismo 4 - Toyota Prius [Trial]"
region: "NTSC-J"
@@ -1408,6 +1414,11 @@ SCED-51700:
region: "PAL-M5"
gameFixes:
- VUKickstartHack # Fixes Character SPS.
SCED-51922:
name: "Ghosthunter [Demo]"
region: "PAL-G"
clampModes:
vuClampMode: 3 # Fixes SPS.
SCED-51935:
name: "Official PlayStation 2 Magazine Demo 38" # German
region: "PAL-E-G"
@@ -1736,6 +1747,13 @@ SCED-53325:
SCED-53348:
name: "Official PlayStation 2 Magazine Demo 58" # French
region: "PAL-F"
SCED-53679:
name: "Fire It Up Lads Demo"
region: "PAL-E"
patches:
default:
content: |-
comment=- WRC Rally needs XGKick fix enabled
SCED-53684:
name: "SingStar '80s [Demo]"
region: "PAL-E"
@@ -2326,9 +2344,10 @@ SCES-51135:
region: "PAL-M5"
compat: 5
roundModes:
vuRoundMode: 0 # Fixes SPS.
vuRoundMode: 1 # Fixes SPS.
eeRoundMode: 0 # Fixes textures on the doors.
clampModes:
vuClampMode: 2 # Fix other SPS.
vuClampMode: 0 # Fix other SPS.
gameFixes:
- VUKickstartHack # Fixes objects disappearing.
SCES-51159:
@@ -2359,6 +2378,8 @@ SCES-51190:
name: "Dark Chronicle"
region: "PAL-M5"
compat: 5
clampModes:
eeClampMode: 3 # Fixes textbox.
SCES-51224:
name: "War of the Monsters"
region: "PAL-E"
@@ -2378,6 +2399,8 @@ SCES-51463:
name: "Ghosthunter"
region: "PAL-M6"
compat: 5
clampModes:
vuClampMode: 3 # Fixes SPS.
gameFixes:
- VUKickstartHack # Fixes Missing Graphics.
SCES-51480:
@@ -2473,9 +2496,10 @@ SCES-51685:
name: "Primal"
region: "PAL-E-R"
roundModes:
vuRoundMode: 0 # Fixes SPS.
vuRoundMode: 1 # Fixes SPS.
eeRoundMode: 0 # Fixes textures on the doors.
clampModes:
vuClampMode: 2 # Fix other SPS.
vuClampMode: 0 # Fix other SPS.
gameFixes:
- VUKickstartHack # Fixes objects disappearing.
SCES-51706:
@@ -2566,6 +2590,8 @@ SCES-52154:
SCES-52156:
name: "Ghosthunter - Hunter on the spectres"
region: "PAL-M3"
clampModes:
vuClampMode: 3 # Fixes SPS.
SCES-52268:
name: "SingStar"
region: "PAL-E"
@@ -3676,6 +3702,8 @@ SCKA-20014:
name: "Dark Cloud 2"
region: "NTSC-K"
compat: 5
clampModes:
eeClampMode: 3 # Fixes textbox.
SCKA-20015:
name: "Time Crisis 3"
region: "NTSC-K"
@@ -4244,6 +4272,8 @@ SCPS-15032:
SCPS-15033:
name: "Dark Chronicle"
region: "NTSC-J"
clampModes:
eeClampMode: 3 # Fixes textbox.
SCPS-15034:
name: "This is Football 2003"
region: "NTSC-J"
@@ -4730,6 +4760,8 @@ SCPS-19214:
SCPS-19215:
name: "Dark Chronicle [PlayStation 2 The Best]"
region: "NTSC-J"
clampModes:
eeClampMode: 3 # Fixes textbox.
SCPS-19251:
name: "Wild ARMs - Alter Code F [PlayStation 2 The Best]"
region: "NTSC-J"
@@ -4789,6 +4821,8 @@ SCPS-19305:
SCPS-19306:
name: "Dark Chronicle [PlayStation 2 The Best]"
region: "NTSC-J"
clampModes:
eeClampMode: 3 # Fixes textbox.
SCPS-19307:
name: "Popolocrois - The First Adventure [PlayStation 2 The Best]"
region: "NTSC-J"
@@ -5143,6 +5177,8 @@ SCPS-55047:
SCPS-55048:
name: "Dark Chronicle"
region: "NTSC-J"
clampModes:
eeClampMode: 3 # Fixes textbox.
SCPS-55049:
name: "King of Fighters 2000, The"
region: "NTSC-J"
@@ -5406,9 +5442,10 @@ SCUS-97142:
region: "NTSC-U"
compat: 5
roundModes:
vuRoundMode: 0 # Fixes SPS.
vuRoundMode: 1 # Fixes SPS.
eeRoundMode: 0 # Fixes textures on the doors.
clampModes:
vuClampMode: 2 # Fix other SPS.
vuClampMode: 0 # Fix other SPS.
gameFixes:
- VUKickstartHack # Fixes objects disappearing.
SCUS-97144:
@@ -5639,6 +5676,8 @@ SCUS-97213:
name: "Dark Cloud 2"
region: "NTSC-U"
compat: 5
clampModes:
eeClampMode: 3 # Fixes textbox.
SCUS-97214:
name: "NCAA GameBreaker 2003"
region: "NTSC-U"
@@ -5675,9 +5714,10 @@ SCUS-97225:
name: "Primal [Demo]"
region: "NTSC-U"
roundModes:
vuRoundMode: 0 # Fixes SPS.
vuRoundMode: 1 # Fixes SPS.
eeRoundMode: 0 # Fixes textures on the doors.
clampModes:
vuClampMode: 2 # Fix other SPS.
vuClampMode: 0 # Fix other SPS.
gameFixes:
- VUKickstartHack # Fixes objects disappearing.
SCUS-97226:
@@ -5689,6 +5729,8 @@ SCUS-97227:
SCUS-97229:
name: "Dark Cloud 2 [Demo]"
region: "NTSC-U"
clampModes:
eeClampMode: 3 # Fixes textbox.
SCUS-97230:
name: "SOCOM - U.S. Navy SEALs (Online)"
region: "NTSC-U"
@@ -7044,6 +7086,8 @@ SLAJ-35003:
SLED-50117:
name: "Metal Gear Solid 2 - Sons of Liberty [Demo] [Zone of the Enders Bonus Disc]"
region: "PAL-E"
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLED-50359:
name: "Devil May Cry [Demo]"
region: "PAL-E"
@@ -7988,12 +8032,18 @@ SLES-50383:
name: "Metal Gear Solid 2 - Sons of Liberty"
region: "PAL-M3"
compat: 5
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLES-50384:
name: "Project Zero II"
name: "Metal Gear Solid 2 - Sons of Liberty"
region: "PAL-I"
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLES-50385:
name: "Metal Gear Solid 2 - Sons of Liberty"
region: "PAL-S"
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLES-50386:
name: "Crash Bandicoot - Wrath of Cortex"
region: "PAL-M6"
@@ -8105,6 +8155,8 @@ SLES-50446:
name: "Shadow Man - 2econd Coming"
region: "PAL-M4"
compat: 5
gameFixes:
- EETimingHack # Fixes cutscene freezes.
speedHacks:
InstantVU1SpeedHack: 0 # Fixes SPS.
SLES-50447:
@@ -8364,6 +8416,8 @@ SLES-50608:
name: "Shadow Man - 2econd Coming"
region: "PAL-G"
compat: 5
gameFixes:
- EETimingHack # Fixes cutscene freezes.
speedHacks:
InstantVU1SpeedHack: 0 # Fixes SPS.
SLES-50613:
@@ -8677,6 +8731,8 @@ SLES-50788:
SLES-50789:
name: "Men in Black II: Alien Escape"
region: "PAL-M5"
gameFixes:
- VIFFIFOHack # Needed to load the main game properly.
SLES-50790:
name: "International Superstar Soccer 2002"
region: "PAL-M3"
@@ -9367,6 +9423,8 @@ SLES-51113:
name: "Zone of the Enders: The 2nd Runner Special Edition"
region: "PAL-M5"
compat: 5
gameFixes:
- DMABusyHack # Fixes the corrupted fade effect in cutscenes.
SLES-51114:
name: "Pro Evolution Soccer 2"
region: "PAL-M5"
@@ -9444,6 +9502,8 @@ SLES-51145:
SLES-51150:
name: "Scrabble Interactive - 2003 Edition"
region: "PAL-M3"
clampModes:
vuClampMode: 0 # Fixes missing UI and game elements.
SLES-51151:
name: "NHL 2003"
region: "PAL-M6"
@@ -12073,6 +12133,7 @@ SLES-52568:
compat: 5
gameFixes:
- XGKickHack # Fixes bad Geometry.
- VUKickstartHack # Fixes graphical glitches.
SLES-52569:
name: "Spyro - A Hero's Tail"
region: "PAL-M6"
@@ -12389,6 +12450,8 @@ SLES-52710:
SLES-52711:
name: "Titeuf Mega Compet"
region: "PAL-F"
gameFixes:
- GIFFIFOHack # Fixes corrupted textures.
patches:
958e5086:
content: |-
@@ -13072,6 +13135,14 @@ SLES-53021:
SLES-53022:
name: "ESPN NBA 2K5"
region: "PAL-E"
gameFixes:
- SkipMPEGHack # Fixes videos.
patches:
CA37B42E:
content: |-
author=Prafull
comment=fixes hang at start
patch=1,EE,0034DA98,word,00000000
SLES-53023:
name: "RTL Ski Jump 2005"
region: "PAL-E-G"
@@ -13951,6 +14022,8 @@ SLES-53491:
SLES-53492:
name: "Total Overdose"
region: "PAL-M5"
gameFixes:
- VUKickstartHack # Fixes SPS.
SLES-53494:
name: "Spongebob SquarePants - Lights, Camera, PANTS!"
region: "PAL-E"
@@ -14488,6 +14561,12 @@ SLES-53686:
SLES-53687:
name: "NBA 2K6"
region: "PAL-M5"
patches:
04808D11:
content: |-
author=Prafull
comment=fixes hang at start
patch=1,EE,00441ff8,word,00000000
SLES-53689:
name: "World Poker Tour 2K6"
region: "PAL-M3"
@@ -14770,6 +14849,14 @@ SLES-53805:
SLES-53809:
name: "K-1 Premium Dynamite!!"
region: "PAL-E"
gameFixes:
- XGKickHack # Fixes black and white fighters.
patches:
B6F9C8D3:
content: |-
comment=Fixes black screen in hardware mode.
patch=1,EE,0030a420,word,0000948c
patch=1,EE,0030a448,word,0000948c
SLES-53810:
name: "Sensible Soccer 2006"
region: "PAL-M5"
@@ -15581,6 +15668,12 @@ SLES-54209:
SLES-54210:
name: "NBA 2K7"
region: "PAL-M5"
patches:
04808D11:
content: |-
author=Prafull
comment=fixes hang at start
patch=1,EE,0044f0f8,word,00000000
SLES-54211:
name: "NHL 2K7"
region: "PAL-M5"
@@ -16783,11 +16876,15 @@ SLES-54767:
SLES-54770:
name: "DreamWorks Shrek the Third"
region: "PAL-E"
roundModes:
vuRoundMode: 0 # Fixes black zones.
clampModes:
eeClampMode: 3 # Fixes objects spawning.
SLES-54771:
name: "DreamWorks Shrek the Third"
region: "PAL-M5"
roundModes:
vuRoundMode: 0 # Fixes black zones.
clampModes:
eeClampMode: 3 # Fixes objects spawning.
SLES-54772:
@@ -16795,6 +16892,8 @@ SLES-54772:
region: "PAL-E"
SLES-54774:
name: "DreamWorks Shrek the Third"
roundModes:
vuRoundMode: 0 # Fixes black zones.
region: "PAL-M5"
clampModes:
eeClampMode: 3 # Fixes objects spawning.
@@ -18570,6 +18669,8 @@ SLES-82009:
name: "Metal Gear Solid 2 - Substance"
region: "PAL-M5"
compat: 5
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLES-82010:
name: "Metal Gear Solid 2, Document of"
region: "PAL-E"
@@ -18820,6 +18921,11 @@ SLKA-25026:
region: "NTSC-K"
clampModes:
vuClampMode: 2 # Fixes SPS in item menu.
SLKA-25029:
name: "MVP Baseball 2003"
region: "NTSC-K"
clampModes:
vuClampMode: 3 # Fixes missing environment.
SLKA-25030:
name: "WWE SmackDown! Shut Your Mouth"
region: "NTSC-K"
@@ -18853,6 +18959,12 @@ SLKA-25043:
name: "Virtua Fighter 4 - Evolution"
region: "NTSC-K"
compat: 5
SLKA-25044:
name: "Robotech: Battlecry"
region: "NTSC-K"
SLKA-25045:
name: "The King of Fighters 2000"
region: "NTSC-K"
SLKA-25046:
name: "Dragon Ball Z"
region: "NTSC-K"
@@ -19058,12 +19170,18 @@ SLKA-25202:
memcardFilters:
- "SLKA-25201"
- "SLKA-25202"
SLKA-25203:
name: "World Soccer Winning Eleven 8 International"
region: "NTSC-K"
SLKA-25204:
name: "Showdown - Legends of Wrestling"
region: "NTSC-K"
SLKA-25205:
name: "Dragon Ball Z 3"
region: "NTSC-K"
SLKA-25206:
name: "Burnout 3: Takedown"
region: "NTSC-K"
SLKA-25207:
name: "Sakura Taisen V - Episode 0 - Samurai Girl of Wild"
region: "NTSC-K"
@@ -19171,6 +19289,9 @@ SLKA-25259:
SLKA-25261:
name: "Tsukiyo ni Saraba"
region: "NTSC-K"
SLKA-25262:
name: "World Soccer Winning Eleven 8 International"
region: "NTSC-K"
SLKA-25263:
name: "NanoBreaker"
region: "NTSC-J"
@@ -19312,6 +19433,9 @@ SLKA-25331:
SLKA-25333:
name: "Metal Slug Complete"
region: "NTSC-K"
SLKA-25335:
name: "Shadow the Hedgehog"
region: "NTSC-K"
SLKA-25341:
name: "Driver - Parallel Lines"
region: "NTSC-K"
@@ -19420,6 +19544,8 @@ SLKA-35001:
name: "Metal Gear Solid 2 Substance"
region: "NTSC-K"
compat: 5
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLKA-35003:
name: "Sakura Taisen - Atsuki Chishioni"
region: "NTSC-K"
@@ -19533,6 +19659,9 @@ SLPM-55131:
SLPM-55138:
name: "Harukanaru Toki no Naka de - Yume no Ukihashi Special"
region: "NTSC-J"
SLPM-55146:
name: "Jikkyou Powerful Pro Yakyuu 2009"
region: "NTSC-J"
SLPM-55148:
name: "007: Nagusame no Houshuu"
region: "NTSC-J"
@@ -19641,6 +19770,11 @@ SLPM-60254:
SLPM-60256:
name: "Dengeki D73 demo"
region: "NTSC-J"
SLPM-60260:
name: "D1 Professional Drift Grand Prix Series [Taikenban]"
region: "NTSC-J"
clampModes:
eeClampMode: 3 # Fixes black void.
SLPM-60262:
name: "10th Anniversary Memorial Save Data [Disc 2]"
region: "NTSC-J"
@@ -20840,6 +20974,8 @@ SLPM-62485:
SLPM-62486:
name: "Chou Saisoku! Zokusha King B.U. [Simple Series DX]"
region: "NTSC-J"
clampModes:
eeClampMode: 3 # Fixes white shadows.
SLPM-62488:
name: "Hot Gimmick Cosplay Mahjong"
region: "NTSC-J"
@@ -21111,6 +21247,14 @@ SLPM-62580:
SLPM-62581:
name: "K-1 Premium 2004 - Fighting Dynamite!!"
region: "NTSC-J"
gameFixes:
- XGKickHack # Fixes black and white fighters.
patches:
0A1042EE:
content: |-
comment=Fixes black screen in hardware mode.
patch=1,EE,00301de0,word,0000948c
patch=1,EE,00301e08,word,0000948c
SLPM-62582:
name: "Slotter-Up Core 6"
region: "NTSC-J"
@@ -21953,9 +22097,13 @@ SLPM-65076:
SLPM-65077:
name: "Metal Gear Solid 2 - Sons of Liberty [Premium Package]"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLPM-65078:
name: "Metal Gear Solid 2 - Sons of Liberty"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLPM-65080:
name: "Tokimeki Memorial 3"
region: "NTSC-J"
@@ -24288,6 +24436,8 @@ SLPM-65862:
SLPM-65863:
name: "D1 Grand Prix Series - Professional Drift"
region: "NTSC-J"
clampModes:
eeClampMode: 3 # Fixes black void.
SLPM-65864:
name: "Nobunaga no Yabou - Tenka Sousei [with Power-Up Kit]"
region: "NTSC-J"
@@ -24938,6 +25088,14 @@ SLPM-66077:
name: "K-1 World Max 2005"
region: "NTSC-J"
compat: 5
gameFixes:
- XGKickHack # Fixes black and white fighters.
patches:
08E3C435:
content: |-
comment=Fixes black screen in hardware mode.
patch=1,EE,003dfe60,word,0000948c
patch=1,EE,003dfe88,word,0000948c
SLPM-66078:
name: "White Princess the Second"
region: "NTSC-J"
@@ -25187,7 +25345,7 @@ SLPM-66163:
author=Prafull
// Skip sceipusync
// Fixes hang before going ingame
patch=1,EE,00156608,word,10000003
patch=1,EE,002324dc,word,00000000
SLPM-66164:
name: "Mahou Tsukai Kurohime"
region: "NTSC-J"
@@ -25622,6 +25780,13 @@ SLPM-66294:
SLPM-66295:
name: "Yamiyo ni Sasayaku - Tantei Sagara Kyouichirou [Limited Edition]"
region: "NTSC-J"
patches:
23A9A026:
content: |-
author=PSI, Jelta
// Game does weird stack manipulation, causing data sent to the IOP to be corrupted unless EE data cache is enabled.
// This patch skips over the stack code, allowing the game to boot.
patch=1,EE,00156888,word,10000003
SLPM-66296:
name: "Yamiyo ni Sasayaku - Tantei Sagara Kyouichirou"
region: "NTSC-J"
@@ -25818,6 +25983,8 @@ SLPM-66356:
SLPM-66358:
name: "Shinobido Takumi"
region: "NTSC-J"
clampModes:
eeClampMode: 3 # Fixes crash after main menu.
SLPM-66359:
name: "Mutsu-boshi Kirari - Hoshifuru Miyako"
region: "NTSC-J"
@@ -25932,6 +26099,13 @@ SLPM-66398:
SLPM-66399:
name: "Samurai 7 [Limited Edition]"
region: "NTSC-J"
patches:
836F4606:
content: |-
author=PSI, Jelta
// Game does weird stack manipulation, causing data sent to the IOP to be corrupted unless EE data cache is enabled.
// This patch skips over the stack code, allowing the game to boot.
patch=1,EE,00157F78,word,10000003
SLPM-66400:
name: "Samurai 7"
region: "NTSC-J"
@@ -26099,6 +26273,12 @@ SLPM-66450:
SLPM-66451:
name: "Major League Baseball 2K6"
region: "NTSC-J"
patches:
F0393708:
content: |-
author=Prafull
comment=fixes hang at start
patch=1,EE,0035d8b8,word,00000000
SLPM-66452:
name: "Kamaitachi no Yoru 3"
region: "NTSC-J"
@@ -26299,6 +26479,8 @@ SLPM-66502:
SLPM-66503:
name: "Metal Gear Solid 2 [Mega Hits]"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLPM-66504:
name: "Onimusha 2 [Mega Hits]"
region: "NTSC-J"
@@ -27242,6 +27424,8 @@ SLPM-66791:
SLPM-66792:
name: "Metal Gear Solid 2 - Sons of Liberty [20th Anniversary Edition]"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLPM-66794:
name: "Metal Gear Solid 3 - Snake Eater [20th Anniversary Edition]"
region: "NTSC-J"
@@ -27758,6 +27942,9 @@ SLPM-66978:
name: "Persona 4 [Konami-style Special Edition]"
region: "NTSC-J"
compat: 5
SLPM-66980:
name: "Gin no Eclipse"
region: "NTSC-J"
SLPM-66987:
name: "Kowloon Youma Gakuen Ki [Best Version]"
region: "NTSC-J"
@@ -27801,6 +27988,8 @@ SLPM-67000:
SLPM-67002:
name: "Metal Gear Solid 2 - Substance"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLPM-67003:
name: "Sakura Taisen - Atsuki Chishioni"
region: "NTSC-J"
@@ -28350,6 +28539,8 @@ SLPS-20048:
SLPS-20050:
name: "Happy! Happy!! Boarders in Hokkaidou Rusutsu Resort"
region: "NTSC-J"
speedHacks:
mvuFlagSpeedHack: 0 # Fixes graphical issues.
SLPS-20051:
name: "Hissatsu Pachinko Station V"
region: "NTSC-J"
@@ -28579,6 +28770,15 @@ SLPS-20187:
name: "Black Matrix 2"
region: "NTSC-J"
compat: 5
SLPS-20190:
name: "Netsu Chu! Pro Yakyuu 2002"
region: "NTSC-J"
patches:
78E100AD:
content: |-
author=Prafull
comment=fixes hang before ingame
patch=1,EE,001022c0,word,00000000
SLPS-20194:
name: "Underwater Unit"
region: "NTSC-J"
@@ -28666,7 +28866,7 @@ SLPS-20272:
region: "NTSC-J"
compat: 5
SLPS-20273:
name: "Netsu Chu! Pro Baseball 2003"
name: "Netsu Chu! Pro Yakyuu 2003"
region: "NTSC-J"
patches:
34fb1fb7:
@@ -28752,8 +28952,14 @@ SLPS-20321:
region: "NTSC-J"
compat: 5
SLPS-20322:
name: "Netsu Chu! Pro Baseball 2003 Fall"
name: "Netsu Chu! Pro Yakyuu 2003: Aki no Night Matsuri"
region: "NTSC-J"
patches:
D3DAF7F4:
content: |-
author=Prafull
comment=fixes hang before ingame
patch=1,EE,00102398,word,00000000
SLPS-20323:
name: "Pochi to Nyaa"
region: "NTSC-J"
@@ -29074,6 +29280,12 @@ SLPS-20453:
compat: 5
gameFixes:
- XGKickHack # Fixes black and white fighters.
patches:
602B7A48:
content: |-
comment=Fixes black screen in hardware mode.
patch=1,EE,00336a20,word,0000948c
patch=1,EE,00336a48,word,0000948c
SLPS-20454:
name: "Simple 2000 Series Vol.93 - The Right Brain Drill"
region: "NTSC-J"
@@ -30016,6 +30228,8 @@ SLPS-25250:
SLPS-25251:
name: "MVP Baseball 2003"
region: "NTSC-J"
clampModes:
vuClampMode: 3 # Fixes missing environment.
SLPS-25252:
name: "Star wars - Jango Fett"
region: "NTSC-J"
@@ -31089,6 +31303,14 @@ SLPS-25577:
SLPS-25578:
name: "K-1 World Grand Prix 2005"
region: "NTSC-J"
gameFixes:
- XGKickHack # Fixes black and white fighters.
patches:
F8664E20:
content: |-
comment=Fixes black screen in hardware mode.
patch=1,EE,004269f0,word,0000948c
patch=1,EE,00426a18,word,0000948c
SLPS-25579:
name: "Little Aid"
region: "NTSC-J"
@@ -33195,6 +33417,8 @@ SLUS-20144:
name: "Metal Gear Solid 2 - Sons of Liberty"
region: "NTSC-U"
compat: 5
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLUS-20145:
name: "Ring of Red"
region: "NTSC-U"
@@ -34301,6 +34525,8 @@ SLUS-20413:
name: "Shadow Man - 2econd Coming"
region: "NTSC-U"
compat: 5
gameFixes:
- EETimingHack # Fixes cutscene freezes.
speedHacks:
InstantVU1SpeedHack: 0 # Fixes SPS.
SLUS-20414:
@@ -34894,6 +35120,8 @@ SLUS-20554:
name: "Metal Gear Solid 2 - Substance"
region: "NTSC-U"
compat: 5
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLUS-20555:
name: "Reel Fishing 3"
region: "NTSC-U"
@@ -35316,6 +35544,8 @@ SLUS-20649:
SLUS-20650:
name: "MVP Baseball 2003"
region: "NTSC-U"
clampModes:
vuClampMode: 3 # Fixes missing environment.
SLUS-20651:
name: "NBA Street Vol. 2"
region: "NTSC-U"
@@ -36355,6 +36585,7 @@ SLUS-20909:
compat: 5
gameFixes:
- XGKickHack # Fixes bad geometry.
- VUKickstartHack # Fixes graphical glitches.
SLUS-20910:
name: "Test Drive - Eve of Destruction"
region: "NTSC-U"
@@ -38090,6 +38321,8 @@ SLUS-21283:
name: "Total Overdose - A Gunslinger's Tale in Mexico"
region: "NTSC-U"
compat: 5
gameFixes:
- VUKickstartHack # Fixes SPS.
SLUS-21284:
name: "Nicktoons Unite!"
region: "NTSC-U"
@@ -38259,6 +38492,8 @@ SLUS-21322:
name: "Eragon"
region: "NTSC-U"
compat: 5
clampModes:
vuClampMode: 3 # Fixes SPS and spawn issues.
SLUS-21323:
name: "Rampage - Total Destruction"
region: "NTSC-U"
@@ -38703,6 +38938,8 @@ SLUS-21416:
name: "D1 Grand Prix"
region: "NTSC-U"
compat: 5
clampModes:
eeClampMode: 3 # Fixes black screen.
SLUS-21417:
name: "Xenosaga - Episode III - Also Sprach Zarathustra [Disc2of2]"
region: "NTSC-U"
@@ -38895,6 +39132,8 @@ SLUS-21454:
name: "DreamWorks Shrek the Third"
region: "NTSC-U"
compat: 5
roundModes:
vuRoundMode: 0 # Fixes black zones.
clampModes:
eeClampMode: 3 # Fixes objects spawning.
SLUS-21455:
@@ -39232,6 +39471,12 @@ SLUS-21560:
SLUS-21561:
name: "Major League Baseball 2K7"
region: "NTSC-U"
patches:
73D6D171:
content: |-
author=Prafull
comment=fixes hang at start
patch=1,EE,003CDE10,word,00000000
SLUS-21563:
name: "Horsez"
region: "NTSC-U"
@@ -40530,6 +40775,12 @@ SLUS-21870:
SLUS-21871:
name: "Major League Baseball 2K9"
region: "NTSC-U"
patches:
72905002:
content: |-
author=Prafull
comment=fixes hang at start
patch=1,EE,003CC5D8,word,00000000
SLUS-21872:
name: "MTV Pimp my Ride - Street Racing"
region: "NTSC-U"
@@ -40808,6 +41059,12 @@ SLUS-21944:
SLUS-21945:
name: "Major League Baseball 2K11"
region: "NTSC-U"
patches:
3D621C56:
content: |-
author=By Prafull
comment=fixes hang at start
patch=1,EE,003CFE58,word,00000000
SLUS-21946:
name: "Madden NFL 12"
region: "NTSC-U"
@@ -40830,6 +41087,12 @@ SLUS-21950:
SLUS-21951:
name: "Major League Baseball 2K12"
region: "NTSC-U"
patches:
C26C70A9:
content: |-
author=By Prafull
comment=fixes hang at start
patch=1,EE,003D4098,word,00000000
SLUS-21954:
name: "FIFA 13"
region: "NTSC-U" # Latin America with En,Fr,Es
@@ -40998,6 +41261,8 @@ SLUS-29003:
name: "Metal Gear Solid 2 - Sons of Liberty [Demo]"
region: "NTSC-U"
compat: 5
gameFixes:
- EETimingHack # Fixes broken half-bottom artifacts.
SLUS-29004:
name: "Unison & Dead or Alive 2 Hardcore [Demo]"
region: "NTSC-U"
@@ -39,6 +39,7 @@
03000000120c0000200e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000120c0000210e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger: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,
030000008305000031b0000000000000,Cideko AK08b,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,
03000000d8140000cecf000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000a306000022f6000001030000,Cyborg V.3 Rumble 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:+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,
030000000d0f00008400000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -54,10 +55,10 @@
03000000280400000140000000020000,Gravis Gamepad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008f0e00000300000007010000,GreenAsia USB Joystick,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Mac OS X,
030000000d0f00002d00000000100000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005f00000000010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005e00000000010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005f00000000000000,Hori Fighting Commander 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,
030000000d0f00005f00000000010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005e00000000000000,Hori Fighting Commander 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: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,
030000000d0f00005e00000000010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
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,
030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro Pad,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,
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,
@@ -90,8 +91,7 @@
0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,
03000000790000000018000000010000,Mayflash Wii U Pro Controller Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
03000000d8140000cecf000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000005e0400002700000001010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,leftx:a0,lefty:a1,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,
030000005e0400002700000001010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,
03000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
03000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,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:Mac OS X,
03000000c62400002b89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
@@ -125,9 +125,9 @@
03000000321500000009000000020000,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:Mac OS X,
030000003215000000090000163a0000,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:Mac OS X,
0300000032150000030a000000000000,Razer Wildcat,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,
03000000830500006020000000010000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000790000001100000005010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000830500006020000000010000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
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,
@@ -146,8 +146,8 @@
03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
05000000484944204465766963650000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
05000000556e6b6e6f776e2048494400,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
05000000556e6b6e6f776e2048494400,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
03000000457500002211000000010000,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:Mac OS X,
@@ -194,9 +194,9 @@
03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,
05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,
03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
03000000c82d00000190000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
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,
03000000c82d00000190000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00000061000000010000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
030000003512000021ab000010010000,8BitDo SFC30,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,start:b11,x:b4,y:b3,platform:Linux,
@@ -252,7 +252,6 @@
03000000120c0000200e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000120c0000210e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,
03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,
@@ -261,16 +260,15 @@
030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000006e0500000320000010010000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,
03000000430b00000300000000010000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000341a000005f7000010010000,HuiJia GameCube Controller Adpater,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,
03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000ac0500002d0200001b010000,Gamesir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000bc2000005656000011010000,Gamesir T4w,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
03000000bc2000005656000011010000,Gamesir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000006f0e00001304000000010000,Xbox 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,
03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000f0250000c183000010010000,Goodbetterbest 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,
0300000079000000d418000000010000,GPD Win 2 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,
@@ -283,28 +281,28 @@
06000000adde0000efbe000002010000,Hidromancer Game 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,
03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,
03000000c9110000f055000011010000,HJC Game Gamepqd,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux,
03000000632500002605000010010000,HJDX,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:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,
030000000d0f00001000000011010000,Hori Fighting Stick 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,
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,
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,
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,
030000000d0f00008500000010010000,Hori Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00008600000002010000,Hori Fighting Commander,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00005f00000011010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00005e00000011010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00005001000009040000,Hori Fighting Commander OCTA,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,
030000000d0f00001000000011010000,Hori Fighting Stick 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,
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 Pad,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,
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,
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,
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,
03000000341a000005f7000010010000,HuiJia GameCube Controller Adpater,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,
030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux,
03000000242e00008816000001010000,Hyperkin X91,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,
050000006964726f69643a636f6e0000,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:Linux,
@@ -313,6 +311,8 @@
03000000fd0500000030000000010000,InterAct GoPad I73000,a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,
0500000049190000020400001b010000,Ipega PG 9069 Bluetooth Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,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,
03000000632500007505000011010000,Ipega PG 9099 Bluetooth Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
0500000049190000030400001b010000,Ipega PG9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000491900000204000000000000,Ipega PG9118,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,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:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
@@ -333,11 +333,9 @@
030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),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,
030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),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,
030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),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,
030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
030000006d04000018c2000010010000,Logitech RumblePad 2,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,
030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,
050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,x:b2,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux
050000004d4f435554452d3035305800,Mocute 054X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
05000000380700006652000025010000,Mad Catz CTRLR,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,
03000000380700005032000011010000,Mad Catz FightPad PRO 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,
03000000380700005082000011010000,Mad Catz FightPad PRO 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,
@@ -351,31 +349,33 @@
03000000ad1b000016f0000090040000,Mad Catz 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,
03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000242f0000f700000001010000,Mayflash Magic S 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,
03000000120c00000500000000010000,Manta Dualshock 2,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:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,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:b2,y:b3,platform:Linux,
03000000790000004318000010010000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,
0300000079000000d218000011010000,Mayflash Magic NS,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,
03000000d620000010a7000011010000,Mayflash Magic NS,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,
03000000242f0000f700000001010000,Mayflash Magic S 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,
0300000025090000e803000001010000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
030000005e0400000700000000010000,Microsoft SideWinder Game Pad USB,a:b0,b:b1,back:b8,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux,
030000005e0400002700000000010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Linux,
030000005e0400008e02000056210000,Microsoft X-Box 360 pad,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,
030000005e0400008e02000004010000,Microsoft Xbox 360 pad,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,
030000005e0400008e02000056210000,Microsoft X-Box 360 pad,a:b0,b:b1,x:b2,y:b3,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux
030000005e0400008e02000062230000,Microsoft Xbox 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000000b000008040000,Microsoft Xbox One Elite 2 pad,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,
050000005e040000050b000003090000,Microsoft Xbox One Elite 2 pad,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e040000e302000003020000,Microsoft Xbox One Elite pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000d102000001010000,Microsoft Xbox One pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000dd02000003020000,Microsoft Xbox One pad 2015,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000d102000003020000,Microsoft Xbox One pad v2,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,
030000005e040000ea02000008040000,Microsoft Xbox One S pad,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,
030000005e0400008502000000010000,Microsoft Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
030000005e0400008902000021010000,Microsoft Xbox pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
030000005e040000000b000008040000,Microsoft Xbox One Elite 2 pad,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,
030000005e040000ea02000008040000,Microsoft Xbox One S pad,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,
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,
03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
050000004d4f435554452d3035305800,Mocute 054X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
@@ -390,10 +390,11 @@
030000001008000001e5000010010000,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:Linux,
060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,
050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,
03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux,
050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b9,b:b8,back:b5,leftshoulder:b2,leftstick:b6,leftx:a1,lefty:a0~,rightshoulder:b4,start:b0,x:b7,y:b10,platform:Linux,
03000000d620000013a7000011010000,Nintendo Switch PowerA Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
@@ -408,7 +409,6 @@
03000000451300000830000010010000,NYKO CORE,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,
19000000010000000100000001010000,odroidgo2 joypad,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,
19000000010000000200000011000000,odroidgo2 joypad v11,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,
030000005e0400000202000000010000,Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:Linux,
05000000362800000100000002010000,OUYA Game 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:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
05000000362800000100000003010000,OUYA Game 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:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
@@ -418,31 +418,26 @@
030000006f0e0000b802000001010000,PDP Afterglow Wired 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,
030000006f0e0000b802000013020000,PDP Afterglow Wired 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,
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,
030000006f0e00008001000011010000,PDP Faceoff 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:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,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 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:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,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,
030000006f0e00008701000011010000,PDP Rock Candy Wired Controller for Nintendo Switch,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,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
030000006f0e00000901000011010000,PDP Versus Fighting Pad,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,
030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000006f0e00008501000011010000,PDP Wired Fight Pad 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,
030000006f0e0000a702000023020000,PDP Xbox One Raven Black,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
0500000049190000030400001b010000,Ipega PG9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000491900000204000000000000,Ipega PG9118,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000006f0e0000a702000023020000,PDP Xbox One Raven Black,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,
030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000d9040000160f000000010000,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:Linux,
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,
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,
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,
03000000d62000000228000001010000,PowerA Wired Controller for 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 Wired Controller for Xbox One and Xbox Series S and X,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,
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,
03000000c62400001a54000001010000,PowerA Xbox One Mini Wired 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,
03000000d620000013a7000011010000,Nintendo Switch PowerA Wired Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
030000006d040000d2ca000011010000,Precision 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,
03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,b:b1,a:b0,x:b3,y:b2,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:b6,righttrigger:b7,platform:Linux,
03000000430b00000300000000010000,EMS Production PS2 Adapter,b:b1,a:b2,x:b3,y:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux,
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000341a00003608000011010000,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,
030000004c0500006802000010010000,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:Linux,
@@ -475,19 +470,20 @@
050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000ff000000cb01000010010000,PSP,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
03000000300f00001211000011010000,Qanba Arcade Joystick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,
03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux,
030000009b2800004200000001010000,Raphnet Technologies Dual NES to USB v2.0,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux,
030000009b2800003200000001010000,Raphnet Technologies GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
030000009b2800006000000001010000,Raphnet Technologies GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000008916000000fd000024010000,Razer Onza Tournament Edition,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,
03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000204000011010000,Razer Panthera 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,
03000000321500000104000011010000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000010000011010000,Razer Rainu,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,
03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,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,
05000000321500000a10000001000000,Razer Raiju Tournament Edition,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:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000710000000010000,Razer Raiju Tournament Edition Wired,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:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000010000011010000,Razer Rainu,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,
03000000321500000011000011010000,Razer Raion Fightpad for 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,
030000008916000000fe000024010000,Razer Sabertooth,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,
03000000c6240000045d000024010000,Razer Sabertooth,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,
@@ -502,16 +498,17 @@
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,
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,
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 V.1 Game 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,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,
03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux,
03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux,
03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,
03000000a306000018f5000010010000,Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,
03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,
03000000a306000018f5000010010000,Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000a306000020f6000011010000,Saitek PS2700 Rumble 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,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux,
03000000a30c00002500000011010000,Sega Genesis Mini 3B controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux,
@@ -546,9 +543,10 @@
030000003b07000004a1000000010000,Suncom SFX Plus for USB,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux,
03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,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:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
03000000457500002211000010010000,SZMY Power Gamepad,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,
030000008f0e00000d31000010010000,SZMY Power 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000457500002211000010010000,SZMY Power Gamepad,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,
030000008f0e00001431000010010000,SZMY Power PS3 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,
03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,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:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux,
030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3 in 1,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:Linux,
@@ -580,12 +578,15 @@
050000000d0f0000f600000001000000,Wireless 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,
030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000014010000,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,
0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
030000005e0400001907000000010000,Xbox 360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400009102000007010000,Xbox 360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000a102000000010000,Xbox 360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000a102000007010000,Xbox 360 Wireless 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,
0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
030000005e0400008e02000000010000,Xbox 360 Wireless EasySMX,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,
030000005e040000a102000014010000,Xbox 360 Wireless Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00001304000000010000,Xbox 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,
03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
0000000058626f782047616d65706100,Xbox Gamepad,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,
030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
030000005e040000d102000002010000,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,
@@ -597,12 +598,12 @@
050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,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,
030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),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,
060000005e040000120b000007050000,Xbox One Wireless Controller (Model 1914),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,
030000005e0400000202000000010000,Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000000010000,Xbox 360 Wireless EasySMX,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,
03000000450c00002043000010010000,XEOX Gamepad SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000ac0500005b05000010010000,Xiaoji Gamesir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,
@@ -49,7 +49,7 @@ VS_OUTPUT vs_main(VS_INPUT input)
return output;
}
PS_OUTPUT ps_main0(PS_INPUT input)
PS_OUTPUT ps_copy(PS_INPUT input)
{
PS_OUTPUT output;
@@ -58,7 +58,7 @@ PS_OUTPUT ps_main0(PS_INPUT input)
return output;
}
PS_OUTPUT ps_main7(PS_INPUT input)
PS_OUTPUT ps_filter_transparency(PS_INPUT input)
{
PS_OUTPUT output;
@@ -95,7 +95,7 @@ float4 ps_scanlines(PS_INPUT input, int i)
return sample_c(input.t) * saturate(mask[i] + 0.5f);
}
uint ps_main1(PS_INPUT input) : SV_Target0
uint ps_convert_rgba8_16bits(PS_INPUT input) : SV_Target0
{
float4 c = sample_c(input.t);
@@ -106,7 +106,7 @@ uint ps_main1(PS_INPUT input) : SV_Target0
return (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000);
}
PS_OUTPUT ps_main2(PS_INPUT input)
PS_OUTPUT ps_datm1(PS_INPUT input)
{
PS_OUTPUT output;
@@ -117,7 +117,7 @@ PS_OUTPUT ps_main2(PS_INPUT input)
return output;
}
PS_OUTPUT ps_main3(PS_INPUT input)
PS_OUTPUT ps_datm0(PS_INPUT input)
{
PS_OUTPUT output;
@@ -128,7 +128,7 @@ PS_OUTPUT ps_main3(PS_INPUT input)
return output;
}
PS_OUTPUT ps_main4(PS_INPUT input)
PS_OUTPUT ps_mod256(PS_INPUT input)
{
PS_OUTPUT output;
@@ -142,7 +142,7 @@ PS_OUTPUT ps_main4(PS_INPUT input)
return output;
}
PS_OUTPUT ps_main5(PS_INPUT input) // scanlines
PS_OUTPUT ps_filter_scanlines(PS_INPUT input)
{
PS_OUTPUT output;
@@ -153,7 +153,7 @@ PS_OUTPUT ps_main5(PS_INPUT input) // scanlines
return output;
}
PS_OUTPUT ps_main6(PS_INPUT input) // diagonal
PS_OUTPUT ps_filter_diagonal(PS_INPUT input)
{
PS_OUTPUT output;
@@ -164,7 +164,7 @@ PS_OUTPUT ps_main6(PS_INPUT input) // diagonal
return output;
}
PS_OUTPUT ps_main8(PS_INPUT input) // triangular
PS_OUTPUT ps_filter_triangular(PS_INPUT input)
{
PS_OUTPUT output;
@@ -177,7 +177,7 @@ PS_OUTPUT ps_main8(PS_INPUT input) // triangular
}
static const float PI = 3.14159265359f;
PS_OUTPUT ps_main9(PS_INPUT input) // triangular
PS_OUTPUT ps_filter_complex(PS_INPUT input) // triangular
{
PS_OUTPUT output;
@@ -191,13 +191,13 @@ PS_OUTPUT ps_main9(PS_INPUT input) // triangular
return output;
}
uint ps_main10(PS_INPUT input) : SV_Target0
uint ps_convert_float32_32bits(PS_INPUT input) : SV_Target0
{
// Convert a FLOAT32 depth texture into a 32 bits UINT texture
return uint(exp2(32.0f) * sample_c(input.t).r);
}
PS_OUTPUT ps_main11(PS_INPUT input)
PS_OUTPUT ps_convert_float32_rgba8(PS_INPUT input)
{
PS_OUTPUT output;
@@ -212,7 +212,7 @@ PS_OUTPUT ps_main11(PS_INPUT input)
return output;
}
PS_OUTPUT ps_main12(PS_INPUT input)
PS_OUTPUT ps_convert_float16_rgb5a1(PS_INPUT input)
{
PS_OUTPUT output;
@@ -225,7 +225,7 @@ PS_OUTPUT ps_main12(PS_INPUT input)
return output;
}
float ps_main13(PS_INPUT input) : SV_Depth
float ps_convert_rgba8_float32(PS_INPUT input) : SV_Depth
{
// Convert a RRGBA texture into a float depth texture
// FIXME: I'm afraid of the accuracy
@@ -234,7 +234,7 @@ float ps_main13(PS_INPUT input) : SV_Depth
return dot(sample_c(input.t), bitSh);
}
float ps_main14(PS_INPUT input) : SV_Depth
float ps_convert_rgba8_float24(PS_INPUT input) : SV_Depth
{
// Same as above but without the alpha channel (24 bits Z)
@@ -244,7 +244,7 @@ float ps_main14(PS_INPUT input) : SV_Depth
return dot(sample_c(input.t).rgb, bitSh);
}
float ps_main15(PS_INPUT input) : SV_Depth
float ps_convert_rgba8_float16(PS_INPUT input) : SV_Depth
{
// Same as above but without the A/B channels (16 bits Z)
@@ -255,7 +255,7 @@ float ps_main15(PS_INPUT input) : SV_Depth
return dot(sample_c(input.t).rg, bitSh);
}
float ps_main16(PS_INPUT input) : SV_Depth
float ps_convert_rgb5a1_float16(PS_INPUT input) : SV_Depth
{
// Convert a RGB5A1 (saved as RGBA8) color to a 16 bit Z
// FIXME: I'm afraid of the accuracy
@@ -266,7 +266,7 @@ float ps_main16(PS_INPUT input) : SV_Depth
return dot(float4(color), bitSh);
}
PS_OUTPUT ps_main17(PS_INPUT input)
PS_OUTPUT ps_convert_rgba_8i(PS_INPUT input)
{
PS_OUTPUT output;
@@ -358,7 +358,7 @@ PS_OUTPUT ps_main17(PS_INPUT input)
}
// DUMMY
PS_OUTPUT ps_main18(PS_INPUT input)
PS_OUTPUT ps_yuv(PS_INPUT input)
{
PS_OUTPUT output;
@@ -367,11 +367,11 @@ PS_OUTPUT ps_main18(PS_INPUT input)
return output;
}
PS_OUTPUT ps_main19(PS_INPUT input)
PS_OUTPUT ps_osd(PS_INPUT input)
{
PS_OUTPUT output;
output.c = input.c * float4(1.0, 1.0, 1.0, sample_c(input.t).r);
output.c = input.c * float4(1.0, 1.0, 1.0, sample_c(input.t).a);
return output;
}
@@ -410,6 +410,23 @@ float4 fetch_red(int2 xy)
return sample_p(rt.r) * 255.0f;
}
float4 fetch_green(int2 xy)
{
float4 rt;
if ((PS_DEPTH_FMT == 1) || (PS_DEPTH_FMT == 2))
{
int depth = (fetch_raw_depth(xy) >> 8) & 0xFF;
rt = (float4)(depth) / 255.0f;
}
else
{
rt = fetch_raw_color(xy);
}
return sample_p(rt.g) * 255.0f;
}
float4 fetch_blue(int2 xy)
{
float4 rt;
@@ -427,12 +444,6 @@ float4 fetch_blue(int2 xy)
return sample_p(rt.b) * 255.0f;
}
float4 fetch_green(int2 xy)
{
float4 rt = fetch_raw_color(xy);
return sample_p(rt.g) * 255.0f;
}
float4 fetch_alpha(int2 xy)
{
float4 rt = fetch_raw_color(xy);
@@ -667,6 +678,24 @@ void ps_dither(inout float3 C, float2 pos_xy)
}
}
void ps_color_clamp_wrap(inout float3 C)
{
// When dithering the bottom 3 bits become meaningless and cause lines in the picture
// so we need to limit the color depth on dithered items
if (SW_BLEND || PS_DITHER)
{
// Standard Clamp
if (PS_COLCLIP == 0 && PS_HDR == 0)
C = clamp(C, (float3)0.0f, (float3)255.0f);
// In 16 bits format, only 5 bits of color are used. It impacts shadows computation of Castlevania
if (PS_DFMT == FMT_16)
C = (float3)((int3)C & (int3)0xF8);
else if (PS_COLCLIP == 1 && PS_HDR == 0)
C = (float3)((int3)C & (int3)0xFF);
}
}
void ps_blend(inout float4 Color, float As, float2 pos_xy)
{
if (SW_BLEND)
@@ -677,33 +706,17 @@ void ps_blend(inout float4 Color, float As, float2 pos_xy)
float3 Cd = RT.rgb;
float3 Cs = Color.rgb;
float3 Cv;
float3 A = (PS_BLEND_A == 0) ? Cs : ((PS_BLEND_A == 1) ? Cd : (float3)0.0f);
float3 B = (PS_BLEND_B == 0) ? Cs : ((PS_BLEND_B == 1) ? Cd : (float3)0.0f);
float3 C = (PS_BLEND_C == 0) ? As : ((PS_BLEND_C == 1) ? Ad : Af);
float3 D = (PS_BLEND_D == 0) ? Cs : ((PS_BLEND_D == 1) ? Cd : (float3)0.0f);
Cv = (PS_BLEND_A == PS_BLEND_B) ? D : trunc(((A - B) * C) + D);
Color.rgb = (PS_BLEND_A == PS_BLEND_B) ? D : trunc(((A - B) * C) + D);
// PABE
if (PS_PABE)
Cv = (Color.a >= 128.0f) ? Cv : Color.rgb;
// Dithering
ps_dither(Cv, pos_xy);
// Standard Clamp
if (PS_COLCLIP == 0 && PS_HDR == 0)
Cv = clamp(Cv, (float3)0.0f, (float3)255.0f);
// In 16 bits format, only 5 bits of color are used. It impacts shadows computation of Castlevania
if (PS_DFMT == FMT_16)
Cv = (float3)((int3)Cv & (int3)0xF8);
else if (PS_COLCLIP == 1 && PS_HDR == 0)
Cv = (float3)((int3)Cv & (int3)0xFF);
Color.rgb = Cv;
Color.rgb = (As >= 1.0f) ? Color.rgb : Cs;
}
}
@@ -755,21 +768,14 @@ PS_OUTPUT ps_main(PS_INPUT input)
if (C.a < A_one) C.a += A_one;
}
if (!SW_BLEND)
ps_dither(C.rgb, input.p.xy);
ps_blend(C, alpha_blend, input.p.xy);
ps_fbmask(C, input.p.xy);
ps_dither(C.rgb, input.p.xy);
// When dithering the bottom 3 bits become meaningless and cause lines in the picture
// so we need to limit the color depth on dithered items
// SW_BLEND already deals with this so no need to do in those cases
if (!SW_BLEND && PS_DITHER && PS_DFMT == FMT_16 && !PS_COLCLIP)
{
C.rgb = clamp(C.rgb, (float3)0.0f, (float3)255.0f);
C.rgb = (uint3)((uint3)C.rgb & (uint3)0xF8);
}
// Color clamp/wrap needs to be done after sw blending and dithering
ps_color_clamp_wrap(C.rgb);
ps_fbmask(C, input.p.xy);
output.c0 = C / 255.0f;
output.c1 = (float4)(alpha_blend);
@@ -52,8 +52,7 @@ layout(std140, binding = 15) uniform cb15
int EMODA;
int EMODC;
int _pad0;
int _pad1;
ivec2 pad_cb15;
};
#endif
@@ -63,7 +62,8 @@ layout(std140, binding = 20) uniform cb20
vec2 VertexScale;
vec2 VertexOffset;
vec4 TextureOffset;
vec2 TextureScale;
vec2 TextureOffset;
vec2 PointSize;
uint MaxDepth;
@@ -80,7 +80,7 @@ layout(std140, binding = 21) uniform cb21
vec4 WH;
vec2 TA;
float pad0_cb21;
float MaxDepthPS;
float Af;
uvec4 MskFix;
@@ -91,12 +91,9 @@ layout(std140, binding = 21) uniform cb21
vec4 MinMax;
vec2 TextureScale;
vec2 pad_cb21;
vec2 TC_OffsetHack;
vec3 pad1_cb21;
float MaxDepthPS;
mat4 DitherMatrix;
};
#endif
@@ -42,7 +42,7 @@ in SHADER
} PSin;
// Give a different name so I remember there is a special case!
#if defined(ps_main1) || defined(ps_main10)
#if defined(ps_convert_rgba8_16bits) || defined(ps_convert_float32_32bits)
layout(location = 0) out uint SV_Target1;
#else
layout(location = 0) out vec4 SV_Target0;
@@ -65,15 +65,15 @@ vec4 ps_crt(uint i)
return sample_c() * clamp((mask[i] + 0.5f), 0.0f, 1.0f);
}
#ifdef ps_main0
void ps_main0()
#ifdef ps_copy
void ps_copy()
{
SV_Target0 = sample_c();
}
#endif
#ifdef ps_main1
void ps_main1()
#ifdef ps_convert_rgba8_16bits
void ps_convert_rgba8_16bits()
{
// Input Color is RGBA8
@@ -117,16 +117,16 @@ void ps_main1()
}
#endif
#ifdef ps_main10
void ps_main10()
#ifdef ps_convert_float32_32bits
void ps_convert_float32_32bits()
{
// Convert a GL_FLOAT32 depth texture into a 32 bits UINT texture
SV_Target1 = uint(exp2(32.0f) * sample_c().r);
}
#endif
#ifdef ps_main11
void ps_main11()
#ifdef ps_convert_float32_rgba8
void ps_convert_float32_rgba8()
{
// Convert a GL_FLOAT32 depth texture into a RGBA color texture
const vec4 bitSh = vec4(exp2(24.0f), exp2(16.0f), exp2(8.0f), exp2(0.0f));
@@ -138,8 +138,8 @@ void ps_main11()
}
#endif
#ifdef ps_main12
void ps_main12()
#ifdef ps_convert_float16_rgb5a1
void ps_convert_float16_rgb5a1()
{
// Convert a GL_FLOAT32 (only 16 lsb) depth into a RGB5A1 color texture
const vec4 bitSh = vec4(exp2(32.0f), exp2(27.0f), exp2(22.0f), exp2(17.0f));
@@ -150,8 +150,8 @@ void ps_main12()
}
#endif
#ifdef ps_main13
void ps_main13()
#ifdef ps_convert_rgba8_float32
void ps_convert_rgba8_float32()
{
// Convert a RRGBA texture into a float depth texture
// FIXME: I'm afraid of the accuracy
@@ -160,8 +160,8 @@ void ps_main13()
}
#endif
#ifdef ps_main14
void ps_main14()
#ifdef ps_convert_rgba8_float24
void ps_convert_rgba8_float24()
{
// Same as above but without the alpha channel (24 bits Z)
@@ -172,8 +172,8 @@ void ps_main14()
}
#endif
#ifdef ps_main15
void ps_main15()
#ifdef ps_convert_rgba8_float16
void ps_convert_rgba8_float16()
{
// Same as above but without the A/B channels (16 bits Z)
@@ -184,8 +184,8 @@ void ps_main15()
}
#endif
#ifdef ps_main16
void ps_main16()
#ifdef ps_convert_rgb5a1_float16
void ps_convert_rgb5a1_float16()
{
// Convert a RGB5A1 (saved as RGBA8) color to a 16 bit Z
// FIXME: I'm afraid of the accuracy
@@ -196,8 +196,8 @@ void ps_main16()
}
#endif
#ifdef ps_main17
void ps_main17()
#ifdef ps_convert_rgba_8i
void ps_convert_rgba_8i()
{
// Potential speed optimization. There is a high probability that
@@ -278,15 +278,15 @@ void ps_main17()
}
#endif
#ifdef ps_main19
void ps_main19()
#ifdef ps_osd
void ps_osd()
{
SV_Target0 = PSin.c * vec4(1.0, 1.0, 1.0, sample_c().r);
}
#endif
#ifdef ps_main7
void ps_main7()
#ifdef ps_filter_transparency
void ps_filter_transparency()
{
vec4 c = sample_c();
@@ -296,7 +296,7 @@ void ps_main7()
}
#endif
#ifdef ps_main5
#ifdef ps_filter_scanlines
vec4 ps_scanlines(uint i)
{
vec4 mask[2] =
@@ -308,7 +308,7 @@ vec4 ps_scanlines(uint i)
return sample_c() * clamp((mask[i] + 0.5f), 0.0f, 1.0f);
}
void ps_main5() // scanlines
void ps_filter_scanlines() // scanlines
{
highp uvec4 p = uvec4(gl_FragCoord);
@@ -318,8 +318,8 @@ void ps_main5() // scanlines
}
#endif
#ifdef ps_main6
void ps_main6() // diagonal
#ifdef ps_filter_diagonal
void ps_filter_diagonal() // diagonal
{
highp uvec4 p = uvec4(gl_FragCoord);
@@ -329,8 +329,8 @@ void ps_main6() // diagonal
}
#endif
#ifdef ps_main8
void ps_main8() // triangular
#ifdef ps_filter_triangular
void ps_filter_triangular() // triangular
{
highp uvec4 p = uvec4(gl_FragCoord);
@@ -340,8 +340,8 @@ void ps_main8() // triangular
}
#endif
#ifdef ps_main9
void ps_main9()
#ifdef ps_filter_complex
void ps_filter_complex()
{
const float PI = 3.14159265359f;
@@ -362,8 +362,8 @@ void ps_main9()
// Used for DATE (stencil)
// DATM == 1
#ifdef ps_main2
void ps_main2()
#ifdef ps_datm1
void ps_datm1()
{
if(sample_c().a < (127.5f / 255.0f)) // >= 0x80 pass
discard;
@@ -372,23 +372,23 @@ void ps_main2()
// Used for DATE (stencil)
// DATM == 0
#ifdef ps_main3
void ps_main3()
#ifdef ps_datm0
void ps_datm0()
{
if((127.5f / 255.0f) < sample_c().a) // < 0x80 pass (== 0x80 should not pass)
discard;
}
#endif
#ifdef ps_main4
void ps_main4()
#ifdef ps_mod256
void ps_mod256()
{
SV_Target0 = mod(round(sample_c() * 255.0f), 256.0f) / 255.0f;
}
#endif
#ifdef ps_main18
void ps_main18()
#ifdef ps_yuv
void ps_yuv()
{
vec4 i = sample_c();
vec4 o;
@@ -369,6 +369,17 @@ vec4 fetch_red()
return sample_p(rt.r) * 255.0f;
}
vec4 fetch_green()
{
#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2
int depth = (fetch_raw_depth() >> 8) & 0xFF;
vec4 rt = vec4(depth) / 255.0f;
#else
vec4 rt = fetch_raw_color();
#endif
return sample_p(rt.g) * 255.0f;
}
vec4 fetch_blue()
{
#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2
@@ -380,12 +391,6 @@ vec4 fetch_blue()
return sample_p(rt.b) * 255.0f;
}
vec4 fetch_green()
{
vec4 rt = fetch_raw_color();
return sample_p(rt.g) * 255.0f;
}
vec4 fetch_alpha()
{
vec4 rt = fetch_raw_color();
@@ -611,7 +616,7 @@ void ps_fbmask(inout vec4 C)
#endif
}
void ps_dither(inout vec4 C)
void ps_dither(inout vec3 C)
{
#if PS_DITHER
#if PS_DITHER == 2
@@ -619,7 +624,35 @@ void ps_dither(inout vec4 C)
#else
ivec2 fpos = ivec2(gl_FragCoord.xy / ScalingFactor.x);
#endif
C.rgb += DitherMatrix[fpos.y&3][fpos.x&3];
C += DitherMatrix[fpos.y&3][fpos.x&3];
#endif
}
void ps_color_clamp_wrap(inout vec3 C)
{
// When dithering the bottom 3 bits become meaningless and cause lines in the picture
// so we need to limit the color depth on dithered items
#if SW_BLEND || PS_DITHER
// Correct the Color value based on the output format
#if PS_COLCLIP == 0 && PS_HDR == 0
// Standard Clamp
C = clamp(C, vec3(0.0f), vec3(255.0f));
#endif
// FIXME rouding of negative float?
// compiler uses trunc but it might need floor
// Warning: normally blending equation is mult(A, B) = A * B >> 7. GPU have the full accuracy
// GS: Color = 1, Alpha = 255 => output 1
// GPU: Color = 1/255, Alpha = 255/255 * 255/128 => output 1.9921875
#if PS_DFMT == FMT_16
// In 16 bits format, only 5 bits of colors are used. It impacts shadows computation of Castlevania
C = vec3(ivec3(C) & ivec3(0xF8));
#elif PS_COLCLIP == 1 && PS_HDR == 0
C = vec3(ivec3(C) & ivec3(0xFF));
#endif
#endif
}
@@ -627,7 +660,6 @@ void ps_blend(inout vec4 Color, float As)
{
#if SW_BLEND
vec4 RT = trunc(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0) * 255.0f + 0.1f);
vec4 Color_pabe = Color;
#if PS_DFMT == FMT_24
float Ad = 1.0f;
@@ -681,30 +713,7 @@ void ps_blend(inout vec4 Color, float As)
// PABE
#if PS_PABE
Color.rgb = (Color_pabe.a >= 128.0f) ? Color.rgb : Color_pabe.rgb;
#endif
// Dithering
ps_dither(Color);
// Correct the Color value based on the output format
#if PS_COLCLIP == 0 && PS_HDR == 0
// Standard Clamp
Color.rgb = clamp(Color.rgb, vec3(0.0f), vec3(255.0f));
#endif
// FIXME rouding of negative float?
// compiler uses trunc but it might need floor
// Warning: normally blending equation is mult(A, B) = A * B >> 7. GPU have the full accuracy
// GS: Color = 1, Alpha = 255 => output 1
// GPU: Color = 1/255, Alpha = 255/255 * 255/128 => output 1.9921875
#if PS_DFMT == FMT_16
// In 16 bits format, only 5 bits of colors are used. It impacts shadows computation of Castlevania
Color.rgb = vec3(ivec3(Color.rgb) & ivec3(0xF8));
#elif PS_COLCLIP == 1 && PS_HDR == 0
Color.rgb = vec3(ivec3(Color.rgb) & ivec3(0xFF));
Color.rgb = (As >= 1.0f) ? Color.rgb : Cs;
#endif
#endif
@@ -835,31 +844,15 @@ void ps_main()
return;
#endif
#if !SW_BLEND
ps_dither(C);
#endif
ps_blend(C, alpha_blend);
ps_dither(C.rgb);
// Color clamp/wrap needs to be done after sw blending and dithering
ps_color_clamp_wrap(C.rgb);
ps_fbmask(C);
// When dithering the bottom 3 bits become meaningless and cause lines in the picture
// so we need to limit the color depth on dithered items
// SW_BLEND already deals with this so no need to do in those cases
#if !SW_BLEND && PS_DITHER && PS_DFMT == FMT_16 && PS_COLCLIP == 0
C.rgb = clamp(C.rgb, vec3(0.0f), vec3(255.0f));
C.rgb = uvec3(uvec3(C.rgb) & uvec3(0xF8));
#endif
// #if PS_HDR == 1
// Use negative value to avoid overflow of the texture (in accumulation mode)
// Note: code were initially done for an Half-Float texture. Due to overflow
// the texture was upgraded to a full float. Maybe this code is useless now!
// Good testcase is castlevania
// if (any(greaterThan(C.rgb, vec3(128.0f)))) {
// C.rgb = (C.rgb - 256.0f);
// }
// #endif
SV_Target0 = C / 255.0f;
SV_Target1 = vec4(alpha_blend);
@@ -24,8 +24,8 @@ const float exp_min32 = exp2(-32.0f);
void texture_coord()
{
vec2 uv = vec2(i_uv) - TextureOffset.xy;
vec2 st = i_st - TextureOffset.xy;
vec2 uv = vec2(i_uv) - TextureOffset;
vec2 st = i_st - TextureOffset;
// Float coordinate
VSout.t_float.xy = st;
+7 -13
View File
@@ -43,7 +43,6 @@ option(BUILD_REPLAY_LOADERS "Build GS replayer to ease testing (developer option
# Path and lib option
#-------------------------------------------------------------------------------
option(PACKAGE_MODE "Use this option to ease packaging of PCSX2 (developer/distribution option)")
option(DISABLE_CHEATS_ZIP "Disable including the cheats_ws.zip file")
option(DISABLE_PCSX2_WRAPPER "Disable including the PCSX2-linux.sh file")
option(DISABLE_SETCAP "Do not set files capabilities")
option(XDG_STD "Use XDG standard path instead of the standard PCSX2 path")
@@ -59,7 +58,7 @@ endif()
if(PACKAGE_MODE)
# Compile all source codes with those defines
list(APPEND PCSX2_DEFS
GAMEINDEX_DIR_COMPILATION=${CMAKE_INSTALL_FULL_DATADIR}/PCSX2
PCSX2_APP_DATADIR="${CMAKE_INSTALL_FULL_DATADIR}/PCSX2"
DOC_DIR_COMPILATION=${CMAKE_INSTALL_FULL_DOCDIR})
endif()
@@ -73,7 +72,7 @@ endif()
#-------------------------------------------------------------------------------
option(USE_ASAN "Enable address sanitizer")
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
set(USE_CLANG TRUE)
message(STATUS "Building with Clang/LLVM.")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
@@ -121,15 +120,7 @@ endif()
# It only cost several MB so disbable it by default
option(CMAKE_BUILD_STRIP "Srip binaries to save a couple of MB (developer option)")
if(NOT DEFINED CMAKE_BUILD_PO)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_BUILD_PO TRUE)
message(STATUS "Enable the building of po files by default in ${CMAKE_BUILD_TYPE} build !!!")
else()
set(CMAKE_BUILD_PO FALSE)
message(STATUS "Disable the building of po files by default in ${CMAKE_BUILD_TYPE} build !!!")
endif()
endif()
option(CMAKE_BUILD_PO "Build po files (modifies git-tracked files)" OFF)
#-------------------------------------------------------------------------------
# Select the architecture
@@ -223,7 +214,10 @@ option(USE_PGO_OPTIMIZE "Enable PGO optimization (use profile)")
if(MSVC)
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>")
else()
add_compile_options(-pipe -fvisibility=hidden -pthread -fno-builtin-strcmp -fno-builtin-memcmp -mfpmath=sse -fno-operator-names)
add_compile_options(-pipe -fvisibility=hidden -pthread -fno-builtin-strcmp -fno-builtin-memcmp -mfpmath=sse)
# -fno-operator-names should only be for C++ files, not C files.
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-operator-names>)
endif()
if(WIN32)
+38 -36
View File
@@ -2,16 +2,13 @@
#
# This will define:
#
# WAYLAND_FOUND - True if Wayland is found
# WAYLAND_LIBRARIES - Link these to use Wayland
# WAYLAND_INCLUDE_DIR - Include directory for Wayland
# WAYLAND_DEFINITIONS - Compiler flags for using Wayland
# Wayland_FOUND - True if Wayland is found
#
# In addition the following more fine grained variables will be defined:
#
# WAYLAND_CLIENT_FOUND WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES
# WAYLAND_SERVER_FOUND WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES
# WAYLAND_EGL_FOUND WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES
# The following imported targets:
# Wayland::Client - Imported Client
# Wayland::Server - Imported Server
# Wayland::Egl - Imported Egl
# Wayland::Cursor - Imported Cursor
#
# Copyright (c) 2013 Martin Gräßlin <mgraesslin@kde.org>
#
@@ -24,39 +21,44 @@ IF (NOT WIN32)
SET(WAYLAND_FIND_QUIETLY TRUE)
ENDIF ()
# Use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor)
FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h)
FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h)
FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h)
FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR NAMES wayland-cursor.h)
SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS})
FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR} ${WAYLAND_CURSOR_INCLUDE_DIR})
set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES})
list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR)
FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client)
FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server)
FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl)
FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CURSOR DEFAULT_MSG WAYLAND_CURSOR_LIBRARIES WAYLAND_CURSOR_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIR)
# FIND_PACKAGE_HANDLE_STANDARD_ARGS is just meant to find the main package and set package found. Not set variables or find individual libs
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Wayland REQUIRED_VARS
WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR
WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR
WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR
WAYLAND_CURSOR_LIBRARIES WAYLAND_CURSOR_INCLUDE_DIR
)
if (WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARIES AND NOT TARGET Wayland::Client)
add_library(Wayland::Client UNKNOWN IMPORTED)
set_target_properties(Wayland::Client PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WAYLAND_CLIENT_INCLUDE_DIR}" IMPORTED_LOCATION "${WAYLAND_CLIENT_LIBRARIES}")
endif()
if (WAYLAND_SERVER_INCLUDE_DIR AND WAYLAND_SERVER_LIBRARIES AND NOT TARGET Wayland::Server)
add_library(Wayland::Server UNKNOWN IMPORTED)
set_target_properties(Wayland::Server PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WAYLAND_SERVER_INCLUDE_DIR}" IMPORTED_LOCATION "${WAYLAND_SERVER_LIBRARIES}")
endif()
if (WAYLAND_EGL_INCLUDE_DIR AND WAYLAND_EGL_LIBRARIES AND NOT TARGET Wayland::Egl)
add_library(Wayland::Egl UNKNOWN IMPORTED)
set_target_properties(Wayland::Egl PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WAYLAND_EGL_INCLUDE_DIR}" IMPORTED_LOCATION "${WAYLAND_EGL_LIBRARIES}")
endif()
if (WAYLAND_CURSOR_INCLUDE_DIR AND WAYLAND_CURSOR_LIBRARIES AND NOT TARGET Wayland::Cursor)
add_library(Wayland::Cursor UNKNOWN IMPORTED)
set_target_properties(Wayland::Cursor PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WAYLAND_CURSOR_INCLUDE_DIR}" IMPORTED_LOCATION "${WAYLAND_CURSOR_LIBRARIES}")
endif()
MARK_AS_ADVANCED(
WAYLAND_INCLUDE_DIR WAYLAND_LIBRARIES
WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES
WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES
WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES
+1 -5
View File
@@ -162,11 +162,7 @@ else()
if(UNIX AND NOT APPLE)
find_package(X11 REQUIRED)
make_imported_target_if_missing(X11::X11 X11)
endif()
if(APPLE)
check_lib(GIO gio-2.0 gio/gio.h)
elseif(UNIX)
# Most plugins (if not all) and PCSX2 core need gtk2, so set the required flags
if (GTK2_API)
find_package(GTK2 REQUIRED gtk)
alias_library(GTK::gtk GTK2::gtk)
+1 -1
View File
@@ -18,8 +18,8 @@
#if !defined(_WIN32)
#include "common/AlignedMalloc.h"
#include "common/Assertions.h"
#include "common/ScopedAlloc.h"
void* __fastcall _aligned_malloc(size_t size, size_t align)
{
+39 -132
View File
@@ -80,50 +80,57 @@ extern Fnptr_OutOfMemory pxDoOutOfMemory;
// --------------------------------------------------------------------------------------
// BaseScopedAlloc
// AlignedBuffer
// --------------------------------------------------------------------------------------
// Base class that allows various ScopedMalloc types to be passed to functions that act
// on them.
// A simple container class for an aligned allocation. By default, no bounds checking is
// performed, and there is no option for enabling bounds checking. If bounds checking and
// other features are needed, use the more robust SafeArray<> instead.
//
// Rationale: This class and the derived varieties are provided as a simple autonomous self-
// destructing container for malloc. The entire class is almost completely dependency free,
// and thus can be included everywhere and anywhere without dependency hassles.
//
template <typename T>
class BaseScopedAlloc
template <typename T, uint align>
class AlignedBuffer
{
protected:
T* m_buffer;
uint m_size;
static_assert(std::is_pod<T>::value, "Must use a POD type");
struct Deleter
{
void operator()(T* ptr)
{
_aligned_free(ptr);
}
};
std::unique_ptr<T[], Deleter> m_buffer;
std::size_t m_size;
public:
BaseScopedAlloc()
AlignedBuffer(size_t size = 0)
{
m_buffer = NULL;
m_size = 0;
Alloc(size);
}
virtual ~BaseScopedAlloc()
{
//pxAssert(m_buffer==NULL);
}
public:
size_t GetSize() const { return m_size; }
size_t GetLength() const { return m_size; }
// Allocates the object to the specified size. If an existing allocation is in
// place, it is freed and replaced with the new allocation, and all data is lost.
// Parameter:
// newSize - size of the new allocation, in elements (not bytes!). If the specified
// size is 0, the the allocation is freed, same as calling Free().
virtual void Alloc(size_t newsize) = 0;
void Alloc(size_t newsize)
{
m_size = newsize;
m_buffer.reset();
if (!m_size)
return;
// Re-sizes the allocation to the requested size, without any data loss.
// Parameter:
// newSize - size of the new allocation, in elements (not bytes!). If the specified
// size is 0, the the allocation is freed, same as calling Free().
virtual void Resize(size_t newsize) = 0;
m_buffer.reset(reinterpret_cast<T*>(_aligned_malloc(this->m_size * sizeof(T), align)));
if (!m_buffer)
throw std::bad_alloc();
}
void Resize(size_t newsize)
{
m_buffer.reset(reinterpret_cast<T*>(pcsx2_aligned_realloc(m_buffer.release(), newsize * sizeof(T), align, m_size * sizeof(T))));
m_size = newsize;
if (!m_buffer)
throw std::bad_alloc();
}
void Free()
{
@@ -162,103 +169,3 @@ public:
return m_buffer[idx];
}
};
// --------------------------------------------------------------------------------------
// ScopedAlloc
// --------------------------------------------------------------------------------------
// A simple container class for a standard malloc allocation. By default, no bounds checking
// is performed, and there is no option for enabling bounds checking. If bounds checking and
// other features are needed, use the more robust SafeArray<> instead.
//
// See docs for BaseScopedAlloc for details and rationale.
//
template <typename T>
class ScopedAlloc : public BaseScopedAlloc<T>
{
typedef BaseScopedAlloc<T> _parent;
public:
ScopedAlloc(size_t size = 0)
: _parent()
{
Alloc(size);
}
virtual ~ScopedAlloc()
{
safe_free(this->m_buffer);
}
virtual void Alloc(size_t newsize)
{
safe_free(this->m_buffer);
this->m_size = newsize;
if (!this->m_size)
return;
this->m_buffer = (T*)malloc(this->m_size * sizeof(T));
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlloc");
}
virtual void Resize(size_t newsize)
{
this->m_size = newsize;
this->m_buffer = (T*)realloc(this->m_buffer, this->m_size * sizeof(T));
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlloc::Resize");
}
using _parent::operator[];
};
// --------------------------------------------------------------------------------------
// ScopedAlignedAlloc
// --------------------------------------------------------------------------------------
// A simple container class for an aligned allocation. By default, no bounds checking is
// performed, and there is no option for enabling bounds checking. If bounds checking and
// other features are needed, use the more robust SafeArray<> instead.
//
// See docs for BaseScopedAlloc for details and rationale.
//
template <typename T, uint align>
class ScopedAlignedAlloc : public BaseScopedAlloc<T>
{
typedef BaseScopedAlloc<T> _parent;
public:
ScopedAlignedAlloc(size_t size = 0)
: _parent()
{
Alloc(size);
}
virtual ~ScopedAlignedAlloc()
{
safe_aligned_free(this->m_buffer);
}
virtual void Alloc(size_t newsize)
{
safe_aligned_free(this->m_buffer);
this->m_size = newsize;
if (!this->m_size)
return;
this->m_buffer = (T*)_aligned_malloc(this->m_size * sizeof(T), align);
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc");
}
virtual void Resize(size_t newsize)
{
this->m_buffer = (T*)pcsx2_aligned_realloc(this->m_buffer, newsize * sizeof(T), align, this->m_size * sizeof(T));
this->m_size = newsize;
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize");
}
using _parent::operator[];
};
+12 -1
View File
@@ -20,12 +20,14 @@ target_sources(common PRIVATE
FastJmp.cpp
GL/Context.cpp
GL/StreamBuffer.cpp
FileSystem.cpp
IniInterface.cpp
Mutex.cpp
Misc.cpp
PathUtils.cpp
PrecompiledHeader.cpp
Perf.cpp
ProgressCallback.cpp
pxStreams.cpp
pxTranslate.cpp
RwMutex.cpp
@@ -33,6 +35,7 @@ target_sources(common PRIVATE
SettingsWrapper.cpp
StringHelpers.cpp
StringUtil.cpp
Timer.cpp
ThreadTools.cpp
WindowInfo.cpp
emitter/bmi.cpp
@@ -61,6 +64,7 @@ target_sources(common PRIVATE
# x86emitter headers
target_sources(common PRIVATE
Align.h
AlignedMalloc.h
Assertions.h
boost_spsc_queue.hpp
Console.h
@@ -68,6 +72,7 @@ target_sources(common PRIVATE
EventSource.h
Exceptions.h
FastJmp.h
FileSystem.h
General.h
GL/Context.h
GL/StreamBuffer.h
@@ -76,18 +81,19 @@ target_sources(common PRIVATE
Path.h
PageFaultSource.h
PrecompiledHeader.h
ProgressCallback.h
pxForwardDefs.h
pxStreams.h
RedtapeWindows.h
RwMutex.h
SafeArray.h
ScopedAlloc.h
ScopedGuard.h
ScopedPtrMT.h
SettingsInterface.h
SettingsWrapper.h
StringHelpers.h
StringUtil.h
Timer.h
Threading.h
TraceLog.h
WindowInfo.h
@@ -170,6 +176,11 @@ else()
endif()
endif()
if (USE_GCC AND CMAKE_INTERPROCEDURAL_OPTIMIZATION)
# GCC LTO doesn't work with asm statements
set_source_files_properties(FastJmp.cpp PROPERTIES COMPILE_FLAGS -fno-lto)
endif()
target_link_libraries(common PRIVATE ${LIBC_LIBRARIES} PUBLIC wxWidgets::all glad)
target_compile_features(common PUBLIC cxx_std_17)
target_include_directories(common PUBLIC ../3rdparty/include ../)
+2 -2
View File
@@ -102,7 +102,7 @@
pxAssert(EnumIsValid(id)); \
} \
\
extern const wxChar* EnumToString(enumName id)
extern const char* EnumToString(enumName id)
class pxEnumEnd_t
{
@@ -277,4 +277,4 @@ extern wxString fromAscii(const char* src);
#include "common/Assertions.h"
#include "common/Exceptions.h"
#include "common/ScopedAlloc.h"
#include "common/AlignedMalloc.h"
File diff suppressed because it is too large Load Diff
+162
View File
@@ -0,0 +1,162 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Pcsx2Defs.h"
#include <cstdio>
#include <ctime>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <sys/stat.h>
#ifdef _WIN32
#define FS_OSPATH_SEPARATOR_CHARACTER '\\'
#define FS_OSPATH_SEPARATOR_STR "\\"
#else
#define FS_OSPATH_SEPARATOR_CHARACTER '/'
#define FS_OSPATH_SEPARATOR_STR "/"
#endif
enum FILESYSTEM_FILE_ATTRIBUTES
{
FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY = 1,
FILESYSTEM_FILE_ATTRIBUTE_READ_ONLY = 2,
FILESYSTEM_FILE_ATTRIBUTE_COMPRESSED = 4,
};
enum FILESYSTEM_FIND_FLAGS
{
FILESYSTEM_FIND_RECURSIVE = (1 << 0),
FILESYSTEM_FIND_RELATIVE_PATHS = (1 << 1),
FILESYSTEM_FIND_HIDDEN_FILES = (1 << 2),
FILESYSTEM_FIND_FOLDERS = (1 << 3),
FILESYSTEM_FIND_FILES = (1 << 4),
FILESYSTEM_FIND_KEEP_ARRAY = (1 << 5),
};
struct FILESYSTEM_STAT_DATA
{
std::time_t ModificationTime;
s64 Size;
u32 Attributes;
};
struct FILESYSTEM_FIND_DATA
{
std::time_t ModificationTime;
std::string FileName;
s64 Size;
u32 Attributes;
};
namespace FileSystem
{
using FindResultsArray = std::vector<FILESYSTEM_FIND_DATA>;
/// Builds a path relative to the specified file
std::string BuildRelativePath(const std::string_view& filename, const std::string_view& new_filename);
/// Joins path components together, producing a new path.
std::string JoinPath(const std::string_view& base, const std::string_view& next);
/// Sanitizes a filename for use in a filesystem.
void SanitizeFileName(char* Destination, u32 cbDestination, const char* FileName, bool StripSlashes /* = true */);
void SanitizeFileName(std::string& Destination, bool StripSlashes = true);
/// Returns true if the specified path is an absolute path (C:\Path on Windows or /path on Unix).
bool IsAbsolutePath(const std::string_view& path);
/// Returns a view of the extension of a filename.
std::string_view GetExtension(const std::string_view& path);
/// Removes the extension of a filename.
std::string_view StripExtension(const std::string_view& path);
/// Replaces the extension of a filename with another.
std::string ReplaceExtension(const std::string_view& path, const std::string_view& new_extension);
/// Returns the display name of a filename. Usually this is the same as the path.
std::string GetDisplayNameFromPath(const std::string_view& path);
/// Returns the directory component of a filename.
std::string_view GetPathDirectory(const std::string_view& path);
/// Returns the filename component of a filename.
std::string_view GetFileNameFromPath(const std::string_view& path);
/// Returns the file title (less the extension and path) from a filename.
std::string_view GetFileTitleFromPath(const std::string_view& path);
/// Returns a list of "root directories" (i.e. root/home directories on Linux, drive letters on Windows).
std::vector<std::string> GetRootDirectoryList();
/// Search for files
bool FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results);
/// Stat file
bool StatFile(const char* path, struct stat* st);
bool StatFile(std::FILE* fp, struct stat* st);
bool StatFile(const char* path, FILESYSTEM_STAT_DATA* pStatData);
bool StatFile(std::FILE* fp, FILESYSTEM_STAT_DATA* pStatData);
s64 GetPathFileSize(const char* path);
/// File exists?
bool FileExists(const char* path);
/// Directory exists?
bool DirectoryExists(const char* path);
/// Delete file
bool DeleteFilePath(const char* path);
/// Rename file
bool RenamePath(const char* OldPath, const char* NewPath);
/// open files
using ManagedCFilePtr = std::unique_ptr<std::FILE, void (*)(std::FILE*)>;
ManagedCFilePtr OpenManagedCFile(const char* filename, const char* mode);
std::FILE* OpenCFile(const char* filename, const char* mode);
int FSeek64(std::FILE* fp, s64 offset, int whence);
s64 FTell64(std::FILE* fp);
s64 FSize64(std::FILE* fp);
int OpenFDFile(const char* filename, int flags, int mode);
std::optional<std::vector<u8>> ReadBinaryFile(const char* filename);
std::optional<std::vector<u8>> ReadBinaryFile(std::FILE* fp);
std::optional<std::string> ReadFileToString(const char* filename);
std::optional<std::string> ReadFileToString(std::FILE* fp);
bool WriteBinaryFile(const char* filename, const void* data, size_t data_length);
bool WriteFileToString(const char* filename, const std::string_view& sv);
/// creates a directory in the local filesystem
/// if the directory already exists, the return value will be true.
/// if Recursive is specified, all parent directories will be created
/// if they do not exist.
bool CreateDirectoryPath(const char* path, bool recursive);
/// Returns the path to the current executable.
std::string GetProgramPath();
/// Retrieves the current working directory.
std::string GetWorkingDirectory();
/// Sets the current working directory. Returns true if successful.
bool SetWorkingDirectory(const char* path);
}; // namespace FileSystem
+2
View File
@@ -225,6 +225,8 @@ namespace Path
extern wxString Combine(const wxString& srcPath, const wxString& srcFile);
extern wxString Combine(const wxDirName& srcPath, const wxFileName& srcFile);
extern wxString Combine(const wxString& srcPath, const wxDirName& srcFile);
extern std::string CombineStdString(const wxDirName& srcPath, const std::string_view& srcFile);
extern std::string CombineStdString(const std::string_view& srcPath, const std::string_view& srcFile);
extern wxString ReplaceExtension(const wxString& src, const wxString& ext);
extern wxString ReplaceFilename(const wxString& src, const wxString& newfilename);
extern wxString GetFilename(const wxString& src);
+15
View File
@@ -149,6 +149,21 @@ wxString Path::Combine(const wxString& srcPath, const wxDirName& srcFile)
return (wxDirName(srcPath) + srcFile).ToString();
}
std::string Path::CombineStdString(const wxDirName& srcPath, const std::string_view& srcFile)
{
const wxString wxResult((srcPath + wxString::FromUTF8(srcFile.data(), srcFile.length())).GetFullPath());
const wxCharBuffer wxBuf(wxResult.ToUTF8());
return std::string(wxBuf.data(), wxBuf.length());
}
std::string Path::CombineStdString(const std::string_view& srcPath, const std::string_view& srcFile)
{
const wxDirName srcPathDir(wxString::FromUTF8(srcPath.data(), srcPath.length()));
const wxString wxResult((srcPathDir + wxString::FromUTF8(srcFile.data(), srcFile.length())).GetFullPath());
const wxCharBuffer wxBuf(wxResult.ToUTF8());
return std::string(wxBuf.data(), wxBuf.length());
}
// Replaces the extension of the file with the one given.
// This function works for path names as well as file names.
wxString Path::ReplaceExtension(const wxString& src, const wxString& ext)
+248
View File
@@ -0,0 +1,248 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Assertions.h"
#include "ProgressCallback.h"
#include "StringUtil.h"
#include "Console.h"
#include <cmath>
#include <cstdio>
#include <limits>
ProgressCallback::~ProgressCallback() {}
void ProgressCallback::SetFormattedStatusText(const char* Format, ...)
{
va_list ap;
va_start(ap, Format);
const std::string str(StringUtil::StdStringFromFormatV(Format, ap));
va_end(ap);
SetStatusText(str.c_str());
}
void ProgressCallback::DisplayFormattedError(const char* format, ...)
{
va_list ap;
va_start(ap, format);
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
va_end(ap);
DisplayError(str.c_str());
}
void ProgressCallback::DisplayFormattedWarning(const char* format, ...)
{
va_list ap;
va_start(ap, format);
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
va_end(ap);
DisplayWarning(str.c_str());
}
void ProgressCallback::DisplayFormattedInformation(const char* format, ...)
{
va_list ap;
va_start(ap, format);
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
va_end(ap);
DisplayInformation(str.c_str());
}
void ProgressCallback::DisplayFormattedDebugMessage(const char* format, ...)
{
va_list ap;
va_start(ap, format);
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
va_end(ap);
DisplayDebugMessage(str.c_str());
}
void ProgressCallback::DisplayFormattedModalError(const char* format, ...)
{
va_list ap;
va_start(ap, format);
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
va_end(ap);
ModalError(str.c_str());
}
bool ProgressCallback::DisplayFormattedModalConfirmation(const char* format, ...)
{
va_list ap;
va_start(ap, format);
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
va_end(ap);
return ModalConfirmation(str.c_str());
}
void ProgressCallback::DisplayFormattedModalInformation(const char* format, ...)
{
va_list ap;
va_start(ap, format);
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
va_end(ap);
ModalInformation(str.c_str());
}
class NullProgressCallbacks final : public ProgressCallback
{
public:
void PushState() override {}
void PopState() override {}
bool IsCancelled() const override { return false; }
bool IsCancellable() const override { return false; }
void SetCancellable(bool cancellable) override {}
void SetTitle(const char* title) override {}
void SetStatusText(const char* statusText) override {}
void SetProgressRange(u32 range) override {}
void SetProgressValue(u32 value) override {}
void IncrementProgressValue() override {}
void DisplayError(const char* message) override { Console.Error("%s", message); }
void DisplayWarning(const char* message) override { Console.Warning("%s", message); }
void DisplayInformation(const char* message) override { Console.WriteLn("%s", message); }
void DisplayDebugMessage(const char* message) override { DevCon.WriteLn("%s", message); }
void ModalError(const char* message) override { Console.Error(message); }
bool ModalConfirmation(const char* message) override
{
Console.WriteLn("%s", message);
return false;
}
void ModalInformation(const char* message) override { Console.WriteLn("%s", message); }
};
static NullProgressCallbacks s_nullProgressCallbacks;
ProgressCallback* ProgressCallback::NullProgressCallback = &s_nullProgressCallbacks;
BaseProgressCallback::BaseProgressCallback()
: m_cancellable(false)
, m_cancelled(false)
, m_progress_range(1)
, m_progress_value(0)
, m_base_progress_value(0)
, m_saved_state(NULL)
{
}
BaseProgressCallback::~BaseProgressCallback()
{
State* pNextState = m_saved_state;
while (pNextState != NULL)
{
State* pCurrentState = pNextState;
pNextState = pCurrentState->next_saved_state;
delete pCurrentState;
}
}
void BaseProgressCallback::PushState()
{
State* pNewState = new State;
pNewState->cancellable = m_cancellable;
pNewState->status_text = m_status_text;
pNewState->progress_range = m_progress_range;
pNewState->progress_value = m_progress_value;
pNewState->base_progress_value = m_base_progress_value;
pNewState->next_saved_state = m_saved_state;
m_saved_state = pNewState;
}
void BaseProgressCallback::PopState()
{
pxAssert(m_saved_state);
State* state = m_saved_state;
m_saved_state = nullptr;
// impose the current position into the previous range
const u32 new_progress_value =
(m_progress_range != 0) ?
static_cast<u32>(((float)m_progress_value / (float)m_progress_range) * (float)state->progress_range) :
state->progress_value;
m_cancellable = state->cancellable;
m_status_text = std::move(state->status_text);
m_progress_range = state->progress_range;
m_progress_value = new_progress_value;
m_base_progress_value = state->base_progress_value;
m_saved_state = state->next_saved_state;
delete state;
}
bool BaseProgressCallback::IsCancelled() const
{
return m_cancelled;
}
bool BaseProgressCallback::IsCancellable() const
{
return m_cancellable;
}
void BaseProgressCallback::SetCancellable(bool cancellable)
{
m_cancellable = cancellable;
}
void BaseProgressCallback::SetStatusText(const char* text)
{
m_status_text = text;
}
void BaseProgressCallback::SetProgressRange(u32 range)
{
if (m_saved_state)
{
// impose the previous range on this range
m_progress_range = m_saved_state->progress_range * range;
m_base_progress_value = m_progress_value = m_saved_state->progress_value * range;
}
else
{
m_progress_range = range;
m_progress_value = 0;
m_base_progress_value = 0;
}
}
void BaseProgressCallback::SetProgressValue(u32 value)
{
m_progress_value = m_base_progress_value + value;
}
void BaseProgressCallback::IncrementProgressValue()
{
SetProgressValue((m_progress_value - m_base_progress_value) + 1);
}
+105
View File
@@ -0,0 +1,105 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Pcsx2Defs.h"
#include <string>
/**
* Progress callbacks, abstracts a blocking operation and allows it to report progress
* without having any dependency on the UI.
*/
class ProgressCallback
{
public:
virtual ~ProgressCallback();
virtual void PushState() = 0;
virtual void PopState() = 0;
virtual bool IsCancelled() const = 0;
virtual bool IsCancellable() const = 0;
virtual void SetCancellable(bool cancellable) = 0;
virtual void SetTitle(const char* title) = 0;
virtual void SetStatusText(const char* text) = 0;
virtual void SetProgressRange(u32 range) = 0;
virtual void SetProgressValue(u32 value) = 0;
virtual void IncrementProgressValue() = 0;
void SetFormattedStatusText(const char* Format, ...);
virtual void DisplayError(const char* message) = 0;
virtual void DisplayWarning(const char* message) = 0;
virtual void DisplayInformation(const char* message) = 0;
virtual void DisplayDebugMessage(const char* message) = 0;
virtual void ModalError(const char* message) = 0;
virtual bool ModalConfirmation(const char* message) = 0;
virtual void ModalInformation(const char* message) = 0;
void DisplayFormattedError(const char* format, ...);
void DisplayFormattedWarning(const char* format, ...);
void DisplayFormattedInformation(const char* format, ...);
void DisplayFormattedDebugMessage(const char* format, ...);
void DisplayFormattedModalError(const char* format, ...);
bool DisplayFormattedModalConfirmation(const char* format, ...);
void DisplayFormattedModalInformation(const char* format, ...);
public:
static ProgressCallback* NullProgressCallback;
};
class BaseProgressCallback : public ProgressCallback
{
public:
BaseProgressCallback();
virtual ~BaseProgressCallback();
virtual void PushState() override;
virtual void PopState() override;
virtual bool IsCancelled() const override;
virtual bool IsCancellable() const override;
virtual void SetCancellable(bool cancellable) override;
virtual void SetStatusText(const char* text) override;
virtual void SetProgressRange(u32 range) override;
virtual void SetProgressValue(u32 value) override;
virtual void IncrementProgressValue() override;
protected:
struct State
{
State* next_saved_state;
std::string status_text;
u32 progress_range;
u32 progress_value;
u32 base_progress_value;
bool cancellable;
};
bool m_cancellable;
bool m_cancelled;
std::string m_status_text;
u32 m_progress_range;
u32 m_progress_value;
u32 m_base_progress_value;
State* m_saved_state;
};
+2 -2
View File
@@ -19,7 +19,7 @@
#include <wx/tokenzr.h>
#include "common/Dependencies.h"
#include "common/SafeArray.h"
#include "common/ScopedAlloc.h"
#include "common/AlignedMalloc.h"
#if _WIN32
#define WX_STR(str) (str.wc_str())
@@ -132,7 +132,7 @@ struct ParsedAssignmentString
// accepts Ascii/UTF8 only.
//
typedef ScopedAlignedAlloc<char, 16> CharBufferType;
typedef AlignedBuffer<char, 16> CharBufferType;
// --------------------------------------------------------------------------------------
// FastFormatAscii
// --------------------------------------------------------------------------------------
+347
View File
@@ -0,0 +1,347 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Timer.h"
#include <cstdio>
#include <cstdlib>
#if defined(_WIN32)
#include "RedtapeWindows.h"
#elif defined(__APPLE__)
#include <mach/mach_init.h>
#include <mach/thread_act.h>
#include <mach/mach_port.h>
#else
#include <pthread.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#endif
namespace Common
{
#ifdef _WIN32
static double s_counter_frequency;
static bool s_counter_initialized = false;
Timer::Value Timer::GetCurrentValue()
{
// even if this races, it should still result in the same value..
if (!s_counter_initialized)
{
LARGE_INTEGER Freq;
QueryPerformanceFrequency(&Freq);
s_counter_frequency = static_cast<double>(Freq.QuadPart) / 1000000000.0;
s_counter_initialized = true;
}
Timer::Value ReturnValue;
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&ReturnValue));
return ReturnValue;
}
double Timer::ConvertValueToNanoseconds(Timer::Value value)
{
return (static_cast<double>(value) / s_counter_frequency);
}
double Timer::ConvertValueToMilliseconds(Timer::Value value)
{
return ((static_cast<double>(value) / s_counter_frequency) / 1000000.0);
}
double Timer::ConvertValueToSeconds(Timer::Value value)
{
return ((static_cast<double>(value) / s_counter_frequency) / 1000000000.0);
}
Timer::Value Timer::ConvertSecondsToValue(double s)
{
return static_cast<Value>((s * 1000000000.0) * s_counter_frequency);
}
Timer::Value Timer::ConvertMillisecondsToValue(double ms)
{
return static_cast<Value>((ms * 1000000.0) * s_counter_frequency);
}
Timer::Value Timer::ConvertNanosecondsToValue(double ns)
{
return static_cast<Value>(ns * s_counter_frequency);
}
#else
Timer::Value Timer::GetCurrentValue()
{
struct timespec tv;
clock_gettime(CLOCK_MONOTONIC, &tv);
return ((Value)tv.tv_nsec + (Value)tv.tv_sec * 1000000000);
}
double Timer::ConvertValueToNanoseconds(Timer::Value value)
{
return static_cast<double>(value);
}
double Timer::ConvertValueToMilliseconds(Timer::Value value)
{
return (static_cast<double>(value) / 1000000.0);
}
double Timer::ConvertValueToSeconds(Timer::Value value)
{
return (static_cast<double>(value) / 1000000000.0);
}
Timer::Value Timer::ConvertSecondsToValue(double s)
{
return static_cast<Value>(s * 1000000000.0);
}
Timer::Value Timer::ConvertMillisecondsToValue(double ms)
{
return static_cast<Value>(ms * 1000000.0);
}
Timer::Value Timer::ConvertNanosecondsToValue(double ns)
{
return static_cast<Value>(ns);
}
#endif
Timer::Timer()
{
Reset();
}
void Timer::Reset()
{
m_tvStartValue = GetCurrentValue();
}
double Timer::GetTimeSeconds() const
{
return ConvertValueToSeconds(GetCurrentValue() - m_tvStartValue);
}
double Timer::GetTimeMilliseconds() const
{
return ConvertValueToMilliseconds(GetCurrentValue() - m_tvStartValue);
}
double Timer::GetTimeNanoseconds() const
{
return ConvertValueToNanoseconds(GetCurrentValue() - m_tvStartValue);
}
double Timer::GetTimeSecondsAndReset()
{
const Value value = GetCurrentValue();
const double ret = ConvertValueToSeconds(value - m_tvStartValue);
m_tvStartValue = value;
return ret;
}
double Timer::GetTimeMillisecondsAndReset()
{
const Value value = GetCurrentValue();
const double ret = ConvertValueToMilliseconds(value - m_tvStartValue);
m_tvStartValue = value;
return ret;
}
double Timer::GetTimeNanosecondsAndReset()
{
const Value value = GetCurrentValue();
const double ret = ConvertValueToNanoseconds(value - m_tvStartValue);
m_tvStartValue = value;
return ret;
}
ThreadCPUTimer::ThreadCPUTimer() = default;
ThreadCPUTimer::ThreadCPUTimer(ThreadCPUTimer&& move)
: m_thread_handle(move.m_thread_handle)
{
move.m_thread_handle = nullptr;
}
ThreadCPUTimer::~ThreadCPUTimer()
{
#ifdef _WIN32
CloseHandle(reinterpret_cast<HANDLE>(m_thread_handle));
#endif
}
ThreadCPUTimer& ThreadCPUTimer::operator=(ThreadCPUTimer&& move)
{
std::swap(m_thread_handle, move.m_thread_handle);
return *this;
}
void ThreadCPUTimer::Reset()
{
m_start_value = GetCurrentValue();
}
ThreadCPUTimer::Value ThreadCPUTimer::GetCurrentValue() const
{
#if defined(_WIN32)
FILETIME create, exit, user, kernel;
if (!m_thread_handle || !GetThreadTimes((HANDLE)m_thread_handle, &create, &exit, &user, &kernel))
return 0;
Value value = (static_cast<Value>(user.dwHighDateTime) << 32) | (static_cast<Value>(user.dwLowDateTime));
value += (static_cast<Value>(kernel.dwHighDateTime) << 32) | (static_cast<Value>(kernel.dwLowDateTime));
return value;
#elif defined(__APPLE__)
thread_basic_info_data_t info;
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
const kern_return_t kr = thread_info((mach_port_t) reinterpret_cast<uintptr_t>(m_thread_handle), THREAD_BASIC_INFO, (thread_info_t)&info, &count);
if (kr != KERN_SUCCESS)
return 0;
Value value = (static_cast<Value>(info.user_time.seconds) * 1000000) + (static_cast<Value>(info.user_time.microseconds));
value += (static_cast<Value>(info.system_time.seconds) * 1000000) + (static_cast<Value>(info.system_time.microseconds));
return value;
#else
clockid_t cid;
if (!m_thread_handle || pthread_getcpuclockid((pthread_t)m_thread_handle, &cid) != 0)
return 0;
struct timespec ts;
if (clock_gettime(cid, &ts) != 0)
return 0;
return (static_cast<Value>(ts.tv_nsec) + static_cast<Value>(ts.tv_sec) * 1000000000LL);
#endif
}
double ThreadCPUTimer::GetTimeSeconds() const
{
return ConvertValueToSeconds(GetCurrentValue() - m_start_value);
}
double ThreadCPUTimer::GetTimeMilliseconds() const
{
return ConvertValueToMilliseconds(GetCurrentValue() - m_start_value);
}
double ThreadCPUTimer::GetTimeNanoseconds() const
{
return ConvertValueToNanoseconds(GetCurrentValue() - m_start_value);
}
void ThreadCPUTimer::GetUsageInSecondsAndReset(Value time_diff, double* usage_time, double* usage_percent)
{
const Value new_value = GetCurrentValue();
const Value diff = new_value - m_start_value;
m_start_value = new_value;
*usage_time = ConvertValueToSeconds(diff);
*usage_percent = GetUtilizationPercentage(time_diff, diff);
}
void ThreadCPUTimer::GetUsageInMillisecondsAndReset(Value time_diff, double* usage_time, double* usage_percent)
{
const Value new_value = GetCurrentValue();
const Value diff = new_value - m_start_value;
m_start_value = new_value;
*usage_time = ConvertValueToMilliseconds(diff);
*usage_percent = GetUtilizationPercentage(time_diff, diff);
}
void ThreadCPUTimer::GetUsageInNanosecondsAndReset(Value time_diff, double* usage_time, double* usage_percent)
{
const Value new_value = GetCurrentValue();
const Value diff = new_value - m_start_value;
m_start_value = new_value;
*usage_time = ConvertValueToNanoseconds(diff);
*usage_percent = GetUtilizationPercentage(time_diff, diff);
}
double ThreadCPUTimer::GetUtilizationPercentage(Timer::Value time_diff, Value cpu_time_diff)
{
#if defined(_WIN32)
return ((static_cast<double>(cpu_time_diff) * 10000.0) / (static_cast<double>(time_diff) / s_counter_frequency));
#elif defined(__APPLE__)
// microseconds, but time_tiff is in nanoseconds, so multiply by 1000 * 100
return (static_cast<double>(cpu_time_diff) * 100000.0) / static_cast<double>(time_diff);
#else
// nanoseconds
return (static_cast<double>(cpu_time_diff) * 100.0) / static_cast<double>(time_diff);
#endif
}
double ThreadCPUTimer::ConvertValueToSeconds(Value value)
{
#if defined(_WIN32)
// 100ns units
return (static_cast<double>(value) / 10000000.0);
#elif defined(__APPLE__)
// microseconds
return (static_cast<double>(value) / 1000000.0);
#else
// nanoseconds
return (static_cast<double>(value) / 1000000000.0);
#endif
}
double ThreadCPUTimer::ConvertValueToMilliseconds(Value value)
{
#if defined(_WIN32)
return (static_cast<double>(value) / 10000.0);
#elif defined(__APPLE__)
return (static_cast<double>(value) / 1000.0);
#else
return (static_cast<double>(value) / 1000000.0);
#endif
}
double ThreadCPUTimer::ConvertValueToNanoseconds(Value value)
{
#if defined(_WIN32)
return (static_cast<double>(value) * 100.0);
#elif defined(__APPLE__)
return (static_cast<double>(value) * 1000.0);
#else
return static_cast<double>(value);
#endif
}
ThreadCPUTimer ThreadCPUTimer::GetForCallingThread()
{
ThreadCPUTimer ret;
#if defined(_WIN32)
ret.m_thread_handle = (void*)OpenThread(THREAD_QUERY_INFORMATION, FALSE, GetCurrentThreadId());
#elif defined(__APPLE__)
ret.m_thread_handle = reinterpret_cast<void*>((uintptr_t)mach_thread_self());
#else
ret.m_thread_handle = (void*)pthread_self();
#endif
ret.Reset();
return ret;
}
} // namespace Common
+94
View File
@@ -0,0 +1,94 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstdint>
namespace Common
{
class Timer
{
public:
using Value = std::uint64_t;
Timer();
static Value GetCurrentValue();
static double ConvertValueToSeconds(Value value);
static double ConvertValueToMilliseconds(Value value);
static double ConvertValueToNanoseconds(Value value);
static Value ConvertSecondsToValue(double s);
static Value ConvertMillisecondsToValue(double s);
static Value ConvertNanosecondsToValue(double ns);
void Reset();
void ResetTo(Value value) { m_tvStartValue = value; }
Value GetStartValue() const { return m_tvStartValue; }
double GetTimeSeconds() const;
double GetTimeMilliseconds() const;
double GetTimeNanoseconds() const;
double GetTimeSecondsAndReset();
double GetTimeMillisecondsAndReset();
double GetTimeNanosecondsAndReset();
private:
Value m_tvStartValue;
};
class ThreadCPUTimer
{
public:
using Value = std::uint64_t;
ThreadCPUTimer();
ThreadCPUTimer(ThreadCPUTimer&& move);
ThreadCPUTimer(const ThreadCPUTimer&) = delete;
~ThreadCPUTimer();
void Reset();
void ResetTo(Value value) { m_start_value = value; }
Value GetStartValue() const { return m_start_value; }
Value GetCurrentValue() const;
double GetTimeSeconds() const;
double GetTimeMilliseconds() const;
double GetTimeNanoseconds() const;
void GetUsageInSecondsAndReset(Value time_diff, double* usage_time, double* usage_percent);
void GetUsageInMillisecondsAndReset(Value time_diff, double* usage_time, double* usage_percent);
void GetUsageInNanosecondsAndReset(Value time_diff, double* usage_time, double* usage_percent);
static double GetUtilizationPercentage(Timer::Value time_diff, Value cpu_time_diff);
static double ConvertValueToSeconds(Value value);
static double ConvertValueToMilliseconds(Value value);
static double ConvertValueToNanoseconds(Value value);
static ThreadCPUTimer GetForCallingThread();
ThreadCPUTimer& operator=(const ThreadCPUTimer&) = delete;
ThreadCPUTimer& operator=(ThreadCPUTimer&& move);
private:
void* m_thread_handle = nullptr;
Value m_start_value = 0;
};
} // namespace Common
+9 -3
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)common\vsprops\BaseProjectConfig.props" />
<Import Project="$(SolutionDir)common\vsprops\WinSDK.props" />
@@ -52,11 +52,14 @@
<ClCompile Include="GL\Context.cpp" />
<ClCompile Include="GL\ContextWGL.cpp" />
<ClCompile Include="GL\StreamBuffer.cpp" />
<ClCompile Include="FileSystem.cpp" />
<ClCompile Include="IniInterface.cpp" />
<ClCompile Include="ProgressCallback.cpp" />
<ClCompile Include="pxStreams.cpp" />
<ClCompile Include="pxTranslate.cpp" />
<ClCompile Include="StringUtil.cpp" />
<ClCompile Include="SettingsWrapper.cpp" />
<ClCompile Include="Timer.cpp" />
<ClCompile Include="VirtualMemory.cpp" />
<ClCompile Include="WindowInfo.cpp" />
<ClCompile Include="x86\MemcpyFast.cpp" />
@@ -100,6 +103,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="Align.h" />
<ClInclude Include="AlignedMalloc.h" />
<ClInclude Include="BitCast.h" />
<ClInclude Include="EmbeddedImage.h" />
<ClInclude Include="boost_spsc_queue.hpp" />
@@ -107,7 +111,8 @@
<ClInclude Include="GL\Context.h" />
<ClInclude Include="GL\ContextWGL.h" />
<ClInclude Include="GL\StreamBuffer.h" />
<ClInclude Include="ScopedAlloc.h" />
<ClInclude Include="FileSystem.h" />
<ClInclude Include="ProgressCallback.h" />
<ClInclude Include="ScopedGuard.h" />
<ClInclude Include="StringUtil.h" />
<ClInclude Include="SettingsInterface.h" />
@@ -126,6 +131,7 @@
<ClInclude Include="RedtapeWindows.h" />
<ClInclude Include="SafeArray.h" />
<ClInclude Include="StringHelpers.h" />
<ClInclude Include="Timer.h" />
<ClInclude Include="WindowInfo.h" />
<ClInclude Include="wxBaseTools.h" />
<ClInclude Include="Threading.h" />
@@ -175,4 +181,4 @@
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
</Project>
+33 -6
View File
@@ -130,8 +130,23 @@
<ClCompile Include="GL\StreamBuffer.cpp">
<Filter>Source Files\GL</Filter>
</ClCompile>
<ClCompile Include="FileSystem.cpp">
<Filter>Source Files\GL</Filter>
</ClCompile>
<ClCompile Include="StringUtil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Timer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ProgressCallback.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="AlignedMalloc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Assertions.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -222,9 +237,6 @@
<ClInclude Include="SafeArray.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ScopedAlloc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="emitter\implement\simd_arithmetic.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -282,9 +294,6 @@
<ClInclude Include="SettingsWrapper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ScopedGuard.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Align.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -303,6 +312,24 @@
<ClInclude Include="GL\StreamBuffer.h">
<Filter>Header Files\GL</Filter>
</ClInclude>
<ClInclude Include="FileSystem.h">
<Filter>Header Files\GL</Filter>
</ClInclude>
<ClInclude Include="StringUtil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ScopedGuard.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Timer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ProgressCallback.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ScopedGuard.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
+6 -8
View File
@@ -21,23 +21,21 @@
// AND'ing this mask against an MXCSR prior to LDMXCSR.
SSE_MXCSR MXCSR_Mask;
const wxChar* EnumToString(SSE_RoundMode sse)
const char* EnumToString(SSE_RoundMode sse)
{
switch (sse)
{
case SSEround_Nearest:
return L"Nearest";
return "Nearest";
case SSEround_NegInf:
return L"NegativeInfinity";
return "NegativeInfinity";
case SSEround_PosInf:
return L"PositiveInfinity";
return "PositiveInfinity";
case SSEround_Chop:
return L"Chop";
return "Chop";
default:
return L"Invalid";
return "Invalid";
}
return L"Invalid";
}
SSE_RoundMode SSE_MXCSR::GetRoundMode() const
+34 -33
View File
@@ -24,21 +24,22 @@
# include <aio.h>
#endif
#include <memory>
#include <string>
class AsyncFileReader
{
protected:
AsyncFileReader() : m_dataoffset(0), m_blocksize(0) {}
wxString m_filename;
std::string m_filename;
int m_dataoffset;
uint m_blocksize;
public:
virtual ~AsyncFileReader(void) {};
virtual ~AsyncFileReader() {};
virtual bool Open(const wxString& fileName)=0;
virtual bool Open(std::string fileName)=0;
virtual int ReadSync(void* pBuffer, uint sector, uint count)=0;
@@ -55,7 +56,7 @@ public:
uint GetBlockSize() const { return m_blocksize; }
const wxString& GetFilename() const
const std::string& GetFilename() const
{
return m_filename;
}
@@ -86,22 +87,22 @@ class FlatFileReader : public AsyncFileReader
public:
FlatFileReader(bool shareWrite = false);
virtual ~FlatFileReader(void);
virtual ~FlatFileReader() override;
virtual bool Open(const wxString& fileName);
virtual bool Open(std::string fileName) override;
virtual int ReadSync(void* pBuffer, uint sector, uint count);
virtual int ReadSync(void* pBuffer, uint sector, uint count) override;
virtual void BeginRead(void* pBuffer, uint sector, uint count);
virtual int FinishRead(void);
virtual void CancelRead(void);
virtual void BeginRead(void* pBuffer, uint sector, uint count) override;
virtual int FinishRead(void) override;
virtual void CancelRead(void) override;
virtual void Close(void);
virtual void Close(void) override;
virtual uint GetBlockCount(void) const;
virtual uint GetBlockCount(void) const override;
virtual void SetBlockSize(uint bytes) { m_blocksize = bytes; }
virtual void SetDataOffset(int bytes) { m_dataoffset = bytes; }
virtual void SetBlockSize(uint bytes) override { m_blocksize = bytes; }
virtual void SetDataOffset(int bytes) override { m_dataoffset = bytes; }
};
class MultipartFileReader : public AsyncFileReader
@@ -123,21 +124,21 @@ class MultipartFileReader : public AsyncFileReader
public:
MultipartFileReader(AsyncFileReader* firstPart);
virtual ~MultipartFileReader(void);
virtual ~MultipartFileReader() override;
virtual bool Open(const wxString& fileName);
virtual bool Open(std::string fileName) override;
virtual int ReadSync(void* pBuffer, uint sector, uint count);
virtual int ReadSync(void* pBuffer, uint sector, uint count) override;
virtual void BeginRead(void* pBuffer, uint sector, uint count);
virtual int FinishRead(void);
virtual void CancelRead(void);
virtual void BeginRead(void* pBuffer, uint sector, uint count) override;
virtual int FinishRead(void) override;
virtual void CancelRead(void) override;
virtual void Close(void);
virtual void Close(void) override;
virtual uint GetBlockCount(void) const;
virtual uint GetBlockCount(void) const override;
virtual void SetBlockSize(uint bytes);
virtual void SetBlockSize(uint bytes) override;
static AsyncFileReader* DetectMultipart(AsyncFileReader* reader);
};
@@ -146,7 +147,7 @@ class BlockdumpFileReader : public AsyncFileReader
{
DeclareNoncopyableObject( BlockdumpFileReader );
wxFileInputStream* m_file;
std::FILE* m_file;
// total number of blocks in the ISO image (including all parts)
u32 m_blocks;
@@ -159,20 +160,20 @@ class BlockdumpFileReader : public AsyncFileReader
int m_lresult;
public:
BlockdumpFileReader(void);
virtual ~BlockdumpFileReader(void);
BlockdumpFileReader();
virtual ~BlockdumpFileReader() override;
virtual bool Open(const wxString& fileName);
virtual bool Open(std::string fileName) override;
virtual int ReadSync(void* pBuffer, uint sector, uint count);
virtual int ReadSync(void* pBuffer, uint sector, uint count) override;
virtual void BeginRead(void* pBuffer, uint sector, uint count);
virtual int FinishRead(void);
virtual void CancelRead(void);
virtual void BeginRead(void* pBuffer, uint sector, uint count) override;
virtual int FinishRead(void) override;
virtual void CancelRead(void) override;
virtual void Close(void);
virtual void Close(void) override;
virtual uint GetBlockCount(void) const;
virtual uint GetBlockCount(void) const override;
static bool DetectBlockdump(AsyncFileReader* reader);
+27 -27
View File
@@ -17,6 +17,7 @@
#include "AsyncFileReader.h"
#include "IopCommon.h"
#include "IsoFileFormats.h"
#include "common/FileSystem.h"
#include <errno.h>
@@ -59,48 +60,45 @@ BlockdumpFileReader::~BlockdumpFileReader(void)
Close();
}
bool BlockdumpFileReader::Open(const wxString& fileName)
bool BlockdumpFileReader::Open(std::string fileName)
{
char buf[32];
char signature[4];
m_filename = fileName;
m_file = new wxFileInputStream(m_filename);
m_file->SeekI(0);
m_file->Read(buf, 4);
if (strncmp(buf, "BDV2", 4) != 0)
m_filename = std::move(fileName);
m_file = FileSystem::OpenCFile(m_filename.c_str(), "rb");
if (!m_file || std::fread(signature, sizeof(signature), 1, m_file) != 1 || std::memcmp(signature, "BDV2", sizeof(signature)) != 0)
{
return false;
}
//m_flags = ISOFLAGS_BLOCKDUMP_V2;
m_file->Read(&m_blocksize, sizeof(m_blocksize));
m_file->Read(&m_blocks, sizeof(m_blocks));
m_file->Read(&m_blockofs, sizeof(m_blockofs));
if (std::fread(&m_blocksize, sizeof(m_blocksize), 1, m_file) != 1 ||
std::fread(&m_blocks, sizeof(m_blocks), 1, m_file) != 1 ||
std::fread(&m_blockofs, sizeof(m_blockofs), 1, m_file) != 1)
{
return false;
}
wxFileOffset flen = m_file->GetLength();
static const wxFileOffset datalen = flen - BlockDumpHeaderSize;
const s64 flen = FileSystem::FSize64(m_file);
const s64 datalen = flen - BlockDumpHeaderSize;
pxAssert((datalen % (m_blocksize + 4)) == 0);
m_dtablesize = datalen / (m_blocksize + 4);
m_dtable = std::unique_ptr<u32[]>(new u32[m_dtablesize]);
m_dtable = std::make_unique<u32[]>(m_dtablesize);
m_file->SeekI(BlockDumpHeaderSize);
if (FileSystem::FSeek64(m_file, BlockDumpHeaderSize, SEEK_SET) != 0)
return false;
u32 bs = 1024 * 1024;
u32 off = 0;
u32 has = 0;
int i = 0;
std::unique_ptr<u8[]> buffer(new u8[bs]);
std::unique_ptr<u8[]> buffer = std::make_unique<u8[]>(bs);
do
{
m_file->Read(buffer.get(), bs);
has = m_file->LastRead();
has = static_cast<u32>(std::fread(buffer.get(), 1, bs, m_file));
while (i < m_dtablesize && off < has)
{
m_dtable[i++] = *reinterpret_cast<u32*>(buffer.get() + off);
@@ -132,15 +130,17 @@ int BlockdumpFileReader::ReadSync(void* pBuffer, uint lsn, uint count)
// seek position ends up being based on (m_blocksize + 4) instead of just m_blocksize.
#ifdef PCSX2_DEBUG
u32 check_lsn;
m_file->SeekI(BlockDumpHeaderSize + (i * (m_blocksize + 4)));
m_file->Read(&check_lsn, sizeof(check_lsn));
u32 check_lsn = 0;
FileSystem::FSeek64(m_file, BlockDumpHeaderSize + (i * (m_blocksize + 4)), SEEK_SET);
std::fread(&check_lsn, sizeof(check_lsn), 1, m_file);
pxAssert(check_lsn == lsn);
#else
m_file->SeekI(BlockDumpHeaderSize + (i * (m_blocksize + 4)) + 4);
if (FileSystem::FSeek64(m_file, BlockDumpHeaderSize + (i * (m_blocksize + 4)) + 4, SEEK_SET) != 0)
break;
#endif
m_file->Read(dst, m_blocksize);
if (std::fread(dst, m_blocksize, 1, m_file) != 1)
break;
ok = true;
break;
@@ -178,7 +178,7 @@ void BlockdumpFileReader::Close(void)
{
if (m_file)
{
delete m_file;
std::fclose(m_file);
m_file = NULL;
}
}
+72 -111
View File
@@ -20,6 +20,8 @@
#include <ctype.h>
#include <wx/datetime.h>
#include "common/FileSystem.h"
#include "CdRom.h"
#include "CDVD.h"
#include "CDVD_internal.h"
@@ -111,34 +113,28 @@ static int mg_BIToffset(u8* buffer)
static void cdvdGetMechaVer(u8* ver)
{
wxFileName mecfile(EmuConfig.FullpathToBios());
mecfile.SetExt(L"mec");
const wxString fname(mecfile.GetFullPath());
// Likely a bad idea to go further
if (mecfile.IsDir())
throw Exception::CannotCreateStream(fname);
if (Path::GetFileSize(fname) < 4)
std::string mecfile(FileSystem::ReplaceExtension(BiosPath, "mec"));
auto fp = FileSystem::OpenManagedCFile(mecfile.c_str(), "rb");
if (!fp || FileSystem::FSize64(fp.get()) < 4)
{
Console.Warning("MEC File Not Found, creating substitute...");
wxFFile fp(fname, L"wb");
if (!fp.IsOpened())
throw Exception::CannotCreateStream(fname);
fp.reset();
fp = FileSystem::OpenManagedCFile(mecfile.c_str(), "w+b");
if (!fp)
{
Console.Error("Failed to read/write NVM/MEC file. Check your BIOS setup/permission settings.");
return;
}
u8 version[4] = {0x3, 0x6, 0x2, 0x0};
fp.Write(version, sizeof(version));
std::fwrite(version, sizeof(version), 1, fp.get());
FileSystem::FSeek64(fp.get(), 0, SEEK_SET);
}
wxFFile fp(fname, L"rb");
if (!fp.IsOpened())
throw Exception::CannotCreateStream(fname);
size_t ret = fp.Read(ver, 4);
auto ret = std::fread(ver, 1, 4, fp.get());
if (ret != 4)
Console.Error(L"Failed to read from %s. Did only %zu/4 bytes", WX_STR(fname), ret);
Console.Error("Failed to read from %s. Did only %zu/4 bytes", mecfile.c_str(), ret);
}
NVMLayout* getNvmLayout()
@@ -153,14 +149,10 @@ NVMLayout* getNvmLayout()
return nvmLayout;
}
static void cdvdCreateNewNVM(const wxString& filename)
static void cdvdCreateNewNVM(std::FILE* fp)
{
wxFFile fp(filename, L"wb");
if (!fp.IsOpened())
throw Exception::CannotCreateStream(filename);
u8 zero[1024] = {0};
fp.Write(zero, sizeof(zero));
u8 zero[1024] = {};
std::fwrite(zero, sizeof(zero), 1, fp);
// Write NVM ILink area with dummy data (Age of Empires 2)
// Also write language data defaulting to English (Guitar Hero 2)
@@ -168,36 +160,34 @@ static void cdvdCreateNewNVM(const wxString& filename)
NVMLayout* nvmLayout = getNvmLayout();
u8 ILinkID_Data[8] = {0x00, 0xAC, 0xFF, 0xFF, 0xFF, 0xFF, 0xB9, 0x86};
fp.Seek(*(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, ilinkId)));
fp.Write(ILinkID_Data, sizeof(ILinkID_Data));
std::fseek(fp, *(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, ilinkId)), SEEK_SET);
std::fwrite(ILinkID_Data, sizeof(ILinkID_Data), 1, fp);
u8 biosLanguage[16];
memcpy(biosLanguage, &biosLangDefaults[BiosRegion][0], 16);
// Config sections first 16 bytes are generally blank expect the last byte which is PS1 mode stuff
// So let's ignore that and just write the PS2 mode stuff
fp.Seek(*(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10);
fp.Write(biosLanguage, sizeof(biosLanguage));
fp.Close();
std::fseek(fp, *(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10, SEEK_SET);
std::fwrite(biosLanguage, sizeof(biosLanguage), 1, fp);
}
// Throws Exception::CannotCreateStream if the file cannot be opened for reading, or cannot
// be created for some reason.
static void cdvdNVM(u8* buffer, int offset, size_t bytes, bool read)
{
wxFileName nvmfile(EmuConfig.FullpathToBios());
nvmfile.SetExt(L"nvm");
const wxString fname(nvmfile.GetFullPath());
// Likely a bad idea to go further
if (nvmfile.IsDir())
throw Exception::CannotCreateStream(fname);
if (Path::GetFileSize(fname) < 1024)
std::string nvmfile(FileSystem::ReplaceExtension(BiosPath, "nvm"));
auto fp = FileSystem::OpenManagedCFile(nvmfile.c_str(), "r+b");
if (!fp || FileSystem::FSize64(fp.get()) < 1024)
{
Console.Warning("NVM File Not Found, creating substitute...");
fp.reset();
fp = FileSystem::OpenManagedCFile(nvmfile.c_str(), "w+b");
if (!fp)
{
Console.Error("Failed to open NVM file '%s' for writing", nvmfile.c_str());
if (read)
std::memset(buffer, 0, bytes);
return;
}
cdvdCreateNewNVM(fname);
cdvdCreateNewNVM(fp.get());
}
else
{
@@ -205,38 +195,28 @@ static void cdvdNVM(u8* buffer, int offset, size_t bytes, bool read)
u8 zero[16] = {0};
NVMLayout* nvmLayout = getNvmLayout();
wxFFile fp(fname, L"r+b");
if (!fp.IsOpened())
throw Exception::CannotCreateStream(fname);
fp.Seek(*(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10);
fp.Read(LanguageParams, 16);
fp.Close();
if (memcmp(LanguageParams, zero, sizeof(LanguageParams)) == 0)
if (std::fseek(fp.get(), *(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10, SEEK_SET) != 0 ||
std::fread(LanguageParams, 16, 1, fp.get()) != 1 ||
std::memcmp(LanguageParams, zero, sizeof(LanguageParams)) == 0)
{
Console.Warning("Language Parameters missing, filling in defaults");
cdvdCreateNewNVM(fname);
FileSystem::FSeek64(fp.get(), 0, SEEK_SET);
cdvdCreateNewNVM(fp.get());
}
}
wxFFile fp(fname, L"r+b");
if (!fp.IsOpened())
throw Exception::CannotCreateStream(fname);
fp.Seek(offset);
std::fseek(fp.get(), offset, SEEK_SET);
size_t ret;
if (read)
ret = fp.Read(buffer, bytes);
ret = std::fread(buffer, 1, bytes, fp.get());
else
ret = fp.Write(buffer, bytes);
ret = std::fwrite(buffer, 1, bytes, fp.get());
if (ret != bytes)
Console.Error(L"Failed to %s %s. Did only %zu/%zu bytes",
read ? L"read from" : L"write to", WX_STR(fname), ret, bytes);
read ? L"read from" : L"write to", nvmfile.c_str(), ret, bytes);
}
static void cdvdReadNVM(u8* dst, int offset, int bytes)
@@ -384,7 +364,7 @@ static MutexRecursive Mutex_NewDiskCB;
static __fi ElfObject* loadElf(const wxString filename, bool isPSXElf)
{
if (filename.StartsWith(L"host"))
return new ElfObject(filename.After(':'), Path::GetFileSize(filename.After(':')), isPSXElf);
return new ElfObject(filename.After(':'), FileSystem::GetPathFileSize(filename.After(':').ToUTF8()), isPSXElf);
// Mimic PS2 behavior!
// Much trial-and-error with changing the ISOFS and BOOT2 contents of an image have shown that
@@ -1058,7 +1038,7 @@ __fi void cdvdActionInterrupt()
cdvd.Spinning = true;
cdvd.Ready |= CDVD_DRIVE_READY; //check (rama)
cdvd.Sector = cdvd.SeekToSector;
cdvd.Status = CDVD_STATUS_READ;
cdvd.Status = CDVD_STATUS_PAUSE;
cdvd.nextSectorsBuffered = 0;
cdvd.triggerDataReady = true;
CDVDSECTORREADY_INT(cdvd.ReadTime);
@@ -1069,7 +1049,7 @@ __fi void cdvdActionInterrupt()
cdvd.Spinning = true; //check (rama)
cdvd.Ready |= CDVD_DRIVE_READY; //check (rama)
cdvd.Sector = cdvd.SeekToSector;
cdvd.Status = CDVD_STATUS_READ;
cdvd.Status = CDVD_STATUS_PAUSE;
cdvd.nextSectorsBuffered = 0;
cdvd.triggerDataReady = true;
CDVDSECTORREADY_INT(cdvd.ReadTime);
@@ -1123,18 +1103,8 @@ __fi void cdvdSectorReady()
}
}
if (cdvd.nextSectorsBuffered == 16 && (cdvd.Ready & CDVD_DRIVE_READY))
{
cdvd.Status = CDVD_STATUS_PAUSE; // Needed here but could be smth else than Pause (rama)
}
else
{
if (cdvd.nextSectorsBuffered < 16)
{
CDVDSECTORREADY_INT(cdvd.ReadTime);
cdvd.Status = CDVD_STATUS_READ;
}
}
if (cdvd.nextSectorsBuffered < 16)
CDVDSECTORREADY_INT(cdvd.ReadTime);
}
// inlined due to being referenced in only one place.
@@ -1159,14 +1129,10 @@ __fi void cdvdReadInterrupt()
cdvd.Reading = 1;
cdvd.Readed = 1;
cdvd.Sector = cdvd.SeekToSector;
CDVD_LOG("Cdvd Seek Complete > Scheduling block read interrupt at iopcycle=%8.8x.",
psxRegs.cycle + cdvd.ReadTime);
CDVDREAD_INT(cdvd.ReadTime);
cdvd.Status = CDVD_STATUS_READ;
return;
CDVD_LOG("Cdvd Seek Complete at iopcycle=%8.8x.", psxRegs.cycle);
}
else if (cdvd.Reading)
if (cdvd.Reading)
{
if (cdvd.RErr == 0)
{
@@ -1237,13 +1203,10 @@ __fi void cdvdReadInterrupt()
iopIntcIrq(2);
cdvd.Ready |= CDVD_DRIVE_READY;
if (cdvd.nextSectorsBuffered < 16)
cdvd.Status = CDVD_STATUS_READ;
else
cdvd.Status = CDVD_STATUS_PAUSE;
cdvd.Status = CDVD_STATUS_PAUSE;
cdvd.nCommand = 0;
//DevCon.Warning("Scheduling interrupt in %d cycles", cdvd.ReadTime - (cdvd.BlockSize / 4));
//DevCon.Warning("Scheduling interrupt in %d cycles", cdvd.ReadTime - ((cdvd.BlockSize / 4) * 12));
// Timing issues on command end
// Star Ocean (1.1 Japan) expects the DMA to end and interrupt at least 128 or more cycles before the CDVD command ends.
// However the time required seems to increase slowly, so delaying the end of the command is not the solution.
@@ -1254,7 +1217,7 @@ __fi void cdvdReadInterrupt()
}
else
{
CDVDREAD_INT((cdvd.BlockSize / 4));
CDVDREAD_INT((cdvd.BlockSize / 4) * 12);
return;
}
@@ -1262,9 +1225,9 @@ __fi void cdvdReadInterrupt()
cdvd.Reading = 1;
cdvd.RErr = DoCDVDreadTrack(cdvd.Sector, cdvd.ReadMode);
if (cdvd.nextSectorsBuffered)
CDVDREAD_INT((cdvd.BlockSize / 4));
CDVDREAD_INT((cdvd.BlockSize / 4) * 12);
else
CDVDREAD_INT(cdvd.ReadTime + (cdvd.BlockSize / 4));
CDVDREAD_INT((psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]) + ((cdvd.BlockSize / 4) * 12));
}
// Returns the number of IOP cycles until the event completes.
@@ -1274,6 +1237,7 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
uint delta = abs((s32)(cdvd.SeekToSector - cdvd.Sector));
uint seektime;
bool isSeeking = cdvd.nCommand == N_CD_SEEK;
cdvd.Ready &= ~(CDVD_DRIVE_READY | CDVD_DRIVE_DATARDY);
cdvd.Reading = 1;
@@ -1311,6 +1275,7 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
CDVD_LOG("CdSeek Begin > to sector %d, from %d - delta=%d [FAST]", cdvd.SeekToSector, cdvd.Sector, delta);
seektime = Cdvd_FastSeek_Cycles;
}
isSeeking = true;
}
else
{
@@ -1318,6 +1283,7 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
// if delta > 0 it will read a new sector so the readInterrupt will account for this.
seektime = 0;
isSeeking = false;
if (delta == 0)
{
@@ -1338,16 +1304,15 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
if (psxRegs.interrupt & (1 << IopEvt_CdvdSectorReady))
{
//DevCon.Warning("coming back from ready sector early reducing %d cycles by %d cycles", seektime, psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]);
seektime = (psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]) + (cdvd.BlockSize / 4);
seektime = (psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]) + ((cdvd.BlockSize / 4) * 12);
}
else
{
CDVDSECTORREADY_INT(cdvd.ReadTime);
seektime = cdvd.ReadTime + (cdvd.BlockSize / 4);
delta = 1; // Forces it to use the rotational delay since we have no sectors buffered and it isn't buffering any.
}
}
else
seektime = (cdvd.BlockSize / 4);
return (cdvd.BlockSize / 4) * 12;
}
else
{
@@ -1357,14 +1322,17 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
}
// Only do this on reads, the seek kind of accounts for this and then it reads the sectors after
if (delta && cdvd.nCommand != N_CD_SEEK)
if (delta && !isSeeking)
{
int rotationalLatency = cdvdRotationalLatency((CDVD_MODE_TYPE)cdvdIsDVD());
//DevCon.Warning("%s rotational latency at sector %d is %d cycles", (cdvd.SpindlCtrl & CDVD_SPINDLE_CAV) ? "CAV" : "CLV", cdvd.SeekToSector, rotationalLatency);
seektime += rotationalLatency + cdvd.ReadTime;
CDVDSECTORREADY_INT(seektime);
seektime += (cdvd.BlockSize / 4);
seektime += (cdvd.BlockSize / 4) * 12;
}
else
CDVDSECTORREADY_INT(seektime);
return seektime;
}
@@ -1642,7 +1610,7 @@ static void cdvdWrite04(u8 rt)
cdvdSetIrq();
cdvd.nCommand = 0;
//After Pausing needs to buffer the next sector
cdvd.Status = CDVD_STATUS_READ;
cdvd.Status = CDVD_STATUS_PAUSE;
cdvd.nextSectorsBuffered = 0;
cdvd.triggerDataReady = true;
CDVDSECTORREADY_INT(cdvd.ReadTime);
@@ -1874,7 +1842,7 @@ static void cdvdWrite04(u8 rt)
HW_DMA3_CHCR &= ~0x01000000;
psxDmaInterrupt(3);
//After reading the TOC it needs to go back to buffer the next sector
cdvd.Status = CDVD_STATUS_READ;
cdvd.Status = CDVD_STATUS_PAUSE;
cdvd.nextSectorsBuffered = 0;
cdvd.triggerDataReady = true;
CDVDSECTORREADY_INT(cdvd.ReadTime);
@@ -1891,7 +1859,7 @@ static void cdvdWrite04(u8 rt)
cdvdSetIrq();
cdvd.nCommand = 0;
//After reading the key it needs to go back to buffer the next sector
cdvd.Status = CDVD_STATUS_READ;
cdvd.Status = CDVD_STATUS_PAUSE;
cdvd.nextSectorsBuffered = 0;
cdvd.triggerDataReady = true;
CDVDSECTORREADY_INT(cdvd.ReadTime);
@@ -1996,7 +1964,6 @@ static __fi void fail_pol_cal()
static void cdvdWrite16(u8 rt) // SCOMMAND
{
try
{
// cdvdTN diskInfo;
// cdvdTD trackInfo;
@@ -2655,12 +2622,6 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
cdvd.ParamP = 0;
cdvd.ParamC = 0;
}
catch (Exception::CannotCreateStream&)
{
Cpu->ThrowException(Exception::RuntimeError()
.SetDiagMsg(L"Failed to read/write NVM/MEC file.")
.SetUserMsg(pxE(L"Failed to read/write NVM/MEC file. Check your BIOS setup/permission settings.")));
}
}
static __fi void cdvdWrite17(u8 rt)
+19 -13
View File
@@ -33,6 +33,7 @@
#include "IsoFS/IsoFSCDVD.h"
#include "CDVDisoReader.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include "DebugTools/SymbolMap.h"
#include "Config.h"
@@ -376,33 +377,33 @@ bool DoCDVDopen()
return true;
}
wxString somepick(Path::GetFilenameWithoutExt(fromUTF8(m_SourceFilename[CurrentSourceType])));
std::string somepick(FileSystem::StripExtension(FileSystem::GetDisplayNameFromPath(m_SourceFilename[CurrentSourceType])));
//FWIW Disc serial availability doesn't seem reliable enough, sometimes it's there and sometime it's just null
//Shouldn't the serial be available all time? Potentially need to look into Elfreloadinfo() reliability
//TODO: Add extra fallback case for CRC.
if (somepick.IsEmpty() && !DiscSerial.IsEmpty())
somepick = L"Untitled-" + DiscSerial;
else if (somepick.IsEmpty())
somepick = L"Untitled";
if (somepick.empty() && !DiscSerial.IsEmpty())
somepick = StringUtil::StdStringFromFormat("Untitled-%s", DiscSerial.ToUTF8().data());
else if (somepick.empty())
somepick = "Untitled";
if (EmuConfig.CurrentBlockdump.empty())
EmuConfig.CurrentBlockdump = StringUtil::wxStringToUTF8String(wxGetCwd());
EmuConfig.CurrentBlockdump = FileSystem::GetWorkingDirectory();
wxString temp(Path::Combine(StringUtil::UTF8StringToWxString(EmuConfig.CurrentBlockdump), somepick));
std::string temp(Path::CombineStdString(EmuConfig.CurrentBlockdump, somepick));
#ifdef ENABLE_TIMESTAMPS
wxDateTime curtime(wxDateTime::GetTimeNow());
temp += pxsFmt(L" (%04d-%02d-%02d %02d-%02d-%02d)",
curtime.GetYear(), curtime.GetMonth(), curtime.GetDay(),
curtime.GetHour(), curtime.GetMinute(), curtime.GetSecond());
temp += StringUtil::StdStringFromFormat(" (%04d-%02d-%02d %02d-%02d-%02d)",
curtime.GetYear(), curtime.GetMonth(), curtime.GetDay(),
curtime.GetHour(), curtime.GetMinute(), curtime.GetSecond());
#endif
temp += L".dump";
temp += ".dump";
cdvdTD td;
CDVD->getTD(0, &td);
blockDumpFile.Create(temp, 2);
blockDumpFile.Create(std::move(temp), 2);
if (blockDumpFile.IsOpened())
{
@@ -432,7 +433,12 @@ bool DoCDVDopen()
void DoCDVDclose()
{
CheckNullCDVD();
//blockDumpFile.Close();
#ifdef PCSX2_CORE
// This was commented out, presumably because pausing/resuming in wx reopens CDVD.
// This is a non-issue in Qt, so we'll leave it behind the ifdef.
blockDumpFile.Close();
#endif
if (CDVD->close != NULL)
CDVD->close();
+1 -1
View File
@@ -52,7 +52,7 @@ s32 CALLBACK ISOopen(const char* pTitle)
try
{
iso.Open(fromUTF8(pTitle));
iso.Open(pTitle);
}
catch (BaseException& ex)
{
+1 -1
View File
@@ -1076,7 +1076,7 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr)
case 0x41000200:
if (cdvd.WaitingDMA)
{
PSX_INT(IopEvt_CdvdRead, cdvd.BlockSize / 4); //Data should be already buffered so simulate DMA time
PSX_INT(IopEvt_CdvdRead, (cdvd.BlockSize / 4) * 12); //Data should be already buffered so simulate DMA time
}
//SysPrintf("unhandled cdrom dma3: madr: %x, bcr: %x, chcr %x\n", madr, bcr, chcr);
return;
+69 -38
View File
@@ -16,71 +16,98 @@
#include "PrecompiledHeader.h"
#include "ChdFileReader.h"
#include "CDVD/CompressedFileReaderUtils.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include <wx/dir.h>
bool ChdFileReader::CanHandle(const wxString& fileName)
ChdFileReader::~ChdFileReader()
{
if (!wxFileName::FileExists(fileName) || !fileName.Lower().EndsWith(L".chd"))
{
Close();
for (std::FILE* fp : m_files)
std::fclose(fp);
}
bool ChdFileReader::CanHandle(const std::string& fileName, const std::string& displayName)
{
if (!StringUtil::EndsWith(displayName, ".chd"))
return false;
}
return true;
}
bool ChdFileReader::Open2(const wxString& fileName)
static chd_error chd_open_wrapper(const char* filename, std::FILE** fp, int mode, chd_file* parent, chd_file** chd)
{
*fp = FileSystem::OpenCFile(filename, "rb");
if (!*fp)
return CHDERR_FILE_NOT_FOUND;
const chd_error err = chd_open_file(*fp, mode, parent, chd);
if (err == CHDERR_NONE)
return err;
std::fclose(*fp);
*fp = nullptr;
return err;
}
bool ChdFileReader::Open2(std::string fileName)
{
Close2();
m_filename = fileName;
m_filename = std::move(fileName);
chd_file* child = NULL;
chd_file* parent = NULL;
chd_file* child = nullptr;
chd_file* parent = nullptr;
std::FILE* fp = nullptr;
chd_header header;
chd_header parent_header;
wxString chds[8];
chds[0] = fileName;
std::string chds[8];
chds[0] = m_filename;
int chd_depth = 0;
chd_error error;
// TODO: Unicode correctness on Windows
while (CHDERR_REQUIRES_PARENT == (error = chd_open(chds[chd_depth].c_str(), CHD_OPEN_READ, NULL, &child)))
std::string dirname;
FileSystem::FindResultsArray results;
while (CHDERR_REQUIRES_PARENT == (error = chd_open_wrapper(chds[chd_depth].c_str(), &fp, CHD_OPEN_READ, NULL, &child)))
{
if (chd_depth >= static_cast<int>(std::size(chds) - 1))
{
Console.Error(L"CDVD: chd_open hit recursion limit searching for parents");
Console.Error("CDVD: chd_open hit recursion limit searching for parents");
return false;
}
// TODO: This is still broken on Windows. Needs to be fixed in libchdr.
if (chd_read_header(chds[chd_depth].c_str(), &header) != CHDERR_NONE)
{
Console.Error(L"CDVD: chd_open chd_read_header error: %s: %s", chd_error_string(error), WX_STR(chds[chd_depth]));
Console.Error("CDVD: chd_open chd_read_header error: %s: %s", chd_error_string(error), chds[chd_depth].c_str());
return false;
}
bool found_parent = false;
wxFileName wxfilename(chds[chd_depth]);
wxString dir_path = wxfilename.GetPath();
wxDir dir(dir_path);
if (dir.IsOpened())
dirname = FileSystem::GetPathDirectory(chds[chd_depth]);
if (FileSystem::FindFiles(dirname.c_str(), "*.*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES, &results))
{
wxString parent_fileName;
bool cont = dir.GetFirst(&parent_fileName, wxString("*.") + wxfilename.GetExt(), wxDIR_FILES | wxDIR_HIDDEN);
for (; cont; cont = dir.GetNext(&parent_fileName))
for (const FILESYSTEM_FIND_DATA& fd : results)
{
parent_fileName = wxFileName(dir_path, parent_fileName).GetFullPath();
if (chd_read_header(parent_fileName.c_str(), &parent_header) == CHDERR_NONE &&
const std::string_view extension(FileSystem::GetExtension(fd.FileName));
if (extension.empty() || StringUtil::Strncasecmp(extension.data(), "chd", 3) != 0)
continue;
if (chd_read_header(fd.FileName.c_str(), &parent_header) == CHDERR_NONE &&
memcmp(parent_header.sha1, header.parentsha1, sizeof(parent_header.sha1)) == 0)
{
found_parent = true;
chds[++chd_depth] = wxString(parent_fileName);
chds[++chd_depth] = std::move(fd.FileName);
break;
}
}
}
if (!found_parent)
{
Console.Error(L"CDVD: chd_open no parent for: %s", WX_STR(chds[chd_depth]));
Console.Error("CDVD: chd_open no parent for: %s", chds[chd_depth].c_str());
break;
}
}
@@ -91,11 +118,17 @@ bool ChdFileReader::Open2(const wxString& fileName)
return false;
}
if (child)
{
pxAssert(fp != nullptr);
m_files.push_back(fp);
}
for (int d = chd_depth - 1; d >= 0; d--)
{
parent = child;
child = NULL;
error = chd_open(chds[d].c_str(), CHD_OPEN_READ, parent, &child);
error = chd_open_wrapper(chds[d].c_str(), &fp, CHD_OPEN_READ, parent, &child);
if (error != CHDERR_NONE)
{
Console.Error(L"CDVD: chd_open return error: %s", chd_error_string(error));
@@ -103,19 +136,17 @@ bool ChdFileReader::Open2(const wxString& fileName)
chd_close(parent);
return false;
}
m_files.push_back(fp);
}
ChdFile = child;
if (chd_read_header(chds[0].c_str(), &header) != CHDERR_NONE)
{
Console.Error(L"CDVD: chd_open chd_read_header error: %s: %s", chd_error_string(error), WX_STR(chds[0]));
return false;
}
file_size = static_cast<u64>(header.unitbytes) * header.unitcount;
hunk_size = header.hunkbytes;
const chd_header* chd_header = chd_get_header(ChdFile);
file_size = static_cast<u64>(chd_header->unitbytes) * chd_header->unitcount;
hunk_size = chd_header->hunkbytes;
// CHD likes to use full 2448 byte blocks, but keeps the +24 offset of source ISOs
// The rest of PCSX2 likes to use 2448 byte buffers, which can't fit that so trim blocks instead
m_internalBlockSize = header.unitbytes;
m_internalBlockSize = chd_header->unitbytes;
return true;
}
@@ -136,7 +167,7 @@ ThreadedFileReader::Chunk ChdFileReader::ChunkForOffset(u64 offset)
return chunk;
}
int ChdFileReader::ReadChunk(void *dst, s64 chunkID)
int ChdFileReader::ReadChunk(void* dst, s64 chunkID)
{
if (chunkID < 0)
return -1;
+5 -3
View File
@@ -16,16 +16,17 @@
#pragma once
#include "ThreadedFileReader.h"
#include "libchdr/chd.h"
#include <vector>
class ChdFileReader : public ThreadedFileReader
{
DeclareNoncopyableObject(ChdFileReader);
public:
virtual ~ChdFileReader(void) { Close(); };
virtual ~ChdFileReader() override;;
static bool CanHandle(const wxString& fileName);
bool Open2(const wxString& fileName) override;
static bool CanHandle(const std::string& fileName, const std::string& displayName);
bool Open2(std::string fileName) override;
Chunk ChunkForOffset(u64 offset) override;
int ReadChunk(void *dst, s64 blockID) override;
@@ -38,4 +39,5 @@ private:
chd_file* ChdFile;
u64 file_size;
u32 hunk_size;
std::vector<std::FILE*> m_files;
};
+3 -3
View File
@@ -18,7 +18,7 @@
void ChunksCache::SetLimit(uint megabytes)
{
m_limit = (PX_off_t)megabytes * 1024 * 1024;
m_limit = (s64)megabytes * 1024 * 1024;
MatchLimit();
}
@@ -34,7 +34,7 @@ void ChunksCache::MatchLimit(bool removeAll)
}
}
void ChunksCache::Take(void* pMallocedSrc, PX_off_t offset, int length, int coverage)
void ChunksCache::Take(void* pMallocedSrc, s64 offset, int length, int coverage)
{
m_entries.push_front(new CacheEntry(pMallocedSrc, offset, length, coverage));
m_size += length;
@@ -42,7 +42,7 @@ void ChunksCache::Take(void* pMallocedSrc, PX_off_t offset, int length, int cove
}
// By design, succeed only if the entire request is in a single cached chunk
int ChunksCache::Read(void* pDest, PX_off_t offset, int length)
int ChunksCache::Read(void* pDest, s64 offset, int length)
{
for (auto it = m_entries.begin(); it != m_entries.end(); it++)
{
+8 -8
View File
@@ -30,11 +30,11 @@ public:
void SetLimit(uint megabytes);
void Clear() { MatchLimit(true); };
void Take(void* pMallocedSrc, PX_off_t offset, int length, int coverage);
int Read(void* pDest, PX_off_t offset, int length);
void Take(void* pMallocedSrc, s64 offset, int length, int coverage);
int Read(void* pDest, s64 offset, int length);
static int CopyAvailable(void* pSrc, PX_off_t srcOffset, int srcSize,
void* pDst, PX_off_t dstOffset, int maxCopySize)
static int CopyAvailable(void* pSrc, s64 srcOffset, int srcSize,
void* pDst, s64 dstOffset, int maxCopySize)
{
int available = CLAMP(maxCopySize, 0, (int)(srcOffset + srcSize - dstOffset));
memcpy(pDst, (char*)pSrc + (dstOffset - srcOffset), available);
@@ -45,7 +45,7 @@ private:
class CacheEntry
{
public:
CacheEntry(void* pMallocedSrc, PX_off_t offset, int length, int coverage)
CacheEntry(void* pMallocedSrc, s64 offset, int length, int coverage)
: data(pMallocedSrc)
, offset(offset)
, coverage(coverage)
@@ -58,15 +58,15 @@ private:
};
void* data;
PX_off_t offset;
s64 offset;
int coverage;
int size;
};
std::list<CacheEntry*> m_entries;
void MatchLimit(bool removeAll = false);
PX_off_t m_size;
PX_off_t m_limit;
s64 m_size;
s64 m_limit;
};
#undef CLAMP
+12 -4
View File
@@ -19,19 +19,27 @@
#include "ChdFileReader.h"
#include "CsoFileReader.h"
#include "GzippedFileReader.h"
#include "common/FileSystem.h"
#include <cctype>
// CompressedFileReader factory.
AsyncFileReader* CompressedFileReader::GetNewReader(const wxString& fileName)
AsyncFileReader* CompressedFileReader::GetNewReader(const std::string& fileName)
{
if (ChdFileReader::CanHandle(fileName))
if (!FileSystem::FileExists(fileName.c_str()))
return nullptr;
std::string displayName(FileSystem::GetDisplayNameFromPath(fileName));
std::transform(displayName.begin(), displayName.end(), displayName.begin(), tolower);
if (ChdFileReader::CanHandle(fileName, displayName))
{
return new ChdFileReader();
}
if (GzippedFileReader::CanHandle(fileName))
if (GzippedFileReader::CanHandle(fileName, displayName))
{
return new GzippedFileReader();
}
if (CsoFileReader::CanHandle(fileName))
if (CsoFileReader::CanHandle(fileName, displayName))
{
return new CsoFileReader();
}
+2 -1
View File
@@ -14,6 +14,7 @@
*/
#pragma once
#include <string>
// Factory - creates an AsyncFileReader derived instance which can read a compressed file
class CompressedFileReader
@@ -23,7 +24,7 @@ public:
// If no matching handler is found, NULL is returned.
// The returned instance still needs ->Open(filename) before usage.
// Open(filename) may still fail.
static AsyncFileReader* GetNewReader(const wxString& fileName);
static AsyncFileReader* GetNewReader(const std::string& fileName);
private:
virtual ~CompressedFileReader() = 0;
-44
View File
@@ -1,44 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2014 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/Pcsx2Types.h"
/////////// Some complementary utilities for zlib_indexed.c //////////
// This is ugly, but it's hard to find something which will work/compile for both
// windows and *nix and work with non-english file names.
// Maybe some day we'll convert all file related ops to wxWidgets, which means also the
// instances at zlib_indexed.h (which use plain stdio FILE*)
#ifdef _WIN32
#define PX_wfilename(name_wxstr) (name_wxstr.wc_str())
#define PX_fopen_rb(name_wxstr) (_wfopen(PX_wfilename(name_wxstr), L"rb"))
#else
#define PX_wfilename(name_wxstr) (name_wxstr.mbc_str())
#define PX_fopen_rb(name_wxstr) (fopen(PX_wfilename(name_wxstr), "rb"))
#endif
#ifdef _WIN32
#define PX_fseeko _fseeki64
#define PX_ftello _ftelli64
#define PX_off_t s64 /* __int64 */
#else
#define PX_fseeko fseeko
#define PX_ftello ftello
#define PX_off_t off_t
#endif
/////////// End of complementary utilities for zlib_indexed.c //////////
+18 -18
View File
@@ -15,9 +15,10 @@
#include "PrecompiledHeader.h"
#include "AsyncFileReader.h"
#include "CompressedFileReaderUtils.h"
#include "CsoFileReader.h"
#include "common/Pcsx2Types.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#ifdef __POSIX__
#include <zlib.h>
#else
@@ -39,12 +40,12 @@ struct CsoHeader
static const u32 CSO_READ_BUFFER_SIZE = 256 * 1024;
bool CsoFileReader::CanHandle(const wxString& fileName)
bool CsoFileReader::CanHandle(const std::string& fileName, const std::string& displayName)
{
bool supported = false;
if (wxFileName::FileExists(fileName) && fileName.Lower().EndsWith(L".cso"))
if (StringUtil::EndsWith(displayName, ".cso"))
{
FILE* fp = PX_fopen_rb(fileName);
FILE* fp = FileSystem::OpenCFile(fileName.c_str(), "rb");
CsoHeader hdr;
if (fp)
{
@@ -67,17 +68,17 @@ bool CsoFileReader::ValidateHeader(const CsoHeader& hdr)
}
if (hdr.ver > 1)
{
Console.Error(L"Only CSOv1 files are supported.");
Console.Error("Only CSOv1 files are supported.");
return false;
}
if ((hdr.frame_size & (hdr.frame_size - 1)) != 0)
{
Console.Error(L"CSO frame size must be a power of two.");
Console.Error("CSO frame size must be a power of two.");
return false;
}
if (hdr.frame_size < 2048)
{
Console.Error(L"CSO frame size must be at least one sector.");
Console.Error("CSO frame size must be at least one sector.");
return false;
}
@@ -85,11 +86,11 @@ bool CsoFileReader::ValidateHeader(const CsoHeader& hdr)
return true;
}
bool CsoFileReader::Open2(const wxString& fileName)
bool CsoFileReader::Open2(std::string fileName)
{
Close2();
m_filename = fileName;
m_src = PX_fopen_rb(m_filename);
m_filename = std::move(fileName);
m_src = FileSystem::OpenCFile(m_filename.c_str(), "rb");
bool success = false;
if (m_src && ReadFileHeader() && InitializeBuffers())
@@ -109,16 +110,15 @@ bool CsoFileReader::ReadFileHeader()
{
CsoHeader hdr = {};
PX_fseeko(m_src, m_dataoffset, SEEK_SET);
if (fread(&hdr, 1, sizeof(hdr), m_src) != sizeof(hdr))
if (FileSystem::FSeek64(m_src, m_dataoffset, SEEK_SET) != 0 || std::fread(&hdr, 1, sizeof(hdr), m_src) != sizeof(hdr))
{
Console.Error(L"Failed to read CSO file header.");
Console.Error("Failed to read CSO file header.");
return false;
}
if (!ValidateHeader(hdr))
{
Console.Error(L"CSO has invalid header.");
Console.Error("CSO has invalid header.");
return false;
}
@@ -156,7 +156,7 @@ bool CsoFileReader::InitializeBuffers()
m_index = new u32[indexSize];
if (fread(m_index, sizeof(u32), indexSize, m_src) != indexSize)
{
Console.Error(L"Unable to read index data from CSO.");
Console.Error("Unable to read index data from CSO.");
return false;
}
@@ -175,7 +175,7 @@ bool CsoFileReader::InitializeBuffers()
void CsoFileReader::Close2()
{
m_filename.Empty();
m_filename.clear();
if (m_src)
{
@@ -235,7 +235,7 @@ int CsoFileReader::ReadChunk(void *dst, s64 chunkID)
if (!compressed)
{
// Just read directly, easy.
if (PX_fseeko(m_src, frameRawPos, SEEK_SET) != 0)
if (FileSystem::FSeek64(m_src, frameRawPos, SEEK_SET) != 0)
{
Console.Error("Unable to seek to uncompressed CSO data.");
return 0;
@@ -244,7 +244,7 @@ int CsoFileReader::ReadChunk(void *dst, s64 chunkID)
}
else
{
if (PX_fseeko(m_src, frameRawPos, SEEK_SET) != 0)
if (FileSystem::FSeek64(m_src, frameRawPos, SEEK_SET) != 0)
{
Console.Error("Unable to seek to compressed CSO data.");
return 0;
+2 -2
View File
@@ -52,8 +52,8 @@ public:
~CsoFileReader(void) { Close(); };
static bool CanHandle(const wxString& fileName);
bool Open2(const wxString& fileName) override;
static bool CanHandle(const std::string& fileName, const std::string& displayName);
bool Open2(std::string fileName) override;
Chunk ChunkForOffset(u64 offset) override;
int ReadChunk(void *dst, s64 chunkID) override;
+66 -74
View File
@@ -14,29 +14,17 @@
*/
#include "PrecompiledHeader.h"
#include <fstream>
#include <wx/stdpaths.h>
#include <fstream>
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include "Config.h"
#include "ChunksCache.h"
#include "CompressedFileReaderUtils.h"
#include "GzippedFileReader.h"
#include "zlib_indexed.h"
#define CLAMP(val, minval, maxval) (std::min(maxval, std::max(minval, val)))
static s64 fsize(const wxString& filename)
{
if (!wxFileName::FileExists(filename))
return -1;
std::ifstream f(PX_wfilename(filename), std::ifstream::binary);
f.seekg(0, f.end);
s64 size = f.tellg();
f.close();
return size;
}
#define GZIP_ID "PCSX2.index.gzip.v1|"
#define GZIP_ID_LEN (sizeof(GZIP_ID) - 1) /* sizeof includes the \0 terminator */
@@ -44,71 +32,75 @@ static s64 fsize(const wxString& filename)
// - [GZIP_ID_LEN] GZIP_ID (no \0)
// - [sizeof(Access)] index (should be allocated, contains various sizes)
// - [rest] the indexed data points (should be allocated, index->list should then point to it)
static Access* ReadIndexFromFile(const wxString& filename)
static Access* ReadIndexFromFile(const char* filename)
{
s64 size = fsize(filename);
if (size <= 0)
auto fp = FileSystem::OpenManagedCFile(filename, "rb");
s64 size;
if (!fp || (size = FileSystem::FSize64(fp.get())) <= 0)
{
Console.Error(L"Error: Can't open index file: '%s'", WX_STR(filename));
Console.Error("Error: Can't open index file: '%s'", filename);
return 0;
}
std::ifstream infile(PX_wfilename(filename), std::ifstream::binary);
char fileId[GZIP_ID_LEN + 1] = {0};
infile.read(fileId, GZIP_ID_LEN);
if (wxString::From8BitData(GZIP_ID) != wxString::From8BitData(fileId))
if (std::fread(fileId, GZIP_ID_LEN, 1, fp.get()) != 1 || std::memcmp(fileId, GZIP_ID, 4) != 0)
{
Console.Error(L"Error: Incompatible gzip index, please delete it manually: '%s'", WX_STR(filename));
infile.close();
Console.Error("Error: Incompatible gzip index, please delete it manually: '%s'", filename);
return 0;
}
Access* index = (Access*)malloc(sizeof(Access));
infile.read((char*)index, sizeof(Access));
s64 datasize = size - GZIP_ID_LEN - sizeof(Access);
if (datasize != (s64)index->have * sizeof(Point))
Access* const index = (Access*)malloc(sizeof(Access));
const s64 datasize = size - GZIP_ID_LEN - sizeof(Access);
if (std::fread(index, sizeof(Access), 1, fp.get()) != 1 ||
datasize != static_cast<s64>(index->have) * static_cast<s64>(sizeof(Point)))
{
Console.Error(L"Error: unexpected size of gzip index, please delete it manually: '%s'.", WX_STR(filename));
infile.close();
Console.Error("Error: unexpected size of gzip index, please delete it manually: '%s'.", filename);
free(index);
return 0;
}
char* buffer = (char*)malloc(datasize);
infile.read(buffer, datasize);
infile.close();
if (std::fread(buffer, datasize, 1, fp.get()) != 1)
{
Console.Error("Error: failed read of gzip index, please delete it manually: '%s'.", filename);
free(buffer);
free(index);
return 0;
}
index->list = (Point*)buffer; // adjust list pointer
return index;
}
static void WriteIndexToFile(Access* index, const wxString filename)
static void WriteIndexToFile(Access* index, const char* filename)
{
if (wxFileName::FileExists(filename))
if (FileSystem::FileExists(filename))
{
Console.Warning(L"WARNING: Won't write index - file name exists (please delete it manually): '%s'", WX_STR(filename));
Console.Warning("WARNING: Won't write index - file name exists (please delete it manually): '%s'", filename);
return;
}
std::ofstream outfile(PX_wfilename(filename), std::ofstream::binary);
outfile.write(GZIP_ID, GZIP_ID_LEN);
auto fp = FileSystem::OpenManagedCFile(filename, "wb");
if (!fp)
return;
bool success = (std::fwrite(GZIP_ID, GZIP_ID_LEN, 1, fp.get()) == 1);
Point* tmp = index->list;
index->list = 0; // current pointer is useless on disk, normalize it as 0.
outfile.write((char*)index, sizeof(Access));
std::fwrite((char*)index, sizeof(Access), 1, fp.get());
index->list = tmp;
outfile.write((char*)index->list, sizeof(Point) * index->have);
outfile.close();
success = success && (std::fwrite((char*)index->list, sizeof(Point) * index->have, 1, fp.get()) == 1);
// Verify
if (fsize(filename) != (s64)GZIP_ID_LEN + sizeof(Access) + sizeof(Point) * index->have)
if (!success)
{
Console.Warning(L"Warning: Can't write index file to disk: '%s'", WX_STR(filename));
Console.Warning("Warning: Can't write index file to disk: '%s'", filename);
}
else
{
Console.WriteLn(Color_Green, L"OK: Gzip quick access index file saved to disk: '%s'", WX_STR(filename));
Console.WriteLn(Color_Green, "OK: Gzip quick access index file saved to disk: '%s'", filename);
}
}
@@ -123,10 +115,10 @@ static wxString INDEX_TEMPLATE_KEY(L"$(f)");
// No checks are performed if the result file name can be created.
// If this proves useful, we can move it into Path:: . Right now there's no need.
static wxString ApplyTemplate(const wxString& name, const wxDirName& base,
const wxString& fileTemplate, const wxString& filename,
const std::string& fileTemplate, const std::string& filename,
bool canEndWithKey)
{
wxString tem(fileTemplate);
wxString tem(StringUtil::UTF8StringToWxString(fileTemplate));
wxString key = INDEX_TEMPLATE_KEY;
tem = tem.Trim(true).Trim(false); // both sides
@@ -141,7 +133,7 @@ static wxString ApplyTemplate(const wxString& name, const wxDirName& base,
return L"";
}
wxString fname(filename);
wxString fname(StringUtil::UTF8StringToWxString(filename));
if (first > 0)
fname = Path::GetFilename(fname); // without path
@@ -179,13 +171,13 @@ static void TestTemplate(const wxDirName &base, const wxString &fname, bool canE
}
*/
static wxString iso2indexname(const wxString& isoname)
static std::string iso2indexname(const std::string& isoname)
{
//testTemplate(isoname);
wxDirName appRoot = // TODO: have only one of this in PCSX2. Right now have few...
(wxDirName)(wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath());
//TestTemplate(appRoot, isoname, false);
return ApplyTemplate(L"gzip index", appRoot, fromUTF8(EmuConfig.GzipIsoIndexTemplate), isoname, false);
return StringUtil::wxStringToUTF8String(ApplyTemplate(L"gzip index", appRoot, EmuConfig.GzipIsoIndexTemplate, isoname, false));
}
GzippedFileReader::GzippedFileReader(void)
@@ -218,7 +210,7 @@ void GzippedFileReader::InitZstates()
void GzippedFileReader::AsyncPrefetchReset(){};
void GzippedFileReader::AsyncPrefetchOpen(){};
void GzippedFileReader::AsyncPrefetchClose(){};
void GzippedFileReader::AsyncPrefetchChunk(PX_off_t dummy){};
void GzippedFileReader::AsyncPrefetchChunk(s64 dummy){};
void GzippedFileReader::AsyncPrefetchCancel(){};
#else
// AsyncPrefetch works as follows:
@@ -239,7 +231,7 @@ void GzippedFileReader::AsyncPrefetchReset()
void GzippedFileReader::AsyncPrefetchOpen()
{
hOverlappedFile = CreateFile(
m_filename,
StringUtil::UTF8StringToWideString(m_filename).c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
@@ -258,7 +250,7 @@ void GzippedFileReader::AsyncPrefetchClose()
AsyncPrefetchReset();
};
void GzippedFileReader::AsyncPrefetchChunk(PX_off_t start)
void GzippedFileReader::AsyncPrefetchChunk(s64 start)
{
if (hOverlappedFile == INVALID_HANDLE_VALUE || asyncInProgress)
{
@@ -296,9 +288,9 @@ void GzippedFileReader::AsyncPrefetchCancel()
#endif /* _WIN32 */
// TODO: do better than just checking existance and extension
bool GzippedFileReader::CanHandle(const wxString& fileName)
bool GzippedFileReader::CanHandle(const std::string& fileName, const std::string& displayName)
{
return wxFileName::FileExists(fileName) && fileName.Lower().EndsWith(L".gz");
return StringUtil::EndsWith(fileName, ".gz");
}
bool GzippedFileReader::OkIndex()
@@ -307,29 +299,29 @@ bool GzippedFileReader::OkIndex()
return true;
// Try to read index from disk
wxString indexfile = iso2indexname(m_filename);
if (indexfile.length() == 0)
const std::string indexfile(iso2indexname(m_filename));
if (indexfile.empty())
return false; // iso2indexname(...) will print errors if it can't apply the template
if (wxFileName::FileExists(indexfile) && (m_pIndex = ReadIndexFromFile(indexfile)))
if (FileSystem::FileExists(indexfile.c_str()) && (m_pIndex = ReadIndexFromFile(indexfile.c_str())))
{
Console.WriteLn(Color_Green, L"OK: Gzip quick access index read from disk: '%s'", WX_STR(indexfile));
Console.WriteLn(Color_Green, "OK: Gzip quick access index read from disk: '%s'", indexfile.c_str());
if (m_pIndex->span != GZFILE_SPAN_DEFAULT)
{
Console.Warning(L"Note: This index has %1.1f MB intervals, while the current default for new indexes is %1.1f MB.",
Console.Warning("Note: This index has %1.1f MB intervals, while the current default for new indexes is %1.1f MB.",
(float)m_pIndex->span / 1024 / 1024, (float)GZFILE_SPAN_DEFAULT / 1024 / 1024);
Console.Warning(L"It will work fine, but if you want to generate a new index with default intervals, delete this index file.");
Console.Warning(L"(smaller intervals mean bigger index file and quicker but more frequent decompressions)");
Console.Warning("It will work fine, but if you want to generate a new index with default intervals, delete this index file.");
Console.Warning("(smaller intervals mean bigger index file and quicker but more frequent decompressions)");
}
InitZstates();
return true;
}
// No valid index file. Generate an index
Console.Warning(L"This may take a while (but only once). Scanning compressed file to generate a quick access index...");
Console.Warning("This may take a while (but only once). Scanning compressed file to generate a quick access index...");
Access* index;
FILE* infile = PX_fopen_rb(m_filename);
FILE* infile = FileSystem::OpenCFile(m_filename.c_str(), "rb");
int len = build_index(infile, GZFILE_SPAN_DEFAULT, &index);
printf("\n"); // build_index prints progress without \n's
fclose(infile);
@@ -337,11 +329,11 @@ bool GzippedFileReader::OkIndex()
if (len >= 0)
{
m_pIndex = index;
WriteIndexToFile((Access*)m_pIndex, indexfile);
WriteIndexToFile((Access*)m_pIndex, indexfile.c_str());
}
else
{
Console.Error(L"ERROR (%d): index could not be generated for file '%s'", len, WX_STR(m_filename));
Console.Error("ERROR (%d): index could not be generated for file '%s'", len, m_filename.c_str());
free_index(index);
InitZstates();
return false;
@@ -351,11 +343,11 @@ bool GzippedFileReader::OkIndex()
return true;
}
bool GzippedFileReader::Open(const wxString& fileName)
bool GzippedFileReader::Open(std::string fileName)
{
Close();
m_filename = fileName;
if (!(m_src = PX_fopen_rb(m_filename)) || !CanHandle(fileName) || !OkIndex())
m_filename = std::move(fileName);
if (!(m_src = FileSystem::OpenCFile(m_filename.c_str(), "rb")) || !OkIndex())
{
Close();
return false;
@@ -384,7 +376,7 @@ int GzippedFileReader::FinishRead(void)
int GzippedFileReader::ReadSync(void* pBuffer, uint sector, uint count)
{
PX_off_t offset = (s64)sector * m_blocksize + m_dataoffset;
s64 offset = (s64)sector * m_blocksize + m_dataoffset;
int bytesToRead = count * m_blocksize;
int res = _ReadSync(pBuffer, offset, bytesToRead);
if (res < 0)
@@ -393,11 +385,11 @@ int GzippedFileReader::ReadSync(void* pBuffer, uint sector, uint count)
}
// If we have a valid and adequate zstate for this span, use it, else, use the index
PX_off_t GzippedFileReader::GetOptimalExtractionStart(PX_off_t offset)
s64 GzippedFileReader::GetOptimalExtractionStart(s64 offset)
{
int span = m_pIndex->span;
Czstate& cstate = m_zstates[offset / span];
PX_off_t stateOffset = cstate.state.isValid ? cstate.state.out_offset : 0;
s64 stateOffset = cstate.state.isValid ? cstate.state.out_offset : 0;
if (stateOffset && stateOffset <= offset)
return stateOffset; // state is faster than indexed
@@ -409,7 +401,7 @@ PX_off_t GzippedFileReader::GetOptimalExtractionStart(PX_off_t offset)
return span * (offset / span); // index direct access boundaries
}
int GzippedFileReader::_ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRead)
int GzippedFileReader::_ReadSync(void* pBuffer, s64 offset, uint bytesToRead)
{
if (!OkIndex())
return -1;
@@ -441,7 +433,7 @@ int GzippedFileReader::_ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRea
// Not available from cache. Decompress from optimal starting
// point in GZFILE_READ_CHUNK_SIZE chunks and cache each chunk.
PTT s = NOW();
PX_off_t extractOffset = GetOptimalExtractionStart(offset); // guaranteed in GZFILE_READ_CHUNK_SIZE boundaries
s64 extractOffset = GetOptimalExtractionStart(offset); // guaranteed in GZFILE_READ_CHUNK_SIZE boundaries
int size = offset + maxInChunk - extractOffset;
unsigned char* extracted = (unsigned char*)malloc(size);
@@ -501,7 +493,7 @@ int GzippedFileReader::_ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRea
void GzippedFileReader::Close()
{
m_filename.Empty();
m_filename.clear();
if (m_pIndex)
{
free_index((Access*)m_pIndex);
+5 -5
View File
@@ -34,8 +34,8 @@ public:
virtual ~GzippedFileReader(void) { Close(); };
static bool CanHandle(const wxString& fileName);
virtual bool Open(const wxString& fileName);
static bool CanHandle(const std::string& fileName, const std::string& displayName);
virtual bool Open(std::string fileName);
virtual int ReadSync(void* pBuffer, uint sector, uint count);
@@ -71,8 +71,8 @@ private:
};
bool OkIndex(); // Verifies that we have an index, or try to create one
PX_off_t GetOptimalExtractionStart(PX_off_t offset);
int _ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRead);
s64 GetOptimalExtractionStart(s64 offset);
int _ReadSync(void* pBuffer, s64 offset, uint bytesToRead);
void InitZstates();
int mBytesRead; // Temp sync read result when simulating async read
@@ -93,6 +93,6 @@ private:
void AsyncPrefetchReset();
void AsyncPrefetchOpen();
void AsyncPrefetchClose();
void AsyncPrefetchChunk(PX_off_t dummy);
void AsyncPrefetchChunk(s64 dummy);
void AsyncPrefetchCancel();
};
+7 -9
View File
@@ -194,19 +194,16 @@ void InputIsoFile::_init()
//
// Note that this is a member method, and that it will clobber any existing ISO state.
// (assertions are generated in debug mode if the object state is not already closed).
bool InputIsoFile::Test(const wxString& srcfile)
bool InputIsoFile::Test(std::string srcfile)
{
Close();
m_filename = srcfile;
return Open(srcfile, true);
return Open(std::move(srcfile), true);
}
bool InputIsoFile::Open(const wxString& srcfile, bool testOnly)
bool InputIsoFile::Open(std::string srcfile, bool testOnly)
{
Close();
m_filename = srcfile;
m_reader = NULL;
m_filename = std::move(srcfile);
bool isBlockdump = false;
bool isCompressed = false;
@@ -224,7 +221,8 @@ bool InputIsoFile::Open(const wxString& srcfile, bool testOnly)
m_reader = new FlatFileReader(EmuConfig.CdvdShareWrite);
}
m_reader->Open(m_filename);
if (!m_reader->Open(m_filename))
return false;
// It might actually be a blockdump file.
// Check that before continuing with the FlatFileReader.
@@ -270,7 +268,7 @@ bool InputIsoFile::Open(const wxString& srcfile, bool testOnly)
m_blocks = m_reader->GetBlockCount();
Console.WriteLn(Color_StrongBlue, L"isoFile open ok: %s", WX_STR(m_filename));
Console.WriteLn(Color_StrongBlue, "isoFile open ok: %s", m_filename.c_str());
ConsoleIndentScope indent;
+9 -9
View File
@@ -16,10 +16,10 @@
#pragma once
#include "CDVD.h"
#include "wx/wfstream.h"
#include "AsyncFileReader.h"
#include "CompressedFileReader.h"
#include <memory>
#include <string>
enum isoType
{
@@ -45,7 +45,7 @@ protected:
uint ReadUnit;
protected:
wxString m_filename;
std::string m_filename;
AsyncFileReader* m_reader;
u32 m_current_lsn;
@@ -75,13 +75,13 @@ public:
uint GetBlockCount() const { return m_blocks; }
int GetBlockOffset() const { return m_blockofs; }
const wxString& GetFilename() const
const std::string& GetFilename() const
{
return m_filename;
}
bool Test(const wxString& srcfile);
bool Open(const wxString& srcfile, bool testOnly = false);
bool Test(std::string srcfile);
bool Open(std::string srcfile, bool testOnly = false);
void Close();
bool Detect(bool readType = true);
@@ -102,7 +102,7 @@ class OutputIsoFile
DeclareNoncopyableObject(OutputIsoFile);
protected:
wxString m_filename;
std::string m_filename;
u32 m_version;
@@ -116,7 +116,7 @@ protected:
// dtable is used when reading blockdumps
std::vector<u32> m_dtable;
std::unique_ptr<wxFileOutputStream> m_outstream;
std::FILE* m_outstream = nullptr;
public:
OutputIsoFile();
@@ -125,12 +125,12 @@ public:
bool IsOpened() const;
u32 GetBlockSize() const;
const wxString& GetFilename() const
const std::string& GetFilename() const
{
return m_filename;
}
void Create(const wxString& filename, int mode);
void Create(std::string filename, int mode);
void Close();
void WriteHeader(int blockofs, uint blocksize, uint blocks);
+25 -16
View File
@@ -17,15 +17,17 @@
#include "PrecompiledHeader.h"
#include "IopCommon.h"
#include "IsoFileFormats.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include <errno.h>
void pxStream_OpenCheck(const wxStreamBase& stream, const wxString& fname, const wxString& mode)
void pxStream_OpenCheck(std::FILE* stream, const std::string& fname, const wxString& mode)
{
if (stream.IsOk())
if (stream)
return;
ScopedExcept ex(Exception::FromErrno(fname, errno));
ScopedExcept ex(Exception::FromErrno(StringUtil::UTF8StringToWxString(fname), errno));
ex->SetDiagMsg(pxsFmt(L"Unable to open the file for %s: %s", WX_STR(mode), WX_STR(ex->DiagMsg())));
ex->Rethrow();
}
@@ -50,20 +52,20 @@ void OutputIsoFile::_init()
m_blocks = 0;
}
void OutputIsoFile::Create(const wxString& filename, int version)
void OutputIsoFile::Create(std::string filename, int version)
{
Close();
m_filename = filename;
m_filename = std::move(filename);
m_version = version;
m_offset = 0;
m_blockofs = 24;
m_blocksize = 2048;
m_outstream = std::make_unique<wxFileOutputStream>(m_filename);
pxStream_OpenCheck(*m_outstream, m_filename, L"writing");
m_outstream = FileSystem::OpenCFile(m_filename.c_str(), "wb");
pxStream_OpenCheck(m_outstream, m_filename, L"writing");
Console.WriteLn("isoFile create ok: %s ", WX_STR(m_filename));
Console.WriteLn("isoFile create ok: %s ", m_filename.c_str());
}
// Generates format header information for blockdumps.
@@ -100,9 +102,8 @@ void OutputIsoFile::WriteSector(const u8* src, uint lsn)
}
else
{
wxFileOffset ofs = (wxFileOffset)lsn * m_blocksize + m_offset;
m_outstream->SeekO(ofs);
const s64 ofs = (s64)lsn * m_blocksize + m_offset;
FileSystem::FSeek64(m_outstream, ofs, SEEK_SET);
}
WriteBuffer(src + m_blockofs, m_blocksize);
@@ -112,19 +113,27 @@ void OutputIsoFile::Close()
{
m_dtable.clear();
if (m_outstream)
{
std::fclose(m_outstream);
m_outstream = nullptr;
}
_init();
}
void OutputIsoFile::WriteBuffer(const void* src, size_t size)
{
m_outstream->Write(src, size);
if (m_outstream->GetLastError() == wxSTREAM_WRITE_ERROR)
if (std::fwrite(src, size, 1, m_outstream) != 1)
{
int err = errno;
if (!err)
throw Exception::BadStream(m_filename).SetDiagMsg(pxsFmt(L"An error occurred while writing %u bytes to file", size));
{
throw Exception::BadStream(StringUtil::UTF8StringToWxString(m_filename))
.SetDiagMsg(pxsFmt(L"An error occurred while writing %u bytes to file", size));
}
ScopedExcept ex(Exception::FromErrno(m_filename, err));
ScopedExcept ex(Exception::FromErrno(StringUtil::UTF8StringToWxString(m_filename), err));
ex->SetDiagMsg(pxsFmt(L"An error occurred while writing %u bytes to file: %s", size, WX_STR(ex->DiagMsg())));
ex->Rethrow();
}
@@ -132,7 +141,7 @@ void OutputIsoFile::WriteBuffer(const void* src, size_t size)
bool OutputIsoFile::IsOpened() const
{
return m_outstream && m_outstream->IsOk();
return m_outstream != nullptr;
}
u32 OutputIsoFile::GetBlockSize() const
+2 -2
View File
@@ -239,10 +239,10 @@ bool ThreadedFileReader::TryCachedRead(void*& buffer, u64& offset, u32& size, co
return allDone;
}
bool ThreadedFileReader::Open(const wxString& fileName)
bool ThreadedFileReader::Open(std::string fileName)
{
CancelAndWaitUntilStopped();
return Open2(fileName);
return Open2(std::move(fileName));
}
int ThreadedFileReader::ReadSync(void* pBuffer, uint sector, uint count)
+2 -2
View File
@@ -47,7 +47,7 @@ protected:
/// Synchronously read the given block into `dst`
virtual int ReadChunk(void* dst, s64 chunkID) = 0;
/// AsyncFileReader open but ThreadedFileReader needs prep work first
virtual bool Open2(const wxString& fileName) = 0;
virtual bool Open2(std::string fileName) = 0;
/// AsyncFileReader close but ThreadedFileReader needs prep work first
virtual void Close2(void) = 0;
@@ -109,7 +109,7 @@ private:
bool TryCachedRead(void*& buffer, u64& offset, u32& size, const std::lock_guard<std::mutex>&);
public:
bool Open(const wxString& fileName) final override;
bool Open(std::string fileName) final override;
int ReadSync(void* pBuffer, uint sector, uint count) final override;
void BeginRead(void* pBuffer, uint sector, uint count) final override;
int FinishRead(void) final override;
+15 -15
View File
@@ -107,7 +107,7 @@ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
#include <zlib/zlib.h>
#endif
#include "CompressedFileReaderUtils.h"
#include "common/FileSystem.h"
#define local static
@@ -122,8 +122,8 @@ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
/* access point entry */
struct point
{
PX_off_t out; /* corresponding offset in uncompressed data */
PX_off_t in; /* offset in input file of first full byte */
s64 out; /* corresponding offset in uncompressed data */
s64 in; /* offset in input file of first full byte */
int bits; /* number of bits (1-7) from byte at in - 1, or 0 */
unsigned char window[WINSIZE]; /* preceding 32K of uncompressed data */
}
@@ -142,7 +142,7 @@ struct access
struct point* list; /* allocated list */
s32 span; /* once the index is built, holds the span size used to build it */
PX_off_t uncompressed_size; /* filled by build_index */
s64 uncompressed_size; /* filled by build_index */
}
#ifndef _WIN32
__attribute__((packed))
@@ -168,7 +168,7 @@ local void free_index(struct access* index)
/* Add an entry to the access point list. If out of memory, deallocate the
existing list and return NULL. */
local struct access* addpoint(struct access* index, int bits,
PX_off_t in, PX_off_t out, unsigned left, unsigned char* window)
s64 in, s64 out, unsigned left, unsigned char* window)
{
struct point* next;
@@ -224,11 +224,11 @@ local struct access* addpoint(struct access* index, int bits,
returns the number of access points on success (>= 1), Z_MEM_ERROR for out
of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a
file read error. On success, *built points to the resulting index. */
local int build_index(FILE* in, PX_off_t span, struct access** built)
local int build_index(FILE* in, s64 span, struct access** built)
{
int ret;
PX_off_t totin, totout, totPrinted; /* our own total counters to avoid 4GB limit */
PX_off_t last; /* totout value of last access point */
s64 totin, totout, totPrinted; /* our own total counters to avoid 4GB limit */
s64 last; /* totout value of last access point */
struct access* index; /* access points being generated */
z_stream strm;
unsigned char input[CHUNK];
@@ -344,13 +344,13 @@ build_index_error:
typedef struct zstate
{
PX_off_t out_offset;
PX_off_t in_offset;
s64 out_offset;
s64 in_offset;
z_stream strm;
int isValid;
} Zstate;
static inline PX_off_t getInOffset(zstate* state)
static inline s64 getInOffset(zstate* state)
{
return state->in_offset;
}
@@ -362,7 +362,7 @@ static inline PX_off_t getInOffset(zstate* state)
should not return a data error unless the file was modified since the index
was generated. extract() may also return Z_ERRNO if there is an error on
reading or seeking the input file. */
local int extract(FILE* in, struct access* index, PX_off_t offset,
local int extract(FILE* in, struct access* index, s64 offset,
unsigned char* buf, int len, zstate* state)
{
int ret, skip;
@@ -386,7 +386,7 @@ local int extract(FILE* in, struct access* index, PX_off_t offset,
if (state->isValid)
{
state->isValid = 0; // we took control over strm. revalidate when/if we give it back
PX_fseeko(in, state->in_offset, SEEK_SET);
FileSystem::FSeek64(in, state->in_offset, SEEK_SET);
state->strm.avail_in = 0;
offset = 0;
skip = 1;
@@ -408,7 +408,7 @@ local int extract(FILE* in, struct access* index, PX_off_t offset,
ret = inflateInit2(&state->strm, -15); /* raw inflate */
if (ret != Z_OK)
return ret;
ret = PX_fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
ret = FileSystem::FSeek64(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
if (ret == -1)
goto extract_ret;
if (here->bits)
@@ -456,7 +456,7 @@ local int extract(FILE* in, struct access* index, PX_off_t offset,
{
if (state->strm.avail_in == 0)
{
state->in_offset = PX_ftello(in);
state->in_offset = FileSystem::FTell64(in);
state->strm.avail_in = fread(input, 1, CHUNK, in);
if (ferror(in))
{
+36 -74
View File
@@ -70,10 +70,6 @@ if(TARGET SDL::SDL)
target_link_libraries(PCSX2_FLAGS INTERFACE SDL::SDL)
endif()
if(WAYLAND_CLIENT_FOUND)
target_compile_definitions(PCSX2 PRIVATE WAYLAND_BUILD)
endif()
if(WIN32)
# Resources
target_sources(PCSX2 PRIVATE
@@ -130,7 +126,7 @@ set(pcsx2Sources
IopIrq.cpp
IopMem.cpp
IopSio2.cpp
IPC.cpp
PINE.cpp
Mdec.cpp
Memory.cpp
MemoryCardFile.cpp
@@ -139,10 +135,10 @@ set(pcsx2Sources
MTGS.cpp
MTVU.cpp
MultipartFileReader.cpp
OutputIsoFile.cpp
Patch.cpp
Patch_Memory.cpp
Pcsx2Config.cpp
PerformanceMetrics.cpp
PrecompiledHeader.cpp
R3000A.cpp
R3000AInterpreter.cpp
@@ -195,6 +191,7 @@ set(pcsx2Headers
Gif_Unit.h
GS.h
Hardware.h
Host.h
Hw.h
IopBios.h
IopCommon.h
@@ -204,7 +201,7 @@ set(pcsx2Headers
IopHw.h
IopMem.h
IopSio2.h
IPC.h
PINE.h
Mdec.h
MTVU.h
Memory.h
@@ -214,6 +211,7 @@ set(pcsx2Headers
Patch.h
PathDefs.h
PCSX2Base.h
PerformanceMetrics.h
PrecompiledHeader.h
R3000A.h
R5900Exceptions.h
@@ -268,7 +266,6 @@ set(pcsx2CDVDHeaders
CDVD/CDVDisoReader.h
CDVD/ChunksCache.h
CDVD/CompressedFileReader.h
CDVD/CompressedFileReaderUtils.h
CDVD/ChdFileReader.h
CDVD/CsoFileReader.h
CDVD/GzippedFileReader.h
@@ -531,18 +528,6 @@ else(WIN32)
COMMAND ${BIN2CPP} "${PADImg}/${result_file}.png" "${PADImgHeader}/${result_file}" )
endforeach()
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.h
COMMAND glib-compile-resources --sourcedir "${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res" --generate-header
--c-name PAD_res "${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/PAD-res.xml" --target=${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.h
DEPENDS ${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/PAD-res.xml ${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/game_controller_db.txt)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.cpp
COMMAND glib-compile-resources --sourcedir "${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res" --generate-source
--c-name PAD_res "${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/PAD-res.xml" --target=${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.cpp
DEPENDS ${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/PAD-res.xml ${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/game_controller_db.txt)
# PAD/Linux sources
set(pcsx2PADSources
PAD/Linux/Device.cpp
@@ -557,7 +542,6 @@ else(WIN32)
PAD/Linux/wx_dialog/GamepadConfiguration.cpp
PAD/Linux/wx_dialog/JoystickConfiguration.cpp
PAD/Linux/Config.cpp
${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.cpp
)
# PAD/Linux headers
@@ -575,7 +559,6 @@ else(WIN32)
PAD/Linux/wx_dialog/opPanel.h
PAD/Linux/wx_dialog/GamepadConfiguration.h
PAD/Linux/wx_dialog/JoystickConfiguration.h
${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.h
# images
${PADImgHeader}/analog.h
${PADImgHeader}/circle.h
@@ -618,6 +601,7 @@ set(pcsx2GSSources
GS/GSLzma.cpp
GS/GSPerfMon.cpp
GS/GSPng.cpp
GS/GSRingHeap.cpp
GS/GSState.cpp
GS/GSTables.cpp
GS/GSUtil.cpp
@@ -650,7 +634,6 @@ set(pcsx2GSSources
GS/Renderers/OpenGL/GSDeviceOGL.cpp
GS/Renderers/OpenGL/GSRendererOGL.cpp
GS/Renderers/OpenGL/GSShaderOGL.cpp
GS/Renderers/OpenGL/GSTextureCacheOGL.cpp
GS/Renderers/OpenGL/GSTextureOGL.cpp
GS/Window/GSSetting.cpp
GS/Window/GSwxDialog.cpp
@@ -677,6 +660,7 @@ set(pcsx2GSHeaders
GS/GSLzma.h
GS/GSPerfMon.h
GS/GSPng.h
GS/GSRingHeap.h
GS/GSState.h
GS/GSTables.h
GS/GSThread_CXX11.h
@@ -720,7 +704,6 @@ set(pcsx2GSHeaders
GS/Renderers/OpenGL/GSDeviceOGL.h
GS/Renderers/OpenGL/GSRendererOGL.h
GS/Renderers/OpenGL/GSShaderOGL.h
GS/Renderers/OpenGL/GSTextureCacheOGL.h
GS/Renderers/OpenGL/GSTextureOGL.h
GS/Renderers/OpenGL/GSUniformBufferOGL.h
GS/Window/GSCaptureDlg.h
@@ -795,7 +778,6 @@ if(WIN32)
GS/Renderers/DX11/GSDevice11.cpp
GS/Renderers/DX11/GSRendererDX11.cpp
GS/Renderers/DX11/GSTexture11.cpp
GS/Renderers/DX11/GSTextureCache11.cpp
GS/Renderers/DX11/GSTextureFX11.cpp
GS/Window/GSCaptureDlg.cpp
GS/Window/GSDialog.cpp
@@ -805,7 +787,6 @@ if(WIN32)
GS/Renderers/DX11/GSDevice11.h
GS/Renderers/DX11/GSRendererDX11.h
GS/Renderers/DX11/GSTexture11.h
GS/Renderers/DX11/GSTextureCache11.h
)
else(WIN32)
list(APPEND pcsx2SPU2Sources
@@ -860,42 +841,6 @@ else(WIN32)
USB/usb-pad/evdev/evdev.h
USB/usb-pad/evdev/shared.h
)
# GS resources
set(pcsx2GSResources
GS/res/fxaa.fx
GS/res/glsl/common_header.glsl
GS/res/glsl/convert.glsl
GS/res/glsl/interlace.glsl
GS/res/glsl/merge.glsl
GS/res/glsl/shadeboost.glsl
GS/res/glsl/tfx_fs.glsl
GS/res/glsl/tfx_vgs.glsl)
set(GSBin "${CMAKE_BINARY_DIR}/pcsx2/GS")
target_include_directories(PCSX2_FLAGS INTERFACE "${GSBin}")
file(MAKE_DIRECTORY "${GSBin}")
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/pcsx2/GS/GS_res.h
COMMAND glib-compile-resources --sourcedir "${CMAKE_SOURCE_DIR}/pcsx2/GS/res" --generate-header
--c-name GS_res "${CMAKE_SOURCE_DIR}/pcsx2/GS/res/GS-res.xml" --target=${CMAKE_BINARY_DIR}/pcsx2/GS/GS_res.h
DEPENDS ${pcsx2GSResources})
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/pcsx2/GS/GS_res.cpp
COMMAND glib-compile-resources --sourcedir "${CMAKE_SOURCE_DIR}/pcsx2/GS/res" --generate-source
--c-name GS_res "${CMAKE_SOURCE_DIR}/pcsx2/GS/res/GS-res.xml" --target=${CMAKE_BINARY_DIR}/pcsx2/GS/GS_res.cpp
DEPENDS ${pcsx2GSResources})
list(APPEND pcsx2GSSources
GS/GS_res.cpp
)
list(APPEND pcsx2GSHeaders
GS/GS_res.h
)
endif(WIN32)
@@ -939,14 +884,13 @@ set(pcsx2GuiSources
gui/AppConfig.cpp
gui/AppCoreThread.cpp
gui/AppEventSources.cpp
gui/AppGameDatabase.cpp
gui/AppHost.cpp
gui/AppUserMode.cpp
gui/AppInit.cpp
gui/AppMain.cpp
gui/AppRes.cpp
gui/CheckedStaticBox.cpp
gui/ConsoleLogger.cpp
gui/CpuUsageProvider.cpp
gui/Dialogs/AboutBoxDialog.cpp
gui/Dialogs/GSDumpDialog.cpp
gui/Dialogs/AssertionDialog.cpp
@@ -960,7 +904,7 @@ set(pcsx2GuiSources
gui/Dialogs/McdConfigDialog.cpp
gui/Dialogs/PickUserModeDialog.cpp
gui/Dialogs/SysConfigDialog.cpp
gui/Dialogs/IPCDialog.cpp
gui/Dialogs/PINEDialog.cpp
gui/Debugger/BreakpointWindow.cpp
gui/Debugger/CtrlDisassemblyView.cpp
gui/Debugger/CtrlRegisterList.cpp
@@ -1015,13 +959,11 @@ set(pcsx2GuiHeaders
gui/AppCoreThread.h
gui/AppEventListeners.h
gui/AppForwardDefs.h
gui/AppGameDatabase.h
gui/App.h
gui/ApplyState.h
gui/AppSaveStates.h
gui/CheckedStaticBox.h
gui/ConsoleLogger.h
gui/CpuUsageProvider.h
gui/Debugger/BreakpointWindow.h
gui/Debugger/CtrlDisassemblyView.h
gui/Debugger/CtrlMemView.h
@@ -1398,7 +1340,7 @@ if(UNIX AND NOT APPLE)
endif()
if(WAYLAND_API)
target_link_libraries(PCSX2_FLAGS INTERFACE
${WAYLAND_CLIENT_LIBRARIES}
Wayland::Client
)
endif()
endif()
@@ -1468,7 +1410,6 @@ if(WIN32)
)
elseif(APPLE)
target_link_libraries(PCSX2_FLAGS INTERFACE
PkgConfig::GIO
PCAP::PCAP
LibXml2::LibXml2
)
@@ -1523,6 +1464,31 @@ if(COMMAND target_precompile_headers)
target_precompile_headers(PCSX2_FLAGS INTERFACE PrecompiledHeader.h)
endif()
# Copy resource files if needed
function(pcsx2_resource path basedir)
get_filename_component(dir ${path} DIRECTORY)
file(RELATIVE_PATH subdir ${basedir} ${dir})
if(APPLE)
target_sources(PCSX2 PRIVATE ${path})
set_source_files_properties(${path} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/${subdir})
elseif(PACKAGE_MODE)
install(FILES ${path} DESTINATION ${CMAKE_INSTALL_DATADIR}/PCSX2/resources/${subdir})
endif()
source_group(Resources/${subdir} FILES ${path})
endfunction()
file(GLOB_RECURSE RESOURCE_FILES ${CMAKE_SOURCE_DIR}/bin/resources/*)
foreach(path IN LISTS RESOURCE_FILES)
get_filename_component(file ${path} NAME)
if("${file}" MATCHES "^\\.") # Don't copy macOS garbage (mainly Finder's .DS_Store files) into application
continue()
endif()
if (NOT WIN32 AND "${path}" MATCHES "/dx11/") # Don't include unneccessary stuff
continue()
endif()
pcsx2_resource(${path} ${CMAKE_SOURCE_DIR}/bin/resources/)
endforeach()
if (APPLE)
# MacOS defaults to having a maximum protection of the __DATA segment of rw (non-executable)
# We have a bunch of page-sized arrays in bss that we use for jit
@@ -1535,10 +1501,7 @@ if (APPLE)
OUTPUT_NAME PCSX2
)
target_sources(PCSX2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources/PCSX2.icns")
target_sources(PCSX2 PRIVATE "${CMAKE_SOURCE_DIR}/bin/GameIndex.yaml")
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources/PCSX2.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
set_source_files_properties("${CMAKE_SOURCE_DIR}/bin/GameIndex.yaml" PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
pcsx2_resource(${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources/PCSX2.icns ${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources)
# If they say to skip postprocess bundle, leave the target in but make it so they have
# to manually run it
@@ -1583,5 +1546,4 @@ source_group(System/Ps2/USB REGULAR_EXPRESSION USB/*)
source_group(Resources/GUI FILES ${pcsx2GuiResources})
source_group(Resources/PAD FILES ${pcsx2PADResources})
source_group(Resources/Recording FILES ${pcsx2RecordingVirtualPadResources})
source_group(Resources FILES ../bin/GameIndex.yaml gui/Resources/PCSX2.icns)
source_group(Resources REGULAR_EXPRESSION ${CMAKE_CURRENT_BINARY_DIR}/*)
+4 -2
View File
@@ -545,7 +545,7 @@ struct Pcsx2Config
CdvdShareWrite : 1, // allows the iso to be modified while it's loaded
EnablePatches : 1, // enables patch detection and application
EnableCheats : 1, // enables cheat detection and application
EnableIPC : 1, // enables inter-process communication
EnablePINE : 1, // enables inter-process communication
EnableWideScreenPatches : 1,
#ifndef DISABLE_RECORDING
EnableRecordingTools : 1,
@@ -598,7 +598,7 @@ struct Pcsx2Config
void LoadSaveMemcards(SettingsWrapper& wrap);
// TODO: Make these std::string when we remove wxFile...
wxString FullpathToBios() const;
std::string FullpathToBios() const;
wxString FullpathToMcd(uint slot) const;
bool MultitapEnabled(uint port) const;
@@ -627,6 +627,8 @@ namespace EmuFolders
extern wxDirName Logs;
extern wxDirName Cheats;
extern wxDirName CheatsWS;
extern wxDirName Resources;
extern wxDirName Cache;
} // namespace EmuFolders
/////////////////////////////////////////////////////////////////////////////////////////
+3
View File
@@ -27,6 +27,7 @@
#include "GS.h"
#include "VUmicro.h"
#include "PerformanceMetrics.h"
#include "ps2/HwInternal.h"
#include "Sio.h"
@@ -400,6 +401,8 @@ u32 UpdateVSyncRate()
cpuRcntSet();
}
PerformanceMetrics::SetVerticalFrequency(vertical_frequency);
if (m_iTicks != ticks)
m_iTicks = ticks;
+21 -7
View File
@@ -45,6 +45,7 @@ char errbuf[PCAP_ERRBUF_SIZE];
int pcap_io_running = 0;
bool pcap_io_switched;
bool pcap_io_blocking;
extern u8 eeprom[];
@@ -83,7 +84,7 @@ bool PCAPGetWin32Adapter(const char* name, PIP_ADAPTER_ADDRESSES adapter, std::u
dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
DevCon.WriteLn("DEV9: New size %i", neededSize);
DWORD dwStatus = GetAdaptersAddresses(
dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
@@ -219,6 +220,14 @@ int pcap_io_init(char* adapter, bool switched, mac_address virtual_mac)
}
}
if (pcap_setnonblock(adhandle, 1, errbuf) == -1)
{
Console.Error("DEV9: Error setting non-blocking: %s", pcap_geterr(adhandle));
Console.Error("DEV9: Continuing in blocking mode");
pcap_io_blocking = true;
}
else
pcap_io_blocking = false;
dlt = pcap_datalink(adhandle);
dlt_name = (char*)pcap_datalink_val_to_name(dlt);
@@ -370,6 +379,12 @@ PCAPAdapter::PCAPAdapter()
host_mac = hostMAC;
ps2_mac = newMAC; //Needed outside of this class
if (pcap_io_init(config.Eth, config.EthApi == NetApi::PCAP_Switched, newMAC) == -1)
{
Console.Error("DEV9: Can't open Device '%s'", config.Eth);
return;
}
#ifdef _WIN32
IP_ADAPTER_ADDRESSES adapter;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> buffer;
@@ -394,15 +409,11 @@ PCAPAdapter::PCAPAdapter()
InitInternalServer(nullptr);
}
#endif
if (pcap_io_init(config.Eth, config.EthApi == NetApi::PCAP_Switched, newMAC) == -1)
{
Console.Error("Can't open Device '%s'\n", config.Eth);
}
}
bool PCAPAdapter::blocks()
{
return true;
pxAssert(pcap_io_running);
return pcap_io_blocking;
}
bool PCAPAdapter::isInitialised()
{
@@ -411,6 +422,9 @@ bool PCAPAdapter::isInitialised()
//gets a packet.rv :true success
bool PCAPAdapter::recv(NetPacket* pkt)
{
if (!pcap_io_blocking && NetAdapter::recv(pkt))
return true;
int size = pcap_io_recv(pkt->buffer, sizeof(pkt->buffer));
if (size > 0 && VerifyPkt(pkt, size))
{
+4 -3
View File
@@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include "AsyncFileReader.h"
#include "common/FileSystem.h"
// The aio module has been reported to cause issues with FreeBSD 10.3, so let's
// disable it for 10.3 and earlier and hope FreeBSD 11 and onwards is fine.
@@ -36,11 +37,11 @@ FlatFileReader::~FlatFileReader(void)
Close();
}
bool FlatFileReader::Open(const wxString& fileName)
bool FlatFileReader::Open(std::string fileName)
{
m_filename = fileName;
m_filename = std::move(fileName);
m_fd = wxOpen(fileName, O_RDONLY, 0);
m_fd = FileSystem::OpenFDFile(m_filename.c_str(), O_RDONLY, 0);
return (m_fd != -1);
}
+2 -1
View File
@@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include "Common.h"
#include "common/FileSystem.h"
#include "GS.h" // for sending game crc to mtgs
#include "Elfheader.h"
@@ -152,7 +153,7 @@ void ElfObject::readIso(IsoFile& file)
void ElfObject::readFile()
{
int rsize = 0;
FILE *f = wxFopen( filename, "rb" );
FILE *f = FileSystem::OpenCFile( filename.ToUTF8(), "rb" );
if (f == NULL) throw Exception::FileNotFound( filename );
fseek(f, 0, SEEK_SET);
+8 -93
View File
@@ -738,7 +738,10 @@ const std::string root_hw("/tmp/GS_HW_dump32/");
void* vmalloc(size_t size, bool code)
{
return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, code ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE);
void* ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, code ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE);
if (!ptr)
throw std::bad_alloc();
return ptr;
}
void vmfree(void* ptr, size_t size)
@@ -845,7 +848,10 @@ void* vmalloc(size_t size, bool code)
#endif
}
return mmap(NULL, size, prot, flags, -1, 0);
void* ptr = mmap(NULL, size, prot, flags, -1, 0);
if (ptr == MAP_FAILED)
throw std::bad_alloc();
return ptr;
}
void vmfree(void* ptr, size_t size)
@@ -906,91 +912,6 @@ void fifo_free(void* ptr, size_t size, size_t repeat)
#endif
static void* s_hModule;
#ifdef _WIN32
bool GSApp::LoadResource(int id, std::vector<char>& buff, const wchar_t* type)
{
buff.clear();
HRSRC hRsrc = FindResource((HMODULE)s_hModule, MAKEINTRESOURCE(id), type != NULL ? type : (LPWSTR)RT_RCDATA);
if (!hRsrc)
return false;
HGLOBAL hGlobal = ::LoadResource((HMODULE)s_hModule, hRsrc);
if (!hGlobal)
return false;
DWORD size = SizeofResource((HMODULE)s_hModule, hRsrc);
if (!size)
return false;
// On Linux resources are always NULL terminated
// Add + 1 on size to do the same for compatibility sake (required by GSDeviceOGL)
buff.resize(size + 1);
memcpy(buff.data(), LockResource(hGlobal), size);
return true;
}
#else
#include "GS_res.h"
bool GSApp::LoadResource(int id, std::vector<char>& buff, const char* type)
{
std::string path;
switch (id)
{
case IDR_COMMON_GLSL:
path = "/GS/res/glsl/common_header.glsl";
break;
case IDR_CONVERT_GLSL:
path = "/GS/res/glsl/convert.glsl";
break;
case IDR_FXAA_FX:
path = "/GS/res/fxaa.fx";
break;
case IDR_INTERLACE_GLSL:
path = "/GS/res/glsl/interlace.glsl";
break;
case IDR_MERGE_GLSL:
path = "/GS/res/glsl/merge.glsl";
break;
case IDR_SHADEBOOST_GLSL:
path = "/GS/res/glsl/shadeboost.glsl";
break;
case IDR_TFX_VGS_GLSL:
path = "/GS/res/glsl/tfx_vgs.glsl";
break;
case IDR_TFX_FS_GLSL:
path = "/GS/res/glsl/tfx_fs.glsl";
break;
case IDR_FONT_ROBOTO:
path = "/GS/res/fonts-roboto/Roboto-Regular.ttf";
break;
default:
printf("LoadResource not implemented for id %d\n", id);
return false;
}
GBytes* bytes = g_resource_lookup_data(GS_res_get_resource(), path.c_str(), G_RESOURCE_LOOKUP_FLAGS_NONE, nullptr);
size_t size = 0;
const void* data = g_bytes_get_data(bytes, &size);
if (data == nullptr || size == 0)
{
printf("Failed to get data for resource: %d\n", id);
return false;
}
buff.clear();
buff.resize(size + 1);
memcpy(buff.data(), data, size + 1);
g_bytes_unref(bytes);
return true;
}
#endif
size_t GSApp::GetIniString(const char* lpAppName, const char* lpKeyName, const char* lpDefault, char* lpReturnedString, size_t nSize, const char* lpFileName)
{
BuildConfigurationMap(lpFileName);
@@ -1213,7 +1134,6 @@ void GSApp::Init()
m_default_configuration["extrathreads"] = "2";
m_default_configuration["extrathreads_height"] = "4";
m_default_configuration["filter"] = std::to_string(static_cast<s8>(BiFiltering::PS2));
m_default_configuration["force_texture_clear"] = "0";
m_default_configuration["fxaa"] = "0";
m_default_configuration["interlace"] = "7";
m_default_configuration["conservative_framebuffer"] = "1";
@@ -1355,11 +1275,6 @@ void GSApp::BuildConfigurationMap(const char* lpFileName)
}
}
void* GSApp::GetModuleHandlePtr()
{
return s_hModule;
}
void GSApp::SetConfigDir()
{
// we need to initialize the ini folder later at runtime than at theApp init, as
-14
View File
@@ -149,14 +149,6 @@ public:
GSApp();
void Init();
void* GetModuleHandlePtr();
#ifdef _WIN32
HMODULE GetModuleHandle()
{
return (HMODULE)GetModuleHandlePtr();
}
#endif
void BuildConfigurationMap(const char* lpFileName);
void ReloadConfig();
@@ -165,12 +157,6 @@ public:
bool WriteIniString(const char* lpAppName, const char* lpKeyName, const char* pString, const char* lpFileName);
int GetIniInt(const char* lpAppName, const char* lpKeyName, int nDefault, const char* lpFileName);
#ifdef _WIN32
bool LoadResource(int id, std::vector<char>& buff, const wchar_t* type = nullptr);
#else
bool LoadResource(int id, std::vector<char>& buff, const char* type = nullptr);
#endif
void SetConfig(const char* entry, const char* value);
void SetConfig(const char* entry, int value);
// Avoid issue with overloading
-59
View File
@@ -44,54 +44,9 @@ BEGIN
"\0"
END
3 TEXTINCLUDE
BEGIN
"#include ""res/tfx.fx""\r\n"
"#include ""res/convert.fx""\r\n"
"#include ""res/interlace.fx""\r\n"
"#include ""res/merge.fx""\r\n"
"#include ""res/fxaa.fx""\r\n"
"#include ""res/shadeboost.fx""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// RCDATA
//
IDR_TFX_FX RCDATA "res\\tfx.fx"
IDR_CONVERT_FX RCDATA "res\\convert.fx"
IDR_INTERLACE_FX RCDATA "res\\interlace.fx"
IDR_MERGE_FX RCDATA "res\\merge.fx"
IDR_FXAA_FX RCDATA "res\\fxaa.fx"
IDR_SHADEBOOST_FX RCDATA "res\\shadeboost.fx"
IDR_CONVERT_GLSL RCDATA "res\\glsl\\convert.glsl";
IDR_INTERLACE_GLSL RCDATA "res\\glsl\\interlace.glsl";
IDR_MERGE_GLSL RCDATA "res\\glsl\\merge.glsl";
IDR_SHADEBOOST_GLSL RCDATA "res\\glsl\\shadeboost.glsl";
IDR_COMMON_GLSL RCDATA "res\\glsl\\common_header.glsl";
IDR_TFX_VGS_GLSL RCDATA "res\\glsl\\tfx_vgs.glsl";
IDR_TFX_FS_GLSL RCDATA "res\\glsl\\tfx_fs.glsl";
IDR_FONT_ROBOTO RCDATA "res\\fonts-roboto\\Roboto-Regular.ttf";
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
@@ -139,18 +94,4 @@ END
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "res/tfx.fx"
#include "res/convert.fx"
#include "res/interlace.fx"
#include "res/merge.fx"
#include "res/fxaa.fx"
#include "res/shadeboost.fx"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
// clang-format on
+11
View File
@@ -33,6 +33,17 @@ public:
_aligned_free(p);
}
void* operator new(size_t size, void* ptr)
{
return ptr;
}
void operator delete(void* ptr, void* placement_ptr)
{
// Just here to satisfy compilers
// Person who calls in-place placement new must handle error case
}
void* operator new[](size_t size)
{
return _aligned_malloc(size, i);
+4 -3
View File
@@ -148,16 +148,17 @@ bool GSClut::WriteTest(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
__assume(0);
}
return m_write.IsDirty(TEX0, TEXCLUT);
// CLUT only reloads if PSM is a valid index type, avoid unnecessary flushes
return ((TEX0.PSM & 0x7) >= 3) && m_write.IsDirty(TEX0, TEXCLUT);
}
void GSClut::Write(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
m_write.TEX0 = TEX0;
m_write.TEXCLUT = TEXCLUT;
m_write.dirty = false;
m_read.dirty = true;
m_write.dirty = false;
(this->*m_wc[TEX0.CSM][TEX0.CPSM][TEX0.PSM])(TEX0, TEXCLUT);
}
+4 -4
View File
@@ -56,7 +56,7 @@ static int findmax(int tl, int br, int limit, int wm, int minuv, int maxuv)
static int reduce(int uv, int size)
{
while (size > 3 && (1 << (size - 1)) >= uv + 1)
while (size > 3 && (1 << (size - 1)) >= uv)
{
size--;
}
@@ -66,7 +66,7 @@ static int reduce(int uv, int size)
static int extend(int uv, int size)
{
while (size < 10 && (1 << size) < uv + 1)
while (size < 10 && (1 << size) < uv)
{
size++;
}
@@ -99,7 +99,7 @@ GIFRegTEX0 GSDrawingContext::GetSizeFixedTEX0(const GSVector4& st, bool linear,
uvf += GSVector4(-0.5f, 0.5f).xxyy();
}
GSVector4i uv = GSVector4i(uvf.floor());
GSVector4i uv = GSVector4i(uvf.floor().xyzw(uvf.ceil()));
uv.x = findmax(uv.x, uv.z, (1 << tw) - 1, wms, minu, maxu);
uv.y = findmax(uv.y, uv.w, (1 << th) - 1, wmt, minv, maxv);
@@ -154,7 +154,7 @@ void GSDrawingContext::ComputeFixedTEX0(const GSVector4& st)
int maxu = (int)CLAMP.MAXU;
int maxv = (int)CLAMP.MAXV;
GSVector4i uv = GSVector4i(st.floor());
GSVector4i uv = GSVector4i(st.floor().xyzw(st.ceil()));
uv.x = findmax(uv.x, uv.z, (1 << TEX0.TW) - 1, wms, minu, maxu);
uv.y = findmax(uv.y, uv.w, (1 << TEX0.TH) - 1, wmt, minv, maxv);
+1 -1
View File
@@ -1733,7 +1733,7 @@ void GSLocalMemory::SaveBMP(const std::string& fn, u32 bp, u32 bw, u32 psm, int
}
}
GSTextureSW t(GSTexture::Offscreen, w, h);
GSTextureSW t(GSTexture::Type::Offscreen, w, h);
if (t.Update(GSVector4i(0, 0, w, h), bits, pitch))
{
+256
View File
@@ -0,0 +1,256 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "GSRingHeap.h"
#include "GS.h"
#include "GSExtra.h"
namespace
{
/// Align `value` to `align` bytes
template <size_t align>
size_t alignTo(size_t value)
{
return ((value + (align - 1)) / align) * align;
}
/// Align to a power of 2 using a mask that's equal to that value - 1
size_t alignUsingMask(size_t align_mask, size_t value)
{
return (value + align_mask) & ~align_mask;
}
} // namespace
/// GSRingHeap operates as a ring buffer, with usage counters for each quadrant
/// If a new quadrant needs to be used but is still in use by existing allocations,
/// the buffer is orphaned and a replaced with a new, larger buffer
struct GSRingHeap::Buffer
{
friend class GSRingHeap;
static const size_t BEGINNING_OFFSET;
static constexpr size_t USAGE_ARR_SIZE = sizeof(uint64_t) / sizeof(size_t);
static constexpr size_t USAGE_ARR_ELEMS_PER_ENTRY = sizeof(size_t) / sizeof(uint16_t);
/// Refcount, main heap holds onto buffer with a +1
/// Each allocation adds `sizeof(allocation)`, to allow for detection of buffers being used inefficiently
/// (e.g. if a buffer is orphaned with very little usage that means allocations aren't being freed in a similar order to being made)
/// Buffer is freed when the main heap drops it (-1) and every allocation is freed, causing this to reach 0
std::atomic<size_t> m_amt_allocated;
/// Holds 4x 16-bit usage counters, indicating how many allocations have been made from the nth quadrant of memory
/// Merged into `size_t` chunks so that they can be operated on with fewer atomic operations
std::atomic<size_t> m_usage[USAGE_ARR_SIZE];
/// Size of whole buffer (including header)
/// Should be kept to at least 2x the largest allocation
size_t m_size;
/// Offset of new allocations
size_t m_write_loc;
/// Amount to rshift buffer offset to get which quadrant it's in (`log2(m_size/4)`)
int m_quadrant_shift;
/// Increment usage counts (use when allocating)
void beginUse(uint64_t usage)
{
for (size_t i = 0; i < USAGE_ARR_SIZE; i++)
{
size_t piece = static_cast<size_t>(usage >> (i * (64 / USAGE_ARR_SIZE)));
size_t prev = m_usage[i].fetch_add(piece, std::memory_order_relaxed);
for (size_t j = 0; j < USAGE_ARR_ELEMS_PER_ENTRY; j++)
{
[[maybe_unused]] uint16_t section = prev >> (j * 16);
assert(section != UINT16_MAX && "Usage count overflow");
}
}
}
/// Decrement usage counts (use when freeing)
void endUse(uint64_t usage)
{
for (size_t i = 0; i < USAGE_ARR_SIZE; i++)
{
size_t piece = static_cast<size_t>(usage >> (i * (64 / USAGE_ARR_SIZE)));
m_usage[i].fetch_sub(piece, std::memory_order_release);
}
}
/// Check if the given quadrant is still in use
bool isStillInUse(uint32_t quadrant)
{
int arridx = (quadrant / USAGE_ARR_ELEMS_PER_ENTRY) % USAGE_ARR_SIZE;
int shift = (quadrant % USAGE_ARR_ELEMS_PER_ENTRY) * 16;
return ((m_usage[arridx].load(std::memory_order_acquire) >> shift) & 0xFFFF) != 0;
}
uint32_t quadrant(size_t off)
{
return static_cast<uint32_t>(off >> m_quadrant_shift);
}
/// Calculate a usage mask from an offset + size
uint64_t usageMask(size_t begin_off, size_t size)
{
// We guarantee size <= two quadrants
// Therefore we only need to check beginning, middle, and end
uint64_t mask = 0;
mask |= 1ull << (quadrant(begin_off) * 16);
size_t mid_off = begin_off + size / 2;
mask |= 1ull << (quadrant(mid_off) * 16);
size_t end_off = begin_off + size - 1;
mask |= 1ull << (quadrant(end_off) * 16);
return mask;
}
/// Decrement the main amt_allocated refcount
void decref(size_t amt)
{
if (unlikely(m_amt_allocated.fetch_sub(amt, std::memory_order_release) == amt))
{
std::atomic_thread_fence(std::memory_order_acquire);
vmfree(this, m_size);
}
}
/// Free an allocation
void free(void* allocation, size_t size)
{
const char* base = reinterpret_cast<const char*>(this);
size_t begin_off = static_cast<const char*>(allocation) - base;
endUse(usageMask(begin_off, size));
decref(size);
}
/// Allocate a value of `size` bytes with `prefix_size` bytes before it (for allocation tracking) and alignment specified by `align_mask`
void* alloc(size_t size, size_t align_mask, size_t prefix_size)
{
uint32_t prev_quadrant = quadrant(m_write_loc - 1);
size_t base_off = alignUsingMask(align_mask, m_write_loc + prefix_size);
uint64_t usage_mask = 1ull << (quadrant(base_off - prefix_size) * 16);
uint32_t new_quadrant = quadrant(base_off + size - 1);
if (prev_quadrant != new_quadrant)
{
uint32_t cur_quadrant = prev_quadrant + 1;
if (new_quadrant >= 4)
{
cur_quadrant = 0;
usage_mask = 0;
base_off = alignUsingMask(align_mask, BEGINNING_OFFSET + prefix_size);
new_quadrant = quadrant(base_off + size - 1);
}
do
{
usage_mask |= 1ull << (cur_quadrant * 16);
if (unlikely(isStillInUse(cur_quadrant)))
return nullptr;
} while (++cur_quadrant <= new_quadrant);
}
m_write_loc = base_off + size;
beginUse(usage_mask);
m_amt_allocated.fetch_add(size + prefix_size, std::memory_order_relaxed);
return reinterpret_cast<char*>(this) + base_off - prefix_size;
}
static Buffer* make(int quadrant_shift)
{
size_t size = 4ull << quadrant_shift;
Buffer* buffer = reinterpret_cast<Buffer*>(vmalloc(size, false));
buffer->m_size = size;
buffer->m_quadrant_shift = quadrant_shift;
buffer->m_amt_allocated.store(1, std::memory_order_relaxed);
for (std::atomic<size_t>& usage : buffer->m_usage)
usage.store(0, std::memory_order_relaxed);
buffer->m_write_loc = BEGINNING_OFFSET;
return buffer;
}
};
const size_t GSRingHeap::Buffer::BEGINNING_OFFSET = alignTo<64>(sizeof(Buffer));
constexpr size_t GSRingHeap::MIN_ALIGN;
GSRingHeap::GSRingHeap()
{
m_current_buffer = Buffer::make(14); // Start with 64k buffer
}
GSRingHeap::~GSRingHeap() noexcept
{
orphanBuffer();
}
void GSRingHeap::orphanBuffer() noexcept
{
m_current_buffer->decref(1);
}
void* GSRingHeap::alloc_internal(size_t size, size_t align_mask, size_t prefix_size)
{
prefix_size += sizeof(Buffer*); // Add space for a pointer to the buffer
size_t total_size = size + prefix_size;
if (likely(total_size <= (m_current_buffer->m_size / 2)))
{
if (void* ptr = m_current_buffer->alloc(size, align_mask, prefix_size))
{
Buffer** bptr = static_cast<Buffer**>(ptr);
*bptr = m_current_buffer;
return bptr + 1;
}
else if (IsDevBuild)
{
size_t total = m_current_buffer->m_size;
size_t mb = 1024 * 1024;
if (total >= mb)
{
size_t used = m_current_buffer->m_amt_allocated.load(std::memory_order_relaxed) - 1;
if (used * 4 < total)
{
fprintf(stderr, "GSRingHeap: Orphaning %dmb buffer with low usage of %d%%, check that allocations are actually being deallocated approximately in order\n", total / mb, static_cast<int>((used * 100) / total));
}
}
}
}
// Couldn't allocate, orphan buffer and make a new one
int shift = m_current_buffer->m_quadrant_shift;
do
{
shift++;
} while (total_size > (2ull << shift));
if (shift > 24 && total_size <= (2ull << (shift - 1)))
{
// If this needs to be >64 mb, we're doing something wrong
fprintf(stderr, "GSRingHeap: Refusing to grow to %umb\n", 4u << (shift - 20));
shift--;
}
Buffer* new_buffer = Buffer::make(shift);
orphanBuffer();
m_current_buffer = new_buffer;
void* ptr = m_current_buffer->alloc(size, align_mask, prefix_size);
assert(ptr && "Fresh buffer failed to allocate!");
Buffer** bptr = static_cast<Buffer**>(ptr);
*bptr = m_current_buffer;
return bptr + 1;
}
void GSRingHeap::free_internal(void* ptr, size_t size) noexcept
{
size += sizeof(Buffer*);
Buffer** bptr = static_cast<Buffer**>(ptr) - 1;
(*bptr)->free(bptr, size);
}
+282
View File
@@ -0,0 +1,282 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <algorithm>
#include <atomic>
#include <cstdint>
#include <cstdlib>
/// A ring buffer pretending to be a heap (screams if you don't actually use it like a ring buffer)
/// Meant for one producer thread creating data and sharing it with multiple consumer threads
/// Expectations:
/// - One thread allocates and writes to allocations
/// - Other threads read from allocations (once shared, no one writes)
/// - Any thread can free
/// - Frees are done in approximately the same order as allocations (but not exactly the same order)
class GSRingHeap
{
struct Buffer;
Buffer* m_current_buffer;
void orphanBuffer() noexcept;
/// Allocate a value of `size` bytes with `prefix_size` bytes before it (for allocation tracking) and alignment specified by `align_mask`
void* alloc_internal(size_t size, size_t align_mask, size_t prefix_size);
/// Free a value of size `size` (equal to prefix_size + size when allocated)
static void free_internal(void* ptr, size_t size) noexcept;
static constexpr size_t MIN_ALIGN = std::max(alignof(size_t), alignof(void*));
static size_t getAlignMask(size_t align)
{
return std::max(MIN_ALIGN, align) - 1;
}
public:
GSRingHeap(GSRingHeap&&) = delete;
GSRingHeap();
~GSRingHeap() noexcept;
/// Allocate a piece of memory with the given size and alignment
void* alloc(size_t size, size_t align)
{
size_t alloc_size = size + sizeof(size_t);
void* ptr = alloc_internal(size, getAlignMask(align), sizeof(size_t));
size_t* header = static_cast<size_t*>(ptr);
*header = alloc_size;
return static_cast<void*>(header + 1);
};
/// Allocate and initialize a T*
template <typename T, typename... Args>
T* make(Args&&... args)
{
std::unique_ptr<void, void(*)(void*)> ptr(alloc(sizeof(T), alignof(T)), GSRingHeap::free);
new (ptr.get()) T(std::forward<Args>(args)...);
return static_cast<T*>(ptr.release());
}
/// Allocate and default-initialize `count` `T`s
template <typename T>
T* make_array(size_t count)
{
std::unique_ptr<void, void(*)(void*)> ptr(alloc(sizeof(T) * count, alignof(T)), GSRingHeap::free);
new (ptr.get()) T[count]();
return static_cast<T*>(ptr.release());
}
/// Free a pointer allocated with `alloc`
static void free(void* ptr)
{
size_t* header = static_cast<size_t*>(ptr) - 1;
free_internal(static_cast<void*>(header), *header);
}
/// Deinitialize and free a pointer created with `make`
template <typename T>
static void destroy(T* ptr)
{
ptr->~T();
free(ptr);
}
/// Deinitialize and free an array allocated with `make_array`
template <typename T>
static void destroy_array(T* ptr)
{
size_t* header = const_cast<size_t*>(reinterpret_cast<const size_t*>(ptr)) - 1;
size_t size = (*header - sizeof(size_t)) / sizeof(T);
for (size_t i = 0; i < size; i++)
ptr[i].~T();
free(ptr);
}
/// Like `std::shared_ptr` but holds a pointer on this allocator
template <typename T>
class SharedPtr
{
friend class GSRingHeap;
struct alignas(MIN_ALIGN) AllocationHeader
{
uint32_t size;
std::atomic<uint32_t> refcnt;
};
T* m_ptr;
SharedPtr(T* ptr)
: m_ptr(ptr)
{
}
AllocationHeader* getHeader()
{
return const_cast<AllocationHeader*>(reinterpret_cast<const AllocationHeader*>(m_ptr)) - 1;
}
public:
SharedPtr()
: m_ptr(nullptr)
{
}
SharedPtr(std::nullptr_t)
: m_ptr(nullptr)
{
}
SharedPtr(const SharedPtr& other)
: m_ptr(other.m_ptr)
{
if (m_ptr)
getHeader()->refcnt.fetch_add(1, std::memory_order_relaxed);
}
SharedPtr(SharedPtr&& other)
: m_ptr(other.m_ptr)
{
other.m_ptr = nullptr;
}
SharedPtr& operator=(const SharedPtr& other)
{
this->~SharedPtr();
new (this) SharedPtr(other);
return *this;
}
SharedPtr& operator=(SharedPtr&& other)
{
this->~SharedPtr();
new (this) SharedPtr(other);
return *this;
}
~SharedPtr()
{
if (!m_ptr)
return;
AllocationHeader* header = getHeader();
// (See top) Expectation: Once shared, no one writes
// Therefore we don't need acquire/release semantics here
if (header->refcnt.fetch_sub(1, std::memory_order_relaxed) == 1)
{
m_ptr->~T();
free_internal(static_cast<void*>(header), header->size);
}
}
T& operator*() const { return *m_ptr; }
T* operator->() const { return m_ptr; }
T* get() const { return m_ptr; }
/// static_cast the pointer to another type
template <typename Other>
SharedPtr<Other> cast() const&
{
getHeader().refcount.fetch_add(1, std::memory_order_relaxed);
return SharedPtr<Other>(static_cast<Other*>(m_ptr));
}
/// static_cast the pointer to another type
template <typename Other>
SharedPtr<Other> cast() &&
{
SharedPtr<Other> other(static_cast<Other*>(m_ptr));
m_ptr = nullptr;
return other;
}
};
/// Make a shared pointer with a different alignment from what the type would normally expect
template <typename T, typename... Args>
SharedPtr<T> make_shared(Args&&... args)
{
using Header = typename SharedPtr<T>::AllocationHeader;
static constexpr size_t alloc_size = sizeof(T) + sizeof(Header);
static_assert(alignof(Header) <= MIN_ALIGN, "Header alignment too high");
static_assert(alloc_size <= UINT32_MAX, "Allocation overflow");
void* ptr = alloc_internal(sizeof(T), getAlignMask(alignof(T)), sizeof(Header));
std::unique_ptr<void, void(*)(void*)> guard(ptr, [](void* p){ free_internal(p, alloc_size); });
Header* header = static_cast<Header*>(ptr);
header->size = static_cast<uint32_t>(alloc_size);
header->refcnt.store(1, std::memory_order_relaxed);
T* tptr = reinterpret_cast<T*>(header + 1);
new (tptr) T(std::forward<Args>(args)...);
guard.release();
return SharedPtr<T>(tptr);
}
template <typename T>
struct Deleter
{
void operator()(T* t)
{
if (t)
destroy(t);
}
};
template <typename T>
struct Deleter<T[]>
{
void operator()(T* t)
{
if (t)
destroy_array(t);
}
};
template <typename T>
using UniquePtr = std::unique_ptr<T, Deleter<T>>;
template <typename T>
struct _unique_if
{
typedef UniquePtr<T> _unique_single;
};
template <typename T>
struct _unique_if<T[]>
{
typedef UniquePtr<T[]> _unique_array_unknown_bound;
};
template <typename T, size_t N>
struct _unique_if<T[N]>
{
typedef void _unique_array_known_bound;
};
template <typename T, typename... Args>
typename _unique_if<T>::_unique_single make_unique(Args&&... args)
{
return UniquePtr<T>(make<T>(std::forward<Args>(args)...));
}
template <typename T>
typename _unique_if<T>::_unique_array_unknown_bound make_unique(size_t count)
{
typedef typename std::remove_extent<T>::type Base;
return UniquePtr<T>(make_array<Base>(count));
}
template <class T, class... _Args>
typename _unique_if<T>::_unique_array_known_bound make_unique(_Args&&...) = delete;
};
+21 -4
View File
@@ -722,7 +722,13 @@ __forceinline void GSState::ApplyPRIM(u32 prim)
{
if (GSUtil::GetPrimClass(m_env.PRIM.PRIM) == GSUtil::GetPrimClass(prim & 7)) // NOTE: assume strips/fans are converted to lists
{
if (m_env.PRMODECONT.AC == 1 && (m_env.PRIM.U32[0] ^ prim) & 0x7f8) // all fields except PRIM
u32 prim_mask = 0x7f8;
const bool is_hardware_renderer =
((theApp.GetCurrentRendererType() == GSRendererType::OGL_HW) || (theApp.GetCurrentRendererType() == GSRendererType::DX1011_HW));
if (is_hardware_renderer && GSUtil::GetPrimClass(prim & 7) == GS_TRIANGLE_CLASS)
prim_mask &= ~0x80; // Mask out AA1.
if (m_env.PRMODECONT.AC == 1 && (m_env.PRIM.U32[0] ^ prim) & prim_mask) // all fields except PRIM
Flush();
}
else
@@ -1055,7 +1061,13 @@ void GSState::GIFRegHandlerPRMODE(const GIFReg* RESTRICT r)
if (!m_env.PRMODECONT.AC)
{
if ((m_env.PRIM.U32[0] ^ r->PRMODE.U32[0]) & 0x7f8)
u32 prim_mask = 0x7f8;
const bool is_hardware_renderer =
((theApp.GetCurrentRendererType() == GSRendererType::OGL_HW) || (theApp.GetCurrentRendererType() == GSRendererType::DX1011_HW));
if (is_hardware_renderer && GSUtil::GetPrimClass(m_env.PRIM.PRIM) == GS_TRIANGLE_CLASS)
prim_mask &= ~0x80; // Mask out AA1.
if ((m_env.PRIM.U32[0] ^ r->PRMODE.U32[0]) & prim_mask)
Flush();
}
else
@@ -2534,8 +2546,13 @@ __forceinline void GSState::VertexKick(u32 skip)
__assume(0);
}
if (auto_flush && PRIM->TME && (m_context->FRAME.Block() == m_context->TEX0.TBP0))
FlushPrim();
if (m_context->FRAME.FBMSK != 0xFFFFFFFF)
{
m_mem.m_clut.Invalidate(m_context->FRAME.Block());
if (auto_flush && PRIM->TME && (m_context->FRAME.Block() == m_context->TEX0.TBP0))
FlushPrim();
}
}
void GSState::GetTextureMinMax(GSVector4i& r, const GIFRegTEX0& TEX0, const GIFRegCLAMP& CLAMP, bool linear)
+134 -62
View File
@@ -18,6 +18,36 @@
#include "GS/GSGL.h"
#include "GS/GS.h"
const char* shaderName(ShaderConvert value)
{
switch (value)
{
case ShaderConvert::COPY: return "ps_copy";
case ShaderConvert::RGBA8_TO_16_BITS: return "ps_convert_rgba8_16bits";
case ShaderConvert::DATM_1: return "ps_datm1";
case ShaderConvert::DATM_0: return "ps_datm0";
case ShaderConvert::MOD_256: return "ps_mod256";
case ShaderConvert::SCANLINE: return "ps_filter_scanlines";
case ShaderConvert::DIAGONAL_FILTER: return "ps_filter_diagonal";
case ShaderConvert::TRANSPARENCY_FILTER: return "ps_filter_transparency";
case ShaderConvert::TRIANGULAR_FILTER: return "ps_filter_triangular";
case ShaderConvert::COMPLEX_FILTER: return "ps_filter_complex";
case ShaderConvert::FLOAT32_TO_32_BITS: return "ps_convert_float32_32bits";
case ShaderConvert::FLOAT32_TO_RGBA8: return "ps_convert_float32_rgba8";
case ShaderConvert::FLOAT16_TO_RGB5A1: return "ps_convert_float16_rgb5a1";
case ShaderConvert::RGBA8_TO_FLOAT32: return "ps_convert_rgba8_float32";
case ShaderConvert::RGBA8_TO_FLOAT24: return "ps_convert_rgba8_float24";
case ShaderConvert::RGBA8_TO_FLOAT16: return "ps_convert_rgba8_float16";
case ShaderConvert::RGB5A1_TO_FLOAT16: return "ps_convert_rgb5a1_float16";
case ShaderConvert::RGBA_TO_8I: return "ps_convert_rgba_8i";
case ShaderConvert::YUV: return "ps_yuv";
case ShaderConvert::OSD: return "ps_osd";
default:
ASSERT(0);
return "ShaderConvertUnknownShader";
}
}
GSDevice::GSDevice()
: m_vsync(false)
, m_rbswapped(false)
@@ -36,9 +66,7 @@ GSDevice::GSDevice()
GSDevice::~GSDevice()
{
for (auto t : m_pool)
delete t;
PurgePool();
delete m_backbuffer;
delete m_merge;
delete m_weavebob;
@@ -53,10 +81,7 @@ bool GSDevice::Create(const WindowInfo& wi)
bool GSDevice::Reset(int w, int h)
{
for (auto t : m_pool)
delete t;
m_pool.clear();
PurgePool();
delete m_backbuffer;
delete m_merge;
@@ -64,13 +89,13 @@ bool GSDevice::Reset(int w, int h)
delete m_blend;
delete m_target_tmp;
m_backbuffer = NULL;
m_merge = NULL;
m_weavebob = NULL;
m_blend = NULL;
m_target_tmp = NULL;
m_backbuffer = nullptr;
m_merge = nullptr;
m_weavebob = nullptr;
m_blend = nullptr;
m_target_tmp = nullptr;
m_current = NULL; // current is special, points to other textures, no need to delete
m_current = nullptr; // current is special, points to other textures, no need to delete
return true;
}
@@ -89,9 +114,9 @@ void GSDevice::Present(const GSVector4i& r, int shader)
if (m_current)
{
static int s_shader[5] = {ShaderConvert_COPY, ShaderConvert_SCANLINE,
ShaderConvert_DIAGONAL_FILTER, ShaderConvert_TRIANGULAR_FILTER,
ShaderConvert_COMPLEX_FILTER}; // FIXME
static constexpr ShaderConvert s_shader[5] = {ShaderConvert::COPY, ShaderConvert::SCANLINE,
ShaderConvert::DIAGONAL_FILTER, ShaderConvert::TRIANGULAR_FILTER,
ShaderConvert::COMPLEX_FILTER}; // FIXME
Present(m_current, m_backbuffer, GSVector4(r), s_shader[shader]);
RenderOsd(m_backbuffer);
@@ -100,28 +125,53 @@ void GSDevice::Present(const GSVector4i& r, int shader)
Flip();
}
void GSDevice::Present(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, int shader)
void GSDevice::Present(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader)
{
StretchRect(sTex, dTex, dRect, shader, m_linear_present);
}
GSTexture* GSDevice::FetchSurface(int type, int w, int h, int format)
GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format)
{
const GSVector2i size(w, h);
GSTexture* t = nullptr;
for (auto i = m_pool.begin(); i != m_pool.end(); ++i)
{
GSTexture* t = *i;
t = *i;
assert(t);
if (t->GetType() == type && t->GetFormat() == format && t->GetSize() == size)
{
m_pool.erase(i);
return t;
break;
}
t = nullptr;
}
return CreateSurface(type, w, h, format);
if (!t)
t = CreateSurface(type, w, h, format);
if (!t)
throw std::bad_alloc();
t->Commit(); // Clear won't be done if the texture isn't committed.
switch (type)
{
case GSTexture::Type::RenderTarget:
ClearRenderTarget(t, 0);
break;
case GSTexture::Type::DepthStencil:
ClearDepth(t);
break;
default:
break;
}
return t;
}
void GSDevice::PrintMemoryUsage()
@@ -184,46 +234,67 @@ void GSDevice::AgePool()
void GSDevice::PurgePool()
{
// OOM emergency. Let's free this useless pool
while (!m_pool.empty())
{
delete m_pool.back();
m_pool.pop_back();
}
for (auto t : m_pool)
delete t;
m_pool.clear();
}
GSTexture* GSDevice::CreateSparseRenderTarget(int w, int h, int format)
GSTexture* GSDevice::CreateSparseRenderTarget(int w, int h, GSTexture::Format format)
{
return FetchSurface(HasColorSparse() ? GSTexture::SparseRenderTarget : GSTexture::RenderTarget, w, h, format);
return FetchSurface(HasColorSparse() ? GSTexture::Type::SparseRenderTarget : GSTexture::Type::RenderTarget, w, h, format);
}
GSTexture* GSDevice::CreateSparseDepthStencil(int w, int h, int format)
GSTexture* GSDevice::CreateSparseDepthStencil(int w, int h, GSTexture::Format format)
{
return FetchSurface(HasDepthSparse() ? GSTexture::SparseDepthStencil : GSTexture::DepthStencil, w, h, format);
return FetchSurface(HasDepthSparse() ? GSTexture::Type::SparseDepthStencil : GSTexture::Type::DepthStencil, w, h, format);
}
GSTexture* GSDevice::CreateRenderTarget(int w, int h, int format)
GSTexture* GSDevice::CreateRenderTarget(int w, int h, GSTexture::Format format)
{
return FetchSurface(GSTexture::RenderTarget, w, h, format);
return FetchSurface(GSTexture::Type::RenderTarget, w, h, format);
}
GSTexture* GSDevice::CreateDepthStencil(int w, int h, int format)
GSTexture* GSDevice::CreateDepthStencil(int w, int h, GSTexture::Format format)
{
return FetchSurface(GSTexture::DepthStencil, w, h, format);
return FetchSurface(GSTexture::Type::DepthStencil, w, h, format);
}
GSTexture* GSDevice::CreateTexture(int w, int h, int format)
GSTexture* GSDevice::CreateTexture(int w, int h, GSTexture::Format format)
{
return FetchSurface(GSTexture::Texture, w, h, format);
return FetchSurface(GSTexture::Type::Texture, w, h, format);
}
GSTexture* GSDevice::CreateOffscreen(int w, int h, int format)
GSTexture* GSDevice::CreateOffscreen(int w, int h, GSTexture::Format format)
{
return FetchSurface(GSTexture::Offscreen, w, h, format);
return FetchSurface(GSTexture::Type::Offscreen, w, h, format);
}
void GSDevice::StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, int shader, bool linear)
GSTexture::Format GSDevice::GetDefaultTextureFormat(GSTexture::Type type)
{
if (type == GSTexture::Type::DepthStencil || type == GSTexture::Type::SparseDepthStencil)
return GSTexture::Format::DepthStencil;
else
return GSTexture::Format::Color;
}
bool GSDevice::DownloadTextureConvert(GSTexture* src, const GSVector4& sRect, const GSVector2i& dSize, GSTexture::Format format, ShaderConvert ps_shader, GSTexture::GSMap& out_map, const bool linear)
{
ASSERT(src);
ASSERT(format == GSTexture::Format::Color || format == GSTexture::Format::UInt16 || format == GSTexture::Format::UInt32);
GSTexture* dst = CreateRenderTarget(dSize.x, dSize.y, format);
if (!dst)
return false;
GSVector4i dRect(0, 0, dSize.x, dSize.y);
StretchRect(src, sRect, dst, GSVector4(dRect), ps_shader, linear);
bool ret = DownloadTexture(dst, dRect, out_map);
Recycle(dst);
return ret;
}
void GSDevice::StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
{
StretchRect(sTex, GSVector4(0, 0, 1, 1), dTex, dRect, shader, linear);
}
@@ -315,7 +386,7 @@ void GSDevice::ExternalFX()
const GSVector4 sRect(0, 0, 1, 1);
const GSVector4 dRect(0, 0, s.x, s.y);
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert_TRANSPARENCY_FILTER, false);
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert::TRANSPARENCY_FILTER, false);
DoExternalFX(m_target_tmp, m_current);
}
}
@@ -329,7 +400,7 @@ void GSDevice::FXAA()
const GSVector4 sRect(0, 0, 1, 1);
const GSVector4 dRect(0, 0, s.x, s.y);
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert_TRANSPARENCY_FILTER, false);
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert::TRANSPARENCY_FILTER, false);
DoFXAA(m_target_tmp, m_current);
}
}
@@ -343,12 +414,12 @@ void GSDevice::ShadeBoost()
const GSVector4 sRect(0, 0, 1, 1);
const GSVector4 dRect(0, 0, s.x, s.y);
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert_COPY, false);
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert::COPY, false);
DoShadeBoost(m_target_tmp, m_current);
}
}
bool GSDevice::ResizeTexture(GSTexture** t, int type, int w, int h)
bool GSDevice::ResizeTexture(GSTexture** t, GSTexture::Type type, int w, int h)
{
if (t == NULL)
{
@@ -360,9 +431,10 @@ bool GSDevice::ResizeTexture(GSTexture** t, int type, int w, int h)
if (t2 == NULL || t2->GetWidth() != w || t2->GetHeight() != h)
{
GSTexture::Format fmt = t2 ? t2->GetFormat() : GetDefaultTextureFormat(type);
delete t2;
t2 = FetchSurface(type, w, h, 0);
t2 = FetchSurface(type, w, h, fmt);
*t = t2;
}
@@ -372,18 +444,18 @@ bool GSDevice::ResizeTexture(GSTexture** t, int type, int w, int h)
bool GSDevice::ResizeTexture(GSTexture** t, int w, int h)
{
return ResizeTexture(t, GSTexture::Texture, w, h);
return ResizeTexture(t, GSTexture::Type::Texture, w, h);
}
bool GSDevice::ResizeTarget(GSTexture** t, int w, int h)
{
return ResizeTexture(t, GSTexture::RenderTarget, w, h);
return ResizeTexture(t, GSTexture::Type::RenderTarget, w, h);
}
bool GSDevice::ResizeTarget(GSTexture** t)
{
GSVector2i s = m_current->GetSize();
return ResizeTexture(t, GSTexture::RenderTarget, s.x, s.y);
return ResizeTexture(t, GSTexture::Type::RenderTarget, s.x, s.y);
}
GSAdapter::operator std::string() const
@@ -438,15 +510,15 @@ std::array<HWBlend, 3*3*3*3 + 1> GSDevice::m_blendMap =
{ BLEND_NO_REC , OP_ADD , CONST_ONE , CONST_ZERO} , // 0020: (Cs - Cs)*F + Cs ==> Cs
{ 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 0021: (Cs - Cs)*F + Cd ==> Cd
{ BLEND_NO_REC , OP_ADD , CONST_ZERO , CONST_ZERO} , // 0022: (Cs - Cs)*F + 0 ==> 0
{ BLEND_A_MAX , OP_SUBTRACT , CONST_ONE , SRC1_ALPHA} , //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As
{ 0 , OP_ADD , SRC1_ALPHA , INV_SRC1_ALPHA} , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As)
{ 0 , OP_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As
{ BLEND_A_MAX | BLEND_MIX2 , OP_SUBTRACT , CONST_ONE , SRC1_ALPHA} , //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As
{ BLEND_MIX1 , OP_ADD , SRC1_ALPHA , INV_SRC1_ALPHA} , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As)
{ BLEND_MIX1 , OP_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As
{ BLEND_A_MAX , OP_SUBTRACT , CONST_ONE , DST_ALPHA} , //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad
{ 0 , OP_ADD , DST_ALPHA , INV_DST_ALPHA} , // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad)
{ 0 , OP_SUBTRACT , DST_ALPHA , DST_ALPHA} , // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad
{ BLEND_A_MAX , OP_SUBTRACT , CONST_ONE , CONST_COLOR} , //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F
{ 0 , OP_ADD , CONST_COLOR , INV_CONST_COLOR} , // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F)
{ 0 , OP_SUBTRACT , CONST_COLOR , CONST_COLOR} , // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F
{ BLEND_A_MAX | BLEND_MIX2 , OP_SUBTRACT , CONST_ONE , CONST_COLOR} , //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F
{ BLEND_MIX1 , OP_ADD , CONST_COLOR , INV_CONST_COLOR} , // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F)
{ BLEND_MIX1 , OP_SUBTRACT , CONST_COLOR , CONST_COLOR} , // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F
{ BLEND_NO_REC | BLEND_A_MAX , OP_ADD , CONST_ONE , CONST_ZERO} , //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1)
{ BLEND_ACCU , OP_ADD , SRC1_ALPHA , CONST_ONE} , //?0201: (Cs - 0)*As + Cd ==> Cs*As + Cd
{ BLEND_NO_REC , OP_ADD , SRC1_ALPHA , CONST_ZERO} , // 0202: (Cs - 0)*As + 0 ==> Cs*As
@@ -456,15 +528,15 @@ std::array<HWBlend, 3*3*3*3 + 1> GSDevice::m_blendMap =
{ BLEND_NO_REC | BLEND_A_MAX , OP_ADD , CONST_ONE , CONST_ZERO} , //*0220: (Cs - 0)*F + Cs ==> Cs*(F + 1)
{ BLEND_ACCU , OP_ADD , CONST_COLOR , CONST_ONE} , //?0221: (Cs - 0)*F + Cd ==> Cs*F + Cd
{ BLEND_NO_REC , OP_ADD , CONST_COLOR , CONST_ZERO} , // 0222: (Cs - 0)*F + 0 ==> Cs*F
{ 0 , OP_ADD , INV_SRC1_ALPHA , SRC1_ALPHA} , // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As)
{ BLEND_A_MAX , OP_REV_SUBTRACT , SRC1_ALPHA , CONST_ONE} , //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As
{ 0 , OP_REV_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As
{ BLEND_MIX3 , OP_ADD , INV_SRC1_ALPHA , SRC1_ALPHA} , // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As)
{ BLEND_A_MAX | BLEND_MIX1 , OP_REV_SUBTRACT , SRC1_ALPHA , CONST_ONE} , //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As
{ BLEND_MIX1 , OP_REV_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As
{ 0 , OP_ADD , INV_DST_ALPHA , DST_ALPHA} , // 1010: (Cd - Cs)*Ad + Cs ==> Cd*Ad + Cs*(1 - Ad)
{ BLEND_A_MAX , OP_REV_SUBTRACT , DST_ALPHA , CONST_ONE} , //*1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad
{ 0 , OP_REV_SUBTRACT , DST_ALPHA , DST_ALPHA} , // 1012: (Cd - Cs)*Ad + 0 ==> Cd*Ad - Cs*Ad
{ 0 , OP_ADD , INV_CONST_COLOR , CONST_COLOR} , // 1020: (Cd - Cs)*F + Cs ==> Cd*F + Cs*(1 - F)
{ BLEND_A_MAX , OP_REV_SUBTRACT , CONST_COLOR , CONST_ONE} , //*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F
{ 0 , OP_REV_SUBTRACT , CONST_COLOR , CONST_COLOR} , // 1022: (Cd - Cs)*F + 0 ==> Cd*F - Cs*F
{ BLEND_MIX3 , OP_ADD , INV_CONST_COLOR , CONST_COLOR} , // 1020: (Cd - Cs)*F + Cs ==> Cd*F + Cs*(1 - F)
{ BLEND_A_MAX | BLEND_MIX1 , OP_REV_SUBTRACT , CONST_COLOR , CONST_ONE} , //*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F
{ BLEND_MIX1 , OP_REV_SUBTRACT , CONST_COLOR , CONST_COLOR} , // 1022: (Cd - Cs)*F + 0 ==> Cd*F - Cs*F
{ BLEND_NO_REC , OP_ADD , CONST_ONE , CONST_ZERO} , // 1100: (Cd - Cd)*As + Cs ==> Cs
{ 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 1101: (Cd - Cd)*As + Cd ==> Cd
{ BLEND_NO_REC , OP_ADD , CONST_ZERO , CONST_ZERO} , // 1102: (Cd - Cd)*As + 0 ==> 0
+52 -42
View File
@@ -26,31 +26,35 @@
#include <dxgi.h>
#endif
enum ShaderConvert
enum class ShaderConvert
{
ShaderConvert_COPY = 0,
ShaderConvert_RGBA8_TO_16_BITS,
ShaderConvert_DATM_1,
ShaderConvert_DATM_0,
ShaderConvert_MOD_256,
ShaderConvert_SCANLINE = 5,
ShaderConvert_DIAGONAL_FILTER,
ShaderConvert_TRANSPARENCY_FILTER,
ShaderConvert_TRIANGULAR_FILTER,
ShaderConvert_COMPLEX_FILTER,
ShaderConvert_FLOAT32_TO_32_BITS = 10,
ShaderConvert_FLOAT32_TO_RGBA8,
ShaderConvert_FLOAT16_TO_RGB5A1,
ShaderConvert_RGBA8_TO_FLOAT32 = 13,
ShaderConvert_RGBA8_TO_FLOAT24,
ShaderConvert_RGBA8_TO_FLOAT16,
ShaderConvert_RGB5A1_TO_FLOAT16,
ShaderConvert_RGBA_TO_8I = 17,
ShaderConvert_YUV,
ShaderConvert_OSD,
ShaderConvert_Count
COPY = 0,
RGBA8_TO_16_BITS,
DATM_1,
DATM_0,
MOD_256,
SCANLINE = 5,
DIAGONAL_FILTER,
TRANSPARENCY_FILTER,
TRIANGULAR_FILTER,
COMPLEX_FILTER,
FLOAT32_TO_32_BITS = 10,
FLOAT32_TO_RGBA8,
FLOAT16_TO_RGB5A1,
RGBA8_TO_FLOAT32 = 13,
RGBA8_TO_FLOAT24,
RGBA8_TO_FLOAT16,
RGB5A1_TO_FLOAT16,
RGBA_TO_8I = 17,
YUV,
OSD,
Count
};
/// Get the name of a shader
/// (Can't put methods on an enum class)
const char* shaderName(ShaderConvert value);
enum ChannelFetch
{
ChannelFetch_NONE = 0,
@@ -115,6 +119,9 @@ public:
enum HWBlendFlags
{
// A couple of flag to determine the blending behavior
BLEND_MIX1 = 0x20, // Mix of hw and sw, do Cs*F or Cs*As in shader
BLEND_MIX2 = 0x40, // Mix of hw and sw, do Cs*(As + 1) or Cs*(F + 1) in shader
BLEND_MIX3 = 0x80, // Mix of hw and sw, do Cs*(1 - As) or Cs*(1 - F) in shader
BLEND_A_MAX = 0x100, // Impossible blending uses coeff bigger than 1
BLEND_C_CLR = 0x200, // Clear color blending (use directly the destination color as blending factor)
BLEND_NO_REC = 0x400, // Doesn't require sampling of the RT as a texture
@@ -168,8 +175,8 @@ protected:
unsigned int m_frame; // for ageing the pool
bool m_linear_present;
virtual GSTexture* CreateSurface(int type, int w, int h, int format) = 0;
virtual GSTexture* FetchSurface(int type, int w, int h, int format);
virtual GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) = 0;
virtual GSTexture* FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format);
virtual void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) = 0;
virtual void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset) = 0;
@@ -197,15 +204,12 @@ public:
virtual bool Reset(int w, int h);
virtual bool IsLost(bool update = false) { return false; }
virtual void Present(const GSVector4i& r, int shader);
virtual void Present(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, int shader = 0);
virtual void Present(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY);
virtual void Flip() {}
virtual void SetVSync(int vsync) { m_vsync = vsync; }
virtual void BeginScene() {}
virtual void DrawPrimitive() {};
virtual void DrawIndexedPrimitive() {}
virtual void DrawIndexedPrimitive(int offset, int count) {}
virtual void EndScene();
virtual bool HasDepthSparse() { return false; }
@@ -216,24 +220,30 @@ public:
virtual void ClearDepth(GSTexture* t) {}
virtual void ClearStencil(GSTexture* t, u8 c) {}
GSTexture* CreateSparseRenderTarget(int w, int h, int format = 0);
GSTexture* CreateSparseDepthStencil(int w, int h, int format = 0);
GSTexture* CreateRenderTarget(int w, int h, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, int format = 0);
GSTexture* CreateTexture(int w, int h, int format = 0);
GSTexture* CreateOffscreen(int w, int h, int format = 0);
GSTexture* CreateSparseRenderTarget(int w, int h, GSTexture::Format format);
GSTexture* CreateSparseDepthStencil(int w, int h, GSTexture::Format format);
GSTexture* CreateRenderTarget(int w, int h, GSTexture::Format format);
GSTexture* CreateDepthStencil(int w, int h, GSTexture::Format format);
GSTexture* CreateTexture(int w, int h, GSTexture::Format format);
GSTexture* CreateOffscreen(int w, int h, GSTexture::Format format);
GSTexture::Format GetDefaultTextureFormat(GSTexture::Type type);
virtual GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sRect, int w, int h, int format = 0, int ps_shader = 0) { return NULL; }
/// Download the region `rect` of `src` into `out_map`
/// `out_map` will be valid a call to `DownloadTextureComplete`
virtual bool DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTexture::GSMap& out_map) { return false; }
/// Scale the region `sRect` of `src` to the size `dSize` using `ps_shader` and store the result in `out_map`
/// `out_map` will be valid a call to `DownloadTextureComplete`
virtual bool DownloadTextureConvert(GSTexture* src, const GSVector4& sRect, const GSVector2i& dSize, GSTexture::Format format, ShaderConvert ps_shader, GSTexture::GSMap& out_map, bool linear);
/// Must be called to free resources after calling `DownloadTexture` or `DownloadTextureConvert`
virtual void DownloadTextureComplete() {}
virtual void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r) {}
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, int shader = 0, bool linear = true) {}
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) {}
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha) {}
void StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, int shader = 0, bool linear = true);
virtual void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) {}
virtual void PSSetShaderResource(int i, GSTexture* sRect) {}
virtual void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL) {}
void StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true);
GSTexture* GetCurrent();
@@ -244,7 +254,7 @@ public:
void ExternalFX();
virtual void RenderOsd(GSTexture* dt) {};
bool ResizeTexture(GSTexture** t, int type, int w, int h);
bool ResizeTexture(GSTexture** t, GSTexture::Type type, int w, int h);
bool ResizeTexture(GSTexture** t, int w, int h);
bool ResizeTarget(GSTexture** t, int w, int h);
bool ResizeTarget(GSTexture** t);
+7 -5
View File
@@ -16,9 +16,7 @@
#include "PrecompiledHeader.h"
#include "GSOsdManager.h"
#include "GS/GS.h"
#ifdef _WIN32
#include "GS/resource.h"
#endif
#include "Host.h"
#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 4)
#include <codecvt>
@@ -31,8 +29,12 @@ void GSOsdManager::LoadFont()
if (error)
{
FT_Error error_load_res = 1;
if (theApp.LoadResource(IDR_FONT_ROBOTO, resource_data_buffer))
error_load_res = FT_New_Memory_Face(m_library, (const FT_Byte*)resource_data_buffer.data(), resource_data_buffer.size(), 0, &m_face);
auto buffer = Host::ReadResourceFile("fonts/Roboto-Regular.ttf");
if (buffer.has_value())
{
resource_data_buffer = std::move(*buffer);
error_load_res = FT_New_Memory_Face(m_library, resource_data_buffer.data(), resource_data_buffer.size(), 0, &m_face);
}
if (error_load_res)
{
+1 -1
View File
@@ -94,5 +94,5 @@ public:
size_t GeneratePrimitives(GSVertexPT1* dst, size_t count);
private:
std::vector<char> resource_data_buffer;
std::vector<u8> resource_data_buffer;
};
+10 -11
View File
@@ -512,18 +512,17 @@ void GSRenderer::VSync(int field)
{
GSVector2i size = m_capture.GetSize();
if (GSTexture* offscreen = m_dev->CopyOffscreen(current, GSVector4(0, 0, 1, 1), size.x, size.y))
bool res;
GSTexture::GSMap m;
if (size == current->GetSize())
res = m_dev->DownloadTexture(current, GSVector4i(0, 0, size.x, size.y), m);
else
res = m_dev->DownloadTextureConvert(current, GSVector4(0, 0, 1, 1), size, GSTexture::Format::Color, ShaderConvert::COPY, m, true);
if (res)
{
GSTexture::GSMap m;
if (offscreen->Map(m))
{
m_capture.DeliverFrame(m.bits, m.pitch, !m_dev->IsRBSwapped());
offscreen->Unmap();
}
m_dev->Recycle(offscreen);
m_capture.DeliverFrame(m.bits, m.pitch, !m_dev->IsRBSwapped());
m_dev->DownloadTextureComplete();
}
}
}
+1
View File
@@ -60,6 +60,7 @@ public:
virtual bool CanUpscale() { return false; }
virtual int GetUpscaleMultiplier() { return 1; }
virtual GSVector2i GetCustomResolution() { return GSVector2i(0, 0); }
virtual GSVector2 GetTextureScaleFactor() { return { 1.0f, 1.0f }; }
GSVector2i GetInternalResolution();
void SetVSync(int vsync);
+2 -2
View File
@@ -22,8 +22,8 @@ GSTexture::GSTexture()
, m_size(0, 0)
, m_committed_size(0, 0)
, m_gpu_page_size(0, 0)
, m_type(0)
, m_format(0)
, m_type(Type::Invalid)
, m_format(Format::Invalid)
, m_sparse(false)
, last_frame_used(0)
, LikelyOffset(false)
+27 -13
View File
@@ -19,15 +19,6 @@
class GSTexture
{
protected:
GSVector2 m_scale;
GSVector2i m_size;
GSVector2i m_committed_size;
GSVector2i m_gpu_page_size;
int m_type;
int m_format;
bool m_sparse;
public:
struct GSMap
{
@@ -35,17 +26,40 @@ public:
int pitch;
};
enum
enum class Type
{
Invalid = 0,
RenderTarget = 1,
DepthStencil,
Texture,
Offscreen,
Backbuffer,
SparseRenderTarget,
SparseDepthStencil
SparseDepthStencil,
};
enum class Format
{
Invalid = 0, ///< Used for initialization
Backbuffer, ///< For displaying to the screen
Color, ///< Standard (RGBA8) color texture
FloatColor, ///< Float-based color texture for colclip emulation (RGBA32F)
DepthStencil, ///< Depth stencil texture
UNorm8, ///< A8UNorm texture for paletted textures and the OSD font
UInt16, ///< UInt16 texture for reading back 16-bit depth
UInt32, ///< UInt32 texture for reading back 24 and 32-bit depth
Int32, ///< Int32 texture for date emulation
};
protected:
GSVector2 m_scale;
GSVector2i m_size;
GSVector2i m_committed_size;
GSVector2i m_gpu_page_size;
Type m_type;
Format m_format;
bool m_sparse;
public:
GSTexture();
virtual ~GSTexture() {}
@@ -70,8 +84,8 @@ public:
int GetHeight() const { return m_size.y; }
GSVector2i GetSize() const { return m_size; }
int GetType() const { return m_type; }
int GetFormat() const { return m_format; }
Type GetType() const { return m_type; }
Format GetFormat() const { return m_format; }
virtual void CommitPages(const GSVector2i& region, bool commit) {}
void CommitRegion(const GSVector2i& region);
+88 -83
View File
@@ -19,7 +19,7 @@
#include "GS/Renderers/DX11/D3D.h"
#include "GS/GSExtra.h"
#include "GS/GSUtil.h"
#include "GS/resource.h"
#include "Host.h"
#include <fstream>
#include <sstream>
#include <VersionHelpers.h>
@@ -218,6 +218,11 @@ bool GSDevice11::Create(const WindowInfo& wi)
m_hack_topleft_offset = (m_upscale_multiplier != 1 && D3D::IsNvidia(adapter.get()) && !disable_safe_features) ? -0.01f : 0.0f;
}
std::optional<std::string> shader = Host::ReadResourceFileToString("shaders/dx11/tfx.fx");
if (!shader.has_value())
return false;
m_tfx_source = std::move(*shader);
// convert
D3D11_INPUT_ELEMENT_DESC il_convert[] =
@@ -229,9 +234,10 @@ bool GSDevice11::Create(const WindowInfo& wi)
ShaderMacro sm_model(m_shader.model);
std::vector<char> shader;
theApp.LoadResource(IDR_CONVERT_FX, shader);
CreateShader(shader, "convert.fx", nullptr, "vs_main", sm_model.GetPtr(), &m_convert.vs, il_convert, std::size(il_convert), m_convert.il.put());
shader = Host::ReadResourceFileToString("shaders/dx11/convert.fx");
if (!shader.has_value())
return false;
CreateShader(*shader, "convert.fx", nullptr, "vs_main", sm_model.GetPtr(), &m_convert.vs, il_convert, std::size(il_convert), m_convert.il.put());
ShaderMacro sm_convert(m_shader.model);
sm_convert.AddMacro("PS_SCALE_FACTOR", std::max(1, m_upscale_multiplier));
@@ -240,7 +246,7 @@ bool GSDevice11::Create(const WindowInfo& wi)
for (size_t i = 0; i < std::size(m_convert.ps); i++)
{
CreateShader(shader, "convert.fx", nullptr, format("ps_main%d", i).c_str(), sm_convert_ptr, m_convert.ps[i].put());
CreateShader(*shader, "convert.fx", nullptr, shaderName(static_cast<ShaderConvert>(i)), sm_convert_ptr, m_convert.ps[i].put());
}
memset(&dsd, 0, sizeof(dsd));
@@ -269,10 +275,13 @@ bool GSDevice11::Create(const WindowInfo& wi)
m_dev->CreateBuffer(&bd, nullptr, m_merge.cb.put());
theApp.LoadResource(IDR_MERGE_FX, shader);
shader = Host::ReadResourceFileToString("shaders/dx11/merge.fx");
if (!shader.has_value())
return false;
for (size_t i = 0; i < std::size(m_merge.ps); i++)
{
CreateShader(shader, "merge.fx", nullptr, format("ps_main%d", i).c_str(), sm_model.GetPtr(), m_merge.ps[i].put());
CreateShader(*shader, "merge.fx", nullptr, format("ps_main%d", i).c_str(), sm_model.GetPtr(), m_merge.ps[i].put());
}
memset(&bsd, 0, sizeof(bsd));
@@ -298,10 +307,12 @@ bool GSDevice11::Create(const WindowInfo& wi)
m_dev->CreateBuffer(&bd, nullptr, m_interlace.cb.put());
theApp.LoadResource(IDR_INTERLACE_FX, shader);
shader = Host::ReadResourceFileToString("shaders/dx11/interlace.fx");
if (!shader.has_value())
return false;
for (size_t i = 0; i < std::size(m_interlace.ps); i++)
{
CreateShader(shader, "interlace.fx", nullptr, format("ps_main%d", i).c_str(), sm_model.GetPtr(), m_interlace.ps[i].put());
CreateShader(*shader, "interlace.fx", nullptr, format("ps_main%d", i).c_str(), sm_model.GetPtr(), m_interlace.ps[i].put());
}
// Shade Boost
@@ -320,8 +331,10 @@ bool GSDevice11::Create(const WindowInfo& wi)
m_dev->CreateBuffer(&bd, nullptr, m_shadeboost.cb.put());
theApp.LoadResource(IDR_SHADEBOOST_FX, shader);
CreateShader(shader, "shadeboost.fx", nullptr, "ps_main", sm_sboost.GetPtr(), m_shadeboost.ps.put());
shader = Host::ReadResourceFileToString("shaders/dx11/shadeboost.fx");
if (!shader.has_value())
return false;
CreateShader(*shader, "shadeboost.fx", nullptr, "ps_main", sm_sboost.GetPtr(), m_shadeboost.ps.put());
// External fx shader
@@ -418,7 +431,7 @@ bool GSDevice11::Create(const WindowInfo& wi)
const GSVector2i tex_font = m_osd.get_texture_font_size();
m_font = std::unique_ptr<GSTexture>(
CreateSurface(GSTexture::Texture, tex_font.x, tex_font.y, DXGI_FORMAT_R8_UNORM));
CreateSurface(GSTexture::Type::Texture, tex_font.x, tex_font.y, GSTexture::Format::UNorm8));
return true;
}
@@ -443,7 +456,7 @@ bool GSDevice11::Reset(int w, int h)
return false;
}
m_backbuffer = new GSTexture11(std::move(backbuffer));
m_backbuffer = new GSTexture11(std::move(backbuffer), GSTexture::Format::Backbuffer);
}
return true;
@@ -562,16 +575,32 @@ void GSDevice11::ClearStencil(GSTexture* t, u8 c)
m_ctx->ClearDepthStencilView(*(GSTexture11*)t, D3D11_CLEAR_STENCIL, 0, c);
}
GSTexture* GSDevice11::CreateSurface(int type, int w, int h, int format)
GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format)
{
D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
DXGI_FORMAT dxformat;
switch (format)
{
case GSTexture::Format::Color: dxformat = DXGI_FORMAT_R8G8B8A8_UNORM; break;
case GSTexture::Format::FloatColor: dxformat = DXGI_FORMAT_R32G32B32A32_FLOAT; break;
case GSTexture::Format::DepthStencil: dxformat = DXGI_FORMAT_R32G8X24_TYPELESS; break;
case GSTexture::Format::UNorm8: dxformat = DXGI_FORMAT_A8_UNORM; break;
case GSTexture::Format::UInt16: dxformat = DXGI_FORMAT_R16_UINT; break;
case GSTexture::Format::UInt32: dxformat = DXGI_FORMAT_R32_UINT; break;
case GSTexture::Format::Int32: dxformat = DXGI_FORMAT_R32_SINT; break;
case GSTexture::Format::Invalid:
case GSTexture::Format::Backbuffer:
ASSERT(0);
dxformat = DXGI_FORMAT_UNKNOWN;
}
// Texture limit for D3D10/11 min 1, max 8192 D3D10, max 16384 D3D11.
desc.Width = std::max(1, std::min(w, m_d3d_texsize));
desc.Height = std::max(1, std::min(h, m_d3d_texsize));
desc.Format = (DXGI_FORMAT)format;
desc.Format = dxformat;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
@@ -580,44 +609,35 @@ GSTexture* GSDevice11::CreateSurface(int type, int w, int h, int format)
// mipmap = m_mipmap > 1 || m_filter != TriFiltering::None;
const bool mipmap = m_mipmap > 1;
const int layers = mipmap && format == DXGI_FORMAT_R8G8B8A8_UNORM ? (int)log2(std::max(w, h)) : 1;
const int layers = mipmap && format == GSTexture::Format::Color ? (int)log2(std::max(w, h)) : 1;
switch (type)
{
case GSTexture::RenderTarget:
case GSTexture::Type::RenderTarget:
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
break;
case GSTexture::DepthStencil:
case GSTexture::Type::DepthStencil:
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
break;
case GSTexture::Texture:
case GSTexture::Type::Texture:
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.MipLevels = layers;
break;
case GSTexture::Offscreen:
case GSTexture::Type::Offscreen:
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
break;
}
GSTexture11* t = NULL;
GSTexture11* t = nullptr;
wil::com_ptr_nothrow<ID3D11Texture2D> texture;
HRESULT hr = m_dev->CreateTexture2D(&desc, nullptr, texture.put());
if (SUCCEEDED(hr))
{
t = new GSTexture11(std::move(texture));
switch (type)
{
case GSTexture::RenderTarget:
ClearRenderTarget(t, 0);
break;
case GSTexture::DepthStencil:
ClearDepth(t);
break;
}
t = new GSTexture11(std::move(texture), format);
assert(type == t->GetType());
}
else
{
@@ -627,42 +647,24 @@ GSTexture* GSDevice11::CreateSurface(int type, int w, int h, int format)
return t;
}
GSTexture* GSDevice11::FetchSurface(int type, int w, int h, int format)
bool GSDevice11::DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTexture::GSMap& out_map)
{
if (format == 0)
format = (type == GSTexture::DepthStencil || type == GSTexture::SparseDepthStencil) ? DXGI_FORMAT_R32G8X24_TYPELESS : DXGI_FORMAT_R8G8B8A8_UNORM;
return __super::FetchSurface(type, w, h, format);
ASSERT(src);
ASSERT(!m_download_tex);
m_download_tex.reset(static_cast<GSTexture11*>(CreateOffscreen(rect.width(), rect.height(), src->GetFormat())));
if (!m_download_tex)
return false;
CopyRect(src, m_download_tex.get(), rect);
return m_download_tex->Map(out_map);
}
GSTexture* GSDevice11::CopyOffscreen(GSTexture* src, const GSVector4& sRect, int w, int h, int format, int ps_shader)
void GSDevice11::DownloadTextureComplete()
{
GSTexture* dst = NULL;
if (format == 0)
if (m_download_tex)
{
format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_download_tex->Unmap();
Recycle(m_download_tex.release());
}
ASSERT(format == DXGI_FORMAT_R8G8B8A8_UNORM || format == DXGI_FORMAT_R16_UINT || format == DXGI_FORMAT_R32_UINT);
if (GSTexture* rt = CreateRenderTarget(w, h, format))
{
GSVector4 dRect(0, 0, w, h);
StretchRect(src, sRect, rt, dRect, m_convert.ps[ps_shader].get(), NULL);
dst = CreateOffscreen(w, h, format);
if (dst)
{
m_ctx->CopyResource(*(GSTexture11*)dst, *(GSTexture11*)rt);
}
Recycle(rt);
}
return dst;
}
void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r)
@@ -678,7 +680,7 @@ void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r)
// DX api isn't happy if we pass a box for depth copy
// It complains that depth/multisample must be a full copy
// and asks us to use a NULL for the box
const bool depth = (sTex->GetType() == GSTexture::DepthStencil);
const bool depth = (sTex->GetType() == GSTexture::Type::DepthStencil);
auto pBox = depth ? nullptr : &box;
m_ctx->CopySubresourceRegion(*(GSTexture11*)dTex, 0, 0, 0, 0, *(GSTexture11*)sTex, 0, pBox);
@@ -686,7 +688,7 @@ void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r)
void GSDevice11::CloneTexture(GSTexture* src, GSTexture** dest)
{
if (!src || !(src->GetType() == GSTexture::DepthStencil || src->GetType() == GSTexture::RenderTarget))
if (!src || !(src->GetType() == GSTexture::Type::DepthStencil || src->GetType() == GSTexture::Type::RenderTarget))
{
ASSERT(0);
return;
@@ -695,7 +697,7 @@ void GSDevice11::CloneTexture(GSTexture* src, GSTexture** dest)
const int w = src->GetWidth();
const int h = src->GetHeight();
if (src->GetType() == GSTexture::DepthStencil)
if (src->GetType() == GSTexture::Type::DepthStencil)
*dest = CreateDepthStencil(w, h, src->GetFormat());
else
*dest = CreateRenderTarget(w, h, src->GetFormat());
@@ -703,9 +705,9 @@ void GSDevice11::CloneTexture(GSTexture* src, GSTexture** dest)
CopyRect(src, *dest, GSVector4i(0, 0, w, h));
}
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, int shader, bool linear)
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
{
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[shader].get(), nullptr, linear);
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), nullptr, linear);
}
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear)
@@ -729,7 +731,7 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
wil::com_ptr_nothrow<ID3D11BlendState> bs;
m_dev->CreateBlendState(&bd, bs.put());
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[ShaderConvert_COPY].get(), nullptr, bs.get(), false);
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(ShaderConvert::COPY)].get(), nullptr, bs.get(), false);
}
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear)
@@ -740,8 +742,10 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
return;
}
const bool draw_in_depth = (ps == m_convert.ps[ShaderConvert_RGBA8_TO_FLOAT32] || ps == m_convert.ps[ShaderConvert_RGBA8_TO_FLOAT24]
|| ps == m_convert.ps[ShaderConvert_RGBA8_TO_FLOAT16] || ps == m_convert.ps[ShaderConvert_RGB5A1_TO_FLOAT16]);
const bool draw_in_depth = ps == m_convert.ps[static_cast<int>(ShaderConvert::RGBA8_TO_FLOAT32)]
|| ps == m_convert.ps[static_cast<int>(ShaderConvert::RGBA8_TO_FLOAT24)]
|| ps == m_convert.ps[static_cast<int>(ShaderConvert::RGBA8_TO_FLOAT16)]
|| ps == m_convert.ps[static_cast<int>(ShaderConvert::RGB5A1_TO_FLOAT16)];
BeginScene();
@@ -827,7 +831,7 @@ void GSDevice11::RenderOsd(GSTexture* dt)
// ps
PSSetShaderResource(0, m_font.get());
PSSetSamplerState(m_convert.pt.get(), nullptr);
PSSetShader(m_convert.ps[ShaderConvert_OSD].get(), nullptr);
PSSetShader(m_convert.ps[static_cast<int>(ShaderConvert::OSD)].get(), nullptr);
// ia
IASetInputLayout(m_convert.il.get());
@@ -920,9 +924,8 @@ void GSDevice11::DoExternalFX(GSTexture* sTex, GSTexture* dTex)
shader << fshader.rdbuf();
const std::string& s = shader.str();
std::vector<char> buff(s.begin(), s.end());
ShaderMacro sm(m_shader.model);
CreateShader(buff, shader_name.c_str(), D3D_COMPILE_STANDARD_FILE_INCLUDE, "ps_main", sm.GetPtr(), m_shaderfx.ps.put());
CreateShader(s, shader_name.c_str(), D3D_COMPILE_STANDARD_FILE_INCLUDE, "ps_main", sm.GetPtr(), m_shaderfx.ps.put());
}
catch (GSRecoverableError)
{
@@ -952,10 +955,12 @@ void GSDevice11::DoFXAA(GSTexture* sTex, GSTexture* dTex)
{
try
{
std::vector<char> shader;
theApp.LoadResource(IDR_FXAA_FX, shader);
ShaderMacro sm(m_shader.model);
CreateShader(shader, "fxaa.fx", nullptr, "ps_main", sm.GetPtr(), m_fxaa.ps.put());
std::optional<std::string> shader = Host::ReadResourceFileToString("shaders/common/fxaa.fx");
if (shader.has_value())
{
ShaderMacro sm(m_shader.model);
CreateShader(*shader, "fxaa.fx", nullptr, "ps_main", sm.GetPtr(), m_fxaa.ps.put());
}
}
catch (GSRecoverableError)
{
@@ -1022,7 +1027,7 @@ void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vert
// ps
PSSetShaderResources(rt, nullptr);
PSSetSamplerState(m_convert.pt.get(), nullptr);
PSSetShader(m_convert.ps[datm ? ShaderConvert_DATM_1 : ShaderConvert_DATM_0].get(), nullptr);
PSSetShader(m_convert.ps[static_cast<int>(datm ? ShaderConvert::DATM_1 : ShaderConvert::DATM_0)].get(), nullptr);
//
@@ -1394,7 +1399,7 @@ D3D_SHADER_MACRO* GSDevice11::ShaderMacro::GetPtr(void)
return (D3D_SHADER_MACRO*)mout.data();
}
void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il)
void GSDevice11::CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il)
{
HRESULT hr;
@@ -1417,7 +1422,7 @@ void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, I
}
}
void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11GeometryShader** gs)
void GSDevice11::CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11GeometryShader** gs)
{
wil::com_ptr_nothrow<ID3DBlob> shader;
@@ -1431,7 +1436,7 @@ void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, I
}
}
void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11PixelShader** ps)
void GSDevice11::CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11PixelShader** ps)
{
wil::com_ptr_nothrow<ID3DBlob> shader;
@@ -1445,7 +1450,7 @@ void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, I
}
}
void GSDevice11::CompileShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3DBlob** shader, const std::string& shader_model)
void GSDevice11::CompileShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3DBlob** shader, const std::string& shader_model)
{
wil::com_ptr_nothrow<ID3DBlob> error;
@@ -1456,7 +1461,7 @@ void GSDevice11::CompileShader(const std::vector<char>& source, const char* fn,
#endif
const HRESULT hr = D3DCompile(
source.data(), source.size(), fn, macro,
source.c_str(), source.size(), fn, macro,
include, entry, shader_model.c_str(),
flags, 0, shader, error.put());
+19 -15
View File
@@ -336,6 +336,7 @@ public:
u32 blend_index : 7;
u32 abe : 1;
u32 accu_blend : 1;
u32 blend_mix : 1;
};
struct
@@ -347,7 +348,7 @@ public:
u32 key;
};
operator u32() { return key & 0x1fff; }
operator u32() { return key & 0x3fff; }
OMBlendSelector()
: key(0)
@@ -395,8 +396,7 @@ private:
int m_mipmap;
int m_d3d_texsize;
GSTexture* CreateSurface(int type, int w, int h, int format);
GSTexture* FetchSurface(int type, int w, int h, int format);
GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) final;
void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) final;
void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0) final;
@@ -449,7 +449,7 @@ private:
{
wil::com_ptr_nothrow<ID3D11InputLayout> il;
wil::com_ptr_nothrow<ID3D11VertexShader> vs;
wil::com_ptr_nothrow<ID3D11PixelShader> ps[ShaderConvert_Count];
wil::com_ptr_nothrow<ID3D11PixelShader> ps[static_cast<int>(ShaderConvert::Count)];
wil::com_ptr_nothrow<ID3D11SamplerState> ln;
wil::com_ptr_nothrow<ID3D11SamplerState> pt;
wil::com_ptr_nothrow<ID3D11DepthStencilState> dss;
@@ -512,6 +512,9 @@ private:
PSConstantBuffer m_ps_cb_cache;
std::unique_ptr<GSTexture> m_font;
std::unique_ptr<GSTexture11> m_download_tex;
std::string m_tfx_source;
protected:
struct
@@ -532,22 +535,23 @@ public:
void Flip();
void SetVSync(int vsync) final;
void DrawPrimitive() final;
void DrawPrimitive();
void DrawIndexedPrimitive();
void DrawIndexedPrimitive(int offset, int count) final;
void DrawIndexedPrimitive(int offset, int count);
void ClearRenderTarget(GSTexture* t, const GSVector4& c) final;
void ClearRenderTarget(GSTexture* t, u32 c) final;
void ClearDepth(GSTexture* t) final;
void ClearStencil(GSTexture* t, u8 c) final;
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sRect, int w, int h, int format = 0, int ps_shader = 0) final;
bool DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTexture::GSMap& out_map) final;
void DownloadTextureComplete() final;
void CloneTexture(GSTexture* src, GSTexture** dest);
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, int shader = 0, bool linear = true) final;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) final;
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear = true);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear = true);
@@ -566,8 +570,8 @@ public:
void VSSetShader(ID3D11VertexShader* vs, ID3D11Buffer* vs_cb);
void GSSetShader(ID3D11GeometryShader* gs, ID3D11Buffer* gs_cb = NULL);
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) final;
void PSSetShaderResource(int i, GSTexture* sr) final;
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
void PSSetShaderResource(int i, GSTexture* sr);
void PSSetShaderResourceView(int i, ID3D11ShaderResourceView* srv, GSTexture* sr);
void PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb);
void PSUpdateShaderState();
@@ -575,7 +579,7 @@ public:
void OMSetDepthStencilState(ID3D11DepthStencilState* dss, u8 sref);
void OMSetBlendState(ID3D11BlendState* bs, float bf);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL) final;
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
bool CreateTextureFX();
void SetupVS(VSSelector sel, const VSConstantBuffer* cb);
@@ -587,9 +591,9 @@ public:
operator ID3D11Device*() { return m_dev.get(); }
operator ID3D11DeviceContext*() { return m_ctx.get(); }
void CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il);
void CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11GeometryShader** gs);
void CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11PixelShader** ps);
void CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il);
void CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11GeometryShader** gs);
void CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11PixelShader** ps);
void CompileShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3DBlob** shader, const std::string& shader_model);
void CompileShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3DBlob** shader, const std::string& shader_model);
};

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