Compare commits

...

167 Commits

Author SHA1 Message Date
yuzubot
bc637ceb8e "Merge Tagged PR 1340" 2020-10-19 12:01:43 +00:00
bunnei
54b977acaa Merge pull request #4783 from bunnei/nvdrv-freespace
hle: service: nvdrv: Implement nvhost_as_gpu::FreeSpace.
2020-10-18 12:41:18 -07:00
bunnei
2190f1a2b7 Merge pull request #4801 from lioncash/missing-bound
mii/manager: Make use of unused lower bound in GetRandomValue()
2020-10-17 23:32:40 -07:00
bunnei
743fe1aea3 Merge pull request #4782 from ReinUsesLisp/remove-dyn-primitive
vk_graphics_pipeline: Manage primitive topology as fixed state
2020-10-17 22:14:17 -07:00
Lioncash
c1577f3448 mii/manager: Make use of unused lower bound in GetRandomValue()
Previously, the lower bound wasn't being used and zero was being used as
the lower bound every time this function was called.

This affects the outcome of some of the randomized entries a little bit,
for example, the lower-bound for beard and mustache flags was supposed
to be 1, not 0.

Aside from these cases, the bug didn't affect anything else.
2020-10-17 09:50:04 -04:00
bunnei
1eb908bc88 Merge pull request #4797 from bunnei/bcat-errors
service: bcat: Check client connection before interacting with socket.
2020-10-16 23:28:40 -07:00
bunnei
cb708631b6 Merge pull request #4798 from lioncash/input-copy
udp/client: Take std::function by const reference with TestCommunication()
2020-10-16 21:20:01 -07:00
bunnei
363c644730 service: bcat: Check client connection before interacting with socket.
- Fixes a crash when BCAT service is offline.
2020-10-16 21:16:56 -07:00
Lioncash
30b1e71066 udp/client: Make use of designated initializers in TestCommunication()
Same behavior, but makes the callback list nicer to look at.
2020-10-16 06:23:51 -04:00
Lioncash
36cfb234d5 udp/client: Take std::function by const reference with TestCommunication()
Avoids redundant copies.
2020-10-16 06:22:29 -04:00
bunnei
64f967fd49 Merge pull request #4790 from lioncash/input-common
input_common/CMakeLists: Make some warnings errors
2020-10-15 20:59:34 -07:00
bunnei
dbd1662ae2 Merge pull request #4784 from bunnei/cancelbuffer
hle: service: vi: Implement BufferQueue::CancelBuffer.
2020-10-15 19:57:27 -07:00
Lioncash
046c0c91a3 input_common/CMakeLists: Make some warnings errors
Makes the input_common code warnings consistent with the rest of the
codebase.
2020-10-15 19:37:51 -04:00
bunnei
046cc81938 Merge pull request #4793 from bunnei/storeopencontext
service: acc: Stub IManagerForApplication::StoreOpenContext.
2020-10-14 20:42:18 -07:00
bunnei
1d714c8c7f service: acc: Stub IManagerForApplication::StoreOpenContext.
- Used by Super Mario 3D All-Stars.
2020-10-14 20:06:33 -07:00
bunnei
d47ac3ce09 Merge pull request #4772 from goldenx86/block-rdna
vk_device: Block VK_EXT_extended_dynamic_state for RDNA devices
2020-10-14 17:51:39 -07:00
bunnei
1f186f34a2 hle: service: vi: Implement BufferQueue::CancelBuffer.
- This is used by Super Mario 3D All-Stars.
2020-10-13 22:11:52 -07:00
bunnei
ca416a0fb8 Merge pull request #4787 from lioncash/conversion
audio_core/CMakeLists: Make warnings consistent with core
2020-10-13 15:30:30 -07:00
Lioncash
9f9b64d280 audio_core/CMakeLists: Make warnings consistent with core
Normalizes the warnings shared between audio_core and core.
2020-10-13 16:36:58 -04:00
Rodrigo Locatti
c5b3c8d06b Merge pull request #4786 from lioncash/flags
core/CMakeLists: Make some warnings errors
2020-10-13 16:20:44 -03:00
Lioncash
39c8d18feb core/CMakeLists: Make some warnings errors
Makes our error coverage a little more consistent across the board by
applying it to Linux side of things as well. This also makes it more
consistent with the warning settings in other libraries in the project.

This also updates httplib to 0.7.9, as there are several warning
cleanups made that allow us to enable several warnings as errors.
2020-10-13 13:16:49 -04:00
ReinUsesLisp
e4e0abc418 vk_graphics_pipeline: Manage primitive topology as fixed state
Vulkan has requirements for primitive topologies that don't play nicely
with yuzu's. Since it's only 4 bits, we can move it to fixed state
without changing the size of the pipeline key.

- Fixes a regression on recent Nvidia drivers on Fire Emblem: Three
  Houses.
2020-10-13 04:08:33 -03:00
bunnei
d291fc1a51 Merge pull request #3929 from FearlessTobi/ticket-keys
file_sys/nsp: Make SetTicketKeys actually do something
2020-10-12 17:58:36 -07:00
bunnei
b260847218 hle: service: nvdrv: Implement nvhost_as_gpu::FreeSpace.
- This is used by Super Mario 3D All-Stars.
2020-10-12 17:39:14 -07:00
bunnei
4c348f4069 Merge pull request #4766 from ReinUsesLisp/tmml-cube
shader/texture: Implement CUBE texture type for TMML and fix arrays
2020-10-12 12:53:57 -07:00
bunnei
419a59a7b1 Merge pull request #4775 from ReinUsesLisp/enforce-class-memaccess
video_core: Enforce -Wclass-memaccess
2020-10-09 23:38:02 -07:00
bunnei
f250011ba0 Merge pull request #4757 from german77/BetterMotion
InputCommon: Add compatibility with only accelerometer and auto calibrate for drift
2020-10-09 23:37:08 -07:00
ReinUsesLisp
e1600b0962 video_core: Enforce -Wclass-memaccess 2020-10-09 16:46:11 -03:00
LC
61b246a3a9 Merge pull request #4771 from ReinUsesLisp/warn-unused-var
video_core: Enforce -Wunused-variable and -Wunused-but-set-variable
2020-10-08 21:10:31 -04:00
goldenx86
0120e5b1d9 vk_device: Block VK_EXT_extended_dynamic_state for RDNA devices
RDNA devices seem to crash when using VK_EXT_extended_dynamic_state in
the latest 20.9.2 proprietary Windows drivers. As a workaround, for now
we block device names corresponding to current RDNA released products.
2020-10-08 21:27:49 -03:00
bunnei
06e65de93c Merge pull request #4677 from german77/ShakeFromButton
InputCommon: Add random motion input for buttons
2020-10-08 10:18:39 -07:00
Rodrigo Locatti
7a99226785 Merge pull request #4765 from ReinUsesLisp/fix-sort-devices
renderer_vulkan/wrapper: Fix physical device sorting
2020-10-08 00:54:44 -03:00
ReinUsesLisp
dffaffaac1 shader/texture: Implement CUBE texture type for TMML and fix arrays
TMML takes an array argument that has no known meaning, this one appears
as the first component in gpr8 followed by s, t and r. Skip this
component when arrays are being used. Also implement CUBE texture types.

- Used by Pikmin 3: Deluxe Demo.
2020-10-07 23:17:46 -03:00
bunnei
3446eb79b5 Merge pull request #4731 from lat9nq/mingw-zstd-fix
common: Use system zstd on Linux
2020-10-07 17:57:14 -07:00
bunnei
92adb69fa7 Merge pull request #4736 from Morph1984/home-button-input-protection-stub
hid: Stub HomeButtonInputProtection service commands
2020-10-07 14:54:05 -07:00
ReinUsesLisp
cd3e959f23 renderer_vulkan/wrapper: Fix physical device sorting
The old code had a sort function that was invalid and it didn't work as
expected when the base vector had a different order (e.g. renderdoc was
attached).

This sorts devices as expected and fixes a debug assert on MSVC.
2020-10-07 17:13:22 -03:00
bunnei
cc0dc3280d Merge pull request #4710 from Morph1984/fix-integrated-updates
submission_package: Fix updates integrated into cartridge images.
2020-10-06 22:27:52 -07:00
bunnei
32b4627a9c Merge pull request #4737 from Morph1984/setshimlibraryversion-stub
capsrv: Stub 3 variants of SetShimLibraryVersion
2020-10-06 21:39:38 -07:00
bunnei
e9b81e9f01 Merge pull request #4727 from FrogTheFrog/patch-1
Reduce the "shake" requirements when configuring UDP.
2020-10-06 15:29:28 -07:00
bunnei
614bd0ee8c Merge pull request #4742 from german77/InputFilter
HID: Only use inputs corresponding to controller type
2020-10-05 21:40:09 -07:00
german
a54aee290f Address comments 2020-10-04 18:15:53 -05:00
bunnei
de4cadca1f Merge pull request #4648 from zhaobot/tx-update-20200911153748
Update translations (2020-09-11)
2020-10-03 22:30:38 -07:00
german
a220d8799e Add compatibility with only accelerometer and auto calibrate for drift 2020-10-03 22:22:01 -05:00
ReinUsesLisp
2a24b1c973 video_core: Enforce -Wunused-variable and -Wunused-but-set-variable 2020-10-02 21:19:35 -03:00
bunnei
182cf7d631 Merge pull request #4734 from german77/motionfusion
HID: Add Stub for EnableSixAxisSensorFusion
2020-10-01 22:39:39 -07:00
german
2f47b27654 Only use inputs corresponding to controller type 2020-10-01 19:39:53 -05:00
german
283616dbd8 Stubbed EnableSixAxisSensorFusion 2020-09-30 10:00:24 -05:00
David
4d0ae1a17a Merge pull request #4291 from german77/ImplementControllerRumble
input_common: First implementation of controller rumble
2020-09-30 21:24:11 +10:00
David
f7808f5658 Merge pull request #4726 from lioncash/applet
frontend/controller: Eliminate dependency on the global system instance
2020-09-30 21:22:45 +10:00
Morph
91bd2281bf caps_c: Stub SetShimLibraryVersion
- Used by caps_su SetShimLibraryVersion
2020-09-30 07:19:46 -04:00
Morph
7d287a6fb0 caps_u: Stub SetShimLibraryVersion
- Used in Super Smash Bros. Ultimate
2020-09-30 07:19:46 -04:00
Morph
9a251339dc caps_su: Properly stub SetShimLibraryVersion 2020-09-30 07:19:46 -04:00
Morph
6380731486 hid: Stub HomeButtonInputProtection service commands
- Used in 1-2 Switch. Given that we do not emulate the functionality of the home button yet, we can stub this for now.
2020-09-30 06:38:24 -04:00
LC
1ba0b077fc Merge pull request #4733 from ReinUsesLisp/game-list-leak
qt/game_list: Give GameListSearchField::KeyReleaseEater a parent
2020-09-30 05:54:18 -04:00
LC
cb56eaee41 Merge pull request #4732 from ReinUsesLisp/wall-clock-destr
common/wall_clock: Add virtual destructors
2020-09-30 05:53:12 -04:00
LC
3665a05488 Merge pull request #4735 from goldenx86/patch-1
Remove ext_extended_dynamic_state blacklist
2020-09-30 05:52:47 -04:00
bunnei
392c1b96bc Merge pull request #4705 from german77/SplitMotionPoller
HID: Use different timing for motion
2020-09-30 01:04:22 -07:00
Lukas Senionis
6ee1a784b8 Reduce the "shake" requirements when configuring UDP. 2020-09-30 10:30:33 +03:00
Matías Locatti
d7843b8ef2 Remove ext_extended_dynamic_state blacklist
Latest AMD 20.9.2 driver fixed this, there's no reason to keep it blocked, as the previous stable signed driver release doesn't include the extension.
2020-09-30 03:13:38 -03:00
ReinUsesLisp
771a9c21cc common/wall_clock: Add virtual destructors
From -fsanitize=address, this code wasn't calling the proper destructor.
Adding virtual destructors for each inherited class and the base class
fixes this bug.

While we are at it, mark the functions as final.
2020-09-30 02:53:34 -03:00
bunnei
385b5602e4 Update yuzu-patreon-step2.yml to set build timeout to 120 min
This is currently necessary to build ffmpeg
2020-09-29 22:17:50 -07:00
bunnei
a1e3f6e27b Merge pull request #4728 from Morph1984/applets-on-top
main: Allow applets to display on top while fullscreen
2020-09-29 15:46:44 -07:00
bunnei
09609dd50e Merge pull request #4721 from lioncash/genfn
codec: Make lookup table static constexpr
2020-09-29 15:16:24 -07:00
bunnei
2a82f1b08b Merge pull request #4722 from lioncash/casting
cubeb_sink: Use static_cast instead of reinterpret_cast in DataCallback()
2020-09-29 15:09:12 -07:00
bunnei
02ea62568f Merge pull request #1703 from DarkLordZach/nvdec-ioctl
nvdrv: Stub nvdec/vic ioctls to bypass nvdec movies
2020-09-29 15:00:48 -07:00
ReinUsesLisp
ae6df703f5 qt/game_list: Give GameListSearchField::KeyReleaseEater a parent
This fixes a memory leak as KeyReleaseEater's destructor was never
called.
2020-09-29 16:23:16 -03:00
german
ab88c2f611 First implementation of controller rumble 2020-09-29 10:38:25 -04:00
lat9nq
2cbce77b92 CMakeLists: use system zstd on Linux
From what I understand, this tells CMake to use the system, not conan,
version of zstd. Required to build on the coming MinGW Docker container.
2020-09-28 21:11:39 -04:00
lat9nq
9d665cb8db CMakeLists: fix for finding zstd on linux-mingw 2020-09-28 20:28:47 -04:00
bunnei
a8be822e8e Merge pull request #4719 from lioncash/audio-warn
audio_core: Resolve sign conversion warnings
2020-09-27 01:52:59 -07:00
Rodrigo Locatti
e5a1e0a76d Merge pull request #4724 from lat9nq/fix-vulkan-nvidia-allocate-2
vk_stream_buffer: Fix initializing Vulkan with NVIDIA on Linux
2020-09-26 23:52:49 +00:00
bunnei
442096298e Merge pull request #4703 from lioncash/desig7
shader/registry: Make use of designated initializers where applicable
2020-09-26 15:23:15 -07:00
Morph
86e4aa81e9 main: Allow applets to display on top while fullscreen
Using the Qt::WindowStaysOnTopHint flag allows these dialogs to show up on top while running in fullscreen. However, if yuzu goes out of focus (by alt-tabbing or otherwise), this flag does not seem to have an effect.
2020-09-26 06:55:47 -04:00
bunnei
fbb5ca2633 Merge pull request #4718 from lioncash/vk
vk_command_pool: Add missing header guard
2020-09-26 00:13:48 -07:00
bunnei
891090799c Merge pull request #4720 from lioncash/header
audio_core: Remove unnecessary inclusions
2020-09-25 22:04:26 -07:00
bunnei
ad76b00f1e Merge pull request #4723 from lioncash/typo
behavior_info: Fix typo Renerer -> Renderer
2020-09-25 22:03:59 -07:00
Lioncash
5c4e237902 core: Mark GetInstance() as deprecated
This way it's obvious that this function shouldn't be used in any future
code.
2020-09-25 19:23:23 -04:00
Lioncash
3e4a0a13cb frontend/controller: Eliminate dependency on the global system instance 2020-09-25 19:23:20 -04:00
german
2978232390 Add random motion input to keyboard 2020-09-25 17:59:52 -05:00
german
03b574ae22 Add random motion input to SDL 2020-09-25 17:59:52 -05:00
Lioncash
90c6141164 command_generator: Make lookup table static constexpr
Allows compilers to elide needing to push these values on the stack
every time the function is called.
2020-09-25 18:33:04 -04:00
lat9nq
ca26fd0f42 vk_stream_buffer: Fix initializing Vulkan with NVIDIA on Linux
The previous fix only partially solved the issue, as only certain GPUs that needed 9 or less MiB subtracted would work (i.e. GTX 980 Ti, GT 730). This takes from DXVK's example to divide `heap_size` by 2 to determine `allocable_size`. Additionally tested on my Quadro K4200, which previously required setting it to 12 to boot.
2020-09-25 17:42:59 -04:00
Lioncash
dc83ca8914 behavior_info: Fix typo Renerer -> Renderer 2020-09-25 17:14:02 -04:00
Lioncash
4073931305 cubeb_sink: Use static_cast instead of reinterpret_cast in DataCallback()
Conversions from void* to the proper data type are well-defined and
supported by static_cast. We don't need to use reinterpret_cast here.
2020-09-25 17:10:02 -04:00
Lioncash
7c0908f301 codec: Make lookup table static constexpr
Allows compilers to elide needing to push these values on the stack
every time the function is called.
2020-09-25 14:24:25 -04:00
Lioncash
966966dc02 audio_core: Remove unnecessary inclusions
Same behavior, but removes header dependencies where they don't need to
be.
2020-09-25 13:19:42 -04:00
Lioncash
8b4ecf22d4 audio_core: Resolve sign conversion warnings
While were at it, we can also enable sign conversion warnings and other
common warnings as errors to prevent these from creeping back into the
codebase.
2020-09-25 01:22:47 -04:00
Lioncash
111852a983 effect_context: Make use of explicit where applicable
While we're at it we can make the destructor of the base class virtual
to ensure that any polymorphism issues never occur.
2020-09-25 00:27:11 -04:00
Lioncash
940d85241b vk_command_pool: Move definition of Pool into the cpp file
Allows the implementation details to be changed without recompiling any
files that include this header.
2020-09-25 00:15:52 -04:00
Lioncash
4ed4bba305 vk_command_pool: Make use of override on destructor 2020-09-25 00:14:10 -04:00
Lioncash
e0f2db4376 vk_command_pool: Add missing header guard 2020-09-25 00:12:45 -04:00
LC
4d4afc1502 Merge pull request #4717 from lioncash/debug
service: Restore "unused" function
2020-09-25 00:07:19 -04:00
Lioncash
f3a1bf53f9 service: Restore "unused" function
Turns out this function is actually used, but within a trace log.
2020-09-25 00:06:40 -04:00
bunnei
2634e3c6eb Merge pull request #4711 from lioncash/move5
arithmetic_integer_immediate: Make use of std::move where applicable
2020-09-24 21:02:42 -07:00
Morph
3602df7f1f submission_package: Fix updates integrated into cartridge images. 2020-09-24 17:23:14 -04:00
bunnei
fa4294cc6f Merge pull request #4678 from Morph1984/LoadOpenContext-partial-impl
acc: Partially implement LoadOpenContext
2020-09-24 11:21:25 -07:00
Lioncash
e3a615a616 arithmetic_integer_immediate: Make use of std::move where applicable
Same behavior, minus any redundant atomic reference count increments and
decrements.
2020-09-24 13:28:45 -04:00
bunnei
d66b897a6d Merge pull request #4674 from ReinUsesLisp/timeline-semaphores
renderer_vulkan: Make unconditional use of VK_KHR_timeline_semaphore
2020-09-23 18:24:27 -07:00
german
ddff03cff5 Use different timing for motion 2020-09-23 19:09:33 -05:00
bunnei
10e8acc451 Merge pull request #4618 from german77/GcAdapterAutoMap
Add automap feature for GC adapter
2020-09-23 15:55:26 -07:00
Lioncash
77532ebde3 shader/registry: Silence a -Wshadow warning 2020-09-23 15:10:25 -04:00
Lioncash
cd6f4f7eed shader/registry: Remove unnecessary namespace qualifiers
Using statements already make these unnecessary.
2020-09-23 15:08:34 -04:00
Rodrigo Locatti
8b0f334e0c Merge pull request #4702 from lioncash/doc-warn
memory: Resolve a -Wdocumentation warning
2020-09-23 19:07:47 +00:00
Rodrigo Locatti
c307ae2402 Merge pull request #4701 from lioncash/unused-proto
install_dialog: Remove unused function prototype
2020-09-23 19:07:27 +00:00
Rodrigo Locatti
6d9661939f Merge pull request #4700 from lioncash/copies
game_list: Eliminate redundant argument copies
2020-09-23 19:06:47 +00:00
Lioncash
ffeb4ef83e shader/registry: Make use of designated initializers where applicable
Same behavior, less repetition.
2020-09-23 15:06:25 -04:00
Lioncash
b14d344dfc memory: Resolve a -Wdocumentation warning
memory doesn't exist as a parameter any more.
2020-09-23 13:39:27 -04:00
Lioncash
aa35e51fcd install_dialog: Make use of [[nodiscard]] where applicable
Allows the compiler to warn against cases where the return value isn't
used (which would be a bug).
2020-09-23 13:22:04 -04:00
Lioncash
e107870bc8 install_dialog: Remove unused function prototype
This function doesn't have an implementation, so it can be removed to
prevent others from unintentionally using it.
2020-09-23 13:20:12 -04:00
Lioncash
f43a1da808 game_list: Make game list function naming consistent
Makes the naming consistent with the rest of the functions that are
present.
2020-09-23 11:28:11 -04:00
Lioncash
d264b7375c game_list: Eliminate redundant argument copies
Several functions can be taken by const reference to avoid copies
2020-09-23 11:20:12 -04:00
Rodrigo Locatti
b8219ec838 Merge pull request #4699 from lioncash/move3
control_flow: Make use of std::move in InsertBranch()
2020-09-23 06:20:59 +00:00
Lioncash
0dc6967ff1 control_flow: emplace elements in place within TryQuery()
Places data structures where they'll eventually be moved to to avoid
needing to even move them in the first place.
2020-09-22 22:54:36 -04:00
Lioncash
fcd0145eb5 control_flow: Make use of std::move in InsertBranch()
Avoids unnecessary atomic increments and decrements.
2020-09-22 22:48:09 -04:00
Rodrigo Locatti
2b863c9aa3 Merge pull request #4698 from lioncash/optional-null
General: Make use of std::nullopt where applicable
2020-09-22 23:37:51 +00:00
Lioncash
ff45c39578 General: Make use of std::nullopt where applicable
Allows some implementations to avoid completely zeroing out the internal
buffer of the optional, and instead only set the validity byte within
the structure.

