Compare commits

...

387 Commits

Author SHA1 Message Date
Merry 3c60bc36a1 biquad_filter: Clamp f64 in ApplyBiquadFilterFloat 2023-02-10 20:43:34 +00:00
Merry 9bdcb1070f biquad_filter: Fix rounding in ApplyBiquadFilterInt 2023-02-10 20:34:52 +00:00
liamwhite b3a8c0dc49 Merge pull request #9761 from Morph1984/oops
main: Re-add QtWebEngine zoom factor
2023-02-10 10:54:10 -05:00
bunnei 84743fd6ce Merge pull request #9765 from liamwhite/ffs-apple
kernel: avoid usage of bit_cast
2023-02-10 07:53:40 -08:00
Liam 36b70dec05 kernel: avoid usage of bit_cast 2023-02-10 09:13:58 -05:00
Morph 3fbb93e5c9 main: Re-add QtWebEngine zoom factor
For some reason, I had removed this in https://github.com/yuzu-emu/yuzu/pull/4949/commits/ad6cec71ecd61aa2533d9efa89b68837516f8464

This should fix any improperly scaled web applets.
2023-02-09 22:57:37 -05:00
liamwhite c5743d5499 Merge pull request #9736 from Kelebek1/dynamic_vertex_attribs
Remove fake vertex bindings when dynamic state is enabled
2023-02-09 22:14:55 -05:00
liamwhite cbb289fbee Merge pull request #9750 from ameerj/glsl-sample-id-mask
glsl_emit_context: Remove redeclarations of gl_SampleID and gl_SampleMask
2023-02-09 22:14:47 -05:00
liamwhite c0b36c2d26 Merge pull request #9758 from german77/multi_audio
audio: cubeb: Fix yuzu crashing when it test for latency
2023-02-09 22:14:33 -05:00
Narr the Reg 7c0dcea96c audio: cubeb: Fix yuzu crashing when it test for latency 2023-02-09 19:38:03 -06:00
Matías Locatti 7bad3a7e5e Merge pull request #9749 from ameerj/pr9559-partial-revert
buffer_base: Partially revert changes from #9559
2023-02-09 17:53:45 -03:00
ameerj eb9f16dce4 buffer_base: Partially revert changes from #9559
This fixes a regression where Yoshi's Crafted World (and potentially other titles) would enter an infinite loop when GPU Accuracy was set to "Normal"
2023-02-08 19:37:23 -05:00
ameerj 04139cb3ed glsl_emit_context: Remove redeclarations of gl_SampleID and gl_SampleMask
These built-ins seem to be available without needing to be declared for fragment shaders, similar i.e. to gl_FragDepth
2023-02-08 19:34:39 -05:00
liamwhite f6477b91f9 Merge pull request #9747 from german77/SetSupportedNpadIdTypes
service: hid: Return error if arguments of SetSupportedNpadIdType is invalid
2023-02-08 10:09:26 -05:00
Narr the Reg c27006e99d service: hid: Return error if arguments of SetSupportedNpadIdType is invalid 2023-02-07 21:11:39 -06:00
Mai f3b532d091 Merge pull request #9739 from liamwhite/old-gcc-fix
kernel: fix compilation with older gcc
2023-02-07 22:10:35 -05:00
liamwhite 1f3e8d633a Merge pull request #4949 from Morph1984/hidpi-temp-fix
main: Enable High DPI fixes for Qt >= 5.14
2023-02-06 23:20:49 -05:00
bunnei ecbf74b87a Merge pull request #9644 from SaiKai/volume_quicksetting
add volume quicksetting with volume slider
2023-02-06 17:10:44 -08:00
bunnei 01cb49973a Merge pull request #9735 from merryhime/dynarmic-6.4.5
dynarmic: Update to 6.4.5
2023-02-06 17:09:17 -08:00
Liam 82c2a3da9f kernel: fix compilation with older gcc 2023-02-06 13:14:27 -05:00
liamwhite 72f78a48e3 Merge pull request #9737 from goldenx86/yuzu_cmd
Update yuzu_cmd's default_ini.h
2023-02-06 09:08:27 -05:00
Matías Locatti 69eaad18a5 Update yuzu_cmd's default_ini.h
Rename FSR, add missing resolution multipliers, and SMAA
2023-02-06 06:01:51 -03:00
Kelebek1 8ae2a664d2 Remove fake vertex bindings when dynamic state is enabled 2023-02-05 22:28:03 +00:00
Merry 3f852c61d1 dynarmic: Update to 6.4.5 2023-02-05 21:49:32 +00:00
Mai 0373000143 Merge pull request #9731 from liamwhite/svc-move-only
kernel/svc: Split implementations into separate files
2023-02-05 02:26:52 -05:00
Liam 92eb091ddb kernel/svc: Split implementations into separate files 2023-02-04 22:37:43 -05:00
bunnei a64fc3ee77 Merge pull request #9720 from SoRadGaming/discordPresenceUpdate
Game Image with Discord RPC
2023-02-04 18:37:21 -08:00
Sorab 923c17f1ae Add Game Icon for Discord RPC
Connected to Yuzu Compatibility Page
2023-02-05 12:40:57 +11:00
liamwhite f5ed51bdf3 Merge pull request #9730 from german77/cmd_arg
yuzu_cmd: Order arguments alphabetically and port arguments from Qt
2023-02-04 15:01:17 -05:00
liamwhite 236b54376d Merge pull request #9729 from german77/sdl_input
yuzu_cmd: Fix touch and controller input
2023-02-04 15:01:07 -05:00
liamwhite 7f56b0c49f Merge pull request #9728 from ameerj/s32-value
shader_recompiler/value.h: Remove lingering references to S32
2023-02-04 15:00:54 -05:00
german77 3cd0b816cc yuzu_cmd: Order arguments alphabetically and port arguments from Qt 2023-02-04 11:33:29 -06:00
german77 ebca59b8e9 yuzu_cmd: Fix mismatching controller input 2023-02-04 11:05:57 -06:00
german77 424643f9af yuzu_cmd: Fix touch input 2023-02-04 10:31:12 -06:00
ameerj 4678f53463 shader_recompiler/value.h: Remove lingering references to S32 2023-02-04 00:13:47 -05:00
bunnei 5aca9386cf Merge pull request #9717 from german77/less_is_better
input_common: Simplify stick from button
2023-02-03 16:09:29 -08:00
bunnei 193b513bf5 Merge pull request #9719 from ameerj/hle-ipc-span-copy
Revert #9718, Copy HLE Read Buffer for OutputAccessLogToSdCard
2023-02-03 15:42:18 -08:00
Jonas Gutenschwager 2a491f7aaa remove disambiguation argument from mute text
Co-authored-by: Morph <39850852+Morph1984@users.noreply.github.com>
2023-02-04 00:00:20 +01:00
ameerj 979e4d9950 fsp_srv: Copy HLE Read Buffer for OutputAccessLogToSdCard 2023-02-03 00:12:16 -05:00
ameerj 2d2522693e Revert "Merge pull request #9718 from yuzu-emu/revert-9508-hle-ipc-buffer-span"
This reverts commit 25fc5c0e11, reversing
changes made to af20e25081.
2023-02-03 00:08:45 -05:00
Mai 9083ad816f Merge pull request #9713 from unfamiliarplace/master
Added 'Hide empty rooms' toggle to lobby
2023-02-02 23:54:48 -05:00
bunnei 25fc5c0e11 Merge pull request #9718 from yuzu-emu/revert-9508-hle-ipc-buffer-span
Revert "hle_ipc: Use std::span to avoid heap allocations/copies when calling ReadBuffer"
2023-02-02 19:04:50 -08:00
bunnei af20e25081 Merge pull request #9704 from liamwhite/das
kernel: add KDeviceAddressSpace
2023-02-02 19:00:23 -08:00
Luke Sawczak 54ab154696 added 'Hide empty rooms' toggle to lobby
fixed typo

fixed typo

fixed typo

clang
2023-02-02 18:46:28 -06:00
liamwhite b01698775b Revert "hle_ipc: Use std::span to avoid heap allocations/copies when calling ReadBuffer" 2023-02-02 15:53:28 -05:00
Narr the Reg 2f2e88c3fb input_common: Simplify stick from button 2023-02-02 10:13:27 -06:00
liamwhite 8a33f8bd30 Merge pull request #9708 from ameerj/gl-context-flush
gl_shader_cache: Force context flush when loading disk shader cache
2023-02-01 22:38:13 -05:00
liamwhite a9a860a4f7 Merge pull request #9703 from ameerj/txq-ms
shaders: Fix TXQ with MSAA textures
2023-02-01 22:38:00 -05:00
Liam 7d1c3a3f59 kernel: add KDeviceAddressSpace 2023-02-01 17:18:21 -05:00
bunnei 92c5ab33b7 Merge pull request #9696 from german77/please_forgive_me_for_this_sin
input_common: Implement turbo buttons
2023-02-01 12:08:34 -08:00
german77 ce1895497d yuzu: config: Draw turbo buttons with a different color 2023-02-01 12:42:06 -06:00
german77 75e81885b0 input_common: Implement turbo buttons 2023-02-01 12:42:05 -06:00
Mai c4aa833d61 Merge pull request #9711 from zhaobot/tx-update-20230201062139
Update translations (2023-02-01)
2023-02-01 01:26:51 -05:00
The yuzu Community 6ef4bee98e Update translations (2023-02-01) 2023-02-01 06:21:50 +00:00
bunnei de28cd0c2d Merge pull request #9697 from liamwhite/kcap
kernel: add KCapabilities
2023-01-31 10:51:10 -08:00
bunnei ed4a88bd93 Merge pull request #9508 from ameerj/hle-ipc-buffer-span
hle_ipc: Use std::span to avoid heap allocations/copies when calling ReadBuffer
2023-01-30 12:17:09 -08:00
liamwhite e74660673b Merge pull request #9701 from german77/common_protocol
input_common: joycon: Remove Magic numbers from common protocol
2023-01-30 09:02:12 -05:00
liamwhite 9de88cb5a7 Merge pull request #9631 from vonchenplus/vulkan_clear
video_core: Implement vulkan clear specified channel
2023-01-30 09:01:55 -05:00
Liam 67a8740af6 kernel: add KCapabilities 2023-01-29 22:08:28 -05:00
ameerj 720ff38097 gl_compute_pipeline: Force context flush when loading shader cache 2023-01-29 21:32:12 -05:00
Narr the Reg c318a4c80b input_common: joycon: Remove Magic numbers from common protocol 2023-01-29 20:12:58 -06:00
Morph 4069c3ac8b Merge pull request #9707 from german77/clang15
cmake: Download clang format 15
2023-01-29 21:00:55 -05:00
german77 fb425159b1 cmake: Download clang format 15 2023-01-29 19:57:40 -06:00
ameerj 01eeda74a6 gl_graphics_pipeline: Force context flush when loading shader cache 2023-01-29 20:26:49 -05:00
Narr the Reg 11fea5deea input_common: joycon: Fill missing enum data 2023-01-29 19:11:46 -06:00
Morph 07cefe9062 Merge pull request #9706 from Morph1984/github-tagged-merge
ci: Abort on failure to query Github's API
2023-01-29 20:09:29 -05:00
Morph e711188be7 apply-patches-by-label: Remove unused variables and imports 2023-01-29 19:53:14 -05:00
Morph 0f04cabf84 apply-patches-by-label: Use python f-strings 2023-01-29 19:53:14 -05:00
Morph 8532e17243 ci: Abort on failure to query Github's API
This raises an exception if the GET request to Github's API returns anything other than 200 OK, ensuring we always have successful merges of tagged PRs.
Also, reduces the number of queried pages from 29 to 9 to reduce the number of requests.
2023-01-29 19:53:14 -05:00
Morph 5f4647df7d Merge pull request #9705 from behunin/patch-1
Move to Clang Format 15
2023-01-29 19:52:38 -05:00
Levi Behunin d5fc56db4b Move to Clang Format 15
Depends on https://github.com/yuzu-emu/build-environments/pull/69

clang-15 primary run
2023-01-29 17:49:42 -07:00
ameerj a63e17566a spirv: Fix TXQ with MSAA textures 2023-01-29 13:47:30 -05:00
ameerj a1d8306bfd emit_glasm_image: Fix TXQ with MSAA textures 2023-01-29 13:42:34 -05:00
ameerj 08feba2b56 emit_glsl_image: Implement TXQ with MSAA textures
Also fixes for texture buffers, which do not have mips eithers.
2023-01-29 13:31:47 -05:00
liamwhite 3aab574521 Merge pull request #9699 from ameerj/texture-pass-desc
texture_pass: Fix texture descriptors comparisons
2023-01-29 12:27:41 -05:00
liamwhite 149271923c Merge pull request #9698 from ameerj/texture-pass-handle
texture_pass: Refactor texture handle retrieval
2023-01-29 12:27:33 -05:00
liamwhite 208e635f37 Merge pull request #9694 from ameerj/txq-mips
shader_recompiler: TXQ: Skip QueryLevels when possible
2023-01-29 12:27:26 -05:00
liamwhite d960723dc9 Merge pull request #9684 from liamwhite/read-the-spec
polyfill_thread: satisfy execution ordering requirements of stop_callback
2023-01-29 09:35:42 -05:00
bunnei 9170387e71 Merge pull request #9689 from german77/joycon-calibration
input_common: joycon: Remove magic numbers from calibration protocol
2023-01-29 02:43:14 -08:00
bunnei a3aedcce65 Merge pull request #9691 from ameerj/msaa-texcache
texture_cache: Fix tracking of MSAA image views
2023-01-28 23:47:45 -08:00
liamwhite 236f591bde Merge pull request #9690 from german77/whoops
yuzu: config: Avoid reading deleted object
2023-01-28 22:28:38 -05:00
ameerj 0d820f2dab texture_pass: Fix texture descriptors comparisons 2023-01-28 21:23:52 -05:00
ameerj 9bb429999e texture_pass: Refactor texture handle retrieval 2023-01-28 21:11:38 -05:00
bunnei 40e7d78179 Merge pull request #9687 from ameerj/ogl-shader-ms
glasm, glsl: Implement multisampled Image Fetch
2023-01-28 16:32:11 -08:00
bunnei 159aab9a97 Merge pull request #9682 from ameerj/shader-s32
shader_recompiler: Remove S32 IR type
2023-01-28 14:00:11 -08:00
ameerj 2c2e019a44 shader_recompiler: TXQ: Skip QueryLevels when possible 2023-01-28 16:25:18 -05:00
ameerj c0cedbae94 emit_glsl_image: Fix ImageFetch for MSAA textures 2023-01-28 14:39:27 -05:00
Narr the Reg e84a441d75 yuzu: config: Avoid reading deleted object 2023-01-28 12:50:27 -06:00
liamwhite cd138540e2 Merge pull request #9661 from SoRadGaming/LDNhostnameSupport
LDN hostname support in direct connect
2023-01-28 12:09:57 -05:00
SoRadGaming ad712926d6 LDN Hostname Support in Direct Connect
- Added IPv6 & Namespace support in direct connection Regex
- Updated Tooltip for Direct Connect UI
- Removed Dropdown Connection Type in Direct Connect
2023-01-28 18:33:21 +11:00
ameerj c2fb7b64ce texture_cache: Adjust image view sizes by MSAA samples 2023-01-28 00:15:29 -05:00
FengChen 818631a412 video_core: Implement vulkan clear specified channel 2023-01-28 12:53:05 +08:00
Liam 619c0e70f0 polyfill_thread: satisfy execution ordering requirements of stop_callback 2023-01-27 21:34:49 -05:00
bunnei 2efe42fc93 Merge pull request #9677 from Morph1984/sleep-one
polyfill_thread: Implement StoppableTimedWait
2023-01-27 18:28:03 -08:00
Narr the Reg 4e29afefc4 input_common: joycon: Replace ReadSPI vector with span 2023-01-27 18:45:25 -06:00
liamwhite 6fa86989f1 Merge pull request #9539 from Wollnashorn/opengl-fsr
video_core/opengl: Added FSR upscaling filter to the OpenGL renderer
2023-01-27 19:28:35 -05:00
Narr the Reg 8647c72778 input_common: joycon: Remove magic numbers from calibration protocol 2023-01-27 17:12:04 -06:00
bunnei 32b2a72e7b Merge pull request #9666 from liamwhite/wait-for-me
kernel: fix incorrect locking order in suspension
2023-01-27 15:06:09 -08:00
ameerj 0f795603fc glasm: Add MS sampler types 2023-01-27 02:09:18 -05:00
ameerj 5710e90150 glsl: Add MS sampler types 2023-01-27 02:09:17 -05:00
Mai e54d08fc1f Merge pull request #9685 from liamwhite/minmax
kernel: unbreak min/max template deduction on Apple Clang
2023-01-27 00:07:50 +00:00
Liam e9e1e7aa3a kernel: unbreak min/max template deduction on Apple Clang 2023-01-26 17:43:37 -05:00
Wollnashorn c4a49eb1dd video_core/opengl: Add FSR upscaling filter to the OpenGL renderer 2023-01-26 21:43:33 +01:00
bunnei 7d0a77a825 Merge pull request #9683 from german77/high_power_joycon
input_common: Implement SetLowPowerMode and TriggersElapsed
2023-01-26 10:56:31 -08:00
Narr the Reg 49707916db input_common: Implement SetLowPowerMode and TriggersElapsed for the joycon driver 2023-01-26 11:21:04 -06:00
bunnei 5669692b4e Merge pull request #9670 from merryhime/revert-af5ecb0b15d4449f58434e70eed835cf71fc5527
Revert "MemoryManager: use fastmem directly."
2023-01-25 22:28:55 -08:00
bunnei 58ba508e9a Merge pull request #9652 from liamwhite/ms
spirv: fix multisampled image fetch
2023-01-25 22:28:18 -08:00
bunnei 2158ccda3b Merge pull request #9604 from liamwhite/pt
kernel: KPageTable: update
2023-01-25 22:27:48 -08:00
ameerj 93cc6e4d99 shader_recompiler: Remove S32 IR type
The frontend IR opcodes do not distinguish between signed and unsigned integer types.

Fixes broken shaders when IR validation/graphics debugging is enabled for shaders that used BitCastS32F32
2023-01-25 22:03:15 -05:00
Morph ad6cec71ec main: Convert to device independent coordinates for scaling
devicePixelRatioF() returns the scaling ratio when high dpi scaling is enabled.
When high dpi scaling is enabled, the raw screen coordinate system is scaled to device independent coordinates.
2023-01-25 21:16:05 -05:00
Morph 5be85c556e main: Use passthrough scaling for non-windows OSes
They should be better than windows when handling fractional scaling ratios.
2023-01-25 21:16:04 -05:00
Morph 6a1b089a50 main: Enable High DPI fixes for Qt >= 5.14
This uses Qt's new high DPI application attributes for scaling the current window.
However, these aren't perfect as scaling with non integer scales will cause artifacts in UI, icons and other elements.
Therefore, we use a heuristic to select an appropriate integer scale value depending on the current screen resolution and applies this to the application.
2023-01-25 21:16:04 -05:00
Morph 0a7cdc1981 Merge pull request #9681 from Morph1984/nice-one-qt6
main: Only set AA_DisableWindowContextHelpButton below Qt6
2023-01-25 20:46:51 -05:00
Morph b6e5a6bda8 main: Only set AA_DisableWindowContextHelpButton below Qt6
This is fortunately disabled by default on Qt6, so we just have to check whether we are compiling with Qt6 or not.
2023-01-25 18:45:22 -05:00
liamwhite 0d1a9a12c9 Merge pull request #9675 from Morph1984/ini-concat
default_ini: Split and concatenate the config string literal
2023-01-25 17:57:09 -05:00
liamwhite 4ec50dfd4f Merge pull request #9668 from Morph1984/qt-why-is-this-not-the-default
main: Globally disable the "?" button on dialogs
2023-01-25 17:56:58 -05:00
liamwhite abda68f3a4 Merge pull request #9676 from german77/revert-stick-range
Revert #9617 and fix it on input_common
2023-01-25 17:56:47 -05:00
Morph c55147b24a input_common: Make use of StoppableTimedWait 2023-01-25 16:43:04 -05:00
Morph 9b0563fa87 polyfill_thread: Implement StoppableTimedWait
StoppableTimedWait allows for a timed wait to be stopped immediately after a stop is requested.
This is useful in cases where long duration thread sleeps are needed and allows for immediate joining of waiting threads after a stop is requested.

Co-Authored-By: liamwhite <liamwhite@users.noreply.github.com>
2023-01-25 16:43:04 -05:00
Narr the Reg b82a098968 Merge pull request #9679 from jbeich/libc++
input_common: unbreak build with libc++ (missing std::ranges::find_if)
2023-01-25 15:21:59 -06:00
Jan Beich 20c7084892 input_common: add missing header for libc++ after 340f15d1fa
src/input_common/drivers/joycon.cpp:187:26: error: no member named 'find_if' in namespace 'std::ranges'
            std::ranges::find_if(left_joycons, [](auto& device) { return !device->IsConnected(); });
            ~~~~~~~~~~~~~^
