Compare commits

..

693 Commits

Author SHA1 Message Date
Ani b8477a470f rpcs3_version: Bump to 0.0.16 2021-04-30 21:42:14 +01:00
Ani 2f44523e6d .github: Update issue templates
Mention settings must be as close to defaults as possible and that game 
patches must be disabled when reporting issues
2021-04-30 21:14:51 +01:00
Ani 2fa5f6f242 .github: Update PR-BUILD.md 2021-04-30 21:14:51 +01:00
Ani a86cce5d70 Update BUILDING.md
- Update Vulkan SDK references to match the version currently used in CI 
(1.2.154)
- Update Python to the oldest still supported version (3.6), also the 
version currently available on bionic
- Update leftover minimum required CMake version to 3.16.9
2021-04-30 21:14:51 +01:00
Ani 9856f170a7 .github: Update CONTRIBUTING.md
Modernize it a little bit
2021-04-30 21:14:51 +01:00
Megamouse ba35619718 curl: fix visual studio build 2021-04-30 17:07:05 +01:00
Ani 37331d8ead stblib: Ignore new 3rdparty warnings 2021-04-30 17:07:05 +01:00
Ani d17784b231 curl: Update from v7.72.0 to v7.76.1 2021-04-30 17:07:05 +01:00
Ani 18e1b45388 stblib: Update stb_truetype from v1.21 to v1.24 2021-04-30 17:07:05 +01:00
Ani 9b083f801c stblib: Update stb_image from v2.22 to v2.26 2021-04-30 17:07:05 +01:00
Ani f0907d6f96 pugixml: Update from v1.9-git to v1.11.4 2021-04-30 17:07:05 +01:00
Megamouse 71d58e3a67 rsx: remove unused tile functions 2021-04-30 08:23:16 +02:00
Megamouse 37425d6fcd GL: Remove unused copy functions 2021-04-30 08:23:16 +02:00
Megamouse 1f295bba5b VK: ReSharper warning fixes 2021-04-30 08:23:16 +02:00
Megamouse a50be7a912 GL: resharper findings (too lazy for const functions) 2021-04-30 08:23:16 +02:00
Ani f9d52ea5b9 OpenAL: Update include from 1.20.1 to 1.21.1 2021-04-30 00:02:08 +01:00
Ani e192869e15 XAudio2: Update from 1.2.0 to 1.2.6
Microsoft.XAudio2.Redist 1.2.0 to 1.2.6
2021-04-30 00:02:08 +01:00
Ani f1be9bbf6c FAudio: Update from 20.03-git to 21.04 2021-04-30 00:02:08 +01:00
Megamouse d331ff3193 overlays: implement text_align::right 2021-04-30 00:30:26 +02:00
Megamouse 035a187c42 user-overlays: add sanity check for enter button 2021-04-30 00:30:26 +02:00
Megamouse 3c37036f7a save-overlays: add entry size info 2021-04-30 00:30:26 +02:00
Megamouse 14b6d6291b save-overlays: add localization 2021-04-30 00:30:26 +02:00
Megamouse 5720a32bc5 save-overlays: change list entry contents.
There's no need to tell the user that the entry is for game xy, they are already playing that game.
On a real PS3 only the subtitle and the date are displayed.
2021-04-30 00:30:26 +02:00
Megamouse 11f57f259c cellSaveData: keep focus after confirmation cancel
It was very annoying to be thrown to beginning of the list after cancelling the confirmation.
2021-04-30 00:30:26 +02:00
Nekotekina 3fc6375ec5 Use consteval (experimental) 2021-04-29 23:16:43 +03:00
Nekotekina f8e05f8e3c Remove redundant operators != 2021-04-29 22:57:40 +03:00
Ani 98c0b3a2b1 glslang: Disable precompile headers 2021-04-29 20:20:40 +01:00
Ani 6423c23a9a glslang: Update to 11.4.0
From SDK-candidate-26-Jul-2020
2021-04-29 20:20:40 +01:00
polar dece8a69f6 BUILD: Refactor libusb submodule (#10169)
* relocate module files
* fix cmake errors
* moved & updated libusb MSVC build file
2021-04-29 16:50:18 +01:00
Nekotekina 5724d2d4c7 Simplify umax
Add operator less and conversion operator.
2021-04-29 12:21:12 +03:00
Nekotekina b1736b6411 Simplify utils::umulh64 (MSVC) 2021-04-29 09:45:57 +03:00
Nekotekina 703ec474f5 Fixup for sys_time_get_timezone (3rd path)
Also simplify Linux path a bit.
2021-04-29 00:07:22 +03:00
xddxd 64a109d28a Toolchain upgrades
CI/FreeBSD: unbreak build with bundled libc++ 12

Co-authored-by: Jan Beich <jbeich@FreeBSD.org>
2021-04-28 23:50:39 +03:00
Jan Beich dc2ec17886 CI/FreeBSD: stop caching downloaded packages
Packages on /latest get out of date pretty quickly, anyway.
2021-04-28 20:44:06 +03:00
kd-11 1d9dd8d29d vk: Add support for tagging objects to ease debugging
- Makes use of VK_EXT_debug_utils
2021-04-28 16:53:02 +03:00
kd-11 8b0e1d6c03 rsx: Make renderdoc compatibility mode a general option 2021-04-28 16:53:02 +03:00
Megamouse f1a9f6263e Rename Rockband to Rock Band 2021-04-27 23:33:46 +02:00
Nekotekina a049c6fd6b Implement sys_time_get_timezone syscall
Try to get system timezone automatically.
Attempt to address #10195.
2021-04-27 22:21:58 +03:00
kd-11 9609767c51 vk: Refactor render target code 2021-04-26 00:33:05 +03:00
Nekotekina 86a8e0716f Test alterable aggregates via overriding be_t
Checking how it might look like without introducing too many changes.
Alteration of its behaviour as a "template template" argument allows:
 - normal access
 - easier aggregate inspection
 - memory access interception
2021-04-25 19:00:16 +03:00
Nekotekina b5e9f09972 fmt: support numeric u128 formatting 2021-04-25 18:17:38 +03:00
Nekotekina 4d9a167f56 u128: add multiplication support (for MSVC) 2021-04-25 18:17:38 +03:00
Nekotekina b704cc8375 shared_ptr.hpp: implement make_single_value(), make_shared_value()
A function that constructs single_ptr from its argument.
Type can be deduced from the argument (unlike make_single).
2021-04-25 18:17:38 +03:00
Nekotekina e34c956196 shared_ptr.hpp: add invoke operator 2021-04-25 18:17:38 +03:00
clienthax 7197dd751a Fcntl e0000025 (#10172)
Co-authored-by: Eladash <elad3356p@gmail.com>
2021-04-24 21:43:09 +03:00
David Carlier 0b9e4ffe54 Mac OS build update and simplification, recent releases of macOS has clock_gettime support. 2021-04-24 12:55:21 +03:00
Megamouse 486ba6121d Qt: fix window position of update dialog 2021-04-24 11:46:51 +02:00
Megamouse 1015c126d7 fix formatting (somehow broken by copy pasta) 2021-04-24 11:46:51 +02:00
Megamouse 1caf81811a Move unspecific Emulator code out of System.cpp 2021-04-24 11:21:22 +03:00
kd-11 4c2a11b6d0 vk: Fix broken FBO swizzle for depth textures. WDB was basically broken for these. 2021-04-24 00:19:50 +03:00
Megamouse 8fd3b26308 sys: more constants 2021-04-23 22:46:15 +02:00
Megamouse 617d21fa84 sys_prx: more constants 2021-04-23 22:02:52 +02:00
Megamouse 4a88ffe250 Fix typo causing unreachable code 2021-04-23 22:02:52 +02:00
Megamouse 41b68ef353 some more constants 2021-04-23 22:02:52 +02:00
Eladash 72c85744b9 kernel-explorer: Show bound queue to port information
Show its IPC key or ID, depends on the queue's type.
2021-04-23 21:34:05 +03:00
Eladash c7b5bbd467 Fix emulation restart 2021-04-23 20:59:02 +03:00
David Carlier 082bbc7336 Following up on MacOS build fix.
Specialisation of llvm_value_t to allow build with LLVM this time.
2021-04-23 15:20:40 +03:00
Megamouse 087dccd194 Implement most of cellUserInfo 2021-04-23 05:50:19 +03:00
Nekotekina 61450335a5 named_thread: use concepts, improve constructors
Better default thread name detection.
2021-04-21 17:19:53 +03:00
Nekotekina 67649d7976 SPU LLVM: restore lost comment 2021-04-21 13:33:44 +03:00
Malcolm Jestadt 6247969ede SPU LLVM: Absolute final fixes for icelake shufb paths
- The constant mask was accessing bits in reverse order of what was expected
2021-04-21 11:00:02 +03:00
Malcolm Jestadt efd38fa940 SPU LLVM: Improve byteswap elimination
- Use the data before it has been swapped rather than relying on a second byteswap to cancel out the first
2021-04-20 23:24:21 +03:00
Malcolm Jestadt 551472220e SPU LLVM: Remove icelake shufb paths for now 2021-04-20 23:24:21 +03:00
p01arst0rm 01703b1350 moved cmake_modules to project root 2021-04-20 21:38:47 +03:00
p01arst0rm e9d785475e removed redundant cmake version check 2021-04-20 21:38:47 +03:00
p01arst0rm 9e008996ab swap STREQUAL for MATCHES 2021-04-20 21:38:47 +03:00
p01arst0rm bcfae17219 unified missmatched indentation in CMake files 2021-04-20 21:38:47 +03:00
dio-gh ddea45160b GUI: take out some unwise shortcuts
Removes the ability to stop or restart emulation via keyboard shortcuts
while the game is running. Prevents loss of work that can happen due to
the current bindings conflicting with very-widely established shortcuts.

Ctrl+C and Ctrl+E will now be unbound, and Ctrl+R will now mean Resume.
Strings that mention these keybinds were adjusted accordingly.
2021-04-20 19:46:47 +03:00
Malcolm Jestadt 53f13a9721 SPU LLVM: Final fixup for icelake shufb paths
- The cause of the problems was due to the constant mask for gf2p9affineqb being used as the first argument, instead of the second argument.
2021-04-20 13:07:24 +03:00
Megamouse 3e33f064bf overlays: hotfix for dialog interaction
Turns out there was an undocumented reason for this.
Nobody warned me that "It's a trap!".
I wonder how this hasn't summoned a shitstorm yet.
2021-04-20 00:42:11 +02:00
Megamouse aa0afc9a4e Input: avoid mouse events when unused 2021-04-20 00:06:23 +02:00
Eladash a0d1cf26d0 Reduce precompilation failure log level (error -> notice) 2021-04-19 23:18:31 +03:00
Megamouse 01d14aed80 fix null chars in hostname log message 2021-04-19 21:54:27 +02:00
Megamouse 3c4c830e20 Qt: Speed up Log Viewer 2021-04-19 21:25:19 +02:00
Nekotekina 0c9c481cee Use requires syntax in more places
Change style in some places.
2021-04-19 16:51:40 +03:00
Nekotekina 7dae376646 Implement fill_array() utility 2021-04-19 12:33:32 +03:00
Nekotekina ccb89bd76a MSVC: disable throwing new 2021-04-19 12:33:32 +03:00
Megamouse b2317543c8 Qt: Fix initial gs_frame position on multi-monitor 2021-04-19 10:44:48 +02:00
p01arst0rm b812ef2771 removed space between and its opening parentheses 2021-04-19 08:59:28 +03:00
David Carlier 7618e7f3fb FreeBSD/clang update proposal.
silence few build warnings, VKDMA: disable Intel chipset for host buffer as it requires root privilege.
2021-04-18 19:56:21 +03:00
David Carlier b6732fbae9 MacOs build fix proposal.
Made on Big Sur, removing few unnecessary old specifics.
Build with LLVM homebrew.
2021-04-18 17:18:09 +03:00
clienthax 68fa377d13 Add dev_flash2+3 2021-04-18 14:49:29 +03:00
Nekotekina 7a9561b966 vm_native: document some unmap_critical behaviour (posix) 2021-04-18 13:13:15 +03:00
Nekotekina c061991c43 vm_native: supply only one madvise flag at a time 2021-04-18 13:13:15 +03:00
Megamouse bdac1d9bfd Qt: fix type mismatch crash of game grid items 2021-04-18 09:58:54 +02:00
David Carlier 266c4209c4 VM: FreeBSD c_madv_no_dump/dump constants support. 2021-04-17 20:47:36 +03:00
Nekotekina fb26da1cb0 bs_t<>: create BitSetEnum concept
Try concepts instead of SFINAE.
2021-04-17 19:23:19 +03:00
Nekotekina d623720f4d Fix condition for -Wno-attributes (regression) 2021-04-17 16:26:41 +03:00
Nekotekina 9d4fcbf946 bs_t<>: fix/cleanup some operators 2021-04-17 15:54:33 +03:00
p01arst0rm 896db3806d replaced CMAKE_COMPILER_IS_GNUCXX with CMAKE_CXX_COMPILER_ID 2021-04-17 15:54:27 +03:00
Megamouse 691b986e36 keyboard pads: release all keys on FocusOut event 2021-04-17 14:03:50 +02:00
Megamouse 5416f60643 basic keyboard: release all keys on FocusOut event 2021-04-17 14:03:50 +02:00
Eladash 67e2e154fa Replace simple_type with std::common_type 2021-04-17 10:27:55 +03:00
Megamouse 330dea181a Qt: unify some movie hover code and fix cellLeave 2021-04-16 23:18:13 +02:00
Megamouse 7bc673002f overlays: fix dirty state of message dialog 2021-04-16 23:18:13 +02:00
Megamouse ae8d1a3a60 Qt: smoother scrolling in savedata manager 2021-04-16 21:26:24 +02:00
Megamouse 27975e9dfd Qt: remove uncritical deprecated notes and titles
This also fixes a savedata notes bug.
The detail section notes were always taken from the deprecated settings.
2021-04-16 21:26:24 +02:00
Megamouse bff938ccf5 Qt: optimize game list repaint with new logic
We now pass a shared pointer to the icon items, so there is no need to trigger a full refresh of the list anymore.
Sadly this doesn't apply to the game grid.
2021-04-16 11:21:04 +02:00
Megamouse 53f317e076 Qt: use gifs as icons on hover if available. 2021-04-16 11:21:04 +02:00
Malcolm Jestadt 0a7df9d02e SPU LLVM: add AVX-512 SPU verification
- This is hidden behind a new setting, as some cpus may downclock agressively when executing 512 wide instructions
2021-04-16 09:35:26 +03:00
Nekotekina 408ffd3d2c fxo: add debug name to the typeinfo 2021-04-15 20:01:29 +03:00
Nekotekina a211895e28 shared_ptr.hpp: use for fs::virtual_device
Add new constructors for single_ptr and shared_ptr.
Change virtual device prefix format.
2021-04-15 17:26:47 +03:00
Nekotekina 19763f8973 Remove unnecessary default:breaks 2021-04-15 15:23:59 +03:00
Desterly 99d6f9c7a9 Skylander - Traptanium portal cleanup
- Remove "Status" query responses from reset request
- Add additional request types for newer portal
2021-04-15 12:10:22 +02:00
Desterly 63e4ac80bd Skylander - Change portal version
Switch emulation to the Traptanium portal.   This portal is universal
and works with all games.
2021-04-15 12:10:22 +02:00
polar 24983ea329 removed whitespace
Co-authored-by: Megamouse <studienricky89@googlemail.com>
2021-04-15 11:37:35 +02:00
p01arst0rm 6cab5b5591 removed extra perentheses pair 2021-04-15 11:37:35 +02:00
p01arst0rm c9d2aed286 small collection of fixes 2021-04-15 11:05:15 +03:00
Eladash a16cc3ac8a lv2: Remove flags from IPC-supported objects 2021-04-15 10:31:40 +03:00
TotalCaesar659 ba1699a831 Fix typo 2021-04-14 20:01:18 +02:00
Megamouse 20c69a0e3e overlays: make auto-repeat buttons configurable
and properly reset the auto-repeat timer whenever a new button was pressed
2021-04-13 20:57:05 +02:00
Megamouse bdc5ed094b overlays: implement OSK password mode 2021-04-13 20:57:05 +02:00
Megamouse 088d22675b overlays: fix osk placeholder 2021-04-13 20:57:05 +02:00
Megamouse fc9b3c13e6 misc: fix old some style casts and redundancies 2021-04-13 20:57:05 +02:00
kd-11 14a64e2529 rsx: Handle rare rounding issue where position.w is very close to zero 2021-04-13 21:26:23 +03:00
Megamouse f5415fb4ac overlays: dynamically change dialog background 2021-04-13 19:13:56 +02:00
Megamouse 20076ed57e Qt: Properly disable perfoverlay datapoint sliders 2021-04-13 19:13:56 +02:00
Michał Karczewski 006b8574ae Update BUILDING.md
There is no `qt515-meta-minimal` package under mentioned package repository, but `qt515base` allows to build CMake configuration
2021-04-13 10:00:52 +03:00
p01arst0rm 1de7ac3c67 added inline suggestion to patch_engine_version to prevent duplicate includes 2021-04-13 09:14:53 +03:00
kd-11 8d1fc18941 vk: Fix mip level packed pitch calculation 2021-04-13 00:14:16 +03:00
kd-11 06dc99ab85 rsx: Fix decompression of RB_RG textures.
- Removes several subtle hacks that hid the real issue.
  A compressed texture has more than one texel per 'block'.
2021-04-11 21:36:36 +03:00
p01arst0rm e4059dfe6a added pvs-studio artifacts to gitignore 2021-04-11 19:44:57 +03:00
p01arst0rm 4048b1e515 added inline suggestion to settings_location to prevent duplicate includes 2021-04-11 18:38:02 +03:00
Nekotekina ccb46df905 Minor fixups (removed unnecessary code) 2021-04-11 16:36:02 +03:00
Megamouse a16d8ba3ea More random changes 2021-04-11 14:01:51 +03:00
xddxd a485957130 Cirrus warning fix 2021-04-11 01:18:23 +03:00
Eladash 56d34e0e80 Enforce backslash at the end of emulated drives paths 2021-04-10 23:51:49 +03:00
Eladash 11824b3916 Win32 FS: Improve fs::create_dir 2021-04-10 23:51:49 +03:00
Eladash 5ca6381624 Implement "PPU LLVM Precompilation" control setting 2021-04-10 18:06:46 +03:00
xddxd 024b184008 Cirrus build 2021-04-10 17:21:01 +03:00
Megamouse 7a105333dc Qt: fix vfs dir remove button enabled state 2021-04-10 15:18:16 +02:00
Megamouse 332eb5fbd6 Log firmware after Emu was initialized 2021-04-10 15:18:16 +02:00
Megamouse 5b0dac797c Remove deprecated user management code 2021-04-10 15:18:16 +02:00
Eladash 86ddc00bb1 Suggest adding RPCS3 to anti-virus whitelist on firmware/PKG installation failure 2021-04-10 10:37:20 +02:00
Nekotekina 3107f37864 Fix psf::load error for error::stream 2021-04-10 00:43:08 +03:00
Megamouse 17f5fec538 sceNp: fix rap file regression (#10084) 2021-04-09 21:37:57 +01:00
Megamouse 03b76b4606 Emu: some cleanup 2021-04-09 21:03:49 +02:00
Eladash a3e8a61547 PSF: Fix string_view optimization
Avoid redundant copies of std::string.
2021-04-09 20:58:30 +03:00
Eladash a8d5a8734a Loader/cellGame: Do not crash on invalid PSF files 2021-04-09 20:58:30 +03:00
Nekotekina 10bbb7fa1f Fix some warnings (deprecate enum arithmetics) 2021-04-09 10:26:13 +03:00
Nekotekina 8c5f2b249c shared_ptr.hpp: further fixes
Improved is_same_ptr() trait (added third "maybe" category).
Fallback to pseudo-runtime check in certain cases (if "maybe").
Fix single_ptr moving assignment operator.
2021-04-09 10:26:13 +03:00
Nekotekina 332c512eed shared_ptr.hpp: minor optimization (GCC hotfix)
Use thread_local for dummy objects (doesn't work on MSVC).
Couldn't find better way to remove fake static objects completely.
In a sense that they don't appear in object files.
2021-04-09 10:26:13 +03:00
Megamouse d10584ac6c DRM: Search all user directories for rap files 2021-04-09 08:47:59 +02:00
Eladash d2b761b7de Log error about HG games booted outside of /dev_hdd0 2021-04-08 23:57:00 +03:00
Eladash 49c5ce30cc Emulation: Fix boot path resolving
* Fix /dev_flash executables path arg. (/host_root is wrong for it)
* Fix usage of /host_root for homebrew applications when it is not mounted, use /app_home.
* Fix path source detection. (don't get fooled by path slashes repetitions, symlinks, '.', ".." and ('\' on Windows))
* Unescape tail of /dev_hdd0 paths.
2021-04-08 23:57:00 +03:00
Nekotekina 95725bf7fc Add -Werror=missing-noreturn (GCC, clang)
May be useful to diagnose functions which fail assertions unconditionally.
2021-04-08 10:29:47 +03:00
Nekotekina 94c62b1eec shared_ptr.hpp: improve is_same_ptr<> trait
Don't always return true on MSVC.
2021-04-08 10:29:47 +03:00
Megamouse 02febd3f65 Workaround: Skip progress_dialog during gameplay 2021-04-06 21:39:34 +03:00
Megamouse 497fbb17a8 progress_dialog fixes 2021-04-06 21:39:34 +03:00
p01arst0rm 5ddb1d6649 moved build options to options.cmake 2021-04-06 15:23:56 +03:00
Nick Renieris 396c129d41 vm: Flag names (refactoring) 2021-04-06 13:07:54 +03:00
cglmrfreeman f64a7bb820 Update OpenSUSE dependencies
Added `libqt5gui-private-headers-devel` dependency to fix `fatal error: qpa/qplatformnativeinterface.h: No such file or directory`
2021-04-05 11:14:59 +03:00
Eladash 4a9be0a8d2 core: Move IDM to FXO 2021-04-04 17:29:32 +03:00
Megamouse bf1756448e overlays: fix taskbar progress reset 2021-04-04 13:38:10 +03:00
Nekotekina ed8f60431f Fixup for progress dialog closing logic
Co-authored-by: Megamouse <studienricky89@googlemail.com>
2021-04-03 23:25:02 +03:00
Nekotekina 6f1f75bc8f Minor progress dialog refactoring
Add rsx::overlays::progress_dialog class (identical to message_dialog).
Don't use Emu.CallAfter() for native dialogs.
Make g_progr_ptotal waitable.
2021-04-03 22:38:04 +03:00
Nekotekina 963d150e93 Fix some -Weffc++ warnings (part 2) 2021-04-03 21:54:15 +03:00
Nekotekina c1f1b1174d Update commits 2021-04-03 21:54:15 +03:00
Nekotekina 1ddeef71c6 Fix some typos 2021-04-03 21:54:15 +03:00
Megamouse b7eefeac8b hotfix: skip progr dialogs if msg dialogs are open 2021-04-03 20:37:40 +02:00
Eladash e57f36fc5b Quick sys_sm_get_params implementation 2021-04-03 17:23:40 +03:00
Eladash 32116086b3 Implement _sys_prx_register_module loading imports/exports functionality 2021-04-03 17:23:40 +03:00
Eladash 878da3b474 Implement get_cellos_appname()
Identifying vsh.self and possibly other operating system executables in the future.
2021-04-03 17:23:40 +03:00
Eladash 73320d4180 Output all fatal log messages to Console/debugger as well 2021-04-03 08:47:58 +02:00
Eladash a1d31f640a Set userland firmware SPRX directory as the default PS3 decryption tool path 2021-04-02 20:54:33 +02:00
Megamouse 9c7230e79f cli: set user-id per command line 2021-04-02 11:50:28 +02:00
Megamouse 98687d474b Move system info to extra line 2021-04-02 07:14:23 +02:00
Eladash 7b57b8f2ca debugger: Implement ability to pause entire emulation on breakpoint 2021-04-01 19:11:55 +03:00
Eladash 55c98bfaef Fix #9879 and fix firmware confirmation dialog when auto-start is disabled 2021-04-01 14:09:02 +03:00
Nekotekina e9a45a2f45 Implement scoped_progress_dialog
Create Emu/system_progress.hpp
Remove atomic g_progr_show
2021-03-31 23:40:09 +02:00
Nekotekina 2212a131ef Fix some -Weffc++ warnings (part 1) 2021-03-31 11:27:09 +03:00
Nekotekina deacf05769 Enable -Wdeprecated-copy
Some classes violated the Rule of 3(5) in their special operator definitions.
2021-03-31 11:27:09 +03:00
Megamouse 870224cde0 Emu/overlay: ingame native overlay PPU compilation 2021-03-31 09:38:30 +02:00
Megamouse e557c962fb Qt: gs_frame position updates 2021-03-30 19:09:01 +02:00
Eladash 5a3c218239 thread-pool: Fix default rounding mode 2021-03-30 11:13:47 +03:00
Eladash 1e71deb0db rsx: Compile shaders when CELL is not running 2021-03-30 11:13:47 +03:00
Eladash dea1d01de2 Fix Emulator::Stop race with IDM
Newly created threads' state could have not been flagged with exit.
2021-03-30 10:21:54 +03:00
Eladash e9bea1c742 Emu: Do not obey auto-exit setting after creating firmware cache 2021-03-30 10:21:54 +03:00
Eladash d51bb8b1cc Fix Emulator::Pause race with IDM 2021-03-30 10:21:54 +03:00
Eladash aad5283786 Fix Emulator::IsPaused() 2021-03-30 10:21:54 +03:00
Megamouse 66df38957b add AppIcon to fatal_error_dialog 2021-03-29 23:32:15 +02:00
xddxd 7cbafd603a Get rid of non-LLVM build configurations (#10030)
Co-authored-by: Megamouse <studienricky89@googlemail.com>
2021-03-29 22:45:48 +03:00
dio-gh 3e48c9744b upgrade icons to a modern design
Credits go to @DAGINATSUKO, and @hcorion for the svg version.
2021-03-29 22:24:40 +03:00
Megamouse a982280400 Qt: Drop int for QT_SCALE_FACTOR_ROUNDING_POLICY 2021-03-29 20:37:33 +02:00
Megamouse d62983e1a2 Qt: Properly set QT_SCALE_FACTOR_ROUNDING_POLICY 2021-03-29 20:37:33 +02:00
Megamouse 90ac24e524 Qt: set find_dialog "next" button to default 2021-03-29 19:19:24 +02:00
Megamouse 0b2ba98238 Qt: add option to hide the log prefix 2021-03-29 19:19:24 +02:00
xddxd 916ce7899b LLVM Clang-cl support and ninja build
Also update the submodule
2021-03-28 17:24:48 +03:00
xddxd b978aa6dca Wording changes and tooltip fix for unsupported CPUs 2021-03-26 18:56:16 +01:00
Megamouse 6565855005 Qt: clean global cfg before adding custom cfgs 2021-03-26 09:08:30 +01:00
Megamouse 9f80a55652 Qt: don't show updater if booted with cli arg 2021-03-25 23:39:42 +01:00
xddxd 9d895e6b15 Scheduler overhaul 2021-03-26 00:29:44 +03:00
Megamouse a7acb84b8b Qt: Remove unused GUI entries when saving a config 2021-03-25 20:34:00 +01:00
Megamouse 8d54453981 Qt: Fix debugger breakpoint deletion 2021-03-24 20:47:51 +01:00
Megamouse 452fb59c74 Qt: select target item in debugger list
This should make it easier to spot the item
2021-03-24 20:47:51 +01:00
Megamouse ba45daff35 Qt: some cleanup in debugger 2021-03-24 20:47:51 +01:00
Nekotekina b3fb6d7d18 Add and fix -Wredundant-decls (GCC) 2021-03-23 22:48:57 +03:00
Nekotekina 5dc3467337 vm: fix reservation_update notification
Rare function.
2021-03-23 21:09:37 +03:00
Nekotekina 729757b1dd atomic.hpp: allow raw notify_all by pointer 2021-03-23 20:58:42 +03:00
Nekotekina 393f9d329d atomic.cpp: allow non-standard sizes in atomic wait (>16) 2021-03-23 20:52:56 +03:00
Nekotekina 820390b7ed atomic.cpp: remove raw_notify and simplify internal logic
Also permit zero size in waiters.
2021-03-23 20:19:10 +03:00
Nekotekina e0790f758e Add some warnings (GCC, clang) 2021-03-23 16:40:44 +03:00
Eladash 2f333424a6 Improve ELF/Trophy loader's error checking 2021-03-23 16:05:23 +03:00
Eladash a67b347966 debugger: Fix SPU memory viewing (#10007)
* debugger: Fix SPU memory viewing

* Fix terminal recovery from page faults (hack allocation)
2021-03-23 13:33:07 +03:00
Megamouse dedf09017a VS: try to unbreak debug builds 2021-03-23 09:11:04 +01:00
Megamouse cd07ab5b5f VS: fix release build 2021-03-23 00:46:26 +01:00
Megamouse 6892cb1c7e Qt: prepare for removal of deprecated GUI settings
If you remove a custom name and already had a deprecated name before, you'll never get rid of it.
This applies to all of the deprecated settings.
2021-03-22 23:47:11 +01:00
Megamouse b518a9a338 VS: fix release Optimization 2021-03-22 20:19:36 +01:00
Megamouse 54d078f379 VS: fix AdditionalIncludeDirectories 2021-03-22 20:19:36 +01:00
Eladash b0a0533a4f Memory string searcher improvements
* Search the entire PS3 4GB address space instead of a small area of memory which is meant mostly for PRX/SELF memory aka vm::main segment. This limitation rendered string searcher nearly useless.
* Implement hexadecimal byte-string, hexadecimal integer, float and double value search formats.
* Multi-thread searching.
* Optimize searching algorithm vastly.
* Fix crash on empty string, report an error.
* Implement case-insensitive string search.
2021-03-22 18:37:26 +03:00
Megamouse 399f20ae54 Qt: Fix debugger step shortcuts 2021-03-22 10:44:30 +01:00
Megamouse 554ba9d6a6 Qt: Allow package installation through cli
Adds --installpkg cli option
2021-03-21 18:44:11 +01:00
Megamouse 2c05e9719d cfg: simplify get_nodes 2021-03-20 20:54:26 +03:00
Megamouse cb9e7358d2 cfg: log unused config entries 2021-03-20 20:54:26 +03:00
Megamouse ae01e1d2c3 cfg: move get_name to _base 2021-03-20 20:54:26 +03:00
Zion Nimchuk 2766e5ca6f Fix some minor shellcheck errors in github upload and windows build scripts 2021-03-20 15:09:48 +03:00
Zion Nimchuk ca0c4f2cc0 Run shellcheck on all build scripts to ensure quality 2021-03-20 15:09:48 +03:00
Megamouse 70c98fff19 Make cli fw installation more foolproof 2021-03-20 11:57:04 +01:00
Romain TISSERAND b5698ee101 Add command-line option to install firmware 2021-03-20 11:57:04 +01:00
Nekotekina 379138af27 Fix NtSetTimerResolution in no-gui mode (Win32)
Add dummy persistent timer with 10ms period.
Replace QTimer invocation with Emu.CallAfter().
This way, headless and no-gui modes should be affected by it.
2021-03-19 22:26:48 +03:00
Eladash 1864419561 Fix SPU mapped memory page size 2021-03-19 22:25:08 +03:00
Megamouse c4a8bb26fb VS: move projects to 3rdParty 2021-03-19 19:52:51 +03:00
Eladash a9ddb1d3b3 GUI: Implement full extraction of PUP
* Implement full extraction of PS3UPDAT.PUP.
* Implement TAR extraction via GUI.
* Use VFS to implement missing PS3 filesystem characters escaping.
* Use VFS to error on illegal paths. (illegal paths such as malware pointing to "/../../..and so on../C:/Windows")
2021-03-19 17:51:09 +01:00
Eladash 314670a347 Improve firmware installation error handling
* Add new error types and descriptions.
* Do not crash on missing 0x100 and 0x300 PUP file entries.
* Report an error on missing PUP package inner files.
* Fix overflow in file-size against header check.
* Move all header errors to pup_object class.
* Move verbose error descriptions to pup_object class.
* Minor optimizations.
2021-03-19 17:51:09 +01:00
Eladash ad49c54531 Fix race in render_creator (#9939) 2021-03-18 12:09:42 +03:00
Megamouse 43ac33c2b4 cellSaveDataEnableOverlay 2021-03-18 11:11:34 +03:00
Nekotekina 83fdcff178 Add commits 2021-03-17 23:53:31 +03:00
Nekotekina ee4009e123 Add supporters 2021-03-17 23:53:10 +03:00
Nekotekina 2decf1ecda Rename and move g_tls_current_cpu_thread inside cpu_thread
Don't declare extern inside get_current_cpu_thread().
Possible workaround for gcc-11.
2021-03-17 23:49:48 +03:00
Eladash 1d7fbd6a9a Fix sceNpTrophyGet(Trophy/Game)Icon 2021-03-17 22:31:57 +03:00
Eladash 1213708b72 Replace some log errors (#9980) 2021-03-17 17:19:35 +03:00
Megamouse 6cc5428d5e Qt: make some scrollbars thicker.
How are we supposed to grab them if they are so tiny?
2021-03-17 08:49:03 +01:00
Nekotekina 8fcebebae3 Implement lv2_mp_flag::cache
Identify /dev_hdd1 without unsafe path comparison.
2021-03-16 19:37:03 +03:00
Nekotekina f801dc6558 Save all 8 syscall_args 2021-03-16 19:33:37 +03:00
Eladash 8716ac554f Fix sys_raw_spu_destroy 2021-03-16 19:31:52 +03:00
Eladash d7b4753007 Make gamedata installation atomic as real PS3 2021-03-16 19:31:52 +03:00
Eladash a9b0d25c01 PPU Debugger: Fixup for syscall arguments (#9932) 2021-03-16 16:20:45 +03:00
Eladash 4c7fc8a70a Improve fs::container_stream::write (#9976)
Add overflow condition.
2021-03-16 14:03:58 +03:00
Megamouse f8e9ea45ba Qt: add bright arrows for tree views 2021-03-15 22:41:00 +01:00
Nekotekina 1b6c14be8d SPIRV: disable error on warnings 2021-03-15 22:31:05 +03:00
Eladash a5bb925a3d Thread.cpp: Add missing newline 2021-03-15 20:41:33 +03:00
shockdude 6a14849381 sys_usbd: DJ Hero Turntable Emulation (#9965)
* Initial Turntable Emulation
2021-03-14 23:48:50 +03:00
Megamouse f93dbb8f49 Qt: dont scale small icons, deal with size instead 2021-03-14 19:56:11 +01:00
Megamouse f83b19cecf Qt: Fix wide game icons (weird copy pasta error) 2021-03-14 19:56:11 +01:00
Megamouse 1e09be19f5 Qt: Fix PaintedPixmap crash if icon is null 2021-03-14 19:56:11 +01:00
Megamouse c1de0bc28c workaround for clang compilation 2021-03-14 16:46:16 +01:00
Megamouse 1a5a0f5eca overlays: Fix aspect ratio of custom bakground images 2021-03-14 16:46:16 +01:00
Megamouse 8b0cd60be9 Qt: Fix game icon canvas size 2021-03-14 16:46:16 +01:00
Megamouse 2239a52e9b Qt: Import Custom Shader Loading Icons
and refactor icon import
2021-03-14 16:46:16 +01:00
kd-11 c9214ce6c0 vk: Disable async streaming by default 2021-03-14 16:39:55 +03:00
Nekotekina bb9b5e6aff Enable -Wtautological-compare 2021-03-13 23:01:37 +03:00
Nekotekina 0327ecc5c1 Enable -Wduplicated-cond (GCC) 2021-03-13 18:46:59 +03:00
Nekotekina ccdea1c4ad Enable -Wduplicated-branches (GCC) 2021-03-13 18:03:08 +03:00
Nekotekina c22e1e71f0 Continue fixing strict aliasing warnings 2021-03-13 18:02:37 +03:00
Eladash aff63028d4 SCE Decryption: Detect illegal RAP files 2021-03-13 11:51:40 +01:00
Eladash 7a7b168af3 GUI: Atomic RAP file installation 2021-03-13 11:51:40 +01:00
Eladash bdf6a1c70e GUI: Handle all PUP files in drag-and-drop 2021-03-13 11:51:40 +01:00
Eladash d1e07434a1 GUI: Handle uppercase RAP file extension 2021-03-13 11:51:40 +01:00
Megamouse c0d823f1d8 Qt: Fix square custom icons 2021-03-13 10:19:39 +01:00
Megamouse 8d0947f07f Qt: Option for Custom Icons 2021-03-13 10:19:39 +01:00
Megamouse 161d8ef47a Qt: Center Custom Icons 2021-03-13 10:19:39 +01:00
Megamouse 8c139206d7 Qt: Import Custom Icons 2021-03-13 10:19:39 +01:00
jtscott e3a7fddddf Resolve minor typo 'verion' 2021-03-13 01:16:01 +01:00
Eladash 923ba6f3bb Fix sysutil_send_system_cmd at Emu.Stop() 2021-03-12 21:01:48 +03:00
Eladash 729cd9284e debugger: Fix PPU threads pausing 2021-03-12 13:01:12 +03:00
kd-11 140c5bfc3e Add asynchronous streaming to the GUI and auto-enable it
- Hopefully not many users are on very weak GPUs
2021-03-12 02:27:05 +03:00
kd-11 a5f0faefc3 vk: Check for uninitialized target before going into any scaling op 2021-03-12 02:27:05 +03:00
kd-11 608f8de347 vk: Solve GPU hang/reset due to waiting on events that are never signaled
- TODO: Some refactoring may be required to pair the primary and secondary CB and avoid such blunders
2021-03-12 02:27:05 +03:00
kd-11 3e8a00d264 Basic fixups 2021-03-12 02:27:05 +03:00
kd-11 7d5a72c9e0 vk: Add options to system configuration 2021-03-12 02:27:05 +03:00
kd-11 48d0f80a86 vk: Add an alternate async queue scheduler
- This version violates spec but does not rely on CPU threads to keep the GPU from hanging. It's ironically much safer to use.
2021-03-12 02:27:05 +03:00
kd-11 bd6c187fcd vk: Tune event polling for higher throughput 2021-03-12 02:27:05 +03:00
kd-11 585837a3f0 vk: Support new fxo usage pattern 2021-03-12 02:27:05 +03:00
kd-11 b4e821c28d vk: Flip on async texture uploads 2021-03-12 02:27:05 +03:00
kd-11 589ac1c5d4 vk: Optimization - avoid touching the mutex at all if possible even when there is no contention 2021-03-12 02:27:05 +03:00
kd-11 c9e8b87c60 vk: Properly clean up async scheduler 2021-03-12 02:27:05 +03:00
kd-11 41f5158247 vk: Sync main pipe with async jobs if any 2021-03-12 02:27:05 +03:00
kd-11 d2993474fb vk: Lazy-initialize image resource on first use when owned by a separate queue 2021-03-12 02:27:05 +03:00
kd-11 77e312fb99 vk: Add the async task scheduler 2021-03-12 02:27:05 +03:00
Eladash cd6ef2958b Add information about unnamed/main threads in logs and fatal dialog
* If thread is unnamed, keep log name empty for main thread, otherwise print thread id. In fatal dialog, main thread can be handled differently (with special remark that it's main thread).
* Always print thread id in fatal dialog, regardless of thread type.

Co-authored-by: Nekotekina <nekotekina@gmail.com>
2021-03-11 22:55:06 +03:00
Megamouse 40f3adc45f Overlays: Implement individual pulse 2021-03-11 20:48:12 +01:00
Eladash cfa2d4aaa8 Loader: Log FNID of imported/exported functions 2021-03-11 15:23:58 +03:00
arabek bdefeaf6f9 Use maybe_unused macro for chip var
Var chip is only used in the WIN32 ifdef block - use maybe_unused to silence the compiler warning about unused variable.
2021-03-11 14:33:04 +03:00
Eladash 0958c10f88 Improve TAR loader (#9908)
* Fix header magic test.
* Rewrite code to not use so many filesystem calls.
* Add many more error checks.
* Add missing NUL filetype.
* octalToDecimal(header.size) has been fixed to use fixed 12 characters range instead of endless string.
* Add many optimizations.
* Fix possible signed overflows with int, use the unisgned u64 type instead which allows for greater files as well.
* Log errors.
2021-03-11 02:26:39 +03:00
Nekotekina 4adf412049 Fix std::bit_cast misuse 2021-03-10 16:11:30 +03:00
Nekotekina 03332c340d Implement utils::bless (pointer cast)
Tries to workaround strict aliasing troubles.
Don't confuse with std::bless which works differently.
2021-03-10 16:02:00 +03:00
Eladash 63ecb56b51 PPU interpreter hotfix 2021-03-10 13:41:13 +03:00
Megamouse cbd895a29c Move code to cpp (#9938)
* GL: move GLOverlays code to cpp
* GL: move GLCompute code to cpp
* VK: move VKOverlays code to cpp
* VK: move VKCompute code to cpp
2021-03-10 00:58:08 +01:00
Nekotekina 9cbe77904d Revert changes in BufferUtils.cpp
Should fix #9933
2021-03-09 19:19:24 +03:00
Nekotekina a6350d5dd1 Fixup write_gather (Linux, BSD)
Split iovec into small portions (256 for now)
2021-03-09 15:54:04 +03:00
Nekotekina 19b5b47b26 Add -Wnull-dereference (commented out) 2021-03-09 15:54:04 +03:00
Eladash 52a0b38379 Workaround segfaults in Vulkan enumeration thread (#9935)
* Workaround segfaults in Vulkan enumeration thread
2021-03-09 13:50:58 +01:00
Nekotekina a4fdbf0a88 Enable -Wstrict-aliasing=1 (GCC)
Fixed partially.
2021-03-09 03:10:15 +03:00
Nekotekina 3990e2d3e6 Add -Wclobbered and -Wcast-function-type (no effect) 2021-03-09 03:10:15 +03:00
Nekotekina 53af2dbb3f Add/fix warning -Wignored-qualifiers (GCC/clang)
Fix simple_array::const_iterator as a part of it.
2021-03-09 03:09:50 +03:00
Nekotekina 5bdd1cf837 Remove some redundant code
Potential fix for future warnings.
2021-03-09 03:09:50 +03:00
dio-gh 5dfe3f414d fix colors for skyline (dark)
Fixes debugger colors in the dark Skyline stylesheet.
2021-03-09 01:07:32 +01:00
dio-gh 324fa10918 fix colors for skyline (bright)
Fixes debugger colors and the notice-level log message colors, the latter to the gray that is noted in the color palette.
2021-03-09 01:07:32 +01:00
dio-gh aad06faf1f fix debugger instr coloring
Fixes the missing color highlights from the currently executing instruction and the breakpoints.
2021-03-09 01:07:32 +01:00
Megamouse 1a3c01154a make from_hdd0_game check lowercase 2021-03-08 22:58:19 +03:00
xddxd df338f0552 Move sys_crashdump to it's own file and make it a module itself 2021-03-08 22:57:35 +03:00
Malcolm Jestadt e5d0e035d0 SPU LLVM: Rearange FM instruction for better performance
- Doesn't eliminate any instructions, but allows for better out of order execution.
2021-03-08 15:48:36 +03:00
xddxd 6d91a9fe6f Possible workaround for mobile Kepler chips 2021-03-08 15:46:03 +03:00
Megamouse 935e398930 patch_manager: expand first search results 2021-03-08 12:05:00 +01:00
Eladash 2afc7cbaaa GUI: Implement MSELF extraction tool (#9909)
* MSELF: fix overflow

* GUI: Implement MSELF extraction tool

* VS: fix mself files in vcxproj

* fix

* Update mself.cpp

* fixed
2021-03-07 17:59:37 +01:00
Megamouse 1b5cf118e7 Input/Qt: implement XInput battery level 2021-03-07 11:48:19 +01:00
Megamouse a3a4c0a906 overlays: don't count initial garbage values.
This might also shave off some microseconds.
2021-03-07 00:52:11 +01:00
Megamouse 3ae7debc17 Qt: Do not allow updates during emulation 2021-03-07 01:56:25 +03:00
Megamouse dab53f4e41 Cleanup Emu before the update reboot 2021-03-07 01:56:25 +03:00
Megamouse 9da7910fc9 Fix auto updates. Don't pass exe as arg0 to execl 2021-03-07 01:56:25 +03:00
Nekotekina 3609eb25c9 Implement thread_ctrl::is_main() 2021-03-06 23:10:31 +03:00
Nekotekina 55c75d2c87 Implement thread_ctrl::get_tid() 2021-03-06 23:10:31 +03:00
Nekotekina ded828dfc9 sysinfo.cpp: Implement utils::main_tid (main thread id)
Careful.
2021-03-06 23:10:31 +03:00
Nekotekina c69c70cf5f Another minor fix for fmt::split
Doesn't affect existing code.
If there are 2 or more separator, choose closest.
2021-03-06 19:30:09 +03:00
Nekotekina 7cd79714fa Minor fix for fmt::split with empty string
Doesn't affect existing code, I believe.
Return at least 1 empty string if is_skip_empty=false.
2021-03-06 19:26:41 +03:00
Nekotekina 87af905018 Enable -Wunused-parameter 2021-03-06 18:07:08 +03:00
Megamouse 7205a93751 add some log messages for debugging 2021-03-06 18:06:21 +03:00
GitArUs f8097a428c Allow games to list all savedata (#9547)
* cellSaveData - allow games to list all savedata, not only those they own.

Co-authored-by: Megamouse <studienricky89@googlemail.com>
2021-03-06 16:01:04 +03:00
Eladash 228988ca2b Fix utils::get_firmware_version()
* Do not crash on invalid file contents.
* Do not crash on unexpected file.open() error.
2021-03-06 14:53:40 +03:00
Megamouse d2b0b019ec DualSense: Fix initial ingame LED update 2021-03-06 11:15:54 +01:00
Eladash a5d74c5e96 GUI: Improve missing firmware handling
* Install PS3UPDAT.PUP at the spot when booting games whenever firmware is missing. The option to boot games without firmware is still supported when all firmware SPRX are HLEd in firmware settings.
* Pop-up a confirmation dialog in firmware installation if firmware is already installed.
2021-03-06 10:34:49 +01:00
Megamouse 3e7e077fad DS3/DS4: fix battery LED update 2021-03-06 02:07:02 +01:00
Megamouse dbb03ae2d7 dualsense: implement lightbar pulse (low battery) 2021-03-06 02:07:02 +01:00
Megamouse 06d2c5357b dualsense: fix LED updates 2021-03-06 02:07:02 +01:00
Megamouse c8e7530e37 dualsense: get hardware and firmware version 2021-03-06 02:07:02 +01:00
Megamouse cdffaa1598 dualsense: implement battery level 2021-03-06 02:07:02 +01:00
Megamouse b836d2497d dualsense: minor cleanup 2021-03-06 02:07:02 +01:00
Megamouse bdd94f053c Qt: reset battery progress bar when not supported. 2021-03-06 02:07:02 +01:00
Megamouse f88c3ae417 Qt: fix settings_dialog layout. Add stretches. 2021-03-05 14:46:52 +03:00
Megamouse b09ac19e61 VS 16.9.0 compilation workaround 2021-03-05 14:46:52 +03:00
Timothy Redaelli 826dc7d5a6 Fix linking with system curl 2021-03-04 12:22:19 +03:00
Timothy Redaelli fa5a2b6a85 SPUThread.cpp: remove "__attribute__((always_inline))"
cmp_rdata and mov_rdata are using __attribute__((always_inline)),
without inline, that is not supported on current g++ (see RPCS3#1546).

Moreover __attribute__((always_inline)) is a noop if used without inline so
just remove it.

A proper fix is to move the 2 functions in an header file as static
(with FORCE_INLINE) so it can be correctly inlined by the compiler.
2021-03-04 12:17:27 +03:00
Nekotekina 8b8120cfb7 Add commits 2021-03-03 17:38:36 +03:00
Nekotekina e6a3b59229 endian.hpp: simplify be_t/le_t constructors 2021-03-03 17:37:51 +03:00
RipleyTom 0eb0b1e1c9 Add some GT6 devices to whitelist 2021-03-03 17:30:16 +03:00
kd-11 1becd2f788 vk: Remove redundant double barrier
- Luckily it was not too harmful in single queue submissions
2021-03-03 13:17:04 +03:00
Megamouse 7c0b93f815 perf overlay: Don't allow 0 or 1 datapoint count
Doesn't render anyway
2021-03-03 00:33:46 +01:00
Megamouse fa852c7dbe perf overlay: add missing graph vertex
And fix potential division by 0
2021-03-03 00:33:46 +01:00
Megamouse 73ca2119ed perf overlay: add datapoint settings to GUI 2021-03-03 00:33:46 +01:00
Megamouse 86dbb859b7 perf overlay: add datapoint count config settings 2021-03-03 00:33:46 +01:00
Megamouse e1e370999e perf overlays: fix dynamic font resize of graphs 2021-03-03 00:33:46 +01:00
Megamouse 038c708a0a perf overlays: add detail level none (hides FPS) 2021-03-03 00:33:46 +01:00
Nekotekina c71bc25090 PPU: remove artificial 0x20000000 barrier for debug stats
Change it to 0xE0000000 (SPU demarcation line)
2021-03-02 21:58:49 +03:00
Nekotekina 52fe86b56c fixed_typemap.hpp: make it a bit fool-proof
Require objects to be non-copyable (move is still allowed).
2021-03-02 21:58:49 +03:00
Eladash 004ebfdaee SPU debugger: Implement MFC journal
* Allow to dump up to 1820 commands with up 128 bytes of data each, using key D with the debugger.
2021-03-02 21:57:51 +03:00
Eladash d0edd44a69 Atomic trophy status updates 2021-03-02 19:19:27 +03:00
Nekotekina ea5e837bd6 fixed_typemap.hpp: return reference 2021-03-02 16:08:14 +03:00
Nekotekina bbf52f3cea named_thread: fix bugs in std::forward usage
Fix few misused threads and other bugs.
2021-03-02 16:08:14 +03:00
Nekotekina d788b12a8e fixed_typemap.hpp: reduce indirection
Backported some changes from auto_typemap.hpp
Implemented methods init(), reset(), clear()
Disabled recreation support.
2021-03-02 16:08:14 +03:00
Nekotekina 8a9320c4ef auto_typemap.hpp: reduce indirection
Implement is_init() method.
Implement optional Size template arg for further optimization.
2021-03-02 16:08:14 +03:00
Nekotekina 5cc9bd7702 typeindices.hpp: upgrade with size and align info
This allows contiguous allocation (as in an aggregate).
2021-03-02 16:08:14 +03:00
Nekotekina aa7e2376ec shared_ptr.hpp: minor fixup for arrays 2021-03-02 16:08:14 +03:00
Eladash ff211a9508 LLVM: Do not crash on failure to create cache file 2021-03-02 16:07:51 +03:00
Megamouse 930895a218 DS3: fix LED battery status 2021-03-02 01:29:28 +01:00
Megamouse 3452e18da1 DS3: fix linux output report 2021-03-02 00:45:42 +01:00
Megamouse b5d4b5a21c DS3: fix regression: pad data is cleared even if there is no new data 2021-03-01 14:37:49 +01:00
Megamouse 2dc798d539 DS3: fix battery_level aquisition 2021-03-01 14:37:49 +01:00
Megamouse 805d52987f Qt/Input: set player LED in pad settings 2021-03-01 14:37:49 +01:00
Megamouse c2467b7b38 ds3: add led battery indicators (Linux only atm)
needs testing. maybe doesn't work
2021-03-01 14:37:49 +01:00
Megamouse 22b8cfd0ba input: add some sanity checks 2021-03-01 14:37:49 +01:00
Megamouse 10a55f16cc DS3: implement player LEDs 2021-03-01 14:37:49 +01:00
Ani 8e4451d1ab rpcs3_version: Bump to 0.0.15 (#9866) 2021-02-28 23:32:23 +00:00
Megamouse 0b5c6350ae cellScreenshot: fix overlay scaling (#9867)
* cellScreenshot: fix overlay scaling
2021-02-28 23:00:49 +00:00
Eladash 48cd56acc2 Report deadlocked thread names in failures to stop emulation (#9865)
* Report deadlocked thread names in failures to stop emulation

Co-authored-by: Nekotekina <nekotekina@gmail.com>
2021-03-01 01:06:48 +03:00
Nekotekina 71e16bfac3 shared_ptr.hpp: minor fixup 2021-03-01 00:28:28 +03:00
Nekotekina b7c579adf9 Tentative fix for -Wattributes
These warnings enabled conditionally for GCC 10.1+.
2021-03-01 00:22:32 +03:00
Eladash 461fa6a88a Firmware installation bugfixes (#9855)
* Fix race condition in PUP installation abortion.
* Fix freezes of emulator in case the PUP installation failed due to filesystem errors.
* Use fs::create_path as opposed to fs::create_dir as it is can create upper directories in case they are missing and is better in error handling.
* Report TAR errors on failure to create directories.
* Fix pup_object constructor to not crash on invalid PUP file header. (report an error)
* Fix pup_object::validate_hashes to not crash on invalid PUP file entries. (report an error)
* Do not call Qt functions inside a named_thread because it is wrong.
2021-02-28 22:59:27 +03:00
Florin9doi dfee46604a Buzz settings 2021-02-28 22:36:47 +03:00
Megamouse a7c9827ad4 Improve cellScreenshot (#9851)
* Fix screenshot logging

* Update libpng to 1.6.37

* cellScreenshot: Write text chunks
* cellScreenshot: add overlay image
* screenshot_manager: add /dev_hdd0/photo/

* read_png_file: use deleter instead of manual close

* cellScreenshot: use Qt for overlays
* cellScreenshot: don't apply overlay to regular img
* screenshot_manager: add mount hack for VFS
* cellScreenshot: escape the whole path
2021-02-28 22:05:04 +03:00
Nekotekina f580bee32c Rewrite cellNetCtlNetStartDialogLoadAsync hack 2021-02-28 20:20:17 +03:00
Nekotekina de9d859f4a named_thread: implement task queue
atomic_ptr: implement push_head()

thread_ctrl::state() triggers task queue execution.
2021-02-28 20:20:17 +03:00
Nekotekina 3aaa0172d5 named_thread: implement "default" event loop
Fixup "sleepy" thread at startup on Windows.
Permit threads which lack operator()() overload.
2021-02-28 20:16:13 +03:00
Nekotekina 29e7eda887 named_thread: rewrite result_storage
Use SFINAE as permitted by std::invoke_result_t<>
2021-02-28 20:16:13 +03:00
Megamouse 7cb32a3680 Qt: set parent for QThread
This may or may not have caused a leak
2021-02-28 18:48:34 +03:00
Megamouse a4d4ab1df9 remove unused variable 2021-02-28 18:48:34 +03:00
kd-11 4bef176e9b vk: Fix inadvertent self-assign 2021-02-28 18:00:20 +03:00
kd-11 d2de8a87bf vk: Explicit initialization of command pool queue family 2021-02-26 15:08:14 +03:00
kd-11 12cad7c393 vk: Add per-queue-family scratch resources and double buffer them 2021-02-26 15:08:14 +03:00
kd-11 be1238cc95 vk: Add support for queue family migration and refactor some texture upload code 2021-02-26 15:08:14 +03:00
RipleyTom 67378c7dea Add CELL_NET_CTL_INFO_DHCP_HOSTNAME impl 2021-02-26 11:58:42 +03:00
Eladash c13039396c Fix stop count incremention in Emu.Stop (#9843)
Until emulation is completely stopped, further CallAfter callbacks may be issued with incorrect stop count memorized.
2021-02-25 14:37:31 +03:00
Megamouse e940632d93 Fix Nan in cpu_stats::get_usage
And apply same logic to linux and windows
2021-02-25 13:08:27 +03:00
Megamouse 6db25aa7fa overlays: Fix cpu usage in low detail mode 2021-02-25 13:08:27 +03:00
Eladash 0012f39384 Fix TTY handling of control characters 2021-02-24 16:42:39 +03:00
kd-11 0e7e5b59ae vk: Handle old GPUs without proper async queues 2021-02-23 23:22:41 +03:00
kd-11 d459da1378 Formatting fixes only
- Mostly remove camelcase usage in old code.
- Properly annotate vulkan API imports with _vk prefix to make it clear they are not regular variables.
2021-02-23 23:22:41 +03:00
Nekotekina 3063369322 vk::render_device::create: try to remove failing assertion 2021-02-23 19:46:37 +03:00
Nekotekina a90ad62fc0 Remove garbage SPUW perf report 2021-02-23 18:24:50 +03:00
Nekotekina cd01a1eb09 Move CPUStats.h -> util/cpu_stats.cpp 2021-02-23 18:24:50 +03:00
Nekotekina 090a769bf6 Implement fs::sync (Linux/POSIX) 2021-02-23 18:24:50 +03:00
Nekotekina 014846cf31 cellSaveData: fix minor issues 2021-02-23 18:24:50 +03:00
Megamouse b83cb2dbf5 product_info: add Harmonix Pro-Drum Kit (#9822)
Co-authored-by: DrGeelfood <79338929+DrGeelfood@users.noreply.github.com>
2021-02-23 18:23:53 +03:00
Eladash 112b7f6571 Fix Emulation::CallAfter
Most CallAfter usages were extremely wrong when ordered after Emu.Stop(). could result in anywhere from emulation stopping hangs to even segfaults.
track_emu_state = true is now the default, I haven't found cases which need need it disabled.
2021-02-23 17:55:36 +03:00
Eladash 68a878264c Minor GUI fix for PPU interpreter at "precompilation" 2021-02-23 17:35:45 +03:00
Megamouse a771f168eb overlays: fix perf overlay switching detail levels
The body was lagging behind the text. This was fixed by calling an updated version of init() on settings change.
This introduced spikes in the frametime graph, so the data had to become members and m_force_update was adjusted to not interfere with data aquisition.
2021-02-23 13:27:54 +03:00
Megamouse 79b5b79de1 overlays: fix initial size of perf_overlay body
You could see that it was not properly adjusted in the first frame in high detail mode.
2021-02-23 13:27:54 +03:00
Megamouse 7cc8380330 overlays: fix perf_metrics_overlay division by 0 2021-02-23 13:27:54 +03:00
Megamouse e91df31f8c overlays: Fix perf_metrics_overlay visibility
Also change auto type to compiled_resource in order to silence a warning about accidental copy by value
2021-02-23 13:27:54 +03:00
Megamouse 663b2c9c5e overlays: Fix frametime graph spikes
The frametime_timer was restarted at the end of the update method, instead of immediately after reading its value.
This means that the frametime was lower than expected when an expensive task was executed in-between.
2021-02-23 13:27:54 +03:00
RipleyTom 801467e565 Fix rpcn registration 2021-02-23 13:17:49 +03:00
Eladash 447d2b6f93 Atomic RSX capture writes 2021-02-23 11:29:23 +03:00
Eladash 9ccf39b27f Atomic SPU LS capture writes 2021-02-23 11:29:23 +03:00
Eladash d4af8dd89a Fix atomicity of savedata/trophy data writes 2021-02-23 11:29:23 +03:00
Eladash 932f31e37b Atomic PARAM.SFO writes 2021-02-23 11:29:23 +03:00
Megamouse 0878db4e17 remove unused variable 2021-02-23 05:03:38 +01:00
Megamouse 037586d7bb fix no-gui crash if no firmware was installed
It's a bit mysterious, but the confirmation box doesn't like being called in this mode.
So let's just return false.
2021-02-23 05:03:38 +01:00
kd-11 cb7cf40b5e vk: Move queue family management from swapchain to logical device 2021-02-23 00:04:53 +03:00
kd-11 3632412c48 vk/dma: Simplify map_dma interface 2021-02-23 00:04:53 +03:00
Nekotekina 4b858648e5 Add supporters 2021-02-22 19:37:42 +03:00
Nekotekina 85bebebb36 Add commits 2021-02-22 19:37:32 +03:00
Nekotekina 980be9e0e8 JIT.cpp: fix overcommit bug (should have been Linux-specific)
Closes #9820

Co-authored-by: Eladash <elad3356p@gmail.com>
2021-02-22 13:35:01 +03:00
Nekotekina ad1027455a Fix minor inconsistency in utils::memory_reset (Linux) 2021-02-22 13:00:01 +03:00
Nekotekina 9dc238187f Simplify utils::align() a bit
std::is_unsigned implies std::is_integral I believe.
2021-02-22 13:00:01 +03:00
Eladash 73d45f3bf0 Remove vm::cleanup_unlock 2021-02-22 12:47:45 +03:00
Eladash 96400234a8 Remove cpu_thread destructor 2021-02-22 12:47:45 +03:00
Megamouse 2e5f321583 evdev: fix build 2021-02-22 10:45:40 +01:00
Megamouse 5a9b29b73a hid: log more info when adding a device
And minor format changes
2021-02-22 10:45:40 +01:00
Megamouse 1b2260132b only call hid_exit when all hid_handlers are done 2021-02-22 10:45:40 +01:00
Megamouse 1479468730 Input: fix build 2021-02-22 10:45:40 +01:00
Megamouse f0b7afd7cc cellPad: minor optimization 2021-02-22 10:45:40 +01:00
Megamouse 870d26f9d8 Input: replace a bunch of static_pointer_cast 2021-02-22 10:45:40 +01:00
Megamouse f6d465667a Input: unify some more code 2021-02-22 10:45:40 +01:00
Megamouse aaae30cb84 DS3: inherit from hid_pad_handler 2021-02-22 10:45:40 +01:00
Megamouse fbb9396813 DualSense: inherit from hid_pad_handler 2021-02-22 10:45:40 +01:00
Megamouse b9a4abce0e DS4: inherit from hid_pad_handler 2021-02-22 10:45:40 +01:00
Megamouse d0cc5c0fc7 DS4: enumerate devices periodically 2021-02-22 10:45:40 +01:00
kd-11 b7c2bfbcde vk: Fix cyclic read-write in dma_block::load/flush
Some DMA block entries are stubs whose parents are DMA_block_EXT
entries.
Performing load() in this case becomes a memcpy(address,
same_address_again, length) which wastes performance and introduces
bugs.
2021-02-22 01:13:31 +03:00
RipleyTom 8be2a55ccc Add mutex lock for NP changes 2021-02-21 18:04:55 +03:00
RipleyTom 81270f3142 Remove now useless code from sys_bnet_connect 2021-02-21 18:04:55 +03:00
Eladash eb0d006168 Fix most of "[x] thread is too sleepy" at Emu.Stop() (#9813)
* Fixes some thread sleep/wait calls
2021-02-21 16:43:02 +03:00
Oschowa a47bda026b Audio/AL: Request our default sampling rate (48kHz) from AL when creating the
context.
Otherwise AL might downsample and output in 44.1kHz unnecessarily, which
happens at least on my system. Also tested on an audio device that
doesn't support 48kHz to makes sure that still works.
2021-02-20 14:31:38 +03:00
RipleyTom 5129d0da45 check alcGetString return pointers 2021-02-20 07:39:56 +01:00
Eladash b86ec2ffcf Fix potential overflows in utils::aligned_div, utils::rounded_div 2021-02-19 16:10:03 +03:00
Eladash 20eb4352fb debugger: Fix single stepping (#9793) 2021-02-19 14:53:09 +03:00
Nekotekina e76d8eb046 Fix -Wstring-aliasing (gcc) 2021-02-18 19:38:22 +03:00
Nekotekina c8fefc4434 Fix -Wpessimizing-move (Clang) 2021-02-18 14:38:56 +03:00
Nekotekina 2c18d67769 Fix -Wsometimed-uninitialized (Clang) 2021-02-18 14:15:52 +03:00
Nekotekina 428771f1d7 Fix -Wself-assign (clang) 2021-02-18 14:07:22 +03:00
Nekotekina 038148bf06 Fix almost all GCC warnings 2021-02-17 22:59:04 +03:00
RipleyTom 6786734d95 Fix mic device default in config 2021-02-17 18:15:58 +03:00
Nekotekina 1446254a03 Add error on missing 'override'
For consistency.
2021-02-15 20:21:30 +03:00
Nekotekina 3bcd76bd4e Fix regression (incorrectly removed specialization)
Changed CRLF->LF in VKPipelineCompiler.h
2021-02-15 17:05:51 +03:00
Nekotekina 0bcece4585 Make -Woverloaded-virtual an error
Had to devirtualize some functions.
2021-02-15 15:50:05 +03:00
Nekotekina 035ab590ec Reset -ftemplate-depth to normal
It became obsolete.
2021-02-15 14:40:29 +03:00
Nekotekina 8e6e57de86 Enable -Wunused-function warning 2021-02-15 14:39:53 +03:00
Eladash 4c1026436f Log "Missing Firmware" if firmware is missing 2021-02-15 09:50:52 +01:00
kd-11 9f97bab717 vk: Fixup and refactor for exclusive fullscreen stuff 2021-02-15 10:27:36 +03:00
13xforever 76518d4c59 add a hidden option to prevent switching to exclusive full screen mode
this is helpful for people streaming RPCS3, or to prevent disabling HDR mode in Windows
2021-02-14 22:01:33 +03:00
kd-11 eba7d3b172 rsx: Add duplicate section detection when there are too many sections in the surface cache
- Check for useless sections.
  Helps in games that create a bunch of sections randomly for one-time use
2021-02-14 20:42:34 +03:00
kd-11 b8311caa6b vk: Silence some compiler warnings 2021-02-14 20:42:34 +03:00
Eladash 5b044a93c1 Fix vm::falloc() for misaligned args (#9764)
Force addr/size alignment.
2021-02-14 13:19:14 +03:00
Eladash f009d36811 Update log messages of PPU/SPU hashes and patches applied 2021-02-14 09:35:42 +01:00
Eladash f43260bd58 Atomic waiting refactoring (#9208)
* Use atomic waitables instead instead of global thread wait as often as possible.
* Add ::is_stopped() and and ::is_paued() which can be used in atomic loops and with atomic wait. (constexpr cpu flags test functions)
* Fix notification bug of sys_spu_thread_group_exit/terminate. (old bug, enhanced by #9117)
* Function time statistics at Emu.Stop() restored. (instead of current "X syscall failed with 0x00000000 : 0")
2021-02-13 17:50:07 +03:00
Eladash cf384795d2 debugger: Improve PPU string constraints 2021-02-13 16:00:26 +03:00
Eladash 423cc1685c PPU LLVM: Reduce PRX/OVL compilation memory usage a little 2021-02-13 13:05:41 +03:00
Nekotekina 0a23a5ef50 Rewrite fs::get_parent_dir
Don't analyse full path if possible.
2021-02-12 21:43:30 +03:00
Nekotekina 629d608d4f Patch engine: add bd32, bd64 and utf8 patch types
bd32 is the same as be32 with a hint it's not executable.
utf8 is NOT null-terminated string, null can be added manually.
2021-02-12 21:43:30 +03:00
Nekotekina 00be247913 Add commits to the list 2021-02-12 21:43:30 +03:00
Eladash 5ed0cc293d Fix PS3 process exit/exitspawn 2021-02-12 19:39:47 +03:00
Eladash 5401cb7392 kernel explorer: Display all PRX/OVL segments 2021-02-12 15:27:59 +03:00
Eladash e26ae9899c Reimplement/fix PRX patches 2021-02-12 15:27:59 +03:00
Alex Saveau 48296c2ba6 Fixup for multi-thread shader compilation (loading stage) (#9762)
* Multi-thread shader compilation

This offers a huge improvement in startup performance. With around 13,000 shaders we go from ~1:30 to under 10 seconds. It looks like this was the original intention of the author given the outer scope recompile variable.

Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
2021-02-12 14:39:35 +03:00
Ani b858fceb4f vk: Support incomplete lavapipe
Disable features still unimplemented by lavapipe when using it:
- samplerAnisotropy
- shaderStorageBufferArrayDynamicIndexing
- wideLines
as of mesa 21.1.0-dev (aea36ee05e9, 2020-02-10)
2021-02-11 14:49:37 +03:00
kd-11 195fb1cf66 rsx: Improve texture cache invalidate
- Bunch of improvements
- Properly signal renderer to rebind textures!
- TODO: Range checks, should be pretty easy
2021-02-10 11:37:14 +03:00
kd-11 52acc23ecf rsx: Fix protection bug 2021-02-10 11:37:14 +03:00
kd-11 0a34fc4bcd vk: Offload garbage collection to offloader thread 2021-02-10 11:37:14 +03:00
kd-11 bec91aab7b rsx: Relax inheritance checks a bit
- It is not a fatal error for a texture to be defined where a framebuffer once existed.
2021-02-10 11:37:14 +03:00
kd-11 5a049d41fd gpu-open/vma: Optimize CheckAllocation method
- Avoids doing useless work. The scanning algorithm is painfully slow on hardware with alignment requirement > 1
- Upto 50ms saved for ~600 allocations when many small allocations exist
2021-02-10 11:37:14 +03:00
kd-11 6f4dbf4fcd vk/vma: Always use aligned requests
- Performance optimization when combined with vma optimizations added by me
2021-02-10 11:37:14 +03:00
kd-11 bf66c36ba4 rsx/texture_cache: Add support for reusing dirty images if possible
- Avoids a silly situation where a texture is discarded and an identical copy created immediately afterward.
  Unfortunately allocating memory blocks is really slow so avoid it as much as possible.
2021-02-10 11:37:14 +03:00
kd-11 0c10f47e85 rsx: Lower cache block length to 256 pages
- Drastically lowers time wasted iterating blocks when many small objects
  are present
2021-02-10 11:37:14 +03:00
kd-11 1bad9a939f rsx: Refactor texture cache utils
- Also lays groundwork for optional hashed sections
2021-02-10 11:37:14 +03:00
Megamouse 8d6504d6e3 GUI: initial log viewer 2021-02-09 22:56:28 +01:00
Ivan 04c187deb5 Revert "Replace GetEmuDir() with GetExeDir() in handle_rpcs3"
This reverts commit f9eb6a31bd.
2021-02-09 22:24:09 +03:00
Megamouse bc938ce630 dualsense: implement player LEDs 2021-02-09 19:21:37 +01:00
Megamouse e5f95a450d dualsense: update description 2021-02-09 19:21:37 +01:00
Megamouse b31d38eef7 LED settings: set modal and add has_battery check 2021-02-09 19:21:37 +01:00
Megamouse db402cb8af dualsense: add player LED support 2021-02-09 19:21:37 +01:00
Megamouse 1af6550db7 dualsense: add lightbar support 2021-02-09 19:21:37 +01:00
Megamouse 7795f5207f dualsense: fix switched motors
The left one seems to be the large motor
2021-02-09 19:21:37 +01:00
Megamouse a9b8a50c31 dualsense: add output report structs based on linux driver 2021-02-09 19:21:37 +01:00
Megamouse a9418fa1e7 dualsense: implement SetPadData for rumble in GUI 2021-02-09 19:21:37 +01:00
Megamouse 08f48d27e8 Input: minor simplification
This might prevent some copy paste error in the future
2021-02-09 19:21:37 +01:00
Megamouse 25a66da4ca Input: rename some functions 2021-02-09 19:21:37 +01:00
Megamouse ff61bc9e7c dualsense: add mic button 2021-02-09 19:21:37 +01:00
Megamouse 3e8f4ba018 dualsense: add gyro support 2021-02-09 19:21:37 +01:00
Jordy Vieira f9eb6a31bd Replace GetEmuDir() with GetExeDir() in handle_rpcs3 2021-02-09 20:06:26 +03:00
Nekotekina 4f8cac731b Fix SAFE_BUFFERS attribute for GCC 2021-02-09 12:33:50 +03:00
Nekotekina 3e496f6625 Add -fstack-protector (Non-MSVC) 2021-02-09 12:06:17 +03:00
kd-11 2d62f9c4c5 vk: Improve spec compliance (#9748)
- Always comply when running under strict mode
- Only allow hacky transport for known-to-work GPUs
2021-02-08 22:11:01 +00:00
Eladash 78811b8816 GUI: Always remove manually added fonts in OnChangeStyleSheetRequest() 2021-02-08 21:38:53 +01:00
Eladash e38cd5149a Fix firmware updating/reinstallation 2021-02-08 21:38:53 +01:00
Megamouse dc2a1e270a Qt: Repaint log on stylesheet change 2021-02-08 13:24:07 +03:00
Megamouse 44ab50553d Qt: Replace relative paths in stylesheets instead of changing the working directory 2021-02-07 20:07:58 +03:00
Megamouse 7c683c368d Qt: Fix weird naming issue on linux 2021-02-07 20:07:58 +03:00
Megamouse 62ca7a9b60 Qt: Simplify stylesheet logic 2021-02-07 20:07:58 +03:00
Nekotekina 632e36ab44 Qt: fix stylesheets on various platforms
Replace relative paths to resources.
Paths should start from GuiConfigs.
2021-02-07 14:09:50 +03:00
Nekotekina 0057c89eaa PPU Analyser: follow fallbacks in some cases
Fallback is an "invisible" branch to the next instruction.
This may be necessary for certain cases when patches are used.
2021-02-07 11:02:45 +03:00
Nekotekina 9e9a55df46 PPU LLVM: compile instructions from patches
For now, only as a single instruction at a time.
2021-02-07 11:02:31 +03:00
Nekotekina 9463238490 PPU Analyser: minor fixups for end pointer
Add more sanity checks for sections.
Remove some redundancy.
2021-02-07 11:02:31 +03:00
Nekotekina b7ff2ecffb Patch system: export some info for future use
For now it's just a list of addresses.
For now it's not used (just a stub).
2021-02-07 11:02:31 +03:00
Eladash fad89f1c3b Fix tiny race in PPU breakpoints (#9731)
If the PPU has just being paused by the debugger, before it entered the breakpoint handler, the PPU would continue onto the next instruction skipping the breakpoint but then being paused on it instead.
2021-02-07 00:25:40 +03:00
Nekotekina 5063eefa96 Fixup for downloader 2021-02-06 15:21:00 +03:00
Nekotekina 1b34fa26ac Update commits.lst (example) 2021-02-06 12:57:14 +03:00
Nekotekina 25827c12a3 Make out of source builds get copy of /GuiConfigs/, /git/, etc.
Reduce quality of kot-bg.jpg.
2021-02-06 12:55:14 +03:00
Nekotekina cb32fd15ee Add supporters 2021-02-06 00:37:53 +03:00
Nekotekina d6dcab443d Updater: add minor sanity check 2021-02-06 00:37:53 +03:00
Nekotekina c32fec774f Create mini-cache for commits
Located in bin/git/commits.lst;
Created with GitHub API with --get-commit-db key.
Can be lazily appended with the same key.
2021-02-06 00:37:53 +03:00
kd-11 ddac4686a7 rsx: Clear vertex output register if nothing is written to it
- On NVIDIA GPUs, gl_Position is not initialized. Always clear to 0 to avoid on-screen crap
2021-02-05 22:22:07 +03:00
Megamouse 2865865382 Don't use std::exit during Qt initialization 2021-02-05 17:32:48 +01:00
Eladash 7ce835e878 Support logger stopping at std::exit (#9722) 2021-02-05 17:07:17 +03:00
Megamouse 7e0fdbbe99 Fix rpcs3.vcxproj 2021-02-04 23:11:05 +01:00
Megamouse fd1f2ca1c6 Rename some variables to snake_case 2021-02-04 23:11:05 +01:00
Nekotekina a6a92f7b6b Qt: remove Q_OBJECT for mouse/kb handlers
Had to move QObject in parent list for g_fxo changes.
2021-02-04 23:11:05 +01:00
Eladash 4f85f151fd SPU: Always signal the debugger about termination 2021-02-03 15:05:38 +03:00
Eladash 478ae0715e Tiny fix for zombie PPU threads 2021-02-03 15:05:38 +03:00
Megamouse 714eb6dcc5 Disable LimitCacheSize option in custom configs
It doesn't make sense on a per game basis and is used before loading them anyway
2021-02-02 18:37:18 +01:00
Megamouse 89942ed92a optimize add_only boot process
No need for hardcore stuff while adding games to the list
2021-02-02 18:37:18 +01:00
Megamouse 6ed9251f44 Remove tooltip event filter from gamelist
Fixes a weird issue where tooltips for the wrong game would popup.
I don't know why the event filter was needed.
Maybe the tooltips didn't work otherwise back then or it was just some copy paste from google.
2021-02-02 15:46:42 +01:00
Megamouse 2c32a721fc Allow BootGame with indirect paths 2021-02-02 13:21:26 +01:00
Nekotekina 08aaae7999 PPU LLVM: workaround patch handling
Try to address #9704
2021-02-02 10:33:13 +03:00
Nekotekina 78bad361ab Fix fs::unread (Linux)
Detach from fs::lock
Handle existing file case (unlink it).
2021-02-02 01:05:53 +03:00
Eladash 2005c89baa memory viewer: Implement RSX mode
* Set the ground for RSX modes of register editor and insttruction editor, do not use shared ptrs directly.
* Make register editor and instruction editor modeless to allow to copypaste values from thread context etc in the background.
2021-02-02 01:05:36 +03:00
Megamouse 8c6aa9db31 Print report_fatal_error to cmd
useful if used like:
start /w ./rpsc3 --headless <path>
2021-02-01 21:44:23 +01:00
Nekotekina 58eef983e2 PPU Analyser: fix constraints for all elfs.
Added for main executable and OVLs.
Forgot to use it not just for SPRX.
2021-02-01 19:14:24 +03:00
Nekotekina 390b192f0a TSX: workaround for check_state freezes 2021-02-01 19:14:24 +03:00
Nekotekina 7b40859eff Remove unused header 2021-02-01 19:14:01 +03:00
Nekotekina d0126f0fa0 Fix freezes in HLE Vdec and SPU LLVM precompilation.
Freezes could accidentally occur on close or ingame.
Deprecate range-for loop on lf_queue.
This is a part of PR #9208

Co-authored-by: Eladash <elad3356p@gmail.com>
2021-02-01 19:14:01 +03:00
Nekotekina 0c034ad7de PPU LLVM: upgrade to GHC call conv
Get rid of some global variables.
Implement ppu_escape (unused yet).
Bump PPU cache version to v4.
2021-02-01 11:30:50 +03:00
Nekotekina aeeceb7d0b Minor fixups 2021-02-01 11:30:50 +03:00
Nekotekina d5f16ce272 PPU Analyser: better constraints for SPRX 2021-02-01 11:30:50 +03:00
Nekotekina c89362f6a2 PPU LLVM: don't use module name as PRX indicator 2021-02-01 11:30:50 +03:00
Nekotekina 8a029159cd PPU Analyser: compile certain functions on per-instruction basis
PPU LLVM: optimize small blocks
2021-02-01 11:30:50 +03:00
Nekotekina 891ebd0cb1 PPU Analyser: use reloc info (disabled for now)
Add blocks from relocations.
2021-02-01 11:30:50 +03:00
Nekotekina 382509d778 PPU LLVM: Implement inline __add_get_ov 2021-02-01 11:30:50 +03:00
Nekotekina f9ee8978ff PPU LLVM: improve analyser
Compile possibly executable holes between detected functions.
Add unused "PPU LLVM Greedy Mode" option (for future updates).
Add "nounwind" attribute to compiled functions (reduces size).
2021-02-01 11:30:50 +03:00
Eladash e71c2df39d Debugger: Add some more shortcut descriptions in F1 helper 2021-02-01 00:21:50 +03:00
Eladash cfc7865f82 Debugger: Allow to unpause a thread which has been paused by global pause 2021-02-01 00:21:50 +03:00
Nekotekina cf6606065d PPU: fix some typos in asm code 2021-01-31 20:00:04 +03:00
Megamouse 9feb92df1b More informative Error message on Vulkan driver crash
The message might not be the only reason, but at least it might help someone like me, who had no idea what he was looking at.
2021-01-31 15:51:21 +01:00
Megamouse be26810cd7 RSX: Implement set_value for progress dialogs 2021-01-31 15:02:26 +01:00
Megamouse df79b6c238 RSX: update shader loading dialog at 60 fps
Looks much smoother
2021-01-31 15:02:26 +01:00
Eladash 82c86ed2f7 Implement standalone OVL (overlay) loading mode
* Allow to load OVL alone.
* Add error checks in ppu_load_exec(), do not crash on error.
* Fix crash on exit from standalone PRX mode, allow kernel explorer to work with it as well for the added OVL mode.
2021-01-31 15:47:05 +03:00
Eladash 9077563dac Add missing destructor of progress dialog 2021-01-31 12:55:20 +01:00
Eladash 8d15f44b33 Fix ppu progress dialog percentage 2021-01-31 12:55:20 +01:00
Eladash b3fbada10e Fix potential crash of progress dialog 2021-01-31 12:55:20 +01:00
Megamouse 31cdd7bdd2 Prevent minor race in Progress Dialog Server 2021-01-31 12:18:32 +03:00
Megamouse c464e90d5d Fix stop exit of check_only ppu_initialize 2021-01-31 12:18:32 +03:00
Megamouse 670d2b191c Minor optimization for check_only ppu_initialize 2021-01-31 12:18:32 +03:00
Megamouse 7bddb87306 Simplify compile threads 2021-01-31 12:18:32 +03:00
Megamouse 2025f02105 Search for more game data directories.
Also properly remove duplicate paths
2021-01-31 11:42:33 +03:00
Megamouse 1078626eea Fix ppu compilation progress dialog
We could only increase the value because we completely based the dialog on cellMsgDialog.
This led to an issue where the dialog would increase its maximum and thus decrease the current percentage.
It then couldn't decrease and was stuck on the old percentage.
2021-01-30 21:34:16 +01:00
Eladash 16c6b44f55 Fix #9680 (#9687)
Fix regression from #9680
2021-01-30 19:05:02 +03:00
Eladash 6b3b06df25 rsx: Set frame limit to auto by default 2021-01-30 16:53:14 +03:00
Eladash e3b3b0cda7 PPU LLVM: Precompile all executable (PRX, MSELF, overlay) code at startup (#9680)
* Precompile LLVM cache at startup of games, like the GUI "Create PPU Cache" option.
* Allow OVL (overlay) precompilation as well (used by certain games).

Co-authored-by: Megamouse <studienricky89@googlemail.com>
Co-authored-by: Nekotekina <nekotekina@gmail.com>
2021-01-30 16:08:22 +03:00
Nekotekina bb2cc196a6 Fixup for preloading SPRX from MSELF
Forgot to append the offset.
Forgot to use different loop variable.
2021-01-29 21:26:34 +03:00
Eladash d3bc96a201 Fix minor issue with usage of STL thread::hardware_concurrency() 2021-01-29 18:23:29 +03:00
Nekotekina 11ba6e45ab Add MSELF support to SPRX precompilation.
Add ppu_precompile() function in PPUThread.cpp

Co-authored-by: Eladash <elad3356p@gmail.com>
2021-01-29 13:34:43 +03:00
Eladash a742501a4f Do not account RSX for TSX pauses 2021-01-29 10:31:15 +03:00
Eladash 70346028c5 Fix GCM HLE
Oops.
2021-01-29 10:31:15 +03:00
Megamouse 3359458175 Handle missing cases of Emu.BootGame failure 2021-01-28 20:54:27 +01:00
Nekotekina 6784301376 Check for rsx::thread existence in Emu.Stop/Pause/Resume 2021-01-28 20:23:13 +03:00
Megamouse 51d19e7c31 Input: remove debug error 2021-01-28 18:02:23 +01:00
Eladash 0652870204 New RSX Debugger 2021-01-28 17:40:26 +03:00
Nekotekina 67dd6754a6 Seal cereal includes in util/cereal.cpp 2021-01-28 10:48:53 +03:00
Nekotekina 34274ec391 Purge unused typeid() invocations 2021-01-28 10:23:29 +03:00
Eladash 28feea0447 Unfatal Segfaults 2021-01-27 21:54:29 +03:00
Nekotekina 53267e283b PPU LLVM: implement ppu_finalize
Properly free certain compiled PRX/OVL modules (except dev_flash)
2021-01-27 18:03:49 +03:00
Nekotekina 15ed963a29 UI: Add supporters 2021-01-27 14:23:26 +03:00
Nekotekina c652d0b183 Detect execution access violation
Don't try to handle it, treat as fatal.
2021-01-27 11:53:10 +03:00
Nekotekina 22c55cbcfa Add trace logging to thread_ctrl::set_thread_affinity_mask 2021-01-26 19:59:48 +03:00
Nekotekina c24d89dd34 Threads: fix typo in emergency_exit (dump useful info) 2021-01-26 19:58:47 +03:00
Nekotekina f10ea1fb9b Thread pool: try to fix resetting affinity mask
Attempt to address #9657
2021-01-26 16:45:36 +03:00
Nekotekina eb72cc9f04 Thread pool: reset thread affinity mask 2021-01-25 22:05:38 +03:00
Nekotekina ee288340b0 Implement thread_ctrl::scoped_priority
RAII priority control (+1, or -1)
2021-01-25 21:49:16 +03:00
Nekotekina a69248299d SPU: Don't use shm::map_critical in SPU LS allocations
Use shm::try_map instead until proper area is found.
2021-01-25 17:45:47 +03:00
Nekotekina caa83d20f7 vm_native.cpp: implement shm::try_map
Treats addr as a hint, emulating windows behaviour.
2021-01-25 16:55:19 +03:00
Malcolm Jestadt 486d48e4f8 SPU LLVM: Optimize ROTQBY family for VBMI
- Avoid masking pshufb index by 0xf by using vpermb instead.
- Also fix conversion of vperm2b index to ShuffleVector index.
2021-01-25 13:18:23 +03:00
Nekotekina 8480674708 Thread pool: reset priority 2021-01-24 16:45:28 +03:00
Ani 7c62574e59 spu: Restore workers priority after initialization 2021-01-24 16:40:59 +03:00
kd-11 22584fb2d1 vk/dma: Disable pasthrough DMA for NVIDIA+windows
- The driver seems to cache page mapping as long as allocation has not been removed
- This is undesirable as we cannot stop the emulator to remove stale allocations every time a page is unmapped
2021-01-24 14:24:55 +03:00
kd-11 90ac9165e2 vk/dma: Unmap pages from GPU when they are unmapped in Cell 2021-01-24 14:24:55 +03:00
kd-11 bcb69a54b2 gl: Avoid type shenanigans used to fake byteswap for select formats
- Just use the reversed type instead.
  The new uploader backend combines swizzle+swap so there is no need for tricks anymore
2021-01-24 14:24:55 +03:00
kd-11 f93cb262ba vk/dma: Fix multiple logical bugs
- Fix range chaining.
- Add validation checks that no overlaps exist.
2021-01-24 14:24:55 +03:00
kd-11 67949bb5b7 vk/dma: Allow interoperability between pass-through and write-back DMA caching types 2021-01-24 14:24:55 +03:00
kd-11 e56da4eb46 vk: Workaround for amdgpu kernel driver 2021-01-24 14:24:55 +03:00
kd-11 f7fdfe52bc vk: Fix custom event signals 2021-01-24 14:24:55 +03:00
kd-11 7de0ff337b vk: Polishing and cleanup
Some spec violations fixes
Make the option dynamic
2021-01-24 14:24:55 +03:00
kd-11 e1c0a917fa vk/dma: Modify default page size to 64k 2021-01-24 14:24:55 +03:00
kd-11 ead180aa60 win32: Be a bit more optimistic with allocated ranges; we get contiguous ranges more often than not 2021-01-24 14:24:55 +03:00
kd-11 58d367d704 vk: Add host-imported DMA buffers 2021-01-24 14:24:55 +03:00
kd-11 a1ab6c28c1 vk/rsx: Fix some more bugs 2021-01-24 14:24:55 +03:00
kd-11 59e46f09b7 vk/dma: Disable memory inheritance
- It is not possible to emulate passthrough memory cleanly, and we don't need to
  A stupid race condition appears when trying to synchronize DMA blocks with memory inheritance.
  Since the usage pattern is to acquire a range and then load or write+flush, this new data is going to be..
  overwritten by the commandbuffer execution sequence later. Acquiring a scratch buffer to hold CPU content during the transition is not worth the effort..
  as the data will be destroyed anyway during the transfer process immediately afterwards.

  Fixes data corruption when moving data around using the emulated DMA passthrough
2021-01-24 14:24:55 +03:00
kd-11 7766076042 rsx/vk: DMA stuff 2021-01-24 14:24:55 +03:00
Eladash b96864c7e6 rsx: Improve gs frame exit workaround
Move to close(), hide before potential hanging at Emu.Stop()
2021-01-23 12:45:53 +03:00
Eladash 79513f06a4 rsx/gui: Delay game window pop-up until first frame 2021-01-23 12:45:53 +03:00
RipleyTom 00ff53499a fix UserInfo2_to_SceNpUserInfo2 2021-01-22 20:51:10 +03:00
Eladash 142b44d4be debugger: Implement F1 helper 2021-01-22 00:39:41 +01:00
Eladash 7f28489c70 Improve ppu_thread_cleaner a bit
Always join thread.
2021-01-21 21:32:13 +03:00
Eladash a58c12db0b SPU: fixup after #9630
Co-Authored-By: Ivan <nekotekina@gmail.com>
2021-01-21 21:32:13 +03:00
Eladash 12e1be2626 Implement thread_ctrl::wait_on (see #9208) 2021-01-21 18:31:51 +03:00
Eladash f81674232e Remove SPU and PPU destructors 2021-01-21 18:31:51 +03:00
kd-11 eb086b0e3f rsx: Add support shadow1D and shadowCube 2021-01-21 10:24:49 +03:00
kd-11 b6b9085773 rsx: Use unsigned variables to avoid sign problems when calculating stipple bits 2021-01-21 10:24:49 +03:00
Nekotekina 241989c5fa Fix new warnings
Added CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0+ enums.
Added CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY0+ enums.

Co-authored-by: Eladash <elad3356p@gmail.com>
2021-01-20 12:27:37 +03:00
Nekotekina f944573b3c Fix old warnings: remove strncpy
Use strcpy_trunc instead.
Change some sce structs.
2021-01-20 12:26:09 +03:00
Nekotekina c66b155dcb Remove unnecessary fmt::throw_exception destructor body
Tested with GCC and Clang in Debug mode, it now works.
2021-01-20 09:02:25 +03:00
RipleyTom 5662867730 Change the way skylander ID is generated 2021-01-20 08:46:39 +03:00
Eladash dbecf0fa50 Introducing RSX debugger entry (main debugger) 2021-01-19 22:55:12 +03:00
Megamouse 62cb532460 Qt: hotfix for downloader
I accidentally broke the download progress bar in the last related PR.
I should've put more trust in the sanity of the younger version of myself.
This should fix it.
2021-01-18 22:41:31 +01:00
Nekotekina f9bc682115 Refactor some 'offending' code a bit (no effect)
It appears linkage errors were rare even in debug mode (GCC/clang).
2021-01-18 21:58:28 +03:00
Nekotekina 6cf0c5cd6d Fix fmt::throw_exception destructor v2
Remove destructor for MSVC.
2021-01-18 21:19:34 +03:00
Nekotekina 8a2a76da1e texture_cache: fix some warnings in AUDIT 2021-01-18 13:49:59 +03:00
Nekotekina e07484f057 Rewrite fmt::throw_exception destructor
Add _DEBUG in debug mode for consistency with MSVC.
2021-01-18 13:49:16 +03:00
Eladash 0070fce286 Compilation fix (#9622) 2021-01-18 13:41:39 +03:00
Malcolm Jestadt a2e8e3090c SPU LLVM: Optimize FSM following comparison
- FSM following a comparison instruction can be optimized to a single shuffle instruction
2021-01-17 16:52:44 +03:00
Nekotekina 0ac68def49 vm_native.cpp: minor compilation fix 2021-01-17 15:14:11 +03:00
Nekotekina def364fe28 SPU LLVM: add splat_scalar helper
Unrolls into zshuffle from the preferred slot.
2021-01-17 15:13:28 +03:00
Alex James c06707c891 CMake: Unset LIBUSB_LIBRARIES when using libusb submodule
If the system has libusb installed but USE_SYS_LIBUSB is false, the
static libusb will link against the system libusb (as pkg_check_modules
sets LIBUSB_LIBRARIES, and 3rdparty/libusb_cmake/libusb.cmake links the
usb-1.0-static target with LIBUSB_LIBRARIES). Unset LIBUSB_LIBRARIES to
avoid this when using the libusb submodule.
2021-01-17 13:51:03 +03:00
Alex James d7a8d385d8 CMake: Use find_package to find SDL2
This ensures that the SDL2 uses an absolute library path, which is
necessary when SDL2 isn't present in the default link directories (e.g.
on macOS).
2021-01-17 13:51:03 +03:00
Nekotekina 3567c43fb5 LLVM: generate trampolines for "null" functions
Embed name into the trampoline for easier debugging.
Only warn about it during the compilation phase.
2021-01-15 21:38:33 +03:00
Nekotekina aaaeb66cc8 vm: Minor fix in vm::close
Supplied size was wrong.
2021-01-15 20:12:30 +03:00
Nekotekina 4ed76a15ff Use different approach in shm::unmap_critical (Linux)
For now, set protection to PROT_NONE.
Attempt to address #9609
2021-01-15 20:11:09 +03:00
Nekotekina b5837d1271 Memory: use MADV_DONTDUMP if available (Linux)
Also refactor other madvise() usage
2021-01-15 19:54:41 +03:00
Eladash e4c3b1c2bd vm: Remove vm::dealloc_verbose_nothrow 2021-01-15 17:37:52 +03:00
Nekotekina ea916fd7e1 Memory: fix critical bug in shm::unmap_critical (Linux)
It was leaving holes in reserved areas.
Windows is unaffected.
2021-01-14 18:04:29 +03:00
Nekotekina 4bee8dc37f Crypto: modernize key_vault.h
Use constexpr, remove warning guards
2021-01-14 15:23:52 +03:00
Nekotekina 8b01d05146 Crypto: modernize ec.h
Add const, use u8
2021-01-14 15:17:07 +03:00
Nekotekina 376e564cff Crypto: make global vars in ec.cpp thread_local 2021-01-14 12:01:41 +03:00
Nekotekina caf02d1841 Crypto: don't modify EDAT_IV (all zeros)
I didn't notice where it gets restored to zeros.
2021-01-13 21:57:38 +03:00
Nekotekina 6cf73fad13 Crypto: workaround -Wunused-variable
Ignore for key vault for now.
2021-01-13 19:02:14 +03:00
Megamouse cfe660ab35 Qt/curl: fix segfault in curl
The QThread lived longer than the m_curl object.
This lead to a crash when closing RPCS3 while the download is still in progress.
2021-01-13 19:01:58 +03:00
Megamouse 8eaf76394c Qt/Input: Use ellipsis as "mouse deadzone"
This is experimental and smoothens the existing square shaped deadzone
2021-01-13 11:25:33 +01:00
Megamouse a692adefd7 Remove legacy patch support 2021-01-13 10:39:17 +01:00
Eladash e05f1c37ad memory viewer: Close all instances after emulation exit 2021-01-12 23:57:36 +03:00
Eladash 923fcc3b3d utils::shm: Hotfix after #9578 2021-01-12 23:57:36 +03:00
Eladash c50b9bc4b4 utils::shm: Make map_self() atomic (#9578) 2021-01-12 19:53:18 +03:00
Eladash e1f95ceb54 sceNpTrophy: Fix sceNpTrophyRegisterContext for handler abortion (#9586)
* Implement handler abortion during context registration.
* Fixed recursive calls to sceNpTrophy functions such as by callbacks from registering context.
* Turns out the reader lock for context registeration was incorrect because ctxt->tropusr and trophy directory are being modified. Made it an exclusive lock after callback.
2021-01-12 19:14:51 +03:00
Megamouse eb77495d5f Implement richtext_item_delegate
And use it in pkg_install_dialog
2021-01-12 14:13:15 +01:00
Megamouse 270d602a26 Add filename to multi pkg installation
Some packages are indistinguishable otherwise
2021-01-12 14:13:15 +01:00
Megamouse dd41ee68de Simplify numbered_widget_item 2021-01-12 14:13:15 +01:00
Megamouse 46dc40f3f1 Add filename to single pkg installation
Some file info is indistinguishable otherwise
2021-01-12 14:13:15 +01:00
Megamouse 7c7af2e102 fix rebase conflicts 2021-01-12 14:13:15 +01:00
Megamouse 36189b8c3b Try to distinguish between Update and DLC (Part 2) 2021-01-12 14:13:15 +01:00
Megamouse cde802b16c Move blocking code in order to free the explorer 2021-01-12 14:13:15 +01:00
Megamouse 1500e5f588 Try to distinguish between Update and DLC 2021-01-12 14:13:15 +01:00
Megamouse fbe91fb245 fix linux compilation 2021-01-12 14:13:15 +01:00
Megamouse 321e7d6977 Don't hide the PKG install progress dialog after each package 2021-01-12 14:13:15 +01:00
Megamouse 56488a4ac9 Use boolean values in unedat 2021-01-12 14:13:15 +01:00
Megamouse 4a75f44d47 Minor include cleanup in utlis.h 2021-01-12 14:13:15 +01:00
Megamouse deb4b03200 Add VERSION fallback to GetPkgInfo 2021-01-12 14:13:15 +01:00
Megamouse df94c906da Add more info to PKG install progress dialog
And fix installation of single packages
2021-01-12 14:13:15 +01:00
Megamouse 4d50d9daa4 unpkg: add missing break and some cleanup 2021-01-12 14:13:15 +01:00
Megamouse 0624bdc72d Use package reader in pkg_install_dialog 2021-01-12 14:13:15 +01:00
Megamouse ccec6e53c0 Rename package_reader member variables 2021-01-12 14:13:15 +01:00
Megamouse 68d411918d Read patchsets from compat db 2021-01-12 14:13:15 +01:00
Nekotekina f14d47bfe6 LLVM: log certain null functions 2021-01-12 15:39:43 +03:00
Nekotekina 0af452720e RSX: Fix possible bug in memory streaming utils 2021-01-12 15:06:31 +03:00
Nekotekina db8e6fe7a7 Enable -Wunused-variable 2021-01-12 14:34:14 +03:00
Nekotekina 631d7d0ce7 Enable -Wunknown-pragmas 2021-01-12 13:01:17 +03:00
Nekotekina ed345e5b65 Enable -Winvalid-offsetof 2021-01-12 13:01:17 +03:00
Nekotekina d3a66af7d6 Enable -Wcomment warning 2021-01-12 13:01:17 +03:00
Megamouse 52deff06ba Random stuff (#9589)
* minor coding style adjustment

* Qt: simplify osk dialog buttons

* replace std::find_if with convenience functions

* RSX: use sv in swizzle comparison

idk, I'll remove this if it was intentional.

* overlays/osk: rename enter to return

This one confused me and make me look for a bug that caused the "enter" key to be disabled, while it was actually the return key (obviously xD).
2021-01-12 12:59:50 +03:00
Megamouse 838cbe1840 tiny include fix 2021-01-11 13:04:46 +03:00
Eladash 70804e2ba6 kernel explorer: Make it single-instance tool 2021-01-10 20:30:23 +01:00
Eladash 07c925223b rsx: Fix index array offset bits 2021-01-10 18:40:02 +03:00
kd-11 c2cbc62be6 vk: Refactor some uber-headers
- VKHelpers was the rug everything was swept under for a long time.
  This commit essentially deprecates its usage across most of the backend.
2021-01-10 12:04:31 +03:00
Nekotekina 9d74d42f2a Fix compilation for gcc-11
In response to #9557
2021-01-09 14:38:01 +03:00
Nekotekina a36f25c7b2 Update LLVM to latest commit 2021-01-09 11:05:12 +03:00
Nekotekina 86fb5412fa Update ASMJIT to oldstable 2021-01-09 11:05:11 +03:00
Nekotekina c5b9ab3aca Update ASMJIT submodule URL 2021-01-09 11:05:11 +03:00
Eladash bf6f43ec3a Utils: Rewrite fmt::split 2021-01-08 22:23:48 +03:00
Megamouse 36159c2bd4 Add comment for deprecated avcodec_register_all
Apparently this is now done automatically and doesn't even need to be called at all
2021-01-08 14:36:49 +03:00
Megamouse 72e1d03860 Qt: ugly fix for ugly deprecation warning
Apparently Qt wants us to implement each comparison on our own, and there is no simple replacement for this.
2021-01-08 14:36:49 +03:00
Megamouse ed1b8f2545 game_list: fix deprecation warning
We only need to check if the data is valid for clicks on empty space in the game grid. I don't remember why I initially checked < 0
2021-01-08 14:36:49 +03:00
Nekotekina 1ad0f24ecd Fix or silence Qt warnings 2021-01-07 13:18:48 +03:00
Nekotekina 586440622b Silence another warning (clang) 2021-01-07 12:46:45 +03:00
Nekotekina 6231b07d2a Silence one warning (clang) 2021-01-07 12:42:15 +03:00
Nekotekina 1dcf5e4f85 Error on no return type warning
Added non-existing noreturn destructor to fmt::throw_exception (for clang).
2021-01-07 11:56:16 +03:00
Nekotekina 9ba8f4795c Remove redundant #pragma once 2021-01-06 23:33:37 +03:00
Eladash 951fe3491e PS3 Loader: Fix sections memorizing 2021-01-06 23:21:38 +03:00
Nekotekina 6ae1f1b02c VFS: fixup handling . and .. after #9528 2021-01-05 16:16:01 +03:00
Nekotekina 673e84920b fixed_typemap.hpp: remove useless reporters 2021-01-05 16:16:01 +03:00
Eladash d1e1c14dc3 VFS: Escape path components which end with space or period 2021-01-05 16:15:47 +03:00
Megamouse 11db3151ae VK refactoring Part 2 (#9542) 2021-01-05 10:49:03 +03:00
Josh Lay 65f81aca0f Docs: Update BUILDING.md (Fedora)
The package `qt5-devel` isn't available, but the `qt5-qtbase-devel` package is 😄 

Before:
```
[root@workstation ~]# dnf install alsa-lib-devel cmake glew glew-devel libatomic libevdev-devel libudev-devel openal-devel qt5-devel qt5-qtbase-private-devel vulkan-devel
Last metadata expiration check: 0:06:39 ago on Mon 04 Jan 2021 08:00:59 PM CST.

Package alsa-lib-devel-1.2.4-5.fc33.x86_64 is already installed.
Package cmake-3.18.4-2.fc33.x86_64 is already installed.
Package glew-2.1.0-8.fc33.x86_64 is already installed.
Package libatomic-10.2.1-9.fc33.i686 is already installed.
Package libatomic-10.2.1-9.fc33.x86_64 is already installed.
Package systemd-devel-246.7-2.fc33.x86_64 is already installed.
No match for argument: qt5-devel
Package vulkan-loader-devel-1.2.148.1-1.fc33.x86_64 is already installed.
Error: Unable to find a match: qt5-devel
[root@workstation ~]#
```
After:
```
[root@workstation ~]# dnf install alsa-lib-devel cmake glew glew-devel libatomic libevdev-devel libudev-devel openal-devel qt5-qtbase-devel qt5-qtbase-private-devel vulkan-devel
[...]
Installed:
  cups-devel-1:2.3.3op1-1.fc33.x86_64            glew-devel-2.1.0-8.fc33.x86_64  libevdev-devel-1.9.1-3.fc33.x86_64  openal-soft-devel-1.19.1-9.fc33.x86_64 
  qt5-qtbase-private-devel-5.15.2-2.fc33.x86_64 

Complete!
[root@workstation ~]# 
```
Build verified working on Fedora 33 with 187216096d
2021-01-05 10:27:56 +03:00
matoro 187216096d Build: Add include for building on certain configs 2021-01-04 10:04:51 +03:00
kd-11 3f9b699eef rsx: Fix ambiguous call to min(float16_t, float) 2021-01-04 02:28:24 +03:00
kd-11 5f8564c655 Update Utilities/Thread.cpp
Co-authored-by: Bird Egop <sampletext32@bk.ru>
2021-01-03 19:31:18 +03:00
kd-11 cbe0000d23 Improved Zen chip detection 2021-01-03 19:31:18 +03:00
Eladash 0e278d2299 rsx: Make FP shader cache load lock-free 2021-01-03 01:47:07 +03:00
Eladash 21d725daa5 rsx: Fix shader cache of 2 or less pipelines 2021-01-03 01:47:07 +03:00
Eladash 247e90b3d0 rsx: Shaders cache loading and saving bugfixes
* Fixed crash whenever files are missing from the cache.
* Fixed crash whenever files are empty.
* Fixed crash whenever file creation/overwrite of cache files failed. (handled by fs::write_file)
* Fixed crash whenever there are any subdirectories inside the pipelines cache directories.
* Overwrite invalid shader cache files if encountered such.
* Optimizations have been added.
2021-01-03 01:47:07 +03:00
774 changed files with 51954 additions and 28727 deletions
+4 -4
View File
@@ -7,10 +7,10 @@ git submodule -q update --init --depth 1 $(awk '/path/ && !/llvm/ { print $3 }'
# Prefer newer Clang than in base system (see also .ci/install-freebsd.sh)
# libc++ isn't in llvm* packages, so download manually
fetch https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/libcxx-11.0.0.src.tar.xz
tar xf libcxx-11.0.0.src.tar.xz
export CC=clang11 CXX=clang++11
export CXXFLAGS="$CXXFLAGS -nostdinc++ -isystem $PWD/libcxx-11.0.0.src/include"
fetch https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.0/libcxx-12.0.0.src.tar.xz
tar xf libcxx-12.0.0.src.tar.xz
export CC=clang12 CXX=clang++12
export CXXFLAGS="$CXXFLAGS -nostdinc++ -D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS -isystem $PWD/libcxx-12.0.0.src/include"
CONFIGURE_ARGS="
-DWITH_LLVM=OFF
+8 -4
View File
@@ -5,7 +5,9 @@ export QT_BASE_DIR=/opt/qt${QTVERMIN}
export PATH=$QT_BASE_DIR/bin:$PATH
export LD_LIBRARY_PATH=$QT_BASE_DIR/lib/x86_64-linux-gnu:$QT_BASE_DIR/lib
cd rpcs3 || exit 1
if [ -z "$CIRRUS_CI" ]; then
cd rpcs3 || exit 1
fi
# Pull all the submodules except llvm, since it is built separately and we just download that build
# Note: Tried to use git submodule status, but it takes over 20 seconds
@@ -55,9 +57,11 @@ ninja; build_status=$?;
cd ..
# If it compiled succesfully let's deploy depending on the build pipeline (Azure Pipelines).
# Azure publishes PRs as artifacts only.
{ [ "$IS_AZURE" = "true" ];
shellcheck .ci/*.sh
# If it compiled succesfully let's deploy.
# Azure and Cirrus publish PRs as artifacts only.
{ [ "$CI_HAS_ARTIFACTS" = "true" ];
} && SHOULD_DEPLOY="true" || SHOULD_DEPLOY="false"
if [ "$build_status" -eq 0 ] && [ "$SHOULD_DEPLOY" = "true" ]; then
+5 -5
View File
@@ -12,7 +12,6 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
./squashfs-root/AppRun ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs
ls ./appdir/usr/lib/
rm -r ./appdir/usr/share/doc
rm ./appdir/usr/lib/libxcb*
cp "$(readlink -f /lib/x86_64-linux-gnu/libnsl.so.1)" ./appdir/usr/lib/libnsl.so.1
export PATH=/rpcs3/build/squashfs-root/usr/bin/:${PATH}
@@ -33,7 +32,8 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
printf "#include <bits/stdc++.h>\nint main(){std::make_exception_ptr(0);std::pmr::get_default_resource();}" | $CXX -x c++ -std=c++2a -o ./appdir/usr/optional/checker -
# Package it up and send it off
./squashfs-root/usr/bin/appimagetool /rpcs3/build/appdir
./squashfs-root/usr/bin/appimagetool "$APPDIR"
ls
COMM_TAG="$(grep 'version{.*}' ../rpcs3/rpcs3_version.cpp | awk -F[\{,] '{printf "%d.%d.%d", $2, $3, $4}')"
@@ -43,14 +43,14 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
mv ./RPCS3*.AppImage "$RPCS3_APPIMAGE"
# If we're building using Azure Pipelines, let's copy over the AppImage artifact
# If we're building using a CI, let's copy over the AppImage artifact
if [ -n "$BUILD_ARTIFACTSTAGINGDIRECTORY" ]; then
cp "$RPCS3_APPIMAGE" ~/artifacts
cp "$RPCS3_APPIMAGE" "$ARTDIR"
fi
FILESIZE=$(stat -c %s ./rpcs3*.AppImage)
SHA256SUM=$(sha256sum ./rpcs3*.AppImage | awk '{ print $1 }')
echo "${SHA256SUM};${FILESIZE}B" > /rpcs3/GitHubReleaseMessage.txt
echo "${SHA256SUM};${FILESIZE}B" > "$RELEASE_MESSAGE"
fi
+3 -3
View File
@@ -4,7 +4,7 @@
ARTIFACT_DIR="$BUILD_ARTIFACTSTAGINGDIRECTORY"
# Remove unecessary files
rm -f ./bin/rpcs3.exp ./bin/rpcs3.lib ./bin/rpcs3.pdb
rm -f ./bin/rpcs3.exp ./bin/rpcs3.lib ./bin/rpcs3.pdb ./bin/vc_redist.x64.exe
# Prepare compatibility database for packaging, as well as
# certificate for ssl (auto-updater)
@@ -20,5 +20,5 @@ sha256sum "$BUILD" | awk '{ print $1 }' | tee "$BUILD.sha256"
echo "$(cat "$BUILD.sha256");$(stat -c %s "$BUILD")B" > GitHubReleaseMessage.txt
# Move files to publishing directory
mv -- "$BUILD" "$ARTIFACT_DIR"
mv -- "$BUILD.sha256" "$ARTIFACT_DIR"
cp -- "$BUILD" "$ARTIFACT_DIR"
cp -- "$BUILD.sha256" "$ARTIFACT_DIR"
+4 -1
View File
@@ -1,10 +1,13 @@
# Variables set by Azure Pipelines
IS_AZURE
CI_HAS_ARTIFACTS
BUILD_REASON
BUILD_SOURCEVERSION
BUILD_ARTIFACTSTAGINGDIRECTORY
BUILD_REPOSITORY_NAME
BUILD_SOURCEBRANCHNAME
APPDIR
ARTDIR
RELEASE_MESSAGE
# Variables for build matrix
COMPILER
DEPLOY_APPIMAGE
+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh -e
# Export variables for later stages of the Azure pipeline
# Values done in this manner will appear as environment variables
# in later stages.
# From pure-sh-bible
# Setting 'IFS' tells 'read' where to split the string.
while IFS='=' read -r key val; do
# Skip over lines containing comments.
[ "${key##\#*}" ] || continue
export "$key"="$val"
done < ".ci/azure-vars.env"
+1 -1
View File
@@ -24,7 +24,7 @@ curl -s \
cat release.json
id=$(grep '"id"' release.json | cut -d ':' -f2 | head -n1 | awk '{$1=$1;print}')
id=${id%?}
echo ${id:?}
echo "${id:?}"
upload_file()
{
+1 -1
View File
@@ -9,7 +9,7 @@ export ASSUME_ALWAYS_YES=true
pkg info # debug
# Prefer newer Clang than in base system (see also .ci/build-freebsd.sh)
pkg install llvm11
pkg install llvm12
# Mandatory dependencies (qt5-dbus and qt5-gui are pulled via qt5-widgets)
pkg install git ccache cmake ninja qt5-qmake qt5-buildtools qt5-widgets qt5-concurrent glew openal-soft ffmpeg
+3 -3
View File
@@ -10,7 +10,7 @@ PR_NUMBER="$SYSTEM_PULLREQUEST_PULLREQUESTID"
QT_HOST="http://mirrors.ocf.berkeley.edu/qt/"
#QT_HOST="http://qt.mirror.constant.com/"
QT_URL_VER=$(echo "$QT_VER" | sed "s/\.//g")
QT_VER_MSVC_UP=$(echo ${QT_VER_MSVC} | tr '[:lower:]' '[:upper:]')
QT_VER_MSVC_UP=$(echo "${QT_VER_MSVC}" | tr '[:lower:]' '[:upper:]')
QT_PREFIX="online/qtsdkrepository/windows_x86/desktop/qt${QT_VER_MAIN}_${QT_URL_VER}/qt.qt${QT_VER_MAIN}.${QT_URL_VER}.win64_${QT_VER_MSVC}_64/${QT_VER}-0-${QT_DATE}"
QT_SUFFIX="-Windows-Windows_10-${QT_VER_MSVC_UP}-Windows-Windows_10-X86_64.7z"
QT_BASE_URL="${QT_HOST}${QT_PREFIX}qtbase${QT_SUFFIX}"
@@ -36,7 +36,7 @@ DEP_URLS=" \
# Pull all the submodules except llvm, since it is built separately and we just download that build
# Note: Tried to use git submodule status, but it takes over 20 seconds
# shellcheck disable=SC2046
git submodule -q update --init --depth 1 $(awk '/path/ && !/llvm/ { print $3 }' .gitmodules)
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/llvm/ { print $3 }' .gitmodules)
# Git bash doesn't have rev, so here it is
rev()
@@ -76,7 +76,7 @@ for url in $DEP_URLS; do
case "$url" in
*qt*) checksum=$(curl -L "${url}.sha1"); algo="sha1"; outDir='C:\Qt\' ;;
*llvm*) checksum=$(curl -L "${url}.sha256"); algo="sha256"; outDir="." ;;
*glslang*) checksum=$(curl -L "${url}.sha256"); algo="sha256"; outDir="./lib/Release - LLVM-x64" ;;
*glslang*) checksum=$(curl -L "${url}.sha256"); algo="sha256"; outDir="./lib/Release-x64" ;;
*Vulkan*)
# Vulkan setup needs to be run in batch environment
# Need to subshell this or else it doesn't wait
+96 -2
View File
@@ -1,5 +1,101 @@
env:
CIRRUS_CLONE_DEPTH: 0 # Unshallow clone to obtain proper GIT_VERSION
BUILD_REPOSITORY_NAME: $CIRRUS_REPO_FULL_NAME
SYSTEM_PULLREQUEST_SOURCEBRANCH: $CIRRUS_BRANCH
SYSTEM_PULLREQUEST_PULLREQUESTID: $CIRRUS_PR
BUILD_SOURCEVERSION: $CIRRUS_CHANGE_IN_REPO
# RPCS3_TOKEN: ENCRYPTED[13a0f18de9285e6c880e3aecbb54258245a74872af7d0fcb92447fa1200ceb6a4dc8acc880ddbf5e653d46336563ca72] # Replace this when we're using Cirrus for master releases!!
windows_task:
matrix:
- name: Cirrus Windows
windows_container:
image: cirrusci/windowsservercore:visualstudio2019
cpu: 8
memory: 16G
env:
CIRRUS_SHELL: "bash"
COMPILER: msvc
QT_VER_MAIN: '5'
BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}\artifacts\
QT_VER: '5.15.2'
QT_VER_MSVC: 'msvc2019'
QT_DATE: '202011130602'
QTDIR: C:\Qt\${QT_VER}\${QT_VER_MSVC}_64
VULKAN_VER: '1.2.154.1'
VULKAN_SDK_SHA: 'b64471f3a720e649c1fae6535ea83b8c642655ebed1485bfdf15bf4d88f746d9'
VULKAN_SDK: C:\VulkanSDK\${VULKAN_VER}
CACHE_DIR: "./cache"
UPLOAD_COMMIT_HASH: 7d09e3be30805911226241afbb14f8cdc2eb054e
UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-win"
deps_cache:
folder: "./cache"
#obj_cache:
# folder: "./tmp"
#obj2_cache:
# folder: "./rpcs3/x64"
setup_script:
- './.ci/get_keys-windows.sh'
- './.ci/setup-windows.sh'
# - choco install -y python # Needed for SPIRV, use either this or make a new Docker image
# spirv_script:
# - export PATH=${PATH}:"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin"
# - cd "${CIRRUS_WORKING_DIR}/Vulkan/spirv-tools-build"
# - msbuild.exe spirv-tools-build.vcxproj //p:Configuration=Release //m
rpcs3_script:
- export PATH=${PATH}:"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin"
- msbuild.exe rpcs3.sln //p:Configuration=Release //m
deploy_script:
- mkdir artifacts
- source './.ci/export-cirrus-vars.sh'
- './.ci/deploy-windows.sh'
artifacts:
name: Artifact
path: "*.7z*"
# push_script: |
# if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ]; then
# source './.ci/export-cirrus-vars.sh'
# './.ci/github-upload.sh'
# fi;
linux_task:
container:
image: rpcs3/rpcs3-ci-bionic:1.0
cpu: 4
memory: 16G
env:
BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}/artifacts
CCACHE_DIR: "/tmp/ccache_dir"
CCACHE_MAXSIZE: 300M
CI_HAS_ARTIFACTS: true
UPLOAD_COMMIT_HASH: d812f1254a1157c80fd402f94446310560f54e5f
UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux"
DEPLOY_APPIMAGE: true
APPDIR: "./appdir"
ARTDIR: ${CIRRUS_WORKING_DIR}/artifacts/
RELEASE_MESSAGE: "../GitHubReleaseMessage.txt"
ccache_cache:
folder: "/tmp/ccache_dir"
matrix:
- name: Cirrus Linux GCC
env:
COMPILER: gcc
gcc_script:
- mkdir artifacts
- ".ci/build-linux.sh"
- name: Cirrus Linux Clang
env:
COMPILER: clang
clang_script:
- mkdir artifacts
- ".ci/build-linux.sh"
artifacts:
name: Artifact
path: "artifacts/*"
# push_script: |
# if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ] && [ "$COMPILER" = "gcc" ]; then
# '.ci/github-upload.sh'
# fi;
freebsd_task:
matrix:
@@ -13,7 +109,5 @@ freebsd_task:
CCACHE_DIR: /tmp/ccache_dir
ccache_cache:
folder: /tmp/ccache_dir
packages_cache:
folder: /var/cache/pkg
install_script: "sh -ex ./.ci/install-freebsd.sh"
script: "./.ci/build-freebsd.sh"
+5 -6
View File
@@ -1,6 +1,6 @@
# Getting Started
Before getting started using the emulator, read the [Quickstart Guide](https://rpcs3.net/quickstart) and the [FAQ](https://rpcs3.net/faq). After reading those, if you need support, visit our [Forums](https://forums.rpcs3.net).
Before getting started using the emulator, read the [Quickstart Guide](https://rpcs3.net/quickstart). After reading it, if you need support, check out [How to ask for Support](https://github.com/RPCS3/rpcs3/wiki/How-to-ask-for-Support).
# Issue Reporting
@@ -8,13 +8,12 @@ Before getting started using the emulator, read the [Quickstart Guide](https://r
**Before reporting an issue:**
- Check if your system matches all the minimum requirements listed in the [Quickstart Guide](https://rpcs3.net/quickstart);
- Check if the issue is meaningful for the team (e.g. The Last of Us doesn't work is obvious and therefore useless);
- Search older issues/forum threads to see if your issue was already submitted.
- Use understandable English. It doesn't need to be perfect, but clear enough to understand your message.
- While reporting issues, don't forget to include details about your system (OS, CPU, GPU, etc.), as well as the RPCS3.log file.
- Search older issues/forum threads to see if your issue was already submitted;
- Use understandable English. It doesn't need to be perfect, but clear enough to understand your message;
- While reporting issues, please follow the template for the type of issue you've selected (Regression Report, Bug Report or Feature Request), which is prefilled on the issue's textbox.
Submitting your test results for Commercial Games must be done on our forums. Please read the [Game Compatibility](https://github.com/RPCS3/rpcs3/wiki/Game-Compatibility) wiki page before doing so.
# Contributing
Check the [Coding Style Guidelines](https://github.com/RPCS3/rpcs3/wiki/Coding-Style), [Roadmap](https://github.com/RPCS3/rpcs3/wiki/Roadmap) and [Developer Information](https://github.com/RPCS3/rpcs3/wiki/Developer-Information). If you have any questions, hit us up on our [Discord Server](https://discord.me/RPCS3) in the **#development** channel.
Check the [Coding Style Guidelines](https://github.com/RPCS3/rpcs3/wiki/Coding-Style) and [Developer Information](https://github.com/RPCS3/rpcs3/wiki/Developer-Information). If you have any questions, hit us up on our [Discord Server](https://discord.me/RPCS3) in the **#development** channel.
@@ -15,6 +15,10 @@ Please briefly describe what has stopped working correctly.
## Details
Please describe the regression as accurately as possible.
#### 0. Make sure you're running with settings as close to default as possible
* **Do NOT enable any emulator game patches when reporting issues**
* Only change settings that are required for the game to work
#### 1. Please provide _exact_ build (or commit) information that introduced the regression you're reporting.
* Please see [How to find the build that caused a regression](https://wiki.rpcs3.net/index.php?title=Help:Using_different_versions_of_RPCS3#How_to_find_the_build_that_caused_a_regression.3F) in our wiki.
* You can find [History of RPCS3 builds](https://rpcs3.net/compatibility?b) here.
@@ -35,12 +39,12 @@ Please describe the regression as accurately as possible.
On Windows it will be near the executable.
* Attach the log:
+ Drag and drop your log file into the issue.
+ Or upload it to the cloud, such as Dropbox, Mega etc.
+ Or upload it to the cloud, such as Dropbox, Mega etc.
#### 3. If you describe graphical regression, please provide an RSX capture and a RenderDoc capture that demonstrate it.
* To create an RSX capture, use _Create_ _RSX_ _Capture_ under _Utilities_.
Captures will be stored in RPCS3 folder → captures.
+ Compress your capture with 7z, Rar etc.
+ Compress your capture with 7z, Rar etc.
And drag and drop it into the issue.
+ Or upload it to the cloud, such as Dropbox, Mega etc.
* To create a RenderDoc capture, please refer to [RenderDoc's documentation](https://renderdoc.org/docs/how/how_capture_frame.html).
@@ -59,4 +63,4 @@ You can find it in _Emulator_ tab in _Settings_.
* etc.
#### Please include.
* Anything else you deem to be important
* Anything else you deem to be important
+6 -2
View File
@@ -16,6 +16,10 @@ Please briefly describe what is not working correctly.
Please describe the problem as accurately as possible.
#### 0. Make sure you're running with settings as close to default as possible
* **Do NOT enable any emulator game patches when reporting issues**
* Only change settings that are required for the game to work
#### 1. Please attach RPCS3's log.
* Run the game until you find the issue.
* Completely close RPCS3, or move to the next step in case it has crashed.
@@ -28,12 +32,12 @@ Please describe the problem as accurately as possible.
On Windows it will be near the executable.
* Attach the log:
+ Drag and drop your log file into the issue.
+ Or upload it to the cloud, such as Dropbox, Mega etc.
+ Or upload it to the cloud, such as Dropbox, Mega etc.
#### 2. If you describe graphical issue, please provide an RSX capture and a RenderDoc capture that demonstrate it.
* To create an RSX capture, use _Create_ _RSX_ _Capture_ under _Utilities_.
Captures will be stored in RPCS3 folder → captures.
+ Compress your capture with 7z, Rar etc.
+ Compress your capture with 7z, Rar etc.
And drag and drop it into the issue.
+ Or upload it to the cloud, such as Dropbox, Mega etc.
* To create a RenderDoc capture, please refer to [RenderDoc's documentation](https://renderdoc.org/docs/how/how_capture_frame.html).
+12 -14
View File
@@ -1,20 +1,18 @@
## How to test a PR build
Please take into account, that RPCS3 build usually takes some time (about 20 min), so you can't access a build, if a PR was just submitted.
Please take into account, that RPCS3 build usually takes some time (about 15 mins), so you can't access a build if a PR was just submitted.
- Open a PR you want to test
- Scroll to the very bottom and locate "Checks" section
- Expand all checks
- Scroll to the very bottom and locate the **Checks** section
- Click on **Show all checks**
You are supposed to see something like this
![image](https://user-images.githubusercontent.com/44116740/102790039-f98f6d00-43b5-11eb-9134-2359b732508d.png)
- Click on **Linux_Build** or **Windows_Build** __Details__
- Click **View more details on Azure Pipelines** at the very bottom
![image](https://user-images.githubusercontent.com/44116740/102790281-45daad00-43b6-11eb-90e7-0fa8c37c31c6.png)
- Click on *1 artifact produced*
![image](https://user-images.githubusercontent.com/44116740/102790526-9a7e2800-43b6-11eb-9925-be1ea1c8bdad.png)
- Select a build for your OS and click three dots on the right, Click **Download artifacts**
![image](https://user-images.githubusercontent.com/44116740/102790636-c9949980-43b6-11eb-9692-1e3ba567b9be.png)
- Congratulations! You are now downloading RPCS3 build for specific PR.
![image](https://user-images.githubusercontent.com/10283761/116630952-2cd99e00-a94c-11eb-933e-986d6020ca92.png)
- Click on __Details__ on either **Cirrus Linux GCC** or **Cirrus Windows**
- Click **View more details on Cirrus CI** at the very bottom
![image](https://user-images.githubusercontent.com/10283761/116631111-5e526980-a94c-11eb-95f7-751e6f15e1ea.png)
- Click on the download button for **Artifact** on the **Artifacts** block
![image](https://user-images.githubusercontent.com/10283761/116631322-bee1a680-a94c-11eb-89a3-be365783582e.png)
Please note, that PR builds are not supposed to be stable, because they contain new changesets.
- Congratulations! You are now downloading an RPCS3 build for that specific PR.
__Please note that PR builds are not supposed to be stable because they contain new changesets.__
+12 -1
View File
@@ -9,7 +9,7 @@
# Compiled Static libraries
*.lai
*.la
# *.a # Commented out since OpenAL Soft's binaries use this extension.
*.a
*.opensdf
*.sdf
*.suo
@@ -45,6 +45,10 @@
!/bin
/bin/*
# Audio DLLs
!/bin/soft_oal.dll
!/bin/xaudio2_9redist.dll
# Themes
!/bin/GuiConfigs/
/bin/GuiConfigs/*.ini
@@ -52,6 +56,9 @@
/bin/GuiConfigs/*.dat
/bin/GuiConfigs/*.dat.*
# Some data from git
!/bin/git/
# Visual Studio Files
.vs/*
.vscode/*
@@ -62,6 +69,8 @@
*.vcxproj.user
enc_temp_folder/*
CMakeSettings.json
*PVS-Studio*
PVS/*
# Ignore other system generated files
x64/*
@@ -116,3 +125,5 @@ yaml-cpp.pc
# ssl certificate
cacert.pem
_ReSharper.*/
+3 -2
View File
@@ -4,7 +4,8 @@
ignore = dirty
[submodule "asmjit"]
path = asmjit
url = https://github.com/kobalicek/asmjit
url = https://github.com/asmjit/asmjit
branch = oldstable
ignore = dirty
[submodule "llvm"]
path = llvm
@@ -52,7 +53,7 @@
url = https://github.com/glennrp/libpng.git
ignore = dirty
[submodule "3rdparty/libusb"]
path = 3rdparty/libusb
path = 3rdparty/libusb/src
url = https://github.com/libusb/libusb.git
ignore = dirty
[submodule "3rdparty/FAudio"]
+4 -3
View File
@@ -123,7 +123,7 @@ if(CMAKE_SYSTEM MATCHES "DragonFly|FreeBSD")
elseif(MSVC)
# Windows time.h defines timespec but doesn't add any flag for it, which makes libusb attempt to define it again
add_definitions(-DHAVE_STRUCT_TIMESPEC=1)
add_subdirectory(libusb_cmake EXCLUDE_FROM_ALL)
add_subdirectory(libusb EXCLUDE_FROM_ALL)
else()
if(USE_SYS_LIBUSB)
# we have the system libusb and have selected to use it
@@ -131,7 +131,8 @@ else()
target_link_libraries(usb-1.0-shared INTERFACE PkgConfig::LIBUSB)
else()
# we don't have the system libusb, so we compile from submodule
add_subdirectory(libusb_cmake EXCLUDE_FROM_ALL)
unset(LIBUSB_LIBRARIES CACHE)
add_subdirectory(libusb EXCLUDE_FROM_ALL)
endif()
endif()
@@ -354,7 +355,7 @@ target_link_libraries(3rdparty_openal INTERFACE ${OPENAL_LIBRARY})
set(FAUDIO_TARGET 3rdparty_dummy_lib)
if(USE_FAUDIO)
# FAudio depends on SDL2
pkg_check_modules(SDL2 sdl2)
find_package(SDL2)
if (NOT SDL2_FOUND OR SDL2_VERSION VERSION_LESS 2.0.9)
message("-- RPCS3: FAudio requires SDL 2.0.9 or newer.")
else()
+4 -4
View File
@@ -8848,7 +8848,7 @@ bool VmaBlockMetadata_Generic::CheckAllocation(
// Check previous suballocations for BufferImageGranularity conflicts.
// Make bigger alignment if necessary.
if(bufferImageGranularity > 1)
if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment)
{
bool bufferImageGranularityConflict = false;
VmaSuballocationList::const_iterator prevSuballocItem = suballocItem;
@@ -8932,7 +8932,7 @@ bool VmaBlockMetadata_Generic::CheckAllocation(
// Check next suballocations for BufferImageGranularity conflicts.
// If conflict exists, we must mark more allocations lost or fail.
if(bufferImageGranularity > 1)
if(bufferImageGranularity > 1 && (allocSize % bufferImageGranularity || *pOffset % bufferImageGranularity))
{
VmaSuballocationList::const_iterator nextSuballocItem = lastSuballocItem;
++nextSuballocItem;
@@ -8991,7 +8991,7 @@ bool VmaBlockMetadata_Generic::CheckAllocation(
// Check previous suballocations for BufferImageGranularity conflicts.
// Make bigger alignment if necessary.
if(bufferImageGranularity > 1)
if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment)
{
bool bufferImageGranularityConflict = false;
VmaSuballocationList::const_iterator prevSuballocItem = suballocItem;
@@ -9031,7 +9031,7 @@ bool VmaBlockMetadata_Generic::CheckAllocation(
// Check next suballocations for BufferImageGranularity conflicts.
// If conflict exists, allocation cannot be made here.
if(bufferImageGranularity > 1)
if(bufferImageGranularity > 1 && (allocSize % bufferImageGranularity || *pOffset % bufferImageGranularity))
{
VmaSuballocationList::const_iterator nextSuballocItem = suballocItem;
++nextSuballocItem;
+31 -32
View File
@@ -22,7 +22,7 @@ extern "C" {
#endif
/** Deprecated macro. */
/* Deprecated macros. */
#define OPENAL
#define ALAPI AL_API
#define ALAPIENTRY AL_APIENTRY
@@ -30,7 +30,7 @@ extern "C" {
#define AL_ILLEGAL_ENUM AL_INVALID_ENUM
#define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
/** Supported AL version. */
/* Supported AL versions. */
#define AL_VERSION_1_0
#define AL_VERSION_1_1
@@ -234,7 +234,7 @@ typedef void ALvoid;
*/
#define AL_SOURCE_STATE 0x1010
/** Source state value. */
/* Source state values. */
#define AL_INITIAL 0x1011
#define AL_PLAYING 0x1012
#define AL_PAUSED 0x1013
@@ -300,7 +300,7 @@ typedef void ALvoid;
* Source maximum distance.
* Type: ALfloat
* Range: [0.0 - ]
* Default: +inf
* Default: FLT_MAX
*
* The distance above which the source is not attenuated any further with a
* clamped distance model, or where attenuation reaches 0.0 gain for linear
@@ -330,15 +330,18 @@ typedef void ALvoid;
*/
#define AL_SOURCE_TYPE 0x1027
/** Source type value. */
/* Source type values. */
#define AL_STATIC 0x1028
#define AL_STREAMING 0x1029
#define AL_UNDETERMINED 0x1030
/** Buffer format specifier. */
/** Unsigned 8-bit mono buffer format. */
#define AL_FORMAT_MONO8 0x1100
/** Signed 16-bit mono buffer format. */
#define AL_FORMAT_MONO16 0x1101
/** Unsigned 8-bit stereo buffer format. */
#define AL_FORMAT_STEREO8 0x1102
/** Signed 16-bit stereo buffer format. */
#define AL_FORMAT_STEREO16 0x1103
/** Buffer frequency (query only). */
@@ -350,11 +353,7 @@ typedef void ALvoid;
/** Buffer data size (query only). */
#define AL_SIZE 0x2004
/**
* Buffer state.
*
* Not for public use.
*/
/* Buffer state. Not for public use. */
#define AL_UNUSED 0x2010
#define AL_PENDING 0x2011
#define AL_PROCESSED 0x2012
@@ -441,7 +440,7 @@ AL_API void AL_APIENTRY alSpeedOfSound(ALfloat value);
#define AL_DISTANCE_MODEL 0xD000
AL_API void AL_APIENTRY alDistanceModel(ALenum distanceModel);
/** Distance model value. */
/* Distance model values. */
#define AL_INVERSE_DISTANCE 0xD001
#define AL_INVERSE_DISTANCE_CLAMPED 0xD002
#define AL_LINEAR_DISTANCE 0xD003
@@ -449,12 +448,12 @@ AL_API void AL_APIENTRY alDistanceModel(ALenum distanceModel);
#define AL_EXPONENT_DISTANCE 0xD005
#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006
/** Renderer State management. */
/* Renderer State management. */
AL_API void AL_APIENTRY alEnable(ALenum capability);
AL_API void AL_APIENTRY alDisable(ALenum capability);
AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability);
/** State retrieval. */
/* State retrieval. */
AL_API const ALchar* AL_APIENTRY alGetString(ALenum param);
AL_API void AL_APIENTRY alGetBooleanv(ALenum param, ALboolean *values);
AL_API void AL_APIENTRY alGetIntegerv(ALenum param, ALint *values);
@@ -465,25 +464,25 @@ AL_API ALint AL_APIENTRY alGetInteger(ALenum param);
AL_API ALfloat AL_APIENTRY alGetFloat(ALenum param);
AL_API ALdouble AL_APIENTRY alGetDouble(ALenum param);
/**
* Error retrieval.
*
* Obtain the first error generated in the AL context since the last check.
*/
/* Error retrieval. */
/** Obtain the first error generated in the AL context since the last check. */
AL_API ALenum AL_APIENTRY alGetError(void);
/**
* Extension support.
*
* Query for the presence of an extension, and obtain any appropriate function
* pointers and enum values.
*/
/** Query for the presence of an extension on the AL context. */
AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extname);
/**
* Retrieve the address of a function. The returned function may be context-
* specific.
*/
AL_API void* AL_APIENTRY alGetProcAddress(const ALchar *fname);
/**
* Retrieve the value of an enum. The returned value may be context-specific.
*/
AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *ename);
/** Set Listener parameters */
/* Set Listener parameters */
AL_API void AL_APIENTRY alListenerf(ALenum param, ALfloat value);
AL_API void AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
AL_API void AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values);
@@ -491,7 +490,7 @@ AL_API void AL_APIENTRY alListeneri(ALenum param, ALint value);
AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3);
AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values);
/** Get Listener parameters */
/* Get Listener parameters */
AL_API void AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value);
AL_API void AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
AL_API void AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values);
@@ -507,7 +506,7 @@ AL_API void AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources);
/** Verify a handle is a valid Source. */
AL_API ALboolean AL_APIENTRY alIsSource(ALuint source);
/** Set Source parameters. */
/* Set Source parameters. */
AL_API void AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value);
AL_API void AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
AL_API void AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat *values);
@@ -515,7 +514,7 @@ AL_API void AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value);
AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3);
AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *values);
/** Get Source parameters. */
/* Get Source parameters. */
AL_API void AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *value);
AL_API void AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
AL_API void AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *values);
@@ -558,7 +557,7 @@ AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer);
/** Specifies the data to be copied into a buffer */
AL_API void AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq);
/** Set Buffer parameters, */
/* Set Buffer parameters, */
AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat value);
AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values);
@@ -566,7 +565,7 @@ AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value);
AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3);
AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values);
/** Get Buffer parameters. */
/* Get Buffer parameters. */
AL_API void AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value);
AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *values);
@@ -574,7 +573,7 @@ AL_API void AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value);
AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3);
AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values);
/** Pointer-to-function type, useful for dynamically getting AL entry points. */
/* Pointer-to-function type, useful for dynamically getting AL entry points. */
typedef void (AL_APIENTRY *LPALENABLE)(ALenum capability);
typedef void (AL_APIENTRY *LPALDISABLE)(ALenum capability);
typedef ALboolean (AL_APIENTRY *LPALISENABLED)(ALenum capability);
+54 -21
View File
@@ -22,7 +22,7 @@ extern "C" {
#endif
/** Deprecated macro. */
/* Deprecated macros. */
#define ALCAPI ALC_API
#define ALCAPIENTRY ALC_APIENTRY
#define ALC_INVALID 0
@@ -89,7 +89,7 @@ typedef void ALCvoid;
/** Context attribute: <int> Hz. */
#define ALC_REFRESH 0x1008
/** Context attribute: AL_TRUE or AL_FALSE. */
/** Context attribute: AL_TRUE or AL_FALSE synchronous context? */
#define ALC_SYNC 0x1009
/** Context attribute: <int> requested Mono (3D) Sources. */
@@ -117,12 +117,14 @@ typedef void ALCvoid;
#define ALC_OUT_OF_MEMORY 0xA005
/** Runtime ALC version. */
/** Runtime ALC major version. */
#define ALC_MAJOR_VERSION 0x1000
/** Runtime ALC minor version. */
#define ALC_MINOR_VERSION 0x1001
/** Context attribute list properties. */
/** Context attribute list size. */
#define ALC_ATTRIBUTES_SIZE 0x1002
/** Context attribute list properties. */
#define ALC_ALL_ATTRIBUTES 0x1003
/** String for the default device specifier. */
@@ -166,49 +168,80 @@ typedef void ALCvoid;
#define ALC_ALL_DEVICES_SPECIFIER 0x1013
/** Context management. */
ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint* attrlist);
/* Context management. */
/** Create and attach a context to the given device. */
ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrlist);
/**
* Makes the given context the active process-wide context. Passing NULL clears
* the active context.
*/
ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context);
/** Resumes processing updates for the given context. */
ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context);
/** Suspends updates for the given context. */
ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context);
/** Remove a context from its device and destroys it. */
ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context);
/** Returns the currently active context. */
ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void);
/** Returns the device that a particular context is attached to. */
ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *context);
/** Device management. */
/* Device management. */
/** Opens the named playback device. */
ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename);
/** Closes the given playback device. */
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device);
/* Error support. */
/**
* Error support.
*
* Obtain the most recent Device error.
*/
/** Obtain the most recent Device error. */
ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device);
/* Extension support. */
/**
* Extension support.
*
* Query for the presence of an extension, and obtain any appropriate
* function pointers and enum values.
* Query for the presence of an extension on the device. Pass a NULL device to
* query a device-inspecific extension.
*/
ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extname);
ALC_API void* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcname);
/**
* Retrieve the address of a function. Given a non-NULL device, the returned
* function may be device-specific.
*/
ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcname);
/**
* Retrieve the value of an enum. Given a non-NULL device, the returned value
* may be device-specific.
*/
ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumname);
/** Query function. */
/* Query functions. */
/** Returns information about the device, and error strings. */
ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param);
/** Returns information about the device and the version of OpenAL. */
ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values);
/** Capture function. */
/* Capture functions. */
/**
* Opens the named capture device with the given frequency, format, and buffer
* size.
*/
ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize);
/** Closes the given capture device. */
ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device);
/** Starts capturing samples into the device buffer. */
ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device);
/** Stops capturing samples. Samples in the device buffer remain available. */
ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device);
/** Reads samples from the device buffer. */
ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
/** Pointer-to-function type, useful for dynamically getting ALC entry points. */
/* Pointer-to-function type, useful for dynamically getting ALC entry points. */
typedef ALCcontext* (ALC_APIENTRY *LPALCCREATECONTEXT)(ALCdevice *device, const ALCint *attrlist);
typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)(ALCcontext *context);
typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)(ALCcontext *context);
@@ -220,7 +253,7 @@ typedef ALCdevice* (ALC_APIENTRY *LPALCOPENDEVICE)(const ALCchar *devicename
typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)(ALCdevice *device);
typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)(ALCdevice *device);
typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)(ALCdevice *device, const ALCchar *extname);
typedef void* (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname);
typedef ALCvoid* (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname);
typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname);
typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)(ALCdevice *device, ALCenum param);
typedef void (ALC_APIENTRY *LPALCGETINTEGERV)(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values);
+68 -19
View File
@@ -22,17 +22,20 @@
#define AL_ALEXT_H
#include <stddef.h>
/* Define int64_t and uint64_t types */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#include <inttypes.h>
#elif defined(_WIN32) && defined(__GNUC__)
/* Define int64 and uint64 types */
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
(defined(__cplusplus) && __cplusplus >= 201103L)
#include <stdint.h>
typedef int64_t _alsoft_int64_t;
typedef uint64_t _alsoft_uint64_t;
#elif defined(_WIN32)
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef __int64 _alsoft_int64_t;
typedef unsigned __int64 _alsoft_uint64_t;
#else
/* Fallback if nothing above works */
#include <inttypes.h>
#include <stdint.h>
typedef int64_t _alsoft_int64_t;
typedef uint64_t _alsoft_uint64_t;
#endif
#include "alc.h"
@@ -158,9 +161,9 @@ extern "C" {
#ifndef AL_EXT_STATIC_BUFFER
#define AL_EXT_STATIC_BUFFER 1
typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei);
typedef void (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq);
AL_API void AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq);
#endif
#endif
@@ -193,9 +196,9 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void);
#define AL_SOFT_buffer_sub_data 1
#define AL_BYTE_RW_OFFSETS_SOFT 0x1031
#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032
typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei);
typedef void (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length);
AL_API void AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length);
#endif
#endif
@@ -343,8 +346,8 @@ ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffe
#define AL_SOFT_source_latency 1
#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200
#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201
typedef int64_t ALint64SOFT;
typedef uint64_t ALuint64SOFT;
typedef _alsoft_int64_t ALint64SOFT;
typedef _alsoft_uint64_t ALuint64SOFT;
typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble);
typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble);
typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*);
@@ -381,11 +384,11 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64
#ifndef AL_SOFT_deferred_updates
#define AL_SOFT_deferred_updates 1
#define AL_DEFERRED_UPDATES_SOFT 0xC002
typedef ALvoid (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void);
typedef ALvoid (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void);
typedef void (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void);
typedef void (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void);
AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void);
AL_API void AL_APIENTRY alDeferUpdatesSOFT(void);
AL_API void AL_APIENTRY alProcessUpdatesSOFT(void);
#endif
#endif
@@ -496,8 +499,8 @@ AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index);
#ifndef ALC_SOFT_device_clock
#define ALC_SOFT_device_clock 1
typedef int64_t ALCint64SOFT;
typedef uint64_t ALCuint64SOFT;
typedef _alsoft_int64_t ALCint64SOFT;
typedef _alsoft_uint64_t ALCuint64SOFT;
#define ALC_DEVICE_CLOCK_SOFT 0x1600
#define ALC_DEVICE_LATENCY_SOFT 0x1601
#define ALC_DEVICE_CLOCK_LATENCY_SOFT 0x1602
@@ -530,6 +533,52 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname,
#define AL_N3D_SOFT 0x0002
#endif
#ifndef ALC_SOFT_loopback_bformat
#define ALC_SOFT_loopback_bformat 1
#define ALC_AMBISONIC_LAYOUT_SOFT 0x1997
#define ALC_AMBISONIC_SCALING_SOFT 0x1998
#define ALC_AMBISONIC_ORDER_SOFT 0x1999
#define ALC_MAX_AMBISONIC_ORDER_SOFT 0x199B
#define ALC_BFORMAT3D_SOFT 0x1507
/* Ambisonic layouts */
#define ALC_FUMA_SOFT 0x0000
#define ALC_ACN_SOFT 0x0001
/* Ambisonic scalings (normalization) */
/*#define ALC_FUMA_SOFT*/
#define ALC_SN3D_SOFT 0x0001
#define ALC_N3D_SOFT 0x0002
#endif
#ifndef AL_SOFT_effect_target
#define AL_SOFT_effect_target
#define AL_EFFECTSLOT_TARGET_SOFT 0x199C
#endif
#ifndef AL_SOFT_events
#define AL_SOFT_events 1
#define AL_EVENT_CALLBACK_FUNCTION_SOFT 0x19A2
#define AL_EVENT_CALLBACK_USER_PARAM_SOFT 0x19A3
#define AL_EVENT_TYPE_BUFFER_COMPLETED_SOFT 0x19A4
#define AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT 0x19A5
#define AL_EVENT_TYPE_DISCONNECTED_SOFT 0x19A6
typedef void (AL_APIENTRY*ALEVENTPROCSOFT)(ALenum eventType, ALuint object, ALuint param,
ALsizei length, const ALchar *message,
void *userParam);
typedef void (AL_APIENTRY*LPALEVENTCONTROLSOFT)(ALsizei count, const ALenum *types, ALboolean enable);
typedef void (AL_APIENTRY*LPALEVENTCALLBACKSOFT)(ALEVENTPROCSOFT callback, void *userParam);
typedef void* (AL_APIENTRY*LPALGETPOINTERSOFT)(ALenum pname);
typedef void (AL_APIENTRY*LPALGETPOINTERVSOFT)(ALenum pname, void **values);
#ifdef AL_ALEXT_PROTOTYPES
AL_API void AL_APIENTRY alEventControlSOFT(ALsizei count, const ALenum *types, ALboolean enable);
AL_API void AL_APIENTRY alEventCallbackSOFT(ALEVENTPROCSOFT callback, void *userParam);
AL_API void* AL_APIENTRY alGetPointerSOFT(ALenum pname);
AL_API void AL_APIENTRY alGetPointervSOFT(ALenum pname, void **values);
#endif
#endif
#ifdef __cplusplus
}
#endif
+30 -30
View File
@@ -243,41 +243,41 @@ typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat*
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects);
AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects);
AL_API void AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects);
AL_API void AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects);
AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect);
AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue);
AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues);
AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue);
AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue);
AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue);
AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues);
AL_API void AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue);
AL_API void AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues);
AL_API void AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue);
AL_API void AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues);
AL_API void AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue);
AL_API void AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues);
AL_API void AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue);
AL_API void AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters);
AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters);
AL_API void AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters);
AL_API void AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters);
AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter);
AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue);
AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues);
AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue);
AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue);
AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue);
AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues);
AL_API void AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue);
AL_API void AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues);
AL_API void AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue);
AL_API void AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues);
AL_API void AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue);
AL_API void AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues);
AL_API void AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue);
AL_API void AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots);
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots);
AL_API void AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots);
AL_API void AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots);
AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues);
AL_API void AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue);
AL_API void AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues);
AL_API void AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue);
AL_API void AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues);
AL_API void AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue);
AL_API void AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues);
AL_API void AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue);
AL_API void AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues);
#endif
/* Filter ranges and defaults. */
+80
View File
@@ -1,35 +1,84 @@
EXPORTS
alAuxiliaryEffectSlotPlaySOFT
alAuxiliaryEffectSlotPlayvSOFT
alAuxiliaryEffectSlotStopSOFT
alAuxiliaryEffectSlotStopvSOFT
alAuxiliaryEffectSlotf
alAuxiliaryEffectSlotfv
alAuxiliaryEffectSloti
alAuxiliaryEffectSlotiv
alBuffer3f
alBuffer3i
alBufferCallbackSOFT
alBufferData
alBufferSamplesSOFT
alBufferStorageSOFT
alBufferSubDataSOFT
alBufferSubSamplesSOFT
alBufferf
alBufferfv
alBufferi
alBufferiv
alDeferUpdatesSOFT
alDeleteAuxiliaryEffectSlots
alDeleteBuffers
alDeleteEffects
alDeleteFilters
alDeleteSources
alDisable
alDistanceModel
alDopplerFactor
alDopplerVelocity
alEffectf
alEffectfv
alEffecti
alEffectiv
alEnable
alEventCallbackSOFT
alEventControlSOFT
alFilterf
alFilterfv
alFilteri
alFilteriv
alFlushMappedBufferSOFT
alGenAuxiliaryEffectSlots
alGenBuffers
alGenEffects
alGenFilters
alGenSources
alGetAuxiliaryEffectSlotf
alGetAuxiliaryEffectSlotfv
alGetAuxiliaryEffectSloti
alGetAuxiliaryEffectSlotiv
alGetBoolean
alGetBooleanv
alGetBuffer3PtrSOFT
alGetBuffer3f
alGetBuffer3i
alGetBufferPtrSOFT
alGetBufferPtrvSOFT
alGetBufferSamplesSOFT
alGetBufferf
alGetBufferfv
alGetBufferi
alGetBufferiv
alGetDouble
alGetDoublev
alGetEffectf
alGetEffectfv
alGetEffecti
alGetEffectiv
alGetEnumValue
alGetError
alGetFilterf
alGetFilterfv
alGetFilteri
alGetFilteriv
alGetFloat
alGetFloatv
alGetInteger
alGetInteger64SOFT
alGetInteger64vSOFT
alGetIntegerv
alGetListener3f
alGetListener3i
@@ -37,17 +86,30 @@ EXPORTS
alGetListenerfv
alGetListeneri
alGetListeneriv
alGetPointerSOFT
alGetPointervSOFT
alGetProcAddress
alGetSource3dSOFT
alGetSource3f
alGetSource3i
alGetSource3i64SOFT
alGetSourcedSOFT
alGetSourcedvSOFT
alGetSourcef
alGetSourcefv
alGetSourcei
alGetSourcei64SOFT
alGetSourcei64vSOFT
alGetSourceiv
alGetString
alGetStringiSOFT
alIsAuxiliaryEffectSlot
alIsBuffer
alIsBufferFormatSupportedSOFT
alIsEffect
alIsEnabled
alIsExtensionPresent
alIsFilter
alIsSource
alListener3f
alListener3i
@@ -55,8 +117,12 @@ EXPORTS
alListenerfv
alListeneri
alListeneriv
alMapBufferSOFT
alProcessUpdatesSOFT
alSource3dSOFT
alSource3f
alSource3i
alSource3i64SOFT
alSourcePause
alSourcePausev
alSourcePlay
@@ -67,11 +133,16 @@ EXPORTS
alSourceStop
alSourceStopv
alSourceUnqueueBuffers
alSourcedSOFT
alSourcedvSOFT
alSourcef
alSourcefv
alSourcei
alSourcei64SOFT
alSourcei64vSOFT
alSourceiv
alSpeedOfSound
alUnmapBufferSOFT
alcCaptureCloseDevice
alcCaptureOpenDevice
alcCaptureSamples
@@ -80,17 +151,26 @@ EXPORTS
alcCloseDevice
alcCreateContext
alcDestroyContext
alcDevicePauseSOFT
alcDeviceResumeSOFT
alcGetContextsDevice
alcGetCurrentContext
alcGetEnumValue
alcGetError
alcGetInteger64vSOFT
alcGetIntegerv
alcGetProcAddress
alcGetString
alcGetStringiSOFT
alcGetThreadContext
alcIsExtensionPresent
alcIsRenderFormatSupportedSOFT
alcLoopbackOpenDeviceSOFT
alcMakeContextCurrent
alcOpenDevice
alcProcessContext
alcRenderSamplesSOFT
alcResetDeviceSOFT
alcSetThreadContext
alcSuspendContext
alsoft_get_version
Binary file not shown.
+10 -9
View File
@@ -18,10 +18,10 @@
// Current name of the DLL shipped in the same SDK as this header.
// The name reflects the current version
#define XAUDIO2_DLL_A "xaudio2redist.dll"
#define XAUDIO2_DLL_W L"xaudio2redist.dll"
#define XAUDIO2D_DLL_A "xaudio2redist.dll"
#define XAUDIO2D_DLL_W L"xaudio2redist.dll"
#define XAUDIO2_DLL_A "xaudio2_9redist.dll"
#define XAUDIO2_DLL_W L"xaudio2_9redist.dll"
#define XAUDIO2D_DLL_A "xaudio2_9redist.dll"
#define XAUDIO2D_DLL_W L"xaudio2_9redist.dll"
#ifdef UNICODE
#define XAUDIO2_DLL XAUDIO2_DLL_W
@@ -446,7 +446,7 @@ DECLARE_INTERFACE_(IXAudio2, IUnknown)
// ARGUMENTS:
// pCallback - Callback interface to be called during each processing pass.
//
STDMETHOD(RegisterForCallbacks) (_In_ IXAudio2EngineCallback* pCallback) PURE;
STDMETHOD(RegisterForCallbacks) (THIS_ _In_ IXAudio2EngineCallback* pCallback) PURE;
// NAME: IXAudio2::UnregisterForCallbacks
// DESCRIPTION: Removes an existing receiver of XAudio2 engine callbacks.
@@ -454,7 +454,7 @@ DECLARE_INTERFACE_(IXAudio2, IUnknown)
// ARGUMENTS:
// pCallback - Previously registered callback interface to be removed.
//
STDMETHOD_(void, UnregisterForCallbacks) (_In_ IXAudio2EngineCallback* pCallback) PURE;
STDMETHOD_(void, UnregisterForCallbacks) (THIS_ _In_ IXAudio2EngineCallback* pCallback) PURE;
// NAME: IXAudio2::CreateSourceVoice
// DESCRIPTION: Creates and configures a source voice.
@@ -1047,6 +1047,8 @@ DECLARE_INTERFACE(IXAudio2VoiceCallback)
#define IXAudio2_QueryInterface(This,riid,ppvInterface) ((This)->lpVtbl->QueryInterface(This,riid,ppvInterface))
#define IXAudio2_AddRef(This) ((This)->lpVtbl->AddRef(This))
#define IXAudio2_Release(This) ((This)->lpVtbl->Release(This))
#define IXAudio2_RegisterForCallbacks(This,pCallback) ((This)->lpVtbl->RegisterForCallbacks(This,pCallback))
#define IXAudio2_UnregisterForCallbacks(This,pCallback) ((This)->lpVtbl->UnregisterForCallbacks(This,pCallback))
#define IXAudio2_CreateSourceVoice(This,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) ((This)->lpVtbl->CreateSourceVoice(This,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain))
#define IXAudio2_CreateSubmixVoice(This,ppSubmixVoice,InputChannels,InputSampleRate,Flags,ProcessingStage,pSendList,pEffectChain) ((This)->lpVtbl->CreateSubmixVoice(This,ppSubmixVoice,InputChannels,InputSampleRate,Flags,ProcessingStage,pSendList,pEffectChain))
#define IXAudio2_CreateMasteringVoice(This,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceId,pEffectChain,StreamCategory) ((This)->lpVtbl->CreateMasteringVoice(This,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceId,pEffectChain,StreamCategory))
@@ -1215,7 +1217,7 @@ __inline float XAudio2CutoffFrequencyToRadians(float CutoffFrequency, UINT32 Sam
{
return XAUDIO2_MAX_FILTER_FREQUENCY;
}
return 2.0f * sinf((float)M_PI * CutoffFrequency / SampleRate);
return 2.0f * sinf((float)M_PI * CutoffFrequency / (float)SampleRate);
}
// Convert from radian frequencies back to absolute frequencies in Hertz
@@ -1234,7 +1236,7 @@ __inline float XAudio2CutoffFrequencyToOnePoleCoefficient(float CutoffFrequency,
{
return XAUDIO2_MAX_FILTER_FREQUENCY;
}
return ( 1.0f - powf(1.0f - 2.0f * CutoffFrequency / SampleRate, 2.0f) );
return ( 1.0f - powf(1.0f - 2.0f * CutoffFrequency / (float)SampleRate, 2.0f) );
}
@@ -1271,4 +1273,3 @@ XAUDIO2_STDAPI XAudio2Create(_Outptr_ IXAudio2** ppXAudio2, UINT32 Flags X2DEFAU
#endif // #ifndef GUID_DEFS_ONLY
#endif // #ifndef __XAUDIO2_INCLUDED__
Binary file not shown.
+1 -1
+13 -9
View File
@@ -1,14 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug - LLVM|x64">
<Configuration>Debug - LLVM</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release - LLVM|x64">
<Configuration>Release - LLVM</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -72,6 +64,7 @@
<ClCompile Include="curl\lib\asyn-ares.c" />
<ClCompile Include="curl\lib\asyn-thread.c" />
<ClCompile Include="curl\lib\base64.c" />
<ClCompile Include="curl\lib\c-hyper.c" />
<ClCompile Include="curl\lib\conncache.c" />
<ClCompile Include="curl\lib\connect.c" />
<ClCompile Include="curl\lib\content_encoding.c" />
@@ -99,6 +92,8 @@
<ClCompile Include="curl\lib\dotdot.c" />
<ClCompile Include="curl\lib\dynbuf.c" />
<ClCompile Include="curl\lib\easy.c" />
<ClCompile Include="curl\lib\easygetopt.c" />
<ClCompile Include="curl\lib\easyoptions.c" />
<ClCompile Include="curl\lib\escape.c" />
<ClCompile Include="curl\lib\file.c" />
<ClCompile Include="curl\lib\fileinfo.c" />
@@ -116,8 +111,10 @@
<ClCompile Include="curl\lib\hostip4.c" />
<ClCompile Include="curl\lib\hostip6.c" />
<ClCompile Include="curl\lib\hostsyn.c" />
<ClCompile Include="curl\lib\hsts.c" />
<ClCompile Include="curl\lib\http.c" />
<ClCompile Include="curl\lib\http2.c" />
<ClCompile Include="curl\lib\http_aws_sigv4.c" />
<ClCompile Include="curl\lib\http_chunks.c" />
<ClCompile Include="curl\lib\http_digest.c" />
<ClCompile Include="curl\lib\http_negotiate.c" />
@@ -152,7 +149,6 @@
<ClCompile Include="curl\lib\rand.c" />
<ClCompile Include="curl\lib\rename.c" />
<ClCompile Include="curl\lib\rtsp.c" />
<ClCompile Include="curl\lib\security.c" />
<ClCompile Include="curl\lib\select.c" />
<ClCompile Include="curl\lib\sendf.c" />
<ClCompile Include="curl\lib\setopt.c" />
@@ -179,8 +175,10 @@
<ClCompile Include="curl\lib\transfer.c" />
<ClCompile Include="curl\lib\url.c" />
<ClCompile Include="curl\lib\urlapi.c" />
<ClCompile Include="curl\lib\vauth\gsasl.c" />
<ClCompile Include="curl\lib\version.c" />
<ClCompile Include="curl\lib\version_win32.c" />
<ClCompile Include="curl\lib\vtls\rustls.c" />
<ClCompile Include="curl\lib\warnless.c" />
<ClCompile Include="curl\lib\wildcard.c" />
<ClCompile Include="curl\lib\x509asn1.c" />
@@ -231,6 +229,7 @@
<ClInclude Include="curl\lib\amigaos.h" />
<ClInclude Include="curl\lib\arpa_telnet.h" />
<ClInclude Include="curl\lib\asyn.h" />
<ClInclude Include="curl\lib\c-hyper.h" />
<ClInclude Include="curl\lib\config-amigaos.h" />
<ClInclude Include="curl\lib\config-dos.h" />
<ClInclude Include="curl\lib\config-mac.h" />
@@ -257,6 +256,7 @@
<ClInclude Include="curl\lib\curl_get_line.h" />
<ClInclude Include="curl\lib\curl_gssapi.h" />
<ClInclude Include="curl\lib\curl_hmac.h" />
<ClInclude Include="curl\lib\curl_krb5.h" />
<ClInclude Include="curl\lib\curl_ldap.h" />
<ClInclude Include="curl\lib\curl_md4.h" />
<ClInclude Include="curl\lib\curl_md5.h" />
@@ -281,6 +281,7 @@
<ClInclude Include="curl\lib\dotdot.h" />
<ClInclude Include="curl\lib\dynbuf.h" />
<ClInclude Include="curl\lib\easyif.h" />
<ClInclude Include="curl\lib\easyoptions.h" />
<ClInclude Include="curl\lib\escape.h" />
<ClInclude Include="curl\lib\file.h" />
<ClInclude Include="curl\lib\fileinfo.h" />
@@ -292,8 +293,10 @@
<ClInclude Include="curl\lib\hash.h" />
<ClInclude Include="curl\lib\hostcheck.h" />
<ClInclude Include="curl\lib\hostip.h" />
<ClInclude Include="curl\lib\hsts.h" />
<ClInclude Include="curl\lib\http.h" />
<ClInclude Include="curl\lib\http2.h" />
<ClInclude Include="curl\lib\http_aws_sigv4.h" />
<ClInclude Include="curl\lib\http_chunks.h" />
<ClInclude Include="curl\lib\http_digest.h" />
<ClInclude Include="curl\lib\http_negotiate.h" />
@@ -351,6 +354,7 @@
<ClInclude Include="curl\lib\urlapi-int.h" />
<ClInclude Include="curl\lib\urldata.h" />
<ClInclude Include="curl\lib\version_win32.h" />
<ClInclude Include="curl\lib\vtls\rustls.h" />
<ClInclude Include="curl\lib\warnless.h" />
<ClInclude Include="curl\lib\wildcard.h" />
<ClInclude Include="curl\lib\x509asn1.h" />
+72 -3
View File
@@ -264,9 +264,6 @@
<ClCompile Include="curl\lib\rtsp.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\security.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\select.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -447,6 +444,42 @@
<ClCompile Include="curl\lib\vtls\wolfssl.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\dynbuf.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\mqtt.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\version_win32.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\vquic\vquic.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\vtls\keylog.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\c-hyper.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\easygetopt.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\easyoptions.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\hsts.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\http_aws_sigv4.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\vtls\rustls.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\vauth\gsasl.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="curl\include\curl\curl.h">
@@ -902,6 +935,42 @@
<ClInclude Include="curl\lib\vtls\wolfssl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\dynbuf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\mqtt.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\setup-win32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\version_win32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\vquic\vquic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\vtls\keylog.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\c-hyper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\curl_krb5.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\easyoptions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\hsts.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\http_aws_sigv4.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\vtls\rustls.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="curl\lib\libcurl.rc">
@@ -1,11 +1,11 @@
cmake_minimum_required(VERSION 2.8.4)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
set(LIBUSB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../libusb/)
project(libusb)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
set(LIBUSB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
option(WITH_DEBUG_LOG "enable debug logging" OFF)
# if debug logging is enabled, by default enable logging
option(WITH_LOGGING "if false, disable all logging" ON)
@@ -2,7 +2,7 @@ include(CheckCXXCompilerFlag)
include(CheckIncludeFiles)
include(CheckTypeSize)
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
if (${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
if (NOT OS_WINDOWS)
# mingw appears to print a bunch of warnings about this
check_cxx_compiler_flag("-fvisibility=hidden" HAVE_VISIBILITY)
@@ -15,9 +15,9 @@
<ProjectGuid>{349EE8F9-7D25-4909-AAF5-FF3FADE72187}</ProjectGuid>
<RootNamespace>libusb</RootNamespace>
</PropertyGroup>
<Import Project="..\common_default.props" />
<Import Project="..\..\common_default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="..\common_default_macros.props" />
<Import Project="..\..\common_default_macros.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
@@ -42,7 +42,7 @@
<ItemDefinitionGroup>
<ClCompile>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>libusb\msvc;libusb\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>src\msvc;src\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WINVER=0x0600;_WIN32_WINNT=0x0600;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
@@ -61,30 +61,30 @@
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="libusb\libusb\core.c" />
<ClCompile Include="libusb\libusb\descriptor.c" />
<ClCompile Include="libusb\libusb\hotplug.c" />
<ClCompile Include="libusb\libusb\io.c" />
<ClCompile Include="libusb\libusb\os\events_windows.c" />
<ClCompile Include="libusb\libusb\strerror.c" />
<ClCompile Include="libusb\libusb\sync.c" />
<ClCompile Include="libusb\libusb\os\threads_windows.c" />
<ClCompile Include="libusb\libusb\os\windows_common.c" />
<ClCompile Include="libusb\libusb\os\windows_usbdk.c" />
<ClCompile Include="libusb\libusb\os\windows_winusb.c" />
<ClCompile Include="src\libusb\core.c" />
<ClCompile Include="src\libusb\descriptor.c" />
<ClCompile Include="src\libusb\hotplug.c" />
<ClCompile Include="src\libusb\io.c" />
<ClCompile Include="src\libusb\os\events_windows.c" />
<ClCompile Include="src\libusb\strerror.c" />
<ClCompile Include="src\libusb\sync.c" />
<ClCompile Include="src\libusb\os\threads_windows.c" />
<ClCompile Include="src\libusb\os\windows_common.c" />
<ClCompile Include="src\libusb\os\windows_usbdk.c" />
<ClCompile Include="src\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="libusb\msvc\config.h" />
<ClInclude Include="libusb\libusb\hotplug.h" />
<ClInclude Include="libusb\libusb\libusb.h" />
<ClInclude Include="libusb\libusb\libusbi.h" />
<ClInclude Include="libusb\libusb\os\events_windows.h" />
<ClInclude Include="libusb\libusb\os\threads_windows.h" />
<ClInclude Include="libusb\libusb\version.h" />
<ClInclude Include="libusb\libusb\version_nano.h" />
<ClInclude Include="libusb\libusb\os\windows_common.h" />
<ClInclude Include="libusb\libusb\os\windows_usbdk.h" />
<ClInclude Include="libusb\libusb\os\windows_winusb.h" />
<ClInclude Include="src\msvc\config.h" />
<ClInclude Include="src\libusb\hotplug.h" />
<ClInclude Include="src\libusb\libusb.h" />
<ClInclude Include="src\libusb\libusbi.h" />
<ClInclude Include="src\libusb\os\events_windows.h" />
<ClInclude Include="src\libusb\os\threads_windows.h" />
<ClInclude Include="src\libusb\version.h" />
<ClInclude Include="src\libusb\version_nano.h" />
<ClInclude Include="src\libusb\os\windows_common.h" />
<ClInclude Include="src\libusb\os\windows_usbdk.h" />
<ClInclude Include="src\libusb\os\windows_winusb.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
View File
+345 -130
View File
File diff suppressed because it is too large Load Diff
+206 -77
View File
@@ -1,5 +1,14 @@
// stb_truetype.h - v1.21 - public domain
// authored from 2009-2016 by Sean Barrett / RAD Game Tools
// stb_truetype.h - v1.24 - public domain
// authored from 2009-2020 by Sean Barrett / RAD Game Tools
//
// =======================================================================
//
// NO SECURITY GUARANTEE -- DO NOT USE THIS ON UNTRUSTED FONT FILES
//
// This library does no range checking of the offsets found in the file,
// meaning an attacker can use it to read arbitrary memory.
//
// =======================================================================
//
// This library processes TrueType files:
// parse files
@@ -32,11 +41,11 @@
// Daniel Ribeiro Maciel
//
// Bug/warning reports/fixes:
// "Zer" on mollyrocket Fabian "ryg" Giesen
// Cass Everitt Martins Mozeiko
// stoiko (Haemimont Games) Cap Petschulat
// Brian Hook Omar Cornut
// Walter van Niftrik github:aloucks
// "Zer" on mollyrocket Fabian "ryg" Giesen github:NiLuJe
// Cass Everitt Martins Mozeiko github:aloucks
// stoiko (Haemimont Games) Cap Petschulat github:oyvindjam
// Brian Hook Omar Cornut github:vassvik
// Walter van Niftrik Ryan Griege
// David Gow Peter LaValle
// David Given Sergey Popov
// Ivan-Assen Ivanov Giumo X. Clanjor
@@ -44,11 +53,14 @@
// Johan Duparc Thomas Fields
// Hou Qiming Derek Vinyard
// Rob Loach Cort Stratton
// Kenney Phillis Jr. github:oyvindjam
// Brian Costabile github:vassvik
//
// Kenney Phillis Jr. Brian Costabile
// Ken Voskuil (kaesve)
//
// VERSION HISTORY
//
// 1.24 (2020-02-05) fix warning
// 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS)
// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined
// 1.21 (2019-02-25) fix warning
// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod
@@ -208,7 +220,7 @@
//
// Advancing for the next character:
// Call GlyphHMetrics, and compute 'current_point += SF * advance'.
//
//
//
// ADVANCED USAGE
//
@@ -333,7 +345,7 @@ int main(int argc, char **argv)
}
return 0;
}
#endif
#endif
//
// Output:
//
@@ -347,9 +359,9 @@ int main(int argc, char **argv)
// :@@. M@M
// @@@o@@@@
// :M@@V:@@.
//
//
//////////////////////////////////////////////////////////////////////////////
//
//
// Complete program: print "Hello World!" banner, with bugs
//
#if 0
@@ -650,7 +662,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, cons
// Calling these functions in sequence is roughly equivalent to calling
// stbtt_PackFontRanges(). If you more control over the packing of multiple
// fonts, or if you want to pack custom data into a font texture, take a look
// at the source to of stbtt_PackFontRanges() and create a custom version
// at the source to of stbtt_PackFontRanges() and create a custom version
// using these functions, e.g. call GatherRects multiple times,
// building up a single array of rects, then call PackRects once,
// then call RenderIntoRects repeatedly. This may result in a
@@ -702,7 +714,7 @@ struct stbtt_fontinfo
int numGlyphs; // number of glyphs, needed for range checking
int loca,head,glyf,hhea,hmtx,kern,gpos; // table locations as offset from start of .ttf
int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf
int index_map; // a cmap mapping for our chosen character encoding
int indexToLocFormat; // format needed to map from glyph index to glyph
@@ -785,6 +797,18 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1,
STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
// as above, but takes one or more glyph indices for greater efficiency
typedef struct stbtt_kerningentry
{
int glyph1; // use stbtt_FindGlyphIndex
int glyph2;
int advance;
} stbtt_kerningentry;
STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info);
STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length);
// Retrieves a complete list of all of the kerning pairs provided by the font
// stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write.
// The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1)
//////////////////////////////////////////////////////////////////////////////
//
@@ -829,6 +853,11 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
// frees the data allocated above
STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg);
STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg);
// fills svg with the character's SVG data.
// returns data size or 0 if SVG not found.
//////////////////////////////////////////////////////////////////////////////
//
// BITMAP RENDERING
@@ -958,7 +987,7 @@ STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, floa
// and computing from that can allow drop-out prevention).
//
// The algorithm has not been optimized at all, so expect it to be slow
// if computing lots of characters or very large sizes.
// if computing lots of characters or very large sizes.
@@ -1330,6 +1359,22 @@ static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict)
return stbtt__cff_get_index(&cff);
}
// since most people won't use this, find this table the first time it's needed
static int stbtt__get_svg(stbtt_fontinfo *info)
{
stbtt_uint32 t;
if (info->svg < 0) {
t = stbtt__find_table(info->data, info->fontstart, "SVG ");
if (t) {
stbtt_uint32 offset = ttULONG(info->data + t + 2);
info->svg = t + offset;
} else {
info->svg = 0;
}
}
return info->svg;
}
static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart)
{
stbtt_uint32 cmap, t;
@@ -1409,6 +1454,8 @@ static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, in
else
info->numGlyphs = 0xffff;
info->svg = -1;
// find a cmap encoding table we understand *now* to avoid searching
// later. (todo: could make this installable)
// the same regardless of glyph.
@@ -1715,7 +1762,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s
if (i != 0)
num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
// now start the new one
// now start the new one
start_off = !(flags & 1);
if (start_off) {
// if we start off with an off-curve point, then when we need to find a point on the curve
@@ -1757,7 +1804,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s
}
}
num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
} else if (numberOfContours == -1) {
} else if (numberOfContours < 0) {
// Compound shapes.
int more = 1;
stbtt_uint8 *comp = data + g + 10;
@@ -1768,7 +1815,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s
int comp_num_verts = 0, i;
stbtt_vertex *comp_verts = 0, *tmp = 0;
float mtx[6] = {1,0,0,1,0,0}, m, n;
flags = ttSHORT(comp); comp+=2;
gidx = ttSHORT(comp); comp+=2;
@@ -1798,7 +1845,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s
mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
}
// Find transformation scales.
m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
@@ -1834,9 +1881,6 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s
// More components ?
more = flags & (1<<5);
}
} else if (numberOfContours < 0) {
// @TODO other compound variations?
STBTT_assert(0);
} else {
// numberOfCounters == 0, do nothing
}
@@ -2265,6 +2309,48 @@ STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_inde
}
}
STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info)
{
stbtt_uint8 *data = info->data + info->kern;
// we only look at the first table. it must be 'horizontal' and format 0.
if (!info->kern)
return 0;
if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
return 0;
if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
return 0;
return ttUSHORT(data+10);
}
STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length)
{
stbtt_uint8 *data = info->data + info->kern;
int k, length;
// we only look at the first table. it must be 'horizontal' and format 0.
if (!info->kern)
return 0;
if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
return 0;
if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
return 0;
length = ttUSHORT(data+10);
if (table_length < length)
length = table_length;
for (k = 0; k < length; k++)
{
table[k].glyph1 = ttUSHORT(data+18+(k*6));
table[k].glyph2 = ttUSHORT(data+20+(k*6));
table[k].advance = ttSHORT(data+22+(k*6));
}
return length;
}
static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
{
stbtt_uint8 *data = info->data + info->kern;
@@ -2540,8 +2626,7 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int
if (info->gpos)
xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
if (info->kern)
else if (info->kern)
xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
return xAdvance;
@@ -2602,6 +2687,45 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
STBTT_free(v, info->userdata);
}
STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl)
{
int i;
stbtt_uint8 *data = info->data;
stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *) info);
int numEntries = ttUSHORT(svg_doc_list);
stbtt_uint8 *svg_docs = svg_doc_list + 2;
for(i=0; i<numEntries; i++) {
stbtt_uint8 *svg_doc = svg_docs + (12 * i);
if ((gl >= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2)))
return svg_doc;
}
return 0;
}
STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg)
{
stbtt_uint8 *data = info->data;
stbtt_uint8 *svg_doc;
if (info->svg == 0)
return 0;
svg_doc = stbtt_FindSVGDoc(info, gl);
if (svg_doc != NULL) {
*svg = (char *) data + info->svg + ttULONG(svg_doc + 4);
return ttULONG(svg_doc + 8);
} else {
return 0;
}
}
STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg)
{
return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg);
}
//////////////////////////////////////////////////////////////////////////////
//
// antialiasing software rasterizer
@@ -2727,7 +2851,7 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
STBTT_assert(z != NULL);
if (!z) return z;
// round dx down to avoid overshooting
if (dxdy < 0)
z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
@@ -2805,7 +2929,7 @@ static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__ac
}
}
}
e = e->next;
}
}
@@ -3533,7 +3657,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info
{
int ix0,iy0,ix1,iy1;
stbtt__bitmap gbm;
stbtt_vertex *vertices;
stbtt_vertex *vertices;
int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
if (scale_x == 0) scale_x = scale_y;
@@ -3556,7 +3680,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info
if (height) *height = gbm.h;
if (xoff ) *xoff = ix0;
if (yoff ) *yoff = iy0;
if (gbm.w && gbm.h) {
gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
if (gbm.pixels) {
@@ -3567,7 +3691,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info
}
STBTT_free(vertices, info->userdata);
return gbm.pixels;
}
}
STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff)
{
@@ -3579,7 +3703,7 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigne
int ix0,iy0;
stbtt_vertex *vertices;
int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
stbtt__bitmap gbm;
stbtt__bitmap gbm;
stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0);
gbm.pixels = output;
@@ -3601,7 +3725,7 @@ STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *
STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
{
return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
}
}
STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint)
{
@@ -3616,7 +3740,7 @@ STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, uns
STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
{
return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff);
}
}
STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint)
{
@@ -3741,7 +3865,7 @@ static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *no
con->y = 0;
con->bottom_y = 0;
STBTT__NOTUSED(nodes);
STBTT__NOTUSED(num_nodes);
STBTT__NOTUSED(num_nodes);
}
static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects)
@@ -3968,6 +4092,7 @@ static float stbtt__oversample_shift(int oversample)
STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
{
int i,j,k;
int missing_glyph_added = 0;
k=0;
for (i=0; i < num_ranges; ++i) {
@@ -3979,7 +4104,7 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
int x0,y0,x1,y1;
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
int glyph = stbtt_FindGlyphIndex(info, codepoint);
if (glyph == 0 && spc->skip_missing) {
if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
rects[k].w = rects[k].h = 0;
} else {
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
@@ -3989,6 +4114,8 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
&x0,&y0,&x1,&y1);
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
if (glyph == 0)
missing_glyph_added = 1;
}
++k;
}
@@ -4023,7 +4150,7 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info
// rects array must be big enough to accommodate all characters in the given ranges
STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
{
int i,j,k, return_value = 1;
int i,j,k, missing_glyph = -1, return_value = 1;
// save current values
int old_h_over = spc->h_oversample;
@@ -4088,6 +4215,13 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const
bc->yoff = (float) y0 * recip_v + sub_y;
bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
if (glyph == 0)
missing_glyph = j;
} else if (spc->skip_missing) {
return_value = 0;
} else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) {
ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
} else {
return_value = 0; // if any fail, report failure
}
@@ -4126,7 +4260,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char
n = 0;
for (i=0; i < num_ranges; ++i)
n += ranges[i].num_chars;
rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
if (rects == NULL)
return 0;
@@ -4137,7 +4271,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char
n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
stbtt_PackFontRangesPackRects(spc, rects, n);
return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
STBTT_free(rects, spc->user_allocator_context);
@@ -4298,7 +4432,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
int x1 = (int) verts[i ].x, y1 = (int) verts[i ].y;
if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
if (x_inter < x)
if (x_inter < x)
winding += (y0 < y1) ? 1 : -1;
}
}
@@ -4324,7 +4458,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
y1 = (int)verts[i ].y;
if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
if (x_inter < x)
if (x_inter < x)
winding += (y0 < y1) ? 1 : -1;
}
} else {
@@ -4336,7 +4470,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
if (hits[1][0] < 0)
winding += (hits[1][1] < 0 ? -1 : 1);
}
}
}
}
}
return winding;
@@ -4389,12 +4523,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
int w,h;
unsigned char *data;
// if one scale is 0, use same scale for both
if (scale_x == 0) scale_x = scale_y;
if (scale_y == 0) {
if (scale_x == 0) return NULL; // if both scales are 0, return NULL
scale_y = scale_x;
}
if (scale == 0) return NULL;
stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1);
@@ -4417,7 +4546,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
// invert for y-downwards bitmaps
scale_y = -scale_y;
{
int x,y,i,j;
float *precompute;
@@ -4566,7 +4695,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
STBTT_free(verts, info->userdata);
}
return data;
}
}
STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff)
{
@@ -4584,7 +4713,7 @@ STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata)
//
// check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string
static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2)
static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2)
{
stbtt_int32 i=0;
@@ -4623,7 +4752,7 @@ static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, s
return i;
}
static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2)
static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2)
{
return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2);
}
@@ -4752,7 +4881,7 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset,
STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index)
{
return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index);
return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index);
}
STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data)
@@ -4845,38 +4974,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/
+22 -17
View File
@@ -7,11 +7,11 @@ Other instructions may be found [here](https://wiki.rpcs3.net/index.php?title=Bu
### Windows 7 or later
* [CMake 3.14.1+](https://www.cmake.org/download/) (add to PATH)
* [Python 3.3+](https://www.python.org/downloads/) (add to PATH)
* [CMake 3.16.9+](https://www.cmake.org/download/) (add to PATH)
* [Python 3.6+](https://www.python.org/downloads/) (add to PATH)
* [Qt 5.15.2](https://www.qt.io/download-qt-installer)
* [Visual Studio 2019](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community)
* [Vulkan SDK 1.1.126+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html))
* [Vulkan SDK 1.2.154+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html))
**Either add the** `QTDIR` **environment variable, e.g.** `<QtInstallFolder>\5.15.2\msvc2019_64\` **, or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2019)**
@@ -19,10 +19,10 @@ Other instructions may be found [here](https://wiki.rpcs3.net/index.php?title=Bu
These are the essentials tools to build RPCS3 on Linux. Some of them can be installed through your favorite package manager.
* Clang 11+ or GCC 9+
* [CMake 3.14.1+](https://www.cmake.org/download/)
* Clang 12+ or GCC 10+
* [CMake 3.16.9+](https://www.cmake.org/download/)
* [Qt 5.15.2](https://www.qt.io/download-qt-installer)
* [Vulkan SDK 1.1.126+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html))
* [Vulkan SDK 1.2.154+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html))
* [SDL2](https://www.libsdl.org/download-2.0.php) (for the FAudio backend)
**If you have an NVIDIA GPU, you may need to install the libglvnd package.**
@@ -43,20 +43,20 @@ Ubuntu usually does not have a new enough Qt package to suit rpcs3's needs. Ther
. /etc/os-release
sudo add-apt-repository ppa:beineri/opt-qt-5.15.2-$UBUNTU_CODENAME
sudo apt-get update
sudo apt-get install qt515-meta-minimal qt515svg
sudo apt-get install qt515base qt515svg
. /opt/qt515/bin/qt515-env.sh >/dev/null 2>&1
```
##### GCC 9.x installation
##### GCC 10.x installation
If the `gcc-9` package is not available on your system, use the following commands
If the `gcc-10` package is not available on your system, use the following commands
```
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-9 g++-9
sudo apt-get install gcc-10 g++-10
```
You can either use `update-alternatives` to setup `gcc-9`/`g++-9` as your default compilers or prefix any `cmake` command by `CXX=g++-9 CC=gcc-9 ` to use it.
You can either use `update-alternatives` to setup `gcc-10`/`g++-10` as your default compilers or prefix any `cmake` command by `CXX=g++-10 CC=gcc-10 ` to use it.
##### Vulkan SDK
@@ -64,7 +64,7 @@ For Ubuntu systems, it is strongly recommended to use the PPA from [LunarG](http
```
. /etc/os-release
wget -qO - https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add -
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.2.148-$UBUNTU_CODENAME.list https://packages.lunarg.com/vulkan/1.2.148/lunarg-vulkan-1.2.148-$UBUNTU_CODENAME.list
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.2.154-$UBUNTU_CODENAME.list https://packages.lunarg.com/vulkan/1.2.154/lunarg-vulkan-1.2.154-$UBUNTU_CODENAME.list
sudo apt update
sudo apt install vulkan-sdk
```
@@ -82,11 +82,11 @@ sudo apt-get install cmake
#### Fedora
sudo dnf install alsa-lib-devel cmake glew glew-devel libatomic libevdev-devel libudev-devel openal-devel qt5-devel qt5-qtbase-private-devel vulkan-devel
sudo dnf install alsa-lib-devel cmake glew glew-devel libatomic libevdev-devel libudev-devel openal-devel qt5-qtbase-devel qt5-qtbase-private-devel vulkan-devel
#### OpenSUSE
sudo zypper install git cmake libasound2 libpulse-devel openal-soft-devel glew-devel zlib-devel libedit-devel vulkan-devel libudev-devel libqt5-qtbase-devel libevdev-devel
sudo zypper install git cmake libasound2 libpulse-devel openal-soft-devel glew-devel zlib-devel libedit-devel vulkan-devel libudev-devel libqt5-qtbase-devel libqt5gui-private-headers-devel libevdev-devel
## Setup the project
@@ -108,11 +108,16 @@ git submodule update --init
#### Building the projects
Open `rpcs3.sln`. The recommended build configuration is `Release - LLVM` for all purposes.
Open `rpcs3.sln`. The recommended build configuration is `Release`. (On older revisions: `Release - LLVM`)
You may want to download the precompiled [LLVM libs](https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win/llvmlibs_mt.7z) and extract them to the root rpcs3 folder (which contains `rpcs3.sln`), as well as download and extract the [additional libs](https://github.com/RPCS3/glslang/releases/download/custom-build-win/glslanglibs_mt.7z) to `lib\%CONFIGURATION%-x64\` to speed up compilation time (unoptimised/debug libs are currently not available precompiled).
If you're not using the precompiled libs, build the projects in *__BUILD_BEFORE* folder: right-click on every project > *Build*.
If you're not using the precompiled libs, build the following projects in *__BUILD_BEFORE* folder by right-clicking on a project > *Build*.:
* glslang-build
* **Either** llvm_build **or** llvm_build_clang_cl
* spirv-tools-build
Afterwards:
`Build > Build Solution`
@@ -121,7 +126,7 @@ If you're not using the precompiled libs, build the projects in *__BUILD_BEFORE*
While still in the project root:
1) `cd .. && mkdir rpcs3_build && cd rpcs3_build`
2) `cmake ../rpcs3/ && make` or `CXX=g++-9 CC=gcc-9 cmake ../rpcs3/ && make` to force these compilers
2) `cmake ../rpcs3/ && make` or `CXX=g++-10 CC=gcc-10 cmake ../rpcs3/ && make` to force these compilers
3) Run RPCS3 with `./bin/rpcs3`
When using GDB, configure it to ignore SIGSEGV signal (`handle SIGSEGV nostop noprint`).
+29 -36
View File
@@ -1,61 +1,54 @@
cmake_minimum_required(VERSION 3.14.1)
cmake_minimum_required(VERSION 3.16.9)
project(rpcs3)
if(CMAKE_COMPILER_IS_GNUCXX)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9)
message(FATAL_ERROR "RPCS3 requires at least gcc-9.")
endif()
if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10)
message(FATAL_ERROR "RPCS3 requires at least gcc-10.")
endif()
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11.0)
message(FATAL_ERROR "RPCS3 requires at least clang-11.0.")
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0)
message(FATAL_ERROR "RPCS3 requires at least clang-12.0.")
endif()
endif()
option(USE_NATIVE_INSTRUCTIONS "USE_NATIVE_INSTRUCTIONS makes rpcs3 compile with -march=native, which is useful for local builds, but not good for packages." ON)
option(WITH_LLVM "Enable usage of LLVM library" ON)
option(BUILD_LLVM_SUBMODULE "Build LLVM from git submodule" ON)
option(USE_ALSA "ALSA audio backend" ON)
option(USE_PULSE "PulseAudio audio backend" ON)
option(USE_FAUDIO "FAudio audio backend" ON)
option(USE_LIBEVDEV "libevdev-based joystick support" ON)
option(USE_DISCORD_RPC "Discord rich presence integration" ON)
option(USE_SYSTEM_ZLIB "Prefer system ZLIB instead of the builtin one" ON)
option(USE_VULKAN "Vulkan render backend" ON)
option(USE_PRECOMPILED_HEADERS "Use precompiled headers" OFF)
# include build options
include(options.cmake)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/rpcs3/cmake_modules")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
set(CMAKE_CXX_STANDARD 20)
include(CheckCXXCompilerFlag)
if (NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type selected, default to Release")
set(CMAKE_BUILD_TYPE "Release")
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type selected, default to Release")
set(CMAKE_BUILD_TYPE "Release")
endif()
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DNDEBUG)
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
add_definitions(-DNDEBUG)
elseif(NOT MSVC)
add_definitions(-D_DEBUG)
endif()
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
message( FATAL_ERROR "RPCS3 can only be compiled on 64-bit platforms." )
message( FATAL_ERROR "RPCS3 can only be compiled on 64-bit platforms." )
endif()
find_program(CCACHE_FOUND ccache)
if (CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
if(CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif()
if(WIN32)
add_definitions(-DUNICODE)
add_definitions(-D_WIN32_WINNT=0x0602)
add_definitions(-DUNICODE)
add_definitions(-D_WIN32_WINNT=0x0602)
endif()
if(APPLE)
include_directories(/opt/local/include)
link_directories(/opt/local/lib)
include_directories(/opt/local/include)
link_directories(/opt/local/lib)
endif()
# Warnings are silenced for 3rdparty code
@@ -64,7 +57,7 @@ set(CMAKE_C_FLAGS -w)
set(LLVM_ENABLE_WARNINGS OFF CACHE BOOL "")
if(MSVC)
add_compile_options(/wd4530 /utf-8) # C++ exception handler used, but unwind semantics are not enabled
add_compile_options(/wd4530 /utf-8) # C++ exception handler used, but unwind semantics are not enabled
endif()
add_subdirectory(Vulkan EXCLUDE_FROM_ALL)
@@ -74,8 +67,8 @@ add_subdirectory(3rdparty)
unset(CMAKE_CXX_FLAGS)
unset(CMAKE_C_FLAGS)
if (NOT WIN32)
add_compile_options(-pthread)
if(NOT WIN32)
add_compile_options(-pthread)
endif()
# TODO: do real installation, including copying directory structure
+15 -6
View File
@@ -3,11 +3,16 @@
#include "util/types.hpp"
#include "Utilities/StrFmt.h"
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#endif
template<typename T, uint N>
struct bf_base
{
using type = T;
using vtype = simple_t<type>;
using vtype = std::common_type_t<type>;
using utype = typename std::make_unsigned<vtype>::type;
// Datatype bitsize
@@ -217,7 +222,7 @@ struct cf_t<void>
}
template<typename T>
static constexpr auto extract(const T& data) -> decltype(+T())
static constexpr auto extract(const T&) -> decltype(+T())
{
return 0;
}
@@ -237,7 +242,7 @@ struct ff_t : bf_base<T, N>
using vtype = typename ff_t::vtype;
// Return constant value
static constexpr vtype extract(const type& data)
static constexpr vtype extract(const type&)
{
static_assert((V & ff_t::vmask) == V, "ff_t<> error: V out of bounds");
return V;
@@ -250,10 +255,14 @@ struct ff_t : bf_base<T, N>
}
};
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif
template<typename T, uint I, uint N>
struct fmt_unveil<bf_t<T, I, N>, void>
{
using type = typename fmt_unveil<simple_t<T>>::type;
using type = typename fmt_unveil<std::common_type_t<T>>::type;
static inline auto get(const bf_t<T, I, N>& bf)
{
@@ -264,7 +273,7 @@ struct fmt_unveil<bf_t<T, I, N>, void>
template<typename F, typename... Fields>
struct fmt_unveil<cf_t<F, Fields...>, void>
{
using type = typename fmt_unveil<simple_t<typename F::type>>::type;
using type = typename fmt_unveil<std::common_type_t<typename F::type>>::type;
static inline auto get(const cf_t<F, Fields...>& cf)
{
@@ -275,7 +284,7 @@ struct fmt_unveil<cf_t<F, Fields...>, void>
template<typename T, T V, uint N>
struct fmt_unveil<ff_t<T, V, N>, void>
{
using type = typename fmt_unveil<simple_t<T>>::type;
using type = typename fmt_unveil<std::common_type_t<T>>::type;
static inline auto get(const ff_t<T, V, N>& ff)
{
+1 -3
View File
@@ -295,7 +295,7 @@ namespace CRCPP
static CRCType Finalize(CRCType remainder, CRCType finalXOR, bool reflectOutput);
template <typename CRCType, crcpp_uint16 CRCWidth>
static CRCType UndoFinalize(CRCType remainder, CRCType finalXOR, bool reflectOutput);
static CRCType UndoFinalize(CRCType crc, CRCType finalXOR, bool reflectOutput);
template <typename CRCType, crcpp_uint16 CRCWidth>
static CRCType CalculateRemainder(const void * data, crcpp_size size, const Parameters<CRCType, CRCWidth> & parameters, CRCType remainder);
@@ -771,8 +771,6 @@ namespace CRCPP
in a function even in a branch will never be executed. This also means we don't need pragmas
to get rid of warnings, but it still can be computed at compile-time. Win-win!
@param[in] x Compile-time expression to bound
@tparam CRCType Integer type for storing the CRC result
@tparam CRCWidth Number of bits in the CRC
@return Non-negative compile-time expression
*/
template <typename IntegerType>
+16 -15
View File
@@ -4,7 +4,6 @@
#include "util/yaml.hpp"
#include <typeinfo>
#include <charconv>
LOG_CHANNEL(cfg_log, "CFG");
@@ -21,27 +20,29 @@ namespace cfg
}
_base::_base(type _type, node* owner, const std::string& name, bool dynamic)
: m_type(_type), m_dynamic(dynamic)
: m_type(_type), m_dynamic(dynamic), m_name(name)
{
for (const auto& pair : owner->m_nodes)
for (const auto& node : owner->m_nodes)
{
if (pair.first == name)
if (node->get_name() == name)
{
cfg_log.fatal("Node already exists: %s", name);
}
}
owner->m_nodes.emplace_back(name, this);
owner->m_nodes.emplace_back(this);
}
bool _base::from_string(const std::string&, bool)
{
fmt::throw_exception("from_string() purecall");
cfg_log.fatal("cfg::_base::from_string() purecall");
return false;
}
bool _base::from_list(std::vector<std::string>&&)
{
fmt::throw_exception("from_list() purecall");
cfg_log.fatal("cfg::_base::from_list() purecall");
return false;
}
// Emit YAML
@@ -137,7 +138,7 @@ bool cfg::try_to_uint64(u64* out, const std::string& value, u64 min, u64 max)
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string& value)
{
u64 max = -1;
u64 max = umax;
for (u64 i = 0;; i++)
{
@@ -219,11 +220,11 @@ void cfg::encode(YAML::Emitter& out, const cfg::_base& rhs)
case type::node:
{
out << YAML::BeginMap;
for (const auto& np : static_cast<const node&>(rhs).get_nodes())
for (const auto& node : static_cast<const node&>(rhs).get_nodes())
{
out << YAML::Key << np.first;
out << YAML::Key << node->get_name();
out << YAML::Value;
encode(out, *np.second);
encode(out, *node);
}
out << YAML::EndMap;
@@ -282,11 +283,11 @@ void cfg::decode(const YAML::Node& data, cfg::_base& rhs, bool dynamic)
if (!pair.first.IsScalar()) continue;
// Find the key among existing nodes
for (const auto& _pair : static_cast<node&>(rhs).get_nodes())
for (const auto& node : static_cast<node&>(rhs).get_nodes())
{
if (_pair.first == pair.first.Scalar())
if (node->get_name() == pair.first.Scalar())
{
decode(pair.second, *_pair.second, dynamic);
decode(pair.second, *node, dynamic);
}
}
}
@@ -367,7 +368,7 @@ void cfg::node::from_default()
{
for (auto& node : m_nodes)
{
node.second->from_default();
node->from_default();
}
}
+10 -13
View File
@@ -48,10 +48,11 @@ namespace cfg
// Config tree entry abstract base class
class _base
{
const type m_type;
const type m_type{};
protected:
bool m_dynamic = true;
const std::string m_name{};
// Ownerless entry constructor
_base(type _type);
@@ -64,11 +65,15 @@ namespace cfg
_base& operator=(const _base&) = delete;
virtual ~_base() = default;
// Get type
type get_type() const { return m_type; }
const std::string& get_name() const { return m_name; }
// Get dynamic property for reloading configs during games
bool get_is_dynamic() const { return m_dynamic; };
bool get_is_dynamic() const { return m_dynamic; }
// Reset defaults
virtual void from_default() = 0;
@@ -95,7 +100,7 @@ namespace cfg
// Config tree node which contains another nodes
class node : public _base
{
std::vector<std::pair<std::string, _base*>> m_nodes;
std::vector<_base*> m_nodes{};
friend class _base;
@@ -391,8 +396,6 @@ namespace cfg
// Simple string entry with mutex
class string : public _base
{
const std::string m_name;
atomic_ptr<std::string> m_value;
public:
@@ -400,7 +403,6 @@ namespace cfg
string(node* owner, std::string name, std::string def = {}, bool dynamic = false)
: _base(type::string, owner, name, dynamic)
, m_name(std::move(name))
, m_value(def)
, def(std::move(def))
{
@@ -426,11 +428,6 @@ namespace cfg
}
}
const std::string& get_name() const
{
return m_name;
}
void from_default() override;
std::string to_string() const override
@@ -448,7 +445,7 @@ namespace cfg
// Simple set entry (TODO: template for various types)
class set_entry final : public _base
{
std::set<std::string> m_set;
std::set<std::string> m_set{};
public:
// Default value is empty list in current implementation
@@ -484,7 +481,7 @@ namespace cfg
class log_entry final : public _base
{
std::map<std::string, logs::level> m_map;
std::map<std::string, logs::level> m_map{};
public:
log_entry(node* owner, const std::string& name)
+270 -159
View File
@@ -6,8 +6,6 @@
#include <unordered_map>
#include <algorithm>
#include <cstring>
#include <cerrno>
#include <typeinfo>
#include <map>
#include "util/asm.hpp"
@@ -61,7 +59,7 @@ static void to_utf8(std::string& out, const wchar_t* source)
// Resize buffer
out.resize(buf_size - 1);
const int result = WideCharToMultiByte(CP_UTF8, 0, source, static_cast<int>(length) + 1, &out.front(), buf_size, NULL, NULL);
const int result = WideCharToMultiByte(CP_UTF8, 0, source, static_cast<int>(length) + 1, &out.front(), buf_size, nullptr, nullptr);
// Fix the size
out.resize(ensure(result) - 1);
@@ -206,13 +204,13 @@ namespace fs
class device_manager final
{
mutable shared_mutex m_mutex;
mutable shared_mutex m_mutex{};
std::unordered_map<std::string, std::shared_ptr<device_base>> m_map;
std::unordered_map<std::string, shared_ptr<device_base>> m_map{};
public:
std::shared_ptr<device_base> get_device(const std::string& path);
std::shared_ptr<device_base> set_device(const std::string& name, const std::shared_ptr<device_base>&);
shared_ptr<device_base> get_device(const std::string& path);
shared_ptr<device_base> set_device(const std::string& name, shared_ptr<device_base>);
};
static device_manager& get_device_manager()
@@ -226,9 +224,9 @@ namespace fs
{
}
stat_t file_base::stat()
[[noreturn]] stat_t file_base::stat()
{
fmt::throw_exception("fs::file::stat() not supported for %s", typeid(*this).name());
fmt::throw_exception("fs::file::stat() not supported.");
}
void file_base::sync()
@@ -277,58 +275,163 @@ namespace fs
{
}
device_base::device_base()
: fs_prefix(fmt::format("/vfsv0_%s%s_", fmt::base57(reinterpret_cast<u64>(this)), fmt::base57(utils::get_unique_tsc())))
{
}
device_base::~device_base()
{
}
bool device_base::remove_dir(const std::string&)
{
g_tls_error = error::readonly;
return false;
}
bool device_base::create_dir(const std::string&)
{
g_tls_error = error::readonly;
return false;
}
bool device_base::rename(const std::string&, const std::string&)
{
g_tls_error = error::readonly;
return false;
}
bool device_base::remove(const std::string&)
{
g_tls_error = error::readonly;
return false;
}
bool device_base::trunc(const std::string&, u64)
{
g_tls_error = error::readonly;
return false;
}
bool device_base::utime(const std::string&, s64, s64)
{
g_tls_error = error::readonly;
return false;
}
}
std::shared_ptr<fs::device_base> fs::device_manager::get_device(const std::string& path)
shared_ptr<fs::device_base> fs::device_manager::get_device(const std::string& path)
{
reader_lock lock(m_mutex);
const auto found = m_map.find(path.substr(0, path.find_first_of('/', 2)));
const usz prefix = path.find_first_of('_', 7) + 1;
if (found == m_map.end())
const auto found = m_map.find(path.substr(prefix, path.find_first_of('/', 1) - prefix));
if (found == m_map.end() || !path.starts_with(found->second->fs_prefix))
{
return nullptr;
return null_ptr;
}
return found->second;
}
std::shared_ptr<fs::device_base> fs::device_manager::set_device(const std::string& name, const std::shared_ptr<device_base>& device)
shared_ptr<fs::device_base> fs::device_manager::set_device(const std::string& name, shared_ptr<device_base> device)
{
std::lock_guard lock(m_mutex);
return m_map[name] = device;
if (device)
{
// Adding
if (auto [it, ok] = m_map.try_emplace(name, std::move(device)); ok)
{
return it->second;
}
g_tls_error = error::exist;
}
else
{
// Removing
if (auto found = m_map.find(name); found != m_map.end())
{
device = std::move(found->second);
m_map.erase(found);
return device;
}
g_tls_error = error::noent;
}
return null_ptr;
}
std::shared_ptr<fs::device_base> fs::get_virtual_device(const std::string& path)
shared_ptr<fs::device_base> fs::get_virtual_device(const std::string& path)
{
// Every virtual device path must have "//" at the beginning
if (path.starts_with("//"))
// Every virtual device path must have specific name at the beginning
if (path.starts_with("/vfsv0_") && path.size() >= 8 + 22 && path[29] == '_' && path.find_first_of('/', 1) > 29)
{
return get_device_manager().get_device(path);
}
return nullptr;
return null_ptr;
}
std::shared_ptr<fs::device_base> fs::set_virtual_device(const std::string& name, const std::shared_ptr<device_base>& device)
shared_ptr<fs::device_base> fs::set_virtual_device(const std::string& name, shared_ptr<device_base> device)
{
ensure(name.starts_with("//") && name[2] != '/');
return get_device_manager().set_device(name, device);
return get_device_manager().set_device(name, std::move(device));
}
std::string fs::get_parent_dir(const std::string& path)
{
// Get (basically) processed path
const auto real_path = fs::escape_path(path);
std::string_view result = path;
const auto pos = real_path.find_last_of(delim);
// Number of path components to remove
usz to_remove = 1;
return real_path.substr(0, pos == umax ? 0 : pos);
while (to_remove--)
{
// Trim contiguous delimiters at the end
if (usz sz = result.find_last_not_of(delim) + 1)
{
result = result.substr(0, sz);
}
else
{
return "/";
}
const auto elem = result.substr(result.find_last_of(delim) + 1);
if (elem.empty() || elem.size() == result.size())
{
break;
}
if (elem == ".")
{
to_remove += 1;
}
if (elem == "..")
{
to_remove += 2;
}
result.remove_suffix(elem.size());
}
if (usz sz = result.find_last_not_of(delim) + 1)
{
result = result.substr(0, sz);
}
else
{
return "/";
}
return std::string{result};
}
bool fs::stat(const std::string& path, stat_t& info)
@@ -548,9 +651,17 @@ bool fs::create_dir(const std::string& path)
}
#ifdef _WIN32
if (!CreateDirectoryW(to_wchar(path).get(), NULL))
if (!CreateDirectoryW(to_wchar(path).get(), nullptr))
{
g_tls_error = to_error(GetLastError());
int res = GetLastError();
if (res == ERROR_ACCESS_DENIED && is_dir(path))
{
// May happen on drives
res = ERROR_ALREADY_EXISTS;
}
g_tls_error = to_error(res);
return false;
}
@@ -660,7 +771,7 @@ bool fs::rename(const std::string& from, const std::string& to, bool overwrite)
}
error1 = GetLastError();
CreateDirectoryW(ws2.get(), NULL); // TODO
CreateDirectoryW(ws2.get(), nullptr); // TODO
}
else
{
@@ -829,7 +940,7 @@ bool fs::truncate_file(const std::string& path, u64 length)
#ifdef _WIN32
// Open the file
const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (handle == INVALID_HANDLE_VALUE)
{
g_tls_error = to_error(GetLastError());
@@ -868,7 +979,7 @@ bool fs::utime(const std::string& path, s64 atime, s64 mtime)
#ifdef _WIN32
// Open the file
const auto handle = CreateFileW(to_wchar(path).get(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL, NULL);
const auto handle = CreateFileW(to_wchar(path).get(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE)
{
g_tls_error = to_error(GetLastError());
@@ -901,6 +1012,16 @@ bool fs::utime(const std::string& path, s64 atime, s64 mtime)
#endif
}
void fs::sync()
{
#ifdef _WIN32
fs::g_tls_error = fs::error::unknown;
#else
::sync();
fs::g_tls_error = fs::error::ok;
#endif
}
[[noreturn]] void fs::xnull(const src_loc& loc)
{
fmt::throw_exception("Null object.%s", loc);
@@ -970,7 +1091,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
share |= FILE_SHARE_WRITE;
}
const HANDLE handle = CreateFileW(to_wchar(path).get(), access, share, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL);
const HANDLE handle = CreateFileW(to_wchar(path).get(), access, share, nullptr, disp, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE)
{
@@ -1037,7 +1158,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
const int size = narrow<int>(count);
DWORD nread;
ensure(ReadFile(m_handle, buffer, size, &nread, NULL)); // "file::read"
ensure(ReadFile(m_handle, buffer, size, &nread, nullptr)); // "file::read"
return nread;
}
@@ -1048,21 +1169,24 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
const int size = narrow<int>(count);
DWORD nwritten;
ensure(WriteFile(m_handle, buffer, size, &nwritten, NULL)); // "file::write"
ensure(WriteFile(m_handle, buffer, size, &nwritten, nullptr)); // "file::write"
return nwritten;
}
u64 seek(s64 offset, seek_mode whence) override
{
if (whence > seek_end)
{
fmt::throw_exception("Invalid whence (0x%x)", whence);
}
LARGE_INTEGER pos;
pos.QuadPart = offset;
const DWORD mode =
whence == seek_set ? FILE_BEGIN :
whence == seek_cur ? FILE_CURRENT :
whence == seek_end ? FILE_END :
(fmt::throw_exception("Invalid whence (0x%x)", whence), 0);
whence == seek_cur ? FILE_CURRENT : FILE_END;
if (!SetFilePointerEx(m_handle, pos, &pos, mode))
{
@@ -1097,13 +1221,22 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
if (mode & fs::append) flags |= O_APPEND;
if (mode & fs::create) flags |= O_CREAT;
if (mode & fs::trunc && !(mode & (fs::lock + fs::unread))) flags |= O_TRUNC;
if (mode & fs::trunc && !(mode & fs::lock)) flags |= O_TRUNC;
if (mode & fs::excl) flags |= O_EXCL;
int perm = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
if (mode & fs::write && mode & fs::unread)
{
if (!(mode & (fs::excl + fs::lock)) && mode & fs::trunc)
{
// Alternative to truncation for "unread" flag (TODO)
if (mode & fs::create)
{
::unlink(path.c_str());
}
}
perm = 0;
}
@@ -1115,14 +1248,14 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
return;
}
if (mode & fs::write && mode & (fs::lock + fs::unread) && ::flock(fd, LOCK_EX | LOCK_NB) != 0)
if (mode & fs::write && mode & fs::lock && ::flock(fd, LOCK_EX | LOCK_NB) != 0)
{
g_tls_error = errno == EWOULDBLOCK ? fs::error::acces : to_error(errno);
::close(fd);
return;
}
if (mode & fs::trunc && mode & (fs::lock + fs::unread) && mode & fs::write)
if (mode & fs::trunc && mode & fs::lock && mode & fs::write)
{
// Postpone truncation in order to avoid using O_TRUNC on a locked file
ensure(::ftruncate(fd, 0) == 0);
@@ -1196,11 +1329,14 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
u64 seek(s64 offset, seek_mode whence) override
{
if (whence > seek_end)
{
fmt::throw_exception("Invalid whence (0x%x)", whence);
}
const int mode =
whence == seek_set ? SEEK_SET :
whence == seek_cur ? SEEK_CUR :
whence == seek_end ? SEEK_END :
(fmt::throw_exception("Invalid whence (0x%x)", whence), 0);
whence == seek_cur ? SEEK_CUR : SEEK_END;
const auto result = ::lseek(m_fd, offset, mode);
@@ -1231,8 +1367,19 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
static_assert(sizeof(iovec) == sizeof(iovec_clone), "Weird iovec size");
static_assert(offsetof(iovec, iov_len) == offsetof(iovec_clone, iov_len), "Weird iovec::iov_len offset");
const auto result = ::writev(m_fd, reinterpret_cast<const iovec*>(buffers), buf_count);
ensure(result != -1); // "file::write_gather"
u64 result = 0;
while (buf_count)
{
iovec arg[256];
const auto count = std::min<u64>(buf_count, 256);
std::memcpy(&arg, buffers, sizeof(iovec) * count);
const auto added = ::writev(m_fd, arg, count);
ensure(added != -1); // "file::write_gather"
result += added;
buf_count -= count;
buffers += count;
}
return result;
}
@@ -1258,7 +1405,11 @@ fs::file::file(const void* ptr, usz size)
{
}
bool trunc(u64 length) override
memory_stream(const memory_stream&) = delete;
memory_stream& operator=(const memory_stream&) = delete;
bool trunc(u64) override
{
return false;
}
@@ -1279,7 +1430,7 @@ fs::file::file(const void* ptr, usz size)
return 0;
}
u64 write(const void* buffer, u64 count) override
u64 write(const void*, u64) override
{
return 0;
}
@@ -1346,7 +1497,7 @@ bool fs::dir::open(const std::string& path)
#ifdef _WIN32
WIN32_FIND_DATAW found;
const auto handle = FindFirstFileExW(to_wchar(path + "/*").get(), FindExInfoBasic, &found, FindExSearchNameMatch, NULL, FIND_FIRST_EX_CASE_SENSITIVE | FIND_FIRST_EX_LARGE_FETCH);
const auto handle = FindFirstFileExW(to_wchar(path + "/*").get(), FindExInfoBasic, &found, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_CASE_SENSITIVE | FIND_FIRST_EX_LARGE_FETCH);
if (handle == INVALID_HANDLE_VALUE)
{
@@ -1428,6 +1579,10 @@ bool fs::dir::open(const std::string& path)
{
}
unix_dir(const unix_dir&) = delete;
unix_dir& operator=(const unix_dir&) = delete;
~unix_dir() override
{
::closedir(m_dd);
@@ -1475,6 +1630,17 @@ bool fs::dir::open(const std::string& path)
return true;
}
bool fs::file::strict_read_check(u64 _size, u64 type_size) const
{
if (usz pos0 = pos(), size0 = size(); pos0 >= size0 || (size0 - pos0) / type_size < _size)
{
fs::g_tls_error = fs::error::inval;
return false;
}
return true;
}
const std::string& fs::get_config_dir()
{
// Use magic static
@@ -1486,9 +1652,9 @@ const std::string& fs::get_config_dir()
wchar_t buf[32768];
constexpr DWORD size = static_cast<DWORD>(std::size(buf));
if (GetEnvironmentVariable(L"RPCS3_CONFIG_DIR", buf, size) - 1 >= size - 1 &&
GetModuleFileName(NULL, buf, size) - 1 >= size - 1)
GetModuleFileName(nullptr, buf, size) - 1 >= size - 1)
{
MessageBoxA(0, fmt::format("GetModuleFileName() failed: error %u.", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR);
MessageBoxA(nullptr, fmt::format("GetModuleFileName() failed: error %u.", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR);
return dir; // empty
}
@@ -1603,110 +1769,6 @@ bool fs::remove_all(const std::string& path, bool remove_root)
return true;
}
std::string fs::escape_path(std::string_view path)
{
std::string real; real.resize(path.size());
auto get_char = [&](usz& from, usz& to, usz count)
{
std::memcpy(&real[to], &path[from], count);
from += count, to += count;
};
usz i = 0, j = -1, pos_nondelim = 0, after_delim = 0;
if (i < path.size())
{
j = 0;
}
for (; i < path.size();)
{
real[j] = path[i];
#ifdef _Win32
if (real[j] == '\\')
{
real[j] = '/';
}
#endif
// If the current character was preceeded by a delimiter special treatment is required:
// If another deleimiter is encountered, remove it (do not write it to output string)
// Otherwise test if it is a "." or ".." sequence.
if (std::exchange(after_delim, path[i] == delim[0] || path[i] == delim[1]))
{
if (!after_delim)
{
if (real[j] == '.')
{
if (i + 1 == path.size())
{
break;
}
get_char(i, j, 1);
switch (real[j])
{
case '.':
{
bool remove_element = true;
usz k = 1;
for (; k + i != path.size(); k++)
{
switch (path[i + k])
{
case '.': continue;
case delim[0]: case delim[1]: break;
default: remove_element = false; break;
}
}
if (remove_element)
{
if (i == 1u)
{
j = pos_nondelim;
real[j] = '\0';// Ensure termination at this posistion
after_delim = true;
i += k;
continue;
}
}
get_char(i, j, k);
continue;
}
case '/':
{
i++;
after_delim = true;
continue;
}
default: get_char(i, j, 1); continue;
}
}
pos_nondelim = j;
get_char(i, j, 1);
}
else
{
i++;
}
}
else
{
get_char(i, j, 1);
}
}
if (j != umax && (real[j] == delim[0] || real[j] == delim[1])) j--; // Do not include a delmiter at the end
real.resize(j + 1);
return real;
}
u64 fs::get_dir_size(const std::string& path, u64 rounding_alignment)
{
u64 result = 0;
@@ -1751,8 +1813,8 @@ fs::file fs::make_gather(std::vector<fs::file> files)
{
u64 pos = 0;
u64 end = 0;
std::vector<file> files;
std::map<u64, u64> ends; // Fragment End Offset -> Index
std::vector<file> files{};
std::map<u64, u64> ends{}; // Fragment End Offset -> Index
gather_stream(std::vector<fs::file> arg)
: files(std::move(arg))
@@ -1784,7 +1846,7 @@ fs::file fs::make_gather(std::vector<fs::file> files)
return result;
}
bool trunc(u64 length) override
bool trunc(u64) override
{
return false;
}
@@ -1827,7 +1889,7 @@ fs::file fs::make_gather(std::vector<fs::file> files)
return 0;
}
u64 write(const void* buffer, u64 size) override
u64 write(const void*, u64) override
{
return 0;
}
@@ -1860,6 +1922,55 @@ fs::file fs::make_gather(std::vector<fs::file> files)
return result;
}
fs::pending_file::pending_file(const std::string& path)
{
do
{
m_path = fmt::format(u8"%s/%s.%s.tmp", get_parent_dir(path), std::string_view(path).substr(path.find_last_of(fs::delim) + 1), fmt::base57(utils::get_unique_tsc()));
if (file.open(m_path, fs::create + fs::write + fs::read + fs::excl))
{
m_dest = path;
break;
}
m_path.clear();
}
while (fs::g_tls_error == fs::error::exist); // Only retry if failed due to existing file
}
fs::pending_file::~pending_file()
{
file.close();
if (!m_path.empty())
{
fs::remove_file(m_path);
}
}
bool fs::pending_file::commit(bool overwrite)
{
if (!file || m_path.empty())
{
fs::g_tls_error = fs::error::noent;
return false;
}
// The temporary file's contents must be on disk before rename
file.sync();
file.close();
if (fs::rename(m_path, m_dest, overwrite))
{
// Disable the destructor
m_path.clear();
return true;
}
return false;
}
template<>
void fmt_class_string<fs::seek_mode>::format(std::string& out, u64 arg)
{
+96 -27
View File
@@ -1,6 +1,7 @@
#pragma once // No BOM and only basic ASCII in this header, or a neko will die
#include "util/types.hpp"
#include "util/shared_ptr.hpp"
#include "bit_set.h"
#include <memory>
@@ -81,7 +82,7 @@ namespace fs
{
virtual ~file_base();
virtual stat_t stat();
[[noreturn]] virtual stat_t stat();
virtual void sync();
virtual bool trunc(u64 length) = 0;
virtual u64 read(void* buffer, u64 size) = 0;
@@ -95,7 +96,12 @@ namespace fs
// Directory entry (TODO)
struct dir_entry : stat_t
{
std::string name;
std::string name{};
dir_entry()
: stat_t{}
{
}
};
// Directory handle base
@@ -119,16 +125,19 @@ namespace fs
// Virtual device
struct device_base
{
const std::string fs_prefix;
device_base();
virtual ~device_base();
virtual bool stat(const std::string& path, stat_t& info) = 0;
virtual bool statfs(const std::string& path, device_stat& info) = 0;
virtual bool remove_dir(const std::string& path) = 0;
virtual bool create_dir(const std::string& path) = 0;
virtual bool rename(const std::string& from, const std::string& to) = 0;
virtual bool remove(const std::string& path) = 0;
virtual bool trunc(const std::string& path, u64 length) = 0;
virtual bool utime(const std::string& path, s64 atime, s64 mtime) = 0;
virtual bool remove_dir(const std::string& path);
virtual bool create_dir(const std::string& path);
virtual bool rename(const std::string& from, const std::string& to);
virtual bool remove(const std::string& path);
virtual bool trunc(const std::string& path, u64 length);
virtual bool utime(const std::string& path, s64 atime, s64 mtime);
virtual std::unique_ptr<file_base> open(const std::string& path, bs_t<open_mode> mode) = 0;
virtual std::unique_ptr<dir_base> open_dir(const std::string& path) = 0;
@@ -141,10 +150,10 @@ namespace fs
constexpr struct pod_tag_t{} pod_tag;
// Get virtual device for specified path (nullptr for real path)
std::shared_ptr<device_base> get_virtual_device(const std::string& path);
shared_ptr<device_base> get_virtual_device(const std::string& path);
// Set virtual device with specified name (nullptr for deletion)
std::shared_ptr<device_base> set_virtual_device(const std::string& root_name, const std::shared_ptr<device_base>&);
shared_ptr<device_base> set_virtual_device(const std::string& name, shared_ptr<device_base> device);
// Try to get parent directory (returns empty string on failure)
std::string get_parent_dir(const std::string& path);
@@ -188,9 +197,14 @@ namespace fs
// Set file access/modification time
bool utime(const std::string& path, s64 atime, s64 mtime);
// Synchronize filesystems (TODO)
void sync();
class file final
{
std::unique_ptr<file_base> m_file;
std::unique_ptr<file_base> m_file{};
bool strict_read_check(u64 size, u64 type_size) const;
public:
// Default constructor
@@ -369,15 +383,24 @@ namespace fs
}
// Read std::basic_string
template <typename T>
std::enable_if_t<std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>, bool> read(std::basic_string<T>& str, usz size,
template <bool IsStrict = false, typename T>
std::enable_if_t<std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>, bool> read(std::basic_string<T>& str, usz _size,
const char* file = __builtin_FILE(),
const char* func = __builtin_FUNCTION(),
u32 line = __builtin_LINE(),
u32 col = __builtin_COLUMN()) const
{
str.resize(size);
return read(&str[0], size * sizeof(T), line, col, file, func) == size * sizeof(T);
if (!m_file) xnull({line, col, file, func});
if (!_size) return true;
if constexpr (IsStrict)
{
// If _size arg is too high std::bad_alloc may happen in resize and then we cannot error check
if (!strict_read_check(_size, sizeof(T))) return false;
}
str.resize(_size);
return read(str.data(), sizeof(T) * _size, line, col, file, func) == sizeof(T) * _size;
}
// Read POD, sizeof(T) is used
@@ -404,15 +427,23 @@ namespace fs
}
// Read POD std::vector
template <typename T>
std::enable_if_t<std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>, bool> read(std::vector<T>& vec, usz size,
template <bool IsStrict = false, typename T>
std::enable_if_t<std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>, bool> read(std::vector<T>& vec, usz _size,
const char* file = __builtin_FILE(),
const char* func = __builtin_FUNCTION(),
u32 line = __builtin_LINE(),
u32 col = __builtin_COLUMN()) const
{
vec.resize(size);
return read(vec.data(), sizeof(T) * size, line, col, file, func) == sizeof(T) * size;
if (!m_file) xnull({line, col, file, func});
if (!_size) return true;
if constexpr (IsStrict)
{
if (!strict_read_check(_size, sizeof(T))) return false;
}
vec.resize(_size);
return read(vec.data(), sizeof(T) * _size, line, col, file, func) == sizeof(T) * _size;
}
// Read POD (experimental)
@@ -474,7 +505,7 @@ namespace fs
class dir final
{
std::unique_ptr<dir_base> m_dir;
std::unique_ptr<dir_base> m_dir{};
public:
dir() = default;
@@ -535,7 +566,7 @@ namespace fs
class iterator
{
const dir* m_parent;
dir_entry m_entry;
dir_entry m_entry{};
public:
enum class mode
@@ -563,6 +594,14 @@ namespace fs
}
}
iterator(const iterator&) = default;
iterator(iterator&&) = default;
iterator& operator=(const iterator&) = default;
iterator& operator=(iterator&&) = default;
dir_entry& operator *()
{
return m_entry;
@@ -597,8 +636,21 @@ namespace fs
// Get common cache directory
const std::string& get_cache_dir();
// Get real path for comparisons (TODO: investigate std::filesystem::path::compare implementation)
std::string escape_path(std::string_view path);
// Unique pending file creation destined to be renamed to the destination file
struct pending_file
{
fs::file file{};
// This is meant to modify files atomically, overwriting is likely
bool commit(bool overwrite = true);
pending_file(const std::string& path);
~pending_file();
private:
std::string m_path{}; // Pending file path
std::string m_dest{}; // Destination file path
};
// Delete directory and all its contents recursively
bool remove_all(const std::string& path, bool remove_root = true);
@@ -672,13 +724,16 @@ namespace fs
{
const u64 old_size = obj.size();
if (old_size + size < old_size)
if (old_size + size < old_size || pos + size < pos)
{
xovfl();
}
if (pos > old_size)
{
// Reserve memory
obj.reserve(pos + size);
// Fill gap if necessary (default-initialized)
obj.resize(pos);
}
@@ -727,14 +782,28 @@ namespace fs
return result;
}
template <typename... Args>
template <bool Flush = false, typename... Args>
bool write_file(const std::string& path, bs_t<fs::open_mode> mode, const Args&... args)
{
// Always use write flag, remove read flag
if (fs::file f{path, mode + fs::write - fs::read})
{
// Write args sequentially
(f.write(args), ...);
if constexpr (sizeof...(args) == 2u && (std::is_pointer_v<Args> || ...))
{
// Specialization for [const void*, usz] args
f.write(args...);
}
else
{
// Write args sequentially
(f.write(args), ...);
}
if constexpr (Flush)
{
f.sync();
}
return true;
}
+118 -29
View File
@@ -7,7 +7,7 @@
#include "mutex.h"
#include "util/vm.hpp"
#include "util/asm.hpp"
#include <immintrin.h>
#include <charconv>
#include <zlib.h>
#ifdef __linux__
@@ -22,8 +22,10 @@ static u8* get_jit_memory()
static void* const s_memory2 = []() -> void*
{
void* ptr = utils::memory_reserve(0x80000000);
#ifdef CAN_OVERCOMMIT
utils::memory_commit(ptr, 0x80000000);
utils::memory_protect(ptr, 0x40000000, utils::protection::wx);
#endif
return ptr;
}();
@@ -79,7 +81,7 @@ static u8* add_jit_memory(usz size, uint align)
if (pos == umax) [[unlikely]]
{
jit_log.error("JIT: Out of memory (size=0x%x, align=0x%x, off=0x%x)", size, align, Off);
jit_log.error("Out of memory (size=0x%x, align=0x%x, off=0x%x)", size, align, Off);
return nullptr;
}
@@ -140,7 +142,7 @@ asmjit::Error jit_runtime::_add(void** dst, asmjit::CodeHolder* code) noexcept
return asmjit::kErrorOk;
}
asmjit::Error jit_runtime::_release(void* ptr) noexcept
asmjit::Error jit_runtime::_release(void*) noexcept
{
return asmjit::kErrorOk;
}
@@ -215,6 +217,10 @@ asmjit::Runtime& asmjit::get_global_runtime()
utils::memory_commit(m_pos, size, utils::protection::wx);
}
custom_runtime(const custom_runtime&) = delete;
custom_runtime& operator=(const custom_runtime&) = delete;
asmjit::Error _add(void** dst, asmjit::CodeHolder* code) noexcept override
{
usz codeSize = code->getCodeSize();
@@ -228,6 +234,7 @@ asmjit::Runtime& asmjit::get_global_runtime()
if (!p || m_pos > m_max) [[unlikely]]
{
*dst = nullptr;
jit_log.fatal("Out of memory (static asmjit)");
return asmjit::kErrorNoVirtualMemory;
}
@@ -245,7 +252,7 @@ asmjit::Runtime& asmjit::get_global_runtime()
return asmjit::kErrorOk;
}
asmjit::Error _release(void* ptr) noexcept override
asmjit::Error _release(void*) noexcept override
{
return asmjit::kErrorOk;
}
@@ -264,10 +271,7 @@ asmjit::Runtime& asmjit::get_global_runtime()
#ifdef LLVM_AVAILABLE
#include <unordered_map>
#include <map>
#include <unordered_set>
#include <set>
#include <array>
#include <deque>
#ifdef _MSC_VER
@@ -277,6 +281,11 @@ asmjit::Runtime& asmjit::get_global_runtime()
#pragma GCC diagnostic ignored "-Wall"
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#pragma GCC diagnostic ignored "-Wredundant-decls"
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
#endif
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/FormattedStream.h"
@@ -290,12 +299,6 @@ asmjit::Runtime& asmjit::get_global_runtime()
#pragma GCC diagnostic pop
#endif
#ifdef _WIN32
#include <Windows.h>
#else
#include <sys/mman.h>
#endif
const bool jit_initialize = []() -> bool
{
llvm::InitializeNativeTarget();
@@ -305,6 +308,66 @@ const bool jit_initialize = []() -> bool
return true;
}();
[[noreturn]] static void null(const char* name)
{
fmt::throw_exception("Null function: %s", name);
}
namespace vm
{
extern u8* const g_sudo_addr;
}
static shared_mutex null_mtx;
static std::unordered_map<std::string, u64> null_funcs;
static u64 make_null_function(const std::string& name)
{
if (name.starts_with("__0x"))
{
u32 addr = -1;
auto res = std::from_chars(name.c_str() + 4, name.c_str() + name.size(), addr, 16);
if (res.ec == std::errc() && res.ptr == name.c_str() + name.size() && addr < 0x8000'0000)
{
// Point the garbage to reserved, non-executable memory
return reinterpret_cast<u64>(vm::g_sudo_addr + addr);
}
}
std::lock_guard lock(null_mtx);
if (u64& func_ptr = null_funcs[name]) [[likely]]
{
// Already exists
return func_ptr;
}
else
{
using namespace asmjit;
// Build a "null" function that contains its name
const auto func = build_function_asm<void (*)()>([&](X86Assembler& c, auto& args)
{
Label data = c.newLabel();
c.lea(args[0], x86::qword_ptr(data, 0));
c.jmp(imm_ptr(&null));
c.align(kAlignCode, 16);
c.bind(data);
// Copy function name bytes
for (char ch : name)
c.db(ch);
c.db(0);
c.align(kAlignData, 16);
});
func_ptr = reinterpret_cast<u64>(func);
return func_ptr;
}
}
// Simple memory manager
struct MemoryManager1 : llvm::RTDyldMemoryManager
{
@@ -322,23 +385,27 @@ struct MemoryManager1 : llvm::RTDyldMemoryManager
MemoryManager1() = default;
MemoryManager1(const MemoryManager1&) = delete;
MemoryManager1& operator=(const MemoryManager1&) = delete;
~MemoryManager1() override
{
utils::memory_release(ptr, c_max_size * 2);
}
[[noreturn]] static void null()
{
fmt::throw_exception("Null function");
}
llvm::JITSymbol findSymbol(const std::string& name) override
{
u64 addr = RTDyldMemoryManager::getSymbolAddress(name);
if (!addr)
{
addr = reinterpret_cast<uptr>(&null);
addr = make_null_function(name);
if (!addr)
{
fmt::throw_exception("Failed to link '%s'", name);
}
}
return {addr, llvm::JITSymbolFlags::Exported};
@@ -348,7 +415,7 @@ struct MemoryManager1 : llvm::RTDyldMemoryManager
{
if (align > c_page_size)
{
jit_log.fatal("JIT: Unsupported alignment (size=0x%x, align=0x%x)", size, align);
jit_log.fatal("Unsupported alignment (size=0x%x, align=0x%x)", size, align);
return nullptr;
}
@@ -357,7 +424,7 @@ struct MemoryManager1 : llvm::RTDyldMemoryManager
if ((newp - 1) / c_max_size != oldp / c_max_size)
{
jit_log.fatal("JIT: Out of memory (size=0x%x, align=0x%x)", size, align);
jit_log.fatal("Out of memory (size=0x%x, align=0x%x)", size, align);
return nullptr;
}
@@ -375,12 +442,12 @@ struct MemoryManager1 : llvm::RTDyldMemoryManager
return this->ptr + olda;
}
u8* allocateCodeSection(uptr size, uint align, uint sec_id, llvm::StringRef sec_name) override
u8* allocateCodeSection(uptr size, uint align, uint /*sec_id*/, llvm::StringRef /*sec_name*/) override
{
return allocate(code_ptr, size, align, utils::protection::wx);
}
u8* allocateDataSection(uptr size, uint align, uint sec_id, llvm::StringRef sec_name, bool is_ro) override
u8* allocateDataSection(uptr size, uint align, uint /*sec_id*/, llvm::StringRef /*sec_name*/, bool /*is_ro*/) override
{
return allocate(data_ptr, size, align, utils::protection::rw);
}
@@ -390,7 +457,7 @@ struct MemoryManager1 : llvm::RTDyldMemoryManager
return false;
}
void registerEHFrames(u8* addr, u64 load_addr, usz size) override
void registerEHFrames(u8*, u64, usz) override
{
}
@@ -408,12 +475,29 @@ struct MemoryManager2 : llvm::RTDyldMemoryManager
{
}
u8* allocateCodeSection(uptr size, uint align, uint sec_id, llvm::StringRef sec_name) override
llvm::JITSymbol findSymbol(const std::string& name) override
{
u64 addr = RTDyldMemoryManager::getSymbolAddress(name);
if (!addr)
{
addr = make_null_function(name);
if (!addr)
{
fmt::throw_exception("Failed to link '%s' (MM2)", name);
}
}
return {addr, llvm::JITSymbolFlags::Exported};
}
u8* allocateCodeSection(uptr size, uint align, uint /*sec_id*/, llvm::StringRef /*sec_name*/) override
{
return jit_runtime::alloc(size, align, true);
}
u8* allocateDataSection(uptr size, uint align, uint sec_id, llvm::StringRef sec_name, bool is_ro) override
u8* allocateDataSection(uptr size, uint align, uint /*sec_id*/, llvm::StringRef /*sec_name*/, bool /*is_ro*/) override
{
return jit_runtime::alloc(size, align, false);
}
@@ -423,7 +507,7 @@ struct MemoryManager2 : llvm::RTDyldMemoryManager
return false;
}
void registerEHFrames(u8* addr, u64 load_addr, usz size) override
void registerEHFrames(u8*, u64, usz) override
{
}
@@ -484,7 +568,12 @@ public:
}
}
fs::file(name, fs::rewrite).write(zbuf.get(), zsz - zs.avail_out);
if (!fs::write_file(name, fs::rewrite, zbuf.get(), zsz - zs.avail_out))
{
jit_log.error("LLVM: Failed to create module file: %s (%s)", name, fs::g_tls_error);
return;
}
jit_log.notice("LLVM: Created module: %s", _module->getName().data());
}
@@ -678,7 +767,7 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
for (auto&& [name, addr] : _link)
{
m_engine->addGlobalMapping(name, addr);
m_engine->updateGlobalMapping(name, addr);
}
}
+19 -4
View File
@@ -13,6 +13,14 @@
#pragma GCC diagnostic ignored "-Wall"
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#pragma GCC diagnostic ignored "-Wredundant-decls"
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#pragma GCC diagnostic ignored "-Weffc++"
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wduplicated-branches"
#endif
#include <asmjit/asmjit.h>
#pragma GCC diagnostic pop
#endif
@@ -168,7 +176,6 @@ inline FT build_function_asm(F&& builder)
#include <unordered_map>
#include "util/types.hpp"
#include "mutex.h"
#ifdef _MSC_VER
#pragma warning(push, 0)
@@ -177,6 +184,14 @@ inline FT build_function_asm(F&& builder)
#pragma GCC diagnostic ignored "-Wall"
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wsuggest-override"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
#ifdef __clang__
#pragma clang diagnostic ignored "-Winconsistent-missing-override"
#endif
#endif
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
@@ -191,13 +206,13 @@ inline FT build_function_asm(F&& builder)
class jit_compiler final
{
// Local LLVM context
llvm::LLVMContext m_context;
llvm::LLVMContext m_context{};
// Execution instance
std::unique_ptr<llvm::ExecutionEngine> m_engine;
std::unique_ptr<llvm::ExecutionEngine> m_engine{};
// Arch
std::string m_cpu;
std::string m_cpu{};
public:
jit_compiler(const std::unordered_map<std::string, u64>& _link, const std::string& _cpu, u32 flags = 0);
+5 -7
View File
@@ -29,24 +29,22 @@
#include <algorithm>
#include <cstring>
#include <stdlib.h>
#include <cstdlib>
// check if the scheme name is valid
static bool IsSchemeValid( const std::string& SchemeName )
{
for ( auto c : SchemeName )
return std::all_of(SchemeName.cbegin(), SchemeName.cend(), [](const auto& c)
{
if ( !isalpha( c ) && c != '+' && c != '-' && c != '.' ) return false;
}
return true;
return isalpha(c) || c == '+' || c == '-' || c == '.';
});
}
bool LUrlParser::clParseURL::GetPort( int* OutPort ) const
{
if ( !IsValid() ) { return false; }
int Port = atoi( m_Port.c_str() );
const int Port = atoi( m_Port.c_str() );
if ( Port <= 0 || Port > 65535 ) { return false; }
+13 -13
View File
@@ -1,21 +1,21 @@
/*
* Lightweight URL & URI parser (RFC 1738, RFC 3986)
* https://github.com/corporateshark/LUrlParser
*
*
* The MIT License (MIT)
*
*
* Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com)
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -47,14 +47,14 @@ namespace LUrlParser
{
public:
LUrlParserError m_ErrorCode;
std::string m_Scheme;
std::string m_Host;
std::string m_Port;
std::string m_Path;
std::string m_Query;
std::string m_Fragment;
std::string m_UserName;
std::string m_Password;
std::string m_Scheme{};
std::string m_Host{};
std::string m_Port{};
std::string m_Path{};
std::string m_Query{};
std::string m_Fragment{};
std::string m_UserName{};
std::string m_Password{};
clParseURL()
: m_ErrorCode( LUrlParserError_Uninitialized )
+62 -29
View File
@@ -254,6 +254,13 @@ void fmt_class_string<u128>::format(std::string& out, u64 arg)
{
// TODO: it should be supported as full-fledged integral type (with %u, %d, etc, fmt)
const u128& num = get_object(arg);
if (!num)
{
out += '0';
return;
}
#ifdef _MSC_VER
fmt::append(out, "0x%016llx%016llx", num.hi, num.lo);
#else
@@ -261,6 +268,12 @@ void fmt_class_string<u128>::format(std::string& out, u64 arg)
#endif
}
template <>
void fmt_class_string<s128>::format(std::string& out, u64 arg)
{
return fmt_class_string<u128>::format(out, arg);
}
template <>
void fmt_class_string<src_loc>::format(std::string& out, u64 arg)
{
@@ -344,7 +357,9 @@ struct fmt::cfmt_src
template <typename T>
T get(usz index) const
{
return *reinterpret_cast<const T*>(reinterpret_cast<const u8*>(args + index));
T res{};
std::memcpy(&res, reinterpret_cast<const u8*>(args + index), sizeof(res));
return res;
}
void skip(usz extra)
@@ -373,6 +388,8 @@ struct fmt::cfmt_src
TYPE(short);
if (std::is_signed<char>::value) TYPE(char);
TYPE(long);
TYPE(u128);
TYPE(s128);
#undef TYPE
@@ -394,56 +411,72 @@ void fmt::raw_append(std::string& out, const char* fmt, const fmt_type_info* sup
cfmt_append(out, fmt, cfmt_src{sup, args});
}
std::string fmt::replace_first(const std::string& src, const std::string& from, const std::string& to)
std::string fmt::replace_all(std::string_view src, std::string_view from, std::string_view to, usz count)
{
auto pos = src.find(from);
std::string target;
target.reserve(src.size() + to.size());
if (pos == umax)
for (usz i = 0, replaced = 0; i < src.size();)
{
return src;
}
const usz pos = src.find(from, i);
return (pos ? src.substr(0, pos) + to : to) + std::string(src.c_str() + pos + from.length());
}
if (pos == umax || replaced++ >= count)
{
// No match or too many encountered, append the rest of the string as is
target.append(src.substr(i));
break;
}
std::string fmt::replace_all(const std::string& src, const std::string& from, const std::string& to)
{
std::string target = src;
for (auto pos = target.find(from); pos != umax; pos = target.find(from, pos + 1))
{
target = (pos ? target.substr(0, pos) + to : to) + std::string(target.c_str() + pos + from.length());
pos += to.length();
// Append source until the matched string position
target.append(src.substr(i, pos - i));
// Replace string
target.append(to);
i = pos + from.size();
}
return target;
}
std::vector<std::string> fmt::split(const std::string& source, std::initializer_list<std::string> separators, bool is_skip_empty)
std::vector<std::string> fmt::split(std::string_view source, std::initializer_list<std::string_view> separators, bool is_skip_empty)
{
std::vector<std::string> result;
usz cursor_begin = 0;
for (usz cursor_end = 0; cursor_end < source.length(); ++cursor_end)
for (usz index = 0; index < source.size();)
{
usz pos = -1;
usz sep_size = 0;
for (auto& separator : separators)
{
if (strncmp(source.c_str() + cursor_end, separator.c_str(), separator.length()) == 0)
if (usz pos0 = source.find(separator, index); pos0 < pos)
{
std::string candidate = source.substr(cursor_begin, cursor_end - cursor_begin);
if (!is_skip_empty || !candidate.empty())
result.push_back(candidate);
cursor_begin = cursor_end + separator.length();
cursor_end = cursor_begin - 1;
break;
pos = pos0;
sep_size = separator.size();
}
}
if (!sep_size)
{
result.emplace_back(&source[index], source.size() - index);
return result;
}
std::string_view piece = {&source[index], pos - index};
index = pos + sep_size;
if (piece.empty() && is_skip_empty)
{
continue;
}
result.emplace_back(std::string(piece));
}
if (cursor_begin != source.length())
if (result.empty() && !is_skip_empty)
{
result.push_back(source.substr(cursor_begin));
result.emplace_back();
}
return result;
+11 -7
View File
@@ -119,7 +119,7 @@ struct fmt_class_string
using type = T;
// Helper function (converts arg to object reference)
static SAFE_BUFFERS FORCE_INLINE const T& get_object(u64 arg)
static FORCE_INLINE SAFE_BUFFERS(const T&) get_object(u64 arg)
{
return *reinterpret_cast<const T*>(static_cast<uptr>(arg));
}
@@ -128,7 +128,7 @@ struct fmt_class_string
using convert_t = const char*(*)(T value);
// Helper function (safely converts arg to enum value)
static SAFE_BUFFERS FORCE_INLINE void format_enum(std::string& out, u64 arg, convert_t convert)
static FORCE_INLINE SAFE_BUFFERS(void) format_enum(std::string& out, u64 arg, convert_t convert)
{
const auto value = static_cast<std::underlying_type_t<T>>(arg);
@@ -147,7 +147,7 @@ struct fmt_class_string
}
// Helper function (bitset formatting)
static SAFE_BUFFERS FORCE_INLINE void format_bitset(std::string& out, u64 arg, const char* prefix, const char* delim, const char* suffix, void (*fmt)(std::string&, u64))
static FORCE_INLINE SAFE_BUFFERS(void) format_bitset(std::string& out, u64 arg, const char* prefix, const char* delim, const char* suffix, void (*fmt)(std::string&, u64))
{
// Start from raw value
fmt_class_string<u64>::format(out, arg);
@@ -249,7 +249,7 @@ namespace fmt
};
template <typename... Args>
SAFE_BUFFERS FORCE_INLINE const fmt_type_info* get_type_info()
FORCE_INLINE SAFE_BUFFERS(const fmt_type_info*) get_type_info()
{
// Constantly initialized null-terminated list of type-specific information
static constexpr fmt_type_info result[sizeof...(Args) + 1]{fmt_type_info::make<fmt_unveil_t<Args>>()...};
@@ -265,7 +265,7 @@ namespace fmt
// Formatting function
template <typename CharT, usz N, typename... Args>
SAFE_BUFFERS FORCE_INLINE void append(std::string& out, const CharT(&fmt)[N], const Args&... args)
FORCE_INLINE SAFE_BUFFERS(void) append(std::string& out, const CharT(&fmt)[N], const Args&... args)
{
static constexpr fmt_type_info type_list[sizeof...(Args) + 1]{fmt_type_info::make<fmt_unveil_t<Args>>()...};
raw_append(out, reinterpret_cast<const char*>(fmt), type_list, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
@@ -273,7 +273,7 @@ namespace fmt
// Formatting function
template <typename CharT, usz N, typename... Args>
SAFE_BUFFERS FORCE_INLINE std::string format(const CharT(&fmt)[N], const Args&... args)
FORCE_INLINE SAFE_BUFFERS(std::string) format(const CharT(&fmt)[N], const Args&... args)
{
std::string result;
append(result, fmt, args...);
@@ -287,7 +287,7 @@ namespace fmt
template <typename CharT, usz N, typename... Args>
struct throw_exception
{
[[noreturn]] SAFE_BUFFERS FORCE_INLINE throw_exception(const CharT(&fmt)[N], const Args&... args,
[[noreturn]] FORCE_INLINE SAFE_BUFFERS() throw_exception(const CharT(&fmt)[N], const Args&... args,
u32 line = __builtin_LINE(),
u32 col = __builtin_COLUMN(),
const char* file = __builtin_FILE(),
@@ -296,6 +296,10 @@ namespace fmt
static constexpr fmt_type_info type_list[sizeof...(Args) + 1]{fmt_type_info::make<fmt_unveil_t<Args>>()...};
raw_throw_exception({line, col, file, func}, reinterpret_cast<const char*>(fmt), type_list, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
}
#ifndef _MSC_VER
[[noreturn]] ~throw_exception();
#endif
};
template <typename CharT, usz N, typename... Args>
+2 -4
View File
@@ -1,6 +1,5 @@
#pragma once
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
@@ -24,8 +23,7 @@ inline void strcpy_trunc(D& dst, const T& src)
namespace fmt
{
std::string replace_first(const std::string& src, const std::string& from, const std::string& to);
std::string replace_all(const std::string& src, const std::string& from, const std::string& to);
std::string replace_all(std::string_view src, std::string_view from, std::string_view to, usz count = -1);
template <usz list_size>
std::string replace_all(std::string src, const std::pair<std::string, std::string> (&list)[list_size])
@@ -75,7 +73,7 @@ namespace fmt
return src;
}
std::vector<std::string> split(const std::string& source, std::initializer_list<std::string> separators, bool is_skip_empty = true);
std::vector<std::string> split(std::string_view source, std::initializer_list<std::string_view> separators, bool is_skip_empty = true);
std::string trim(const std::string& source, const std::string& values = " \t");
template <typename T>
+403 -212
View File
@@ -2,14 +2,14 @@
#include "Emu/System.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/RawSPUThread.h"
#include "Emu/Cell/lv2/sys_mmapper.h"
#include "Emu/Cell/lv2/sys_event.h"
#include "Emu/RSX/RSXThread.h"
#include "Thread.h"
#include "Utilities/JIT.h"
#include <typeinfo>
#include <thread>
#include <sstream>
#include <cfenv>
#ifdef _WIN32
#include <Windows.h>
@@ -94,7 +94,7 @@ thread_local bool g_tls_access_violation_recovered = false;
extern thread_local std::string(*g_tls_log_prefix)();
// Report error and call std::abort(), defined in main.cpp
[[noreturn]] void report_fatal_error(const std::string&);
[[noreturn]] void report_fatal_error(std::string_view);
template <>
void fmt_class_string<std::thread::id>::format(std::string& out, u64 arg)
@@ -104,6 +104,28 @@ void fmt_class_string<std::thread::id>::format(std::string& out, u64 arg)
out += ss.str();
}
std::string dump_useful_thread_info()
{
thread_local volatile bool guard = false;
std::string result;
// In case the dumping function was the cause for the exception/access violation
// Avoid recursion
if (std::exchange(guard, true))
{
return result;
}
if (auto cpu = get_current_cpu_thread())
{
result = cpu->dump_all();
}
guard = false;
return result;
}
#ifndef _WIN32
bool IsDebuggerPresent()
{
@@ -428,7 +450,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, usz
}
case 0x7f:
{
if ((repe && !oso) || (!repe && oso)) // MOVDQU/MOVDQA xmm/m, xmm
if (repe != oso) // MOVDQU/MOVDQA xmm/m, xmm
{
out_op = X64OP_STORE;
out_reg = get_modRM_reg_xmm(code, rex);
@@ -542,7 +564,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, usz
}
case 0x80:
{
switch (auto mod_code = get_modRM_reg(code, 0))
switch (get_modRM_reg(code, 0))
{
//case 0: out_op = X64OP_ADD; break; // TODO: strange info in instruction manual
case 1: out_op = X64OP_OR; break;
@@ -561,7 +583,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, usz
}
case 0x81:
{
switch (auto mod_code = get_modRM_reg(code, 0))
switch (get_modRM_reg(code, 0))
{
case 0: out_op = X64OP_ADD; break;
case 1: out_op = X64OP_OR; break;
@@ -580,7 +602,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, usz
}
case 0x83:
{
switch (auto mod_code = get_modRM_reg(code, 0))
switch (get_modRM_reg(code, 0))
{
case 0: out_op = X64OP_ADD; break;
case 1: out_op = X64OP_OR; break;
@@ -721,7 +743,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, usz
const u8 vopm = op1 == 0xc5 ? 1 : op2 & 0x1f;
const u8 vop1 = op1 == 0xc5 ? op3 : code[2];
const u8 vlen = (opx & 0x4) ? 32 : 16;
const u8 vreg = (~opx >> 3) & 0xf;
//const u8 vreg = (~opx >> 3) & 0xf;
out_length += op1 == 0xc5 ? 2 : 3;
code += op1 == 0xc5 ? 2 : 3;
@@ -782,7 +804,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, usz
}
case 0xf6:
{
switch (auto mod_code = get_modRM_reg(code, 0))
switch (get_modRM_reg(code, 0))
{
case 0: out_op = X64OP_LOAD_TEST; break;
default: out_op = X64OP_NONE; break; // TODO...
@@ -795,7 +817,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, usz
}
case 0xf7:
{
switch (auto mod_code = get_modRM_reg(code, 0))
switch (get_modRM_reg(code, 0))
{
case 0: out_op = X64OP_LOAD_TEST; break;
default: out_op = X64OP_NONE; break; // TODO...
@@ -1176,7 +1198,7 @@ usz get_x64_access_size(x64_context* context, x64_op_t op, x64_reg_t reg, usz d_
if (reg != X64_NOT_SET) // get "full" access size from RCX register
{
u64 counter;
u64 counter = 1;
if (!get_x64_reg_value(context, reg, 8, i_size, counter))
{
return -1;
@@ -1239,7 +1261,9 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
{
if (op == X64OP_NONE)
{
sig_log.error("decode_x64_reg_op(%p): unsupported opcode: %s", code, *reinterpret_cast<const be_t<v128, 1>*>(code));
be_t<v128> dump;
std::memcpy(&dump, code, sizeof(dump));
sig_log.error("decode_x64_reg_op(%p): unsupported opcode: %s", code, dump);
}
};
@@ -1376,7 +1400,6 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
// Hack: allocate memory in case the emulator is stopping
const auto hack_alloc = [&]()
{
// If failed the value remains true and std::terminate should be called
g_tls_access_violation_recovered = true;
const auto area = vm::reserve_map(vm::any, addr & -0x10000, 0x10000);
@@ -1386,9 +1409,9 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
return false;
}
if (area->flags & 0x100 || (is_writing && vm::check_addr(addr)))
if (vm::reader_lock rlock; vm::check_addr(addr, 0))
{
// For 4kb pages or read only memory
// For allocated memory with protection lower than required (such as protection::no or read-only while writing to it)
utils::memory_protect(vm::base(addr & -0x1000), 0x1000, utils::protection::rw);
return true;
}
@@ -1397,18 +1420,18 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
return vm::check_addr(addr, is_writing ? vm::page_writable : vm::page_readable);
};
if (cpu)
if (cpu && (cpu->id_type() == 1 || cpu->id_type() == 2))
{
vm::temporary_unlock(*cpu);
u32 pf_port_id = 0;
if (auto pf_entries = g_fxo->get<page_fault_notification_entries>(); true)
if (auto& pf_entries = g_fxo->get<page_fault_notification_entries>(); true)
{
if (auto mem = vm::get(vm::any, addr))
{
reader_lock lock(pf_entries->mutex);
reader_lock lock(pf_entries.mutex);
for (const auto& entry : pf_entries->entries)
for (const auto& entry : pf_entries.entries)
{
if (entry.start_addr == mem->addr)
{
@@ -1424,7 +1447,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
// We notify the game that a page fault occurred so it can rectify it.
// Note, for data3, were the memory readable AND we got a page fault, it must be due to a write violation since reads are allowed.
u64 data1 = addr;
u64 data2;
u64 data2 = 0;
if (cpu->id_type() == 1)
{
@@ -1468,10 +1491,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
// Now, place the page fault event onto table so that other functions [sys_mmapper_free_address and pagefault recovery funcs etc]
// know that this thread is page faulted and where.
auto pf_events = g_fxo->get<page_fault_event_entries>();
auto& pf_events = g_fxo->get<page_fault_event_entries>();
{
std::lock_guard pf_lock(pf_events->pf_mutex);
pf_events->events.emplace(cpu, addr);
std::lock_guard pf_lock(pf_events.pf_mutex);
pf_events.events.emplace(cpu, addr);
}
sig_log.warning("Page_fault %s location 0x%x because of %s memory", is_writing ? "writing" : "reading",
@@ -1502,36 +1525,37 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
if (sending_error)
{
vm_log.fatal("Unknown error 0x%x while trying to pass page fault.", +sending_error);
vm_log.error("Unknown error 0x%x while trying to pass page fault.", +sending_error);
return false;
}
else
{
// Wait until the thread is recovered
while (!cpu->state.test_and_reset(cpu_flag::signal))
while (auto state = cpu->state.fetch_sub(cpu_flag::signal))
{
if (cpu->is_stopped())
if (is_stopped(state) || state & cpu_flag::signal)
{
break;
}
thread_ctrl::wait();
thread_ctrl::wait_on(cpu->state, state);
}
}
// Reschedule, test cpu state and try recovery if stopped
if (cpu->test_stopped() && !hack_alloc())
{
std::terminate();
return false;
}
return true;
}
if (cpu->id_type() != 1)
if (cpu->id_type() == 2)
{
if (!g_tls_access_violation_recovered)
{
vm_log.notice("\n%s", cpu->dump_all());
vm_log.notice("\n%s", dump_useful_thread_info());
vm_log.error("Access violation %s location 0x%x (%s) [type=u%u]", is_writing ? "writing" : "reading", addr, (is_writing && vm::check_addr(addr)) ? "read-only memory" : "unmapped memory", d_size * 8);
}
@@ -1542,7 +1566,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
if (cpu->check_state() && !hack_alloc())
{
std::terminate();
return false;
}
return true;
@@ -1560,9 +1584,9 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
Emu.Pause();
if (cpu && !g_tls_access_violation_recovered)
if (!g_tls_access_violation_recovered)
{
vm_log.notice("\n%s", cpu->dump_all());
vm_log.notice("\n%s", dump_useful_thread_info());
}
// Note: a thread may access violate more than once after hack_alloc recovery
@@ -1579,12 +1603,28 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
if (Emu.IsStopped() && !hack_alloc())
{
std::terminate();
return false;
}
return true;
}
static void append_thread_name(std::string& msg)
{
if (thread_ctrl::get_current())
{
fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
}
else if (thread_ctrl::is_main())
{
fmt::append(msg, "Thread: Main Thread.\n");
}
else
{
fmt::append(msg, "Thread id = %s.\n", std::this_thread::get_id());
}
}
#ifdef _WIN32
static LONG exception_handler(PEXCEPTION_POINTERS pExp) noexcept
@@ -1595,9 +1635,10 @@ static LONG exception_handler(PEXCEPTION_POINTERS pExp) noexcept
}
const auto ptr = reinterpret_cast<u8*>(pExp->ExceptionRecord->ExceptionInformation[1]);
const bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] != 0;
const bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] == 1;
const bool is_executing = pExp->ExceptionRecord->ExceptionInformation[0] == 8;
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && !is_executing)
{
u32 addr = 0;
@@ -1629,7 +1670,9 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
{
const auto cause = pExp->ExceptionRecord->ExceptionInformation[0] != 0 ? "writing" : "reading";
const auto cause =
pExp->ExceptionRecord->ExceptionInformation[0] == 8 ? "executing" :
pExp->ExceptionRecord->ExceptionInformation[0] == 1 ? "writing" : "reading";
fmt::append(msg, "Segfault %s location %p at %p.\n", cause, pExp->ExceptionRecord->ExceptionInformation[1], pExp->ExceptionRecord->ExceptionAddress);
}
@@ -1643,19 +1686,7 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
}
}
if (thread_ctrl::get_current())
{
fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
if (const auto cpu = get_current_cpu_thread())
{
sys_log.notice("\n%s", cpu->dump_all());
}
}
// TODO: Report full thread name if not an emu thread
fmt::append(msg, "Thread id = %s.\n", std::this_thread::get_id());
append_thread_name(msg);
std::vector<HMODULE> modules;
for (DWORD size = 256; modules.size() != size; size /= sizeof(HMODULE))
@@ -1712,14 +1743,7 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
// TODO: print registers and the callstack
sys_log.fatal("\n%s", msg);
if (!IsDebuggerPresent())
{
report_fatal_error(msg);
}
return EXCEPTION_CONTINUE_SEARCH;
thread_ctrl::emergency_exit(msg);
}
const bool s_exception_handler_set = []() -> bool
@@ -1739,26 +1763,29 @@ const bool s_exception_handler_set = []() -> bool
#else
static void signal_handler(int sig, siginfo_t* info, void* uct) noexcept
static void signal_handler(int /*sig*/, siginfo_t* info, void* uct) noexcept
{
x64_context* context = static_cast<ucontext_t*>(uct);
#ifdef __APPLE__
const bool is_writing = context->uc_mcontext->__es.__err & 0x2;
const u64 err = context->uc_mcontext->__es.__err;
#elif defined(__DragonFly__) || defined(__FreeBSD__)
const bool is_writing = context->uc_mcontext.mc_err & 0x2;
const u64 err = context->uc_mcontext.mc_err;
#elif defined(__OpenBSD__)
const bool is_writing = context->sc_err & 0x2;
const u64 err = context->sc_err;
#elif defined(__NetBSD__)
const bool is_writing = context->uc_mcontext.__gregs[_REG_ERR] & 0x2;
const u64 err = context->uc_mcontext.__gregs[_REG_ERR];
#else
const bool is_writing = context->uc_mcontext.gregs[REG_ERR] & 0x2;
const u64 err = context->uc_mcontext.gregs[REG_ERR];
#endif
const u64 exec64 = (reinterpret_cast<u64>(info->si_addr) - reinterpret_cast<u64>(vm::g_exec_addr)) / 2;
const auto cause = is_writing ? "writing" : "reading";
const bool is_executing = err & 0x10;
const bool is_writing = err & 0x2;
if (auto [addr, ok] = vm::try_get_addr(info->si_addr); ok)
const u64 exec64 = (reinterpret_cast<u64>(info->si_addr) - reinterpret_cast<u64>(vm::g_exec_addr)) / 2;
const auto cause = is_executing ? "executing" : is_writing ? "writing" : "reading";
if (auto [addr, ok] = vm::try_get_addr(info->si_addr); ok && !is_executing)
{
// Try to process access violation
if (thread_ctrl::get_current() && handle_access_violation(addr, is_writing, context))
@@ -1767,7 +1794,7 @@ static void signal_handler(int sig, siginfo_t* info, void* uct) noexcept
}
}
if (exec64 < 0x100000000ull)
if (exec64 < 0x100000000ull && !is_executing)
{
if (thread_ctrl::get_current() && handle_access_violation(static_cast<u32>(exec64), is_writing, context))
{
@@ -1775,33 +1802,22 @@ static void signal_handler(int sig, siginfo_t* info, void* uct) noexcept
}
}
if (const auto cpu = get_current_cpu_thread())
{
sys_log.notice("\n%s", cpu->dump_all());
}
std::string msg = fmt::format("Segfault %s location %p at %p.\n", cause, info->si_addr, RIP(context));
if (thread_ctrl::get_current())
{
fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
}
// TODO: Report full thread name if not an emu thread
fmt::append(msg, "Thread id = %s.\n", std::this_thread::get_id());
sys_log.fatal("\n%s", msg);
std::fprintf(stderr, "%s\n", msg.c_str());
append_thread_name(msg);
if (IsDebuggerPresent())
{
sys_log.fatal("\n%s", msg);
sys_log.notice("\n%s", dump_useful_thread_info());
// Convert to SIGTRAP
raise(SIGTRAP);
return;
}
report_fatal_error(msg);
thread_ctrl::emergency_exit(msg);
}
void sigpipe_signaling_handler(int)
@@ -2027,11 +2043,11 @@ u64 thread_base::finalize(thread_state result_state) noexcept
const u64 _self = m_thread;
// Set result state (errored or finalized)
const bool ok = 0 == (3 & ~m_sync.fetch_op([&](u64& v)
m_sync.fetch_op([&](u64& v)
{
v &= -4;
v |= static_cast<u32>(result_state);
}));
});
// Signal waiting threads
m_sync.notify_all(2);
@@ -2061,6 +2077,12 @@ thread_base::native_entry thread_base::finalize(u64 _self) noexcept
// Try to add self to thread pool
set_name("..pool");
thread_ctrl::set_native_priority(0);
thread_ctrl::set_thread_affinity_mask(0);
std::fesetround(FE_TONEAREST);
static constexpr u64 s_stop_bit = 0x8000'0000'0000'0000ull;
static atomic_t<u64> s_pool_ctr = []
@@ -2069,7 +2091,7 @@ thread_base::native_entry thread_base::finalize(u64 _self) noexcept
{
s_pool_ctr |= s_stop_bit;
while (u64 remains = s_pool_ctr & ~s_stop_bit)
while (/*u64 remains = */s_pool_ctr & ~s_stop_bit)
{
for (u32 i = 0; i < std::size(s_thread_pool); i++)
{
@@ -2190,6 +2212,24 @@ thread_base::native_entry thread_base::make_trampoline(u64(*entry)(thread_base*
});
}
thread_state thread_ctrl::state()
{
auto _this = g_tls_this_thread;
// Guard for recursive calls (TODO: may be more effective to reuse one of m_sync bits)
static thread_local bool s_tls_exec = false;
// Drain execution queue
if (!s_tls_exec)
{
s_tls_exec = true;
_this->exec();
s_tls_exec = false;
}
return static_cast<thread_state>(_this->m_sync & 3);
}
void thread_ctrl::_wait_for(u64 usec, bool alert /* true */)
{
auto _this = g_tls_this_thread;
@@ -2239,13 +2279,16 @@ void thread_ctrl::_wait_for(u64 usec, bool alert /* true */)
}
#endif
if (_this->m_sync.bit_test_reset(2))
if (_this->m_sync.bit_test_reset(2) || _this->m_taskq)
{
return;
}
// Wait for signal and thread state abort
_this->m_sync.wait(0, 4 + 1, atomic_wait_timeout{usec <= 0xffff'ffff'ffff'ffff / 1000 ? usec * 1000 : 0xffff'ffff'ffff'ffff});
atomic_wait::list<2> list{};
list.set<0>(_this->m_sync, 0, 4 + 1);
list.set<1>(_this->m_taskq, nullptr);
list.wait(atomic_wait_timeout{usec <= 0xffff'ffff'ffff'ffff / 1000 ? usec * 1000 : 0xffff'ffff'ffff'ffff});
}
std::string thread_ctrl::get_name_cached()
@@ -2281,6 +2324,9 @@ thread_base::thread_base(native_entry entry, std::string_view name)
thread_base::~thread_base()
{
// Cleanup abandoned tasks: initialize default results and signal
this->exec();
// Only cleanup on errored status
if ((m_sync & 3) == 2)
{
@@ -2305,7 +2351,6 @@ bool thread_base::join(bool dtor) const
// Hacked for too sleepy threads (1ms) TODO: make sure it's unneeded and remove
const auto timeout = dtor && Emu.IsStopped() ? atomic_wait_timeout{1'000'000} : atomic_wait_timeout::inf;
bool warn = false;
auto stamp0 = __rdtsc();
for (u64 i = 0; (m_sync & 3) <= 1; i++)
@@ -2317,20 +2362,12 @@ bool thread_base::join(bool dtor) const
break;
}
if (i > 20 && Emu.IsStopped())
if (i >= 16 && !(i & (i - 1)) && timeout != atomic_wait_timeout::inf)
{
stamp0 = __rdtsc();
atomic_wait_engine::raw_notify(0, get_native_id());
stamp0 = __rdtsc() - stamp0;
warn = true;
sig_log.error(u8"Thread [%s] is too sleepy. Waiting for it %.3fµs already!", *m_tname.load(), (__rdtsc() - stamp0) / (utils::get_tsc_freq() / 1000000.));
}
}
if (warn)
{
sig_log.error(u8"Thread [%s] is too sleepy. Took %.3fµs to wake it up!", *m_tname.load(), stamp0 / (utils::get_tsc_freq() / 1000000.));
}
return (m_sync & 3) == 3;
}
@@ -2389,16 +2426,92 @@ u64 thread_base::get_cycles()
}
}
void thread_base::push(shared_ptr<thread_future> task)
{
const auto next = &task->next;
m_taskq.push_head(*next, std::move(task));
m_taskq.notify_one();
}
void thread_base::exec()
{
if (!m_taskq) [[likely]]
{
return;
}
while (shared_ptr<thread_future> head = m_taskq.exchange(null_ptr))
{
// TODO: check if adapting reverse algorithm is feasible here
shared_ptr<thread_future>* prev{};
for (auto ptr = head.get(); ptr; ptr = ptr->next.get())
{
utils::prefetch_exec(ptr->exec.load());
ptr->prev = prev;
if (ptr->next)
{
prev = &ptr->next;
}
}
if (!prev)
{
prev = &head;
}
for (auto ptr = prev->get(); ptr; ptr = ptr->prev->get())
{
if (auto task = ptr->exec.load()) [[likely]]
{
// Execute or discard (if aborting)
if ((m_sync & 3) == 0) [[likely]]
{
task(this, ptr);
}
else
{
task(nullptr, ptr);
}
// Notify waiters
ptr->exec.release(nullptr);
ptr->exec.notify_all();
}
if (ptr->next)
{
// Partial cleanup
ptr->next.reset();
}
if (!ptr->prev)
{
break;
}
}
if (!m_taskq) [[likely]]
{
return;
}
}
}
[[noreturn]] void thread_ctrl::emergency_exit(std::string_view reason)
{
sig_log.fatal("Thread terminated due to fatal error: %s", reason);
if (std::string info = dump_useful_thread_info(); !info.empty())
{
sys_log.notice("\n%s", info);
}
std::fprintf(stderr, "Thread '%s' terminated due to fatal error: %s\n", g_tls_log_prefix().c_str(), std::string(reason).c_str());
sig_log.fatal("Thread terminated due to fatal error: %s", reason);
#ifdef _WIN32
if (IsDebuggerPresent())
{
OutputDebugStringA(fmt::format("Thread '%s' terminated due to fatal error: %s\n", g_tls_log_prefix(), reason).c_str());
__debugbreak();
}
#else
@@ -2429,8 +2542,7 @@ u64 thread_base::get_cycles()
#endif
}
// Assume main thread
report_fatal_error(std::string(reason));
report_fatal_error(reason);
}
void thread_ctrl::detect_cpu_layout()
@@ -2496,9 +2608,9 @@ u64 thread_ctrl::get_affinity_mask(thread_class group)
{
detect_cpu_layout();
if (const auto thread_count = std::thread::hardware_concurrency())
if (const auto thread_count = utils::get_thread_count())
{
const u64 all_cores_mask = thread_count < 64 ? UINT64_MAX >> (64 - thread_count): UINT64_MAX;
const u64 all_cores_mask = process_affinity_mask;
switch (g_native_core_layout)
{
@@ -2509,105 +2621,171 @@ u64 thread_ctrl::get_affinity_mask(thread_class group)
}
case native_core_arrangement::amd_ccx:
{
u64 spu_mask, ppu_mask, rsx_mask;
const auto system_id = utils::get_cpu_brand();
if (thread_count >= 32)
if (thread_count <= 8)
{
if (system_id.find("3950X") != umax)
// Single CCX or not enough threads, do nothing
return all_cores_mask;
}
u64 spu_mask, ppu_mask, rsx_mask;
spu_mask = ppu_mask = rsx_mask = all_cores_mask; // Fallback, in case someone is messing with core config
const auto system_id = utils::get_cpu_brand();
const auto family_id = utils::get_cpu_family();
const auto model_id = utils::get_cpu_model();
switch (family_id)
{
case 0x17: // Zen, Zen+, Zen2
case 0x18: // Dhyana core (Zen)
{
if (model_id > 0x30)
{
// zen2
// Ryzen 9 3950X
// Assign threads 9-32
ppu_mask = 0b11111111000000000000000000000000;
spu_mask = 0b00000000111111110000000000000000;
rsx_mask = 0b00000000000000001111111100000000;
}
else if (system_id.find("2970WX") != umax)
{
// zen+
// Threadripper 2970WX
// Assign threads 9-24
ppu_mask = 0b000000111111000000000000;
spu_mask = ppu_mask;
rsx_mask = 0b111111000000000000000000;
// Zen2 (models 49, 96, 113, 144)
// Much improved inter-CCX latency
switch (thread_count)
{
case 128:
case 64:
case 48:
case 32:
// TR 3000 series, or R9 3950X, Assign threads 9-32
ppu_mask = 0b11111111000000000000000000000000;
spu_mask = 0b00000000111111110000000000000000;
rsx_mask = 0b00000000000000001111111100000000;
break;
case 24:
// 3900X, Assign threads 7-24
ppu_mask = 0b111111000000000000000000;
spu_mask = 0b000000111111000000000000;
rsx_mask = 0b000000000000111111000000;
break;
case 16:
// 3700, 3800 family, Assign threads 1-16
ppu_mask = 0b0000000011110000;
spu_mask = 0b1111111100000000;
rsx_mask = 0b0000000000001111;
break;
case 12:
// 3600 family, Assign threads 1-12
ppu_mask = 0b000000111000;
spu_mask = 0b111111000000;
rsx_mask = 0b000000000111;
break;
default:
break;
}
}
else
{
// zen(+)
// Threadripper 1950X/2950X/2990WX
// Assign threads 17-32
ppu_mask = 0b00000000111111110000000000000000;
spu_mask = ppu_mask;
rsx_mask = 0b11111111000000000000000000000000;
// Zen, Zen+ (models 1, 8(+), 17, 24(+), 32)
switch (thread_count)
{
case 64:
// TR 2990WX, Assign threads 17-32
ppu_mask = 0b00000000111111110000000000000000;
spu_mask = ppu_mask;
rsx_mask = 0b11111111000000000000000000000000;
break;
case 48:
// TR 2970WX, Assign threads 9-24
ppu_mask = 0b000000111111000000000000;
spu_mask = ppu_mask;
rsx_mask = 0b111111000000000000000000;
break;
case 32:
// TR 2950X, TR 1950X, Assign threads 17-32
ppu_mask = 0b00000000111111110000000000000000;
spu_mask = ppu_mask;
rsx_mask = 0b11111111000000000000000000000000;
break;
case 24:
// TR 1920X, 2920X, Assign threads 13-24
ppu_mask = 0b000000111111000000000000;
spu_mask = ppu_mask;
rsx_mask = 0b111111000000000000000000;
break;
case 16:
// 1700, 1800, 2700, TR 1900X family
if (g_cfg.core.thread_scheduler == thread_scheduler_mode::alt)
{
ppu_mask = 0b0010000010000000;
spu_mask = 0b0000101010101010;
rsx_mask = 0b1000000000000000;
}
else
{
ppu_mask = 0b1111111100000000;
spu_mask = ppu_mask;
rsx_mask = 0b0000000000111100;
}
break;
case 12:
// 1600, 2600 family, Assign threads 3-12
ppu_mask = 0b111111000000;
spu_mask = ppu_mask;
rsx_mask = 0b000000111100;
break;
default:
break;
}
}
break;
}
else if (thread_count == 24)
case 0x19: // Zen3
{
if (system_id.find("3900X") != umax)
// Single-CCX architecture, just disable SMT if wide enough
// CCX now holds upto 16 threads
// Lack of hw availability makes testing difficult
switch (thread_count)
{
// zen2
// Ryzen 9 3900X
// Assign threads 7-22
case 24:
// 5900X, Use same scheduler as 3900X
// Unverified on windows, may be worse than just disabling SMT and scheduler
ppu_mask = 0b111111000000000000000000;
spu_mask = 0b000000111111000000000000;
rsx_mask = 0b000000000000111111000000;
break;
case 16:
// 5800X
if (g_cfg.core.thread_scheduler == thread_scheduler_mode::alt)
{
ppu_mask = 0b0000000011110000;
spu_mask = 0b1111111100000000;
rsx_mask = 0b0000000000001111;
}
else
{
// Verified by more than one windows user on 16-thread CPU
ppu_mask = spu_mask = rsx_mask = (0b10101010101010101010101010101010 & all_cores_mask);
}
break;
case 12:
// 5600X
if (g_cfg.core.thread_scheduler == thread_scheduler_mode::alt)
{
ppu_mask = 0b000000001100;
spu_mask = 0b111111110000;
rsx_mask = 0b000000000011;
}
else
{
ppu_mask = spu_mask = rsx_mask = all_cores_mask;
}
break;
default:
if (thread_count > 24)
{
ppu_mask = spu_mask = rsx_mask = (0b10101010101010101010101010101010 & all_cores_mask);
}
break;
}
else
{
// zen(+)
// Threadripper 1920X/2920X
// Assign threads 13-24
ppu_mask = 0b000000111111000000000000;
spu_mask = ppu_mask;
rsx_mask = 0b111111000000000000000000;
}
break;
}
else if (thread_count == 16)
default:
{
if (system_id.find("3700X") != umax || system_id.find("3800X") != umax)
{
// Ryzen 7 3700/3800 (x)
// Assign threads 1-16
ppu_mask = 0b0000000011110000;
spu_mask = 0b1111111100000000;
rsx_mask = 0b0000000000001111;
}
else
{
// zen(+)
// Ryzen 7, Threadripper
// Assign threads 3-16
ppu_mask = 0b1111111100000000;
spu_mask = ppu_mask;
rsx_mask = 0b0000000000111100;
}
break;
}
else if (thread_count == 12)
{
if (system_id.find("3600") != umax)
{
// zen2
// R5 3600 (x)
// Assign threads 1-12
ppu_mask = 0b000000111000;
spu_mask = 0b111111000000;
rsx_mask = 0b000000000111;
}
else
{
// zen(+)
// R5 1600/2600 (x)
// Assign threads 3-12
ppu_mask = 0b111111000000;
spu_mask = ppu_mask;
rsx_mask = 0b000000111100;
}
}
else
{
// R5 & R3 don't seem to improve performance no matter how these are shuffled
ppu_mask = spu_mask = rsx_mask = 0b11111111 & all_cores_mask;
}
switch (group)
@@ -2625,23 +2803,8 @@ u64 thread_ctrl::get_affinity_mask(thread_class group)
}
case native_core_arrangement::intel_ht:
{
/* This has been disabled as it seems to degrade performance instead of improving it.
if (thread_count <= 4)
{
//i3 or worse
switch (group)
{
case thread_class::rsx:
case thread_class::ppu:
return (0b0101 & all_cores_mask);
case thread_class::spu:
return (0b1010 & all_cores_mask);
case thread_class::general:
return all_cores_mask;
}
}
*/
if (thread_count >= 12 && g_cfg.core.thread_scheduler == thread_scheduler_mode::alt)
return (0b10101010101010101010101010101010 & all_cores_mask); // Potentially improves performance by mimicking HT off
return all_cores_mask;
}
}
@@ -2709,15 +2872,26 @@ DECLARE(thread_ctrl::process_affinity_mask) = get_process_affinity_mask();
void thread_ctrl::set_thread_affinity_mask(u64 mask)
{
sig_log.trace("set_thread_affinity_mask called with mask=0x%x", mask);
#ifdef _WIN32
HANDLE _this_thread = GetCurrentThread();
SetThreadAffinityMask(_this_thread, mask);
if (!SetThreadAffinityMask(_this_thread, !mask ? process_affinity_mask : mask))
{
sig_log.error("Failed to set thread affinity 0x%x: error 0x%x.", mask, GetLastError());
}
#elif __APPLE__
// Supports only one core
thread_affinity_policy_data_t policy = { static_cast<integer_t>(std::countr_zero(mask)) };
thread_port_t mach_thread = pthread_mach_thread_np(pthread_self());
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, reinterpret_cast<thread_policy_t>(&policy), 1);
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, reinterpret_cast<thread_policy_t>(&policy), !mask ? 0 : 1);
#elif defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__)
if (!mask)
{
// Reset affinity mask
mask = process_affinity_mask;
}
cpu_set_t cs;
CPU_ZERO(&cs);
@@ -2749,7 +2923,7 @@ void thread_ctrl::set_thread_affinity_mask(u64 mask)
u64 thread_ctrl::get_thread_affinity_mask()
{
#ifdef _WIN32
const u64 res = get_process_affinity_mask();
const u64 res = process_affinity_mask;
if (DWORD_PTR result = SetThreadAffinityMask(GetCurrentThread(), res))
{
@@ -2810,9 +2984,12 @@ std::pair<void*, usz> thread_ctrl::get_thread_stack()
void* saddr = 0;
usz ssize = 0;
pthread_attr_t attr;
#ifdef __linux__
#if defined(__linux__)
pthread_getattr_np(pthread_self(), &attr);
pthread_attr_getstack(&attr, &saddr, &ssize);
#elif defined(__APPLE__)
saddr = pthread_get_stackaddr_np(pthread_self());
ssize = pthread_get_stacksize_np(pthread_self());
#else
pthread_attr_get_np(pthread_self(), &attr);
pthread_attr_getstackaddr(&attr, &saddr);
@@ -2821,3 +2998,17 @@ std::pair<void*, usz> thread_ctrl::get_thread_stack()
#endif
return {saddr, ssize};
}
u64 thread_ctrl::get_tid()
{
#ifdef _WIN32
return GetCurrentThreadId();
#else
return reinterpret_cast<u64>(pthread_self());
#endif
}
bool thread_ctrl::is_main()
{
return get_tid() == utils::main_tid;
}
+278 -35
View File
@@ -5,8 +5,6 @@
#include "util/shared_ptr.hpp"
#include <string>
#include <memory>
#include <string_view>
#include "mutex.h"
#include "lockless.h"
@@ -42,10 +40,22 @@ class need_wakeup {};
template <class Context>
class named_thread;
template <typename T>
class thread_base;
template <typename Ctx, typename... Args>
struct result_storage
{
static_assert(std::is_default_constructible_v<T> && noexcept(T()));
static constexpr bool empty = true;
using type = void;
};
template <typename Ctx, typename... Args> requires (!std::is_void_v<std::invoke_result_t<Ctx, Args&&...>>)
struct result_storage<Ctx, Args...>
{
using T = std::invoke_result_t<Ctx, Args&&...>;
static_assert(std::is_default_constructible_v<T>);
alignas(T) std::byte data[sizeof(T)];
@@ -53,38 +63,58 @@ struct result_storage
using type = T;
T* get()
T* _get()
{
return reinterpret_cast<T*>(&data);
}
const T* get() const
const T* _get() const
{
return reinterpret_cast<const T*>(&data);
}
void init() noexcept
{
new (data) T();
}
void destroy() noexcept
{
get()->~T();
_get()->~T();
}
};
template <>
struct result_storage<void>
template <typename T>
concept NamedThreadName = requires (T& t)
{
static constexpr bool empty = true;
using type = void;
std::string_view(t.thread_name);
};
template <class Context, typename... Args>
using result_storage_t = result_storage<std::invoke_result_t<Context, Args...>>;
// Base class for task queue (linked list)
class thread_future
{
friend class thread_base;
template <typename T, typename = void>
struct thread_thread_name : std::bool_constant<false> {};
shared_ptr<thread_future> next{};
template <typename T>
struct thread_thread_name<T, std::void_t<decltype(named_thread<T>::thread_name)>> : std::bool_constant<true> {};
shared_ptr<thread_future>* prev{};
protected:
atomic_t<void(*)(thread_base*, thread_future*)> exec{};
public:
// Get reference to the atomic variable for inspection and waiting for
const auto& get_wait() const
{
return exec;
}
// Wait (preset)
void wait() const
{
exec.wait<atomic_wait::op_ne>(nullptr);
}
};
// Thread base class
class thread_base
@@ -109,6 +139,9 @@ private:
// Thread name
atomic_ptr<std::string> m_tname;
// Thread task queue (reversed linked list)
atomic_ptr<thread_future> m_taskq{};
// Start thread
void start();
@@ -149,6 +182,13 @@ public:
// Get thread id
u64 get_native_id() const;
// Add work to the queue
void push(shared_ptr<thread_future>);
private:
// Clear task queue (execute unless aborting)
void exec();
};
// Collection of global function for current thread
@@ -216,11 +256,8 @@ public:
return static_cast<thread_base&>(thread).get_native_id();
}
// Read current state
static inline thread_state state()
{
return static_cast<thread_state>(g_tls_this_thread->m_sync & 3);
}
// Read current state, possibly executing some tasks
static thread_state state();
// Wait once with timeout. May spuriously return false.
static inline void wait_for(u64 usec, bool alert = true)
@@ -234,6 +271,24 @@ public:
_wait_for(-1, true);
}
// Wait for both thread sync var and provided atomic var
template <atomic_wait::op Op = atomic_wait::op::eq, typename T, typename U>
static inline void wait_on(T& wait, U old, u64 usec = -1)
{
auto _this = g_tls_this_thread;
if (_this->m_sync.bit_test_reset(2) || _this->m_taskq)
{
return;
}
atomic_wait::list<3> list{};
list.set<0, Op>(wait, old);
list.set<1>(_this->m_sync, 0, 4 + 1);
list.set<2>(_this->m_taskq, nullptr);
list.wait(atomic_wait_timeout{usec <= 0xffff'ffff'ffff'ffff / 1000 ? usec * 1000 : 0xffff'ffff'ffff'ffff});
}
// Exit.
[[noreturn]] static void emergency_exit(std::string_view reason);
@@ -264,16 +319,118 @@ public:
// Get current thread stack addr and size
static std::pair<void*, usz> get_thread_stack();
// Sets the native thread priority and returns it to zero at destructor
struct scoped_priority
{
explicit scoped_priority(int prio)
{
set_native_priority(prio);
}
scoped_priority(const scoped_priority&) = delete;
scoped_priority& operator=(const scoped_priority&) = delete;
~scoped_priority()
{
set_native_priority(0);
}
};
// Get thread ID (works for all threads)
static u64 get_tid();
// Check whether current thread is main thread (usually Qt GUI)
static bool is_main();
private:
// Miscellaneous
static const u64 process_affinity_mask;
};
// Used internally
template <bool Discard, typename Ctx, typename... Args>
class thread_future_t : public thread_future, result_storage<Ctx, std::conditional_t<Discard, int, void>, Args...>
{
[[no_unique_address]] decltype(std::make_tuple(std::forward<Args>(std::declval<Args>())...)) m_args;
[[no_unique_address]] Ctx m_func;
using future = thread_future_t;
public:
thread_future_t(Ctx&& func, Args&&... args)
: m_args(std::forward<Args>(args)...)
, m_func(std::forward<Ctx>(func))
{
thread_future::exec.raw() = +[](thread_base* tb, thread_future* tf)
{
const auto _this = static_cast<future*>(tf);
if (!tb) [[unlikely]]
{
if constexpr (!future::empty && !Discard)
{
_this->init();
}
return;
}
if constexpr (future::empty || Discard)
{
std::apply(_this->m_func, std::move(_this->m_args));
}
else
{
new (_this->_get()) decltype(auto)(std::apply(_this->m_func, std::move(_this->m_args)));
}
};
}
~thread_future_t()
{
if constexpr (!future::empty && !Discard)
{
if (!this->exec)
{
this->destroy();
}
}
}
decltype(auto) get()
{
while (this->exec)
{
this->wait();
}
if constexpr (!future::empty && !Discard)
{
return *this->_get();
}
}
decltype(auto) get() const
{
while (this->exec)
{
this->wait();
}
if constexpr (!future::empty && !Discard)
{
return *this->_get();
}
}
};
// Derived from the callable object Context, possibly a lambda
template <class Context>
class named_thread final : public Context, result_storage_t<Context>, thread_base
class named_thread final : public Context, result_storage<Context>, thread_base
{
using result = result_storage_t<Context>;
using result = result_storage<Context>;
using thread = thread_base;
static u64 entry_point(thread_base* _base)
@@ -288,19 +445,30 @@ class named_thread final : public Context, result_storage_t<Context>, thread_bas
if constexpr (!result::empty)
{
// Construct using default constructor in the case of failure
new (static_cast<result*>(static_cast<named_thread*>(thread_ctrl::get_current()))->get()) typename result::type();
static_cast<result*>(static_cast<named_thread*>(thread_ctrl::get_current()))->init();
}
});
if constexpr (result::empty)
{
// No result
Context::operator()();
if constexpr (std::is_invocable_v<Context>)
{
Context::operator()();
}
else
{
// Default event loop
while (thread_ctrl::state() != thread_state::aborting)
{
thread_ctrl::wait();
}
}
}
else
{
// Construct the result using placement new (copy elision should happen)
new (result::get()) typename result::type(Context::operator()());
new (result::_get()) decltype(auto)(Context::operator()());
}
return thread::finalize(thread_state::finished);
@@ -311,17 +479,17 @@ class named_thread final : public Context, result_storage_t<Context>, thread_bas
friend class thread_ctrl;
public:
// Default constructor
template <bool Valid = std::is_default_constructible_v<Context> && thread_thread_name<Context>(), typename = std::enable_if_t<Valid>>
named_thread()
: Context()
// Forwarding constructor with default name (also potentially the default constructor)
template <typename... Args> requires (std::is_constructible_v<Context, Args&&...>) && (NamedThreadName<Context>)
named_thread(Args&&... args)
: Context(std::forward<Args>(args)...)
, thread(trampoline, Context::thread_name)
{
thread::start();
}
// Normal forwarding constructor
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<Context, Args&&...>>>
template <typename... Args> requires (std::is_constructible_v<Context, Args&&...>) && (!NamedThreadName<Context>)
named_thread(std::string_view name, Args&&... args)
: Context(std::forward<Args>(args)...)
, thread(trampoline, name)
@@ -348,7 +516,7 @@ public:
if constexpr (!result::empty)
{
return *result::get();
return *result::_get();
}
}
@@ -359,7 +527,82 @@ public:
if constexpr (!result::empty)
{
return *result::get();
return *result::_get();
}
}
// Send command to the thread to invoke directly (references should be passed via std::ref())
template <bool Discard = true, typename Arg, typename... Args>
auto operator()(Arg&& arg, Args&&... args)
{
// Overloaded operator() of the Context.
constexpr bool v1 = std::is_invocable_v<Context, Arg&&, Args&&...>;
// Anything invocable, not necessarily involving the Context.
constexpr bool v2 = std::is_invocable_v<Arg&&, Args&&...>;
// Could be pointer to a non-static member function (or data member) of the Context.
constexpr bool v3 = std::is_member_pointer_v<std::decay_t<Arg>> && std::is_invocable_v<Arg, Context&, Args&&...>;
// Only one invocation type shall be valid, otherwise we don't know.
static_assert((v1 + v2 + v3) == 1, "Ambiguous or invalid named_thread call.");
if constexpr (v1)
{
using future = thread_future_t<Discard, Context&, Arg, Args...>;
single_ptr<future> target = make_single<future>(*static_cast<Context*>(this), std::forward<Arg>(arg), std::forward<Args>(args)...);
if constexpr (!Discard)
{
shared_ptr<future> result = std::move(target);
// Copy result
thread::push(result);
return result;
}
else
{
// Move target
thread::push(std::move(target));
return;
}
}
else if constexpr (v2)
{
using future = thread_future_t<Discard, Arg, Args...>;
single_ptr<future> target = make_single<future>(std::forward<Arg>(arg), std::forward<Args>(args)...);
if constexpr (!Discard)
{
shared_ptr<future> result = std::move(target);
thread::push(result);
return result;
}
else
{
thread::push(std::move(target));
return;
}
}
else if constexpr (v3)
{
using future = thread_future_t<Discard, Arg, Context&, Args...>;
single_ptr<future> target = make_single<future>(std::forward<Arg>(arg), std::ref(*static_cast<Context*>(this)), std::forward<Args>(args)...);
if constexpr (!Discard)
{
shared_ptr<future> result = std::move(target);
thread::push(result);
return result;
}
else
{
thread::push(std::move(target));
return;
}
}
}
+6 -6
View File
@@ -30,31 +30,31 @@ public:
double GetElapsedTimeInSec() const
{
return double(GetElapsedTimeInMicroSec()) / 1000000.0;
return static_cast<double>(GetElapsedTimeInMicroSec()) / 1000000.0;
}
double GetElapsedTimeInMilliSec() const
{
return double(GetElapsedTimeInMicroSec()) / 1000.0;
return static_cast<double>(GetElapsedTimeInMicroSec()) / 1000.0;
}
u64 GetElapsedTimeInMicroSec() const
{
steady_clock::time_point now = m_stopped ? m_end : steady_clock::now();
const steady_clock::time_point now = m_stopped ? m_end : steady_clock::now();
return std::chrono::duration_cast<std::chrono::microseconds>(now - m_start).count();
}
u64 GetElapsedTimeInNanoSec() const
{
steady_clock::time_point now = m_stopped ? m_end : steady_clock::now();
const steady_clock::time_point now = m_stopped ? m_end : steady_clock::now();
return std::chrono::duration_cast<std::chrono::nanoseconds>(now - m_start).count();
}
u64 GetMsSince(steady_clock::time_point timestamp)
u64 GetMsSince(steady_clock::time_point timestamp) const
{
steady_clock::time_point now = m_stopped ? m_end : steady_clock::now();
const steady_clock::time_point now = m_stopped ? m_end : steady_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(now - timestamp).count();
}
+16 -49
View File
@@ -3,6 +3,7 @@
#include "util/types.hpp"
#include "StrFmt.h"
#include <vector>
#include <algorithm>
namespace utils
@@ -65,7 +66,6 @@ namespace utils
public:
// Constructors
constexpr address_range() = default;
constexpr address_range(const address_range &other) : start(other.start), end(other.end) {}
static constexpr address_range start_length(u32 _start, u32 _length)
{
@@ -239,16 +239,11 @@ namespace utils
}
// Comparison Operators
bool operator ==(const address_range &other) const
bool operator ==(const address_range& other) const
{
return (start == other.start && end == other.end);
}
bool operator !=(const address_range &other) const
{
return (start != other.start || end != other.end);
}
/**
* Debug
*/
@@ -272,10 +267,10 @@ namespace utils
class address_range_vector
{
public:
using vector_type = typename std::vector<address_range>;
using iterator = typename vector_type::iterator;
using const_iterator = typename vector_type::const_iterator;
using size_type = typename vector_type::size_type;
using vector_type = std::vector<address_range>;
using iterator = vector_type::iterator;
using const_iterator = vector_type::const_iterator;
using size_type = vector_type::size_type;
private:
vector_type data;
@@ -456,7 +451,7 @@ namespace utils
// Will fail if ranges within the vector overlap our touch each-other
bool check_consistency() const
{
usz _size = data.size();
const usz _size = data.size();
for (usz i = 0; i < _size; ++i)
{
@@ -486,20 +481,10 @@ namespace utils
// Test for overlap with a given range
bool overlaps(const address_range &range) const
{
for (const address_range &current : data)
return std::any_of(data.cbegin(), data.cend(), [&range](const address_range& cur)
{
if (!current.valid())
{
continue;
}
if (current.overlaps(range))
{
return true;
}
}
return false;
return cur.valid() && cur.overlaps(range);
});
}
// Test for overlap with a given address_range vector
@@ -531,37 +516,19 @@ namespace utils
// Test if a given range is fully contained inside this vector
bool contains(const address_range &range) const
{
for (const address_range &cur : *this)
return std::any_of(this->begin(), this->end(), [&range](const address_range& cur)
{
if (!cur.valid())
{
continue;
}
if (range.inside(cur))
{
return true;
}
}
return false;
return cur.valid() && cur.inside(range);
});
}
// Test if all ranges in this vector are full contained inside a specific range
bool inside(const address_range &range) const
{
for (const address_range &cur : *this)
return std::all_of(this->begin(), this->end(), [&range](const address_range& cur)
{
if (!cur.valid())
{
continue;
}
if (!cur.inside(range))
{
return false;
}
}
return true;
return !cur.valid() || cur.inside(range);
});
}
};
+80 -161
View File
@@ -9,11 +9,6 @@
LOG_CHANNEL(patch_log, "PAT");
namespace config_key
{
static const std::string enable_legacy_patches = "Enable Legacy Patches";
}
template <>
void fmt_class_string<YAML::NodeType::value>::format(std::string& out, u64 arg)
{
@@ -49,9 +44,12 @@ void fmt_class_string<patch_type>::format(std::string& out, u64 arg)
case patch_type::bef64: return "bef64";
case patch_type::be16: return "be16";
case patch_type::be32: return "be32";
case patch_type::bd32: return "bd32";
case patch_type::be64: return "be64";
case patch_type::bd64: return "bd64";
case patch_type::lef32: return "lef32";
case patch_type::lef64: return "lef64";
case patch_type::utf8: return "utf8";
}
return unknown;
@@ -128,16 +126,14 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st
}
// Load patch config to determine which patches are enabled
bool enable_legacy_patches = false;
patch_map patch_config;
if (!importing)
{
patch_config = load_config(enable_legacy_patches);
patch_config = load_config();
}
std::string version;
bool is_legacy_patch = false;
if (const auto version_node = root[patch_key::version])
{
@@ -153,17 +149,12 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st
// We don't need the Version node in local memory anymore
root.remove(patch_key::version);
}
else if (importing)
else
{
append_log_message(log_messages, fmt::format("Error: No '%s' entry found. Patch engine version = %s (file: %s)", patch_key::version, patch_engine_version, path));
patch_log.error("No '%s' entry found. Patch engine version = %s (file: %s)", patch_key::version, patch_engine_version, path);
return false;
}
else
{
patch_log.warning("Patch engine version %s: Reading legacy patch file %s", patch_engine_version, path);
is_legacy_patch = true;
}
bool is_valid = true;
@@ -172,30 +163,6 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st
{
const auto& main_key = pair.first.Scalar();
// Use old logic and yaml layout if this is a legacy patch
if (is_legacy_patch)
{
struct patch_info info{};
info.hash = main_key;
info.is_enabled = enable_legacy_patches;
info.is_legacy = true;
info.source_path = path;
if (!read_patch_node(info, pair.second, root, log_messages))
{
is_valid = false;
}
// Find or create an entry matching the key/hash in our map
auto& container = patches_map[main_key];
container.hash = main_key;
container.is_legacy = true;
container.patch_info_map["legacy"] = info;
continue;
}
// Use new logic and yaml layout
if (const auto yml_type = pair.second.Type(); yml_type != YAML::NodeType::Map)
{
append_log_message(log_messages, fmt::format("Error: Skipping key %s: expected Map, found %s", main_key, yml_type));
@@ -212,7 +179,6 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st
// Find or create an entry matching the key/hash in our map
auto& container = patches_map[main_key];
container.is_legacy = false;
container.hash = main_key;
container.version = version;
@@ -431,35 +397,6 @@ bool patch_engine::add_patch_data(YAML::Node node, patch_info& info, u32 modifie
{
// Special syntax: anchors (named sequence)
// Most legacy patches don't use the anchor syntax correctly, so try to sanitize it.
if (info.is_legacy)
{
if (const auto yml_type = addr_node.Type(); yml_type == YAML::NodeType::Scalar)
{
if (!root)
{
patch_log.fatal("Trying to parse legacy patch with invalid root."); // Sanity Check
return false;
}
const auto anchor = addr_node.Scalar();
const auto anchor_node = root[anchor];
if (anchor_node)
{
addr_node = anchor_node;
append_log_message(log_messages, fmt::format("Incorrect anchor syntax found in legacy patch: %s (key: %s)", anchor, info.hash));
patch_log.warning("Incorrect anchor syntax found in legacy patch: %s (key: %s)", anchor, info.hash);
}
else
{
append_log_message(log_messages, fmt::format("Anchor not found in legacy patch: %s (key: %s)", anchor, info.hash));
patch_log.error("Anchor not found in legacy patch: %s (key: %s)", anchor, info.hash);
return false;
}
}
}
// Check if the anchor was resolved.
if (const auto yml_type = addr_node.Type(); yml_type != YAML::NodeType::Sequence)
{
@@ -493,6 +430,10 @@ bool patch_engine::add_patch_data(YAML::Node node, patch_info& info, u32 modifie
switch (p_data.type)
{
case patch_type::utf8:
{
break;
}
case patch_type::bef32:
case patch_type::lef32:
case patch_type::bef64:
@@ -553,10 +494,7 @@ bool patch_engine::read_patch_node(patch_info& info, YAML::Node node, const YAML
void patch_engine::append_global_patches()
{
// Legacy patch.yml
load(m_map, fs::get_config_dir() + "patch.yml");
// New patch.yml
// Regular patch.yml
load(m_map, get_patches_path() + "patch.yml");
// Imported patch.yml
@@ -570,45 +508,30 @@ void patch_engine::append_title_patches(const std::string& title_id)
return;
}
// Legacy patch.yml
load(m_map, fs::get_config_dir() + "data/" + title_id + "/patch.yml");
// New patch.yml
// Regular patch.yml
load(m_map, get_patches_path() + title_id + "_patch.yml");
}
usz patch_engine::apply(const std::string& name, u8* dst)
static std::basic_string<u32> apply_modification(const patch_engine::patch_info& patch, u8* dst, u32 filesz, u32 min_addr)
{
return apply_patch<false>(name, dst, 0, 0);
}
usz patch_engine::apply_with_ls_check(const std::string& name, u8* dst, u32 filesz, u32 ls_addr)
{
return apply_patch<true>(name, dst, filesz, ls_addr);
}
template <bool check_local_storage>
static usz apply_modification(const patch_engine::patch_info& patch, u8* dst, u32 filesz, u32 ls_addr)
{
usz applied = 0;
std::basic_string<u32> applied;
for (const auto& p : patch.data_list)
{
u32 offset = p.offset;
if constexpr (check_local_storage)
if (offset < min_addr || offset - min_addr >= filesz)
{
if (offset < ls_addr || offset >= (ls_addr + filesz))
{
// This patch is out of range for this segment
continue;
}
offset -= ls_addr;
// This patch is out of range for this segment
continue;
}
offset -= min_addr;
auto ptr = dst + offset;
u32 resval = umax;
switch (p.type)
{
case patch_type::invalid:
@@ -624,77 +547,113 @@ static usz apply_modification(const patch_engine::patch_info& patch, u8* dst, u3
}
case patch_type::le16:
{
*reinterpret_cast<le_t<u16, 1>*>(ptr) = static_cast<u16>(p.value.long_value);
le_t<u16> val = static_cast<u16>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::le32:
{
*reinterpret_cast<le_t<u32, 1>*>(ptr) = static_cast<u32>(p.value.long_value);
le_t<u32> val = static_cast<u32>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::lef32:
{
*reinterpret_cast<le_t<u32, 1>*>(ptr) = std::bit_cast<u32, f32>(static_cast<f32>(p.value.double_value));
le_t<f32> val = static_cast<f32>(p.value.double_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::le64:
{
*reinterpret_cast<le_t<u64, 1>*>(ptr) = static_cast<u64>(p.value.long_value);
le_t<u64> val = static_cast<u64>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::lef64:
{
*reinterpret_cast<le_t<u64, 1>*>(ptr) = std::bit_cast<u64, f64>(p.value.double_value);
le_t<f64> val = p.value.double_value;
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::be16:
{
*reinterpret_cast<be_t<u16, 1>*>(ptr) = static_cast<u16>(p.value.long_value);
be_t<u16> val = static_cast<u16>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::bd32:
{
be_t<u32> val = static_cast<u32>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::be32:
{
*reinterpret_cast<be_t<u32, 1>*>(ptr) = static_cast<u32>(p.value.long_value);
be_t<u32> val = static_cast<u32>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
if (offset % 4 == 0)
resval = offset;
break;
}
case patch_type::bef32:
{
*reinterpret_cast<be_t<u32, 1>*>(ptr) = std::bit_cast<u32, f32>(static_cast<f32>(p.value.double_value));
be_t<f32> val = static_cast<f32>(p.value.double_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::bd64:
{
be_t<u64> val = static_cast<u64>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::be64:
{
*reinterpret_cast<be_t<u64, 1>*>(ptr) = static_cast<u64>(p.value.long_value);
be_t<u64> val = static_cast<u64>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
if (offset % 4)
{
break;
}
resval = offset;
applied.push_back((offset + 7) & -4); // Two 32-bit locations
break;
}
case patch_type::bef64:
{
*reinterpret_cast<be_t<u64, 1>*>(ptr) = std::bit_cast<u64, f64>(p.value.double_value);
be_t<f64> val = p.value.double_value;
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::utf8:
{
std::memcpy(ptr, p.original_value.data(), p.original_value.size());
break;
}
}
++applied;
// Possibly an executable instruction
applied.push_back(resval);
}
return applied;
}
template <bool check_local_storage>
usz patch_engine::apply_patch(const std::string& name, u8* dst, u32 filesz, u32 ls_addr)
std::basic_string<u32> patch_engine::apply(const std::string& name, u8* dst, u32 filesz, u32 min_addr)
{
if (m_map.find(name) == m_map.cend())
{
return 0;
return {};
}
usz applied_total = 0;
std::basic_string<u32> applied_total;
const auto& container = m_map.at(name);
const auto serial = Emu.GetTitleID();
const auto app_version = Emu.GetAppVersion();
const auto& serial = Emu.GetTitleID();
const auto& app_version = Emu.GetAppVersion();
// Different containers in order to seperate the patches
std::vector<patch_engine::patch_info> legacy_patches;
std::vector<patch_engine::patch_info> patches_for_this_serial_and_this_version;
std::vector<patch_engine::patch_info> patches_for_this_serial_and_all_versions;
std::vector<patch_engine::patch_info> patches_for_all_serials_and_this_version;
@@ -703,17 +662,6 @@ usz patch_engine::apply_patch(const std::string& name, u8* dst, u32 filesz, u32
// Sort patches into different vectors based on their serial and version
for (const auto& [description, patch] : container.patch_info_map)
{
// Find out if this legacy patch is enabled
if (patch.is_legacy)
{
if (patch.is_enabled)
{
legacy_patches.push_back(patch);
}
continue;
}
// Find out if this patch is enabled
for (const auto& [title, serials] : patch.titles)
{
@@ -780,7 +728,6 @@ usz patch_engine::apply_patch(const std::string& name, u8* dst, u32 filesz, u32
// Sort specific patches in front of global patches
std::vector<patch_engine::patch_info> sorted_patches;
sorted_patches.insert(sorted_patches.end(), legacy_patches.begin(), legacy_patches.end());
sorted_patches.insert(sorted_patches.end(), patches_for_this_serial_and_this_version.begin(), patches_for_this_serial_and_this_version.end());
sorted_patches.insert(sorted_patches.end(), patches_for_this_serial_and_all_versions.begin(), patches_for_this_serial_and_all_versions.end());
sorted_patches.insert(sorted_patches.end(), patches_for_all_serials_and_this_version.begin(), patches_for_all_serials_and_this_version.end());
@@ -799,23 +746,17 @@ usz patch_engine::apply_patch(const std::string& name, u8* dst, u32 filesz, u32
m_applied_groups.insert(patch.patch_group);
}
const usz applied = apply_modification<check_local_storage>(patch, dst, filesz, ls_addr);
auto applied = apply_modification(patch, dst, filesz, min_addr);
applied_total += applied;
if (patch.is_legacy)
{
patch_log.success("Applied legacy patch (hash='%s')(<- %d)", patch.hash, applied);
}
else
{
patch_log.success("Applied patch (hash='%s', description='%s', author='%s', patch_version='%s', file_version='%s') (<- %d)", patch.hash, patch.description, patch.author, patch.patch_version, patch.version, applied);
}
patch_log.success("Applied patch (hash='%s', description='%s', author='%s', patch_version='%s', file_version='%s') (<- %u)", patch.hash, patch.description, patch.author, patch.patch_version, patch.version, applied.size());
}
return applied_total;
}
void patch_engine::save_config(const patch_map& patches_map, bool enable_legacy_patches)
void patch_engine::save_config(const patch_map& patches_map)
{
const std::string path = get_patch_config_path();
patch_log.notice("Saving patch config file %s", path);
@@ -830,26 +771,13 @@ void patch_engine::save_config(const patch_map& patches_map, bool enable_legacy_
YAML::Emitter out;
out << YAML::BeginMap;
// Save "Enable Legacy Patches"
out << config_key::enable_legacy_patches << enable_legacy_patches;
// Save 'enabled' state per hash, description, serial and app_version
patch_map config_map;
for (const auto& [hash, container] : patches_map)
{
if (container.is_legacy)
{
continue;
}
for (const auto& [description, patch] : container.patch_info_map)
{
if (patch.is_legacy)
{
continue;
}
for (const auto& [title, serials] : patch.titles)
{
for (const auto& [serial, app_versions] : serials)
@@ -865,7 +793,7 @@ void patch_engine::save_config(const patch_map& patches_map, bool enable_legacy_
}
}
if (const auto& enabled_patches = config_map[hash].patch_info_map; enabled_patches.size() > 0)
if (const auto& enabled_patches = config_map[hash].patch_info_map; !enabled_patches.empty())
{
out << hash << YAML::BeginMap;
@@ -1092,10 +1020,8 @@ bool patch_engine::remove_patch(const patch_info& info)
return false;
}
patch_engine::patch_map patch_engine::load_config(bool& enable_legacy_patches)
patch_engine::patch_map patch_engine::load_config()
{
enable_legacy_patches = true; // Default to true
patch_map config_map;
const std::string path = get_patch_config_path();
@@ -1111,13 +1037,6 @@ patch_engine::patch_map patch_engine::load_config(bool& enable_legacy_patches)
return config_map;
}
// Try to load "Enable Legacy Patches" (default to true)
if (auto enable_legacy_node = root[config_key::enable_legacy_patches])
{
enable_legacy_patches = enable_legacy_node.as<bool>(true);
root.remove(config_key::enable_legacy_patches); // Remove the node in order to skip it in the next part
}
for (const auto pair : root)
{
const auto& hash = pair.first.Scalar();
+28 -31
View File
@@ -20,7 +20,7 @@ namespace patch_key
static const std::string version = "Version";
}
static const std::string patch_engine_version = "1.2";
inline static const std::string patch_engine_version = "1.2";
enum class patch_type
{
@@ -34,9 +34,12 @@ enum class patch_type
lef64,
be16,
be32,
bd32, // be32 with data hint (non-code)
be64,
bd64, // be64 with data hint (non-code)
bef32,
bef64,
utf8, // Text of string (not null-terminated automatically)
};
class patch_engine
@@ -46,12 +49,12 @@ public:
{
patch_type type = patch_type::load;
u32 offset = 0;
std::string original_value; // Used for import consistency (avoid rounding etc.)
std::string original_value{}; // Used for import consistency (avoid rounding etc.)
union
{
u64 long_value;
f64 double_value;
} value { 0 };
} value{0};
};
using patch_app_versions = std::unordered_map<std::string /*app_version*/, bool /*enabled*/>;
@@ -61,34 +64,35 @@ public:
struct patch_info
{
// Patch information
std::vector<patch_data> data_list;
patch_titles titles;
std::string description;
std::string patch_version;
std::string patch_group;
std::string author;
std::string notes;
std::string source_path;
std::vector<patch_data> data_list{};
patch_titles titles{};
std::string description{};
std::string patch_version{};
std::string patch_group{};
std::string author{};
std::string notes{};
std::string source_path{};
// Redundant information for accessibility (see patch_container)
std::string hash;
std::string version;
bool is_legacy = false;
bool is_enabled = false; // only for legacy patches
std::string hash{};
std::string version{};
};
struct patch_container
{
std::unordered_map<std::string /*description*/, patch_info> patch_info_map;
std::string hash;
std::string version;
bool is_legacy = false;
std::unordered_map<std::string /*description*/, patch_info> patch_info_map{};
std::string hash{};
std::string version{};
};
using patch_map = std::unordered_map<std::string /*hash*/, patch_container>;
patch_engine();
patch_engine(const patch_engine&) = delete;
patch_engine& operator=(const patch_engine&) = delete;
// Returns the directory in which patch_config.yml is located
static std::string get_patch_config_path();
@@ -111,7 +115,7 @@ public:
static bool add_patch_data(YAML::Node node, patch_info& info, u32 modifier, const YAML::Node& root, std::stringstream* log_messages = nullptr);
// Save to patch_config.yml
static void save_config(const patch_map& patches_map, bool enable_legacy_patches);
static void save_config(const patch_map& patches_map);
// Save a patch file
static bool save_patches(const patch_map& patches, const std::string& path, std::stringstream* log_messages = nullptr);
@@ -123,7 +127,7 @@ public:
static bool remove_patch(const patch_info& info);
// Load patch_config.yml
static patch_map load_config(bool& enable_legacy_patches);
static patch_map load_config();
// Load from file and append to member patches map
void append_global_patches();
@@ -132,19 +136,12 @@ public:
void append_title_patches(const std::string& title_id);
// Apply patch (returns the number of entries applied)
usz apply(const std::string& name, u8* dst);
// Apply patch with a check that the address exists in SPU local storage
usz apply_with_ls_check(const std::string& name, u8* dst, u32 filesz, u32 ls_addr);
std::basic_string<u32> apply(const std::string& name, u8* dst, u32 filesz = UINT32_MAX, u32 min_addr = 0);
private:
// Internal: Apply patch (returns the number of entries applied)
template <bool check_local_storage>
usz apply_patch(const std::string& name, u8* dst, u32 filesz, u32 ls_addr);
// Database
patch_map m_map;
patch_map m_map{};
// Only one patch per patch group can be applied
std::set<std::string> m_applied_groups;
std::set<std::string> m_applied_groups{};
};
+56 -94
View File
@@ -26,10 +26,16 @@ Intersection (&) and symmetric difference (^) is also available.
#include "Utilities/StrFmt.h"
template <typename T>
concept BitSetEnum = std::is_enum_v<T> && requires(T x)
{
T::__bitset_enum_max;
};
template <BitSetEnum T>
class atomic_bs_t;
// Bitset type for enum class with available bits [0, T::__bitset_enum_max)
template <typename T>
template <BitSetEnum T>
class bs_t final
{
public:
@@ -112,24 +118,24 @@ public:
return *this;
}
constexpr bs_t operator +(bs_t rhs) const
friend constexpr bs_t operator +(bs_t lhs, bs_t rhs)
{
return bs_t(0, m_data | rhs.m_data);
return bs_t(0, lhs.m_data | rhs.m_data);
}
constexpr bs_t operator -(bs_t rhs) const
friend constexpr bs_t operator -(bs_t lhs, bs_t rhs)
{
return bs_t(0, m_data & ~rhs.m_data);
return bs_t(0, lhs.m_data & ~rhs.m_data);
}
constexpr bs_t operator &(bs_t rhs) const
friend constexpr bs_t operator &(bs_t lhs, bs_t rhs)
{
return bs_t(0, m_data & rhs.m_data);
return bs_t(0, lhs.m_data & rhs.m_data);
}
constexpr bs_t operator ^(bs_t rhs) const
friend constexpr bs_t operator ^(bs_t lhs, bs_t rhs)
{
return bs_t(0, m_data ^ rhs.m_data);
return bs_t(0, lhs.m_data ^ rhs.m_data);
}
constexpr bool operator ==(bs_t rhs) const
@@ -137,16 +143,6 @@ public:
return m_data == rhs.m_data;
}
constexpr bool operator !=(bs_t rhs) const
{
return m_data != rhs.m_data;
}
constexpr bool test(bs_t rhs) const
{
return (m_data & rhs.m_data) != 0;
}
constexpr bool test_and_set(T bit)
{
bool r = (m_data & shift(bit)) != 0;
@@ -170,42 +166,70 @@ public:
};
// Unary '+' operator: promote plain enum value to bitset value
template <typename T, typename = decltype(T::__bitset_enum_max)>
template <BitSetEnum T>
constexpr bs_t<T> operator +(T bit)
{
return bit;
return bs_t<T>(bit);
}
// Binary '+' operator: bitset union
template <typename T, typename = decltype(T::__bitset_enum_max)>
constexpr bs_t<T> operator +(T lhs, T rhs)
template <BitSetEnum T, typename U> requires (std::is_constructible_v<bs_t<T>, U>)
constexpr bs_t<T> operator +(T lhs, const U& rhs)
{
return bs_t<T>(lhs) + bs_t<T>(rhs);
}
// Binary '+' operator: bitset union
template <typename U, BitSetEnum T> requires (std::is_constructible_v<bs_t<T>, U> && !std::is_enum_v<U>)
constexpr bs_t<T> operator +(const U& lhs, T rhs)
{
return bs_t<T>(lhs) + bs_t<T>(rhs);
}
// Binary '-' operator: bitset difference
template <typename T, typename = decltype(T::__bitset_enum_max)>
constexpr bs_t<T> operator -(T lhs, T rhs)
template <BitSetEnum T, typename U> requires (std::is_constructible_v<bs_t<T>, U>)
constexpr bs_t<T> operator -(T lhs, const U& rhs)
{
return bs_t<T>(lhs) - bs_t<T>(rhs);
}
// Binary '-' operator: bitset difference
template <typename U, BitSetEnum T> requires (std::is_constructible_v<bs_t<T>, U> && !std::is_enum_v<U>)
constexpr bs_t<T> operator -(const U& lhs, T rhs)
{
return bs_t<T>(lhs) - bs_t<T>(rhs);
}
// Binary '&' operator: bitset intersection
template <typename T, typename = decltype(T::__bitset_enum_max)>
constexpr bs_t<T> operator &(T lhs, T rhs)
template <BitSetEnum T, typename U> requires (std::is_constructible_v<bs_t<T>, U>)
constexpr bs_t<T> operator &(T lhs, const U& rhs)
{
return bs_t<T>(lhs) & bs_t<T>(rhs);
}
// Binary '&' operator: bitset intersection
template <typename U, BitSetEnum T> requires (std::is_constructible_v<bs_t<T>, U> && !std::is_enum_v<U>)
constexpr bs_t<T> operator &(const U& lhs, T rhs)
{
return bs_t<T>(lhs) & bs_t<T>(rhs);
}
// Binary '^' operator: bitset symmetric difference
template <typename T, typename = decltype(T::__bitset_enum_max)>
constexpr bs_t<T> operator ^(T lhs, T rhs)
template <BitSetEnum T, typename U> requires (std::is_constructible_v<bs_t<T>, U>)
constexpr bs_t<T> operator ^(T lhs, const U& rhs)
{
return bs_t<T>(lhs) ^ bs_t<T>(rhs);
}
// Binary '^' operator: bitset symmetric difference
template <typename U, BitSetEnum T> requires (std::is_constructible_v<bs_t<T>, U> && !std::is_enum_v<U>)
constexpr bs_t<T> operator ^(const U& lhs, T rhs)
{
return bs_t<T>(lhs) ^ bs_t<T>(rhs);
}
// Atomic bitset specialization with optimized operations
template <typename T>
template <BitSetEnum T>
class atomic_bs_t : public atomic_t<::bs_t<T>>
{
// Corresponding bitset type
@@ -237,6 +261,8 @@ public:
{
}
using base::operator bs_t;
explicit operator bool() const
{
return static_cast<bool>(base::load());
@@ -315,70 +341,6 @@ public:
auto fetch_or(const bs_t&) = delete;
auto or_fetch(const bs_t&) = delete;
auto operator |=(const bs_t&) = delete;
auto operator ++() = delete;
auto operator --() = delete;
auto operator ++(int) = delete;
auto operator --(int) = delete;
bs_t operator +(bs_t rhs) const
{
return bs_t(0, base::load().m_data | rhs.m_data);
}
bs_t operator -(bs_t rhs) const
{
return bs_t(0, base::load().m_data & ~rhs.m_data);
}
bs_t operator &(bs_t rhs) const
{
return bs_t(0, base::load().m_data & rhs.m_data);
}
bs_t operator ^(bs_t rhs) const
{
return bs_t(0, base::load().m_data ^ rhs.m_data);
}
bs_t operator ==(bs_t rhs) const
{
return base::load().m_data == rhs.m_data;
}
bs_t operator !=(bs_t rhs) const
{
return base::load().m_data != rhs.m_data;
}
friend bs_t operator +(bs_t lhs, const atomic_bs_t& rhs)
{
return bs_t(0, lhs.m_data | rhs.load().m_data);
}
friend bs_t operator -(bs_t lhs, const atomic_bs_t& rhs)
{
return bs_t(0, lhs.m_data & ~rhs.load().m_data);
}
friend bs_t operator &(bs_t lhs, const atomic_bs_t& rhs)
{
return bs_t(0, lhs.m_data & rhs.load().m_data);
}
friend bs_t operator ^(bs_t lhs, const atomic_bs_t& rhs)
{
return bs_t(0, lhs.m_data ^ rhs.load().m_data);
}
friend bs_t operator ==(bs_t lhs, const atomic_bs_t& rhs)
{
return lhs.m_data == rhs.load().m_data;
}
friend bs_t operator !=(bs_t lhs, const atomic_bs_t& rhs)
{
return lhs.m_data != rhs.load().m_data;
}
bool test_and_set(T rhs)
{
+88 -26
View File
@@ -5,8 +5,7 @@
#include <string>
#include <vector>
#include <algorithm>
static const usz size_dropped = -1;
#include "util/asm.hpp"
/*
C-style format parser. Appends formatted string to `out`, returns number of characters written.
@@ -42,7 +41,7 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
const auto drop_sequence = [&]
{
out.insert(out.end(), fmt - ctx.size, fmt);
ctx.size = size_dropped;
ctx.size = umax;
};
const auto read_decimal = [&](uint result) -> uint
@@ -56,36 +55,65 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
return result;
};
const auto write_octal = [&](u64 value, u64 min_num)
const auto write_octal = [&](auto value, u64 min_num)
{
out.resize(out.size() + std::max<u64>(min_num, 66 / 3 - (std::countl_zero<u64>(value | 1) + 2) / 3), '0');
if constexpr (sizeof(value) == 16)
{
out.resize(out.size() + std::max<u64>(min_num, 129 / 3 - (utils::clz128(value | 1) + 1) / 3), '0');
}
else
{
out.resize(out.size() + std::max<u64>(min_num, 66 / 3 - (std::countl_zero<u64>(value | 1) + 2) / 3), '0');
}
// Write in reversed order
for (auto i = out.rbegin(); value; i++, value /= 8)
for (auto i = out.rbegin(); value; i++, value >>= 3)
{
*i = value % 8 + '0';
*i = static_cast<char>(static_cast<u64>(value) & 7) + '0';
}
};
const auto write_hex = [&](u64 value, bool upper, u64 min_num)
const auto write_hex = [&](auto value, bool upper, u64 min_num)
{
out.resize(out.size() + std::max<u64>(min_num, 64 / 4 - std::countl_zero<u64>(value | 1) / 4), '0');
if constexpr (sizeof(value) == 16)
{
out.resize(out.size() + std::max<u64>(min_num, 128 / 4 - utils::clz128(value | 1) / 4), '0');
}
else
{
out.resize(out.size() + std::max<u64>(min_num, 64 / 4 - std::countl_zero<u64>(value | 1) / 4), '0');
}
// Write in reversed order
for (auto i = out.rbegin(); value; i++, value /= 16)
for (auto i = out.rbegin(); value; i++, value >>= 4)
{
*i = (upper ? "0123456789ABCDEF" : "0123456789abcdef")[value % 16];
*i = (upper ? "0123456789ABCDEF" : "0123456789abcdef")[static_cast<usz>(value & 0xf)];
}
};
const auto write_decimal = [&](u64 value, s64 min_size)
const auto write_decimal = [&](auto value, s64 min_size)
{
const usz start = out.size();
do
{
out.push_back(value % 10 + '0');
value /= 10;
if constexpr (sizeof(value) == 16)
{
const u128 v0 = value;
value >>= 1;
constexpr u128 by_five = 0x3333'3333'3333'3333;
const u128 v1 = (value >> 64) * by_five;
const u128 v2 = ((value >> 64) * by_five) >> 64;
const u128 v3 = (static_cast<u64>(value) * by_five) >> 64;
value = v1 + v2 + v3;
out.push_back(static_cast<char>(static_cast<u64>(v0 - (value * 10))) + '0');
}
else
{
out.push_back(value % 10 + '0');
value /= 10;
}
}
while (0 < --min_size || value);
@@ -113,7 +141,7 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
ctx = {0};
out.push_back(ch);
}
else if (ctx.size == size_dropped)
else if (ctx.size == umax)
{
out.push_back(ch);
}
@@ -369,7 +397,16 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
out.push_back(' ');
}
write_decimal(negative ? 0 - val : val, ctx.prec);
if (ctx.type == 16)
{
// TODO: support negative values (s128)
u128 val2 = *reinterpret_cast<u128*>(val);
write_decimal(val2, ctx.prec);
}
else
{
write_decimal(negative ? 0 - val : val, ctx.prec);
}
}
const usz size2 = out.size() - start;
@@ -425,14 +462,23 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
{
out.push_back('0');
if (val)
if (ctx.prec)
{
write_octal(val, ctx.prec ? ctx.prec - 1 : 0);
ctx.prec--;
}
}
else if (!ctx.dot || ctx.prec)
if ((ctx.alter && val) || !ctx.dot || ctx.prec)
{
write_octal(val, ctx.prec);
if (ctx.type == 16)
{
u128 val2 = *reinterpret_cast<u128*>(val);
write_octal(val2, ctx.prec);
}
else
{
write_octal(val, ctx.prec);
}
}
const usz size2 = out.size() - start;
@@ -485,12 +531,20 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
if (val)
{
out.push_back(ch); // Prepend 0x or 0X
write_hex(val, ch == 'X', ctx.prec);
}
}
else if (!ctx.dot || ctx.prec)
if ((ctx.alter && val) || !ctx.dot || ctx.prec)
{
write_hex(val, ch == 'X', ctx.prec);
if (ctx.type == 16)
{
u128 val2 = *reinterpret_cast<u128*>(val);
write_hex(val2, ch == 'X', ctx.prec);
}
else
{
write_hex(val, ch == 'X', ctx.prec);
}
}
const usz size2 = out.size() - start;
@@ -544,7 +598,15 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
if (!ctx.dot || ctx.prec)
{
write_decimal(val, ctx.prec);
if (ctx.type == 16)
{
u128 val2 = *reinterpret_cast<u128*>(val);
write_decimal(val2, ctx.prec);
}
else
{
write_decimal(val, ctx.prec);
}
}
const usz size2 = out.size() - start;
@@ -610,7 +672,7 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
const u64 arg1 = ctx.args >= 1 ? src.template get<u64>(1) : 0;
const u64 arg2 = ctx.args >= 2 ? src.template get<u64>(2) : 0;
if (const usz _size = std::snprintf(0, 0, _fmt.c_str(), arg0, arg1, arg2))
if (const usz _size = std::snprintf(nullptr, 0, _fmt.c_str(), arg0, arg1, arg2))
{
out.resize(out.size() + _size);
std::snprintf(&out.front() + out.size() - _size, _size + 1, _fmt.c_str(), arg0, arg1, arg2);
@@ -630,7 +692,7 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
}
// Handle unfinished sequence
if (ctx.size && ctx.size != size_dropped)
if (ctx.size && ctx.size != umax)
{
fmt--, drop_sequence();
}
+3 -3
View File
@@ -21,11 +21,11 @@ constexpr u8 cheat_type_max = static_cast<u8>(cheat_type::max);
struct cheat_info
{
std::string game;
std::string description;
std::string game{};
std::string description{};
cheat_type type = cheat_type::max;
u32 offset{};
std::string red_script;
std::string red_script{};
bool from_str(const std::string& cheat_line);
std::string to_str() const;
-3
View File
@@ -1,8 +1,5 @@
#include "cond.h"
#include "sync.h"
#include "lockless.h"
#include <climits>
// use constants, increase signal space
+16 -2
View File
@@ -17,10 +17,24 @@ namespace date_time
return buf;
}
static inline std::string fmt_time(const char* fmt, const s64 time)
{
tm buf;
time_t t = time;
#ifdef _MSC_VER
localtime_s(&buf, &t);
#else
buf = *localtime(&t);
#endif
char str[80];
strftime(str, sizeof(str), fmt, &buf);
return str;
}
static inline std::string current_time()
{
char str[80];
tm now = get_time(0);
tm now = get_time(nullptr);
strftime(str, sizeof(str), "%c", &now);
return str;
}
@@ -29,7 +43,7 @@ namespace date_time
static inline std::string current_time_narrow()
{
char str[80];
tm now = get_time(0);
tm now = get_time(nullptr);
std::string parse_buf;
+4 -110
View File
@@ -102,14 +102,6 @@ struct size2_base
return width == rhs.width && height == rhs.height;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator !=(const size2_base& rhs) const
{
return width != rhs.width || height != rhs.height;
}
#endif
template<typename NT>
explicit constexpr operator size2_base<NT>() const
{
@@ -211,19 +203,6 @@ struct position1_base
return x == rhs;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
bool operator !=(const position1_base& rhs) const
{
return !(*this == rhs);
}
bool operator !=(T rhs) const
{
return !(*this == rhs);
}
#endif
template<typename NT>
explicit operator position1_base<NT>() const
{
@@ -383,19 +362,6 @@ struct position2_base
return x == rhs && y == rhs;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator !=(const position2_base& rhs) const
{
return !(*this == rhs);
}
constexpr bool operator !=(T rhs) const
{
return !(*this == rhs);
}
#endif
template<typename NT>
explicit constexpr operator position2_base<NT>() const
{
@@ -478,19 +444,6 @@ struct position3_base
return x == rhs && y == rhs && z == rhs;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
bool operator !=(const position3_base& rhs) const
{
return !(*this == rhs);
}
bool operator !=(T rhs) const
{
return !(*this == rhs);
}
#endif
template<typename NT>
explicit operator position3_base<NT>() const
{
@@ -571,19 +524,6 @@ struct position4_base
return x == rhs && y == rhs && z == rhs && w == rhs;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator !=(const position4_base& rhs) const
{
return !(*this == rhs);
}
constexpr bool operator !=(T rhs) const
{
return !(*this == rhs);
}
#endif
template<typename NT>
explicit constexpr operator position4_base<NT>() const
{
@@ -639,14 +579,6 @@ struct coord_base
return position == rhs.position && size == rhs.size;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const coord_base& rhs) const
{
return position != rhs.position || size != rhs.size;
}
#endif
template<typename NT>
explicit constexpr operator coord_base<NT>() const
{
@@ -718,14 +650,6 @@ struct area_base
return x1 == rhs.x1 && x2 == rhs.x2 && y1 == rhs.y1 && y2 == rhs.y2;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const area_base& rhs) const
{
return !(*this == rhs);
}
#endif
constexpr area_base operator - (const size2_base<T>& size) const
{
return{ x1 - size.width, y1 - size.height, x2 - size.width, y2 - size.height };
@@ -864,17 +788,10 @@ struct color4_base
{
}
constexpr bool operator == (const color4_base& rhs) const
constexpr bool operator ==(const color4_base& rhs) const
{
return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const color4_base& rhs) const
{
return !(*this == rhs);
}
#endif
void operator *= (const color4_base<T>& rhs)
{
@@ -940,17 +857,10 @@ struct color3_base
{
}
constexpr bool operator == (const color3_base& rhs) const
constexpr bool operator ==(const color3_base& rhs) const
{
return r == rhs.r && g == rhs.g && b == rhs.b;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const color3_base& rhs) const
{
return !(*this == rhs);
}
#endif
template<typename NT>
explicit constexpr operator color3_base<NT>() const
@@ -984,19 +894,11 @@ struct color2_base
{
}
constexpr bool operator == (const color2_base& rhs) const
constexpr bool operator ==(const color2_base& rhs) const
{
return r == rhs.r && g == rhs.g;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const color2_base& rhs) const
{
return !(*this == rhs);
}
#endif
template<typename NT>
explicit constexpr operator color2_base<NT>() const
{
@@ -1018,19 +920,11 @@ struct color1_base
{
}
constexpr bool operator == (const color1_base& rhs) const
constexpr bool operator ==(const color1_base& rhs) const
{
return r == rhs.r;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const color1_base& rhs) const
{
return !(*this == rhs);
}
#endif
template<typename NT>
explicit constexpr operator color1_base<NT>() const
{
+1 -64
View File
@@ -161,11 +161,6 @@ public:
return m_ptr == rhs.m_ptr;
}
bool operator !=(const lf_queue_iterator& rhs) const
{
return m_ptr != rhs.m_ptr;
}
T& operator *() const
{
return m_ptr->m_data;
@@ -308,7 +303,7 @@ public:
}
template <atomic_wait::op Flags = atomic_wait::op::eq>
void wait(std::nullptr_t null = nullptr) noexcept
void wait(std::nullptr_t /*null*/ = nullptr) noexcept
{
if (m_head == nullptr)
{
@@ -365,64 +360,6 @@ public:
return count;
}
// Iterator that enables direct endless range-for loop: for (auto* ptr : queue) ...
class iterator
{
lf_queue* _this = nullptr;
lf_queue_slice<T> m_data;
public:
constexpr iterator() = default;
explicit iterator(lf_queue* _this)
: _this(_this)
{
m_data = _this->pop_all();
}
bool operator !=(const iterator& rhs) const
{
return _this != rhs._this;
}
T* operator *() const
{
return m_data ? m_data.get() : nullptr;
}
iterator& operator ++()
{
if (m_data)
{
m_data.pop_front();
}
if (!m_data)
{
m_data = _this->pop_all();
if (!m_data)
{
_this->wait();
m_data = _this->pop_all();
}
}
return *this;
}
};
iterator begin()
{
return iterator{this};
}
iterator end()
{
return iterator{};
}
};
// Concurrent linked list, elements remain until destroyed.
+2 -2
View File
@@ -1,7 +1,7 @@
#include "stdafx.h"
#include "Utilities/rXml.h"
rXmlNode::rXmlNode() : handle()
rXmlNode::rXmlNode()
{
}
@@ -55,7 +55,7 @@ std::string rXmlNode::GetNodeContent()
return handle.text().get();
}
rXmlDocument::rXmlDocument() : handle()
rXmlDocument::rXmlDocument()
{
}
+15 -2
View File
@@ -1,6 +1,19 @@
#pragma once
#ifdef _MSC_VER
#pragma warning(push, 0)
#include <pugixml.hpp>
#pragma warning(pop)
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wall"
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Weffc++"
#include <pugixml.hpp>
#pragma GCC diagnostic pop
#endif
#include <memory>
struct rXmlNode
@@ -13,7 +26,7 @@ struct rXmlNode
std::string GetAttribute( const std::string &name);
std::string GetNodeContent();
pugi::xml_node handle;
pugi::xml_node handle{};
};
struct rXmlDocument
@@ -24,5 +37,5 @@ struct rXmlDocument
void Read(const std::string& data);
std::shared_ptr<rXmlNode> GetRoot();
pugi::xml_document handle;
pugi::xml_document handle{};
};
-1
View File
@@ -1,6 +1,5 @@
#pragma once
#include <mutex>
#include "util/types.hpp"
#include "util/atomic.hpp"
+1 -3
View File
@@ -3,7 +3,6 @@
/* For internal use. Don't include. */
#include "util/types.hpp"
#include "util/atomic.hpp"
#include "util/dyn_lib.hpp"
#ifdef _WIN32
@@ -11,7 +10,7 @@
#define NOMINMAX
#endif
#include <Windows.h>
#include <time.h>
#include <ctime>
#elif __linux__
#include <errno.h>
#include <sys/syscall.h>
@@ -21,7 +20,6 @@
#include <fcntl.h>
#endif
#include <algorithm>
#include <ctime>
#include <chrono>
#include <mutex>
#include <condition_variable>
+1
View File
@@ -1,3 +1,4 @@
set(ENABLE_PCH OFF CACHE BOOL "Enables Precompiled header" FORCE)
set(BUILD_EXTERNAL OFF CACHE BOOL "Build external dependencies in /External" FORCE)
set(SKIP_GLSLANG_INSTALL ON CACHE BOOL "Skip installation" FORCE)
set(ENABLE_SPVREMAPPER OFF CACHE BOOL "Enables building of SPVRemapper" FORCE)
+8 -7
View File
@@ -38,24 +38,25 @@
</ImportGroup>
<PropertyGroup Label="UserMacros">
<CmakeGenerator>"Visual Studio $(VisualStudioVersion.Substring(0,2))"</CmakeGenerator>
<CmakeCLI>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang</CmakeCLI>
<CmakeReleaseCLI>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_BUILD_TYPE="Release" -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang</CmakeReleaseCLI>
<CmakeDebugCLI>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_BUILD_TYPE="Debug" -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang</CmakeDebugCLI>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>$(CmakeCLI)
<NMakeBuildCommandLine>$(CmakeReleaseCLI)
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>$(CmakeCLI)
<NMakeReBuildCommandLine>$(CmakeReleaseCLI)
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>$(CmakeCLI)
<NMakeCleanCommandLine>$(CmakeReleaseCLI)
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>$(CmakeCLI)
<NMakeBuildCommandLine>$(CmakeDebugCLI)
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>$(CmakeCLI)
<NMakeReBuildCommandLine>$(CmakeDebugCLI)
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>$(CmakeCLI)
<NMakeCleanCommandLine>$(CmakeDebugCLI)
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
</NMakeCleanCommandLine>
</PropertyGroup>
@@ -38,25 +38,26 @@
</ImportGroup>
<PropertyGroup Label="UserMacros">
<CmakeGenerator>"Visual Studio $(VisualStudioVersion.Substring(0,2))"</CmakeGenerator>
<CmakeCLI>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DSPIRV-Headers_SOURCE_DIR=$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../spirv-headers')) ../spirv-tools</CmakeCLI>
<CmakeReleaseCLI>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_BUILD_TYPE="Release" -DSPIRV_WERROR=OFF -DSPIRV-Headers_SOURCE_DIR=$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../spirv-headers')) ../spirv-tools</CmakeReleaseCLI>
<CmakeDebugCLI>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_BUILD_TYPE="Debug" -DSPIRV_WERROR=OFF -DSPIRV-Headers_SOURCE_DIR=$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../spirv-headers')) ../spirv-tools</CmakeDebugCLI>
<PropsAbsPath>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\common_default.props'))</PropsAbsPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>$(CmakeCLI)
<NMakeBuildCommandLine>$(CmakeReleaseCLI)
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>$(CmakeCLI)
<NMakeReBuildCommandLine>$(CmakeReleaseCLI)
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>$(CmakeCLI)
<NMakeCleanCommandLine>$(CmakeReleaseCLI)
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>$(CmakeCLI)
<NMakeBuildCommandLine>$(CmakeDebugCLI)
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>$(CmakeCLI)
<NMakeReBuildCommandLine>$(CmakeDebugCLI)
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>$(CmakeCLI)
<NMakeCleanCommandLine>$(CmakeDebugCLI)
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m
</NMakeCleanCommandLine>
</PropertyGroup>
+1 -1
Submodule asmjit updated: fc251c914e...723f58581a
+1 -17
View File
@@ -1,18 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug - LLVM|x64">
<Configuration>Debug - LLVM</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release - LLVM|x64">
<Configuration>Release - LLVM</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -104,23 +96,15 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="..\rpcs3_debug.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'" Label="PropertySheets">
<Import Project="..\rpcs3_debug.props" />
<Import Project="..\rpcs3_llvm.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="..\rpcs3_release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'" Label="PropertySheets">
<Import Project="..\rpcs3_release.props" />
<Import Project="..\rpcs3_llvm.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>ASMJIT_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release'">MaxSpeed</Optimization>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+10 -8
View File
@@ -5,10 +5,7 @@ trigger:
tags:
exclude:
- '*'
pr:
branches:
include:
- master
pr: none
jobs:
- job: Linux_Build
strategy:
@@ -19,12 +16,17 @@ jobs:
COMPILER: gcc
variables:
CCACHE_DIR: $(Pipeline.Workspace)/ccache
IS_AZURE: true
CI_HAS_ARTIFACTS: true
UPLOAD_COMMIT_HASH: d812f1254a1157c80fd402f94446310560f54e5f
UPLOAD_REPO_FULL_NAME: "RPCS3/rpcs3-binaries-linux"
DEPLOY_APPIMAGE: true
APPDIR: "/rpcs3/build/appdir"
ARTDIR: "/root/artifacts"
RELEASE_MESSAGE: "/rpcs3/GitHubReleaseMessage.txt"
pool:
vmImage: 'ubuntu-latest'
steps:
- task: Cache@2
inputs:
@@ -33,13 +35,13 @@ jobs:
displayName: ccache
- bash: |
docker pull --quiet rpcs3/rpcs3-travis-xenial:1.7
docker pull --quiet rpcs3/rpcs3-ci-bionic:1.0
docker run \
-v $(pwd):/rpcs3 \
--env-file .ci/docker.env \
-v $CCACHE_DIR:/root/.ccache \
-v $BUILD_ARTIFACTSTAGINGDIRECTORY:/root/artifacts \
rpcs3/rpcs3-travis-xenial:1.7 \
rpcs3/rpcs3-ci-bionic:1.0 \
/rpcs3/.ci/build-linux.sh
displayName: Docker setup and build
@@ -102,7 +104,7 @@ jobs:
solution: 'rpcs3.sln'
maximumCpuCount: true
platform: x64
configuration: 'Release - LLVM'
configuration: 'Release'
displayName: Compile RPCS3
- bash: .ci/deploy-windows.sh
@@ -340,3 +340,28 @@ QLabel#debugger_frame_pc {
color: #000; /* Font Color: Black */
background-color: #00ff00; /* Green */
}
/* Tree view changes*/
QTreeView::branch:has-children:!has-siblings:closed,
QTreeView::branch:closed:has-children:has-siblings {
border-image: none;
image: url("GuiConfigs/list_arrow_white.png");
}
QTreeView::branch:open:has-children:!has-siblings,
QTreeView::branch:open:has-children:has-siblings {
border-image: none;
image: url("GuiConfigs/list_arrow_down_white.png");
}
QTreeView::branch:has-children:!has-siblings:closed:hover,
QTreeView::branch:closed:has-children:has-siblings:hover {
border-image: none;
image: url("GuiConfigs/list_arrow_blue.png");
}
QTreeView::branch:open:has-children:!has-siblings:hover,
QTreeView::branch:open:has-children:has-siblings:hover {
border-image: none;
image: url("GuiConfigs/list_arrow_down_blue.png");
}
+36 -2
View File
@@ -159,12 +159,12 @@ QCheckBox::indicator:disabled {
/* Scrollbars */
QScrollBar {
width: 5px;
width: 10px;
background: #23262d;
}
QTableView QScrollBar {
width: 3px;
width: 10px;
height: 3px;
}
@@ -628,3 +628,37 @@ QLabel#tty_text {
color: #f8f8f8;
}
/* Debugger colors */
QLabel#debugger_frame_breakpoint {
color: #000; /* Font Color: Black */
background-color: #ffff00; /* Yellow */
}
QLabel#debugger_frame_pc {
color: #000; /* Font Color: Black */
background-color: #00ff00; /* Green */
}
/* Tree view changes*/
QTreeView::branch:has-children:!has-siblings:closed,
QTreeView::branch:closed:has-children:has-siblings {
border-image: none;
image: url("GuiConfigs/list_arrow_white.png");
}
QTreeView::branch:open:has-children:!has-siblings,
QTreeView::branch:open:has-children:has-siblings {
border-image: none;
image: url("GuiConfigs/list_arrow_down_white.png");
}
QTreeView::branch:has-children:!has-siblings:closed:hover,
QTreeView::branch:closed:has-children:has-siblings:hover {
border-image: none;
image: url("GuiConfigs/list_arrow_green.png");
}
QTreeView::branch:open:has-children:!has-siblings:hover,
QTreeView::branch:open:has-children:has-siblings:hover {
border-image: none;
image: url("GuiConfigs/list_arrow_down_green.png");
}
+25
View File
@@ -343,3 +343,28 @@ QTextEdit#tty_frame {
QLabel#tty_text {
color: #ffffff; /* White */
}
/* Tree view changes*/
QTreeView::branch:has-children:!has-siblings:closed,
QTreeView::branch:closed:has-children:has-siblings {
border-image: none;
image: url("GuiConfigs/list_arrow_white.png");
}
QTreeView::branch:open:has-children:!has-siblings,
QTreeView::branch:open:has-children:has-siblings {
border-image: none;
image: url("GuiConfigs/list_arrow_down_white.png");
}
QTreeView::branch:has-children:!has-siblings:closed:hover,
QTreeView::branch:closed:has-children:has-siblings:hover {
border-image: none;
image: url("GuiConfigs/list_arrow_blue.png");
}
QTreeView::branch:open:has-children:!has-siblings:hover,
QTreeView::branch:open:has-children:has-siblings:hover {
border-image: none;
image: url("GuiConfigs/list_arrow_down_blue.png");
}
@@ -337,3 +337,28 @@ QLabel#debugger_frame_pc {
color: #000; /* Font Color: Black */
background-color: #333b44; /* Green */
}
/* Tree view changes*/
QTreeView::branch:has-children:!has-siblings:closed,
QTreeView::branch:closed:has-children:has-siblings {
border-image: none;
image: url("GuiConfigs/list_arrow_white.png");
}
QTreeView::branch:open:has-children:!has-siblings,
QTreeView::branch:open:has-children:has-siblings {
border-image: none;
image: url("GuiConfigs/list_arrow_down_white.png");
}
QTreeView::branch:has-children:!has-siblings:closed:hover,
QTreeView::branch:closed:has-children:has-siblings:hover {
border-image: none;
image: url("GuiConfigs/list_arrow_blue.png");
}
QTreeView::branch:open:has-children:!has-siblings:hover,
QTreeView::branch:open:has-children:has-siblings:hover {
border-image: none;
image: url("GuiConfigs/list_arrow_down_blue.png");
}
+36 -2
View File
@@ -189,11 +189,11 @@ QSlider#sizeSlider::handle:hover {
/* Scrollbars */
QScrollBar {
width: 5px;
width: 10px;
}
QTableView QScrollBar {
width: 3px;
width: 10px;
height: 3px;
}
@@ -650,3 +650,37 @@ QLabel#thumbnail_icon_color {
color: #370048;
}
/* Debugger colors */
QLabel#debugger_frame_breakpoint {
color: #000; /* Font Color: Black */
background-color: #ffff00; /* Yellow */
}
QLabel#debugger_frame_pc {
color: #000; /* Font Color: Black */
background-color: #00ff00; /* Green */
}
/* Tree view changes*/
QTreeView::branch:has-children:!has-siblings:closed,
QTreeView::branch:closed:has-children:has-siblings {
border-image: none;
image: url("GuiConfigs/list_arrow_white.png");
}
QTreeView::branch:open:has-children:!has-siblings,
QTreeView::branch:open:has-children:has-siblings {
border-image: none;
image: url("GuiConfigs/list_arrow_down_white.png");
}
QTreeView::branch:has-children:!has-siblings:closed:hover,
QTreeView::branch:closed:has-children:has-siblings:hover {
border-image: none;
image: url("GuiConfigs/list_arrow_blue.png");
}
QTreeView::branch:open:has-children:!has-siblings:hover,
QTreeView::branch:open:has-children:has-siblings:hover {
border-image: none;
image: url("GuiConfigs/list_arrow_down_blue.png");
}
+12 -3
View File
@@ -193,7 +193,7 @@ QSlider#sizeSlider::handle:hover {
/* Scrollbars */
QScrollBar {
width: 5px;
width: 10px;
}
QScrollArea {
@@ -201,7 +201,7 @@ QScrollArea {
}
QTableView QScrollBar {
width: 3px;
width: 10px;
height: 3px;
}
@@ -648,7 +648,7 @@ QLabel#log_level_warning {
}
QLabel#log_level_notice {
color: #FFFFFF;
color: #455971;
}
QLabel#log_level_trace {
@@ -669,3 +669,12 @@ QLabel#thumbnail_icon_color {
color: #8500ae;
}
/* Debugger colors */
QLabel#debugger_frame_breakpoint {
color: #000; /* Font Color: Black */
background-color: #ffff00; /* Yellow */
}
QLabel#debugger_frame_pc {
color: #000; /* Font Color: Black */
background-color: #00ff00; /* Green */
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

+1
View File
@@ -0,0 +1 @@
Cached data from GitHub API.
+12029
View File
File diff suppressed because one or more lines are too long
Binary file not shown.

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