This also makes it consistent how we return empty optionals.
2020-09-22 17:32:33 -04:00
bunnei
c07fd2898b Merge pull request #4697 from lioncash/copy5
ips_layer: Eliminate a redundant copy in Parse()
2020-09-22 13:42:47 -07:00
Lioncash
a881efbf26 ips_layer: Eliminate a redundant copy in Parse()
Prevents unnecessary copying of the line being parsed.
2020-09-22 16:38:45 -04:00
bunnei
53829d4cbd Merge pull request #4675 from Morph1984/fix-boot-multicontent
submission_package: Account for multi-content NSPs
2020-09-21 16:36:46 -07:00
Morph
7a504a9365 acc: Stub LoadOpenContext
This is used in multiple games such as:
- Clubhouse Games: 51 Worldwide Classics
- Grandia HD Collection
- XCOM 2 Collection
- Baldur's Gate 1/2
- Dr Kawashima's Brain Training
- Super Mario 3D All-Stars
2020-09-21 01:01:02 -04:00
Rodrigo Locatti
a2eb44db82 Merge pull request #4692 from ReinUsesLisp/remove-vsync
renderer_opengl: Remove emulated mailbox presentation
2020-09-21 00:21:32 +00:00
bunnei
754109fd54 Merge pull request #4683 from Morph1984/NpadHandheldActivationMode-impl
hid: Implement Get/SetNpadHandheldActivationMode
2020-09-20 12:39:20 -07:00
ReinUsesLisp
7003090187 renderer_opengl: Remove emulated mailbox presentation
Emulated mailbox presentation was causing performance issues on
Nvidia's OpenGL driver. Remove it.
2020-09-20 16:29:41 -03:00
bunnei
8a85a562ed Merge pull request #4643 from FearlessTobi/decrease-pad-update-interval
Test: Decrease pad_update_ns
2020-09-19 00:39:50 -07:00
ReinUsesLisp
4f5bbe56ba vk_query_cache: Hack counter destructor to avoid reserving queries
This is a hack to destroy all HostCounter instances before the base
class destructor is called. The query cache should be redesigned to have
a proper ownership model instead of using shared pointers.

For now, destroy the host counter hierarchy from the derived class
destructor.
2020-09-19 01:47:29 -03:00
ReinUsesLisp
58b0ae84b5 renderer_vulkan: Make unconditional use of VK_KHR_timeline_semaphore
This reworks how host<->device synchronization works on the Vulkan
backend. Instead of "protecting" resources with a fence and signalling
these as free when the fence is known to be signalled by the host GPU,
use timeline semaphores.

Vulkan timeline semaphores allow use to work on a subset of D3D12
fences. As far as we are concerned, timeline semaphores are a value set
by the host or the device that can be waited by either of them.

Taking advantange of this, we can have a monolithically increasing
atomic value for each submission to the graphics queue. Instead of
protecting resources with a fence, we simply store the current logical
tick (the atomic value stored in CPU memory). When we want to know if a
resource is free, it can be compared to the current GPU tick.

This greatly simplifies resource management code and the free status of
resources should have less false negatives.

To workaround bugs in validation layers, when these are attached there's
a thread waiting for timeline semaphores.
2020-09-19 01:46:37 -03:00
german
c5e257017f Add automap feature for GC adapter 2020-09-18 16:51:16 -05:00
Rodrigo Locatti
059dd724d6 Merge pull request #4684 from lioncash/desig4
fermi_2d: Make use of designated initializers
2020-09-18 19:14:56 +00:00
Lioncash
91bca9eb0b fermi_2d: Make use of designated initializers
Same behavior, less repetition. We can also ensure all members of Config
are initialized.
2020-09-18 13:55:21 -04:00
Morph
ab961e0701 hid: Implement Get/SetNpadHandheldActivationMode
- Used in Clubhouse Games: 51 Worldwide Classics
2020-09-18 10:10:30 -04:00
David
050a4a401b Merge pull request #4680 from Morph1984/fix-motion-mapping
configure_input_player: Fixes motion mapping using ConfigureButtonClick
2020-09-18 21:03:50 +10:00
Morph
70499b8cbd configure_input_player: Fixes motion mapping using ConfigureButtonClick 2020-09-18 03:56:31 -04:00
bunnei
8568f44ffa Merge pull request #4647 from Morph1984/readd-context-menu
configure_input_player: Re-add "Clear" context menu option
2020-09-17 22:59:13 -07:00
bunnei
669005b75e Merge pull request #4676 from Morph1984/GetPreviousProgramIndex-impl
am: Stub GetPreviousProgramIndex
2020-09-17 22:12:57 -07:00
Morph
40a72e9cd5 am: Stub GetPreviousProgramIndex
- Used in Super Mario 3D All-Stars
2020-09-17 22:03:02 -04:00
Morph
65d9def873 configure_input_player: Re-add "Clear" context menu option
The context menu was removed in Mjölnir Part 1 as part of the input rewrite as we were unaware of it's usage statistics.
However, as this was the only way to clear the inputs of individual buttons, this PR will re-add it back in.
2020-09-17 21:57:06 -04:00
Morph
41c2f5200c submission_package: Account for multi-content NSPs
Previously we assumed a submission package can only contain one Program NCA with a single TitleID.
However, Super Mario 3D All-Stars contains four Program NCAs, each with their unique TitleIDs.
This accounts for the existence of multi-content games such as this one.
- Fixes booting Super Mario 3D All-Stars from the games list.
2020-09-17 20:44:51 -04:00
Rodrigo Locatti
53fc5d0190 Merge pull request #4670 from lioncash/initializer
arm_dynarmic_cp15: Initialize member variables
2020-09-17 21:20:53 +00:00
Rodrigo Locatti
9bdca01c27 Merge pull request #4665 from lioncash/sm-kernel
service/sm: Eliminate dependency on the global system instance
2020-09-17 21:20:39 +00:00
Rodrigo Locatti
8100275309 Merge pull request #4666 from lioncash/unused-func
service: Remove unused funcation
2020-09-17 21:19:48 +00:00
Rodrigo Locatti
131532b570 Merge pull request #4671 from lioncash/nfp-copy
command_generator/nfp: Eliminate unnecessary copies
2020-09-17 21:19:12 +00:00
Rodrigo Locatti
31461589c5 Merge pull request #4672 from lioncash/narrowing
decoder/texture: Eliminate narrowing conversion in GetTldCode()
2020-09-17 21:17:54 +00:00
Rodrigo Locatti
9f51242524 Merge pull request #4673 from lioncash/fallthrough
decode/image: Eliminate switch fallthrough in DecodeImage()
2020-09-17 21:17:16 +00:00
bunnei
3f6d83b27c Merge pull request #4594 from german77/MotionHID
hid/configuration: Implement motion controls to HID
2020-09-17 12:39:01 -07:00
Lioncash
4944d48ee8 decode/image: Eliminate switch fallthrough in DecodeImage()
Fortunately this didn't result in any issues, given the block that code
was falling through to would immediately break.
2020-09-17 15:12:18 -04:00
Lioncash
ffc66f089d decoder/texture: Eliminate narrowing conversion in GetTldCode()
The assignment was previously truncating a u64 value to a bool.
2020-09-17 15:04:17 -04:00
Lioncash
362e2940be audio_core/command_generator: Use const references where applicable
In a lot of cases, we can make use of const references rather than
non-const references.

While we're in the area we can silence some truncation and sign
conversion warnings.
2020-09-17 13:52:55 -04:00
Lioncash
9539e4d8fd audio_core/command_generator: Avoid an unnecessary copy in GenerateFinalMixCommand() 2020-09-17 13:45:24 -04:00
Lioncash
aca3621146 nfp: Eliminate two unnecessary copies
GetAmiiboBuffer() returns by const reference, so we can use a reference
instead of taking the returned buffer by value.
2020-09-17 13:35:55 -04:00
Lioncash
1ee9ceb5af arm_dynarmic_cp15: Initialize member variables
Ensures that the member variables are always initialized to a
deterministic value on creation.
2020-09-17 13:03:49 -04:00
bunnei
382bf1faf4 Merge pull request #4668 from lioncash/port
control_metadata: Resolve typo in Portuguese language name
2020-09-17 09:55:01 -07:00
Lioncash
02b8b6677a control_metadata: Resolve typo in Portuguese language name
This isn't used anywhere, so this is a trivial fix.
2020-09-17 11:45:30 -04:00
Lioncash
8bbd82863d service: Remove unused funcation
This is now completely unused, so it can be removed.
2020-09-17 11:03:26 -04:00
Lioncash
057aa6275d service/sm: Slightly more efficient string name validation
We can check the end of the string first for null-termination, rather
than the beginning of the string.
2020-09-17 10:54:12 -04:00
Lioncash
78b1bc3b61 service/sm: Eliminate dependency on the global system instance 2020-09-17 10:43:54 -04:00
The yuzu Community
b5784e9af2 Update translations (2020-09-11) 2020-09-11 15:38:10 +00:00
FearlessTobi
57162e1df3 Test: Decrease pad_update_ns
There have been reports of quite heavy input lag in the past.
Compared to Citra for example, our pad_update_ns value is very high.
So let's decrease it and see if it helps with this problem.
2020-09-10 16:38:53 +02:00
Morph
5b6268d26a configure_input: Hook up the motion button and checkbox
This allows toggling motion on or off, and allows access to the motion configuration.
Also changes the [waiting] text for motion buttons to Shake! as this is how motion is connected to a player.
2020-09-05 09:46:34 -04:00
german
797564599f Minor cleanup 2020-09-05 09:42:21 -04:00
german
6ee8eab670 Add cemu hook changes related to PR #4609 2020-09-04 21:48:13 -05:00
german
0774b17846 Remove RealMotionDevice 2020-09-04 21:48:13 -05:00
Morph
8e18b61972 configure_input_player: Show/hide motion buttons based on the controller 2020-09-04 21:48:13 -05:00
Morph
df3cbd4758 controllers/npad: Simplify motion entry assignment
Simplifies the motion assignment in the Dual Joycon entry and assigns index 1 of the motion entry (Motion 2) for the right joycon.
2020-09-04 21:48:13 -05:00
german
ff679f3d17 Include HID and configuration changes related to motion 2020-09-04 21:48:03 -05:00
FearlessTobi
4d4bbe756f file_sys/nsp: Make SetTicketKeys actually do something
Previously, the method wasn't modifying any class state and therefore not having any effects when called.
Since this has been the case for a very long time now, I'm not sure if we couldn't just remove this method altogether.
2020-07-18 02:02:39 +02:00
bunnei
1adf640d37 service: nvhost_vic: Ignore Submit commands. 2020-06-04 22:32:28 -04:00
Zach Hilman
34635a42c0 nvdrv: Stub nvdec/vic ioctls to bypass nvdec movies 2020-06-04 22:32:28 -04:00
225 changed files with 58987 additions and 3548 deletions

View File

@@ -9,6 +9,7 @@ stages:
displayName: 'build'
jobs:
- job: build
timeoutInMinutes: 120
displayName: 'windows-msvc'
pool:
vmImage: windows-2019