src/input_common/drivers/joycon.cpp:193:54: error: no member named 'find_if' in namespace 'std::ranges'
        const auto unconnected_device = std::ranges::find_if(
                                        ~~~~~~~~~~~~~^
src/input_common/drivers/joycon.cpp:393:51: error: no member named 'find_if' in namespace 'std::ranges'
        const auto matching_device = std::ranges::find_if(
                                     ~~~~~~~~~~~~~^
src/input_common/drivers/joycon.cpp:402:51: error: no member named 'find_if' in namespace 'std::ranges'
        const auto matching_device = std::ranges::find_if(
                                     ~~~~~~~~~~~~~^
2023-01-25 19:52:56 +00:00
Narr the Reg cc821bfae1 Revert 9617 and fix it on input_common 2023-01-25 13:52:50 -06:00
Morph 4cdf69c378 default_ini: Split and concatenate the config string literal
We are dangerously close to MSVC's 16384 character limit for string literals. Breaking this string up and concatenating will allow for more settings to be added in the future.
2023-01-25 14:06:06 -05:00
Merry dc7ab4c5d6 Revert "MemoryManager: use fastmem directly."
This reverts commit af5ecb0b15.
2023-01-25 10:12:04 +00:00
Morph cdfb3795af main: Globally disable the "?" button on dialogs
Sets the AA_DisableWindowContextHelpButton attribute to disable this useless button globally.
2023-01-25 01:12:50 -05:00
bunnei 44b981fd3e Merge pull request #9662 from abouvier/cmake-llvm
cmake: prefer system llvm library
2023-01-24 11:03:14 -08:00
liamwhite a68af583ea Merge pull request #9492 from german77/joycon_release
Input_common: Implement custom joycon driver v2
2023-01-24 09:29:37 -05:00
Liam 693cad8e9b kernel: split SetAddressKey into user and kernel variants 2023-01-23 20:31:03 -05:00
Liam 5086380a63 kernel: fix incorrect locking order in suspension 2023-01-23 17:14:41 -05:00
Liam 76a4356e55 spirv: fix multisampled image fetch 2023-01-23 12:03:19 -05:00
Alexandre Bouvier 34b1ea9c19 cmake: prefer system llvm library 2023-01-23 06:23:00 +01:00
liamwhite f99f618d45 Merge pull request #9555 from abouvier/catch2-update
tests: update catch2 to 3.0.1
2023-01-22 18:22:47 -05:00
Liam 31e54c4573 kernel: KPageTable: update 2023-01-22 13:17:29 -05:00
liamwhite 78df1ddce8 Merge pull request #9660 from german77/koreaToTaiwan
yuzu: Fix language comobox crash
2023-01-22 13:14:38 -05:00
liamwhite 9184b6ed2b Merge pull request #9656 from liamwhite/nsight
nsight_aftermath_tracker: update for latest Aftermath SDK
2023-01-22 13:14:28 -05:00
liamwhite ff2bbc8205 Merge pull request #9637 from SaiKai/repeat_shortcuts
allow volume up/down hotkeys to be repeated
2023-01-22 13:14:19 -05:00
liamwhite 02ac593257 Merge pull request #9617 from german77/off_by_one
core: hid: Fix stick minimum range
2023-01-22 13:14:10 -05:00
liamwhite 9705094a57 Merge pull request #9613 from Kelebek1/demangle
Add stacktrace symbol demangling
2023-01-22 13:13:58 -05:00
german77 a436467152 yuzu: Fix language comobox crash 2023-01-22 10:42:59 -06:00
Liam c6eab71d5c nsight_aftermath_tracker: update for latest Aftermath SDK 2023-01-21 13:01:19 -05:00
Kelebek1 31229dd245 Change licenses 2023-01-21 06:19:43 +00:00
bunnei 380dcde154 Merge pull request #9642 from Tachi107/appstream-metadata-fix
fix(dist): wrap screenshots in <image> tags
2023-01-20 21:02:38 -08:00
bunnei f78068d7bf Merge pull request #9611 from liamwhite/patch-1
debugger: add host fastmem pointer fetch command
2023-01-20 10:00:33 -08:00
Narr the Reg d9ee7c3297 core: hid: Make use of SCOPE_EXIT and SCOPE_GUARD where applicable 2023-01-20 00:51:46 -06:00
german77 fafa92cfb8 input_common: Fix joycon mappings 2023-01-20 00:51:46 -06:00
german77 340f15d1fa input_common: Address byte review 2023-01-20 00:51:45 -06:00
bunnei 7d77798f0e Merge pull request #9640 from german77/why_sdl
input_common: reset sdl motion if data is invalid
2023-01-19 18:47:21 -08:00
Narr the Reg 4a307a7b3a core: hid: Only set the polling mode to the correct side 2023-01-19 18:05:23 -06:00
german77 b40aefb39e input_common: Drop Pro controller support from custom driver 2023-01-19 18:05:22 -06:00
german77 d05ea2f3eb input_common: Fix issue where ring and irs are enabled at the same time 2023-01-19 18:05:22 -06:00
Narr the Reg 459fb2b213 input_common: Implement joycon ir camera 2023-01-19 18:05:22 -06:00
german77 5cb437703f yuzu: Add ring controller test button 2023-01-19 18:05:22 -06:00
german77 527dad7097 input_common: Use DriverResult on all engines 2023-01-19 18:05:22 -06:00
german77 e1a3bda4d9 Address review comments 2023-01-19 18:05:22 -06:00
Narr the Reg 1c08d532e0 core: hid: Fix input regressions 2023-01-19 18:05:22 -06:00
german77 6d6b7bdbc3 input_common: Implement joycon nfc 2023-01-19 18:05:21 -06:00
Narr the Reg 6e33731f29 input_common: Add dual joycon support 2023-01-19 18:05:21 -06:00
Narr the Reg 751d36e739 input_common: Add support for joycon ring controller 2023-01-19 18:05:21 -06:00
Narr the Reg f09a023292 input_common: Add support for joycon input reports 2023-01-19 18:05:21 -06:00
Narr the Reg 5676c2e17f input_common: Use calibration from joycon 2023-01-19 18:05:21 -06:00
Narr the Reg 594b2ade6d input_common: Add support for joycon generic functions 2023-01-19 18:05:21 -06:00
Narr the Reg 6aa6301acd input_common: Add joycon low level functions 2023-01-19 18:05:21 -06:00
Narr the Reg 36d5e0a411 service: hid: Set led pattern and fix color detection 2023-01-19 18:05:20 -06:00
Narr the Reg ed5fa10e97 core: hid: Enable pulling color data from controllers 2023-01-19 18:05:20 -06:00
Narr the Reg a4074001fe core: hid: Migrate ring from emulated devices to emulated controller 2023-01-19 18:05:20 -06:00
Narr the Reg 18c9f8eeed yuzu: Update controller colors and button names 2023-01-19 18:05:20 -06:00
Narr the Reg 2d802893e7 input_common: Disable SDL driver with switch controllers 2023-01-19 18:05:20 -06:00
Narr the Reg d80e6c399b input_common: Initial skeleton for custom joycon driver 2023-01-19 18:05:20 -06:00
liamwhite 475370c8f8 Merge pull request #9556 from vonchenplus/draw_texture
video_core: Implement maxwell3d draw texture method
2023-01-19 14:58:53 -05:00
bunnei 9ca3a4758a Merge pull request #9623 from liamwhite/wp-oops
memory: fix watchpoint use when fastmem is enabled
2023-01-19 10:50:21 -08:00
Jonas Gutenschwager 4653effad8 add volume quicksetting with volume slider 2023-01-19 15:13:23 +01:00
Andrea Pappacoda 9f08b3c3c9 fix(dist): wrap screenshots in <image> tags
The [appstream] spec says that <screenshot/> tags must be wrapped in
either <image/> or <video/> tags, so this patch does just that.

[appstream]: https://freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-screenshots
2023-01-19 10:13:30 +01:00
Narr the Reg 67c3c65f7b Merge pull request #9638 from Kelebek1/firmware4
Demote maxwell3d Firmware4 call log to debug
2023-01-18 23:15:22 -06:00
bunnei 413df0811d Merge pull request #9619 from liamwhite/timing-spaghetti
timing: wait for completion on unregister
2023-01-18 15:13:38 -08:00
german77 db6cb9cc0a input_common: reset sdl motion if data is invalid 2023-01-18 10:05:55 -06:00
Jonas Gutenschwager 887ed5c0e2 fix format 2023-01-18 15:49:47 +01:00
bunnei 82e2ac6026 Merge pull request #9615 from merryhime/upsample-ob1
audio_core: Corrective fixes to upsampler
2023-01-17 23:34:12 -08:00
bunnei 1551f97950 Merge pull request #9608 from liamwhite/fps
nvnflinger: correct swap interval handling
2023-01-17 23:13:47 -08:00
Kelebek1 5a106cf11e Demote maxwell3d Firmware4 call log to debug 2023-01-18 01:59:11 +00:00
Jonas Gutenschwager 83754e4789 allow volume up/down hotkeys to be repeated 2023-01-18 00:39:31 +01:00
bunnei 28fde29924 Merge pull request #9612 from goldenx86/1.5xScaler
1.5X, 7X, 8X resolution scaler options
2023-01-16 17:49:06 -08:00
bunnei 58a10ed5d0 Merge pull request #9622 from merryhime/dynarmic
externals: Update dynarmic to 6.4.4
2023-01-15 23:22:54 -08:00
Feng Chen 9fc7ca1731 Address feedback 2023-01-16 10:27:57 +08:00
Liam f1a0ce0e70 memory: fix watchpoint use when fastmem is enabled 2023-01-15 10:24:31 -05:00
Merry 2817af0961 externals: Update dynarmic to 6.4.4 2023-01-15 02:31:00 +00:00
Liam 0953cdd271 timing: wait for completion on unregister 2023-01-14 15:48:01 -05:00
Kelebek1 42b16bb33a Be careful of mangled out of bounds read 2023-01-14 19:53:55 +00:00
german77 50c86b3c2a core: hid: Fix stick minimum range 2023-01-14 11:53:43 -06:00
Merry a0e8e5b22e upsample: Fix coefficient format 2023-01-14 17:09:03 +00:00
Merry 122a8faa38 audio_core: Fix off-by-one error in upsampler 2023-01-14 15:19:11 +00:00
Kelebek1 ce0b8d618d Move demangle impl to cpp 2023-01-14 05:12:41 +00:00
Kelebek1 80a55c1663 Add stacktrace symbol demangling 2023-01-14 04:43:21 +00:00
Matías Locatti d7dbd8e774 Update settings.h 2023-01-13 04:56:25 -03:00
Matías Locatti 4294429a07 CPP 2023-01-13 04:55:26 -03:00
Matías Locatti bb2aec00a2 UI change 2023-01-13 04:54:29 -03:00
Matías Locatti 3ba53f2511 1.5X resolution scaler option 2023-01-13 02:34:24 -03:00
Liam e9c3d16f6f debugger: add host fastmem pointer fetch command 2023-01-12 18:35:14 -05:00
Liam 2f2ef5b147 nvnflinger: correct swap interval handling 2023-01-11 22:05:08 -05:00
bunnei 0e8f98a441 Merge pull request #9605 from german77/mouse_mapping
yuzu: Read mouse scroll
2023-01-10 17:32:58 -08:00
Narr the Reg 87b02f78e1 yuzu: Read mouse wheel input 2023-01-10 18:20:58 -06:00
Morph c277dad25f Merge pull request #9596 from liamwhite/mvk
MoltenVK: restrict number of vertex attributes/bindings to 16
2023-01-10 18:11:44 -05:00
liamwhite cbcf210c19 Merge pull request #9582 from yuzu-emu/revert-9518-revert-9504-pg2
Revert "Revert "k_page_group: synchronize""
2023-01-10 15:27:33 -05:00
liamwhite 0eae0b6803 Merge pull request #9601 from liamwhite/it-never-ends
qt: unlock during signal emission
2023-01-10 15:27:12 -05:00
liamwhite 74404261d2 Merge pull request #9598 from liamwhite/indirect
vulkan_common: fix indirect draw with count
2023-01-10 15:27:02 -05:00
liamwhite e2c68edd35 Merge pull request #9595 from liamwhite/per-game
qt: fix configuration weirdness on turbo
2023-01-10 15:26:49 -05:00
liamwhite 9f974ea818 Merge pull request #9565 from MonsterDruide1/tas-multiplayer-lengths
TAS: Show all script lengths for multiplayer
2023-01-10 15:26:36 -05:00
Liam 385ddef8c3 qt: unlock during signal emission 2023-01-10 12:46:01 -05:00
Liam fa8581e900 vulkan_common: fix indirect draw with count 2023-01-10 09:43:36 -05:00
TellowKrinkle eaf425bd32 MoltenVK: restrict number of vertex attributes/bindings to 16 2023-01-09 19:01:09 -05:00
Liam 1caa84e652 qt: fix configuration weirdness on turbo 2023-01-09 17:54:49 -05:00
UltraHDR fda0e7e989 macOS: Make Yuzu show up in the Launchpad Games folder (#9594)
https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype
This makes it show up in the Launchpad Games folder
2023-01-09 16:43:45 -05:00
Morph 6bf1436f5c Merge pull request #9589 from liamwhite/default
renderer_vulkan: disable turbo by default
2023-01-09 16:23:24 -05:00
Morph ffb12f4f9f Merge pull request #9581 from liamwhite/turbo2
renderer_vulkan: pause turbo submissions on inactive queue
2023-01-09 16:23:16 -05:00
Morph a4cd747122 Merge pull request #9530 from liamwhite/vk-feature-init
vulkan_device: refactor feature testing
2023-01-09 16:23:04 -05:00
Morph 3be8312120 Merge pull request #9569 from liamwhite/shutdown-wars
qt: additional fixes for reentrant shutdown
2023-01-09 16:21:27 -05:00
Liam 279005448a vulkan_device: refactor feature testing 2023-01-09 16:12:16 -05:00
Fernando S 948ac976d1 Merge pull request #9583 from FernandoS27/fuck-ogl-already
VideoCore: Fix OGL cache invalidation.
2023-01-08 14:05:29 -05:00
Liam 0df43e4e07 renderer_vulkan: disable turbo by default 2023-01-08 11:38:30 -05:00
Fernando Sahmkow efbb6fe288 VideoCore: Fix OGL cache invalidation. 2023-01-07 21:56:17 -05:00
bunnei a5693afa03 Revert "Revert "k_page_group: synchronize"" 2023-01-07 15:32:10 -08:00
bunnei 66e4a48b75 Merge pull request #9563 from german77/crash_not_allowed
input_common: Create an update engine
2023-01-07 13:41:27 -08:00
MonsterDruide1 115bf20448 TAS: Show all script lengths for multiplayer 2023-01-07 21:15:37 +01:00
liamwhite 926438b68d Merge pull request #9578 from bylaws/patch-2
Avoid OOB array access reading passthrough attr mask
2023-01-07 15:14:08 -05:00
Liam c19c8ac92c renderer_vulkan: pause turbo submissions on inactive queue 2023-01-07 14:35:11 -05:00
Billy Laws d34275a260 Avoid OOB array access reading passthrough attr mask
YFC 1.5 extended the size of the varying mask used to hold passthrough attrs without considering this
2023-01-07 18:38:21 +00:00
Narr the Reg 432d48d9c8 Merge pull request #9570 from liamwhite/less-clock-boost
renderer_vulkan: disable clock boost on unvalidated devices
2023-01-07 10:41:37 -06:00
Narr the Reg cc92b7fd94 Merge pull request #9573 from liamwhite/optional
vulkan_device: avoid attempt to access empty optional
2023-01-07 10:40:21 -06:00
Liam 444b25bae1 vulkan_device: avoid attempt to access empty optional 2023-01-06 21:23:21 -05:00
Liam 2e4dde12c7 renderer_vulkan: disable clock boost on unvalidated devices 2023-01-06 19:07:47 -05:00
Liam 9ed4c13758 qt: additional fixes for reentrant shutdown 2023-01-06 18:50:01 -05:00
liamwhite c0f17e1b27 Merge pull request #9567 from german77/antialias
opengl: Sanitize antialiasing config
2023-01-06 15:20:23 -05:00
Narr the Reg 4bda2b475f opengl: Sanitize antialiasing config 2023-01-06 13:42:20 -06:00
Fernando S 7ef897a277 Merge pull request #9566 from Wollnashorn/vulkan-cache-header-fix
video_core/vulkan: Fixed loading of Vulkan driver pipeline cache
2023-01-06 11:58:36 -05:00
Wollnashorn 457826a83b video_core/vulkan: Fixed loading of Vulkan driver pipeline cache
The header size of the Vulkan driver pipeline cache files was incorrectly in PipelineCache::LoadVulkanPipelineCache, for which the pipeline cache wasn't read correctly and got invalidated on each load.
2023-01-06 16:52:41 +01:00
Fernando S 8b251fc3f6 Merge pull request #9535 from bylaws/master
Port over several shader-compiler fixes from skyline
2023-01-06 10:06:45 -05:00
liamwhite 3c05988df2 Merge pull request #9561 from liamwhite/update-dynarmic
externals: update dynarmic, xbyak
2023-01-06 10:00:18 -05:00
liamwhite 6d74490139 Merge pull request #9558 from MonsterDruide1/network-timeout-noerror
net: Silently translate ETIMEDOUT network error
2023-01-06 10:00:09 -05:00
liamwhite 020dbcdbc7 Merge pull request #9552 from liamwhite/turbo
vulkan: implement 'turbo mode' clock booster
2023-01-06 09:59:59 -05:00
Fernando S 5bcbb8de45 Merge pull request #9559 from FernandoS27/cached-writes
VideoCore: Implement Cached Writes, use fastmem for reading GPU memory and eliminate old stuffs
2023-01-06 07:31:39 -05:00
liamwhite 990fe2b3fc Merge pull request #9564 from FernandoS27/oops-i-did-it-again
MacroHLE: eliminate 2 rushed macros.
2023-01-05 22:14:27 -05:00
Fernando Sahmkow f6245dc40a MacroHLE: eliminate 2 rushed macros. 2023-01-05 20:53:31 -05:00
Narr the Reg 8042ce7e19 input_common: Create an update engine 2023-01-05 19:24:29 -06:00
liamwhite eaca61e073 Merge pull request #9528 from liamwhite/mvk-nulldesc
renderer_vulkan: implement fallback path for null buffer descriptors
2023-01-05 18:31:55 -05:00
liamwhite 3e33a878dc Merge pull request #9536 from liamwhite/debug-utils
vulkan_common: unify VK_EXT_debug_utils and selection of validation layer
2023-01-05 18:31:45 -05:00
Liam 1ee0540f82 externals: update dynarmic, xbyak 2023-01-05 18:06:06 -05:00
Billy Laws 58fec43768 Run clang-format 2023-01-05 22:18:10 +00:00
Billy Laws 12b4c9c04c externals: Update sirit 2023-01-05 22:13:07 +00:00
Billy Laws 68ed60cee4 shader_recompiler: Fix shuffle partitioning for >64 invoc-per-subgroup GPUs
The existing implementation only supports 64 invoc-per-subgroup GPUs, and misbehaves on adreno when invocations need to be split into 4 emulated subgroups.
2023-01-05 22:13:07 +00:00
Billy Laws 6c812a0c84 Vulkan, OpenGL: Hook up geometry shader passthrough emulation 2023-01-05 22:13:07 +00:00
Billy Laws 625a4af73a shader_recompiler: Add support for lowering geometry passthrough
Reuses most of the existing code for generating the gl_Layer passthrough. Fixes geometry in Nier: Automata on GPUs without HW passthrough support.
2023-01-05 22:13:07 +00:00
Billy Laws 9e2997c4b6 Vulkan, OpenGL: Hook up storage buffer alignment code 2023-01-05 22:13:07 +00:00
Billy Laws 8804a4eb23 shader_recompiler: Align SSBO offsets to meet host requirements
We can take advantage of SSBO addresses being passed in a constant bufer to account for the extra alignment requirements in the shader itself.
2023-01-05 22:13:07 +00:00
Billy Laws 3f0985c7b0 shader_recompiler: SPIRV: Only enable int64 feature when supported 2023-01-05 22:13:07 +00:00
Billy Laws c1cc99584c shader_recompiler: Add comparison operators to descriptor types 2023-01-05 22:13:07 +00:00
Billy Laws bbfad79c89 Vulkan: Add a workaround for input_position on Adreno drivers
Adreno drivers will crash compiling geometry shaders if the input position is not wrapped in a gl_in struct.
2023-01-05 22:13:07 +00:00
Fernando S 1428451722 Merge pull request #9527 from Wollnashorn/amd-cache-fix
video_core/vulkan: Implemented `VkPipelineCache` to store Vulkan pipelines
2023-01-05 16:38:07 -05:00
Wollnashorn e07976a22b video_core/vulkan: Vulkan driver pipelines now contain cache version
So that old cache can get deleted when the cache version changes and does not grow infinitely
2023-01-05 21:03:01 +01:00
Wollnashorn 9c9008ac81 video_core/vulkan: Driver pipeline cache will now be deleted with the shader cache 2023-01-05 21:03:01 +01:00
Wollnashorn 8945fafcc0 config: Set the Vulkan driver pipeline cache option to be global 2023-01-05 21:03:01 +01:00
Wollnashorn f2aa816679 video_core/vulkan: Added check if Vulkan pipeline path has been set 2023-01-05 21:03:01 +01:00
Wollnashorn f4626512ff config: Better wording for VK pipeline cache option and enable by default 2023-01-05 21:03:01 +01:00
Wollnashorn 67d4f190f7 yuzu-cmd: Removed use_vulkan_driver_pipeline_cache from default_ini.h
The addition of the use_vulkan_driver_pipeline_cache option into the default ini string literal caused the 16,384-byte limit of the MSVC compiler to be exceeded.
2023-01-05 21:03:01 +01:00
Wollnashorn 16809c1fa7 video_core/vulkan: Added VkPipelineCache to store Vulkan pipelines
As an optional feature which can be enabled in the advanced graphics configuration, all pipelines that get built at the initial shader loading are stored in a VkPipelineCache object and are dumped to the disk.

These vendor specific pipeline cache files are located at `/shader/GAME_ID/vulkan_pipelines.bin`. This feature was mainly added because of an issue with the AMD driver (see yuzu-emu#8507) causing invalidation of the cache files the driver builds automatically.
2023-01-05 21:02:44 +01:00
Fernando Sahmkow b56ad93bbc BufferBase: Don't ignore GPU pages. 2023-01-05 14:00:10 -05:00
Fernando Sahmkow 2d0c4f2b1d Fermi2D: sync cache flushes 2023-01-05 06:43:28 -05:00
Fernando Sahmkow af5ecb0b15 MemoryManager: use fastmem directly. 2023-01-05 06:06:33 -05:00
MonsterDruide1 688a9fbfa6 net: Silently translate ETIMEDOUT network error 2023-01-05 11:54:36 +01:00
Fernando Sahmkow 6c7eb81f7d video_core: Cache GPU internal writes. 2023-01-05 05:23:39 -05:00
liamwhite e82e3e06be Merge pull request #9557 from FernandoS27/ooops-i-killed-the-shitty-drivers
Vulkan: Fix drivers that don't support dynamic_state_2 up
2023-01-05 00:14:01 -05:00
Fernando Sahmkow 4d9af4a9d2 Vulkan: Fix drivers that don't support dynamic_state_2 up 2023-01-05 00:11:16 -05:00
Feng Chen 013b689153 video_core: Implement opengl/vulkan draw_texture 2023-01-05 12:41:33 +08:00
Feng Chen 1e8cee2ddf video_core: Implement maxwell3d draw texture method 2023-01-05 12:41:28 +08:00
Alexandre Bouvier 7a2bd13f5b cmake: support the standard cmake testing option 2023-01-05 05:03:34 +01:00
Alexandre Bouvier d0fe27708e tests: update catch2 to 3.0.1 2023-01-05 04:58:31 +01:00
Liam a4269c285a common: add setting for renderer clock workaround 2023-01-04 22:22:01 -05:00
Liam 301e9bbc03 vulkan: implement 'turbo mode' clock booster 2023-01-04 22:22:01 -05:00
Liam 66ae79de13 renderer_vulkan: implement fallback path for null descriptors 2023-01-04 22:14:01 -05:00
liamwhite b78328f19a Merge pull request #9501 from FernandoS27/yfc-rel-2
Yuzu Fried Chicken Part 1.5: MacroHLE Rework and Dynamic State
2023-01-04 21:20:00 -05:00
Fernando Sahmkow 3ecc03ec1b yuzu-ui: Add setting for disabling macro HLE 2023-01-04 14:56:52 -05:00
Fernando Sahmkow a0c697124c Video_core: Address feedback 2023-01-04 14:39:42 -05:00
Fernando Sahmkow 03ccd8bf43 Texture Cache: Implement async texture downloads. 2023-01-03 22:52:15 -05:00
liamwhite bbeb6e460c Merge pull request #9518 from gidoly/revert-9504-pg2
Revert "k_page_group: synchronize"
2023-01-03 21:40:57 -05:00
Fernando Sahmkow ddbf851ef6 Vulkan: Update blacklisting to latest driver versions. 2023-01-03 21:16:43 -05:00
Fernando Sahmkow a045e860dd ShaderCompiler: Inline driver specific constants. 2023-01-03 16:29:25 -05:00
Fernando Sahmkow b62ffb612d Vulkan: rework stencil tracking. 2023-01-03 16:29:16 -05:00
liamwhite 6f031f08fe Merge pull request #9547 from MonsterDruide1/tas-doesnt-flap
TAS: Immediately switch stick to TAS on input
2023-01-03 15:03:58 -05:00
MonsterDruide1 04cb05fce0 TAS: Immediately switch stick to TAS on input
Co-Authored-By: Narr the Reg <5944268+german77@users.noreply.github.com>
2023-01-03 20:08:25 +01:00
liamwhite a7e610403d Merge pull request #9542 from abouvier/cmake-module-path
cmake: move find-modules to root cmake dir
2023-01-02 13:45:36 -05:00
Alexandre Bouvier eceee8c3d9 cmake: move find-modules to root cmake dir 2023-01-02 18:22:07 +01:00
liamwhite 2b110d61e7 Merge pull request #9541 from abouvier/cmake-option
cmake: allow options shadowing with normal variables
2023-01-02 11:29:32 -05:00
liamwhite 6804a43f49 Merge pull request #9540 from MonsterDruide1/tas-sanitized-record
TAS: Record sanitized instead of raw stick inputs
2023-01-02 09:51:29 -05:00
bunnei 48bcb91a2e Merge pull request #9537 from abouvier/cmake-almost-quiet
cmake: improve find_package failure messages
2023-01-02 01:08:20 -08:00
bunnei 09c9be3703 Merge pull request #9543 from german77/nifm
service: nifm: Initialize request state
2023-01-01 21:38:43 -08:00
german77 80bcc18788 service: nifm: Initialize request state 2023-01-01 20:58:08 -06:00
german77 ebd811b535 service: nifm: Match documentation names 2023-01-01 20:58:01 -06:00
Alexandre Bouvier 306c791e67 cmake: allow options shadowing with normal variables 2023-01-02 02:43:38 +01:00
Alexandre Bouvier 1dfcf19c36 cmake: improve find_package failure messages 2023-01-02 02:27:25 +01:00
Liam f9c6d39a6c vulkan_common: blacklist radv from extended_dynamic_state2 on drivers before 22.3.1 2023-01-01 16:43:58 -05:00
Liam 4814d87385 video_core: fix build 2023-01-01 16:43:58 -05:00
Fernando Sahmkow d09aa0182f MacroHLE: Final cleanup and fixes. 2023-01-01 16:43:58 -05:00
Fernando Sahmkow 581a7d785b Rasterizer: Setup skeleton for Host Conditional rendering 2023-01-01 16:43:58 -05:00
Fernando Sahmkow 3630bfaef3 RasterizerMemory: Add filtering for flushing/invalidation operations. 2023-01-01 16:43:58 -05:00
Fernando Sahmkow 2793304117 Vulkan: Allow stagging buffer deferrals. 2023-01-01 16:43:58 -05:00
Fernando Sahmkow 8d694701bc MacroHLE: Add OpenGL Support 2023-01-01 16:43:58 -05:00
Fernando Sahmkow 4c82e47edd Vulkan: Add other additional pipeline specs 2023-01-01 16:43:58 -05:00
Fernando Sahmkow d33251db93 Vulkan: Implement Dynamic State 3 2023-01-01 16:43:58 -05:00
Fernando Sahmkow f800e485c9 Vulkan Implement Dynamic State 2 LogicOp and PatchVertices 2023-01-01 16:43:58 -05:00
Fernando Sahmkow c897c55e3c Vulkan: Implement Dynamic States 2 2023-01-01 16:43:57 -05:00
Fernando Sahmkow cb1497d0d7 DMAPusher: Improve collection of non executing methods 2023-01-01 16:43:57 -05:00
Fernando Sahmkow ce448ce770 Revert Buffer cache changes and setup additional macros. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow 18637766ef MacroHLE: Reduce massive calculations on sizing estimation. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow aad0cbf024 MacroHLE: Add HLE replacement for base vertex and base instance. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow 93ac5a6a6d MacroHLE: Add Index Buffer size estimation. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow c541559767 MacroHLE: Refactor MacroHLE system. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow 0f89828073 MacroHLE: Implement DrawIndexedIndirect & DrawArraysIndirect. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow a5a94f52ff MacroHLE: Add MultidrawIndirect HLE Macro. 2023-01-01 16:43:57 -05:00
MonsterDruide1 d46c9c4659 TAS: Record sanitized instead of raw stick inputs
Co-Authored-By: Narr the Reg <5944268+german77@users.noreply.github.com>
2023-01-01 22:39:18 +01:00
Mai a12a4f2a13 Merge pull request #9538 from merryhime/char-concat
vfs: Replace cstr concat with char concat
2023-01-01 20:00:46 +00:00
Merry bee395d2f0 vfs: Replace cstr concat with char concat 2023-01-01 18:52:02 +00:00
Liam aa13ee5c4a vulkan_common: unify VK_EXT_debug_utils and selection of validation layer 2023-01-01 11:59:47 -05:00
liamwhite 92103d4ff3 Merge pull request #9533 from merryhime/overcommit
host_memory: mmap changes for virtual_base
2023-01-01 10:24:07 -05:00
liamwhite b2d8bbe0e0 Merge pull request #9532 from zhaobot/tx-update-20230101024213
Update translations (2023-01-01)
2023-01-01 10:23:55 -05:00
liamwhite 0b228fde15 Merge pull request #9514 from ColinKinloch/en_gb
settings: warn on invalid regon/language combinations
2023-01-01 10:23:46 -05:00
Merry fd1831b65b host_memory: Use transparent huge pages where available 2023-01-01 11:40:35 +00:00
Merry 4d7be85e73 host_memory: Allocate virtual_base with MAP_NORESERVE
Specify that we do not require swap to be reserved for this address range;
allow overcommitting.
2023-01-01 11:40:35 +00:00
The yuzu Community 72722986d0 Update translations (2023-01-01) 2023-01-01 02:42:48 +00:00
liamwhite 88f5d38b93 Merge pull request #9526 from ColinKinloch/choose_clang_format
ci: Allow setting clang-format binary
2022-12-30 15:20:20 -05:00
Colin Kinloch 5d36d4b143 ci: Allow setting clang-format binary 2022-12-30 14:29:41 +00:00
Colin Kinloch 28cfc2146f settings: comment language blocklist columns 2022-12-30 13:51:35 +00:00
bunnei 0ac34bd058 Merge pull request #9524 from bunnei/touch-button-crash-fix
core: hid: emulated_console: Avoid a crash if frontend does not configure touch_from_button_maps.
2022-12-30 03:26:41 -05:00
bunnei 05c709bebe core: hid: emulated_console: Avoid a crash if frontend does not configure touch_from_button_maps. 2022-12-30 00:14:53 -08:00
bunnei c3af6d8372 Merge pull request #9515 from liamwhite/cmake-refactor
CMake: make more features optional
2022-12-29 23:37:25 -05:00
Narr the Reg 73167b12b5 Merge pull request #9521 from Wollnashorn/global-only-multiplayer-settings
config: Save multiplayer settings only globally
2022-12-29 22:22:48 -06:00
Wollnashorn 1df5d12b19 config: Save multiplayer settings only globally
Saved multiplayer settings like the nickname, remote address, etc. were reset everytime a game was booted up and the game-specific config files were loaded, as these values will never be set.
2022-12-30 02:32:58 +01:00
Colin Kinloch 8594f287b8 settings: added regon/language warning bounds check 2022-12-29 15:55:24 +00:00
gidoly 10eaf31af3 Revert "k_page_group: synchronize" 2022-12-29 17:39:42 +09:00
liamwhite 9fdacb5e3a Merge pull request #9423 from vonchenplus/vulkan_quad_strip
video_core: Implement all vulkan topology
2022-12-28 20:59:23 -05:00
Liam 9ce23bde24 cmake: make Vulkan-Headers external the default 2022-12-28 20:55:32 -05:00
ameerj b0722591c9 hle_ipc: Use thread_local ReadBuffer 2022-12-28 18:46:54 -05:00
ameerj a1490d77ac hle_ipc: Rename ReadBufferSpan to ReadBuffer 2022-12-28 18:46:54 -05:00
ameerj 59c0f85407 hle_ipc: Rename ReadBuffer to ReadBufferCopy
Indicates explicitly that a copy is occurring
2022-12-28 18:46:54 -05:00
ameerj 7c1bf68bb4 bsd: Use std::span for read payloads
Allows the use of HLERequestContext::ReadBufferSpan
2022-12-28 18:46:54 -05:00
ameerj f517f82416 nvdrv: Use std::span for inputs
Allows the use of HLERequestContext::ReadBufferSpan
2022-12-28 18:46:53 -05:00
ameerj e7032d9e64 hidbus: Use ReadBufferSpan 2022-12-28 18:46:53 -05:00
Liam c18cf05a06 cmake: make cubeb and SDL2 optional 2022-12-28 17:29:32 -05:00
bunnei 60419dd35e Merge pull request #9504 from liamwhite/pg2
k_page_group: synchronize
2022-12-28 17:28:31 -05:00
Liam be43b62d79 cmake: make libusb optional 2022-12-28 17:26:46 -05:00
Liam 3c2aa183a1 cmake: ignore missing package finders for packages with submodule fallbacks 2022-12-28 17:21:31 -05:00
Liam 106cf27135 cmake: make room server optional 2022-12-28 17:18:27 -05:00
Colin Kinloch 2ccf175324 settings: warn on invalid regon/language combinations 2022-12-28 20:34:28 +00:00
bunnei c5de54d509 Merge pull request #9490 from ameerj/texture-cache-prealloc
texture_cache: Use pre-allocated heap buffer for texture swizzles
2022-12-27 00:07:35 -05:00
bunnei 343c01b87a Merge pull request #9495 from german77/no_refresh
yuzu: Automatically refresh device list
2022-12-27 00:07:13 -05:00
Mai 2d7f9fb21b Merge pull request #9507 from abouvier/patch-1
tests: add missing header
2022-12-26 07:19:08 +00:00
Alexandre Bouvier dce2649daf tests: add missing header
<cstring> is needed for std::memcpy
2022-12-26 04:26:31 +00:00
FengChen 6a397bc8ed video_core: Implement other missing vulkan topology 2022-12-26 12:20:49 +08:00
FengChen 86d5b4e556 video_core: Implement vulkan QuadStrip topology 2022-12-26 11:37:34 +08:00
Narr the Reg ac00ead7d4 Merge pull request #9489 from MonsterDruide1/tas-stick-deadzone
TAS: Increase accuracy of Stick inputs
2022-12-25 17:47:50 -06:00
ameerj 32d01a39b0 nvflinger: Split Parcel class into InputParcel and OutputParcel
The usages of the Parcel class were already unique to either Read or Write operations.
Avoids needing a vector of the input payload for the InputParcel use-case, instead it can remain as a span.
2022-12-25 17:19:10 -05:00
ameerj 7ffd624248 service: Use ReadBufferSpan where it is trivial to do so 2022-12-25 17:04:02 -05:00
MonsterDruide1 bc4126acd7 TAS: Increase accuracy of Stick inputs 2022-12-25 21:49:09 +01:00
ameerj 7584d36922 texture_cache: Use Common::ScratchBuffer for swizzle buffers 2022-12-25 15:47:41 -05:00
ameerj 1209d428f1 texture_cache: Use pre-allocated buffer for texture downloads 2022-12-25 15:38:36 -05:00
ameerj c448b3af2f texture_cache: Use pre-allocated buffer for texture uploads 2022-12-25 15:38:36 -05:00
Liam 28d9c30861 k_page_table: remove HACK_OpenPages/ClosePages 2022-12-25 13:43:49 -05:00
ameerj fbc375f0de fsp_srv: Use ReadBufferSpan 2022-12-25 13:21:15 -05:00
ameerj 9349f06963 hle_ipc: Add ReadBufferSpan function
Returns a std::span to the buffer address, rather than create a copy of the memory into a std::vector
2022-12-25 13:20:59 -05:00
Liam 3392fdac9b k_page_group: synchronize 2022-12-25 12:55:21 -05:00
liamwhite 9933121256 Merge pull request #9500 from liamwhite/reentrant-shutdown
qt: prevent reentrant shutdown
2022-12-25 12:51:25 -05:00
liamwhite c6767704fb Merge pull request #9496 from liamwhite/shm3
kernel: workaround static shared memory initialization
2022-12-25 12:51:16 -05:00
liamwhite ea70d9c79e Merge pull request #9487 from liamwhite/look-at-the-time
time: add LockFreeAtomicType
2022-12-25 12:50:57 -05:00
Fernando S 3e6850f00b Merge pull request #9453 from ameerj/scratch-vector
common: Add ScratchBuffer Class
2022-12-24 20:26:06 -05:00
Liam cb7f0c2ec3 qt: prevent reentrant shutdown 2022-12-24 17:31:34 -05:00
liamwhite c86e21abe4 qt: fix 'Pause' menu item (#9497) 2022-12-23 21:44:53 -05:00
Chris Oboe 201733d1b5 Disable automatically opening the console on windows yuzu-cmd builds (#9485)
* don't automatically open the console on windows build of yuzu-cmd

* fix formatting
2022-12-23 21:39:59 -05:00
liamwhite db15142ac9 Merge pull request #9476 from liamwhite/async-shutdown
qt: continue event loop during game close
2022-12-23 21:05:10 -05:00
Morph fa231645f2 Merge pull request #9486 from liamwhite/shutdown-hell
qt: exit properly on guest-initiated close
2022-12-23 21:03:58 -05:00
german77 c3a5522830 yuzu: Automatically refresh device list 2022-12-23 18:26:48 -06:00
Liam 99eccf581e kernel: workaround static shared memory initialization 2022-12-23 13:40:30 -05:00
Liam 80670a5b6c time: add LockFreeAtomicType 2022-12-21 22:36:55 -05:00
Liam 60ce34aa80 qt: exit properly on guest-initiated close 2022-12-21 19:55:01 -05:00
ameerj c6590ad07b scratch_buffer: Explicitly defing resize and resize_destructive functions
resize keeps previous data intact when the buffer grows
resize_destructive destroys the previous data when the buffer grows
2022-12-19 22:40:50 -05:00
ameerj 64869807e2 tests: Add ScratchBuffer tests 2022-12-19 18:08:04 -05:00
ameerj 61e4f2d931 dma_pusher: Rework command_headers usage
Uses ScratchBuffer and avoids overwriting the command_headers buffer with the prefetch_command_list
2022-12-19 18:08:04 -05:00
ameerj bdef22ff85 buffer_cache: Use Common::ScratchBuffer for ImmediateBuffer usage 2022-12-19 18:08:04 -05:00
ameerj 4bc2d82130 video_core: Add usages of ScratchBuffer 2022-12-19 18:08:04 -05:00
ameerj cfc34dd41d common: Add ScratchBuffer class
This class creates a default initialized heap allocated buffer for cases where value initializing members during allocation or resize
is redundant.
2022-12-19 18:07:51 -05:00
ameerj 88ba5a7f22 common: add make_unique_for_overwrite 2022-12-19 18:07:42 -05:00
499 changed files with 53369 additions and 27271 deletions
Regular → Executable
+1 -1
View File
@@ -10,7 +10,7 @@ if grep -nrI '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .ci* dis
fi
# Default clang-format points to default 3.5 version one
CLANG_FORMAT=clang-format-12
CLANG_FORMAT=${CLANG_FORMAT:-clang-format-15}
$CLANG_FORMAT --version
if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then
+9 -11
View File
@@ -2,15 +2,12 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Download all pull requests as patches that match a specific label
# Usage: python download-patches-by-label.py <Label to Match> <Root Path Folder to DL to>
# Usage: python apply-patches-by-label.py <Label to Match>
import requests, sys, json, urllib3.request, shutil, subprocess, os, traceback
import json, requests, subprocess, sys, traceback
tagline = sys.argv[2]
http = urllib3.PoolManager()
dl_list = {}
def check_individual(labels):
for label in labels:
if (label["name"] == sys.argv[1]):
@@ -18,8 +15,9 @@ def check_individual(labels):
return False
def do_page(page):
url = 'https://api.github.com/repos/yuzu-emu/yuzu/pulls?page=%s' % page
url = f"https://api.github.com/repos/yuzu-emu/yuzu/pulls?page={page}"
response = requests.get(url)
response.raise_for_status()
if (response.ok):
j = json.loads(response.content)
if j == []:
@@ -27,13 +25,13 @@ def do_page(page):
for pr in j:
if (check_individual(pr["labels"])):
pn = pr["number"]
print("Matched PR# %s" % pn)
print(subprocess.check_output(["git", "fetch", "https://github.com/yuzu-emu/yuzu.git", "pull/%s/head:pr-%s" % (pn, pn), "-f", "--no-recurse-submodules"]))
print(subprocess.check_output(["git", "merge", "--squash", "pr-%s" % pn]))
print(subprocess.check_output(["git", "commit", "-m\"Merge %s PR %s\"" % (tagline, pn)]))
print(f"Matched PR# {pn}")
print(subprocess.check_output(["git", "fetch", "https://github.com/yuzu-emu/yuzu.git", f"pull/{pn}/head:pr-{pn}", "-f", "--no-recurse-submodules"]))
print(subprocess.check_output(["git", "merge", "--squash", f"pr-{pn}"]))
print(subprocess.check_output(["git", "commit", f"-m\"Merge {tagline} PR {pn}\""]))
try:
for i in range(1,30):
for i in range(1,10):
do_page(i)
except:
traceback.print_exc(file=sys.stdout)
+31 -21
View File
@@ -3,17 +3,14 @@
cmake_minimum_required(VERSION 3.22)
# Dynarmic has cmake_minimum_required(3.12) and we may want to override
# some of its variables, which is only possible in 3.13+
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
project(yuzu)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/find-modules")
include(DownloadExternals)
include(CMakeDependentOption)
project(yuzu)
include(CTest)
# Set bundled sdl2/qt as dependent options.
# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
@@ -22,6 +19,8 @@ CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON
# On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion
CMAKE_DEPENDENT_OPTION(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" ON "ENABLE_SDL2;NOT MSVC" OFF)
option(ENABLE_LIBUSB "Enable the use of LibUSB" ON)
option(ENABLE_OPENGL "Enable OpenGL" ON)
mark_as_advanced(FORCE ENABLE_OPENGL)
option(ENABLE_QT "Enable the Qt frontend" ON)
@@ -35,6 +34,8 @@ option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" "${WIN32}")
option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ON)
option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF)
option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF)
@@ -43,10 +44,12 @@ option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
option(YUZU_TESTS "Compile tests" ON)
option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}")
option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
option(YUZU_ROOM "Compile LDN room server" ON)
CMAKE_DEPENDENT_OPTION(YUZU_CRASH_DUMPS "Compile Windows crash dump (Minidump) support" OFF "WIN32" OFF)
option(YUZU_USE_BUNDLED_VCPKG "Use vcpkg for yuzu dependencies" "${MSVC}")
@@ -201,40 +204,48 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
# System imported libraries
# =======================================================================
find_package(enet 1.3)
# Enforce the search mode of non-required packages for better and shorter failure messages
find_package(enet 1.3 MODULE)
find_package(fmt 9 REQUIRED)
find_package(inih)
find_package(libusb 1.0.24)
find_package(inih MODULE)
find_package(LLVM MODULE)
find_package(lz4 REQUIRED)
find_package(nlohmann_json 3.8 REQUIRED)
find_package(Opus 1.3)
find_package(Vulkan 1.3.238)
find_package(Opus 1.3 MODULE)
find_package(ZLIB 1.2 REQUIRED)
find_package(zstd 1.5 REQUIRED)
if (NOT YUZU_USE_EXTERNAL_VULKAN_HEADERS)
find_package(Vulkan 1.3.238 REQUIRED)
endif()
if (ENABLE_LIBUSB)
find_package(libusb 1.0.24 MODULE)
endif()
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
find_package(xbyak 6)
find_package(xbyak 6 CONFIG)
endif()
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
find_package(dynarmic 6.4.0)
find_package(dynarmic 6.4.0 CONFIG)
endif()
if (ENABLE_CUBEB)
find_package(cubeb)
find_package(cubeb CONFIG)
endif()
if (USE_DISCORD_PRESENCE)
find_package(DiscordRPC)
find_package(DiscordRPC MODULE)
endif()
if (ENABLE_WEB_SERVICE)
find_package(cpp-jwt 1.4)
find_package(httplib 0.11)
find_package(cpp-jwt 1.4 CONFIG)
find_package(httplib 0.11 MODULE)
endif()
if (YUZU_TESTS)
find_package(Catch2 2.13.7 REQUIRED)
find_package(Catch2 3.0.1 REQUIRED)
endif()
find_package(Boost 1.73.0 COMPONENTS context)
@@ -503,7 +514,7 @@ endif()
# against all the src files. This should be used before making a pull request.
# =======================================================================
set(CLANG_FORMAT_POSTFIX "-12")
set(CLANG_FORMAT_POSTFIX "-15")
find_program(CLANG_FORMAT
NAMES clang-format${CLANG_FORMAT_POSTFIX}
clang-format
@@ -598,7 +609,6 @@ if (YUZU_USE_FASTER_LD AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
endif()
endif()
enable_testing()
add_subdirectory(externals)
add_subdirectory(src)
+16
View File
@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2023 Alexandre Bouvier <contact@amb.tf>
#
# SPDX-License-Identifier: GPL-3.0-or-later
find_package(LLVM QUIET CONFIG)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVM CONFIG_MODE)
if (LLVM_FOUND AND NOT TARGET LLVM::Demangle)
add_library(LLVM::Demangle INTERFACE IMPORTED)
llvm_map_components_to_libnames(LLVM_LIBRARIES demangle)
target_compile_definitions(LLVM::Demangle INTERFACE ${LLVM_DEFINITIONS})
target_include_directories(LLVM::Demangle INTERFACE ${LLVM_INCLUDE_DIRS})
target_link_libraries(LLVM::Demangle INTERFACE ${LLVM_LIBRARIES})
endif()
@@ -5,7 +5,7 @@
include(FindPackageHandleStandardArgs)
find_package(httplib QUIET CONFIG)
if (httplib_FOUND)
if (httplib_CONSIDERED_CONFIGS)
find_package_handle_standard_args(httplib CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
@@ -4,7 +4,7 @@
include(FindPackageHandleStandardArgs)
find_package(lz4 QUIET CONFIG)
if (lz4_FOUND)
if (lz4_CONSIDERED_CONFIGS)
find_package_handle_standard_args(lz4 CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
@@ -4,7 +4,7 @@
include(FindPackageHandleStandardArgs)
find_package(zstd QUIET CONFIG)
if (zstd_FOUND)
if (zstd_CONSIDERED_CONFIGS)
find_package_handle_standard_args(zstd CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
+15
View File
@@ -0,0 +1,15 @@
---- LLVM Exceptions to the Apache 2.0 License ----
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into an Object form of such source code, you
may redistribute such embedded portions in such Object form without complying
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
In addition, if you combine or link compiled forms of this Software with
software that is licensed under the GPLv2 ("Combined Software") and if a
court of competent jurisdiction determines that the patent provision (Section
3), the indemnity provision (Section 9) or other Section of the License
conflicts with the conditions of the GPLv2, you may retroactively and
prospectively choose to deem waived or otherwise exclude such Section(s) of
the License, but only in their entirety and only with respect to the Combined
Software.
+1125 -827
View File
File diff suppressed because it is too large Load Diff
+1127 -829
View File
File diff suppressed because it is too large Load Diff
+1123 -825
View File
File diff suppressed because it is too large Load Diff
+1167 -869
View File
File diff suppressed because it is too large Load Diff
+1126 -828
View File
File diff suppressed because it is too large Load Diff
+1158 -857
View File
File diff suppressed because it is too large Load Diff
+1133 -832
View File
File diff suppressed because it is too large Load Diff
+1125 -827
View File
File diff suppressed because it is too large Load Diff
+1180 -883
View File
File diff suppressed because it is too large Load Diff
+1127 -829
View File
File diff suppressed because it is too large Load Diff
+1130 -829
View File
File diff suppressed because it is too large Load Diff
+1125 -827
View File
File diff suppressed because it is too large Load Diff
+1133 -835
View File
File diff suppressed because it is too large Load Diff
+1295 -983
View File
File diff suppressed because it is too large Load Diff
+1154 -856
View File
File diff suppressed because it is too large Load Diff
+1137 -839
View File
File diff suppressed because it is too large Load Diff
+1221 -920
View File
File diff suppressed because it is too large Load Diff
+1133 -835
View File
File diff suppressed because it is too large Load Diff
+1135 -833
View File
File diff suppressed because it is too large Load Diff
+1204 -903
View File
File diff suppressed because it is too large Load Diff
+733 -599
View File
File diff suppressed because it is too large Load Diff
+733 -599
View File
File diff suppressed because it is too large Load Diff
+1164 -863
View File
File diff suppressed because it is too large Load Diff
+1132 -831
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -53,10 +53,10 @@ SPDX-License-Identifier: CC0-1.0
<developer_name>yuzu Emulator Team</developer_name>
<content_rating type="oars-1.0"/>
<screenshots>
<screenshot type="default">https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/001-Super%20Mario%20Odyssey%20.png</screenshot>
<screenshot>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/004-The%20Legend%20of%20Zelda%20Skyward%20Sword%20HD.png</screenshot>
<screenshot>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/007-Pokemon%20Sword.png</screenshot>
<screenshot>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/010-Hyrule%20Warriors%20Age%20of%20Calamity.png</screenshot>
<screenshot>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/039-Pok%C3%A9mon%20Mystery%20Dungeon%20Rescue%20Team%20DX.png.png.png</screenshot>
<screenshot type="default"><image>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/001-Super%20Mario%20Odyssey%20.png</image></screenshot>
<screenshot><image>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/004-The%20Legend%20of%20Zelda%20Skyward%20Sword%20HD.png</image></screenshot>
<screenshot><image>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/007-Pokemon%20Sword.png</image></screenshot>
<screenshot><image>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/010-Hyrule%20Warriors%20Age%20of%20Calamity.png</image></screenshot>
<screenshot><image>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/039-Pok%C3%A9mon%20Mystery%20Dungeon%20Rescue%20Team%20DX.png.png.png</image></screenshot>
</screenshots>
</component>
+21 -12
View File
@@ -1,9 +1,12 @@
# SPDX-FileCopyrightText: 2016 Citra Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/externals/find-modules")
include(DownloadExternals)
# Dynarmic has cmake_minimum_required(3.12) and we may want to override
# some of its variables, which is only possible in 3.13+
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
# Disable tests in all externals supporting the standard option name
set(BUILD_TESTING OFF)
# xbyak
if ((ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) AND NOT TARGET xbyak::xbyak)
@@ -12,8 +15,7 @@ endif()
# Dynarmic
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) AND NOT TARGET dynarmic::dynarmic)
set(DYNARMIC_NO_BUNDLED_FMT ON)
set(DYNARMIC_IGNORE_ASSERTS ON CACHE BOOL "" FORCE)
set(DYNARMIC_IGNORE_ASSERTS ON)
add_subdirectory(dynarmic EXCLUDE_FROM_ALL)
add_library(dynarmic::dynarmic ALIAS dynarmic)
endif()
@@ -45,7 +47,7 @@ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12" AND CMAKE_CXX_COMPILER
endif()
# libusb
if (NOT TARGET libusb::usb)
if (ENABLE_LIBUSB AND NOT TARGET libusb::usb)
add_subdirectory(libusb EXCLUDE_FROM_ALL)
endif()
@@ -60,10 +62,10 @@ if (YUZU_USE_EXTERNAL_SDL2)
Locale Power Render)
foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS})
string(TOUPPER ${_SUB} _OPT)
option(SDL_${_OPT} "" OFF)
set(SDL_${_OPT} OFF)
endforeach()
option(HIDAPI "" ON)
set(HIDAPI ON)
endif()
set(SDL_STATIC ON)
set(SDL_SHARED OFF)
@@ -83,7 +85,7 @@ endif()
# Cubeb
if (ENABLE_CUBEB AND NOT TARGET cubeb::cubeb)
set(BUILD_TESTS OFF CACHE BOOL "")
set(BUILD_TESTS OFF)
add_subdirectory(cubeb EXCLUDE_FROM_ALL)
add_library(cubeb::cubeb ALIAS cubeb)
endif()
@@ -98,6 +100,7 @@ endif()
# Sirit
add_subdirectory(sirit EXCLUDE_FROM_ALL)
# httplib
if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
if (NOT WIN32)
find_package(OpenSSL 1.1)
@@ -108,7 +111,7 @@ if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
if (WIN32 OR NOT OPENSSL_FOUND)
# LibreSSL
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
set(LIBRESSL_SKIP_INSTALL ON)
set(OPENSSLDIR "/etc/ssl/")
add_subdirectory(libressl EXCLUDE_FROM_ALL)
target_include_directories(ssl INTERFACE ./libressl/include)
@@ -118,7 +121,6 @@ if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
DEFINITION OPENSSL_LIBS)
endif()
# httplib
add_library(httplib INTERFACE)
target_include_directories(httplib INTERFACE ./cpp-httplib)
target_compile_definitions(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
@@ -152,6 +154,13 @@ if (YUZU_USE_BUNDLED_FFMPEG)
endif()
# Vulkan-Headers
if (NOT TARGET Vulkan::Headers)
if (YUZU_USE_EXTERNAL_VULKAN_HEADERS)
add_subdirectory(Vulkan-Headers EXCLUDE_FROM_ALL)
endif()
if (NOT TARGET LLVM::Demangle)
add_library(demangle STATIC)
target_include_directories(demangle PUBLIC ./demangle)
target_sources(demangle PRIVATE demangle/ItaniumDemangle.cpp)
add_library(LLVM::Demangle ALIAS demangle)
endif()
+588
View File
@@ -0,0 +1,588 @@
//===------------------------- ItaniumDemangle.cpp ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// FIXME: (possibly) incomplete list of features that clang mangles that this
// file does not yet support:
// - C++ modules TS
#include "llvm/Demangle/Demangle.h"
#include "llvm/Demangle/ItaniumDemangle.h"
#include <cassert>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <numeric>
#include <utility>
#include <vector>
using namespace llvm;
using namespace llvm::itanium_demangle;
constexpr const char *itanium_demangle::FloatData<float>::spec;
constexpr const char *itanium_demangle::FloatData<double>::spec;
constexpr const char *itanium_demangle::FloatData<long double>::spec;
// <discriminator> := _ <non-negative number> # when number < 10
// := __ <non-negative number> _ # when number >= 10
// extension := decimal-digit+ # at the end of string
const char *itanium_demangle::parse_discriminator(const char *first,
const char *last) {
// parse but ignore discriminator
if (first != last) {
if (*first == '_') {
const char *t1 = first + 1;
if (t1 != last) {
if (std::isdigit(*t1))
first = t1 + 1;
else if (*t1 == '_') {
for (++t1; t1 != last && std::isdigit(*t1); ++t1)
;
if (t1 != last && *t1 == '_')
first = t1 + 1;
}
}
} else if (std::isdigit(*first)) {
const char *t1 = first + 1;
for (; t1 != last && std::isdigit(*t1); ++t1)
;
if (t1 == last)
first = last;
}
}
return first;
}
#ifndef NDEBUG
namespace {
struct DumpVisitor {
unsigned Depth = 0;
bool PendingNewline = false;
template<typename NodeT> static constexpr bool wantsNewline(const NodeT *) {
return true;
}
static bool wantsNewline(NodeArray A) { return !A.empty(); }
static constexpr bool wantsNewline(...) { return false; }
template<typename ...Ts> static bool anyWantNewline(Ts ...Vs) {
for (bool B : {wantsNewline(Vs)...})
if (B)
return true;
return false;
}
void printStr(const char *S) { fprintf(stderr, "%s", S); }
void print(StringView SV) {
fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.begin());
}
void print(const Node *N) {
if (N)
N->visit(std::ref(*this));
else
printStr("<null>");
}
void print(NodeOrString NS) {
if (NS.isNode())
print(NS.asNode());
else if (NS.isString())
print(NS.asString());
else
printStr("NodeOrString()");
}
void print(NodeArray A) {
++Depth;
printStr("{");
bool First = true;
for (const Node *N : A) {
if (First)
print(N);
else
printWithComma(N);
First = false;
}
printStr("}");
--Depth;
}
// Overload used when T is exactly 'bool', not merely convertible to 'bool'.
void print(bool B) { printStr(B ? "true" : "false"); }
template <class T>
typename std::enable_if<std::is_unsigned<T>::value>::type print(T N) {
fprintf(stderr, "%llu", (unsigned long long)N);
}
template <class T>
typename std::enable_if<std::is_signed<T>::value>::type print(T N) {
fprintf(stderr, "%lld", (long long)N);
}
void print(ReferenceKind RK) {
switch (RK) {
case ReferenceKind::LValue:
return printStr("ReferenceKind::LValue");
case ReferenceKind::RValue:
return printStr("ReferenceKind::RValue");
}
}
void print(FunctionRefQual RQ) {
switch (RQ) {
case FunctionRefQual::FrefQualNone:
return printStr("FunctionRefQual::FrefQualNone");
case FunctionRefQual::FrefQualLValue:
return printStr("FunctionRefQual::FrefQualLValue");
case FunctionRefQual::FrefQualRValue:
return printStr("FunctionRefQual::FrefQualRValue");
}
}
void print(Qualifiers Qs) {
if (!Qs) return printStr("QualNone");
struct QualName { Qualifiers Q; const char *Name; } Names[] = {
{QualConst, "QualConst"},
{QualVolatile, "QualVolatile"},
{QualRestrict, "QualRestrict"},
};
for (QualName Name : Names) {
if (Qs & Name.Q) {
printStr(Name.Name);
Qs = Qualifiers(Qs & ~Name.Q);
if (Qs) printStr(" | ");
}
}
}
void print(SpecialSubKind SSK) {
switch (SSK) {
case SpecialSubKind::allocator:
return printStr("SpecialSubKind::allocator");
case SpecialSubKind::basic_string:
return printStr("SpecialSubKind::basic_string");
case SpecialSubKind::string:
return printStr("SpecialSubKind::string");
case SpecialSubKind::istream:
return printStr("SpecialSubKind::istream");
case SpecialSubKind::ostream:
return printStr("SpecialSubKind::ostream");
case SpecialSubKind::iostream:
return printStr("SpecialSubKind::iostream");
}
}
void print(TemplateParamKind TPK) {
switch (TPK) {
case TemplateParamKind::Type:
return printStr("TemplateParamKind::Type");
case TemplateParamKind::NonType:
return printStr("TemplateParamKind::NonType");
case TemplateParamKind::Template:
return printStr("TemplateParamKind::Template");
}
}
void newLine() {
printStr("\n");
for (unsigned I = 0; I != Depth; ++I)
printStr(" ");
PendingNewline = false;
}
template<typename T> void printWithPendingNewline(T V) {
print(V);
if (wantsNewline(V))
PendingNewline = true;
}
template<typename T> void printWithComma(T V) {
if (PendingNewline || wantsNewline(V)) {
printStr(",");
newLine();
} else {
printStr(", ");
}
printWithPendingNewline(V);
}
struct CtorArgPrinter {
DumpVisitor &Visitor;
template<typename T, typename ...Rest> void operator()(T V, Rest ...Vs) {
if (Visitor.anyWantNewline(V, Vs...))
Visitor.newLine();
Visitor.printWithPendingNewline(V);
int PrintInOrder[] = { (Visitor.printWithComma(Vs), 0)..., 0 };
(void)PrintInOrder;
}
};
template<typename NodeT> void operator()(const NodeT *Node) {
Depth += 2;
fprintf(stderr, "%s(", itanium_demangle::NodeKind<NodeT>::name());
Node->match(CtorArgPrinter{*this});
fprintf(stderr, ")");
Depth -= 2;
}
void operator()(const ForwardTemplateReference *Node) {
Depth += 2;
fprintf(stderr, "ForwardTemplateReference(");
if (Node->Ref && !Node->Printing) {
Node->Printing = true;
CtorArgPrinter{*this}(Node->Ref);
Node->Printing = false;
} else {
CtorArgPrinter{*this}(Node->Index);
}
fprintf(stderr, ")");
Depth -= 2;
}
};
}
void itanium_demangle::Node::dump() const {
DumpVisitor V;
visit(std::ref(V));
V.newLine();
}
#endif
namespace {
class BumpPointerAllocator {
struct BlockMeta {
BlockMeta* Next;
size_t Current;
};
static constexpr size_t AllocSize = 4096;
static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta);
alignas(long double) char InitialBuffer[AllocSize];
BlockMeta* BlockList = nullptr;
void grow() {
char* NewMeta = static_cast<char *>(std::malloc(AllocSize));
if (NewMeta == nullptr)
std::terminate();
BlockList = new (NewMeta) BlockMeta{BlockList, 0};
}
void* allocateMassive(size_t NBytes) {
NBytes += sizeof(BlockMeta);
BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(std::malloc(NBytes));
if (NewMeta == nullptr)
std::terminate();
BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0};
return static_cast<void*>(NewMeta + 1);
}
public:
BumpPointerAllocator()
: BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {}
void* allocate(size_t N) {
N = (N + 15u) & ~15u;
if (N + BlockList->Current >= UsableAllocSize) {
if (N > UsableAllocSize)
return allocateMassive(N);
grow();
}
BlockList->Current += N;
return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) +
BlockList->Current - N);
}
void reset() {
while (BlockList) {
BlockMeta* Tmp = BlockList;
BlockList = BlockList->Next;
if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
std::free(Tmp);
}
BlockList = new (InitialBuffer) BlockMeta{nullptr, 0};
}
~BumpPointerAllocator() { reset(); }
};
class DefaultAllocator {
BumpPointerAllocator Alloc;
public:
void reset() { Alloc.reset(); }
template<typename T, typename ...Args> T *makeNode(Args &&...args) {
return new (Alloc.allocate(sizeof(T)))
T(std::forward<Args>(args)...);
}
void *allocateNodeArray(size_t sz) {
return Alloc.allocate(sizeof(Node *) * sz);
}
};
} // unnamed namespace
//===----------------------------------------------------------------------===//
// Code beyond this point should not be synchronized with libc++abi.
//===----------------------------------------------------------------------===//
using Demangler = itanium_demangle::ManglingParser<DefaultAllocator>;
char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
size_t *N, int *Status) {
if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
if (Status)
*Status = demangle_invalid_args;
return nullptr;
}
int InternalStatus = demangle_success;
Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
OutputStream S;
Node *AST = Parser.parse();
if (AST == nullptr)
InternalStatus = demangle_invalid_mangled_name;
else if (!initializeOutputStream(Buf, N, S, 1024))
InternalStatus = demangle_memory_alloc_failure;
else {
assert(Parser.ForwardTemplateRefs.empty());
AST->print(S);
S += '\0';
if (N != nullptr)
*N = S.getCurrentPosition();
Buf = S.getBuffer();
}
if (Status)
*Status = InternalStatus;
return InternalStatus == demangle_success ? Buf : nullptr;
}
ItaniumPartialDemangler::ItaniumPartialDemangler()
: RootNode(nullptr), Context(new Demangler{nullptr, nullptr}) {}
ItaniumPartialDemangler::~ItaniumPartialDemangler() {
delete static_cast<Demangler *>(Context);
}
ItaniumPartialDemangler::ItaniumPartialDemangler(
ItaniumPartialDemangler &&Other)
: RootNode(Other.RootNode), Context(Other.Context) {
Other.Context = Other.RootNode = nullptr;
}
ItaniumPartialDemangler &ItaniumPartialDemangler::
operator=(ItaniumPartialDemangler &&Other) {
std::swap(RootNode, Other.RootNode);
std::swap(Context, Other.Context);
return *this;
}
// Demangle MangledName into an AST, storing it into this->RootNode.
bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) {
Demangler *Parser = static_cast<Demangler *>(Context);
size_t Len = std::strlen(MangledName);
Parser->reset(MangledName, MangledName + Len);
RootNode = Parser->parse();
return RootNode == nullptr;
}
static char *printNode(const Node *RootNode, char *Buf, size_t *N) {
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
RootNode->print(S);
S += '\0';
if (N != nullptr)
*N = S.getCurrentPosition();
return S.getBuffer();
}
char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
if (!isFunction())
return nullptr;
const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
while (true) {
switch (Name->getKind()) {
case Node::KAbiTagAttr:
Name = static_cast<const AbiTagAttr *>(Name)->Base;
continue;
case Node::KStdQualifiedName:
Name = static_cast<const StdQualifiedName *>(Name)->Child;
continue;
case Node::KNestedName:
Name = static_cast<const NestedName *>(Name)->Name;
continue;
case Node::KLocalName:
Name = static_cast<const LocalName *>(Name)->Entity;
continue;
case Node::KNameWithTemplateArgs:
Name = static_cast<const NameWithTemplateArgs *>(Name)->Name;
continue;
default:
return printNode(Name, Buf, N);
}
}
}
char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
size_t *N) const {
if (!isFunction())
return nullptr;
const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
KeepGoingLocalFunction:
while (true) {
if (Name->getKind() == Node::KAbiTagAttr) {
Name = static_cast<const AbiTagAttr *>(Name)->Base;
continue;
}
if (Name->getKind() == Node::KNameWithTemplateArgs) {
Name = static_cast<const NameWithTemplateArgs *>(Name)->Name;
continue;
}
break;
}
switch (Name->getKind()) {
case Node::KStdQualifiedName:
S += "std";
break;
case Node::KNestedName:
static_cast<const NestedName *>(Name)->Qual->print(S);
break;
case Node::KLocalName: {
auto *LN = static_cast<const LocalName *>(Name);
LN->Encoding->print(S);
S += "::";
Name = LN->Entity;
goto KeepGoingLocalFunction;
}
default:
break;
}
S += '\0';
if (N != nullptr)
*N = S.getCurrentPosition();
return S.getBuffer();
}
char *ItaniumPartialDemangler::getFunctionName(char *Buf, size_t *N) const {
if (!isFunction())
return nullptr;
auto *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
return printNode(Name, Buf, N);
}
char *ItaniumPartialDemangler::getFunctionParameters(char *Buf,
size_t *N) const {
if (!isFunction())
return nullptr;
NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
S += '(';
Params.printWithComma(S);
S += ')';
S += '\0';
if (N != nullptr)
*N = S.getCurrentPosition();
return S.getBuffer();
}
char *ItaniumPartialDemangler::getFunctionReturnType(
char *Buf, size_t *N) const {
if (!isFunction())
return nullptr;
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
if (const Node *Ret =
static_cast<const FunctionEncoding *>(RootNode)->getReturnType())
Ret->print(S);
S += '\0';
if (N != nullptr)
*N = S.getCurrentPosition();
return S.getBuffer();
}
char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const {
assert(RootNode != nullptr && "must call partialDemangle()");
return printNode(static_cast<Node *>(RootNode), Buf, N);
}
bool ItaniumPartialDemangler::hasFunctionQualifiers() const {
assert(RootNode != nullptr && "must call partialDemangle()");
if (!isFunction())
return false;
auto *E = static_cast<const FunctionEncoding *>(RootNode);
return E->getCVQuals() != QualNone || E->getRefQual() != FrefQualNone;
}
bool ItaniumPartialDemangler::isCtorOrDtor() const {
const Node *N = static_cast<const Node *>(RootNode);
while (N) {
switch (N->getKind()) {
default:
return false;
case Node::KCtorDtorName:
return true;
case Node::KAbiTagAttr:
N = static_cast<const AbiTagAttr *>(N)->Base;
break;
case Node::KFunctionEncoding:
N = static_cast<const FunctionEncoding *>(N)->getName();
break;
case Node::KLocalName:
N = static_cast<const LocalName *>(N)->Entity;
break;
case Node::KNameWithTemplateArgs:
N = static_cast<const NameWithTemplateArgs *>(N)->Name;
break;
case Node::KNestedName:
N = static_cast<const NestedName *>(N)->Name;
break;
case Node::KStdQualifiedName:
N = static_cast<const StdQualifiedName *>(N)->Child;
break;
}
}
return false;
}
bool ItaniumPartialDemangler::isFunction() const {
assert(RootNode != nullptr && "must call partialDemangle()");
return static_cast<const Node *>(RootNode)->getKind() ==
Node::KFunctionEncoding;
}
bool ItaniumPartialDemangler::isSpecialName() const {
assert(RootNode != nullptr && "must call partialDemangle()");
auto K = static_cast<const Node *>(RootNode)->getKind();
return K == Node::KSpecialName || K == Node::KCtorVtableSpecialName;
}
bool ItaniumPartialDemangler::isData() const {
return !isFunction() && !isSpecialName();
}
+104
View File
@@ -0,0 +1,104 @@
//===--- Demangle.h ---------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEMANGLE_DEMANGLE_H
#define LLVM_DEMANGLE_DEMANGLE_H
#include <cstddef>
#include <string>
namespace llvm {
/// This is a llvm local version of __cxa_demangle. Other than the name and
/// being in the llvm namespace it is identical.
///
/// The mangled_name is demangled into buf and returned. If the buffer is not
/// large enough, realloc is used to expand it.
///
/// The *status will be set to a value from the following enumeration
enum : int {
demangle_unknown_error = -4,
demangle_invalid_args = -3,
demangle_invalid_mangled_name = -2,
demangle_memory_alloc_failure = -1,
demangle_success = 0,
};
char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
int *status);
enum MSDemangleFlags {
MSDF_None = 0,
MSDF_DumpBackrefs = 1 << 0,
MSDF_NoAccessSpecifier = 1 << 1,
MSDF_NoCallingConvention = 1 << 2,
MSDF_NoReturnType = 1 << 3,
MSDF_NoMemberType = 1 << 4,
};
char *microsoftDemangle(const char *mangled_name, char *buf, size_t *n,
int *status, MSDemangleFlags Flags = MSDF_None);
/// "Partial" demangler. This supports demangling a string into an AST
/// (typically an intermediate stage in itaniumDemangle) and querying certain
/// properties or partially printing the demangled name.
struct ItaniumPartialDemangler {
ItaniumPartialDemangler();
ItaniumPartialDemangler(ItaniumPartialDemangler &&Other);
ItaniumPartialDemangler &operator=(ItaniumPartialDemangler &&Other);
/// Demangle into an AST. Subsequent calls to the rest of the member functions
/// implicitly operate on the AST this produces.
/// \return true on error, false otherwise
bool partialDemangle(const char *MangledName);
/// Just print the entire mangled name into Buf. Buf and N behave like the
/// second and third parameters to itaniumDemangle.
char *finishDemangle(char *Buf, size_t *N) const;
/// Get the base name of a function. This doesn't include trailing template
/// arguments, ie for "a::b<int>" this function returns "b".
char *getFunctionBaseName(char *Buf, size_t *N) const;
/// Get the context name for a function. For "a::b::c", this function returns
/// "a::b".
char *getFunctionDeclContextName(char *Buf, size_t *N) const;
/// Get the entire name of this function.
char *getFunctionName(char *Buf, size_t *N) const;
/// Get the parameters for this function.
char *getFunctionParameters(char *Buf, size_t *N) const;
char *getFunctionReturnType(char *Buf, size_t *N) const;
/// If this function has any any cv or reference qualifiers. These imply that
/// the function is a non-static member function.
bool hasFunctionQualifiers() const;
/// If this symbol describes a constructor or destructor.
bool isCtorOrDtor() const;
/// If this symbol describes a function.
bool isFunction() const;
/// If this symbol describes a variable.
bool isData() const;
/// If this symbol is a <special-name>. These are generally implicitly
/// generated by the implementation, such as vtables and typeinfo names.
bool isSpecialName() const;
~ItaniumPartialDemangler();
private:
void *RootNode;
void *Context;
};
} // namespace llvm
#endif
+93
View File
@@ -0,0 +1,93 @@
//===--- DemangleConfig.h ---------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains a variety of feature test macros copied from
// include/llvm/Support/Compiler.h so that LLVMDemangle does not need to take
// a dependency on LLVMSupport.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEMANGLE_COMPILER_H
#define LLVM_DEMANGLE_COMPILER_H
#ifndef __has_feature
#define __has_feature(x) 0
#endif
#ifndef __has_cpp_attribute
#define __has_cpp_attribute(x) 0
#endif
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
#ifndef DEMANGLE_GNUC_PREREQ
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
#define DEMANGLE_GNUC_PREREQ(maj, min, patch) \
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
((maj) << 20) + ((min) << 10) + (patch))
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
#define DEMANGLE_GNUC_PREREQ(maj, min, patch) \
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
#else
#define DEMANGLE_GNUC_PREREQ(maj, min, patch) 0
#endif
#endif
#if __has_attribute(used) || DEMANGLE_GNUC_PREREQ(3, 1, 0)
#define DEMANGLE_ATTRIBUTE_USED __attribute__((__used__))
#else
#define DEMANGLE_ATTRIBUTE_USED
#endif
#if __has_builtin(__builtin_unreachable) || DEMANGLE_GNUC_PREREQ(4, 5, 0)
#define DEMANGLE_UNREACHABLE __builtin_unreachable()
#elif defined(_MSC_VER)
#define DEMANGLE_UNREACHABLE __assume(false)
#else
#define DEMANGLE_UNREACHABLE
#endif
#if __has_attribute(noinline) || DEMANGLE_GNUC_PREREQ(3, 4, 0)
#define DEMANGLE_ATTRIBUTE_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER)
#define DEMANGLE_ATTRIBUTE_NOINLINE __declspec(noinline)
#else
#define DEMANGLE_ATTRIBUTE_NOINLINE
#endif
#if !defined(NDEBUG)
#define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE DEMANGLE_ATTRIBUTE_USED
#else
#define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE
#endif
#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
#define DEMANGLE_FALLTHROUGH [[fallthrough]]
#elif __has_cpp_attribute(gnu::fallthrough)
#define DEMANGLE_FALLTHROUGH [[gnu::fallthrough]]
#elif !__cplusplus
// Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
// error when __has_cpp_attribute is given a scoped attribute in C mode.
#define DEMANGLE_FALLTHROUGH
#elif __has_cpp_attribute(clang::fallthrough)
#define DEMANGLE_FALLTHROUGH [[clang::fallthrough]]
#else
#define DEMANGLE_FALLTHROUGH
#endif
#define DEMANGLE_NAMESPACE_BEGIN namespace llvm { namespace itanium_demangle {
#define DEMANGLE_NAMESPACE_END } }
#endif
File diff suppressed because it is too large Load Diff
+127
View File
@@ -0,0 +1,127 @@
//===--- StringView.h -------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// FIXME: Use std::string_view instead when we support C++17.
//
//===----------------------------------------------------------------------===//
#ifndef DEMANGLE_STRINGVIEW_H
#define DEMANGLE_STRINGVIEW_H
#include "DemangleConfig.h"
#include <algorithm>
#include <cassert>
#include <cstring>
DEMANGLE_NAMESPACE_BEGIN
class StringView {
const char *First;
const char *Last;
public:
static const size_t npos = ~size_t(0);
template <size_t N>
StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
StringView(const char *First_, const char *Last_)
: First(First_), Last(Last_) {}
StringView(const char *First_, size_t Len)
: First(First_), Last(First_ + Len) {}
StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
StringView() : First(nullptr), Last(nullptr) {}
StringView substr(size_t From) const {
return StringView(begin() + From, size() - From);
}
size_t find(char C, size_t From = 0) const {
size_t FindBegin = std::min(From, size());
// Avoid calling memchr with nullptr.
if (FindBegin < size()) {
// Just forward to memchr, which is faster than a hand-rolled loop.
if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin))
return size_t(static_cast<const char *>(P) - First);
}
return npos;
}
StringView substr(size_t From, size_t To) const {
if (To >= size())
To = size() - 1;
if (From >= size())
From = size() - 1;
return StringView(First + From, First + To);
}
StringView dropFront(size_t N = 1) const {
if (N >= size())
N = size();
return StringView(First + N, Last);
}
StringView dropBack(size_t N = 1) const {
if (N >= size())
N = size();
return StringView(First, Last - N);
}
char front() const {
assert(!empty());
return *begin();
}
char back() const {
assert(!empty());
return *(end() - 1);
}
char popFront() {
assert(!empty());
return *First++;
}
bool consumeFront(char C) {
if (!startsWith(C))
return false;
*this = dropFront(1);
return true;
}
bool consumeFront(StringView S) {
if (!startsWith(S))
return false;
*this = dropFront(S.size());
return true;
}
bool startsWith(char C) const { return !empty() && *begin() == C; }
bool startsWith(StringView Str) const {
if (Str.size() > size())
return false;
return std::equal(Str.begin(), Str.end(), begin());
}
const char &operator[](size_t Idx) const { return *(begin() + Idx); }
const char *begin() const { return First; }
const char *end() const { return Last; }
size_t size() const { return static_cast<size_t>(Last - First); }
bool empty() const { return First == Last; }
};
inline bool operator==(const StringView &LHS, const StringView &RHS) {
return LHS.size() == RHS.size() &&
std::equal(LHS.begin(), LHS.end(), RHS.begin());
}
DEMANGLE_NAMESPACE_END
#endif
+192
View File
@@ -0,0 +1,192 @@
//===--- Utility.h ----------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Provide some utility classes for use in the demangler(s).
//
//===----------------------------------------------------------------------===//
#ifndef DEMANGLE_UTILITY_H
#define DEMANGLE_UTILITY_H
#include "StringView.h"
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <iterator>
#include <limits>
DEMANGLE_NAMESPACE_BEGIN
// Stream that AST nodes write their string representation into after the AST
// has been parsed.
class OutputStream {
char *Buffer;
size_t CurrentPosition;
size_t BufferCapacity;
// Ensure there is at least n more positions in buffer.
void grow(size_t N) {
if (N + CurrentPosition >= BufferCapacity) {
BufferCapacity *= 2;
if (BufferCapacity < N + CurrentPosition)
BufferCapacity = N + CurrentPosition;
Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
if (Buffer == nullptr)
std::terminate();
}
}
void writeUnsigned(uint64_t N, bool isNeg = false) {
// Handle special case...
if (N == 0) {
*this << '0';
return;
}
char Temp[21];
char *TempPtr = std::end(Temp);
while (N) {
*--TempPtr = '0' + char(N % 10);
N /= 10;
}
// Add negative sign...
if (isNeg)
*--TempPtr = '-';
this->operator<<(StringView(TempPtr, std::end(Temp)));
}
public:
OutputStream(char *StartBuf, size_t Size)
: Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
OutputStream() = default;
void reset(char *Buffer_, size_t BufferCapacity_) {
CurrentPosition = 0;
Buffer = Buffer_;
BufferCapacity = BufferCapacity_;
}
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
/// into the pack that we're currently printing.
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
OutputStream &operator+=(StringView R) {
size_t Size = R.size();
if (Size == 0)
return *this;
grow(Size);
std::memmove(Buffer + CurrentPosition, R.begin(), Size);
CurrentPosition += Size;
return *this;
}
OutputStream &operator+=(char C) {
grow(1);
Buffer[CurrentPosition++] = C;
return *this;
}
OutputStream &operator<<(StringView R) { return (*this += R); }
OutputStream &operator<<(char C) { return (*this += C); }
OutputStream &operator<<(long long N) {
if (N < 0)
writeUnsigned(static_cast<unsigned long long>(-N), true);
else
writeUnsigned(static_cast<unsigned long long>(N));
return *this;
}
OutputStream &operator<<(unsigned long long N) {
writeUnsigned(N, false);
return *this;
}
OutputStream &operator<<(long N) {
return this->operator<<(static_cast<long long>(N));
}
OutputStream &operator<<(unsigned long N) {
return this->operator<<(static_cast<unsigned long long>(N));
}
OutputStream &operator<<(int N) {
return this->operator<<(static_cast<long long>(N));
}
OutputStream &operator<<(unsigned int N) {
return this->operator<<(static_cast<unsigned long long>(N));
}
size_t getCurrentPosition() const { return CurrentPosition; }
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
char back() const {
return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
}
bool empty() const { return CurrentPosition == 0; }
char *getBuffer() { return Buffer; }
char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
size_t getBufferCapacity() { return BufferCapacity; }
};
template <class T> class SwapAndRestore {
T &Restore;
T OriginalValue;
bool ShouldRestore = true;
public:
SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
SwapAndRestore(T &Restore_, T NewVal)
: Restore(Restore_), OriginalValue(Restore) {
Restore = std::move(NewVal);
}
~SwapAndRestore() {
if (ShouldRestore)
Restore = std::move(OriginalValue);
}
void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
void restoreNow(bool Force) {
if (!Force && !ShouldRestore)
return;
Restore = std::move(OriginalValue);
ShouldRestore = false;
}
SwapAndRestore(const SwapAndRestore &) = delete;
SwapAndRestore &operator=(const SwapAndRestore &) = delete;
};
inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
size_t InitSize) {
size_t BufferSize;
if (Buf == nullptr) {
Buf = static_cast<char *>(std::malloc(InitSize));
if (Buf == nullptr)
return false;
BufferSize = InitSize;
} else
BufferSize = *N;
S.reset(Buf, BufferSize);
return true;
}
DEMANGLE_NAMESPACE_END
#endif
+4 -1
View File
@@ -161,7 +161,10 @@ add_subdirectory(video_core)
add_subdirectory(network)
add_subdirectory(input_common)
add_subdirectory(shader_recompiler)
add_subdirectory(dedicated_room)
if (YUZU_ROOM)
add_subdirectory(dedicated_room)
endif()
if (YUZU_TESTS)
add_subdirectory(tests)
+13 -6
View File
@@ -187,11 +187,7 @@ add_library(audio_core STATIC
renderer/voice/voice_info.cpp
renderer/voice/voice_info.h
renderer/voice/voice_state.h
sink/cubeb_sink.cpp
sink/cubeb_sink.h
sink/null_sink.h
sink/sdl2_sink.cpp
sink/sdl2_sink.h
sink/sink.h
sink/sink_details.cpp
sink/sink_details.h
@@ -222,11 +218,22 @@ if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
target_link_libraries(audio_core PRIVATE dynarmic::dynarmic)
endif()
if(ENABLE_CUBEB)
if (ENABLE_CUBEB)
target_sources(audio_core PRIVATE
sink/cubeb_sink.cpp
sink/cubeb_sink.h
)
target_link_libraries(audio_core PRIVATE cubeb::cubeb)
target_compile_definitions(audio_core PRIVATE -DHAVE_CUBEB=1)
endif()
if(ENABLE_SDL2)
if (ENABLE_SDL2)
target_sources(audio_core PRIVATE
sink/sdl2_sink.cpp
sink/sdl2_sink.h
)
target_link_libraries(audio_core PRIVATE SDL2::SDL2)
target_compile_definitions(audio_core PRIVATE HAVE_SDL2)
endif()
@@ -4,6 +4,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/biquad_filter.h"
#include "audio_core/renderer/voice/voice_state.h"
#include "common/bit_cast.h"
namespace AudioCore::AudioRenderer {
/**
@@ -19,21 +20,21 @@ namespace AudioCore::AudioRenderer {
void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
std::array<s16, 3>& b_, std::array<s16, 2>& a_,
VoiceState::BiquadFilterState& state, const u32 sample_count) {
constexpr s64 min{std::numeric_limits<s32>::min()};
constexpr s64 max{std::numeric_limits<s32>::max()};
constexpr f64 min{std::numeric_limits<s32>::min()};
constexpr f64 max{std::numeric_limits<s32>::max()};
std::array<f64, 3> b{Common::FixedPoint<50, 14>::from_base(b_[0]).to_double(),
Common::FixedPoint<50, 14>::from_base(b_[1]).to_double(),
Common::FixedPoint<50, 14>::from_base(b_[2]).to_double()};
std::array<f64, 2> a{Common::FixedPoint<50, 14>::from_base(a_[0]).to_double(),
Common::FixedPoint<50, 14>::from_base(a_[1]).to_double()};
std::array<f64, 4> s{state.s0.to_double(), state.s1.to_double(), state.s2.to_double(),
state.s3.to_double()};
std::array<f64, 4> s{Common::BitCast<f64>(state.s0), Common::BitCast<f64>(state.s1),
Common::BitCast<f64>(state.s2), Common::BitCast<f64>(state.s3)};
for (u32 i = 0; i < sample_count; i++) {
f64 in_sample{static_cast<f64>(input[i])};
auto sample{in_sample * b[0] + s[0] * b[1] + s[1] * b[2] + s[2] * a[0] + s[3] * a[1]};
output[i] = static_cast<s32>(std::clamp(static_cast<s64>(sample), min, max));
output[i] = static_cast<s32>(std::clamp(sample, min, max));
s[1] = s[0];
s[0] = in_sample;
@@ -41,10 +42,10 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
s[2] = sample;
}
state.s0 = s[0];
state.s1 = s[1];
state.s2 = s[2];
state.s3 = s[3];
state.s0 = Common::BitCast<s64>(s[0]);
state.s1 = Common::BitCast<s64>(s[1]);
state.s2 = Common::BitCast<s64>(s[2]);
state.s3 = Common::BitCast<s64>(s[3]);
}
/**
@@ -58,29 +59,20 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
* @param sample_count - Number of samples to process.
*/
static void ApplyBiquadFilterInt(std::span<s32> output, std::span<const s32> input,
std::array<s16, 3>& b_, std::array<s16, 2>& a_,
std::array<s16, 3>& b, std::array<s16, 2>& a,
VoiceState::BiquadFilterState& state, const u32 sample_count) {
constexpr s64 min{std::numeric_limits<s32>::min()};
constexpr s64 max{std::numeric_limits<s32>::max()};
std::array<Common::FixedPoint<50, 14>, 3> b{
Common::FixedPoint<50, 14>::from_base(b_[0]),
Common::FixedPoint<50, 14>::from_base(b_[1]),
Common::FixedPoint<50, 14>::from_base(b_[2]),
};
std::array<Common::FixedPoint<50, 14>, 3> a{
Common::FixedPoint<50, 14>::from_base(a_[0]),
Common::FixedPoint<50, 14>::from_base(a_[1]),
};
for (u32 i = 0; i < sample_count; i++) {
s64 in_sample{input[i]};
auto sample{in_sample * b[0] + state.s0};
const auto out_sample{std::clamp(sample.to_long(), min, max)};
const s64 in_sample{input[i]};
const s64 sample{in_sample * b[0] + state.s0};
const s64 out_sample{std::clamp<s64>((sample + (1 << 13)) >> 14, min, max)};
output[i] = static_cast<s32>(out_sample);
state.s0 = state.s1 + b[1] * in_sample + a[0] * out_sample;
state.s1 = 0 + b[2] * in_sample + a[1] * out_sample;
state.s1 = b[2] * in_sample + a[1] * out_sample;
}
}
@@ -20,25 +20,25 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
const u32 target_sample_count, const u32 source_sample_count,
UpsamplerState* state) {
constexpr u32 WindowSize = 10;
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow1{
51.93359375f, -18.80078125f, 9.73046875f, -5.33203125f, 2.84375f,
-1.41015625f, 0.62109375f, -0.2265625f, 0.0625f, -0.00390625f,
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc1{
0.95376587f, -0.12872314f, 0.060028076f, -0.032470703f, 0.017669678f,
-0.009124756f, 0.004272461f, -0.001739502f, 0.000579834f, -0.000091552734f,
};
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow2{
105.35546875f, -24.52734375f, 11.9609375f, -6.515625f, 3.52734375f,
-1.796875f, 0.828125f, -0.32421875f, 0.1015625f, -0.015625f,
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc2{
0.8230896f, -0.19161987f, 0.093444824f, -0.05090332f, 0.027557373f,
-0.014038086f, 0.0064697266f, -0.002532959f, 0.00079345703f, -0.00012207031f,
};
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow3{
122.08203125f, -16.47656250f, 7.68359375f, -4.15625000f, 2.26171875f,
-1.16796875f, 0.54687500f, -0.22265625f, 0.07421875f, -0.01171875f,
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc3{
0.6298828f, -0.19274902f, 0.09725952f, -0.05319214f, 0.028625488f,
-0.014373779f, 0.006500244f, -0.0024719238f, 0.0007324219f, -0.000091552734f,
};
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow4{
23.73437500f, -9.62109375f, 5.07812500f, -2.78125000f, 1.46875000f,
-0.71484375f, 0.30859375f, -0.10546875f, 0.02734375f, 0.00000000f,
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc4{
0.4057312f, -0.1468811f, 0.07601929f, -0.041656494f, 0.022216797f,
-0.011016846f, 0.004852295f, -0.0017700195f, 0.00048828125f, -0.000030517578f,
};
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow5{
80.62500000f, -24.67187500f, 12.44921875f, -6.80859375f, 3.66406250f,
-1.83984375f, 0.83203125f, -0.31640625f, 0.09375000f, -0.01171875f,
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc5{
0.1854248f, -0.075164795f, 0.03967285f, -0.021728516f, 0.011474609f,
-0.005584717f, 0.0024108887f, -0.0008239746f, 0.00021362305f, 0.0f,
};
if (!state->initialized) {
@@ -91,52 +91,31 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
static_cast<u16>((state->history_output_index + 1) % UpsamplerState::HistorySize);
};
auto calculate_sample = [&state](std::span<const Common::FixedPoint<24, 8>> coeffs1,
std::span<const Common::FixedPoint<24, 8>> coeffs2) -> s32 {
auto calculate_sample = [&state](std::span<const Common::FixedPoint<17, 15>> coeffs1,
std::span<const Common::FixedPoint<17, 15>> coeffs2) -> s32 {
auto output_index{state->history_output_index};
auto start_pos{output_index - state->history_start_index + 1U};
auto end_pos{10U};
u64 result{0};
if (start_pos < 10) {
end_pos = start_pos;
}
for (u32 coeff_index = 0; coeff_index < 10; coeff_index++) {
result += static_cast<u64>(state->history[output_index].to_raw()) *
coeffs1[coeff_index].to_raw();
u64 prev_contrib{0};
u32 coeff_index{0};
for (; coeff_index < end_pos; coeff_index++, output_index--) {
prev_contrib += static_cast<u64>(state->history[output_index].to_raw()) *
coeffs1[coeff_index].to_raw();
}
auto end_index{state->history_end_index};
for (; start_pos < 9; start_pos++, coeff_index++, end_index--) {
prev_contrib += static_cast<u64>(state->history[end_index].to_raw()) *
coeffs1[coeff_index].to_raw();
output_index = output_index == state->history_start_index ? state->history_end_index
: output_index - 1;
}
output_index =
static_cast<u16>((state->history_output_index + 1) % UpsamplerState::HistorySize);
start_pos = state->history_end_index - output_index + 1U;
end_pos = 10U;
if (start_pos < 10) {
end_pos = start_pos;
for (u32 coeff_index = 0; coeff_index < 10; coeff_index++) {
result += static_cast<u64>(state->history[output_index].to_raw()) *
coeffs2[coeff_index].to_raw();
output_index = output_index == state->history_end_index ? state->history_start_index
: output_index + 1;
}
u64 next_contrib{0};
coeff_index = 0;
for (; coeff_index < end_pos; coeff_index++, output_index++) {
next_contrib += static_cast<u64>(state->history[output_index].to_raw()) *
coeffs2[coeff_index].to_raw();
}
auto start_index{state->history_start_index};
for (; start_pos < 9; start_pos++, start_index++, coeff_index++) {
next_contrib += static_cast<u64>(state->history[start_index].to_raw()) *
coeffs2[coeff_index].to_raw();
}
return static_cast<s32>(((prev_contrib >> 15) + (next_contrib >> 15)) >> 8);
return static_cast<s32>(result >> (8 + 15));
};
switch (state->ratio.to_int_floor()) {
@@ -150,23 +129,23 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
break;
case 1:
output[write_index] = calculate_sample(SincWindow3, SincWindow4);
output[write_index] = calculate_sample(WindowedSinc1, WindowedSinc5);
break;
case 2:
output[write_index] = calculate_sample(SincWindow2, SincWindow1);
output[write_index] = calculate_sample(WindowedSinc2, WindowedSinc4);
break;
case 3:
output[write_index] = calculate_sample(SincWindow5, SincWindow5);
output[write_index] = calculate_sample(WindowedSinc3, WindowedSinc3);
break;
case 4:
output[write_index] = calculate_sample(SincWindow1, SincWindow2);
output[write_index] = calculate_sample(WindowedSinc4, WindowedSinc2);
break;
case 5:
output[write_index] = calculate_sample(SincWindow4, SincWindow3);
output[write_index] = calculate_sample(WindowedSinc5, WindowedSinc1);
break;
}
state->sample_index = static_cast<u8>((state->sample_index + 1) % 6);
@@ -183,11 +162,11 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
break;
case 1:
output[write_index] = calculate_sample(SincWindow2, SincWindow1);
output[write_index] = calculate_sample(WindowedSinc2, WindowedSinc4);
break;
case 2:
output[write_index] = calculate_sample(SincWindow1, SincWindow2);
output[write_index] = calculate_sample(WindowedSinc4, WindowedSinc2);
break;
}
state->sample_index = static_cast<u8>((state->sample_index + 1) % 3);
@@ -204,12 +183,12 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
break;
case 1:
output[write_index] = calculate_sample(SincWindow1, SincWindow2);
output[write_index] = calculate_sample(WindowedSinc4, WindowedSinc2);
break;
case 2:
increment();
output[write_index] = calculate_sample(SincWindow2, SincWindow1);
output[write_index] = calculate_sample(WindowedSinc2, WindowedSinc4);
break;
}
state->sample_index = static_cast<u8>((state->sample_index + 1) % 3);
+4 -4
View File
@@ -19,10 +19,10 @@ struct VoiceState {
* State of the voice's biquad filter.
*/
struct BiquadFilterState {
Common::FixedPoint<50, 14> s0;
Common::FixedPoint<50, 14> s1;
Common::FixedPoint<50, 14> s2;
Common::FixedPoint<50, 14> s3;
s64 s0;
s64 s1;
s64 s2;
s64 s3;
};
/**
+20
View File
@@ -302,11 +302,21 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
std::vector<std::string> device_list;
cubeb* ctx;
#ifdef _WIN32
auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif
if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
return {};
}
#ifdef _WIN32
if (SUCCEEDED(com_init_result)) {
CoUninitialize();
}
#endif
auto type{capture ? CUBEB_DEVICE_TYPE_INPUT : CUBEB_DEVICE_TYPE_OUTPUT};
cubeb_device_collection collection;
if (cubeb_enumerate_devices(ctx, type, &collection) != CUBEB_OK) {
@@ -329,12 +339,22 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
u32 GetCubebLatency() {
cubeb* ctx;
#ifdef _WIN32
auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif
if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
// Return a large latency so we choose SDL instead.
return 10000u;
}
#ifdef _WIN32
if (SUCCEEDED(com_init_result)) {
CoUninitialize();
}
#endif
cubeb_stream_params params{};
params.rate = TargetSampleRate;
params.channels = 2;
+6 -1
View File
@@ -38,6 +38,8 @@ add_library(common STATIC
common_precompiled_headers.h
common_types.h
concepts.h
demangle.cpp
demangle.h
div_ceil.h
dynamic_library.cpp
dynamic_library.h
@@ -78,6 +80,7 @@ add_library(common STATIC
logging/types.h
lz4_compression.cpp
lz4_compression.h
make_unique_for_overwrite.h
math_util.h
memory_detect.cpp
memory_detect.h
@@ -96,11 +99,13 @@ add_library(common STATIC
point.h
precompiled_headers.h
quaternion.h
range_map.h
reader_writer_queue.h
ring_buffer.h
${CMAKE_CURRENT_BINARY_DIR}/scm_rev.cpp
scm_rev.h
scope_exit.h
scratch_buffer.h
settings.cpp
settings.h
settings_input.cpp
@@ -172,7 +177,7 @@ endif()
create_target_directory_groups(common)
target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile Threads::Threads)
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd)
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle)
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(common PRIVATE precompiled_headers.h)
+4 -3
View File
@@ -12,7 +12,8 @@
namespace Common {
template <typename VaType, size_t AddressSpaceBits>
concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >= AddressSpaceBits;
concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >=
AddressSpaceBits;
struct EmptyStruct {};
@@ -21,7 +22,7 @@ struct EmptyStruct {};
*/
template <typename VaType, VaType UnmappedVa, typename PaType, PaType UnmappedPa,
bool PaContigSplit, size_t AddressSpaceBits, typename ExtraBlockInfo = EmptyStruct>
requires AddressSpaceValid<VaType, AddressSpaceBits>
requires AddressSpaceValid<VaType, AddressSpaceBits>
class FlatAddressSpaceMap {
public:
/// The maximum VA that this AS can technically reach
@@ -109,7 +110,7 @@ private:
* initial, fast linear pass and a subsequent slower pass that iterates until it finds a free block
*/
template <typename VaType, VaType UnmappedVa, size_t AddressSpaceBits>
requires AddressSpaceValid<VaType, AddressSpaceBits>
requires AddressSpaceValid<VaType, AddressSpaceBits>
class FlatAllocator
: public FlatAddressSpaceMap<VaType, UnmappedVa, bool, false, false, AddressSpaceBits> {
private:
+9 -9
View File
@@ -10,7 +10,7 @@
namespace Common {
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignUp(T value, size_t size) {
auto mod{static_cast<T>(value % size)};
value -= mod;
@@ -18,31 +18,31 @@ requires std::is_unsigned_v<T>
}
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignUpLog2(T value, size_t align_log2) {
return static_cast<T>((value + ((1ULL << align_log2) - 1)) >> align_log2 << align_log2);
}
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignDown(T value, size_t size) {
return static_cast<T>(value - value % size);
}
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool Is4KBAligned(T value) {
return (value & 0xFFF) == 0;
}
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool IsWordAligned(T value) {
return (value & 0b11) == 0;
}
template <typename T>
requires std::is_integral_v<T>
requires std::is_integral_v<T>
[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) {
using U = typename std::make_unsigned_t<T>;
const U mask = static_cast<U>(alignment - 1);
@@ -50,7 +50,7 @@ requires std::is_integral_v<T>
}
template <typename T, typename U>
requires std::is_integral_v<T>
requires std::is_integral_v<T>
[[nodiscard]] constexpr T DivideUp(T x, U y) {
return (x + (y - 1)) / y;
}
@@ -73,11 +73,11 @@ public:
constexpr AlignmentAllocator(const AlignmentAllocator<T2, Align>&) noexcept {}
[[nodiscard]] T* allocate(size_type n) {
return static_cast<T*>(::operator new (n * sizeof(T), std::align_val_t{Align}));
return static_cast<T*>(::operator new(n * sizeof(T), std::align_val_t{Align}));
}
void deallocate(T* p, size_type n) {
::operator delete (p, n * sizeof(T), std::align_val_t{Align});
::operator delete(p, n * sizeof(T), std::align_val_t{Align});
}
template <typename T2>
+1 -1
View File
@@ -75,7 +75,7 @@ extern "C" void AnnotateHappensAfter(const char*, int, void*);
#if defined(AE_VCPP) || defined(AE_ICC)
#define AE_FORCEINLINE __forceinline
#elif defined(AE_GCC)
//#define AE_FORCEINLINE __attribute__((always_inline))
// #define AE_FORCEINLINE __attribute__((always_inline))
#define AE_FORCEINLINE inline
#else
#define AE_FORCEINLINE inline
+3 -3
View File
@@ -45,19 +45,19 @@ template <typename T>
}
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool IsPow2(T value) {
return std::has_single_bit(value);
}
template <typename T>
requires std::is_integral_v<T>
requires std::is_integral_v<T>
[[nodiscard]] T NextPow2(T value) {
return static_cast<T>(1ULL << ((8U * sizeof(T)) - std::countl_zero(value - 1U)));
}
template <size_t bit_index, typename T>
requires std::is_integral_v<T>
requires std::is_integral_v<T>
[[nodiscard]] constexpr bool Bit(const T value) {
static_assert(bit_index < BitSize<T>(), "bit_index must be smaller than size of T");
return ((value >> bit_index) & T(1)) == T(1);
+3 -3
View File
@@ -16,9 +16,9 @@ concept IsContiguousContainer = std::contiguous_iterator<typename T::iterator>;
// is available on all supported platforms.
template <typename Derived, typename Base>
concept DerivedFrom = requires {
std::is_base_of_v<Base, Derived>;
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
};
std::is_base_of_v<Base, Derived>;
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
};
// TODO: Replace with std::convertible_to when libc++ implements it.
template <typename From, typename To>
+35
View File
@@ -0,0 +1,35 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <llvm/Demangle/Demangle.h>
#include "common/demangle.h"
#include "common/scope_exit.h"
namespace Common {
std::string DemangleSymbol(const std::string& mangled) {
auto is_itanium = [](const std::string& name) -> bool {
// A valid Itanium encoding requires 1-4 leading underscores, followed by 'Z'.
auto pos = name.find_first_not_of('_');
return pos > 0 && pos <= 4 && pos < name.size() && name[pos] == 'Z';
};
if (mangled.empty()) {
return mangled;
}
char* demangled = nullptr;
SCOPE_EXIT({ std::free(demangled); });
if (is_itanium(mangled)) {
demangled = llvm::itaniumDemangle(mangled.c_str(), nullptr, nullptr, nullptr);
}
if (!demangled) {
return mangled;
}
return demangled;
}
} // namespace Common
+12
View File
@@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <string>
namespace Common {
std::string DemangleSymbol(const std::string& mangled);
} // namespace Common
+2 -2
View File
@@ -10,14 +10,14 @@ namespace Common {
/// Ceiled integer division.
template <typename N, typename D>
requires std::is_integral_v<N> && std::is_unsigned_v<D>
requires std::is_integral_v<N> && std::is_unsigned_v<D>
[[nodiscard]] constexpr N DivCeil(N number, D divisor) {
return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor);
}
/// Ceiled integer division with logarithmic divisor in base 2
template <typename N, typename D>
requires std::is_integral_v<N> && std::is_unsigned_v<D>
requires std::is_integral_v<N> && std::is_unsigned_v<D>
[[nodiscard]] constexpr N DivCeilLog2(N value, D alignment_log2) {
return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2);
}
+30 -30
View File
@@ -64,7 +64,7 @@ struct no_init_t {
* Additionally, this requires E to be trivially destructible
*/
template <typename T, typename E, bool = std::is_trivially_destructible_v<T>>
requires std::is_trivially_destructible_v<E>
requires std::is_trivially_destructible_v<E>
struct expected_storage_base {
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
@@ -111,7 +111,7 @@ struct expected_storage_base {
* Additionally, this requires E to be trivially destructible
*/
template <typename T, typename E>
requires std::is_trivially_destructible_v<E>
requires std::is_trivially_destructible_v<E>
struct expected_storage_base<T, E, true> {
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
@@ -251,7 +251,7 @@ struct expected_operations_base : expected_storage_base<T, E> {
* Additionally, this requires E to be trivially copy constructible
*/
template <typename T, typename E, bool = std::is_trivially_copy_constructible_v<T>>
requires std::is_trivially_copy_constructible_v<E>
requires std::is_trivially_copy_constructible_v<E>
struct expected_copy_base : expected_operations_base<T, E> {
using expected_operations_base<T, E>::expected_operations_base;
};
@@ -261,7 +261,7 @@ struct expected_copy_base : expected_operations_base<T, E> {
* Additionally, this requires E to be trivially copy constructible
*/
template <typename T, typename E>
requires std::is_trivially_copy_constructible_v<E>
requires std::is_trivially_copy_constructible_v<E>
struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
using expected_operations_base<T, E>::expected_operations_base;
@@ -289,7 +289,7 @@ struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
* Additionally, this requires E to be trivially move constructible
*/
template <typename T, typename E, bool = std::is_trivially_move_constructible_v<T>>
requires std::is_trivially_move_constructible_v<E>
requires std::is_trivially_move_constructible_v<E>
struct expected_move_base : expected_copy_base<T, E> {
using expected_copy_base<T, E>::expected_copy_base;
};
@@ -299,7 +299,7 @@ struct expected_move_base : expected_copy_base<T, E> {
* Additionally, this requires E to be trivially move constructible
*/
template <typename T, typename E>
requires std::is_trivially_move_constructible_v<E>
requires std::is_trivially_move_constructible_v<E>
struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
using expected_copy_base<T, E>::expected_copy_base;
@@ -330,9 +330,9 @@ template <typename T, typename E,
bool = std::conjunction_v<std::is_trivially_copy_assignable<T>,
std::is_trivially_copy_constructible<T>,
std::is_trivially_destructible<T>>>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_copy_assign_base : expected_move_base<T, E> {
using expected_move_base<T, E>::expected_move_base;
};
@@ -342,9 +342,9 @@ struct expected_copy_assign_base : expected_move_base<T, E> {
* Additionally, this requires E to be trivially copy assignable
*/
template <typename T, typename E>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> {
using expected_move_base<T, E>::expected_move_base;
@@ -371,9 +371,9 @@ template <typename T, typename E,
bool = std::conjunction_v<std::is_trivially_move_assignable<T>,
std::is_trivially_move_constructible<T>,
std::is_trivially_destructible<T>>>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_move_assign_base : expected_copy_assign_base<T, E> {
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
};
@@ -383,9 +383,9 @@ struct expected_move_assign_base : expected_copy_assign_base<T, E> {
* Additionally, this requires E to be trivially move assignable
*/
template <typename T, typename E>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E> {
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
@@ -412,7 +412,7 @@ struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E>
*/
template <typename T, typename E, bool EnableCopy = std::is_copy_constructible_v<T>,
bool EnableMove = std::is_move_constructible_v<T>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
@@ -422,7 +422,7 @@ struct expected_delete_ctor_base {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, true, false> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
@@ -432,7 +432,7 @@ struct expected_delete_ctor_base<T, E, true, false> {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, false, true> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
@@ -442,7 +442,7 @@ struct expected_delete_ctor_base<T, E, false, true> {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, false, false> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
@@ -460,8 +460,8 @@ template <
typename T, typename E,
bool EnableCopy = std::conjunction_v<std::is_copy_constructible<T>, std::is_copy_assignable<T>>,
bool EnableMove = std::conjunction_v<std::is_move_constructible<T>, std::is_move_assignable<T>>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
@@ -471,8 +471,8 @@ struct expected_delete_assign_base {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, true, false> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
@@ -482,8 +482,8 @@ struct expected_delete_assign_base<T, E, true, false> {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, false, true> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
@@ -493,8 +493,8 @@ struct expected_delete_assign_base<T, E, false, true> {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, false, false> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
+17 -2
View File
@@ -393,12 +393,27 @@ public:
}
// Virtual memory initialization
virtual_base = static_cast<u8*>(
mmap(nullptr, virtual_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
#if defined(__FreeBSD__)
virtual_base =
static_cast<u8*>(mmap(nullptr, virtual_size, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER, -1, 0));
if (virtual_base == MAP_FAILED) {
virtual_base = static_cast<u8*>(
mmap(nullptr, virtual_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
if (virtual_base == MAP_FAILED) {
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
throw std::bad_alloc{};
}
}
#else
virtual_base = static_cast<u8*>(mmap(nullptr, virtual_size, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0));
if (virtual_base == MAP_FAILED) {
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
throw std::bad_alloc{};
}
madvise(virtual_base, virtual_size, MADV_HUGEPAGE);
#endif
good = true;
}
+43 -30
View File
@@ -51,6 +51,8 @@ enum class PollingMode {
NFC,
// Enable infrared camera polling
IR,
// Enable ring controller polling
Ring,
};
enum class CameraFormat {
@@ -62,21 +64,22 @@ enum class CameraFormat {
None,
};
// Vibration reply from the controller
enum class VibrationError {
None,
// Different results that can happen from a device request
enum class DriverResult {
Success,
WrongReply,
Timeout,
UnsupportedControllerType,
HandleInUse,
ErrorReadingData,
ErrorWritingData,
NoDeviceDetected,
InvalidHandle,
NotSupported,
Disabled,
Unknown,
};
// Polling mode reply from the controller
enum class PollingError {
None,
NotSupported,
Unknown,
};
// Nfc reply from the controller
enum class NfcState {
Success,
@@ -90,13 +93,6 @@ enum class NfcState {
Unknown,
};
// Ir camera reply from the controller
enum class CameraError {
None,
NotSupported,
Unknown,
};
// Hint for amplification curve to be used
enum class VibrationAmplificationType {
Linear,
@@ -134,6 +130,8 @@ struct ButtonStatus {
bool inverted{};
// Press once to activate, press again to release
bool toggle{};
// Spams the button when active
bool turbo{};
// Internal lock for the toggle status
bool locked{};
};
@@ -190,6 +188,8 @@ struct TouchStatus {
struct BodyColorStatus {
u32 body{};
u32 buttons{};
u32 left_grip{};
u32 right_grip{};
};
// HD rumble data
@@ -228,17 +228,31 @@ enum class ButtonNames {
Engine,
// This will display the button by value instead of the button name
Value,
// Joycon button names
ButtonLeft,
ButtonRight,
ButtonDown,
ButtonUp,
TriggerZ,
TriggerR,
TriggerL,
ButtonA,
ButtonB,
ButtonX,
ButtonY,
ButtonPlus,
ButtonMinus,
ButtonHome,
ButtonCapture,
ButtonStickL,
ButtonStickR,
TriggerL,
TriggerZL,
TriggerSL,
TriggerR,
TriggerZR,
TriggerSR,
// GC button names
TriggerZ,
ButtonStart,
// DS4 button names
@@ -292,9 +306,6 @@ class InputDevice {
public:
virtual ~InputDevice() = default;
// Request input device to update if necessary
virtual void SoftUpdate() {}
// Force input device to update data regardless of the current state
virtual void ForceUpdate() {}
@@ -319,22 +330,24 @@ class OutputDevice {
public:
virtual ~OutputDevice() = default;
virtual void SetLED([[maybe_unused]] const LedStatus& led_status) {}
virtual DriverResult SetLED([[maybe_unused]] const LedStatus& led_status) {
return DriverResult::NotSupported;
}
virtual VibrationError SetVibration([[maybe_unused]] const VibrationStatus& vibration_status) {
return VibrationError::NotSupported;
virtual DriverResult SetVibration([[maybe_unused]] const VibrationStatus& vibration_status) {
return DriverResult::NotSupported;
}
virtual bool IsVibrationEnabled() {
return false;
}
virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
return PollingError::NotSupported;
virtual DriverResult SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
return DriverResult::NotSupported;
}
virtual CameraError SetCameraFormat([[maybe_unused]] CameraFormat camera_format) {
return CameraError::NotSupported;
virtual DriverResult SetCameraFormat([[maybe_unused]] CameraFormat camera_format) {
return DriverResult::NotSupported;
}
virtual NfcState SupportsNfc() const {
+11 -9
View File
@@ -242,19 +242,21 @@ public:
template <typename T>
concept HasRedBlackKeyType = requires {
{ std::is_same<typename T::RedBlackKeyType, void>::value } -> std::convertible_to<bool>;
};
{
std::is_same<typename T::RedBlackKeyType, void>::value
} -> std::convertible_to<bool>;
};
namespace impl {
template <typename T, typename Default>
consteval auto* GetRedBlackKeyType() {
if constexpr (HasRedBlackKeyType<T>) {
return static_cast<typename T::RedBlackKeyType*>(nullptr);
} else {
return static_cast<Default*>(nullptr);
}
template <typename T, typename Default>
consteval auto* GetRedBlackKeyType() {
if constexpr (HasRedBlackKeyType<T>) {
return static_cast<typename T::RedBlackKeyType*>(nullptr);
} else {
return static_cast<Default*>(nullptr);
}
}
} // namespace impl
+27
View File
@@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include <type_traits>
namespace Common {
template <class T>
requires(!std::is_array_v<T>)
std::unique_ptr<T> make_unique_for_overwrite() {
return std::unique_ptr<T>(new T);
}
template <class T>
requires std::is_unbounded_array_v<T>
std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) {
return std::unique_ptr<T>(new std::remove_extent_t<T>[n]);
}
template <class T, class... Args>
requires std::is_bounded_array_v<T>
void make_unique_for_overwrite(Args&&...) = delete;
} // namespace Common
+4 -4
View File
@@ -18,9 +18,9 @@ namespace ranges {
template <typename T>
concept range = requires(T& t) {
begin(t);
end(t);
};
begin(t);
end(t);
};
template <typename T>
concept input_range = range<T>;
@@ -421,7 +421,7 @@ struct generate_fn {
}
template <typename R, std::copy_constructible F>
requires std::invocable<F&> && ranges::output_range<R>
requires std::invocable<F&> && ranges::output_range<R>
constexpr ranges::iterator_t<R> operator()(R&& r, F gen) const {
return operator()(ranges::begin(r), ranges::end(r), std::move(gen));
}
+86 -41
View File
@@ -11,6 +11,8 @@
#ifdef __cpp_lib_jthread
#include <chrono>
#include <condition_variable>
#include <stop_token>
#include <thread>
@@ -21,23 +23,36 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred&& pred) {
cv.wait(lock, token, std::move(pred));
}
template <typename Rep, typename Period>
bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
std::condition_variable_any cv;
std::mutex m;
// Perform the timed wait.
std::unique_lock lk{m};
return !cv.wait_for(lk, token, rel_time, [&] { return token.stop_requested(); });
}
} // namespace Common
#else
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <thread>
#include <type_traits>
#include <utility>
namespace std {
namespace polyfill {
using stop_state_callbacks = list<function<void()>>;
using stop_state_callback = size_t;
class stop_state {
public:
@@ -45,61 +60,69 @@ public:
~stop_state() = default;
bool request_stop() {
stop_state_callbacks callbacks;
unique_lock lk{m_lock};
{
scoped_lock lk{m_lock};
if (m_stop_requested.load()) {
// Already set, nothing to do
return false;
}
// Set as requested
m_stop_requested = true;
// Copy callback list
callbacks = m_callbacks;
if (m_stop_requested) {
// Already set, nothing to do.
return false;
}
for (auto callback : callbacks) {
callback();
// Mark stop requested.
m_stop_requested = true;
while (!m_callbacks.empty()) {
// Get an iterator to the first element.
const auto it = m_callbacks.begin();
// Move the callback function out of the map.
function<void()> f;
swap(it->second, f);
// Erase the now-empty map element.
m_callbacks.erase(it);
// Run the callback.
if (f) {
f();
}
}
return true;
}
bool stop_requested() const {
return m_stop_requested.load();
unique_lock lk{m_lock};
return m_stop_requested;
}
stop_state_callbacks::const_iterator insert_callback(function<void()> f) {
stop_state_callbacks::const_iterator ret{};
bool should_run{};
stop_state_callback insert_callback(function<void()> f) {
unique_lock lk{m_lock};
{
scoped_lock lk{m_lock};
should_run = m_stop_requested.load();
m_callbacks.push_front(f);
ret = m_callbacks.begin();
}
if (should_run) {
f();
if (m_stop_requested) {
// Stop already requested. Don't insert anything,
// just run the callback synchronously.
if (f) {
f();
}
return 0;
}
// Insert the callback.
stop_state_callback ret = ++m_next_callback;
m_callbacks.emplace(ret, move(f));
return ret;
}
void remove_callback(stop_state_callbacks::const_iterator it) {
scoped_lock lk{m_lock};
m_callbacks.erase(it);
void remove_callback(stop_state_callback cb) {
unique_lock lk{m_lock};
m_callbacks.erase(cb);
}
private:
mutex m_lock;
atomic<bool> m_stop_requested;
stop_state_callbacks m_callbacks;
mutable recursive_mutex m_lock;
map<stop_state_callback, function<void()>> m_callbacks;
stop_state_callback m_next_callback{0};
bool m_stop_requested{false};
};
} // namespace polyfill
@@ -190,7 +213,7 @@ public:
using callback_type = Callback;
template <typename C>
requires constructible_from<Callback, C>
requires constructible_from<Callback, C>
explicit stop_callback(const stop_token& st,
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
: m_stop_state(st.m_stop_state) {
@@ -199,7 +222,7 @@ public:
}
}
template <typename C>
requires constructible_from<Callback, C>
requires constructible_from<Callback, C>
explicit stop_callback(stop_token&& st,
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
: m_stop_state(move(st.m_stop_state)) {
@@ -209,7 +232,7 @@ public:
}
~stop_callback() {
if (m_stop_state && m_callback) {
m_stop_state->remove_callback(*m_callback);
m_stop_state->remove_callback(m_callback);
}
}
@@ -220,7 +243,7 @@ public:
private:
shared_ptr<polyfill::stop_state> m_stop_state;
optional<polyfill::stop_state_callbacks::const_iterator> m_callback;
polyfill::stop_state_callback m_callback;
};
template <typename Callback>
@@ -318,6 +341,28 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred pred) {
cv.wait(lock, [&] { return pred() || token.stop_requested(); });
}
template <typename Rep, typename Period>
bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
if (token.stop_requested()) {
return false;
}
bool stop_requested = false;
std::condition_variable cv;
std::mutex m;
std::stop_callback cb(token, [&] {
// Wake up the waiting thread.
std::unique_lock lk{m};
stop_requested = true;
cv.notify_one();
});
// Perform the timed wait.
std::unique_lock lk{m};
return !cv.wait_for(lk, rel_time, [&] { return stop_requested; });
}
} // namespace Common
#endif
+139
View File
@@ -0,0 +1,139 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <map>
#include <type_traits>
#include "common/common_types.h"
namespace Common {
template <typename KeyTBase, typename ValueT>
class RangeMap {
private:
using KeyT =
std::conditional_t<std::is_signed_v<KeyTBase>, KeyTBase, std::make_signed_t<KeyTBase>>;
public:
explicit RangeMap(ValueT null_value_) : null_value{null_value_} {
container.emplace(std::numeric_limits<KeyT>::min(), null_value);
};
~RangeMap() = default;
void Map(KeyTBase address, KeyTBase address_end, ValueT value) {
KeyT new_address = static_cast<KeyT>(address);
KeyT new_address_end = static_cast<KeyT>(address_end);
if (new_address < 0) {
new_address = 0;
}
if (new_address_end < 0) {
new_address_end = 0;
}
InternalMap(new_address, new_address_end, value);
}
void Unmap(KeyTBase address, KeyTBase address_end) {
Map(address, address_end, null_value);
}
[[nodiscard]] size_t GetContinousSizeFrom(KeyTBase address) const {
const KeyT new_address = static_cast<KeyT>(address);
if (new_address < 0) {
return 0;
}
return ContinousSizeInternal(new_address);
}
[[nodiscard]] ValueT GetValueAt(KeyT address) const {
const KeyT new_address = static_cast<KeyT>(address);
if (new_address < 0) {
return null_value;
}
return GetValueInternal(new_address);
}
private:
using MapType = std::map<KeyT, ValueT>;
using IteratorType = typename MapType::iterator;
using ConstIteratorType = typename MapType::const_iterator;
size_t ContinousSizeInternal(KeyT address) const {
const auto it = GetFirstElementBeforeOrOn(address);
if (it == container.end() || it->second == null_value) {
return 0;
}
const auto it_end = std::next(it);
if (it_end == container.end()) {
return std::numeric_limits<KeyT>::max() - address;
}
return it_end->first - address;
}
ValueT GetValueInternal(KeyT address) const {
const auto it = GetFirstElementBeforeOrOn(address);
if (it == container.end()) {
return null_value;
}
return it->second;
}
ConstIteratorType GetFirstElementBeforeOrOn(KeyT address) const {
auto it = container.lower_bound(address);
if (it == container.begin()) {
return it;
}
if (it != container.end() && (it->first == address)) {
return it;
}
--it;
return it;
}
ValueT GetFirstValueWithin(KeyT address) {
auto it = container.lower_bound(address);
if (it == container.begin()) {
return it->second;
}
if (it == container.end()) [[unlikely]] { // this would be a bug
return null_value;
}
--it;
return it->second;
}
ValueT GetLastValueWithin(KeyT address) {
auto it = container.upper_bound(address);
if (it == container.end()) {
return null_value;
}
if (it == container.begin()) [[unlikely]] { // this would be a bug
return it->second;
}
--it;
return it->second;
}
void InternalMap(KeyT address, KeyT address_end, ValueT value) {
const bool must_add_start = GetFirstValueWithin(address) != value;
const ValueT last_value = GetLastValueWithin(address_end);
const bool must_add_end = last_value != value;
auto it = container.lower_bound(address);
const auto it_end = container.upper_bound(address_end);
while (it != it_end) {
it = container.erase(it);
}
if (must_add_start) {
container.emplace(address, value);
}
if (must_add_end) {
container.emplace(address_end, last_value);
}
}
ValueT null_value;
MapType container;
};
} // namespace Common
+95
View File
@@ -0,0 +1,95 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/make_unique_for_overwrite.h"
namespace Common {
/**
* ScratchBuffer class
* This class creates a default initialized heap allocated buffer for cases such as intermediate
* buffers being copied into entirely, where value initializing members during allocation or resize
* is redundant.
*/
template <typename T>
class ScratchBuffer {
public:
ScratchBuffer() = default;
explicit ScratchBuffer(size_t initial_capacity)
: last_requested_size{initial_capacity}, buffer_capacity{initial_capacity},
buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {}
~ScratchBuffer() = default;
/// This will only grow the buffer's capacity if size is greater than the current capacity.
/// The previously held data will remain intact.
void resize(size_t size) {
if (size > buffer_capacity) {
auto new_buffer = Common::make_unique_for_overwrite<T[]>(size);
std::move(buffer.get(), buffer.get() + buffer_capacity, new_buffer.get());
buffer = std::move(new_buffer);
buffer_capacity = size;
}
last_requested_size = size;
}
/// This will only grow the buffer's capacity if size is greater than the current capacity.
/// The previously held data will be destroyed if a reallocation occurs.
void resize_destructive(size_t size) {
if (size > buffer_capacity) {
buffer_capacity = size;
buffer = Common::make_unique_for_overwrite<T[]>(buffer_capacity);
}
last_requested_size = size;
}
[[nodiscard]] T* data() noexcept {
return buffer.get();
}
[[nodiscard]] const T* data() const noexcept {
return buffer.get();
}
[[nodiscard]] T* begin() noexcept {
return data();
}
[[nodiscard]] const T* begin() const noexcept {
return data();
}
[[nodiscard]] T* end() noexcept {
return data() + last_requested_size;
}
[[nodiscard]] const T* end() const noexcept {
return data() + last_requested_size;
}
[[nodiscard]] T& operator[](size_t i) {
return buffer[i];
}
[[nodiscard]] const T& operator[](size_t i) const {
return buffer[i];
}
[[nodiscard]] size_t size() const noexcept {
return last_requested_size;
}
[[nodiscard]] size_t capacity() const noexcept {
return buffer_capacity;
}
private:
size_t last_requested_size{};
size_t buffer_capacity{};
std::unique_ptr<T[]> buffer{};
};
} // namespace Common
+14
View File
@@ -129,6 +129,10 @@ void UpdateRescalingInfo() {
info.up_scale = 1;
info.down_shift = 0;
break;
case ResolutionSetup::Res3_2X:
info.up_scale = 3;
info.down_shift = 1;
break;
case ResolutionSetup::Res2X:
info.up_scale = 2;
info.down_shift = 0;
@@ -149,6 +153,14 @@ void UpdateRescalingInfo() {
info.up_scale = 6;
info.down_shift = 0;
break;
case ResolutionSetup::Res7X:
info.up_scale = 7;
info.down_shift = 0;
break;
case ResolutionSetup::Res8X:
info.up_scale = 8;
info.down_shift = 0;
break;
default:
ASSERT(false);
info.up_scale = 1;
@@ -185,6 +197,7 @@ void RestoreGlobalState(bool is_powered_on) {
// Renderer
values.fsr_sharpening_slider.SetGlobal(true);
values.renderer_backend.SetGlobal(true);
values.renderer_force_max_clock.SetGlobal(true);
values.vulkan_device.SetGlobal(true);
values.aspect_ratio.SetGlobal(true);
values.max_anisotropy.SetGlobal(true);
@@ -200,6 +213,7 @@ void RestoreGlobalState(bool is_powered_on) {
values.use_asynchronous_shaders.SetGlobal(true);
values.use_fast_gpu_time.SetGlobal(true);
values.use_pessimistic_flushes.SetGlobal(true);
values.use_vulkan_driver_pipeline_cache.SetGlobal(true);
values.bg_red.SetGlobal(true);
values.bg_green.SetGlobal(true);
values.bg_blue.SetGlobal(true);
+21 -9
View File
@@ -56,11 +56,14 @@ enum class ResolutionSetup : u32 {
Res1_2X = 0,
Res3_4X = 1,
Res1X = 2,
Res2X = 3,
Res3X = 4,
Res4X = 5,
Res5X = 6,
Res6X = 7,
Res3_2X = 3,
Res2X = 4,
Res3X = 5,
Res4X = 6,
Res5X = 7,
Res6X = 8,
Res7X = 9,
Res8X = 10,
};
enum class ScalingFilter : u32 {
@@ -128,7 +131,8 @@ public:
* @param default_val Intial value of the setting, and default value of the setting
* @param name Label for the setting
*/
explicit Setting(const Type& default_val, const std::string& name) requires(!ranged)
explicit Setting(const Type& default_val, const std::string& name)
requires(!ranged)
: value{default_val}, default_value{default_val}, label{name} {}
virtual ~Setting() = default;
@@ -141,7 +145,8 @@ public:
* @param name Label for the setting
*/
explicit Setting(const Type& default_val, const Type& min_val, const Type& max_val,
const std::string& name) requires(ranged)
const std::string& name)
requires(ranged)
: value{default_val},
default_value{default_val}, maximum{max_val}, minimum{min_val}, label{name} {}
@@ -229,7 +234,8 @@ public:
* @param default_val Intial value of the setting, and default value of the setting
* @param name Label for the setting
*/
explicit SwitchableSetting(const Type& default_val, const std::string& name) requires(!ranged)
explicit SwitchableSetting(const Type& default_val, const std::string& name)
requires(!ranged)
: Setting<Type>{default_val, name} {}
virtual ~SwitchableSetting() = default;
@@ -242,7 +248,8 @@ public:
* @param name Label for the setting
*/
explicit SwitchableSetting(const Type& default_val, const Type& min_val, const Type& max_val,
const std::string& name) requires(ranged)
const std::string& name)
requires(ranged)
: Setting<Type, true>{default_val, min_val, max_val, name} {}
/**
@@ -415,6 +422,7 @@ struct Values {
// Renderer
SwitchableSetting<RendererBackend, true> renderer_backend{
RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, "backend"};
SwitchableSetting<bool> renderer_force_max_clock{false, "force_max_clock"};
Setting<bool> renderer_debug{false, "debug"};
Setting<bool> renderer_shader_feedback{false, "shader_feedback"};
Setting<bool> enable_nsight_aftermath{false, "nsight_aftermath"};
@@ -451,6 +459,8 @@ struct Values {
SwitchableSetting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};
SwitchableSetting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"};
SwitchableSetting<bool> use_pessimistic_flushes{false, "use_pessimistic_flushes"};
SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{true,
"use_vulkan_driver_pipeline_cache"};
SwitchableSetting<u8> bg_red{0, "bg_red"};
SwitchableSetting<u8> bg_green{0, "bg_green"};
@@ -477,6 +487,7 @@ struct Values {
Setting<bool> enable_raw_input{false, "enable_raw_input"};
Setting<bool> controller_navigation{true, "controller_navigation"};
Setting<bool> enable_joycon_driver{true, "enable_joycon_driver"};
SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"};
SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"};
@@ -531,6 +542,7 @@ struct Values {
Setting<bool> reporting_services{false, "reporting_services"};
Setting<bool> quest_flag{false, "quest_flag"};
Setting<bool> disable_macro_jit{false, "disable_macro_jit"};
Setting<bool> disable_macro_hle{false, "disable_macro_hle"};
Setting<bool> extended_logging{false, "extended_logging"};
Setting<bool> use_debug_asserts{false, "use_debug_asserts"};
Setting<bool> use_auto_stub{false, "use_auto_stub"};
+1 -1
View File
@@ -30,7 +30,7 @@ std::string ToUpper(std::string str) {
return str;
}
std::string StringFromBuffer(const std::vector<u8>& data) {
std::string StringFromBuffer(std::span<const u8> data) {
return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
}
+2 -1
View File
@@ -5,6 +5,7 @@
#pragma once
#include <cstddef>
#include <span>
#include <string>
#include <vector>
#include "common/common_types.h"
@@ -17,7 +18,7 @@ namespace Common {
/// Make a string uppercase
[[nodiscard]] std::string ToUpper(std::string str);
[[nodiscard]] std::string StringFromBuffer(const std::vector<u8>& data);
[[nodiscard]] std::string StringFromBuffer(std::span<const u8> data);
[[nodiscard]] std::string StripSpaces(const std::string& s);
[[nodiscard]] std::string StripQuotes(const std::string& s);
+37 -37
View File
@@ -103,12 +103,12 @@ concept IsRBEntry = CheckRBEntry<T>::value;
template <typename T>
concept HasRBEntry = requires(T& t, const T& ct) {
{ t.GetRBEntry() } -> std::same_as<RBEntry<T>&>;
{ ct.GetRBEntry() } -> std::same_as<const RBEntry<T>&>;
};
{ t.GetRBEntry() } -> std::same_as<RBEntry<T>&>;
{ ct.GetRBEntry() } -> std::same_as<const RBEntry<T>&>;
};
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
class RBHead {
private:
T* m_rbh_root = nullptr;
@@ -130,90 +130,90 @@ public:
};
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr RBEntry<T>& RB_ENTRY(T* t) {
return t->GetRBEntry();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr const RBEntry<T>& RB_ENTRY(const T* t) {
return t->GetRBEntry();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr T* RB_LEFT(T* t) {
return RB_ENTRY(t).Left();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr const T* RB_LEFT(const T* t) {
return RB_ENTRY(t).Left();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr T* RB_RIGHT(T* t) {
return RB_ENTRY(t).Right();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr const T* RB_RIGHT(const T* t) {
return RB_ENTRY(t).Right();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr T* RB_PARENT(T* t) {
return RB_ENTRY(t).Parent();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr const T* RB_PARENT(const T* t) {
return RB_ENTRY(t).Parent();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET_LEFT(T* t, T* e) {
RB_ENTRY(t).SetLeft(e);
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET_RIGHT(T* t, T* e) {
RB_ENTRY(t).SetRight(e);
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET_PARENT(T* t, T* e) {
RB_ENTRY(t).SetParent(e);
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr bool RB_IS_BLACK(const T* t) {
return RB_ENTRY(t).IsBlack();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr bool RB_IS_RED(const T* t) {
return RB_ENTRY(t).IsRed();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr RBColor RB_COLOR(const T* t) {
return RB_ENTRY(t).Color();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET_COLOR(T* t, RBColor c) {
RB_ENTRY(t).SetColor(c);
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET(T* elm, T* parent) {
auto& rb_entry = RB_ENTRY(elm);
rb_entry.SetParent(parent);
@@ -223,14 +223,14 @@ constexpr void RB_SET(T* elm, T* parent) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET_BLACKRED(T* black, T* red) {
RB_SET_COLOR(black, RBColor::RB_BLACK);
RB_SET_COLOR(red, RBColor::RB_RED);
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) {
tmp = RB_RIGHT(elm);
if (RB_SET_RIGHT(elm, RB_LEFT(tmp)); RB_RIGHT(elm) != nullptr) {
@@ -252,7 +252,7 @@ constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) {
tmp = RB_LEFT(elm);
if (RB_SET_LEFT(elm, RB_RIGHT(tmp)); RB_LEFT(elm) != nullptr) {
@@ -274,7 +274,7 @@ constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) {
T* tmp;
while ((elm == nullptr || RB_IS_BLACK(elm)) && elm != head.Root()) {
@@ -358,7 +358,7 @@ constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) {
T* child = nullptr;
T* parent = nullptr;
@@ -451,7 +451,7 @@ constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) {
T *parent = nullptr, *tmp = nullptr;
while ((parent = RB_PARENT(elm)) != nullptr && RB_IS_RED(parent)) {
@@ -499,7 +499,7 @@ constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) {
}
template <typename T, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) {
T* parent = nullptr;
T* tmp = head.Root();
@@ -534,7 +534,7 @@ constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) {
T* tmp = head.Root();
@@ -553,7 +553,7 @@ constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) {
T* tmp = head.Root();
T* res = nullptr;
@@ -574,7 +574,7 @@ constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename U, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
T* tmp = head.Root();
@@ -593,7 +593,7 @@ constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
}
template <typename T, typename U, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
T* tmp = head.Root();
T* res = nullptr;
@@ -614,7 +614,7 @@ constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
}
template <typename T, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) {
T* tmp = head.Root();
@@ -631,7 +631,7 @@ constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename U, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) {
T* tmp = head.Root();
@@ -648,7 +648,7 @@ constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_NEXT(T* elm) {
if (RB_RIGHT(elm)) {
elm = RB_RIGHT(elm);
@@ -669,7 +669,7 @@ constexpr T* RB_NEXT(T* elm) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_PREV(T* elm) {
if (RB_LEFT(elm)) {
elm = RB_LEFT(elm);
@@ -690,7 +690,7 @@ constexpr T* RB_PREV(T* elm) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_MIN(RBHead<T>& head) {
T* tmp = head.Root();
T* parent = nullptr;
@@ -704,7 +704,7 @@ constexpr T* RB_MIN(RBHead<T>& head) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_MAX(RBHead<T>& head) {
T* tmp = head.Root();
T* parent = nullptr;
+5 -11
View File
@@ -348,9 +348,7 @@ public:
// _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all
// component names (x<->r) and permutations (xy<->yx)
#define _DEFINE_SWIZZLER2(a, b, name) \
[[nodiscard]] constexpr Vec2<T> name() const { \
return Vec2<T>(a, b); \
}
[[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); }
#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \
_DEFINE_SWIZZLER2(a, b, a##b); \
_DEFINE_SWIZZLER2(a, b, a2##b2); \
@@ -543,9 +541,7 @@ public:
// DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and
// permutations (xy<->yx)
#define _DEFINE_SWIZZLER2(a, b, name) \
[[nodiscard]] constexpr Vec2<T> name() const { \
return Vec2<T>(a, b); \
}
[[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); }
#define DEFINE_SWIZZLER2_COMP1(a, a2) \
_DEFINE_SWIZZLER2(a, a, a##a); \
_DEFINE_SWIZZLER2(a, a, a2##a2)
@@ -570,9 +566,7 @@ public:
#undef _DEFINE_SWIZZLER2
#define _DEFINE_SWIZZLER3(a, b, c, name) \
[[nodiscard]] constexpr Vec3<T> name() const { \
return Vec3<T>(a, b, c); \
}
[[nodiscard]] constexpr Vec3<T> name() const { return Vec3<T>(a, b, c); }
#define DEFINE_SWIZZLER3_COMP1(a, a2) \
_DEFINE_SWIZZLER3(a, a, a, a##a##a); \
_DEFINE_SWIZZLER3(a, a, a, a2##a2##a2)
@@ -641,8 +635,8 @@ template <typename T>
// linear interpolation via float: 0.0=begin, 1.0=end
template <typename X>
[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{})
Lerp(const X& begin, const X& end, const float t) {
[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end,
const float t) {
return begin * (1.f - t) + end * t;
}
+41 -1
View File
@@ -182,6 +182,8 @@ add_library(core STATIC
hle/kernel/k_auto_object_container.cpp
hle/kernel/k_auto_object_container.h
hle/kernel/k_affinity_mask.h
hle/kernel/k_capabilities.cpp
hle/kernel/k_capabilities.h
hle/kernel/k_class_token.cpp
hle/kernel/k_class_token.h
hle/kernel/k_client_port.cpp
@@ -193,6 +195,8 @@ add_library(core STATIC
hle/kernel/k_condition_variable.cpp
hle/kernel/k_condition_variable.h
hle/kernel/k_debug.h
hle/kernel/k_device_address_space.cpp
hle/kernel/k_device_address_space.h
hle/kernel/k_dynamic_page_manager.h
hle/kernel/k_dynamic_resource_manager.h
hle/kernel/k_dynamic_slab_heap.h
@@ -226,6 +230,7 @@ add_library(core STATIC
hle/kernel/k_page_buffer.h
hle/kernel/k_page_heap.cpp
hle/kernel/k_page_heap.h
hle/kernel/k_page_group.cpp
hle/kernel/k_page_group.h
hle/kernel/k_page_table.cpp
hle/kernel/k_page_table.h
@@ -293,7 +298,42 @@ add_library(core STATIC
hle/kernel/svc.h
hle/kernel/svc_common.h
hle/kernel/svc_types.h
hle/kernel/svc_wrap.h
hle/kernel/svc/svc_activity.cpp
hle/kernel/svc/svc_address_arbiter.cpp
hle/kernel/svc/svc_address_translation.cpp
hle/kernel/svc/svc_cache.cpp
hle/kernel/svc/svc_code_memory.cpp
hle/kernel/svc/svc_condition_variable.cpp
hle/kernel/svc/svc_debug.cpp
hle/kernel/svc/svc_debug_string.cpp
hle/kernel/svc/svc_device_address_space.cpp
hle/kernel/svc/svc_event.cpp
hle/kernel/svc/svc_exception.cpp
hle/kernel/svc/svc_info.cpp
hle/kernel/svc/svc_interrupt_event.cpp
hle/kernel/svc/svc_io_pool.cpp
hle/kernel/svc/svc_ipc.cpp
hle/kernel/svc/svc_kernel_debug.cpp
hle/kernel/svc/svc_light_ipc.cpp
hle/kernel/svc/svc_lock.cpp
hle/kernel/svc/svc_memory.cpp
hle/kernel/svc/svc_physical_memory.cpp
hle/kernel/svc/svc_port.cpp
hle/kernel/svc/svc_power_management.cpp
hle/kernel/svc/svc_process.cpp
hle/kernel/svc/svc_process_memory.cpp
hle/kernel/svc/svc_processor.cpp
hle/kernel/svc/svc_query_memory.cpp
hle/kernel/svc/svc_register.cpp
hle/kernel/svc/svc_resource_limit.cpp
hle/kernel/svc/svc_secure_monitor_call.cpp
hle/kernel/svc/svc_session.cpp
hle/kernel/svc/svc_shared_memory.cpp
hle/kernel/svc/svc_synchronization.cpp
hle/kernel/svc/svc_thread.cpp
hle/kernel/svc/svc_thread_profiler.cpp
hle/kernel/svc/svc_tick.cpp
hle/kernel/svc/svc_transfer_memory.cpp
hle/result.h
hle/service/acc/acc.cpp
hle/service/acc/acc.h
+4 -18
View File
@@ -1,14 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef _MSC_VER
#include <cxxabi.h>
#endif
#include <map>
#include <optional>
#include "common/bit_field.h"
#include "common/common_types.h"
#include "common/demangle.h"
#include "common/logging/log.h"
#include "core/arm/arm_interface.h"
#include "core/arm/symbols.h"
@@ -71,20 +69,8 @@ void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<Backt
const auto symbol_set = symbols.find(entry.module);
if (symbol_set != symbols.end()) {
const auto symbol = Symbols::GetSymbolName(symbol_set->second, entry.offset);
if (symbol.has_value()) {
#ifdef _MSC_VER
// TODO(DarkLordZach): Add demangling of symbol names.
entry.name = *symbol;
#else
int status{-1};
char* demangled{abi::__cxa_demangle(symbol->c_str(), nullptr, nullptr, &status)};
if (status == 0 && demangled != nullptr) {
entry.name = demangled;
std::free(demangled);
} else {
entry.name = *symbol;
}
#endif
if (symbol) {
entry.name = Common::DemangleSymbol(*symbol);
}
}
}
@@ -229,7 +229,11 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
config.enable_cycle_counting = true;
// Code cache size
#ifdef ARCHITECTURE_arm64
config.code_cache_size = 128_MiB;
#else
config.code_cache_size = 512_MiB;
#endif
// Allow memory fault handling to work
if (system.DebuggerEnabled()) {
@@ -288,7 +288,11 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
config.enable_cycle_counting = true;
// Code cache size
#ifdef ARCHITECTURE_arm64
config.code_cache_size = 128_MiB;
#else
config.code_cache_size = 512_MiB;
#endif
// Allow memory fault handling to work
if (system.DebuggerEnabled()) {
+17 -23
View File
@@ -142,16 +142,24 @@ void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
}
void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data) {
std::scoped_lock scope{basic_lock};
const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
return e.type.lock().get() == event_type.get() && e.user_data == user_data;
});
std::uintptr_t user_data, bool wait) {
{
std::scoped_lock lk{basic_lock};
const auto itr =
std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
return e.type.lock().get() == event_type.get() && e.user_data == user_data;
});
// Removing random items breaks the invariant so we have to re-establish it.
if (itr != event_queue.end()) {
event_queue.erase(itr, event_queue.end());
std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
// Removing random items breaks the invariant so we have to re-establish it.
if (itr != event_queue.end()) {
event_queue.erase(itr, event_queue.end());
std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
}
// Force any in-progress events to finish
if (wait) {
std::scoped_lock lk{advance_lock};
}
}
@@ -190,20 +198,6 @@ u64 CoreTiming::GetClockTicks() const {
return CpuCyclesToClockCycles(ticks);
}
void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) {
std::scoped_lock lock{basic_lock};
const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
return e.type.lock().get() == event_type.get();
});
// Removing random items breaks the invariant so we have to re-establish it.
if (itr != event_queue.end()) {
event_queue.erase(itr, event_queue.end());
std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
}
std::optional<s64> CoreTiming::Advance() {
std::scoped_lock lock{advance_lock, basic_lock};
global_timer = GetGlobalTimeNs().count();
+6 -3
View File
@@ -98,10 +98,13 @@ public:
const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data = 0, bool absolute_time = false);
void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data);
void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data,
bool wait = true);
/// We only permit one event of each type in the queue at a time.
void RemoveEvent(const std::shared_ptr<EventType>& event_type);
void UnscheduleEventWithoutWait(const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data) {
UnscheduleEvent(event_type, user_data, false);
}
void AddTicks(u64 ticks_to_add);
+23 -3
View File
@@ -11,6 +11,7 @@
#include "common/hex_util.h"
#include "common/logging/log.h"
#include "common/scope_exit.h"
#include "common/settings.h"
#include "core/arm/arm_interface.h"
#include "core/core.h"
#include "core/debugger/gdbstub.h"
@@ -731,7 +732,25 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
auto* process = system.CurrentProcess();
auto& page_table = process->PageTable();
if (command_str == "get info") {
const char* commands = "Commands:\n"
" get fastmem\n"
" get info\n"
" get mappings\n";
if (command_str == "get fastmem") {
if (Settings::IsFastmemEnabled()) {
const auto& impl = page_table.PageTableImpl();
const auto region = reinterpret_cast<uintptr_t>(impl.fastmem_arena);
const auto region_bits = impl.current_address_space_width_in_bits;
const auto region_size = 1ULL << region_bits;
reply = fmt::format("Region bits: {}\n"
"Host address: {:#x} - {:#x}\n",
region_bits, region, region + region_size - 1);
} else {
reply = "Fastmem is not enabled.\n";
}
} else if (command_str == "get info") {
Loader::AppLoader::Modules modules;
system.GetAppLoader().ReadNSOModules(modules);
@@ -787,9 +806,10 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
cur_addr = next_address;
}
} else if (command_str == "help") {
reply = "Commands:\n get info\n get mappings\n";
reply = commands;
} else {
reply = "Unknown command.\nCommands:\n get info\n get mappings\n";
reply = "Unknown command.\n";
reply += commands;
}
std::span<const u8> reply_span{reinterpret_cast<u8*>(&reply.front()), reply.size()};
+3 -3
View File
@@ -194,9 +194,9 @@ std::size_t VfsFile::WriteBytes(const std::vector<u8>& data, std::size_t offset)
std::string VfsFile::GetFullPath() const {
if (GetContainingDirectory() == nullptr)
return "/" + GetName();
return '/' + GetName();
return GetContainingDirectory()->GetFullPath() + "/" + GetName();
return GetContainingDirectory()->GetFullPath() + '/' + GetName();
}
VirtualFile VfsDirectory::GetFileRelative(std::string_view path) const {
@@ -435,7 +435,7 @@ std::string VfsDirectory::GetFullPath() const {
if (IsRoot())
return GetName();
return GetParentDirectory()->GetFullPath() + "/" + GetName();
return GetParentDirectory()->GetFullPath() + '/' + GetName();
}
bool ReadOnlyVfsDirectory::IsWritable() const {
+20
View File
@@ -25,6 +25,26 @@ constexpr std::array<s32, Common::BitSize<u64>()> VirtualToPhysicalCoreMap{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
};
static constexpr inline size_t NumVirtualCores = Common::BitSize<u64>();
static constexpr inline u64 VirtualCoreMask = [] {
u64 mask = 0;
for (size_t i = 0; i < NumVirtualCores; ++i) {
mask |= (UINT64_C(1) << i);
}
return mask;
}();
static constexpr inline u64 ConvertVirtualCoreMaskToPhysical(u64 v_core_mask) {
u64 p_core_mask = 0;
while (v_core_mask != 0) {
const u64 next = std::countr_zero(v_core_mask);
v_core_mask &= ~(static_cast<u64>(1) << next);
p_core_mask |= (static_cast<u64>(1) << VirtualToPhysicalCoreMap[next]);
}
return p_core_mask;
}
// Cortex-A57 supports 4 memory watchpoints
constexpr u64 NUM_WATCHPOINTS = 4;
+5
View File
@@ -40,6 +40,11 @@ void EmulatedConsole::SetTouchParams() {
touch_params[index++] = std::move(touchscreen_param);
}
if (Settings::values.touch_from_button_maps.empty()) {
LOG_WARNING(Input, "touch_from_button_maps is unset by frontend config");
return;
}
const auto button_index =
static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
const auto& touch_buttons = Settings::values.touch_from_button_maps[button_index].buttons;
+308 -100
View File
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <common/scope_exit.h>
#include "common/polyfill_ranges.h"
#include "common/thread.h"
@@ -11,6 +12,12 @@
namespace Core::HID {
constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
constexpr s32 HID_TRIGGER_MAX = 0x7fff;
constexpr u32 TURBO_BUTTON_DELAY = 4;
// Use a common UUID for TAS and Virtual Gamepad
constexpr Common::UUID TAS_UUID =
Common::UUID{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xA5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
constexpr Common::UUID VIRTUAL_UUID =
Common::UUID{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
EmulatedController::EmulatedController(NpadIdType npad_id_type_) : npad_id_type(npad_id_type_) {}
@@ -88,6 +95,7 @@ void EmulatedController::ReloadFromSettings() {
motion_params[index] = Common::ParamPackage(player.motions[index]);
}
controller.color_values = {};
controller.colors_state.fullkey = {
.body = GetNpadColor(player.body_color_left),
.button = GetNpadColor(player.button_color_left),
@@ -101,6 +109,8 @@ void EmulatedController::ReloadFromSettings() {
.button = GetNpadColor(player.button_color_right),
};
ring_params[0] = Common::ParamPackage(Settings::values.ringcon_analogs);
// Other or debug controller should always be a pro controller
if (npad_id_type != NpadIdType::Other) {
SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type));
@@ -127,18 +137,28 @@ void EmulatedController::LoadDevices() {
trigger_params[LeftIndex] = button_params[Settings::NativeButton::ZL];
trigger_params[RightIndex] = button_params[Settings::NativeButton::ZR];
color_params[LeftIndex] = left_joycon;
color_params[RightIndex] = right_joycon;
color_params[LeftIndex].Set("color", true);
color_params[RightIndex].Set("color", true);
battery_params[LeftIndex] = left_joycon;
battery_params[RightIndex] = right_joycon;
battery_params[LeftIndex].Set("battery", true);
battery_params[RightIndex].Set("battery", true);
camera_params = Common::ParamPackage{"engine:camera,camera:1"};
nfc_params = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"};
camera_params[0] = right_joycon;
camera_params[0].Set("camera", true);
camera_params[1] = Common::ParamPackage{"engine:camera,camera:1"};
ring_params[1] = Common::ParamPackage{"engine:joycon,axis_x:100,axis_y:101"};
nfc_params[0] = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"};
nfc_params[1] = right_joycon;
nfc_params[1].Set("nfc", true);
output_params[LeftIndex] = left_joycon;
output_params[RightIndex] = right_joycon;
output_params[2] = camera_params;
output_params[3] = nfc_params;
output_params[2] = camera_params[1];
output_params[3] = nfc_params[0];
output_params[LeftIndex].Set("output", true);
output_params[RightIndex].Set("output", true);
output_params[2].Set("output", true);
@@ -154,8 +174,11 @@ void EmulatedController::LoadDevices() {
Common::Input::CreateInputDevice);
std::ranges::transform(battery_params, battery_devices.begin(),
Common::Input::CreateInputDevice);
camera_devices = Common::Input::CreateInputDevice(camera_params);
nfc_devices = Common::Input::CreateInputDevice(nfc_params);
std::ranges::transform(color_params, color_devices.begin(), Common::Input::CreateInputDevice);
std::ranges::transform(camera_params, camera_devices.begin(), Common::Input::CreateInputDevice);
std::ranges::transform(ring_params, ring_analog_devices.begin(),
Common::Input::CreateInputDevice);
std::ranges::transform(nfc_params, nfc_devices.begin(), Common::Input::CreateInputDevice);
std::ranges::transform(output_params, output_devices.begin(),
Common::Input::CreateOutputDevice);
@@ -210,6 +233,13 @@ void EmulatedController::LoadTASParams() {
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
tas_stick_params[Settings::NativeAnalog::RStick].Set("axis_x", 2);
tas_stick_params[Settings::NativeAnalog::RStick].Set("axis_y", 3);
// set to optimal stick to avoid sanitizing the stick and tweaking the coordinates
// making sure they play back in the game as originally written down in the script file
tas_stick_params[Settings::NativeAnalog::LStick].Set("deadzone", 0.0f);
tas_stick_params[Settings::NativeAnalog::LStick].Set("range", 1.0f);
tas_stick_params[Settings::NativeAnalog::RStick].Set("deadzone", 0.0f);
tas_stick_params[Settings::NativeAnalog::RStick].Set("range", 1.0f);
}
void EmulatedController::LoadVirtualGamepadParams() {
@@ -310,6 +340,19 @@ void EmulatedController::ReloadInput() {
battery_devices[index]->ForceUpdate();
}
for (std::size_t index = 0; index < color_devices.size(); ++index) {
if (!color_devices[index]) {
continue;
}
color_devices[index]->SetCallback({
.on_change =
[this, index](const Common::Input::CallbackStatus& callback) {
SetColors(callback, index);
},
});
color_devices[index]->ForceUpdate();
}
for (std::size_t index = 0; index < motion_devices.size(); ++index) {
if (!motion_devices[index]) {
continue;
@@ -323,27 +366,38 @@ void EmulatedController::ReloadInput() {
motion_devices[index]->ForceUpdate();
}
if (camera_devices) {
camera_devices->SetCallback({
for (std::size_t index = 0; index < camera_devices.size(); ++index) {
if (!camera_devices[index]) {
continue;
}
camera_devices[index]->SetCallback({
.on_change =
[this](const Common::Input::CallbackStatus& callback) { SetCamera(callback); },
});
camera_devices->ForceUpdate();
camera_devices[index]->ForceUpdate();
}
if (nfc_devices) {
if (npad_id_type == NpadIdType::Handheld || npad_id_type == NpadIdType::Player1) {
nfc_devices->SetCallback({
.on_change =
[this](const Common::Input::CallbackStatus& callback) { SetNfc(callback); },
});
nfc_devices->ForceUpdate();
for (std::size_t index = 0; index < ring_analog_devices.size(); ++index) {
if (!ring_analog_devices[index]) {
continue;
}
ring_analog_devices[index]->SetCallback({
.on_change =
[this](const Common::Input::CallbackStatus& callback) { SetRingAnalog(callback); },
});
ring_analog_devices[index]->ForceUpdate();
}
// Use a common UUID for TAS
static constexpr Common::UUID TAS_UUID = Common::UUID{
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xA5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
for (std::size_t index = 0; index < nfc_devices.size(); ++index) {
if (!nfc_devices[index]) {
continue;
}
nfc_devices[index]->SetCallback({
.on_change =
[this](const Common::Input::CallbackStatus& callback) { SetNfc(callback); },
});
nfc_devices[index]->ForceUpdate();
}
// Register TAS devices. No need to force update
for (std::size_t index = 0; index < tas_button_devices.size(); ++index) {
@@ -370,10 +424,6 @@ void EmulatedController::ReloadInput() {
});
}
// Use a common UUID for Virtual Gamepad
static constexpr Common::UUID VIRTUAL_UUID = Common::UUID{
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
// Register virtual devices. No need to force update
for (std::size_t index = 0; index < virtual_button_devices.size(); ++index) {
if (!virtual_button_devices[index]) {
@@ -398,6 +448,7 @@ void EmulatedController::ReloadInput() {
},
});
}
turbo_button_state = 0;
}
void EmulatedController::UnloadInput() {
@@ -416,6 +467,9 @@ void EmulatedController::UnloadInput() {
for (auto& battery : battery_devices) {
battery.reset();
}
for (auto& color : color_devices) {
color.reset();
}
for (auto& output : output_devices) {
output.reset();
}
@@ -431,8 +485,15 @@ void EmulatedController::UnloadInput() {
for (auto& stick : virtual_stick_devices) {
stick.reset();
}
camera_devices.reset();
nfc_devices.reset();
for (auto& camera : camera_devices) {
camera.reset();
}
for (auto& ring : ring_analog_devices) {
ring.reset();
}
for (auto& nfc : nfc_devices) {
nfc.reset();
}
}
void EmulatedController::EnableConfiguration() {
@@ -444,6 +505,11 @@ void EmulatedController::EnableConfiguration() {
void EmulatedController::DisableConfiguration() {
is_configuring = false;
// Get Joycon colors before turning on the controller
for (const auto& color_device : color_devices) {
color_device->ForceUpdate();
}
// Apply temporary npad type to the real controller
if (tmp_npad_type != npad_type) {
if (is_connected) {
@@ -497,6 +563,9 @@ void EmulatedController::SaveCurrentConfig() {
for (std::size_t index = 0; index < player.motions.size(); ++index) {
player.motions[index] = motion_params[index].Serialize();
}
if (npad_id_type == NpadIdType::Player1) {
Settings::values.ringcon_analogs = ring_params[0].Serialize();
}
}
void EmulatedController::RestoreConfig() {
@@ -620,6 +689,7 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
}
current_status.toggle = new_status.toggle;
current_status.turbo = new_status.turbo;
current_status.uuid = uuid;
// Update button status with current
@@ -768,12 +838,21 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
if (index >= controller.stick_values.size()) {
return;
}
std::unique_lock lock{mutex};
auto trigger_guard =
SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Stick, !is_configuring); });
std::scoped_lock lock{mutex};
const auto stick_value = TransformToStick(callback);
// Only read stick values that have the same uuid or are over the threshold to avoid flapping
if (controller.stick_values[index].uuid != uuid) {
if (!stick_value.down && !stick_value.up && !stick_value.left && !stick_value.right) {
const bool is_tas = uuid == TAS_UUID;
if (is_tas && stick_value.x.value == 0 && stick_value.y.value == 0) {
trigger_guard.Cancel();
return;
}
if (!is_tas && !stick_value.down && !stick_value.up && !stick_value.left &&
!stick_value.right) {
trigger_guard.Cancel();
return;
}
}
@@ -784,8 +863,6 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
if (is_configuring) {
controller.analog_stick_state.left = {};
controller.analog_stick_state.right = {};
lock.unlock();
TriggerOnChange(ControllerTriggerType::Stick, false);
return;
}
@@ -810,9 +887,6 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
controller.npad_button_state.stick_r_down.Assign(controller.stick_values[index].down);
break;
}
lock.unlock();
TriggerOnChange(ControllerTriggerType::Stick, true);
}
void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callback,
@@ -820,7 +894,9 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac
if (index >= controller.trigger_values.size()) {
return;
}
std::unique_lock lock{mutex};
auto trigger_guard =
SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Trigger, !is_configuring); });
std::scoped_lock lock{mutex};
const auto trigger_value = TransformToTrigger(callback);
// Only read trigger values that have the same uuid or are pressed once
@@ -836,13 +912,12 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac
if (is_configuring) {
controller.gc_trigger_state.left = 0;
controller.gc_trigger_state.right = 0;
lock.unlock();
TriggerOnChange(ControllerTriggerType::Trigger, false);
return;
}
// Only GC controllers have analog triggers
if (npad_type != NpadStyleIndex::GameCube) {
trigger_guard.Cancel();
return;
}
@@ -859,9 +934,6 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac
controller.npad_button_state.zr.Assign(trigger.pressed.value);
break;
}
lock.unlock();
TriggerOnChange(ControllerTriggerType::Trigger, true);
}
void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback,
@@ -869,7 +941,8 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
if (index >= controller.motion_values.size()) {
return;
}
std::unique_lock lock{mutex};
SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Motion, !is_configuring); });
std::scoped_lock lock{mutex};
auto& raw_status = controller.motion_values[index].raw_status;
auto& emulated = controller.motion_values[index].emulated;
@@ -890,8 +963,6 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
force_update_motion = raw_status.force_update;
if (is_configuring) {
lock.unlock();
TriggerOnChange(ControllerTriggerType::Motion, false);
return;
}
@@ -901,9 +972,56 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
motion.rotation = emulated.GetRotations();
motion.orientation = emulated.GetOrientation();
motion.is_at_rest = !emulated.IsMoving(motion_sensitivity);
}
lock.unlock();
TriggerOnChange(ControllerTriggerType::Motion, true);
void EmulatedController::SetColors(const Common::Input::CallbackStatus& callback,
std::size_t index) {
if (index >= controller.color_values.size()) {
return;
}
auto trigger_guard =
SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Color, !is_configuring); });
std::scoped_lock lock{mutex};
controller.color_values[index] = TransformToColor(callback);
if (is_configuring) {
return;
}
if (controller.color_values[index].body == 0) {
trigger_guard.Cancel();
return;
}
controller.colors_state.fullkey = {
.body = GetNpadColor(controller.color_values[index].body),
.button = GetNpadColor(controller.color_values[index].buttons),
};
if (npad_type == NpadStyleIndex::ProController) {
controller.colors_state.left = {
.body = GetNpadColor(controller.color_values[index].left_grip),
.button = GetNpadColor(controller.color_values[index].buttons),
};
controller.colors_state.right = {
.body = GetNpadColor(controller.color_values[index].right_grip),
.button = GetNpadColor(controller.color_values[index].buttons),
};
} else {
switch (index) {
case LeftIndex:
controller.colors_state.left = {
.body = GetNpadColor(controller.color_values[index].body),
.button = GetNpadColor(controller.color_values[index].buttons),
};
break;
case RightIndex:
controller.colors_state.right = {
.body = GetNpadColor(controller.color_values[index].body),
.button = GetNpadColor(controller.color_values[index].buttons),
};
break;
}
}
}
void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callback,
@@ -911,12 +1029,11 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac
if (index >= controller.battery_values.size()) {
return;
}
std::unique_lock lock{mutex};
SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Battery, !is_configuring); });
std::scoped_lock lock{mutex};
controller.battery_values[index] = TransformToBattery(callback);
if (is_configuring) {
lock.unlock();
TriggerOnChange(ControllerTriggerType::Battery, false);
return;
}
@@ -972,18 +1089,14 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac
};
break;
}
lock.unlock();
TriggerOnChange(ControllerTriggerType::Battery, true);
}
void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback) {
std::unique_lock lock{mutex};
SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::IrSensor, !is_configuring); });
std::scoped_lock lock{mutex};
controller.camera_values = TransformToCamera(callback);
if (is_configuring) {
lock.unlock();
TriggerOnChange(ControllerTriggerType::IrSensor, false);
return;
}
@@ -991,18 +1104,28 @@ void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback
controller.camera_state.format =
static_cast<Core::IrSensor::ImageTransferProcessorFormat>(controller.camera_values.format);
controller.camera_state.data = controller.camera_values.data;
}
lock.unlock();
TriggerOnChange(ControllerTriggerType::IrSensor, true);
void EmulatedController::SetRingAnalog(const Common::Input::CallbackStatus& callback) {
SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::RingController, !is_configuring); });
std::scoped_lock lock{mutex};
const auto force_value = TransformToStick(callback);
controller.ring_analog_value = force_value.x;
if (is_configuring) {
return;
}
controller.ring_analog_state.force = force_value.x.value;
}
void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) {
std::unique_lock lock{mutex};
SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Nfc, !is_configuring); });
std::scoped_lock lock{mutex};
controller.nfc_values = TransformToNfc(callback);
if (is_configuring) {
lock.unlock();
TriggerOnChange(ControllerTriggerType::Nfc, false);
return;
}
@@ -1010,9 +1133,6 @@ void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) {
controller.nfc_values.state,
controller.nfc_values.data,
};
lock.unlock();
TriggerOnChange(ControllerTriggerType::Nfc, true);
}
bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) {
@@ -1044,7 +1164,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
.type = type,
};
return output_devices[device_index]->SetVibration(status) ==
Common::Input::VibrationError::None;
Common::Input::DriverResult::Success;
}
bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
@@ -1066,16 +1186,32 @@ bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
return output_devices[device_index]->IsVibrationEnabled();
}
bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) {
LOG_INFO(Service_HID, "Set polling mode {}", polling_mode);
auto& output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
Common::Input::DriverResult EmulatedController::SetPollingMode(
EmulatedDeviceIndex device_index, Common::Input::PollingMode polling_mode) {
LOG_INFO(Service_HID, "Set polling mode {}, device_index={}", polling_mode, device_index);
auto& left_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Left)];
auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& nfc_output_device = output_devices[3];
const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode);
const auto mapped_nfc_result = output_device->SetPollingMode(polling_mode);
if (device_index == EmulatedDeviceIndex::LeftIndex) {
return left_output_device->SetPollingMode(polling_mode);
}
return virtual_nfc_result == Common::Input::PollingError::None ||
mapped_nfc_result == Common::Input::PollingError::None;
if (device_index == EmulatedDeviceIndex::RightIndex) {
const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode);
const auto mapped_nfc_result = right_output_device->SetPollingMode(polling_mode);
if (virtual_nfc_result == Common::Input::DriverResult::Success) {
return virtual_nfc_result;
}
return mapped_nfc_result;
}
left_output_device->SetPollingMode(polling_mode);
right_output_device->SetPollingMode(polling_mode);
nfc_output_device->SetPollingMode(polling_mode);
return Common::Input::DriverResult::Success;
}
bool EmulatedController::SetCameraFormat(
@@ -1086,13 +1222,22 @@ bool EmulatedController::SetCameraFormat(
auto& camera_output_device = output_devices[2];
if (right_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>(
camera_format)) == Common::Input::CameraError::None) {
camera_format)) == Common::Input::DriverResult::Success) {
return true;
}
// Fallback to Qt camera if native device doesn't have support
return camera_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>(
camera_format)) == Common::Input::CameraError::None;
camera_format)) == Common::Input::DriverResult::Success;
}
Common::ParamPackage EmulatedController::GetRingParam() const {
return ring_params[0];
}
void EmulatedController::SetRingParam(Common::ParamPackage param) {
ring_params[0] = std::move(param);
ReloadInput();
}
bool EmulatedController::HasNfc() const {
@@ -1246,39 +1391,35 @@ void EmulatedController::Connect(bool use_temporary_value) {
return;
}
std::unique_lock lock{mutex};
auto trigger_guard =
SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Connected, !is_configuring); });
std::scoped_lock lock{mutex};
if (is_configuring) {
tmp_is_connected = true;
lock.unlock();
TriggerOnChange(ControllerTriggerType::Connected, false);
return;
}
if (is_connected) {
trigger_guard.Cancel();
return;
}
is_connected = true;
lock.unlock();
TriggerOnChange(ControllerTriggerType::Connected, true);
}
void EmulatedController::Disconnect() {
std::unique_lock lock{mutex};
auto trigger_guard =
SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Disconnected, !is_configuring); });
std::scoped_lock lock{mutex};
if (is_configuring) {
tmp_is_connected = false;
lock.unlock();
TriggerOnChange(ControllerTriggerType::Disconnected, false);
return;
}
if (!is_connected) {
trigger_guard.Cancel();
return;
}
is_connected = false;
lock.unlock();
TriggerOnChange(ControllerTriggerType::Disconnected, true);
}
bool EmulatedController::IsConnected(bool get_temporary_value) const {
@@ -1303,19 +1444,21 @@ NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) c
}
void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
std::unique_lock lock{mutex};
auto trigger_guard =
SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Type, !is_configuring); });
std::scoped_lock lock{mutex};
if (is_configuring) {
if (tmp_npad_type == npad_type_) {
trigger_guard.Cancel();
return;
}
tmp_npad_type = npad_type_;
lock.unlock();
TriggerOnChange(ControllerTriggerType::Type, false);
return;
}
if (npad_type == npad_type_) {
trigger_guard.Cancel();
return;
}
if (is_connected) {
@@ -1323,9 +1466,6 @@ void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
NpadIdTypeToIndex(npad_id_type));
}
npad_type = npad_type_;
lock.unlock();
TriggerOnChange(ControllerTriggerType::Type, true);
}
LedPattern EmulatedController::GetLedPattern() const {
@@ -1386,6 +1526,10 @@ CameraValues EmulatedController::GetCameraValues() const {
return controller.camera_values;
}
RingAnalogValue EmulatedController::GetRingSensorValues() const {
return controller.ring_analog_value;
}
HomeButtonState EmulatedController::GetHomeButtons() const {
std::scoped_lock lock{mutex};
if (is_configuring) {
@@ -1407,7 +1551,7 @@ NpadButtonState EmulatedController::GetNpadButtons() const {
if (is_configuring) {
return {};
}
return controller.npad_button_state;
return {controller.npad_button_state.raw & GetTurboButtonMask()};
}
DebugPadButton EmulatedController::GetDebugPadButtons() const {
@@ -1419,22 +1563,12 @@ DebugPadButton EmulatedController::GetDebugPadButtons() const {
}
AnalogSticks EmulatedController::GetSticks() const {
std::unique_lock lock{mutex};
std::scoped_lock lock{mutex};
if (is_configuring) {
return {};
}
// Some drivers like stick from buttons need constant refreshing
for (auto& device : stick_devices) {
if (!device) {
continue;
}
lock.unlock();
device->SoftUpdate();
lock.lock();
}
return controller.analog_stick_state;
}
@@ -1479,6 +1613,10 @@ const CameraState& EmulatedController::GetCamera() const {
return controller.camera_state;
}
RingSensorForce EmulatedController::GetRingSensorForce() const {
return controller.ring_analog_state;
}
const NfcState& EmulatedController::GetNfc() const {
std::scoped_lock lock{mutex};
return controller.nfc_state;
@@ -1521,4 +1659,74 @@ void EmulatedController::DeleteCallback(int key) {
}
callback_list.erase(iterator);
}
void EmulatedController::TurboButtonUpdate() {
turbo_button_state = (turbo_button_state + 1) % (TURBO_BUTTON_DELAY * 2);
}
NpadButton EmulatedController::GetTurboButtonMask() const {
// Apply no mask when disabled
if (turbo_button_state < TURBO_BUTTON_DELAY) {
return {NpadButton::All};
}
NpadButtonState button_mask{};
for (std::size_t index = 0; index < controller.button_values.size(); ++index) {
if (!controller.button_values[index].turbo) {
continue;
}
switch (index) {
case Settings::NativeButton::A:
button_mask.a.Assign(1);
break;
case Settings::NativeButton::B:
button_mask.b.Assign(1);
break;
case Settings::NativeButton::X:
button_mask.x.Assign(1);
break;
case Settings::NativeButton::Y:
button_mask.y.Assign(1);
break;
case Settings::NativeButton::L:
button_mask.l.Assign(1);
break;
case Settings::NativeButton::R:
button_mask.r.Assign(1);
break;
case Settings::NativeButton::ZL:
button_mask.zl.Assign(1);
break;
case Settings::NativeButton::ZR:
button_mask.zr.Assign(1);
break;
case Settings::NativeButton::DLeft:
button_mask.left.Assign(1);
break;
case Settings::NativeButton::DUp:
button_mask.up.Assign(1);
break;
case Settings::NativeButton::DRight:
button_mask.right.Assign(1);
break;
case Settings::NativeButton::DDown:
button_mask.down.Assign(1);
break;
case Settings::NativeButton::SL:
button_mask.left_sl.Assign(1);
button_mask.right_sl.Assign(1);
break;
case Settings::NativeButton::SR:
button_mask.left_sr.Assign(1);
button_mask.right_sr.Assign(1);
break;
default:
break;
}
}
return static_cast<NpadButton>(~button_mask.raw);
}
} // namespace Core::HID
+63 -7
View File
@@ -35,19 +35,27 @@ using ControllerMotionDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeMotion::NumMotions>;
using TriggerDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeTrigger::NumTriggers>;
using ColorDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
using BatteryDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
using CameraDevices = std::unique_ptr<Common::Input::InputDevice>;
using NfcDevices = std::unique_ptr<Common::Input::InputDevice>;
using CameraDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
using RingAnalogDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
using NfcDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
using OutputDevices = std::array<std::unique_ptr<Common::Input::OutputDevice>, output_devices_size>;
using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>;
using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>;
using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>;
using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>;
using ColorParams = std::array<Common::ParamPackage, max_emulated_controllers>;
using BatteryParams = std::array<Common::ParamPackage, max_emulated_controllers>;
using CameraParams = Common::ParamPackage;
using NfcParams = Common::ParamPackage;
using CameraParams = std::array<Common::ParamPackage, max_emulated_controllers>;
using RingAnalogParams = std::array<Common::ParamPackage, max_emulated_controllers>;
using NfcParams = std::array<Common::ParamPackage, max_emulated_controllers>;
using OutputParams = std::array<Common::ParamPackage, output_devices_size>;
using ButtonValues = std::array<Common::Input::ButtonStatus, Settings::NativeButton::NumButtons>;
@@ -58,6 +66,7 @@ using ControllerMotionValues = std::array<ControllerMotionInfo, Settings::Native
using ColorValues = std::array<Common::Input::BodyColorStatus, max_emulated_controllers>;
using BatteryValues = std::array<Common::Input::BatteryStatus, max_emulated_controllers>;
using CameraValues = Common::Input::CameraStatus;
using RingAnalogValue = Common::Input::AnalogStatus;
using NfcValues = Common::Input::NfcStatus;
using VibrationValues = std::array<Common::Input::VibrationStatus, max_emulated_controllers>;
@@ -84,6 +93,10 @@ struct CameraState {
std::size_t sample{};
};
struct RingSensorForce {
f32 force;
};
struct NfcState {
Common::Input::NfcState state{};
std::vector<u8> data{};
@@ -116,6 +129,7 @@ struct ControllerStatus {
BatteryValues battery_values{};
VibrationValues vibration_values{};
CameraValues camera_values{};
RingAnalogValue ring_analog_value{};
NfcValues nfc_values{};
// Data for HID serices
@@ -129,6 +143,7 @@ struct ControllerStatus {
ControllerColors colors_state{};
BatteryLevelState battery_state{};
CameraState camera_state{};
RingSensorForce ring_analog_state{};
NfcState nfc_state{};
};
@@ -141,6 +156,7 @@ enum class ControllerTriggerType {
Battery,
Vibration,
IrSensor,
RingController,
Nfc,
Connected,
Disconnected,
@@ -294,6 +310,9 @@ public:
/// Returns the latest camera status from the controller with parameters
CameraValues GetCameraValues() const;
/// Returns the latest status of analog input from the ring sensor with parameters
RingAnalogValue GetRingSensorValues() const;
/// Returns the latest status of button input for the hid::HomeButton service
HomeButtonState GetHomeButtons() const;
@@ -324,6 +343,9 @@ public:
/// Returns the latest camera status from the controller
const CameraState& GetCamera() const;
/// Returns the latest ringcon force sensor value
RingSensorForce GetRingSensorForce() const;
/// Returns the latest ntag status from the controller
const NfcState& GetNfc() const;
@@ -341,10 +363,12 @@ public:
/**
* Sets the desired data to be polled from a controller
* @param device_index index of the controller to set the polling mode
* @param polling_mode type of input desired buttons, gyro, nfc, ir, etc.
* @return true if SetPollingMode was successfull
* @return driver result from this command
*/
bool SetPollingMode(Common::Input::PollingMode polling_mode);
Common::Input::DriverResult SetPollingMode(EmulatedDeviceIndex device_index,
Common::Input::PollingMode polling_mode);
/**
* Sets the desired camera format to be polled from a controller
@@ -353,6 +377,15 @@ public:
*/
bool SetCameraFormat(Core::IrSensor::ImageTransferProcessorFormat camera_format);
// Returns the current mapped ring device
Common::ParamPackage GetRingParam() const;
/**
* Updates the current mapped ring device
* @param param ParamPackage with ring sensor data to be mapped
*/
void SetRingParam(Common::ParamPackage param);
/// Returns true if the device has nfc support
bool HasNfc() const;
@@ -378,6 +411,9 @@ public:
*/
void DeleteCallback(int key);
/// Swaps the state of the turbo buttons
void TurboButtonUpdate();
private:
/// creates input devices from params
void LoadDevices();
@@ -432,10 +468,17 @@ private:
*/
void SetMotion(const Common::Input::CallbackStatus& callback, std::size_t index);
/**
* Updates the color status of the controller
* @param callback A CallbackStatus containing the color status
* @param index color ID of the to be updated
*/
void SetColors(const Common::Input::CallbackStatus& callback, std::size_t index);
/**
* Updates the battery status of the controller
* @param callback A CallbackStatus containing the battery status
* @param index Button ID of the to be updated
* @param index battery ID of the to be updated
*/
void SetBattery(const Common::Input::CallbackStatus& callback, std::size_t index);
@@ -445,6 +488,12 @@ private:
*/
void SetCamera(const Common::Input::CallbackStatus& callback);
/**
* Updates the ring analog sensor status of the ring controller
* @param callback A CallbackStatus containing the force status
*/
void SetRingAnalog(const Common::Input::CallbackStatus& callback);
/**
* Updates the nfc status of the controller
* @param callback A CallbackStatus containing the nfc status
@@ -465,6 +514,8 @@ private:
*/
void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
NpadButton GetTurboButtonMask() const;
const NpadIdType npad_id_type;
NpadStyleIndex npad_type{NpadStyleIndex::None};
NpadStyleIndex original_npad_type{NpadStyleIndex::None};
@@ -474,6 +525,7 @@ private:
bool system_buttons_enabled{true};
f32 motion_sensitivity{0.01f};
bool force_update_motion{false};
u32 turbo_button_state{0};
// Temporary values to avoid doing changes while the controller is in configuring mode
NpadStyleIndex tmp_npad_type{NpadStyleIndex::None};
@@ -484,7 +536,9 @@ private:
ControllerMotionParams motion_params;
TriggerParams trigger_params;
BatteryParams battery_params;
ColorParams color_params;
CameraParams camera_params;
RingAnalogParams ring_params;
NfcParams nfc_params;
OutputParams output_params;
@@ -493,7 +547,9 @@ private:
ControllerMotionDevices motion_devices;
TriggerDevices trigger_devices;
BatteryDevices battery_devices;
ColorDevices color_devices;
CameraDevices camera_devices;
RingAnalogDevices ring_analog_devices;
NfcDevices nfc_devices;
OutputDevices output_devices;
-46
View File
@@ -14,7 +14,6 @@ EmulatedDevices::EmulatedDevices() = default;
EmulatedDevices::~EmulatedDevices() = default;
void EmulatedDevices::ReloadFromSettings() {
ring_params = Common::ParamPackage(Settings::values.ringcon_analogs);
ReloadInput();
}
@@ -66,8 +65,6 @@ void EmulatedDevices::ReloadInput() {
key_index++;
}
ring_analog_device = Common::Input::CreateInputDevice(ring_params);
for (std::size_t index = 0; index < mouse_button_devices.size(); ++index) {
if (!mouse_button_devices[index]) {
continue;
@@ -122,13 +119,6 @@ void EmulatedDevices::ReloadInput() {
},
});
}
if (ring_analog_device) {
ring_analog_device->SetCallback({
.on_change =
[this](const Common::Input::CallbackStatus& callback) { SetRingAnalog(callback); },
});
}
}
void EmulatedDevices::UnloadInput() {
@@ -145,7 +135,6 @@ void EmulatedDevices::UnloadInput() {
for (auto& button : keyboard_modifier_devices) {
button.reset();
}
ring_analog_device.reset();
}
void EmulatedDevices::EnableConfiguration() {
@@ -165,7 +154,6 @@ void EmulatedDevices::SaveCurrentConfig() {
if (!is_configuring) {
return;
}
Settings::values.ringcon_analogs = ring_params.Serialize();
}
void EmulatedDevices::RestoreConfig() {
@@ -175,15 +163,6 @@ void EmulatedDevices::RestoreConfig() {
ReloadFromSettings();
}
Common::ParamPackage EmulatedDevices::GetRingParam() const {
return ring_params;
}
void EmulatedDevices::SetRingParam(Common::ParamPackage param) {
ring_params = std::move(param);
ReloadInput();
}
void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& callback,
std::size_t index) {
if (index >= device_status.keyboard_values.size()) {
@@ -430,23 +409,6 @@ void EmulatedDevices::SetMouseStick(const Common::Input::CallbackStatus& callbac
TriggerOnChange(DeviceTriggerType::Mouse);
}
void EmulatedDevices::SetRingAnalog(const Common::Input::CallbackStatus& callback) {
std::lock_guard lock{mutex};
const auto force_value = TransformToStick(callback);
device_status.ring_analog_value = force_value.x;
if (is_configuring) {
device_status.ring_analog_value = {};
TriggerOnChange(DeviceTriggerType::RingController);
return;
}
device_status.ring_analog_state.force = force_value.x.value;
TriggerOnChange(DeviceTriggerType::RingController);
}
KeyboardValues EmulatedDevices::GetKeyboardValues() const {
std::scoped_lock lock{mutex};
return device_status.keyboard_values;
@@ -462,10 +424,6 @@ MouseButtonValues EmulatedDevices::GetMouseButtonsValues() const {
return device_status.mouse_button_values;
}
RingAnalogValue EmulatedDevices::GetRingSensorValues() const {
return device_status.ring_analog_value;
}
KeyboardKey EmulatedDevices::GetKeyboard() const {
std::scoped_lock lock{mutex};
return device_status.keyboard_state;
@@ -491,10 +449,6 @@ AnalogStickState EmulatedDevices::GetMouseWheel() const {
return device_status.mouse_wheel_state;
}
RingSensorForce EmulatedDevices::GetRingSensorForce() const {
return device_status.ring_analog_state;
}
void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) {
std::scoped_lock lock{callback_mutex};
for (const auto& poller_pair : callback_list) {
-18
View File
@@ -26,11 +26,9 @@ using MouseButtonDevices = std::array<std::unique_ptr<Common::Input::InputDevice
using MouseAnalogDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickDevice = std::unique_ptr<Common::Input::InputDevice>;
using RingAnalogDevice = std::unique_ptr<Common::Input::InputDevice>;
using MouseButtonParams =
std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons>;
using RingAnalogParams = Common::ParamPackage;
using KeyboardValues =
std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardKeys>;
@@ -41,17 +39,12 @@ using MouseButtonValues =
using MouseAnalogValues =
std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickValue = Common::Input::TouchStatus;
using RingAnalogValue = Common::Input::AnalogStatus;
struct MousePosition {
f32 x;
f32 y;
};
struct RingSensorForce {
f32 force;
};
struct DeviceStatus {
// Data from input_common
KeyboardValues keyboard_values{};
@@ -59,7 +52,6 @@ struct DeviceStatus {
MouseButtonValues mouse_button_values{};
MouseAnalogValues mouse_analog_values{};
MouseStickValue mouse_stick_value{};
RingAnalogValue ring_analog_value{};
// Data for HID serices
KeyboardKey keyboard_state{};
@@ -67,7 +59,6 @@ struct DeviceStatus {
MouseButton mouse_button_state{};
MousePosition mouse_position_state{};
AnalogStickState mouse_wheel_state{};
RingSensorForce ring_analog_state{};
};
enum class DeviceTriggerType {
@@ -138,9 +129,6 @@ public:
/// Returns the latest status of button input from the mouse with parameters
MouseButtonValues GetMouseButtonsValues() const;
/// Returns the latest status of analog input from the ring sensor with parameters
RingAnalogValue GetRingSensorValues() const;
/// Returns the latest status of button input from the keyboard
KeyboardKey GetKeyboard() const;
@@ -156,9 +144,6 @@ public:
/// Returns the latest mouse wheel change
AnalogStickState GetMouseWheel() const;
/// Returns the latest ringcon force sensor value
RingSensorForce GetRingSensorForce() const;
/**
* Adds a callback to the list of events
* @param update_callback InterfaceUpdateCallback that will be triggered
@@ -224,14 +209,11 @@ private:
bool is_configuring{false};
RingAnalogParams ring_params;
KeyboardDevices keyboard_devices;
KeyboardModifierDevices keyboard_modifier_devices;
MouseButtonDevices mouse_button_devices;
MouseAnalogDevices mouse_analog_devices;
MouseStickDevice mouse_stick_device;
RingAnalogDevice ring_analog_device;
mutable std::mutex mutex;
mutable std::mutex callback_mutex;
+12
View File
@@ -304,6 +304,18 @@ Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& cal
return nfc;
}
Common::Input::BodyColorStatus TransformToColor(const Common::Input::CallbackStatus& callback) {
switch (callback.type) {
case Common::Input::InputType::Color:
return callback.color_status;
break;
default:
LOG_ERROR(Input, "Conversion from type {} to color not implemented", callback.type);
return {};
break;
}
}
void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value) {
const auto& properties = analog.properties;
float& raw_value = analog.raw_value;
+9 -1
View File
@@ -88,10 +88,18 @@ Common::Input::CameraStatus TransformToCamera(const Common::Input::CallbackStatu
* Converts raw input data into a valid nfc status.
*
* @param callback Supported callbacks: Nfc.
* @return A valid CameraObject object.
* @return A valid data tag vector.
*/
Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& callback);
/**
* Converts raw input data into a valid color status.
*
* @param callback Supported callbacks: Color.
* @return A valid Color object.
*/
Common::Input::BodyColorStatus TransformToColor(const Common::Input::CallbackStatus& callback);
/**
* Converts raw analog data into a valid analog value
* @param analog An analog object containing raw data and properties
+29 -1
View File
@@ -11,6 +11,7 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/scratch_buffer.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_auto_object.h"
@@ -325,7 +326,7 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_threa
return ResultSuccess;
}
std::vector<u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const {
std::vector<u8> HLERequestContext::ReadBufferCopy(std::size_t buffer_index) const {
const bool is_buffer_a{BufferDescriptorA().size() > buffer_index &&
BufferDescriptorA()[buffer_index].Size()};
if (is_buffer_a) {
@@ -345,6 +346,33 @@ std::vector<u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const {
}
}
std::span<const u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const {
static thread_local std::array<Common::ScratchBuffer<u8>, 2> read_buffer_a;
static thread_local std::array<Common::ScratchBuffer<u8>, 2> read_buffer_x;
const bool is_buffer_a{BufferDescriptorA().size() > buffer_index &&
BufferDescriptorA()[buffer_index].Size()};
if (is_buffer_a) {
ASSERT_OR_EXECUTE_MSG(
BufferDescriptorA().size() > buffer_index, { return {}; },
"BufferDescriptorA invalid buffer_index {}", buffer_index);
auto& read_buffer = read_buffer_a[buffer_index];
read_buffer.resize_destructive(BufferDescriptorA()[buffer_index].Size());
memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), read_buffer.data(),
read_buffer.size());
return read_buffer;
} else {
ASSERT_OR_EXECUTE_MSG(
BufferDescriptorX().size() > buffer_index, { return {}; },
"BufferDescriptorX invalid buffer_index {}", buffer_index);
auto& read_buffer = read_buffer_x[buffer_index];
read_buffer.resize_destructive(BufferDescriptorX()[buffer_index].Size());
memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), read_buffer.data(),
read_buffer.size());
return read_buffer;
}
}
std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
std::size_t buffer_index) const {
if (size == 0) {
+6 -2
View File
@@ -7,6 +7,7 @@
#include <functional>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <type_traits>
#include <vector>
@@ -270,8 +271,11 @@ public:
return domain_message_header.has_value();
}
/// Helper function to read a buffer using the appropriate buffer descriptor
[[nodiscard]] std::vector<u8> ReadBuffer(std::size_t buffer_index = 0) const;
/// Helper function to get a span of a buffer using the appropriate buffer descriptor
[[nodiscard]] std::span<const u8> ReadBuffer(std::size_t buffer_index = 0) const;
/// Helper function to read a copy of a buffer using the appropriate buffer descriptor
[[nodiscard]] std::vector<u8> ReadBufferCopy(std::size_t buffer_index = 0) const;
/// Helper function to write a buffer using the appropriate buffer descriptor
std::size_t WriteBuffer(const void* buffer, std::size_t size,
@@ -11,6 +11,7 @@
#include "core/hle/kernel/init/init_slab_setup.h"
#include "core/hle/kernel/k_code_memory.h"
#include "core/hle/kernel/k_debug.h"
#include "core/hle/kernel/k_device_address_space.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_event_info.h"
#include "core/hle/kernel/k_memory_layout.h"
@@ -43,6 +44,7 @@ namespace Kernel::Init {
HANDLER(KSharedMemoryInfo, (SLAB_COUNT(KSharedMemory) * 8), ##__VA_ARGS__) \
HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ##__VA_ARGS__) \
HANDLER(KCodeMemory, (SLAB_COUNT(KCodeMemory)), ##__VA_ARGS__) \
HANDLER(KDeviceAddressSpace, (SLAB_COUNT(KDeviceAddressSpace)), ##__VA_ARGS__) \
HANDLER(KSession, (SLAB_COUNT(KSession)), ##__VA_ARGS__) \
HANDLER(KThreadLocalPage, \
(SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), \
+6 -14
View File
@@ -24,9 +24,7 @@ private:
friend class ::Kernel::KClassTokenGenerator; \
static constexpr inline auto ObjectType = ::Kernel::KClassTokenGenerator::ObjectType::CLASS; \
static constexpr inline const char* const TypeName = #CLASS; \
static constexpr inline ClassTokenType ClassToken() { \
return ::Kernel::ClassToken<CLASS>; \
} \
static constexpr inline ClassTokenType ClassToken() { return ::Kernel::ClassToken<CLASS>; } \
\
public: \
YUZU_NON_COPYABLE(CLASS); \
@@ -37,15 +35,9 @@ public:
constexpr ClassTokenType Token = ClassToken(); \
return TypeObj(TypeName, Token); \
} \
static constexpr const char* GetStaticTypeName() { \
return TypeName; \
} \
virtual TypeObj GetTypeObj() ATTRIBUTE { \
return GetStaticTypeObj(); \
} \
virtual const char* GetTypeName() ATTRIBUTE { \
return GetStaticTypeName(); \
} \
static constexpr const char* GetStaticTypeName() { return TypeName; } \
virtual TypeObj GetTypeObj() ATTRIBUTE { return GetStaticTypeObj(); } \
virtual const char* GetTypeName() ATTRIBUTE { return GetStaticTypeName(); } \
\
private: \
constexpr bool operator!=(const TypeObj& rhs)
@@ -245,8 +237,8 @@ public:
}
template <typename U>
requires(std::derived_from<T, U> ||
std::derived_from<U, T>) constexpr KScopedAutoObject(KScopedAutoObject<U>&& rhs) {
requires(std::derived_from<T, U> || std::derived_from<U, T>)
constexpr KScopedAutoObject(KScopedAutoObject<U>&& rhs) {
if constexpr (std::derived_from<U, T>) {
// Upcast.
m_obj = rhs.m_obj;

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