4749
dist/languages/de.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4757
dist/languages/es.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4732
dist/languages/fr.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4724
dist/languages/it.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4752
dist/languages/ja_JP.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4719
dist/languages/nl.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4713
dist/languages/pl.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4757
dist/languages/pt_BR.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4725
dist/languages/pt_PT.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4720
dist/languages/ru_RU.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4747
dist/languages/zh_CN.ts vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -90,6 +90,9 @@ if (ENABLE_WEB_SERVICE)
target_include_directories(httplib INTERFACE ./httplib)
target_compile_definitions(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
if (WIN32)
target_link_libraries(httplib INTERFACE crypt32 cryptui ws2_32)
endif()
endif()
# Opus

File diff suppressed because it is too large Load Diff

View File

@@ -44,6 +44,19 @@ add_library(audio_core STATIC
create_target_directory_groups(audio_core)
if (NOT MSVC)
target_compile_options(audio_core PRIVATE
-Werror=conversion
-Werror=ignored-qualifiers
-Werror=implicit-fallthrough
-Werror=reorder
-Werror=sign-compare
-Werror=unused-but-set-parameter
-Werror=unused-but-set-variable
-Werror=unused-variable
)
endif()
target_link_libraries(audio_core PUBLIC common core)
target_link_libraries(audio_core PRIVATE SoundTouch)

View File

@@ -55,7 +55,8 @@ void Filter::Process(std::vector<s16>& signal) {
/// @param total_count The total number of biquads to be cascaded.
/// @param index 0-index of the biquad to calculate the Q value for.
static double CascadingBiquadQ(std::size_t total_count, std::size_t index) {
const double pole = M_PI * (2 * index + 1) / (4.0 * total_count);
const auto pole =
M_PI * static_cast<double>(2 * index + 1) / (4.0 * static_cast<double>(total_count));
return 1.0 / (2.0 * std::cos(pole));
}

View File

@@ -146,7 +146,7 @@ std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input,
return {};
if (ratio <= 0) {
LOG_CRITICAL(Audio, "Nonsensical interpolation ratio {}", ratio);
LOG_ERROR(Audio, "Nonsensical interpolation ratio {}", ratio);
return input;
}
@@ -164,7 +164,8 @@ std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input,
const std::size_t num_frames{input.size() / 2};
std::vector<s16> output;
output.reserve(static_cast<std::size_t>(input.size() / ratio + InterpolationState::taps));
output.reserve(static_cast<std::size_t>(static_cast<double>(input.size()) / ratio +
InterpolationState::taps));
for (std::size_t frame{}; frame < num_frames; ++frame) {
const std::size_t lut_index{(state.fraction >> 8) * InterpolationState::taps};

View File

@@ -3,16 +3,13 @@
// Refer to the license.txt file included.
#include <vector>
#include "audio_core/algorithm/interpolate.h"
#include "audio_core/audio_out.h"
#include "audio_core/audio_renderer.h"
#include "audio_core/codec.h"
#include "audio_core/common.h"
#include "audio_core/info_updater.h"
#include "audio_core/voice_context.h"
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/writable_event.h"
#include "core/memory.h"
#include "core/settings.h"

View File

@@ -21,7 +21,6 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/swap.h"
#include "core/hle/kernel/object.h"
#include "core/hle/result.h"
namespace Core::Timing {

View File

@@ -57,15 +57,15 @@ bool BehaviorInfo::IsLongSizePreDelaySupported() const {
return AudioCommon::IsRevisionSupported(3, user_revision);
}
bool BehaviorInfo::IsAudioRenererProcessingTimeLimit80PercentSupported() const {
bool BehaviorInfo::IsAudioRendererProcessingTimeLimit80PercentSupported() const {
return AudioCommon::IsRevisionSupported(5, user_revision);
}
bool BehaviorInfo::IsAudioRenererProcessingTimeLimit75PercentSupported() const {
bool BehaviorInfo::IsAudioRendererProcessingTimeLimit75PercentSupported() const {
return AudioCommon::IsRevisionSupported(4, user_revision);
}
bool BehaviorInfo::IsAudioRenererProcessingTimeLimit70PercentSupported() const {
bool BehaviorInfo::IsAudioRendererProcessingTimeLimit70PercentSupported() const {
return AudioCommon::IsRevisionSupported(1, user_revision);
}

View File

@@ -49,9 +49,9 @@ public:
bool IsAdpcmLoopContextBugFixed() const;
bool IsSplitterSupported() const;
bool IsLongSizePreDelaySupported() const;
bool IsAudioRenererProcessingTimeLimit80PercentSupported() const;
bool IsAudioRenererProcessingTimeLimit75PercentSupported() const;
bool IsAudioRenererProcessingTimeLimit70PercentSupported() const;
bool IsAudioRendererProcessingTimeLimit80PercentSupported() const;
bool IsAudioRendererProcessingTimeLimit75PercentSupported() const;
bool IsAudioRendererProcessingTimeLimit70PercentSupported() const;
bool IsElapsedFrameCountSupported() const;
bool IsMemoryPoolForceMappingEnabled() const;
bool IsFlushVoiceWaveBuffersSupported() const;

View File

@@ -16,8 +16,9 @@ std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM
constexpr std::size_t FRAME_LEN = 8;
constexpr std::size_t SAMPLES_PER_FRAME = 14;
constexpr std::array<int, 16> SIGNED_NIBBLES = {
{0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}};
static constexpr std::array<int, 16> SIGNED_NIBBLES{
0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1,
};
const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME;
const std::size_t ret_size =

View File

@@ -38,7 +38,7 @@ using ADPCM_Coeff = std::array<s16, 16>;
* @param state ADPCM state, this is updated with new state
* @return Decoded stereo signed PCM16 data, sample_count in length
*/
std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff,
std::vector<s16> DecodeADPCM(const u8* data, std::size_t size, const ADPCM_Coeff& coeff,
ADPCMState& state);
}; // namespace AudioCore::Codec

View File

@@ -152,7 +152,7 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) {
if (!destination_data->IsConfigured()) {
continue;
}
if (destination_data->GetMixId() >= mix_context.GetCount()) {
if (destination_data->GetMixId() >= static_cast<int>(mix_context.GetCount())) {
continue;
}
@@ -196,7 +196,7 @@ void CommandGenerator::PreCommand() {
for (std::size_t i = 0; i < splitter_context.GetInfoCount(); i++) {
const auto& base = splitter_context.GetInfo(i);
std::string graph = fmt::format("b[{}]", i);
auto* head = base.GetHead();
const auto* head = base.GetHead();
while (head != nullptr) {
graph += fmt::format("->{}", head->GetMixId());
head = head->GetNextDestination();
@@ -214,7 +214,7 @@ void CommandGenerator::PostCommand() {
void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
s32 channel) {
auto& in_params = voice_info.GetInParams();
const auto& in_params = voice_info.GetInParams();
const auto depop = in_params.should_depop;
if (depop) {
@@ -405,7 +405,7 @@ void CommandGenerator::GenerateBiquadFilterEffectCommand(s32 mix_buffer_offset,
}
void CommandGenerator::GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* info, bool enabled) {
auto aux = dynamic_cast<EffectAuxInfo*>(info);
auto* aux = dynamic_cast<EffectAuxInfo*>(info);
const auto& params = aux->GetParams();
if (aux->GetSendBuffer() != 0 && aux->GetRecvBuffer() != 0) {
const auto max_channels = params.count;
@@ -435,7 +435,7 @@ void CommandGenerator::GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* inf
GetMixBuffer(output_index), worker_params.sample_count, offset, write_count);
memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP));
if (samples_read != worker_params.sample_count &&
if (samples_read != static_cast<int>(worker_params.sample_count) &&
samples_read <= params.sample_count) {
std::memset(GetMixBuffer(output_index), 0, params.sample_count - samples_read);
}
@@ -571,7 +571,7 @@ void CommandGenerator::GenerateSubMixCommand(ServerMixInfo& mix_info) {
if (dumping_frame) {
LOG_DEBUG(Audio, "(DSP_TRACE) GenerateSubMixCommand");
}
auto& in_params = mix_info.GetInParams();
const auto& in_params = mix_info.GetInParams();
GenerateDepopForMixBuffersCommand(in_params.buffer_count, in_params.buffer_offset,
in_params.sample_rate);
@@ -611,7 +611,8 @@ void CommandGenerator::GenerateMixCommands(ServerMixInfo& mix_info) {
const auto& dest_mix = mix_context.GetInfo(destination_data->GetMixId());
const auto& dest_in_params = dest_mix.GetInParams();
const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset;
for (std::size_t i = 0; i < dest_in_params.buffer_count; i++) {
for (std::size_t i = 0; i < static_cast<std::size_t>(dest_in_params.buffer_count);
i++) {
const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i);
if (mixed_volume != 0.0f) {
GenerateMixCommand(dest_in_params.buffer_offset + i, mix_index, mixed_volume,
@@ -650,7 +651,7 @@ void CommandGenerator::GenerateFinalMixCommand() {
LOG_DEBUG(Audio, "(DSP_TRACE) GenerateFinalMixCommand");
}
auto& mix_info = mix_context.GetFinalMixInfo();
const auto in_params = mix_info.GetInParams();
const auto& in_params = mix_info.GetInParams();
GenerateDepopForMixBuffersCommand(in_params.buffer_count, in_params.buffer_offset,
in_params.sample_rate);
@@ -674,7 +675,7 @@ void CommandGenerator::GenerateFinalMixCommand() {
s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
s32 sample_count, s32 channel, std::size_t mix_offset) {
auto& in_params = voice_info.GetInParams();
const auto& in_params = voice_info.GetInParams();
const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
if (wave_buffer.buffer_address == 0) {
return 0;
@@ -704,7 +705,7 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s
std::vector<s16> buffer(samples_processed * channel_count);
memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16));
for (std::size_t i = 0; i < samples_processed; i++) {
for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
sample_buffer[mix_offset + i] = buffer[i * channel_count + channel];
}
}
@@ -714,7 +715,7 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s
s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
s32 sample_count, s32 channel, std::size_t mix_offset) {
auto& in_params = voice_info.GetInParams();
const auto& in_params = voice_info.GetInParams();
const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
if (wave_buffer.buffer_address == 0) {
return 0;
@@ -726,8 +727,9 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
return 0;
}
constexpr std::array<int, 16> SIGNED_NIBBLES = {
{0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}};
static constexpr std::array<int, 16> SIGNED_NIBBLES{
0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1,
};
constexpr std::size_t FRAME_LEN = 8;
constexpr std::size_t NIBBLES_PER_SAMPLE = 16;
@@ -766,8 +768,8 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
val = std::clamp<s32>(val, -32768, 32767);
// Advance output feedback.
yn2 = yn1;
yn1 = val;
return static_cast<s16>(val);
yn1 = static_cast<s16>(val);
return yn1;
};
std::size_t buffer_offset{};
@@ -789,9 +791,8 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
position_in_frame += 2;
// Decode entire frame
if (remaining_samples >= SAMPLES_PER_FRAME) {
if (remaining_samples >= static_cast<int>(SAMPLES_PER_FRAME)) {
for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
// Sample 1
const s32 s0 = SIGNED_NIBBLES[buffer[buffer_offset] >> 4];
const s32 s1 = SIGNED_NIBBLES[buffer[buffer_offset++] & 0xf];
@@ -800,7 +801,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
sample_buffer[cur_mix_offset++] = sample_1;
sample_buffer[cur_mix_offset++] = sample_2;
}
remaining_samples -= SAMPLES_PER_FRAME;
remaining_samples -= static_cast<int>(SAMPLES_PER_FRAME);
position_in_frame += SAMPLES_PER_FRAME;
continue;
}
@@ -853,7 +854,7 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
VoiceState& dsp_state, s32 channel,
s32 target_sample_rate, s32 sample_count,
s32 node_id) {
auto& in_params = voice_info.GetInParams();
const auto& in_params = voice_info.GetInParams();
if (dumping_frame) {
LOG_DEBUG(Audio,
"(DSP_TRACE) DecodeFromWaveBuffers, node_id={}, channel={}, "
@@ -866,8 +867,8 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
const auto resample_rate = static_cast<s32>(
static_cast<float>(in_params.sample_rate) / static_cast<float>(target_sample_rate) *
static_cast<float>(static_cast<s32>(in_params.pitch * 32768.0f)));
auto* output_base = output;
if ((dsp_state.fraction + sample_count * resample_rate) > (SCALED_MIX_BUFFER_SIZE - 4ULL)) {
if (dsp_state.fraction + sample_count * resample_rate >
static_cast<s32>(SCALED_MIX_BUFFER_SIZE - 4ULL)) {
return;
}

View File

@@ -7,7 +7,6 @@
#include <array>
#include "audio_core/common.h"
#include "audio_core/voice_context.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
namespace Core::Memory {

View File

@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#pragma once
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/swap.h"

View File

@@ -93,8 +93,10 @@ public:
constexpr s32 clev{707}; // center mixing level coefficient
constexpr s32 slev{707}; // surround mixing level coefficient
buf.push_back(left + (clev * center / 1000) + (slev * surround_left / 1000));
buf.push_back(right + (clev * center / 1000) + (slev * surround_right / 1000));
buf.push_back(static_cast<s16>(left + (clev * center / 1000) +
(slev * surround_left / 1000)));
buf.push_back(static_cast<s16>(right + (clev * center / 1000) +
(slev * surround_right / 1000)));
}
queue.Push(buf);
return;
@@ -192,8 +194,8 @@ SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels,
long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
void* output_buffer, long num_frames) {
CubebSinkStream* impl = static_cast<CubebSinkStream*>(user_data);
u8* buffer = reinterpret_cast<u8*>(output_buffer);
auto* impl = static_cast<CubebSinkStream*>(user_data);
auto* buffer = static_cast<u8*>(output_buffer);
if (!impl) {
return {};

View File

@@ -184,19 +184,19 @@ void EffectAuxInfo::UpdateForCommandGeneration() {
}
}
const VAddr EffectAuxInfo::GetSendInfo() const {
VAddr EffectAuxInfo::GetSendInfo() const {
return send_info;
}
const VAddr EffectAuxInfo::GetSendBuffer() const {
VAddr EffectAuxInfo::GetSendBuffer() const {
return send_buffer;
}
const VAddr EffectAuxInfo::GetRecvInfo() const {
VAddr EffectAuxInfo::GetRecvInfo() const {
return recv_info;
}
const VAddr EffectAuxInfo::GetRecvBuffer() const {
VAddr EffectAuxInfo::GetRecvBuffer() const {
return recv_buffer;
}

View File

@@ -166,13 +166,13 @@ public:
std::array<u8, 0xa0> raw;
};
};
static_assert(sizeof(EffectInfo::InParams) == 0xc0, "InParams is an invalid size");
static_assert(sizeof(InParams) == 0xc0, "InParams is an invalid size");
struct OutParams {
UsageStatus status{};
INSERT_PADDING_BYTES(15);
};
static_assert(sizeof(EffectInfo::OutParams) == 0x10, "OutParams is an invalid size");
static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size");
};
struct AuxAddress {
@@ -184,8 +184,8 @@ struct AuxAddress {
class EffectBase {
public:
EffectBase(EffectType effect_type);
~EffectBase();
explicit EffectBase(EffectType effect_type);
virtual ~EffectBase();
virtual void Update(EffectInfo::InParams& in_params) = 0;
virtual void UpdateForCommandGeneration() = 0;
@@ -206,8 +206,7 @@ protected:
template <typename T>
class EffectGeneric : public EffectBase {
public:
EffectGeneric(EffectType effect_type) : EffectBase::EffectBase(effect_type) {}
~EffectGeneric() = default;
explicit EffectGeneric(EffectType effect_type) : EffectBase(effect_type) {}
T& GetParams() {
return internal_params;
@@ -224,7 +223,7 @@ private:
class EffectStubbed : public EffectBase {
public:
explicit EffectStubbed();
~EffectStubbed();
~EffectStubbed() override;
void Update(EffectInfo::InParams& in_params) override;
void UpdateForCommandGeneration() override;
@@ -233,7 +232,7 @@ public:
class EffectI3dl2Reverb : public EffectGeneric<I3dl2ReverbParams> {
public:
explicit EffectI3dl2Reverb();
~EffectI3dl2Reverb();
~EffectI3dl2Reverb() override;
void Update(EffectInfo::InParams& in_params) override;
void UpdateForCommandGeneration() override;
@@ -245,7 +244,7 @@ private:
class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> {
public:
explicit EffectBiquadFilter();
~EffectBiquadFilter();
~EffectBiquadFilter() override;
void Update(EffectInfo::InParams& in_params) override;
void UpdateForCommandGeneration() override;
@@ -254,14 +253,14 @@ public:
class EffectAuxInfo : public EffectGeneric<AuxInfo> {
public:
explicit EffectAuxInfo();
~EffectAuxInfo();
~EffectAuxInfo() override;
void Update(EffectInfo::InParams& in_params) override;
void UpdateForCommandGeneration() override;
const VAddr GetSendInfo() const;
const VAddr GetSendBuffer() const;
const VAddr GetRecvInfo() const;
const VAddr GetRecvBuffer() const;
VAddr GetSendInfo() const;
VAddr GetSendBuffer() const;
VAddr GetRecvInfo() const;
VAddr GetRecvBuffer() const;
private:
VAddr send_info{};
@@ -275,7 +274,7 @@ private:
class EffectDelay : public EffectGeneric<DelayParams> {
public:
explicit EffectDelay();
~EffectDelay();
~EffectDelay() override;
void Update(EffectInfo::InParams& in_params) override;
void UpdateForCommandGeneration() override;
@@ -287,7 +286,7 @@ private:
class EffectBufferMixer : public EffectGeneric<BufferMixerParams> {
public:
explicit EffectBufferMixer();
~EffectBufferMixer();
~EffectBufferMixer() override;
void Update(EffectInfo::InParams& in_params) override;
void UpdateForCommandGeneration() override;
@@ -296,7 +295,7 @@ public:
class EffectReverb : public EffectGeneric<ReverbParams> {
public:
explicit EffectReverb();
~EffectReverb();
~EffectReverb() override;
void Update(EffectInfo::InParams& in_params) override;
void UpdateForCommandGeneration() override;

View File

@@ -64,7 +64,6 @@ bool InfoUpdater::UpdateBehaviorInfo(BehaviorInfo& in_behavior_info) {
}
bool InfoUpdater::UpdateMemoryPools(std::vector<ServerMemoryPoolInfo>& memory_pool_info) {
const auto force_mapping = behavior_info.IsMemoryPoolForceMappingEnabled();
const auto memory_pool_count = memory_pool_info.size();
const auto total_memory_pool_in = sizeof(ServerMemoryPoolInfo::InParams) * memory_pool_count;
const auto total_memory_pool_out = sizeof(ServerMemoryPoolInfo::OutParams) * memory_pool_count;
@@ -174,7 +173,7 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
}
// Voice states for each channel
std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT> voice_states{};
ASSERT(in_params.id < voice_count);
ASSERT(static_cast<std::size_t>(in_params.id) < voice_count);
// Grab our current voice info
auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(in_params.id));
@@ -352,8 +351,8 @@ ResultCode InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buf
for (std::size_t i = 0; i < mix_count; i++) {
const auto& in = mix_in_params[i];
total_buffer_count += in.buffer_count;
if (in.dest_mix_id > mix_count && in.dest_mix_id != AudioCommon::NO_MIX &&
in.mix_id != AudioCommon::FINAL_MIX) {
if (static_cast<std::size_t>(in.dest_mix_id) > mix_count &&
in.dest_mix_id != AudioCommon::NO_MIX && in.mix_id != AudioCommon::FINAL_MIX) {
LOG_ERROR(
Audio,
"Invalid mix destination, mix_id={:X}, dest_mix_id={:X}, mix_buffer_count={:X}",

View File

@@ -53,7 +53,7 @@ void MixContext::UpdateDistancesFromFinalMix() {
auto mix_id = in_params.mix_id;
// Needs to be referenced out of scope
s32 distance_to_final_mix{AudioCommon::FINAL_MIX};
for (; distance_to_final_mix < info_count; distance_to_final_mix++) {
for (; distance_to_final_mix < static_cast<s32>(info_count); distance_to_final_mix++) {
if (mix_id == AudioCommon::FINAL_MIX) {
// If we're at the final mix, we're done
break;
@@ -77,7 +77,7 @@ void MixContext::UpdateDistancesFromFinalMix() {
}
// If we're out of range for our distance, mark it as no final mix
if (distance_to_final_mix >= info_count) {
if (distance_to_final_mix >= static_cast<s32>(info_count)) {
distance_to_final_mix = AudioCommon::NO_FINAL_MIX;
}

View File

@@ -306,7 +306,7 @@ bool SplitterContext::UpdateInfo(const std::vector<u8>& input, std::size_t& inpu
break;
}
if (header.send_id < 0 || header.send_id > info_count) {
if (header.send_id < 0 || static_cast<std::size_t>(header.send_id) > info_count) {
LOG_ERROR(Audio, "Bad splitter data id");
break;
}
@@ -348,7 +348,7 @@ bool SplitterContext::UpdateData(const std::vector<u8>& input, std::size_t& inpu
break;
}
if (header.splitter_id < 0 || header.splitter_id > data_count) {
if (header.splitter_id < 0 || static_cast<std::size_t>(header.splitter_id) > data_count) {
LOG_ERROR(Audio, "Bad splitter data id");
break;
}
@@ -434,7 +434,7 @@ const std::vector<s32>& NodeStates::GetIndexList() const {
}
void NodeStates::PushTsortResult(s32 index) {
ASSERT(index < node_count);
ASSERT(index < static_cast<s32>(node_count));
index_list[index_pos++] = index;
}

View File

@@ -12,7 +12,6 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
#include "core/settings.h"
namespace AudioCore {

View File

@@ -128,7 +128,10 @@ void ServerVoiceInfo::UpdateParameters(const VoiceInfo::InParams& voice_in,
in_params.wave_buffer_count = voice_in.wave_buffer_count;
in_params.wave_bufffer_head = voice_in.wave_buffer_head;
if (behavior_info.IsFlushVoiceWaveBuffersSupported()) {
in_params.wave_buffer_flush_request_count += voice_in.wave_buffer_flush_request_count;
const auto in_request_count = in_params.wave_buffer_flush_request_count;
const auto voice_request_count = voice_in.wave_buffer_flush_request_count;
in_params.wave_buffer_flush_request_count =
static_cast<u8>(in_request_count + voice_request_count);
}
in_params.mix_id = voice_in.mix_id;
if (behavior_info.IsSplitterSupported()) {
@@ -488,11 +491,11 @@ s32 VoiceContext::DecodePcm16(s32* output_buffer, ServerWaveBuffer* wave_buffer,
// Fast path
if (channel_count == 1) {
for (std::size_t i = 0; i < samples_processed; i++) {
for (std::ptrdiff_t i = 0; i < samples_processed; i++) {
output_buffer[i] = buffer_data[i];
}
} else {
for (std::size_t i = 0; i < samples_processed; i++) {
for (std::ptrdiff_t i = 0; i < samples_processed; i++) {
output_buffer[i] = buffer_data[i * channel_count + channel];
}
}

View File

@@ -192,4 +192,9 @@ create_target_directory_groups(common)
find_package(Boost 1.71 COMPONENTS context headers REQUIRED)
target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile)
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd xbyak)
target_link_libraries(common PRIVATE lz4::lz4 xbyak)
if (MSVC)
target_link_libraries(common PRIVATE zstd::zstd)
else()
target_link_libraries(common PRIVATE zstd)
endif()

View File

@@ -29,22 +29,19 @@ assert_noinline_call(const Fn& fn) {
}
#define ASSERT(_a_) \
do \
if (!(_a_)) { \
assert_noinline_call([] { LOG_CRITICAL(Debug, "Assertion Failed!"); }); \
} \
while (0)
if (!(_a_)) { \
LOG_CRITICAL(Debug, "Assertion Failed!"); \
}
#define ASSERT_MSG(_a_, ...) \
do \
if (!(_a_)) { \
assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \
} \
while (0)
if (!(_a_)) { \
LOG_CRITICAL(Debug, "Assertion Failed! " __VA_ARGS__); \
}
#define UNREACHABLE() assert_noinline_call([] { LOG_CRITICAL(Debug, "Unreachable code!"); })
#define UNREACHABLE() \
{ LOG_CRITICAL(Debug, "Unreachable code!"); }
#define UNREACHABLE_MSG(...) \
assert_noinline_call([&] { LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); })
{ LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); }
#ifdef _DEBUG
#define DEBUG_ASSERT(_a_) ASSERT(_a_)

View File

@@ -16,14 +16,14 @@ namespace Common {
[[nodiscard]] constexpr u8 ToHexNibble(char c) {
if (c >= 65 && c <= 70) {
return c - 55;
return static_cast<u8>(c - 55);
}
if (c >= 97 && c <= 102) {
return c - 87;
return static_cast<u8>(c - 87);
}
return c - 48;
return static_cast<u8>(c - 48);
}
[[nodiscard]] std::vector<u8> HexStringToVector(std::string_view str, bool little_endian);
@@ -33,11 +33,11 @@ template <std::size_t Size, bool le = false>
std::array<u8, Size> out{};
if constexpr (le) {
for (std::size_t i = 2 * Size - 2; i <= 2 * Size; i -= 2) {
out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
out[i / 2] = static_cast<u8>((ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]));
}
} else {
for (std::size_t i = 0; i < 2 * Size; i += 2) {
out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
out[i / 2] = static_cast<u8>((ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]));
}
}
return out;

View File

@@ -20,8 +20,8 @@ struct Rectangle {
constexpr Rectangle() = default;
constexpr Rectangle(T left, T top, T right, T bottom)
: left(left), top(top), right(right), bottom(bottom) {}
constexpr Rectangle(T left_, T top_, T right_, T bottom_)
: left(left_), top(top_), right(right_), bottom(bottom_) {}
[[nodiscard]] T GetWidth() const {
if constexpr (std::is_floating_point_v<T>) {

View File

@@ -87,7 +87,13 @@ public:
template <typename V>
[[nodiscard]] constexpr Vec2<decltype(T{} * V{})> operator*(const V& f) const {
return {x * f, y * f};
using TV = decltype(T{} * V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) * static_cast<C>(f)),
};
}
template <typename V>
@@ -98,7 +104,13 @@ public:
template <typename V>
[[nodiscard]] constexpr Vec2<decltype(T{} / V{})> operator/(const V& f) const {
return {x / f, y / f};
using TV = decltype(T{} / V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) / static_cast<C>(f)),
};
}
template <typename V>
@@ -168,7 +180,10 @@ public:
template <typename T, typename V>
[[nodiscard]] constexpr Vec2<T> operator*(const V& f, const Vec2<T>& vec) {
return Vec2<T>(f * vec.x, f * vec.y);
using C = std::common_type_t<T, V>;
return Vec2<T>(static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.x)),
static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.y)));
}
using Vec2f = Vec2<float>;
@@ -237,7 +252,14 @@ public:
template <typename V>
[[nodiscard]] constexpr Vec3<decltype(T{} * V{})> operator*(const V& f) const {
return {x * f, y * f, z * f};
using TV = decltype(T{} * V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(z) * static_cast<C>(f)),
};
}
template <typename V>
@@ -247,7 +269,14 @@ public:
}
template <typename V>
[[nodiscard]] constexpr Vec3<decltype(T{} / V{})> operator/(const V& f) const {
return {x / f, y / f, z / f};
using TV = decltype(T{} / V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(z) / static_cast<C>(f)),
};
}
template <typename V>
@@ -367,7 +396,11 @@ public:
template <typename T, typename V>
[[nodiscard]] constexpr Vec3<T> operator*(const V& f, const Vec3<T>& vec) {
return Vec3<T>(f * vec.x, f * vec.y, f * vec.z);
using C = std::common_type_t<T, V>;
return Vec3<T>(static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.x)),
static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.y)),
static_cast<T>(static_cast<C>(f) * static_cast<C>(vec.z)));
}
template <>
@@ -446,7 +479,15 @@ public:
template <typename V>
[[nodiscard]] constexpr Vec4<decltype(T{} * V{})> operator*(const V& f) const {
return {x * f, y * f, z * f, w * f};
using TV = decltype(T{} * V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(z) * static_cast<C>(f)),
static_cast<TV>(static_cast<C>(w) * static_cast<C>(f)),
};
}
template <typename V>
@@ -457,7 +498,15 @@ public:
template <typename V>
[[nodiscard]] constexpr Vec4<decltype(T{} / V{})> operator/(const V& f) const {
return {x / f, y / f, z / f, w / f};
using TV = decltype(T{} / V{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(x) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(y) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(z) / static_cast<C>(f)),
static_cast<TV>(static_cast<C>(w) / static_cast<C>(f)),
};
}
template <typename V>
@@ -582,7 +631,15 @@ public:
template <typename T, typename V>
[[nodiscard]] constexpr Vec4<decltype(V{} * T{})> operator*(const V& f, const Vec4<T>& vec) {
return {f * vec.x, f * vec.y, f * vec.z, f * vec.w};
using TV = decltype(V{} * T{});
using C = std::common_type_t<T, V>;
return {
static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.x)),
static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.y)),
static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.z)),
static_cast<TV>(static_cast<C>(f) * static_cast<C>(vec.w)),
};
}
using Vec4f = Vec4<float>;

View File

@@ -15,7 +15,7 @@ namespace Common {
using base_timer = std::chrono::steady_clock;
using base_time_point = std::chrono::time_point<base_timer>;
class StandardWallClock : public WallClock {
class StandardWallClock final : public WallClock {
public:
StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency)
: WallClock(emulated_cpu_frequency, emulated_clock_frequency, false) {

View File

@@ -13,6 +13,8 @@ namespace Common {
class WallClock {
public:
virtual ~WallClock() = default;
/// Returns current wall time in nanoseconds
[[nodiscard]] virtual std::chrono::nanoseconds GetTimeNS() = 0;

View File

@@ -12,7 +12,7 @@
namespace Common {
namespace X64 {
class NativeClock : public WallClock {
class NativeClock final : public WallClock {
public:
NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, u64 rtsc_frequency);

View File

@@ -623,6 +623,17 @@ if (MSVC)
# 'context' : truncation from 'type1' to 'type2'
/we4305
)
else()
target_compile_options(core PRIVATE
-Werror=conversion
-Werror=ignored-qualifiers
-Werror=implicit-fallthrough
-Werror=reorder
-Werror=sign-compare
-Werror=unused-but-set-parameter
-Werror=unused-but-set-variable
-Werror=unused-variable
)
endif()
create_target_directory_groups(core)

View File

@@ -34,7 +34,7 @@ std::optional<Callback> DynarmicCP15::CompileInternalOperation(bool two, unsigne
CoprocReg CRm, unsigned opc2) {
LOG_CRITICAL(Core_ARM, "CP15: cdp{} p15, {}, {}, {}, {}, {}", two ? "2" : "", opc1, CRd, CRn,
CRm, opc2);
return {};
return std::nullopt;
}
CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1, CoprocReg CRn,
@@ -115,7 +115,7 @@ std::optional<Callback> DynarmicCP15::CompileLoadWords(bool two, bool long_trans
LOG_CRITICAL(Core_ARM, "CP15: mrrc{}{} p15, {}, [...]", two ? "2" : "",
long_transfer ? "l" : "", CRd);
}
return {};
return std::nullopt;
}
std::optional<Callback> DynarmicCP15::CompileStoreWords(bool two, bool long_transfer, CoprocReg CRd,
@@ -127,7 +127,7 @@ std::optional<Callback> DynarmicCP15::CompileStoreWords(bool two, bool long_tran
LOG_CRITICAL(Core_ARM, "CP15: mrrc{}{} p15, {}, [...]", two ? "2" : "",
long_transfer ? "l" : "", CRd);
}
return {};
return std::nullopt;
}
} // namespace Core

View File

@@ -35,8 +35,8 @@ public:
std::optional<u8> option) override;
ARM_Dynarmic_32& parent;
u32 uprw;
u32 uro;
u32 uprw = 0;
u32 uro = 0;
};
} // namespace Core

View File

@@ -178,7 +178,7 @@ struct System::Impl {
arp_manager.ResetAll();
telemetry_session = std::make_unique<Core::TelemetrySession>();
service_manager = std::make_shared<Service::SM::ServiceManager>();
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
Service::Init(service_manager, system);
GDBStub::DeferStart();

View File

@@ -120,7 +120,7 @@ public:
* Gets the instance of the System singleton class.
* @returns Reference to the instance of the System singleton class.
*/
static System& GetInstance() {
[[deprecated("Use of the global system instance is deprecated")]] static System& GetInstance() {
return s_instance;
}

View File

@@ -411,7 +411,7 @@ Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, KeyManager& ke
// Combine sources and seed
for (auto& source : sd_key_sources) {
for (std::size_t i = 0; i < source.size(); ++i) {
source[i] ^= sd_seed[i & 0xF];
source[i] = static_cast<u8>(source[i] ^ sd_seed[i & 0xF]);
}
}

View File

@@ -323,7 +323,7 @@ bool NCA::ReadRomFSSection(const NCASectionHeader& section, const NCASectionTabl
subsection_buckets.back().entries.push_back({section.bktr.relocation.offset, {0}, ctr_low});
subsection_buckets.back().entries.push_back({size, {0}, 0});
std::optional<Core::Crypto::Key128> key = {};
std::optional<Core::Crypto::Key128> key;
if (encrypted) {
if (has_rights_id) {
status = Loader::ResultStatus::Success;
@@ -442,18 +442,18 @@ std::optional<Core::Crypto::Key128> NCA::GetTitlekey() {
memcpy(rights_id.data(), header.rights_id.data(), 16);
if (rights_id == u128{}) {
status = Loader::ResultStatus::ErrorInvalidRightsID;
return {};
return std::nullopt;
}
auto titlekey = keys.GetKey(Core::Crypto::S128KeyType::Titlekey, rights_id[1], rights_id[0]);
if (titlekey == Core::Crypto::Key128{}) {
status = Loader::ResultStatus::ErrorMissingTitlekey;
return {};
return std::nullopt;
}
if (!keys.HasKey(Core::Crypto::S128KeyType::Titlekek, master_key_id)) {
status = Loader::ResultStatus::ErrorMissingTitlekek;
return {};
return std::nullopt;
}
Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(
@@ -477,7 +477,7 @@ VirtualFile NCA::Decrypt(const NCASectionHeader& s_header, VirtualFile in, u64 s
case NCASectionCryptoType::BKTR:
LOG_TRACE(Crypto, "called with mode=CTR, starting_offset={:016X}", starting_offset);
{
std::optional<Core::Crypto::Key128> key = {};
std::optional<Core::Crypto::Key128> key;
if (has_rights_id) {
status = Loader::ResultStatus::Success;
key = GetTitlekey();

View File

@@ -83,7 +83,7 @@ enum class Language : u8 {
Italian = 7,
Dutch = 8,
CanadianFrench = 9,
Portugese = 10,
Portuguese = 10,
Russian = 11,
Korean = 12,
Taiwanese = 13,

View File

@@ -266,8 +266,9 @@ std::multimap<u64, VirtualFile> RomFSBuildContext::Build() {
cur_file->offset = file_partition_size;
file_partition_size += cur_file->size;
cur_file->entry_offset = entry_offset;
entry_offset += sizeof(RomFSFileEntry) +
Common::AlignUp(cur_file->path_len - cur_file->cur_path_ofs, 4);
entry_offset +=
static_cast<u32>(sizeof(RomFSFileEntry) +
Common::AlignUp(cur_file->path_len - cur_file->cur_path_ofs, 4));
prev_file = cur_file;
}
// Assign deferred parent/sibling ownership.
@@ -284,8 +285,9 @@ std::multimap<u64, VirtualFile> RomFSBuildContext::Build() {
for (const auto& it : directories) {
cur_dir = it.second;
cur_dir->entry_offset = entry_offset;
entry_offset += sizeof(RomFSDirectoryEntry) +
Common::AlignUp(cur_dir->path_len - cur_dir->cur_path_ofs, 4);
entry_offset +=
static_cast<u32>(sizeof(RomFSDirectoryEntry) +
Common::AlignUp(cur_dir->path_len - cur_dir->cur_path_ofs, 4));
}
// Assign deferred parent/sibling ownership.
for (auto it = directories.rbegin(); it->second != root; ++it) {

View File

@@ -245,9 +245,11 @@ void IPSwitchCompiler::Parse() {
// Read rest of patch
while (true) {
if (i + 1 >= lines.size())
if (i + 1 >= lines.size()) {
break;
const auto patch_line = lines[++i];
}
const auto& patch_line = lines[++i];
// Start of new patch
if (StartsWith(patch_line, "@enabled") || StartsWith(patch_line, "@disabled")) {
@@ -297,7 +299,7 @@ void IPSwitchCompiler::Parse() {
patch_text->GetName(), offset, Common::HexToString(replace));
}
patch.records.insert_or_assign(offset, std::move(replace));
patch.records.insert_or_assign(static_cast<u32>(offset), std::move(replace));
}
patches.push_back(std::move(patch));

View File

@@ -108,7 +108,7 @@ std::vector<u8> CNMT::Serialize() const {
memcpy(out.data() + sizeof(CNMTHeader), &opt_header, sizeof(OptionalHeader));
}
auto offset = header.table_offset;
u64_le offset = header.table_offset;
for (const auto& rec : content_records) {
memcpy(out.data() + offset + sizeof(CNMTHeader), &rec, sizeof(ContentRecord));

View File

@@ -29,7 +29,7 @@
namespace FileSys {
namespace {
constexpr u64 SINGLE_BYTE_MODULUS = 0x100;
constexpr u32 SINGLE_BYTE_MODULUS = 0x100;
constexpr u64 DLC_BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000;
constexpr std::array<const char*, 14> EXEFS_FILE_NAMES{

View File

@@ -19,38 +19,6 @@
#include "core/loader/loader.h"
namespace FileSys {
namespace {
void SetTicketKeys(const std::vector<VirtualFile>& files) {
auto& keys = Core::Crypto::KeyManager::Instance();
for (const auto& ticket_file : files) {
if (ticket_file == nullptr) {
continue;
}
if (ticket_file->GetExtension() != "tik") {
continue;
}
if (ticket_file->GetSize() <
Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET + sizeof(Core::Crypto::Key128)) {
continue;
}
Core::Crypto::Key128 key{};
ticket_file->Read(key.data(), key.size(), Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET);
// We get the name without the extension in order to create the rights ID.
std::string name_only(ticket_file->GetName());
name_only.erase(name_only.size() - 4);
const auto rights_id_raw = Common::HexStringToArray<16>(name_only);
u128 rights_id;
std::memcpy(rights_id.data(), rights_id_raw.data(), sizeof(u128));
keys.SetKey(Core::Crypto::S128KeyType::Titlekey, key, rights_id[1], rights_id[0]);
}
}
} // Anonymous namespace
NSP::NSP(VirtualFile file_)
: file(std::move(file_)), status{Loader::ResultStatus::Success},
@@ -232,6 +200,35 @@ VirtualDir NSP::GetParentDirectory() const {
return file->GetContainingDirectory();
}
void NSP::SetTicketKeys(const std::vector<VirtualFile>& files) {
for (const auto& ticket_file : files) {
if (ticket_file == nullptr) {
continue;
}
if (ticket_file->GetExtension() != "tik") {
continue;
}
if (ticket_file->GetSize() <
Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET + sizeof(Core::Crypto::Key128)) {
continue;
}
Core::Crypto::Key128 key{};
ticket_file->Read(key.data(), key.size(), Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET);
// We get the name without the extension in order to create the rights ID.
std::string name_only(ticket_file->GetName());
name_only.erase(name_only.size() - 4);
const auto rights_id_raw = Common::HexStringToArray<16>(name_only);
u128 rights_id;
std::memcpy(rights_id.data(), rights_id_raw.data(), sizeof(u128));
keys.SetKey(Core::Crypto::S128KeyType::Titlekey, key, rights_id[1], rights_id[0]);
}
}
void NSP::InitializeExeFSAndRomFS(const std::vector<VirtualFile>& files) {
exefs = pfs;
@@ -267,9 +264,9 @@ void NSP::ReadNCAs(const std::vector<VirtualFile>& files) {
}
const CNMT cnmt(inner_file);
auto& ncas_title = ncas[cnmt.GetTitleID()];
ncas_title[{cnmt.GetType(), ContentRecordType::Meta}] = nca;
ncas[cnmt.GetTitleID()][{cnmt.GetType(), ContentRecordType::Meta}] = nca;
for (const auto& rec : cnmt.GetContentRecords()) {
const auto id_string = Common::HexToString(rec.nca_id, false);
auto next_file = pfs->GetFile(fmt::format("{}.nca", id_string));
@@ -286,13 +283,32 @@ void NSP::ReadNCAs(const std::vector<VirtualFile>& files) {
}
auto next_nca = std::make_shared<NCA>(std::move(next_file), nullptr, 0);
if (next_nca->GetType() == NCAContentType::Program) {
program_status[cnmt.GetTitleID()] = next_nca->GetStatus();
program_status[next_nca->GetTitleId()] = next_nca->GetStatus();
}
if (next_nca->GetStatus() == Loader::ResultStatus::Success ||
(next_nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS &&
(cnmt.GetTitleID() & 0x800) != 0)) {
ncas_title[{cnmt.GetType(), rec.type}] = std::move(next_nca);
if (next_nca->GetStatus() != Loader::ResultStatus::Success &&
next_nca->GetStatus() != Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) {
continue;
}
// If the last 3 hexadecimal digits of the CNMT TitleID is 0x800 or is missing the
// BKTRBaseRomFS, this is an update NCA. Otherwise, this is a base NCA.
if ((cnmt.GetTitleID() & 0x800) != 0 ||
next_nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) {
// If the last 3 hexadecimal digits of the NCA's TitleID is between 0x1 and
// 0x7FF, this is a multi-program update NCA. Otherwise, this is a regular
// update NCA.
if ((next_nca->GetTitleId() & 0x7FF) != 0 &&
(next_nca->GetTitleId() & 0x800) == 0) {
ncas[next_nca->GetTitleId()][{cnmt.GetType(), rec.type}] =
std::move(next_nca);
} else {
ncas[cnmt.GetTitleID()][{cnmt.GetType(), rec.type}] = std::move(next_nca);
}
} else {
ncas[next_nca->GetTitleId()][{cnmt.GetType(), rec.type}] = std::move(next_nca);
}
}

View File

@@ -63,6 +63,7 @@ public:
VirtualDir GetParentDirectory() const override;
private:
void SetTicketKeys(const std::vector<VirtualFile>& files);
void InitializeExeFSAndRomFS(const std::vector<VirtualFile>& files);
void ReadNCAs(const std::vector<VirtualFile>& files);

View File

@@ -169,11 +169,12 @@ VfsDirectory::~VfsDirectory() = default;
std::optional<u8> VfsFile::ReadByte(std::size_t offset) const {
u8 out{};
std::size_t size = Read(&out, 1, offset);
if (size == 1)
const std::size_t size = Read(&out, sizeof(u8), offset);
if (size == 1) {
return out;
}
return {};
return std::nullopt;
}
std::vector<u8> VfsFile::ReadBytes(std::size_t size, std::size_t offset) const {

View File

@@ -58,10 +58,11 @@ std::size_t OffsetVfsFile::Write(const u8* data, std::size_t length, std::size_t
}
std::optional<u8> OffsetVfsFile::ReadByte(std::size_t r_offset) const {
if (r_offset < size)
return file->ReadByte(offset + r_offset);
if (r_offset >= size) {
return std::nullopt;
}
return {};
return file->ReadByte(offset + r_offset);
}
std::vector<u8> OffsetVfsFile::ReadBytes(std::size_t r_size, std::size_t r_offset) const {

View File

@@ -54,9 +54,11 @@ public:
}
std::optional<u8> ReadByte(std::size_t offset) const override {
if (offset < size)
return value;
return {};
if (offset >= size) {
return std::nullopt;
}
return value;
}
std::vector<u8> ReadBytes(std::size_t length, std::size_t offset) const override {

View File

@@ -4,7 +4,6 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
#include "core/frontend/applets/controller.h"
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/hid.h"
@@ -14,6 +13,9 @@ namespace Core::Frontend {
ControllerApplet::~ControllerApplet() = default;
DefaultControllerApplet::DefaultControllerApplet(Service::SM::ServiceManager& service_manager_)
: service_manager{service_manager_} {}
DefaultControllerApplet::~DefaultControllerApplet() = default;
void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callback,
@@ -21,9 +23,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb
LOG_INFO(Service_HID, "called, deducing the best configuration based on the given parameters!");
auto& npad =
Core::System::GetInstance()
.ServiceManager()
.GetService<Service::HID::Hid>("hid")
service_manager.GetService<Service::HID::Hid>("hid")
->GetAppletResource()
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad);

View File

@@ -8,6 +8,10 @@
#include "common/common_types.h"
namespace Service::SM {
class ServiceManager;
}
namespace Core::Frontend {
using BorderColor = std::array<u8, 4>;
@@ -39,10 +43,14 @@ public:
class DefaultControllerApplet final : public ControllerApplet {
public:
explicit DefaultControllerApplet(Service::SM::ServiceManager& service_manager_);
~DefaultControllerApplet() override;
void ReconfigureControllers(std::function<void()> callback,
ControllerParameters parameters) const override;
private:
Service::SM::ServiceManager& service_manager;
};
} // namespace Core::Frontend

View File

@@ -84,10 +84,12 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) {
return;
std::lock_guard guard{touch_state->mutex};
touch_state->touch_x = static_cast<float>(framebuffer_x - framebuffer_layout.screen.left) /
(framebuffer_layout.screen.right - framebuffer_layout.screen.left);
touch_state->touch_y = static_cast<float>(framebuffer_y - framebuffer_layout.screen.top) /
(framebuffer_layout.screen.bottom - framebuffer_layout.screen.top);
touch_state->touch_x =
static_cast<float>(framebuffer_x - framebuffer_layout.screen.left) /
static_cast<float>(framebuffer_layout.screen.right - framebuffer_layout.screen.left);
touch_state->touch_y =
static_cast<float>(framebuffer_y - framebuffer_layout.screen.top) /
static_cast<float>(framebuffer_layout.screen.bottom - framebuffer_layout.screen.top);
touch_state->touch_pressed = true;
}

View File

@@ -14,8 +14,8 @@ namespace Layout {
template <class T>
static Common::Rectangle<T> MaxRectangle(Common::Rectangle<T> window_area,
float screen_aspect_ratio) {
float scale = std::min(static_cast<float>(window_area.GetWidth()),
window_area.GetHeight() / screen_aspect_ratio);
const float scale = std::min(static_cast<float>(window_area.GetWidth()),
static_cast<float>(window_area.GetHeight()) / screen_aspect_ratio);
return Common::Rectangle<T>{0, 0, static_cast<T>(std::round(scale)),
static_cast<T>(std::round(scale * screen_aspect_ratio))};
}
@@ -27,7 +27,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height) {
// so just calculate them both even if the other isn't showing.
FramebufferLayout res{width, height, false, {}};
const float window_aspect_ratio = static_cast<float>(height) / width;
const float window_aspect_ratio = static_cast<float>(height) / static_cast<float>(width);
const float emulation_aspect_ratio = EmulationAspectRatio(
static_cast<AspectRatio>(Settings::values.aspect_ratio.GetValue()), window_aspect_ratio);

View File

@@ -33,6 +33,9 @@ public:
virtual bool GetAnalogDirectionStatus(AnalogDirection direction) const {
return {};
}
virtual bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const {
return {};
}
};
/// An abstract class template for a factory that can create input devices.
@@ -119,11 +122,11 @@ using ButtonDevice = InputDevice<bool>;
using AnalogDevice = InputDevice<std::tuple<float, float>>;
/**
* A motion device is an input device that returns a tuple of accelerometer state vector and
* gyroscope state vector.
* A motion status is an object that returns a tuple of accelerometer state vector,
* gyroscope state vector, rotation state vector and orientation state matrix.
*
* For both vectors:
* x+ is the same direction as LEFT on D-pad.
* x+ is the same direction as RIGHT on D-pad.
* y+ is normal to the touch screen, pointing outward.
* z+ is the same direction as UP on D-pad.
*
@@ -133,8 +136,22 @@ using AnalogDevice = InputDevice<std::tuple<float, float>>;
* For gyroscope state vector:
* Orientation is determined by right-hand rule.
* Units: deg/sec
*
* For rotation state vector
* Units: rotations
*
* For orientation state matrix
* x vector
* y vector
* z vector
*/
using MotionDevice = InputDevice<std::tuple<Common::Vec3<float>, Common::Vec3<float>>>;
using MotionStatus = std::tuple<Common::Vec3<float>, Common::Vec3<float>, Common::Vec3<float>,
std::array<Common::Vec3f, 3>>;
/**
* A motion device is an input device that returns a motion status object
*/
using MotionDevice = InputDevice<MotionStatus>;
/**
* A touch device is an input device that returns a tuple of two floats and a bool. The floats are

View File

@@ -291,11 +291,11 @@ static void FpuWrite(std::size_t id, u128 val, Kernel::Thread* thread = nullptr)
*/
static u8 HexCharToValue(u8 hex) {
if (hex >= '0' && hex <= '9') {
return hex - '0';
return static_cast<u8>(hex - '0');
} else if (hex >= 'a' && hex <= 'f') {
return hex - 'a' + 0xA;
return static_cast<u8>(hex - 'a' + 0xA);
} else if (hex >= 'A' && hex <= 'F') {
return hex - 'A' + 0xA;
return static_cast<u8>(hex - 'A' + 0xA);
}
LOG_ERROR(Debug_GDBStub, "Invalid nibble: {} ({:02X})", hex, hex);
@@ -310,9 +310,9 @@ static u8 HexCharToValue(u8 hex) {
static u8 NibbleToHex(u8 n) {
n &= 0xF;
if (n < 0xA) {
return '0' + n;
return static_cast<u8>('0' + n);
} else {
return 'a' + n - 0xA;
return static_cast<u8>('a' + n - 0xA);
}
}
@@ -355,8 +355,8 @@ static u64 HexToLong(const u8* src, std::size_t len) {
*/
static void MemToGdbHex(u8* dest, const u8* src, std::size_t len) {
while (len-- > 0) {
u8 tmp = *src++;
*dest++ = NibbleToHex(tmp >> 4);
const u8 tmp = *src++;
*dest++ = NibbleToHex(static_cast<u8>(tmp >> 4));
*dest++ = NibbleToHex(tmp);
}
}
@@ -370,7 +370,7 @@ static void MemToGdbHex(u8* dest, const u8* src, std::size_t len) {
*/
static void GdbHexToMem(u8* dest, const u8* src, std::size_t len) {
while (len-- > 0) {
*dest++ = (HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]);
*dest++ = static_cast<u8>((HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]));
src += 2;
}
}
@@ -602,22 +602,22 @@ static void SendReply(const char* reply) {
memcpy(command_buffer + 1, reply, command_length);
u8 checksum = CalculateChecksum(command_buffer, command_length + 1);
const u8 checksum = CalculateChecksum(command_buffer, command_length + 1);
command_buffer[0] = GDB_STUB_START;
command_buffer[command_length + 1] = GDB_STUB_END;
command_buffer[command_length + 2] = NibbleToHex(checksum >> 4);
command_buffer[command_length + 2] = NibbleToHex(static_cast<u8>(checksum >> 4));
command_buffer[command_length + 3] = NibbleToHex(checksum);
u8* ptr = command_buffer;
u32 left = command_length + 4;
while (left > 0) {
int sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0);
const auto sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0);
if (sent_size < 0) {
LOG_ERROR(Debug_GDBStub, "gdb: send failed");
return Shutdown();
}
left -= sent_size;
left -= static_cast<u32>(sent_size);
ptr += sent_size;
}
}
@@ -777,10 +777,10 @@ static void ReadCommand() {
command_buffer[command_length++] = c;
}
u8 checksum_received = HexCharToValue(ReadByte()) << 4;
checksum_received |= HexCharToValue(ReadByte());
auto checksum_received = static_cast<u32>(HexCharToValue(ReadByte()) << 4);
checksum_received |= static_cast<u32>(HexCharToValue(ReadByte()));
u8 checksum_calculated = CalculateChecksum(command_buffer, command_length);
const u32 checksum_calculated = CalculateChecksum(command_buffer, command_length);
if (checksum_received != checksum_calculated) {
LOG_ERROR(Debug_GDBStub,

View File

@@ -38,10 +38,11 @@ public:
explicit RequestHelperBase(Kernel::HLERequestContext& context)
: context(&context), cmdbuf(context.CommandBuffer()) {}
void Skip(unsigned size_in_words, bool set_to_null) {
if (set_to_null)
void Skip(u32 size_in_words, bool set_to_null) {
if (set_to_null) {
memset(cmdbuf + index, 0, size_in_words * sizeof(u32));
index += size_in_words;
}
index += static_cast<ptrdiff_t>(size_in_words);
}
/**
@@ -49,15 +50,15 @@ public:
*/
void AlignWithPadding() {
if (index & 3) {
Skip(4 - (index & 3), true);
Skip(static_cast<u32>(4 - (index & 3)), true);
}
}
unsigned GetCurrentOffset() const {
return static_cast<unsigned>(index);
u32 GetCurrentOffset() const {
return static_cast<u32>(index);
}
void SetCurrentOffset(unsigned offset) {
void SetCurrentOffset(u32 offset) {
index = static_cast<ptrdiff_t>(offset);
}
};
@@ -89,7 +90,7 @@ public:
// The entire size of the raw data section in u32 units, including the 16 bytes of mandatory
// padding.
u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size;
u64 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size;
u32 num_handles_to_move{};
u32 num_domain_objects{};
@@ -105,7 +106,7 @@ public:
raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects;
}
header.data_size.Assign(raw_data_size);
header.data_size.Assign(static_cast<u32>(raw_data_size));
if (num_handles_to_copy || num_handles_to_move) {
header.enable_handle_descriptor.Assign(1);
}

View File

@@ -118,7 +118,7 @@ std::shared_ptr<Object> HandleTable::GetGeneric(Handle handle) const {
void HandleTable::Clear() {
for (u16 i = 0; i < table_size; ++i) {
generations[i] = i + 1;
generations[i] = static_cast<u16>(i + 1);
objects[i] = nullptr;
}
next_free_slot = 0;

View File

@@ -72,7 +72,7 @@ u32 GlobalScheduler::SelectThreads() {
if (top_thread != nullptr) {
// TODO(Blinkhawk): Implement Thread Pinning
} else {
idle_cores |= (1ul << core);
idle_cores |= (1U << core);
}
top_threads[core] = top_thread;
}
@@ -126,7 +126,7 @@ u32 GlobalScheduler::SelectThreads() {
top_threads[core_id] = suggested;
}
idle_cores &= ~(1ul << core_id);
idle_cores &= ~(1U << core_id);
}
u32 cores_needing_context_switch{};
for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {
@@ -134,7 +134,7 @@ u32 GlobalScheduler::SelectThreads() {
ASSERT(top_threads[core] == nullptr ||
static_cast<u32>(top_threads[core]->GetProcessorID()) == core);
if (update_thread(top_threads[core], sched)) {
cores_needing_context_switch |= (1ul << core);
cores_needing_context_switch |= (1U << core);
}
}
return cores_needing_context_switch;
@@ -364,7 +364,7 @@ void GlobalScheduler::EnableInterruptAndSchedule(u32 cores_pending_reschedule,
} else {
must_context_switch = true;
}
cores_pending_reschedule &= ~(1ul << core);
cores_pending_reschedule &= ~(1U << core);
}
if (must_context_switch) {
auto& core_scheduler = kernel.CurrentScheduler();
@@ -767,7 +767,7 @@ void Scheduler::SwitchToCurrent() {
current_thread->context_guard.unlock();
break;
}
if (current_thread->GetProcessorID() != core_id) {
if (static_cast<u32>(current_thread->GetProcessorID()) != core_id) {
current_thread->context_guard.unlock();
break;
}

View File

@@ -496,7 +496,7 @@ public:
{3, nullptr, "LoadIdTokenCache"},
{130, nullptr, "GetNintendoAccountUserResourceCacheForApplication"},
{150, nullptr, "CreateAuthorizationRequest"},
{160, nullptr, "StoreOpenContext"},
{160, &IManagerForApplication::StoreOpenContext, "StoreOpenContext"},
{170, nullptr, "LoadNetworkServiceLicenseKindAsync"},
};
// clang-format on
@@ -520,6 +520,12 @@ private:
rb.PushRaw<u64>(user_id.GetNintendoID());
}
void StoreOpenContext(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
Common::UUID user_id;
};
@@ -774,6 +780,17 @@ void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::LoadOpenContext(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
// This is similar to GetBaasAccountManagerForApplication
// This command is used concurrently with ListOpenContextStoredUsers
// TODO: Find the differences between this and GetBaasAccountManagerForApplication
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IManagerForApplication>(profile_manager->GetLastOpenedUser());
}
void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");

View File

@@ -34,6 +34,7 @@ public:
void IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx);
void GetProfileEditor(Kernel::HLERequestContext& ctx);
void ListQualifiedUsers(Kernel::HLERequestContext& ctx);
void LoadOpenContext(Kernel::HLERequestContext& ctx);
void ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx);
private:

View File

@@ -29,7 +29,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{110, nullptr, "StoreSaveDataThumbnail"},
{111, nullptr, "ClearSaveDataThumbnail"},
{120, nullptr, "CreateGuestLoginRequest"},
{130, nullptr, "LoadOpenContext"}, // 5.0.0+
{130, &ACC_U0::LoadOpenContext, "LoadOpenContext"}, // 5.0.0+
{131, &ACC_U0::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 6.0.0+
{140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"}, // 6.0.0+
{141, &ACC_U0::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+

View File

@@ -1192,7 +1192,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
{120, nullptr, "ExecuteProgram"},
{121, nullptr, "ClearUserChannel"},
{122, nullptr, "UnpopToUserChannel"},
{123, nullptr, "GetPreviousProgramIndex"},
{123, &IApplicationFunctions::GetPreviousProgramIndex, "GetPreviousProgramIndex"},
{124, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
{130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"},
{140, &IApplicationFunctions::GetFriendInvitationStorageChannelEvent, "GetFriendInvitationStorageChannelEvent"},
@@ -1554,6 +1554,14 @@ void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(Kernel::HLEReque
rb.Push<u32>(0);
}
void IApplicationFunctions::GetPreviousProgramIndex(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<s32>(previous_program_index);
}
void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");

View File

@@ -288,11 +288,13 @@ private:
void SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx);
void QueryApplicationPlayStatistics(Kernel::HLERequestContext& ctx);
void QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx);
void GetPreviousProgramIndex(Kernel::HLERequestContext& ctx);
void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx);
void GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx);
bool launch_popped_application_specific = false;
bool launch_popped_account_preselect = false;
s32 previous_program_index{-1};
Kernel::EventPair gpu_error_detected_event;
Kernel::EventPair friend_invitation_storage_channel_event;
Core::System& system;

View File

@@ -206,7 +206,8 @@ void AppletManager::SetDefaultAppletFrontendSet() {
void AppletManager::SetDefaultAppletsIfMissing() {
if (frontend.controller == nullptr) {
frontend.controller = std::make_unique<Core::Frontend::DefaultControllerApplet>();
frontend.controller =
std::make_unique<Core::Frontend::DefaultControllerApplet>(system.ServiceManager());
}
if (frontend.e_commerce == nullptr) {

View File

@@ -196,7 +196,9 @@ private:
const std::string& content_type_name) {
if (client == nullptr) {
client = std::make_unique<httplib::SSLClient>(BOXCAT_HOSTNAME, PORT);
client->set_timeout_sec(timeout_seconds);
client->set_connection_timeout(timeout_seconds);
client->set_read_timeout(timeout_seconds);
client->set_write_timeout(timeout_seconds);
}
httplib::Headers headers{
@@ -255,7 +257,7 @@ private:
return out;
}
std::unique_ptr<httplib::Client> client;
std::unique_ptr<httplib::SSLClient> client;
std::string path;
u64 title_id;
u64 build_id;
@@ -443,13 +445,25 @@ std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title)
Boxcat::StatusResult Boxcat::GetStatus(std::optional<std::string>& global,
std::map<std::string, EventStatus>& games) {
httplib::SSLClient client{BOXCAT_HOSTNAME, static_cast<int>(PORT)};
client.set_timeout_sec(static_cast<int>(TIMEOUT_SECONDS));
client.set_connection_timeout(static_cast<int>(TIMEOUT_SECONDS));
client.set_read_timeout(static_cast<int>(TIMEOUT_SECONDS));
client.set_write_timeout(static_cast<int>(TIMEOUT_SECONDS));
httplib::Headers headers{
{std::string("Game-Assets-API-Version"), std::string(BOXCAT_API_VERSION)},
{std::string("Boxcat-Client-Type"), std::string(BOXCAT_CLIENT_TYPE)},
};
if (!client.is_valid()) {
LOG_ERROR(Service_BCAT, "Client is invalid, going offline!");
return StatusResult::Offline;
}
if (!client.is_socket_open()) {
LOG_ERROR(Service_BCAT, "Failed to open socket, going offline!");
return StatusResult::Offline;
}
const auto response = client.Get(BOXCAT_PATHNAME_EVENTS, headers);
if (response == nullptr)
return StatusResult::Offline;

View File

@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/caps/caps_c.h"
namespace Service::Capture {
@@ -47,7 +49,7 @@ CAPS_C::CAPS_C() : ServiceFramework("caps:c") {
static const FunctionInfo functions[] = {
{1, nullptr, "CaptureRawImage"},
{2, nullptr, "CaptureRawImageWithTimeout"},
{33, nullptr, "Unknown33"},
{33, &CAPS_C::SetShimLibraryVersion, "SetShimLibraryVersion"},
{1001, nullptr, "RequestTakingScreenShot"},
{1002, nullptr, "RequestTakingScreenShotWithTimeout"},
{1011, nullptr, "NotifyTakingScreenShotRefused"},
@@ -72,4 +74,16 @@ CAPS_C::CAPS_C() : ServiceFramework("caps:c") {
CAPS_C::~CAPS_C() = default;
void CAPS_C::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto library_version{rp.Pop<u64>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
library_version, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
} // namespace Service::Capture

View File

@@ -16,6 +16,9 @@ class CAPS_C final : public ServiceFramework<CAPS_C> {
public:
explicit CAPS_C();
~CAPS_C() override;
private:
void SetShimLibraryVersion(Kernel::HLERequestContext& ctx);
};
} // namespace Service::Capture

View File

@@ -25,7 +25,12 @@ CAPS_SU::CAPS_SU() : ServiceFramework("caps:su") {
CAPS_SU::~CAPS_SU() = default;
void CAPS_SU::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Capture, "(STUBBED) called");
IPC::RequestParser rp{ctx};
const auto library_version{rp.Pop<u64>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
library_version, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);

View File

@@ -31,8 +31,7 @@ public:
CAPS_U::CAPS_U() : ServiceFramework("caps:u") {
// clang-format off
static const FunctionInfo functions[] = {
{31, nullptr, "GetShimLibraryVersion"},
{32, nullptr, "SetShimLibraryVersion"},
{32, &CAPS_U::SetShimLibraryVersion, "SetShimLibraryVersion"},
{102, &CAPS_U::GetAlbumContentsFileListForApplication, "GetAlbumContentsFileListForApplication"},
{103, nullptr, "DeleteAlbumContentsFileForApplication"},
{104, nullptr, "GetAlbumContentsFileSizeForApplication"},
@@ -53,6 +52,18 @@ CAPS_U::CAPS_U() : ServiceFramework("caps:u") {
CAPS_U::~CAPS_U() = default;
void CAPS_U::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto library_version{rp.Pop<u64>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
library_version, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void CAPS_U::GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& ctx) {
// Takes a type-0x6 output buffer containing an array of ApplicationAlbumFileEntry, a PID, an
// u8 ContentType, two s64s, and an u64 AppletResourceUserId. Returns an output u64 for total

View File

@@ -18,6 +18,7 @@ public:
~CAPS_U() override;
private:
void SetShimLibraryVersion(Kernel::HLERequestContext& ctx);
void GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& ctx);
};

View File

@@ -31,6 +31,10 @@ public:
virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
std::size_t size) = 0;
// When the controller is requesting a motion update for the shared memory
virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
std::size_t size) {}
// Called when input devices should be loaded
virtual void OnLoadInputDevices() = 0;

View File

@@ -42,8 +42,8 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
cur_entry.modifier = 0;
if (Settings::values.keyboard_enabled) {
for (std::size_t i = 0; i < keyboard_keys.size(); ++i) {
cur_entry.key[i / KEYS_PER_BYTE] |=
(keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE));
auto& entry = cur_entry.key[i / KEYS_PER_BYTE];
entry = static_cast<u8>(entry | (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE)));
}
for (std::size_t i = 0; i < keyboard_mods.size(); ++i) {

View File

@@ -250,6 +250,9 @@ void Controller_NPad::OnLoadInputDevices() {
std::transform(players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN,
players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END,
sticks[i].begin(), Input::CreateDevice<Input::AnalogDevice>);
std::transform(players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_BEGIN,
players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_END,
motions[i].begin(), Input::CreateDevice<Input::MotionDevice>);
}
}
@@ -257,7 +260,7 @@ void Controller_NPad::OnRelease() {}
void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
const auto controller_idx = NPadIdToIndex(npad_id);
[[maybe_unused]] const auto controller_type = connected_controllers[controller_idx].type;
const auto controller_type = connected_controllers[controller_idx].type;
if (!connected_controllers[controller_idx].is_connected) {
return;
}
@@ -272,54 +275,63 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus();
using namespace Settings::NativeButton;
pad_state.a.Assign(button_state[A - BUTTON_HID_BEGIN]->GetStatus());
pad_state.b.Assign(button_state[B - BUTTON_HID_BEGIN]->GetStatus());
pad_state.x.Assign(button_state[X - BUTTON_HID_BEGIN]->GetStatus());
pad_state.y.Assign(button_state[Y - BUTTON_HID_BEGIN]->GetStatus());
pad_state.l_stick.Assign(button_state[LStick - BUTTON_HID_BEGIN]->GetStatus());
pad_state.r_stick.Assign(button_state[RStick - BUTTON_HID_BEGIN]->GetStatus());
pad_state.l.Assign(button_state[L - BUTTON_HID_BEGIN]->GetStatus());
pad_state.r.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus());
pad_state.zl.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus());
pad_state.zr.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus());
pad_state.plus.Assign(button_state[Plus - BUTTON_HID_BEGIN]->GetStatus());
pad_state.minus.Assign(button_state[Minus - BUTTON_HID_BEGIN]->GetStatus());
if (controller_type != NPadControllerType::JoyLeft) {
pad_state.a.Assign(button_state[A - BUTTON_HID_BEGIN]->GetStatus());
pad_state.b.Assign(button_state[B - BUTTON_HID_BEGIN]->GetStatus());
pad_state.x.Assign(button_state[X - BUTTON_HID_BEGIN]->GetStatus());
pad_state.y.Assign(button_state[Y - BUTTON_HID_BEGIN]->GetStatus());
pad_state.r_stick.Assign(button_state[RStick - BUTTON_HID_BEGIN]->GetStatus());
pad_state.r.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus());
pad_state.zr.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus());
pad_state.plus.Assign(button_state[Plus - BUTTON_HID_BEGIN]->GetStatus());
pad_state.d_left.Assign(button_state[DLeft - BUTTON_HID_BEGIN]->GetStatus());
pad_state.d_up.Assign(button_state[DUp - BUTTON_HID_BEGIN]->GetStatus());
pad_state.d_right.Assign(button_state[DRight - BUTTON_HID_BEGIN]->GetStatus());
pad_state.d_down.Assign(button_state[DDown - BUTTON_HID_BEGIN]->GetStatus());
pad_state.r_stick_right.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT));
pad_state.r_stick_left.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT));
pad_state.r_stick_up.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
->GetAnalogDirectionStatus(Input::AnalogDirection::UP));
pad_state.r_stick_down.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN));
rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
}
pad_state.l_stick_right.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus(
Input::AnalogDirection::RIGHT));
pad_state.l_stick_left.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus(
Input::AnalogDirection::LEFT));
pad_state.l_stick_up.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus(
Input::AnalogDirection::UP));
pad_state.l_stick_down.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus(
Input::AnalogDirection::DOWN));
if (controller_type != NPadControllerType::JoyRight) {
pad_state.d_left.Assign(button_state[DLeft - BUTTON_HID_BEGIN]->GetStatus());
pad_state.d_up.Assign(button_state[DUp - BUTTON_HID_BEGIN]->GetStatus());
pad_state.d_right.Assign(button_state[DRight - BUTTON_HID_BEGIN]->GetStatus());
pad_state.d_down.Assign(button_state[DDown - BUTTON_HID_BEGIN]->GetStatus());
pad_state.l_stick.Assign(button_state[LStick - BUTTON_HID_BEGIN]->GetStatus());
pad_state.l.Assign(button_state[L - BUTTON_HID_BEGIN]->GetStatus());
pad_state.zl.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus());
pad_state.minus.Assign(button_state[Minus - BUTTON_HID_BEGIN]->GetStatus());
pad_state.r_stick_right.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT));
pad_state.r_stick_left.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT));
pad_state.r_stick_up.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
->GetAnalogDirectionStatus(Input::AnalogDirection::UP));
pad_state.r_stick_down.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN));
pad_state.l_stick_right.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT));
pad_state.l_stick_left.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT));
pad_state.l_stick_up.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
->GetAnalogDirectionStatus(Input::AnalogDirection::UP));
pad_state.l_stick_down.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN));
lstick_entry.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
}
pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus());
pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus());
lstick_entry.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
if (controller_type == NPadControllerType::JoyLeft ||
controller_type == NPadControllerType::JoyRight) {
pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus());
pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus());
}
}
void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
@@ -360,6 +372,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
continue;
}
const u32 npad_index = static_cast<u32>(i);
RequestPadStateUpdate(npad_index);
auto& pad_state = npad_pad_states[npad_index];
@@ -463,6 +476,131 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
shared_memory_entries.size() * sizeof(NPadEntry));
}
void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
std::size_t data_len) {
if (!IsControllerActivated()) {
return;
}
for (std::size_t i = 0; i < shared_memory_entries.size(); i++) {
auto& npad = shared_memory_entries[i];
const auto& controller_type = connected_controllers[i].type;
if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) {
continue;
}
const std::array<SixAxisGeneric*, 6> controller_sixaxes{
&npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left,
&npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right,
};
for (auto* sixaxis_sensor : controller_sixaxes) {
sixaxis_sensor->common.entry_count = 16;
sixaxis_sensor->common.total_entry_count = 17;
const auto& last_entry =
sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
sixaxis_sensor->common.timestamp = core_timing.GetCPUTicks();
sixaxis_sensor->common.last_entry_index =
(sixaxis_sensor->common.last_entry_index + 1) % 17;
auto& cur_entry = sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
cur_entry.timestamp = last_entry.timestamp + 1;
cur_entry.timestamp2 = cur_entry.timestamp;
}
// Try to read sixaxis sensor states
std::array<MotionDevice, 2> motion_devices;
if (sixaxis_sensors_enabled && Settings::values.motion_enabled) {
sixaxis_at_rest = true;
for (std::size_t e = 0; e < motion_devices.size(); ++e) {
const auto& device = motions[i][e];
if (device) {
std::tie(motion_devices[e].accel, motion_devices[e].gyro,
motion_devices[e].rotation, motion_devices[e].orientation) =
device->GetStatus();
sixaxis_at_rest = sixaxis_at_rest && motion_devices[e].gyro.Length2() < 0.0001f;
}
}
}
auto& full_sixaxis_entry =
npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index];
auto& handheld_sixaxis_entry =
npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index];
auto& dual_left_sixaxis_entry =
npad.sixaxis_dual_left.sixaxis[npad.sixaxis_dual_left.common.last_entry_index];
auto& dual_right_sixaxis_entry =
npad.sixaxis_dual_right.sixaxis[npad.sixaxis_dual_right.common.last_entry_index];
auto& left_sixaxis_entry =
npad.sixaxis_left.sixaxis[npad.sixaxis_left.common.last_entry_index];
auto& right_sixaxis_entry =
npad.sixaxis_right.sixaxis[npad.sixaxis_right.common.last_entry_index];
switch (controller_type) {
case NPadControllerType::None:
UNREACHABLE();
break;
case NPadControllerType::ProController:
if (sixaxis_sensors_enabled && motions[i][0]) {
full_sixaxis_entry.accel = motion_devices[0].accel;
full_sixaxis_entry.gyro = motion_devices[0].gyro;
full_sixaxis_entry.rotation = motion_devices[0].rotation;
full_sixaxis_entry.orientation = motion_devices[0].orientation;
}
break;
case NPadControllerType::Handheld:
if (sixaxis_sensors_enabled && motions[i][0]) {
handheld_sixaxis_entry.accel = motion_devices[0].accel;
handheld_sixaxis_entry.gyro = motion_devices[0].gyro;
handheld_sixaxis_entry.rotation = motion_devices[0].rotation;
handheld_sixaxis_entry.orientation = motion_devices[0].orientation;
}
break;
case NPadControllerType::JoyDual:
if (sixaxis_sensors_enabled && motions[i][0]) {
// Set motion for the left joycon
dual_left_sixaxis_entry.accel = motion_devices[0].accel;
dual_left_sixaxis_entry.gyro = motion_devices[0].gyro;
dual_left_sixaxis_entry.rotation = motion_devices[0].rotation;
dual_left_sixaxis_entry.orientation = motion_devices[0].orientation;
}
if (sixaxis_sensors_enabled && motions[i][1]) {
// Set motion for the right joycon
dual_right_sixaxis_entry.accel = motion_devices[1].accel;
dual_right_sixaxis_entry.gyro = motion_devices[1].gyro;
dual_right_sixaxis_entry.rotation = motion_devices[1].rotation;
dual_right_sixaxis_entry.orientation = motion_devices[1].orientation;
}
break;
case NPadControllerType::JoyLeft:
if (sixaxis_sensors_enabled && motions[i][0]) {
left_sixaxis_entry.accel = motion_devices[0].accel;
left_sixaxis_entry.gyro = motion_devices[0].gyro;
left_sixaxis_entry.rotation = motion_devices[0].rotation;
left_sixaxis_entry.orientation = motion_devices[0].orientation;
}
break;
case NPadControllerType::JoyRight:
if (sixaxis_sensors_enabled && motions[i][1]) {
right_sixaxis_entry.accel = motion_devices[1].accel;
right_sixaxis_entry.gyro = motion_devices[1].gyro;
right_sixaxis_entry.rotation = motion_devices[1].rotation;
right_sixaxis_entry.orientation = motion_devices[1].orientation;
}
break;
case NPadControllerType::Pokeball:
break;
}
}
std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
shared_memory_entries.size() * sizeof(NPadEntry));
}
void Controller_NPad::SetSupportedStyleSet(NPadType style_set) {
style.raw = style_set.raw;
}
@@ -495,6 +633,14 @@ Controller_NPad::NpadHoldType Controller_NPad::GetHoldType() const {
return hold_type;
}
void Controller_NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) {
handheld_activation_mode = activation_mode;
}
Controller_NPad::NpadHandheldActivationMode Controller_NPad::GetNpadHandheldActivationMode() const {
return handheld_activation_mode;
}
void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode) {
const std::size_t npad_index = NPadIdToIndex(npad_id);
ASSERT(npad_index < shared_memory_entries.size());
@@ -503,20 +649,31 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode)
}
}
void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
void Controller_NPad::VibrateController(const std::vector<u32>& controllers,
const std::vector<Vibration>& vibrations) {
LOG_DEBUG(Service_HID, "(STUBBED) called");
LOG_TRACE(Service_HID, "called");
if (!Settings::values.vibration_enabled || !can_controllers_vibrate) {
return;
}
for (std::size_t i = 0; i < controller_ids.size(); i++) {
std::size_t controller_pos = NPadIdToIndex(static_cast<u32>(i));
if (connected_controllers[controller_pos].is_connected) {
// TODO(ogniK): Vibrate the physical controller
bool success = true;
for (std::size_t i = 0; i < controllers.size(); ++i) {
if (!connected_controllers[i].is_connected) {
continue;
}
using namespace Settings::NativeButton;
const auto& button_state = buttons[i];
if (button_state[A - BUTTON_HID_BEGIN]) {
if (button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
vibrations[0].amp_high, vibrations[0].amp_low, vibrations[0].freq_high,
vibrations[0].freq_low)) {
success = false;
}
}
}
last_processed_vibration = vibrations.back();
if (success) {
last_processed_vibration = vibrations.back();
}
}
Controller_NPad::Vibration Controller_NPad::GetLastVibration() const {
@@ -582,6 +739,14 @@ Controller_NPad::GyroscopeZeroDriftMode Controller_NPad::GetGyroscopeZeroDriftMo
return gyroscope_zero_drift_mode;
}
bool Controller_NPad::IsSixAxisSensorAtRest() const {
return sixaxis_at_rest;
}
void Controller_NPad::SetSixAxisEnabled(bool six_axis_status) {
sixaxis_sensors_enabled = six_axis_status;
}
void Controller_NPad::MergeSingleJoyAsDualJoy(u32 npad_id_1, u32 npad_id_2) {
const auto npad_index_1 = NPadIdToIndex(npad_id_1);
const auto npad_index_2 = NPadIdToIndex(npad_id_2);
@@ -656,6 +821,15 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) {
}
}
bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const {
return unintended_home_button_input_protection[NPadIdToIndex(npad_id)];
}
void Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
u32 npad_id) {
unintended_home_button_input_protection[NPadIdToIndex(npad_id)] = is_protection_enabled;
}
void Controller_NPad::SetVibrationEnabled(bool can_vibrate) {
can_controllers_vibrate = can_vibrate;
}

View File

@@ -32,6 +32,10 @@ public:
// When the controller is requesting an update for the shared memory
void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
// When the controller is requesting a motion update for the shared memory
void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
std::size_t size) override;
// Called when input devices should be loaded
void OnLoadInputDevices() override;
@@ -74,6 +78,12 @@ public:
Single = 1,
};
enum class NpadHandheldActivationMode : u64 {
Dual = 0,
Single = 1,
None = 2,
};
enum class NPadControllerType {
None,
ProController,
@@ -110,9 +120,12 @@ public:
void SetHoldType(NpadHoldType joy_hold_type);
NpadHoldType GetHoldType() const;
void SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode);
NpadHandheldActivationMode GetNpadHandheldActivationMode() const;
void SetNpadMode(u32 npad_id, NPadAssignments assignment_mode);
void VibrateController(const std::vector<u32>& controller_ids,
void VibrateController(const std::vector<u32>& controllers,
const std::vector<Vibration>& vibrations);
Vibration GetLastVibration() const;
@@ -130,7 +143,11 @@ public:
void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode);
GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode() const;
bool IsSixAxisSensorAtRest() const;
void SetSixAxisEnabled(bool six_axis_status);
LedPattern GetLedPattern(u32 npad_id);
bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const;
void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id);
void SetVibrationEnabled(bool can_vibrate);
bool IsVibrationEnabled() const;
void ClearAllConnectedControllers();
@@ -252,6 +269,24 @@ private:
};
static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size");
struct SixAxisStates {
s64_le timestamp{};
INSERT_PADDING_WORDS(2);
s64_le timestamp2{};
Common::Vec3f accel{};
Common::Vec3f gyro{};
Common::Vec3f rotation{};
std::array<Common::Vec3f, 3> orientation{};
s64_le always_one{1};
};
static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size");
struct SixAxisGeneric {
CommonHeader common{};
std::array<SixAxisStates, 17> sixaxis{};
};
static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size");
enum class ColorReadError : u32_le {
ReadOk = 0,
ColorDoesntExist = 1,
@@ -281,6 +316,13 @@ private:
};
};
struct MotionDevice {
Common::Vec3f accel;
Common::Vec3f gyro;
Common::Vec3f rotation;
std::array<Common::Vec3f, 3> orientation;
};
struct NPadEntry {
NPadType joy_styles;
NPadAssignments pad_assignment;
@@ -300,9 +342,12 @@ private:
NPadGeneric pokeball_states;
NPadGeneric libnx; // TODO(ogniK): Find out what this actually is, libnx seems to only be
// relying on this for the time being
INSERT_PADDING_BYTES(
0x708 *
6); // TODO(ogniK): SixAxis states, require more information before implementation
SixAxisGeneric sixaxis_full;
SixAxisGeneric sixaxis_handheld;
SixAxisGeneric sixaxis_dual_left;
SixAxisGeneric sixaxis_dual_right;
SixAxisGeneric sixaxis_left;
SixAxisGeneric sixaxis_right;
NPadDevice device_type;
NPadProperties properties;
INSERT_PADDING_WORDS(1);
@@ -325,22 +370,30 @@ private:
NPadType style{};
std::array<NPadEntry, 10> shared_memory_entries{};
std::array<
using ButtonArray = std::array<
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>,
10>
buttons;
std::array<
10>;
using StickArray = std::array<
std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>,
10>
sticks;
10>;
using MotionArray = std::array<
std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTION_HID>,
10>;
ButtonArray buttons;
StickArray sticks;
MotionArray motions;
std::vector<u32> supported_npad_id_types{};
NpadHoldType hold_type{NpadHoldType::Vertical};
NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
// Each controller should have their own styleset changed event
std::array<Kernel::EventPair, 10> styleset_changed_events;
Vibration last_processed_vibration{};
std::array<ControllerHolder, 10> connected_controllers{};
std::array<bool, 10> unintended_home_button_input_protection{};
GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
bool can_controllers_vibrate{true};
bool sixaxis_sensors_enabled{true};
bool sixaxis_at_rest{true};
std::array<ControllerPad, 10> npad_pad_states{};
bool is_in_lr_assignment_mode{false};
Core::System& system;

View File

@@ -40,7 +40,8 @@ namespace Service::HID {
// Updating period for each HID device.
// HID is polled every 15ms, this value was derived from
// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet
constexpr auto pad_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.6Hz)
constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz)
constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz)
constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
IAppletResource::IAppletResource(Core::System& system)
@@ -79,10 +80,14 @@ IAppletResource::IAppletResource(Core::System& system)
[this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
UpdateControllers(user_data, ns_late);
});
// TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
motion_update_event = Core::Timing::CreateEvent(
"HID::MotionPadCallback",
[this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
UpdateMotion(user_data, ns_late);
});
system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event);
system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event);
ReloadInputDevices();
}
@@ -122,6 +127,16 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event);
}
void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
for (const auto& controller : controllers) {
controller->OnMotionUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
}
core_timing.ScheduleEvent(motion_update_ns - ns_late, motion_update_event);
}
class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
public:
IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") {
@@ -164,8 +179,8 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
{56, nullptr, "ActivateJoyXpad"},
{58, nullptr, "GetJoyXpadLifoHandle"},
{59, nullptr, "GetJoyXpadIds"},
{60, nullptr, "ActivateSixAxisSensor"},
{61, nullptr, "DeactivateSixAxisSensor"},
{60, &Hid::ActivateSixAxisSensor, "ActivateSixAxisSensor"},
{61, &Hid::DeactivateSixAxisSensor, "DeactivateSixAxisSensor"},
{62, nullptr, "GetSixAxisSensorLifoHandle"},
{63, nullptr, "ActivateJoySixAxisSensor"},
{64, nullptr, "DeactivateJoySixAxisSensor"},
@@ -173,7 +188,7 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
{66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
{67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"},
{68, nullptr, "IsSixAxisSensorFusionEnabled"},
{69, nullptr, "EnableSixAxisSensorFusion"},
{69, &Hid::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"},
{70, nullptr, "SetSixAxisSensorFusionParameters"},
{71, nullptr, "GetSixAxisSensorFusionParameters"},
{72, nullptr, "ResetSixAxisSensorFusionParameters"},
@@ -209,8 +224,8 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
{128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
{129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"},
{130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
{131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
{132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
{131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"},
{132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"},
{133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
{134, nullptr, "SetNpadAnalogStickUseCenterClamp"},
{135, nullptr, "SetNpadCaptureButtonAssignment"},
@@ -329,6 +344,31 @@ void Hid::GetXpadIDs(Kernel::HLERequestContext& ctx) {
rb.Push(0);
}
void Hid::ActivateSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad).SetSixAxisEnabled(true);
LOG_DEBUG(Service_HID, "called, handle={}, applet_resource_user_id={}", handle,
applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad).SetSixAxisEnabled(false);
LOG_DEBUG(Service_HID, "called, handle={}, applet_resource_user_id={}", handle,
applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::ActivateDebugPad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@@ -433,6 +473,19 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
[[maybe_unused]] const auto enable{rp.Pop<bool>()};
const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto handle{rp.Pop<u32>()};
@@ -484,13 +537,13 @@ void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
applet_resource_user_id);
LOG_DEBUG(Service_HID, "called, handle={}, applet_resource_user_id={}", handle,
applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
// TODO (Hexagon12): Properly implement reading gyroscope values from controllers.
rb.Push(true);
rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad)
.IsSixAxisSensorAtRest());
}
void Hid::SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
@@ -714,8 +767,11 @@ void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto mode{rp.Pop<u64>()};
LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}",
applet_resource_user_id, mode);
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, mode={}", applet_resource_user_id,
mode);
applet_resource->GetController<Controller_NPad>(HidController::NPad)
.SetNpadHandheldActivationMode(Controller_NPad::NpadHandheldActivationMode{mode});
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -725,11 +781,13 @@ void Hid::GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
applet_resource_user_id);
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(
static_cast<u64>(applet_resource->GetController<Controller_NPad>(HidController::NPad)
.GetNpadHandheldActivationMode()));
}
void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
@@ -751,6 +809,40 @@ void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
}
}
void Hid::IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id,
applet_resource_user_id);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<bool>(controller.IsUnintendedHomeButtonInputProtectionEnabled(npad_id));
}
void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto unintended_home_button_input_protection{rp.Pop<bool>()};
const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID,
"(STUBBED) called, unintended_home_button_input_protection={}, npad_id={},"
"applet_resource_user_id={}",
npad_id, unintended_home_button_input_protection, applet_resource_user_id);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
controller.SetUnintendedHomeButtonInputProtectionEnabled(
unintended_home_button_input_protection, npad_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@@ -772,18 +864,18 @@ void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto controller_id{rp.Pop<u32>()};
const auto controller{rp.Pop<u32>()};
const auto vibration_values{rp.PopRaw<Controller_NPad::Vibration>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id,
LOG_DEBUG(Service_HID, "called, controller={}, applet_resource_user_id={}", controller,
applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
applet_resource->GetController<Controller_NPad>(HidController::NPad)
.VibrateController({controller_id}, {vibration_values});
.VibrateController({controller}, {vibration_values});
}
void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
@@ -801,8 +893,6 @@ void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
std::memcpy(controller_list.data(), controllers.data(), controllers.size());
std::memcpy(vibration_list.data(), vibrations.data(), vibrations.size());
std::transform(controller_list.begin(), controller_list.end(), controller_list.begin(),
[](u32 controller_id) { return controller_id - 3; });
applet_resource->GetController<Controller_NPad>(HidController::NPad)
.VibrateController(controller_list, vibration_list);

View File

@@ -65,10 +65,12 @@ private:
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
std::shared_ptr<Kernel::SharedMemory> shared_mem;
std::shared_ptr<Core::Timing::EventType> pad_update_event;
std::shared_ptr<Core::Timing::EventType> motion_update_event;
Core::System& system;
std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
@@ -86,6 +88,8 @@ private:
void CreateAppletResource(Kernel::HLERequestContext& ctx);
void ActivateXpad(Kernel::HLERequestContext& ctx);
void GetXpadIDs(Kernel::HLERequestContext& ctx);
void ActivateSixAxisSensor(Kernel::HLERequestContext& ctx);
void DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx);
void ActivateDebugPad(Kernel::HLERequestContext& ctx);
void ActivateTouchScreen(Kernel::HLERequestContext& ctx);
void ActivateMouse(Kernel::HLERequestContext& ctx);
@@ -95,6 +99,7 @@ private:
void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx);
void StartSixAxisSensor(Kernel::HLERequestContext& ctx);
void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
void EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx);
void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
void GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
void ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
@@ -118,6 +123,8 @@ private:
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
void IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx);
void EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx);
void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx);
void EndPermitVibrationSession(Kernel::HLERequestContext& ctx);
void SendVibrationValue(Kernel::HLERequestContext& ctx);

View File

@@ -131,7 +131,7 @@ template <typename T>
T GetRandomValue(T min, T max) {
std::random_device device;
std::mt19937 gen(device());
std::uniform_int_distribution<u64> distribution(0, static_cast<u64>(max));
std::uniform_int_distribution<u64> distribution(static_cast<u64>(min), static_cast<u64>(max));
return static_cast<T>(distribution(gen));
}
@@ -428,7 +428,7 @@ bool MiiManager::IsFullDatabase() const {
}
u32 MiiManager::GetCount(SourceFlag source_flag) const {
u32 count{};
std::size_t count{};
if ((source_flag & SourceFlag::Database) != SourceFlag::None) {
// TODO(bunnei): We don't implement the Mii database, but when we do, update this
count += 0;
@@ -436,7 +436,7 @@ u32 MiiManager::GetCount(SourceFlag source_flag) const {
if ((source_flag & SourceFlag::Default) != SourceFlag::None) {
count += DefaultMiiCount;
}
return count;
return static_cast<u32>(count);
}
ResultVal<MiiInfo> MiiManager::UpdateLatest([[maybe_unused]] const MiiInfo& info,

View File

@@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <array>
#include <atomic>
#include "common/logging/log.h"
@@ -72,10 +73,10 @@ private:
std::array<u8, 10> uuid;
u8 uuid_length; // TODO(ogniK): Figure out if this is actual the uuid length or does it
// mean something else
INSERT_PADDING_BYTES(0x15);
std::array<u8, 0x15> padding_1;
u32_le protocol;
u32_le tag_type;
INSERT_PADDING_BYTES(0x2c);
std::array<u8, 0x2c> padding_2;
};
static_assert(sizeof(TagInfo) == 0x54, "TagInfo is an invalid size");
@@ -213,13 +214,15 @@ private:
LOG_DEBUG(Service_NFP, "called");
IPC::ResponseBuilder rb{ctx, 2};
auto amiibo = nfp_interface.GetAmiiboBuffer();
TagInfo tag_info{};
tag_info.uuid = amiibo.uuid;
tag_info.uuid_length = static_cast<u8>(tag_info.uuid.size());
tag_info.protocol = 1; // TODO(ogniK): Figure out actual values
tag_info.tag_type = 2;
const auto& amiibo = nfp_interface.GetAmiiboBuffer();
const TagInfo tag_info{
.uuid = amiibo.uuid,
.uuid_length = static_cast<u8>(tag_info.uuid.size()),
.padding_1 = {},
.protocol = 1, // TODO(ogniK): Figure out actual values
.tag_type = 2,
.padding_2 = {},
};
ctx.WriteBuffer(tag_info);
rb.Push(RESULT_SUCCESS);
}
@@ -236,7 +239,7 @@ private:
LOG_DEBUG(Service_NFP, "called");
IPC::ResponseBuilder rb{ctx, 2};
auto amiibo = nfp_interface.GetAmiiboBuffer();
const auto& amiibo = nfp_interface.GetAmiiboBuffer();
ctx.WriteBuffer(amiibo.model_info);
rb.Push(RESULT_SUCCESS);
}

View File

@@ -46,6 +46,8 @@ u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, const std:
return GetVARegions(input, output);
case IoctlCommand::IocUnmapBufferCommand:
return UnmapBuffer(input, output);
case IoctlCommand::IocFreeSpaceCommand:
return FreeSpace(input, output);
default:
break;
}
@@ -91,6 +93,20 @@ u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>&
return result;
}
u32 nvhost_as_gpu::FreeSpace(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlFreeSpace params{};
std::memcpy(&params, input.data(), input.size());
LOG_DEBUG(Service_NVDRV, "called, offset={:X}, pages={:X}, page_size={:X}", params.offset,
params.pages, params.page_size);
system.GPU().MemoryManager().Unmap(params.offset,
static_cast<std::size_t>(params.pages) * params.page_size);
std::memcpy(output.data(), &params, output.size());
return NvErrCodes::Success;
}
u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) {
const auto num_entries = input.size() / sizeof(IoctlRemapEntry);
@@ -265,7 +281,7 @@ std::optional<nvhost_as_gpu::BufferMap> nvhost_as_gpu::FindBufferMap(GPUVAddr gp
}
}
return {};
return std::nullopt;
}
void nvhost_as_gpu::AddBufferMap(GPUVAddr gpu_addr, std::size_t size, VAddr cpu_addr,
@@ -286,7 +302,7 @@ std::optional<std::size_t> nvhost_as_gpu::RemoveBufferMap(GPUVAddr gpu_addr) {
return size;
}
return {};
return std::nullopt;
}
} // namespace Service::Nvidia::Devices

View File

@@ -82,6 +82,7 @@ private:
IocBindChannelCommand = 0x40044101,
IocGetVaRegionsCommand = 0xC0404108,
IocUnmapBufferCommand = 0xC0084105,
IocFreeSpaceCommand = 0xC0104103,
};
struct IoctlInitalizeEx {
@@ -107,6 +108,13 @@ private:
};
static_assert(sizeof(IoctlAllocSpace) == 24, "IoctlInitalizeEx is incorrect size");
struct IoctlFreeSpace {
u64_le offset;
u32_le pages;
u32_le page_size;
};
static_assert(sizeof(IoctlFreeSpace) == 16, "IoctlFreeSpace is incorrect size");
struct IoctlRemapEntry {
u16_le flags;
u16_le kind;
@@ -162,6 +170,7 @@ private:
u32 Remap(const std::vector<u8>& input, std::vector<u8>& output);
u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
u32 UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
u32 FreeSpace(const std::vector<u8>& input, std::vector<u8>& output);
u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output);

View File

@@ -22,6 +22,18 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
switch (static_cast<IoctlCommand>(command.raw)) {
case IoctlCommand::IocSetNVMAPfdCommand:
return SetNVMAPfd(input, output);
case IoctlCommand::IocSubmit:
return Submit(input, output);
case IoctlCommand::IocGetSyncpoint:
return GetSyncpoint(input, output);
case IoctlCommand::IocGetWaitbase:
return GetWaitbase(input, output);
case IoctlCommand::IocMapBuffer:
return MapBuffer(input, output);
case IoctlCommand::IocMapBufferEx:
return MapBufferEx(input, output);
case IoctlCommand::IocUnmapBufferEx:
return UnmapBufferEx(input, output);
}
UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -30,11 +42,67 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlSetNvmapFD params{};
std::memcpy(&params, input.data(), input.size());
std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
nvmap_fd = params.nvmap_fd;
return 0;
}
u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlSubmit params{};
std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
return 0;
}
u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlGetSyncpoint params{};
std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
params.value = 0; // Seems to be hard coded at 0
std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
return 0;
}
u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlGetWaitbase params{};
std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
params.value = 0; // Seems to be hard coded at 0
std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
return 0;
}
u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlMapBuffer params{};
std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
params.address_1);
params.address_1 = 0;
params.address_2 = 0;
std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
return 0;
}
u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlMapBufferEx params{};
std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
params.address_1);
params.address_1 = 0;
params.address_2 = 0;
std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
return 0;
}
u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlUnmapBufferEx params{};
std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
return 0;
}
} // namespace Service::Nvidia::Devices

View File

@@ -23,16 +23,66 @@ public:
private:
enum class IoctlCommand : u32_le {
IocSetNVMAPfdCommand = 0x40044801,
IocSubmit = 0xC0400001,
IocGetSyncpoint = 0xC0080002,
IocGetWaitbase = 0xC0080003,
IocMapBuffer = 0xC01C0009,
IocMapBufferEx = 0xC0A40009,
IocUnmapBufferEx = 0xC0A4000A,
};
struct IoctlSetNvmapFD {
u32_le nvmap_fd;
};
static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
static_assert(sizeof(IoctlSetNvmapFD) == 0x4, "IoctlSetNvmapFD is incorrect size");
struct IoctlSubmit {
INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit has incorrect size");
struct IoctlGetSyncpoint {
u32 unknown; // seems to be ignored? Nintendo added this
u32 value;
};
static_assert(sizeof(IoctlGetSyncpoint) == 0x08, "IoctlGetSyncpoint has incorrect size");
struct IoctlGetWaitbase {
u32 unknown; // seems to be ignored? Nintendo added this
u32 value;
};
static_assert(sizeof(IoctlGetWaitbase) == 0x08, "IoctlGetWaitbase has incorrect size");
struct IoctlMapBuffer {
u32 unknown;
u32 address_1;
u32 address_2;
INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
struct IoctlMapBufferEx {
u32 unknown;
u32 address_1;
u32 address_2;
INSERT_PADDING_BYTES(0x98); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlMapBufferEx) == 0xA4, "IoctlMapBufferEx has incorrect size");
struct IoctlUnmapBufferEx {
INSERT_PADDING_BYTES(0xA4); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlUnmapBufferEx) == 0xA4, "IoctlUnmapBufferEx has incorrect size");
u32_le nvmap_fd{};
u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
};
} // namespace Service::Nvidia::Devices

View File

@@ -22,6 +22,18 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
switch (static_cast<IoctlCommand>(command.raw)) {
case IoctlCommand::IocSetNVMAPfdCommand:
return SetNVMAPfd(input, output);
case IoctlCommand::IocSubmit:
return Submit(input, output);
case IoctlCommand::IocGetSyncpoint:
return GetSyncpoint(input, output);
case IoctlCommand::IocGetWaitbase:
return GetWaitbase(input, output);
case IoctlCommand::IocMapBuffer:
return MapBuffer(input, output);
case IoctlCommand::IocMapBufferEx:
return MapBuffer(input, output);
case IoctlCommand::IocUnmapBufferEx:
return UnmapBufferEx(input, output);
}
UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -30,11 +42,71 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlSetNvmapFD params{};
std::memcpy(&params, input.data(), input.size());
std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
nvmap_fd = params.nvmap_fd;
return 0;
}
u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlSubmit params{};
std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
// Workaround for Luigi's Mansion 3, as nvhost_vic is not implemented for asynch GPU
params.command_buffer = {};
std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
return 0;
}
u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlGetSyncpoint params{};
std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
params.value = 0; // Seems to be hard coded at 0
std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
return 0;
}
u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlGetWaitbase params{};
std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
params.value = 0; // Seems to be hard coded at 0
std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
return 0;
}
u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlMapBuffer params{};
std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
params.address_1);
params.address_1 = 0;
params.address_2 = 0;
std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
return 0;
}
u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlMapBufferEx params{};
std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
params.address_1);
params.address_1 = 0;
params.address_2 = 0;
std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
return 0;
}
u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlUnmapBufferEx params{};
std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
return 0;
}
} // namespace Service::Nvidia::Devices

View File

@@ -4,6 +4,7 @@
#pragma once
#include <array>
#include <vector>
#include "common/common_types.h"
#include "common/swap.h"
@@ -23,6 +24,12 @@ public:
private:
enum class IoctlCommand : u32_le {
IocSetNVMAPfdCommand = 0x40044801,
IocSubmit = 0xC0400001,
IocGetSyncpoint = 0xC0080002,
IocGetWaitbase = 0xC0080003,
IocMapBuffer = 0xC01C0009,
IocMapBufferEx = 0xC03C0009,
IocUnmapBufferEx = 0xC03C000A,
};
struct IoctlSetNvmapFD {
@@ -30,9 +37,65 @@ private:
};
static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
struct IoctlSubmitCommandBuffer {
u32 id;
u32 offset;
u32 count;
};
static_assert(sizeof(IoctlSubmitCommandBuffer) == 0xC,
"IoctlSubmitCommandBuffer is incorrect size");
struct IoctlSubmit {
u32 command_buffer_count;
u32 relocations_count;
u32 syncpt_count;
u32 wait_count;
std::array<IoctlSubmitCommandBuffer, 4> command_buffer;
};
static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit is incorrect size");
struct IoctlGetSyncpoint {
u32 unknown; // seems to be ignored? Nintendo added this
u32 value;
};
static_assert(sizeof(IoctlGetSyncpoint) == 0x8, "IoctlGetSyncpoint is incorrect size");
struct IoctlGetWaitbase {
u32 unknown; // seems to be ignored? Nintendo added this
u32 value;
};
static_assert(sizeof(IoctlGetWaitbase) == 0x8, "IoctlGetWaitbase is incorrect size");
struct IoctlMapBuffer {
u32 unknown;
u32 address_1;
u32 address_2;
INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
struct IoctlMapBufferEx {
u32 unknown;
u32 address_1;
u32 address_2;
INSERT_PADDING_BYTES(0x30); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlMapBufferEx) == 0x3C, "IoctlMapBufferEx is incorrect size");
struct IoctlUnmapBufferEx {
INSERT_PADDING_BYTES(0x3C); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlUnmapBufferEx) == 0x3C, "IoctlUnmapBufferEx is incorrect size");
u32_le nvmap_fd{};
u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
};
} // namespace Service::Nvidia::Devices

View File

@@ -54,7 +54,7 @@ struct EventInterface {
}
mask = mask >> 1;
}
return {};
return std::nullopt;
}
void SetEventStatus(const u32 event_id, EventState new_status) {
EventState old_status = status[event_id];

View File

@@ -99,6 +99,20 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
queue_sequence.push_back(slot);
}
void BufferQueue::CancelBuffer(u32 slot, const Service::Nvidia::MultiFence& multi_fence) {
const auto itr = std::find_if(queue.begin(), queue.end(),
[slot](const Buffer& buffer) { return buffer.slot == slot; });
ASSERT(itr != queue.end());
ASSERT(itr->status != Buffer::Status::Free);
itr->status = Buffer::Status::Free;
itr->multi_fence = multi_fence;
itr->swap_interval = 0;
free_buffers.push_back(slot);
buffer_wait_event.writable->Signal();
}
std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() {
auto itr = queue.end();
// Iterate to find a queued buffer matching the requested slot.

View File

@@ -95,6 +95,7 @@ public:
void QueueBuffer(u32 slot, BufferTransformFlags transform,
const Common::Rectangle<int>& crop_rect, u32 swap_interval,
Service::Nvidia::MultiFence& multi_fence);
void CancelBuffer(u32 slot, const Service::Nvidia::MultiFence& multi_fence);
std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer();
void ReleaseBuffer(u32 slot);
void Disconnect();

View File

@@ -114,7 +114,7 @@ std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) {
[&](const VI::Display& display) { return display.GetName() == name; });
if (itr == displays.end()) {
return {};
return std::nullopt;
}
return itr->GetID();
@@ -124,7 +124,7 @@ std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
auto* const display = FindDisplay(display_id);
if (display == nullptr) {
return {};
return std::nullopt;
}
const u64 layer_id = next_layer_id++;
@@ -144,7 +144,7 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) co
const auto* const layer = FindLayer(display_id, layer_id);
if (layer == nullptr) {
return {};
return std::nullopt;
}
return layer->GetBufferQueue().GetId();

View File

@@ -89,8 +89,6 @@ namespace Service {
return function_string;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ServiceFrameworkBase::ServiceFrameworkBase(const char* service_name, u32 max_sessions,
InvokerFn* handler_invoker)
: service_name(service_name), max_sessions(max_sessions), handler_invoker(handler_invoker) {}
@@ -189,9 +187,6 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
return RESULT_SUCCESS;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Module interface
/// Initialize ServiceManager
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) {
// NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it

View File

@@ -19,7 +19,7 @@ constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorModule::SM, 4);
constexpr ResultCode ERR_INVALID_NAME(ErrorModule::SM, 6);
constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7);
ServiceManager::ServiceManager() = default;
ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {}
ServiceManager::~ServiceManager() = default;
void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) {
@@ -27,11 +27,11 @@ void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) {
}
static ResultCode ValidateServiceName(const std::string& name) {
if (name.size() <= 0 || name.size() > 8) {
if (name.empty() || name.size() > 8) {
LOG_ERROR(Service_SM, "Invalid service name! service={}", name);
return ERR_INVALID_NAME;
}
if (name.find('\0') != std::string::npos) {
if (name.rfind('\0') != std::string::npos) {
LOG_ERROR(Service_SM, "A non null terminated service was passed");
return ERR_INVALID_NAME;
}
@@ -48,8 +48,8 @@ void ServiceManager::InstallInterfaces(std::shared_ptr<ServiceManager> self,
self->controller_interface = std::make_unique<Controller>();
}
ResultVal<std::shared_ptr<Kernel::ServerPort>> ServiceManager::RegisterService(
std::string name, unsigned int max_sessions) {
ResultVal<std::shared_ptr<Kernel::ServerPort>> ServiceManager::RegisterService(std::string name,
u32 max_sessions) {
CASCADE_CODE(ValidateServiceName(name));
@@ -58,7 +58,6 @@ ResultVal<std::shared_ptr<Kernel::ServerPort>> ServiceManager::RegisterService(
return ERR_ALREADY_REGISTERED;
}
auto& kernel = Core::System::GetInstance().Kernel();
auto [server_port, client_port] =
Kernel::ServerPort::CreatePortPair(kernel, max_sessions, name);

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