summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.ci/yuzu-patreon-step2.yml1
-rw-r--r--src/audio_core/codec.cpp5
-rw-r--r--src/audio_core/codec.h2
-rw-r--r--src/audio_core/command_generator.cpp5
-rw-r--r--src/audio_core/cubeb_sink.cpp4
-rw-r--r--src/common/wall_clock.cpp2
-rw-r--r--src/common/wall_clock.h2
-rw-r--r--src/common/x64/native_clock.h2
-rw-r--r--src/core/core.h2
-rw-r--r--src/core/frontend/applets/controller.cpp8
-rw-r--r--src/core/frontend/applets/controller.h8
-rw-r--r--src/core/hle/service/am/applets/applets.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.h4
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp202
-rw-r--r--src/core/hle/service/hid/controllers/npad.h4
-rw-r--r--src/core/hle/service/hid/hid.cpp21
-rw-r--r--src/core/hle/service/hid/hid.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp70
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h52
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp74
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h63
-rw-r--r--src/video_core/renderer_vulkan/vk_device.cpp8
-rw-r--r--src/yuzu/game_list.cpp5
-rw-r--r--src/yuzu/game_list_p.h2
-rw-r--r--src/yuzu/main.cpp14
25 files changed, 454 insertions, 111 deletions
diff --git a/.ci/yuzu-patreon-step2.yml b/.ci/yuzu-patreon-step2.yml
index 41eccd973..3f338e2a0 100644
--- a/.ci/yuzu-patreon-step2.yml
+++ b/.ci/yuzu-patreon-step2.yml
@@ -9,6 +9,7 @@ stages:
9 displayName: 'build' 9 displayName: 'build'
10 jobs: 10 jobs:
11 - job: build 11 - job: build
12 timeoutInMinutes: 120
12 displayName: 'windows-msvc' 13 displayName: 'windows-msvc'
13 pool: 14 pool:
14 vmImage: windows-2019 15 vmImage: windows-2019
diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp
index c5a0d98ce..2fb91c13a 100644
--- a/src/audio_core/codec.cpp
+++ b/src/audio_core/codec.cpp
@@ -16,8 +16,9 @@ std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM
16 16
17 constexpr std::size_t FRAME_LEN = 8; 17 constexpr std::size_t FRAME_LEN = 8;
18 constexpr std::size_t SAMPLES_PER_FRAME = 14; 18 constexpr std::size_t SAMPLES_PER_FRAME = 14;
19 constexpr std::array<int, 16> SIGNED_NIBBLES = { 19 static constexpr std::array<int, 16> SIGNED_NIBBLES{
20 {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; 20 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1,
21 };
21 22
22 const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME; 23 const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME;
23 const std::size_t ret_size = 24 const std::size_t ret_size =
diff --git a/src/audio_core/codec.h b/src/audio_core/codec.h
index ef2ce01a8..9507abb1b 100644
--- a/src/audio_core/codec.h
+++ b/src/audio_core/codec.h
@@ -38,7 +38,7 @@ using ADPCM_Coeff = std::array<s16, 16>;
38 * @param state ADPCM state, this is updated with new state 38 * @param state ADPCM state, this is updated with new state
39 * @return Decoded stereo signed PCM16 data, sample_count in length 39 * @return Decoded stereo signed PCM16 data, sample_count in length
40 */ 40 */
41std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff, 41std::vector<s16> DecodeADPCM(const u8* data, std::size_t size, const ADPCM_Coeff& coeff,
42 ADPCMState& state); 42 ADPCMState& state);
43 43
44}; // namespace AudioCore::Codec 44}; // namespace AudioCore::Codec
diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp
index 7f2597257..bba40d13d 100644
--- a/src/audio_core/command_generator.cpp
+++ b/src/audio_core/command_generator.cpp
@@ -727,8 +727,9 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
727 return 0; 727 return 0;
728 } 728 }
729 729
730 constexpr std::array<int, 16> SIGNED_NIBBLES = { 730 static constexpr std::array<int, 16> SIGNED_NIBBLES{
731 {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; 731 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1,
732 };
732 733
733 constexpr std::size_t FRAME_LEN = 8; 734 constexpr std::size_t FRAME_LEN = 8;
734 constexpr std::size_t NIBBLES_PER_SAMPLE = 16; 735 constexpr std::size_t NIBBLES_PER_SAMPLE = 16;
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp
index 83c06c0ed..eb82791f6 100644
--- a/src/audio_core/cubeb_sink.cpp
+++ b/src/audio_core/cubeb_sink.cpp
@@ -192,8 +192,8 @@ SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels,
192 192
193long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, 193long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
194 void* output_buffer, long num_frames) { 194 void* output_buffer, long num_frames) {
195 CubebSinkStream* impl = static_cast<CubebSinkStream*>(user_data); 195 auto* impl = static_cast<CubebSinkStream*>(user_data);
196 u8* buffer = reinterpret_cast<u8*>(output_buffer); 196 auto* buffer = static_cast<u8*>(output_buffer);
197 197
198 if (!impl) { 198 if (!impl) {
199 return {}; 199 return {};
diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp
index 3afbdb898..7a20e95b7 100644
--- a/src/common/wall_clock.cpp
+++ b/src/common/wall_clock.cpp
@@ -15,7 +15,7 @@ namespace Common {
15using base_timer = std::chrono::steady_clock; 15using base_timer = std::chrono::steady_clock;
16using base_time_point = std::chrono::time_point<base_timer>; 16using base_time_point = std::chrono::time_point<base_timer>;
17 17
18class StandardWallClock : public WallClock { 18class StandardWallClock final : public WallClock {
19public: 19public:
20 StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency) 20 StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency)
21 : WallClock(emulated_cpu_frequency, emulated_clock_frequency, false) { 21 : WallClock(emulated_cpu_frequency, emulated_clock_frequency, false) {
diff --git a/src/common/wall_clock.h b/src/common/wall_clock.h
index 5db30083d..bc7adfbf8 100644
--- a/src/common/wall_clock.h
+++ b/src/common/wall_clock.h
@@ -13,6 +13,8 @@ namespace Common {
13 13
14class WallClock { 14class WallClock {
15public: 15public:
16 virtual ~WallClock() = default;
17
16 /// Returns current wall time in nanoseconds 18 /// Returns current wall time in nanoseconds
17 [[nodiscard]] virtual std::chrono::nanoseconds GetTimeNS() = 0; 19 [[nodiscard]] virtual std::chrono::nanoseconds GetTimeNS() = 0;
18 20
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h
index 891a3bbfd..7c503df26 100644
--- a/src/common/x64/native_clock.h
+++ b/src/common/x64/native_clock.h
@@ -12,7 +12,7 @@
12namespace Common { 12namespace Common {
13 13
14namespace X64 { 14namespace X64 {
15class NativeClock : public WallClock { 15class NativeClock final : public WallClock {
16public: 16public:
17 NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, u64 rtsc_frequency); 17 NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, u64 rtsc_frequency);
18 18
diff --git a/src/core/core.h b/src/core/core.h
index 83ded63a5..27efe30bb 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -120,7 +120,7 @@ public:
120 * Gets the instance of the System singleton class. 120 * Gets the instance of the System singleton class.
121 * @returns Reference to the instance of the System singleton class. 121 * @returns Reference to the instance of the System singleton class.
122 */ 122 */
123 static System& GetInstance() { 123 [[deprecated("Use of the global system instance is deprecated")]] static System& GetInstance() {
124 return s_instance; 124 return s_instance;
125 } 125 }
126 126
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp
index 4505da758..c5d65f2d0 100644
--- a/src/core/frontend/applets/controller.cpp
+++ b/src/core/frontend/applets/controller.cpp
@@ -4,7 +4,6 @@
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core.h"
8#include "core/frontend/applets/controller.h" 7#include "core/frontend/applets/controller.h"
9#include "core/hle/service/hid/controllers/npad.h" 8#include "core/hle/service/hid/controllers/npad.h"
10#include "core/hle/service/hid/hid.h" 9#include "core/hle/service/hid/hid.h"
@@ -14,6 +13,9 @@ namespace Core::Frontend {
14 13
15ControllerApplet::~ControllerApplet() = default; 14ControllerApplet::~ControllerApplet() = default;
16 15
16DefaultControllerApplet::DefaultControllerApplet(Service::SM::ServiceManager& service_manager_)
17 : service_manager{service_manager_} {}
18
17DefaultControllerApplet::~DefaultControllerApplet() = default; 19DefaultControllerApplet::~DefaultControllerApplet() = default;
18 20
19void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callback, 21void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callback,
@@ -21,9 +23,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb
21 LOG_INFO(Service_HID, "called, deducing the best configuration based on the given parameters!"); 23 LOG_INFO(Service_HID, "called, deducing the best configuration based on the given parameters!");
22 24
23 auto& npad = 25 auto& npad =
24 Core::System::GetInstance() 26 service_manager.GetService<Service::HID::Hid>("hid")
25 .ServiceManager()
26 .GetService<Service::HID::Hid>("hid")
27 ->GetAppletResource() 27 ->GetAppletResource()
28 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad); 28 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad);
29 29
diff --git a/src/core/frontend/applets/controller.h b/src/core/frontend/applets/controller.h
index a227f15cd..3e49cdbb9 100644
--- a/src/core/frontend/applets/controller.h
+++ b/src/core/frontend/applets/controller.h
@@ -8,6 +8,10 @@
8 8
9#include "common/common_types.h" 9#include "common/common_types.h"
10 10
11namespace Service::SM {
12class ServiceManager;
13}
14
11namespace Core::Frontend { 15namespace Core::Frontend {
12 16
13using BorderColor = std::array<u8, 4>; 17using BorderColor = std::array<u8, 4>;
@@ -39,10 +43,14 @@ public:
39 43
40class DefaultControllerApplet final : public ControllerApplet { 44class DefaultControllerApplet final : public ControllerApplet {
41public: 45public:
46 explicit DefaultControllerApplet(Service::SM::ServiceManager& service_manager_);
42 ~DefaultControllerApplet() override; 47 ~DefaultControllerApplet() override;
43 48
44 void ReconfigureControllers(std::function<void()> callback, 49 void ReconfigureControllers(std::function<void()> callback,
45 ControllerParameters parameters) const override; 50 ControllerParameters parameters) const override;
51
52private:
53 Service::SM::ServiceManager& service_manager;
46}; 54};
47 55
48} // namespace Core::Frontend 56} // namespace Core::Frontend
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index 4e0800f9a..2b626bb40 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -206,7 +206,8 @@ void AppletManager::SetDefaultAppletFrontendSet() {
206 206
207void AppletManager::SetDefaultAppletsIfMissing() { 207void AppletManager::SetDefaultAppletsIfMissing() {
208 if (frontend.controller == nullptr) { 208 if (frontend.controller == nullptr) {
209 frontend.controller = std::make_unique<Core::Frontend::DefaultControllerApplet>(); 209 frontend.controller =
210 std::make_unique<Core::Frontend::DefaultControllerApplet>(system.ServiceManager());
210 } 211 }
211 212
212 if (frontend.e_commerce == nullptr) { 213 if (frontend.e_commerce == nullptr) {
diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h
index 8bc69c372..f47a9e61c 100644
--- a/src/core/hle/service/hid/controllers/controller_base.h
+++ b/src/core/hle/service/hid/controllers/controller_base.h
@@ -31,6 +31,10 @@ public:
31 virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 31 virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
32 std::size_t size) = 0; 32 std::size_t size) = 0;
33 33
34 // When the controller is requesting a motion update for the shared memory
35 virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
36 std::size_t size) {}
37
34 // Called when input devices should be loaded 38 // Called when input devices should be loaded
35 virtual void OnLoadInputDevices() = 0; 39 virtual void OnLoadInputDevices() = 0;
36 40
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 83c3beab6..fb007767d 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -365,6 +365,135 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
365 } 365 }
366 const u32 npad_index = static_cast<u32>(i); 366 const u32 npad_index = static_cast<u32>(i);
367 367
368 RequestPadStateUpdate(npad_index);
369 auto& pad_state = npad_pad_states[npad_index];
370
371 auto& main_controller =
372 npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index];
373 auto& handheld_entry =
374 npad.handheld_states.npad[npad.handheld_states.common.last_entry_index];
375 auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index];
376 auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index];
377 auto& right_entry =
378 npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index];
379 auto& pokeball_entry =
380 npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index];
381 auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index];
382
383 libnx_entry.connection_status.raw = 0;
384 libnx_entry.connection_status.IsConnected.Assign(1);
385 auto& full_sixaxis_entry =
386 npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index];
387 auto& handheld_sixaxis_entry =
388 npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index];
389 auto& dual_left_sixaxis_entry =
390 npad.sixaxis_dual_left.sixaxis[npad.sixaxis_dual_left.common.last_entry_index];
391 auto& dual_right_sixaxis_entry =
392 npad.sixaxis_dual_right.sixaxis[npad.sixaxis_dual_right.common.last_entry_index];
393 auto& left_sixaxis_entry =
394 npad.sixaxis_left.sixaxis[npad.sixaxis_left.common.last_entry_index];
395 auto& right_sixaxis_entry =
396 npad.sixaxis_right.sixaxis[npad.sixaxis_right.common.last_entry_index];
397
398 switch (controller_type) {
399 case NPadControllerType::None:
400 UNREACHABLE();
401 break;
402 case NPadControllerType::ProController:
403 main_controller.connection_status.raw = 0;
404 main_controller.connection_status.IsConnected.Assign(1);
405 main_controller.connection_status.IsWired.Assign(1);
406 main_controller.pad.pad_states.raw = pad_state.pad_states.raw;
407 main_controller.pad.l_stick = pad_state.l_stick;
408 main_controller.pad.r_stick = pad_state.r_stick;
409
410 libnx_entry.connection_status.IsWired.Assign(1);
411 break;
412 case NPadControllerType::Handheld:
413 handheld_entry.connection_status.raw = 0;
414 handheld_entry.connection_status.IsConnected.Assign(1);
415 handheld_entry.connection_status.IsWired.Assign(1);
416 handheld_entry.connection_status.IsLeftJoyConnected.Assign(1);
417 handheld_entry.connection_status.IsRightJoyConnected.Assign(1);
418 handheld_entry.connection_status.IsLeftJoyWired.Assign(1);
419 handheld_entry.connection_status.IsRightJoyWired.Assign(1);
420 handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw;
421 handheld_entry.pad.l_stick = pad_state.l_stick;
422 handheld_entry.pad.r_stick = pad_state.r_stick;
423
424 libnx_entry.connection_status.IsWired.Assign(1);
425 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
426 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
427 libnx_entry.connection_status.IsLeftJoyWired.Assign(1);
428 libnx_entry.connection_status.IsRightJoyWired.Assign(1);
429 break;
430 case NPadControllerType::JoyDual:
431 dual_entry.connection_status.raw = 0;
432 dual_entry.connection_status.IsConnected.Assign(1);
433 dual_entry.connection_status.IsLeftJoyConnected.Assign(1);
434 dual_entry.connection_status.IsRightJoyConnected.Assign(1);
435 dual_entry.pad.pad_states.raw = pad_state.pad_states.raw;
436 dual_entry.pad.l_stick = pad_state.l_stick;
437 dual_entry.pad.r_stick = pad_state.r_stick;
438
439 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
440 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
441 break;
442 case NPadControllerType::JoyLeft:
443 left_entry.connection_status.raw = 0;
444 left_entry.connection_status.IsConnected.Assign(1);
445 left_entry.connection_status.IsLeftJoyConnected.Assign(1);
446 left_entry.pad.pad_states.raw = pad_state.pad_states.raw;
447 left_entry.pad.l_stick = pad_state.l_stick;
448 left_entry.pad.r_stick = pad_state.r_stick;
449
450 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
451 break;
452 case NPadControllerType::JoyRight:
453 right_entry.connection_status.raw = 0;
454 right_entry.connection_status.IsConnected.Assign(1);
455 right_entry.connection_status.IsRightJoyConnected.Assign(1);
456 right_entry.pad.pad_states.raw = pad_state.pad_states.raw;
457 right_entry.pad.l_stick = pad_state.l_stick;
458 right_entry.pad.r_stick = pad_state.r_stick;
459
460 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
461 break;
462 case NPadControllerType::Pokeball:
463 pokeball_entry.connection_status.raw = 0;
464 pokeball_entry.connection_status.IsConnected.Assign(1);
465 pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw;
466 pokeball_entry.pad.l_stick = pad_state.l_stick;
467 pokeball_entry.pad.r_stick = pad_state.r_stick;
468 break;
469 }
470
471 // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate
472 // any controllers.
473 libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw;
474 libnx_entry.pad.l_stick = pad_state.l_stick;
475 libnx_entry.pad.r_stick = pad_state.r_stick;
476
477 press_state |= static_cast<u32>(pad_state.pad_states.raw);
478 }
479 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
480 shared_memory_entries.size() * sizeof(NPadEntry));
481}
482
483void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
484 std::size_t data_len) {
485 if (!IsControllerActivated()) {
486 return;
487 }
488 for (std::size_t i = 0; i < shared_memory_entries.size(); i++) {
489 auto& npad = shared_memory_entries[i];
490
491 const auto& controller_type = connected_controllers[i].type;
492
493 if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) {
494 continue;
495 }
496
368 const std::array<SixAxisGeneric*, 6> controller_sixaxes{ 497 const std::array<SixAxisGeneric*, 6> controller_sixaxes{
369 &npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left, 498 &npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left,
370 &npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right, 499 &npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right,
@@ -403,9 +532,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
403 } 532 }
404 } 533 }
405 534
406 RequestPadStateUpdate(npad_index);
407 auto& pad_state = npad_pad_states[npad_index];
408
409 auto& main_controller = 535 auto& main_controller =
410 npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; 536 npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index];
411 auto& handheld_entry = 537 auto& handheld_entry =
@@ -418,8 +544,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
418 npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index]; 544 npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index];
419 auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; 545 auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index];
420 546
421 libnx_entry.connection_status.raw = 0;
422 libnx_entry.connection_status.IsConnected.Assign(1);
423 auto& full_sixaxis_entry = 547 auto& full_sixaxis_entry =
424 npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index]; 548 npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index];
425 auto& handheld_sixaxis_entry = 549 auto& handheld_sixaxis_entry =
@@ -438,15 +562,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
438 UNREACHABLE(); 562 UNREACHABLE();
439 break; 563 break;
440 case NPadControllerType::ProController: 564 case NPadControllerType::ProController:
441 main_controller.connection_status.raw = 0;
442 main_controller.connection_status.IsConnected.Assign(1);
443 main_controller.connection_status.IsWired.Assign(1);
444 main_controller.pad.pad_states.raw = pad_state.pad_states.raw;
445 main_controller.pad.l_stick = pad_state.l_stick;
446 main_controller.pad.r_stick = pad_state.r_stick;
447
448 libnx_entry.connection_status.IsWired.Assign(1);
449
450 if (sixaxis_sensors_enabled && motions[i][0]) { 565 if (sixaxis_sensors_enabled && motions[i][0]) {
451 full_sixaxis_entry.accel = motion_devices[0].accel; 566 full_sixaxis_entry.accel = motion_devices[0].accel;
452 full_sixaxis_entry.gyro = motion_devices[0].gyro; 567 full_sixaxis_entry.gyro = motion_devices[0].gyro;
@@ -455,23 +570,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
455 } 570 }
456 break; 571 break;
457 case NPadControllerType::Handheld: 572 case NPadControllerType::Handheld:
458 handheld_entry.connection_status.raw = 0;
459 handheld_entry.connection_status.IsConnected.Assign(1);
460 handheld_entry.connection_status.IsWired.Assign(1);
461 handheld_entry.connection_status.IsLeftJoyConnected.Assign(1);
462 handheld_entry.connection_status.IsRightJoyConnected.Assign(1);
463 handheld_entry.connection_status.IsLeftJoyWired.Assign(1);
464 handheld_entry.connection_status.IsRightJoyWired.Assign(1);
465 handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw;
466 handheld_entry.pad.l_stick = pad_state.l_stick;
467 handheld_entry.pad.r_stick = pad_state.r_stick;
468
469 libnx_entry.connection_status.IsWired.Assign(1);
470 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
471 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
472 libnx_entry.connection_status.IsLeftJoyWired.Assign(1);
473 libnx_entry.connection_status.IsRightJoyWired.Assign(1);
474
475 if (sixaxis_sensors_enabled && motions[i][0]) { 573 if (sixaxis_sensors_enabled && motions[i][0]) {
476 handheld_sixaxis_entry.accel = motion_devices[0].accel; 574 handheld_sixaxis_entry.accel = motion_devices[0].accel;
477 handheld_sixaxis_entry.gyro = motion_devices[0].gyro; 575 handheld_sixaxis_entry.gyro = motion_devices[0].gyro;
@@ -480,17 +578,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
480 } 578 }
481 break; 579 break;
482 case NPadControllerType::JoyDual: 580 case NPadControllerType::JoyDual:
483 dual_entry.connection_status.raw = 0;
484 dual_entry.connection_status.IsConnected.Assign(1);
485 dual_entry.connection_status.IsLeftJoyConnected.Assign(1);
486 dual_entry.connection_status.IsRightJoyConnected.Assign(1);
487 dual_entry.pad.pad_states.raw = pad_state.pad_states.raw;
488 dual_entry.pad.l_stick = pad_state.l_stick;
489 dual_entry.pad.r_stick = pad_state.r_stick;
490
491 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
492 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
493
494 if (sixaxis_sensors_enabled && motions[i][0]) { 581 if (sixaxis_sensors_enabled && motions[i][0]) {
495 // Set motion for the left joycon 582 // Set motion for the left joycon
496 dual_left_sixaxis_entry.accel = motion_devices[0].accel; 583 dual_left_sixaxis_entry.accel = motion_devices[0].accel;
@@ -507,15 +594,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
507 } 594 }
508 break; 595 break;
509 case NPadControllerType::JoyLeft: 596 case NPadControllerType::JoyLeft:
510 left_entry.connection_status.raw = 0;
511 left_entry.connection_status.IsConnected.Assign(1);
512 left_entry.connection_status.IsLeftJoyConnected.Assign(1);
513 left_entry.pad.pad_states.raw = pad_state.pad_states.raw;
514 left_entry.pad.l_stick = pad_state.l_stick;
515 left_entry.pad.r_stick = pad_state.r_stick;
516
517 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
518
519 if (sixaxis_sensors_enabled && motions[i][0]) { 597 if (sixaxis_sensors_enabled && motions[i][0]) {
520 left_sixaxis_entry.accel = motion_devices[0].accel; 598 left_sixaxis_entry.accel = motion_devices[0].accel;
521 left_sixaxis_entry.gyro = motion_devices[0].gyro; 599 left_sixaxis_entry.gyro = motion_devices[0].gyro;
@@ -524,15 +602,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
524 } 602 }
525 break; 603 break;
526 case NPadControllerType::JoyRight: 604 case NPadControllerType::JoyRight:
527 right_entry.connection_status.raw = 0;
528 right_entry.connection_status.IsConnected.Assign(1);
529 right_entry.connection_status.IsRightJoyConnected.Assign(1);
530 right_entry.pad.pad_states.raw = pad_state.pad_states.raw;
531 right_entry.pad.l_stick = pad_state.l_stick;
532 right_entry.pad.r_stick = pad_state.r_stick;
533
534 libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
535
536 if (sixaxis_sensors_enabled && motions[i][1]) { 605 if (sixaxis_sensors_enabled && motions[i][1]) {
537 right_sixaxis_entry.accel = motion_devices[1].accel; 606 right_sixaxis_entry.accel = motion_devices[1].accel;
538 right_sixaxis_entry.gyro = motion_devices[1].gyro; 607 right_sixaxis_entry.gyro = motion_devices[1].gyro;
@@ -541,21 +610,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
541 } 610 }
542 break; 611 break;
543 case NPadControllerType::Pokeball: 612 case NPadControllerType::Pokeball:
544 pokeball_entry.connection_status.raw = 0;
545 pokeball_entry.connection_status.IsConnected.Assign(1);
546 pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw;
547 pokeball_entry.pad.l_stick = pad_state.l_stick;
548 pokeball_entry.pad.r_stick = pad_state.r_stick;
549 break; 613 break;
550 } 614 }
551
552 // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate
553 // any controllers.
554 libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw;
555 libnx_entry.pad.l_stick = pad_state.l_stick;
556 libnx_entry.pad.r_stick = pad_state.r_stick;
557
558 press_state |= static_cast<u32>(pad_state.pad_states.raw);
559 } 615 }
560 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), 616 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
561 shared_memory_entries.size() * sizeof(NPadEntry)); 617 shared_memory_entries.size() * sizeof(NPadEntry));
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 0cff6821f..e65277c7b 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -32,6 +32,10 @@ public:
32 // When the controller is requesting an update for the shared memory 32 // When the controller is requesting an update for the shared memory
33 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; 33 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
34 34
35 // When the controller is requesting a motion update for the shared memory
36 void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
37 std::size_t size) override;
38
35 // Called when input devices should be loaded 39 // Called when input devices should be loaded
36 void OnLoadInputDevices() override; 40 void OnLoadInputDevices() override;
37 41
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index dc198791d..90a71ab1c 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -40,7 +40,8 @@ namespace Service::HID {
40// Updating period for each HID device. 40// Updating period for each HID device.
41// HID is polled every 15ms, this value was derived from 41// HID is polled every 15ms, this value was derived from
42// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet 42// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet
43constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz) 43constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz)
44constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz)
44constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; 45constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
45 46
46IAppletResource::IAppletResource(Core::System& system) 47IAppletResource::IAppletResource(Core::System& system)
@@ -79,10 +80,14 @@ IAppletResource::IAppletResource(Core::System& system)
79 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 80 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
80 UpdateControllers(user_data, ns_late); 81 UpdateControllers(user_data, ns_late);
81 }); 82 });
82 83 motion_update_event = Core::Timing::CreateEvent(
83 // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) 84 "HID::MotionPadCallback",
85 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
86 UpdateMotion(user_data, ns_late);
87 });
84 88
85 system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event); 89 system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event);
90 system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event);
86 91
87 ReloadInputDevices(); 92 ReloadInputDevices();
88} 93}
@@ -122,6 +127,16 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
122 core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event); 127 core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event);
123} 128}
124 129
130void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
131 auto& core_timing = system.CoreTiming();
132
133 for (const auto& controller : controllers) {
134 controller->OnMotionUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
135 }
136
137 core_timing.ScheduleEvent(motion_update_ns - ns_late, motion_update_event);
138}
139
125class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { 140class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
126public: 141public:
127 IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") { 142 IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index e04aaf1e9..3cfd72a51 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -65,10 +65,12 @@ private:
65 65
66 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); 66 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
67 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 67 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
68 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
68 69
69 std::shared_ptr<Kernel::SharedMemory> shared_mem; 70 std::shared_ptr<Kernel::SharedMemory> shared_mem;
70 71
71 std::shared_ptr<Core::Timing::EventType> pad_update_event; 72 std::shared_ptr<Core::Timing::EventType> pad_update_event;
73 std::shared_ptr<Core::Timing::EventType> motion_update_event;
72 Core::System& system; 74 Core::System& system;
73 75
74 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)> 76 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index bdae8b887..fcb612864 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -22,6 +22,18 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
22 switch (static_cast<IoctlCommand>(command.raw)) { 22 switch (static_cast<IoctlCommand>(command.raw)) {
23 case IoctlCommand::IocSetNVMAPfdCommand: 23 case IoctlCommand::IocSetNVMAPfdCommand:
24 return SetNVMAPfd(input, output); 24 return SetNVMAPfd(input, output);
25 case IoctlCommand::IocSubmit:
26 return Submit(input, output);
27 case IoctlCommand::IocGetSyncpoint:
28 return GetSyncpoint(input, output);
29 case IoctlCommand::IocGetWaitbase:
30 return GetWaitbase(input, output);
31 case IoctlCommand::IocMapBuffer:
32 return MapBuffer(input, output);
33 case IoctlCommand::IocMapBufferEx:
34 return MapBufferEx(input, output);
35 case IoctlCommand::IocUnmapBufferEx:
36 return UnmapBufferEx(input, output);
25 } 37 }
26 38
27 UNIMPLEMENTED_MSG("Unimplemented ioctl"); 39 UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -30,11 +42,67 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
30 42
31u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { 43u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
32 IoctlSetNvmapFD params{}; 44 IoctlSetNvmapFD params{};
33 std::memcpy(&params, input.data(), input.size()); 45 std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
34 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); 46 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
35 47
36 nvmap_fd = params.nvmap_fd; 48 nvmap_fd = params.nvmap_fd;
37 return 0; 49 return 0;
38} 50}
39 51
52u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
53 IoctlSubmit params{};
54 std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
55 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
56 std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
57 return 0;
58}
59
60u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
61 IoctlGetSyncpoint params{};
62 std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
63 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
64 params.value = 0; // Seems to be hard coded at 0
65 std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
66 return 0;
67}
68
69u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
70 IoctlGetWaitbase params{};
71 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
72 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
73 params.value = 0; // Seems to be hard coded at 0
74 std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
75 return 0;
76}
77
78u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
79 IoctlMapBuffer params{};
80 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
81 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
82 params.address_1);
83 params.address_1 = 0;
84 params.address_2 = 0;
85 std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
86 return 0;
87}
88
89u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
90 IoctlMapBufferEx params{};
91 std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
92 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
93 params.address_1);
94 params.address_1 = 0;
95 params.address_2 = 0;
96 std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
97 return 0;
98}
99
100u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
101 IoctlUnmapBufferEx params{};
102 std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
103 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
104 std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
105 return 0;
106}
107
40} // namespace Service::Nvidia::Devices 108} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index cbdac8069..4332db118 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -23,16 +23,66 @@ public:
23private: 23private:
24 enum class IoctlCommand : u32_le { 24 enum class IoctlCommand : u32_le {
25 IocSetNVMAPfdCommand = 0x40044801, 25 IocSetNVMAPfdCommand = 0x40044801,
26 IocSubmit = 0xC0400001,
27 IocGetSyncpoint = 0xC0080002,
28 IocGetWaitbase = 0xC0080003,
29 IocMapBuffer = 0xC01C0009,
30 IocMapBufferEx = 0xC0A40009,
31 IocUnmapBufferEx = 0xC0A4000A,
26 }; 32 };
27 33
28 struct IoctlSetNvmapFD { 34 struct IoctlSetNvmapFD {
29 u32_le nvmap_fd; 35 u32_le nvmap_fd;
30 }; 36 };
31 static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); 37 static_assert(sizeof(IoctlSetNvmapFD) == 0x4, "IoctlSetNvmapFD is incorrect size");
38
39 struct IoctlSubmit {
40 INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure
41 };
42 static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit has incorrect size");
43
44 struct IoctlGetSyncpoint {
45 u32 unknown; // seems to be ignored? Nintendo added this
46 u32 value;
47 };
48 static_assert(sizeof(IoctlGetSyncpoint) == 0x08, "IoctlGetSyncpoint has incorrect size");
49
50 struct IoctlGetWaitbase {
51 u32 unknown; // seems to be ignored? Nintendo added this
52 u32 value;
53 };
54 static_assert(sizeof(IoctlGetWaitbase) == 0x08, "IoctlGetWaitbase has incorrect size");
55
56 struct IoctlMapBuffer {
57 u32 unknown;
58 u32 address_1;
59 u32 address_2;
60 INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
61 };
62 static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
63
64 struct IoctlMapBufferEx {
65 u32 unknown;
66 u32 address_1;
67 u32 address_2;
68 INSERT_PADDING_BYTES(0x98); // TODO(DarkLordZach): RE this structure
69 };
70 static_assert(sizeof(IoctlMapBufferEx) == 0xA4, "IoctlMapBufferEx has incorrect size");
71
72 struct IoctlUnmapBufferEx {
73 INSERT_PADDING_BYTES(0xA4); // TODO(DarkLordZach): RE this structure
74 };
75 static_assert(sizeof(IoctlUnmapBufferEx) == 0xA4, "IoctlUnmapBufferEx has incorrect size");
32 76
33 u32_le nvmap_fd{}; 77 u32_le nvmap_fd{};
34 78
35 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); 79 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
80 u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
81 u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
82 u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
83 u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
84 u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
85 u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
36}; 86};
37 87
38} // namespace Service::Nvidia::Devices 88} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index c695b8863..9da19ad56 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -22,6 +22,18 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
22 switch (static_cast<IoctlCommand>(command.raw)) { 22 switch (static_cast<IoctlCommand>(command.raw)) {
23 case IoctlCommand::IocSetNVMAPfdCommand: 23 case IoctlCommand::IocSetNVMAPfdCommand:
24 return SetNVMAPfd(input, output); 24 return SetNVMAPfd(input, output);
25 case IoctlCommand::IocSubmit:
26 return Submit(input, output);
27 case IoctlCommand::IocGetSyncpoint:
28 return GetSyncpoint(input, output);
29 case IoctlCommand::IocGetWaitbase:
30 return GetWaitbase(input, output);
31 case IoctlCommand::IocMapBuffer:
32 return MapBuffer(input, output);
33 case IoctlCommand::IocMapBufferEx:
34 return MapBuffer(input, output);
35 case IoctlCommand::IocUnmapBufferEx:
36 return UnmapBufferEx(input, output);
25 } 37 }
26 38
27 UNIMPLEMENTED_MSG("Unimplemented ioctl"); 39 UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -30,11 +42,71 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
30 42
31u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { 43u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
32 IoctlSetNvmapFD params{}; 44 IoctlSetNvmapFD params{};
33 std::memcpy(&params, input.data(), input.size()); 45 std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
34 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); 46 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
35 47
36 nvmap_fd = params.nvmap_fd; 48 nvmap_fd = params.nvmap_fd;
37 return 0; 49 return 0;
38} 50}
39 51
52u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
53 IoctlSubmit params{};
54 std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
55 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
56
57 // Workaround for Luigi's Mansion 3, as nvhost_vic is not implemented for asynch GPU
58 params.command_buffer = {};
59
60 std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
61 return 0;
62}
63
64u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
65 IoctlGetSyncpoint params{};
66 std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
67 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
68 params.value = 0; // Seems to be hard coded at 0
69 std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
70 return 0;
71}
72
73u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
74 IoctlGetWaitbase params{};
75 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
76 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
77 params.value = 0; // Seems to be hard coded at 0
78 std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
79 return 0;
80}
81
82u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
83 IoctlMapBuffer params{};
84 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
85 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
86 params.address_1);
87 params.address_1 = 0;
88 params.address_2 = 0;
89 std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
90 return 0;
91}
92
93u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
94 IoctlMapBufferEx params{};
95 std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
96 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
97 params.address_1);
98 params.address_1 = 0;
99 params.address_2 = 0;
100 std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
101 return 0;
102}
103
104u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
105 IoctlUnmapBufferEx params{};
106 std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
107 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
108 std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
109 return 0;
110}
111
40} // namespace Service::Nvidia::Devices 112} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index bec32bea1..a7bb7bbd5 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
7#include <vector> 8#include <vector>
8#include "common/common_types.h" 9#include "common/common_types.h"
9#include "common/swap.h" 10#include "common/swap.h"
@@ -23,6 +24,12 @@ public:
23private: 24private:
24 enum class IoctlCommand : u32_le { 25 enum class IoctlCommand : u32_le {
25 IocSetNVMAPfdCommand = 0x40044801, 26 IocSetNVMAPfdCommand = 0x40044801,
27 IocSubmit = 0xC0400001,
28 IocGetSyncpoint = 0xC0080002,
29 IocGetWaitbase = 0xC0080003,
30 IocMapBuffer = 0xC01C0009,
31 IocMapBufferEx = 0xC03C0009,
32 IocUnmapBufferEx = 0xC03C000A,
26 }; 33 };
27 34
28 struct IoctlSetNvmapFD { 35 struct IoctlSetNvmapFD {
@@ -30,9 +37,65 @@ private:
30 }; 37 };
31 static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); 38 static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
32 39
40 struct IoctlSubmitCommandBuffer {
41 u32 id;
42 u32 offset;
43 u32 count;
44 };
45 static_assert(sizeof(IoctlSubmitCommandBuffer) == 0xC,
46 "IoctlSubmitCommandBuffer is incorrect size");
47
48 struct IoctlSubmit {
49 u32 command_buffer_count;
50 u32 relocations_count;
51 u32 syncpt_count;
52 u32 wait_count;
53 std::array<IoctlSubmitCommandBuffer, 4> command_buffer;
54 };
55 static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit is incorrect size");
56
57 struct IoctlGetSyncpoint {
58 u32 unknown; // seems to be ignored? Nintendo added this
59 u32 value;
60 };
61 static_assert(sizeof(IoctlGetSyncpoint) == 0x8, "IoctlGetSyncpoint is incorrect size");
62
63 struct IoctlGetWaitbase {
64 u32 unknown; // seems to be ignored? Nintendo added this
65 u32 value;
66 };
67 static_assert(sizeof(IoctlGetWaitbase) == 0x8, "IoctlGetWaitbase is incorrect size");
68
69 struct IoctlMapBuffer {
70 u32 unknown;
71 u32 address_1;
72 u32 address_2;
73 INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
74 };
75 static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
76
77 struct IoctlMapBufferEx {
78 u32 unknown;
79 u32 address_1;
80 u32 address_2;
81 INSERT_PADDING_BYTES(0x30); // TODO(DarkLordZach): RE this structure
82 };
83 static_assert(sizeof(IoctlMapBufferEx) == 0x3C, "IoctlMapBufferEx is incorrect size");
84
85 struct IoctlUnmapBufferEx {
86 INSERT_PADDING_BYTES(0x3C); // TODO(DarkLordZach): RE this structure
87 };
88 static_assert(sizeof(IoctlUnmapBufferEx) == 0x3C, "IoctlUnmapBufferEx is incorrect size");
89
33 u32_le nvmap_fd{}; 90 u32_le nvmap_fd{};
34 91
35 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); 92 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
93 u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
94 u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
95 u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
96 u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
97 u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
98 u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
36}; 99};
37 100
38} // namespace Service::Nvidia::Devices 101} // namespace Service::Nvidia::Devices
diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp
index 05e31f1de..3d8d3213d 100644
--- a/src/video_core/renderer_vulkan/vk_device.cpp
+++ b/src/video_core/renderer_vulkan/vk_device.cpp
@@ -388,14 +388,6 @@ bool VKDevice::Create() {
388 388
389 CollectTelemetryParameters(); 389 CollectTelemetryParameters();
390 390
391 if (ext_extended_dynamic_state && driver_id == VK_DRIVER_ID_AMD_PROPRIETARY_KHR) {
392 // AMD's proprietary driver supports VK_EXT_extended_dynamic_state but the <stride> field
393 // seems to be bugged. Blacklisting it for now.
394 LOG_WARNING(Render_Vulkan,
395 "Blacklisting AMD proprietary from VK_EXT_extended_dynamic_state");
396 ext_extended_dynamic_state = false;
397 }
398
399 graphics_queue = logical.GetQueue(graphics_family); 391 graphics_queue = logical.GetQueue(graphics_family);
400 present_queue = logical.GetQueue(present_family); 392 present_queue = logical.GetQueue(present_family);
401 393
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index a9738e298..70d865112 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -25,7 +25,8 @@
25#include "yuzu/main.h" 25#include "yuzu/main.h"
26#include "yuzu/uisettings.h" 26#include "yuzu/uisettings.h"
27 27
28GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist) : gamelist{gamelist} {} 28GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist, QObject* parent)
29 : QObject(parent), gamelist{gamelist} {}
29 30
30// EventFilter in order to process systemkeys while editing the searchfield 31// EventFilter in order to process systemkeys while editing the searchfield
31bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { 32bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) {
@@ -116,7 +117,7 @@ void GameListSearchField::setFocus() {
116} 117}
117 118
118GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { 119GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
119 auto* const key_release_eater = new KeyReleaseEater(parent); 120 auto* const key_release_eater = new KeyReleaseEater(parent, this);
120 layout_filter = new QHBoxLayout; 121 layout_filter = new QHBoxLayout;
121 layout_filter->setMargin(8); 122 layout_filter->setMargin(8);
122 label_filter = new QLabel; 123 label_filter = new QLabel;
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index 92779a9c7..248855aff 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -330,7 +330,7 @@ public:
330private: 330private:
331 class KeyReleaseEater : public QObject { 331 class KeyReleaseEater : public QObject {
332 public: 332 public:
333 explicit KeyReleaseEater(GameList* gamelist); 333 explicit KeyReleaseEater(GameList* gamelist, QObject* parent = nullptr);
334 334
335 private: 335 private:
336 GameList* gamelist = nullptr; 336 GameList* gamelist = nullptr;
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 6a2a88dd8..e3de0f0e1 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -288,8 +288,8 @@ GMainWindow::~GMainWindow() {
288void GMainWindow::ControllerSelectorReconfigureControllers( 288void GMainWindow::ControllerSelectorReconfigureControllers(
289 const Core::Frontend::ControllerParameters& parameters) { 289 const Core::Frontend::ControllerParameters& parameters) {
290 QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get()); 290 QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get());
291 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | 291 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
292 Qt::WindowSystemMenuHint); 292 Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
293 dialog.setWindowModality(Qt::WindowModal); 293 dialog.setWindowModality(Qt::WindowModal);
294 dialog.exec(); 294 dialog.exec();
295 295
@@ -307,8 +307,9 @@ void GMainWindow::ProfileSelectorSelectProfile() {
307 int index = 0; 307 int index = 0;
308 if (manager.GetUserCount() != 1) { 308 if (manager.GetUserCount() != 1) {
309 QtProfileSelectionDialog dialog(this); 309 QtProfileSelectionDialog dialog(this);
310 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | 310 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
311 Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); 311 Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
312 Qt::WindowCloseButtonHint);
312 dialog.setWindowModality(Qt::WindowModal); 313 dialog.setWindowModality(Qt::WindowModal);
313 314
314 if (dialog.exec() == QDialog::Rejected) { 315 if (dialog.exec() == QDialog::Rejected) {
@@ -331,8 +332,9 @@ void GMainWindow::ProfileSelectorSelectProfile() {
331void GMainWindow::SoftwareKeyboardGetText( 332void GMainWindow::SoftwareKeyboardGetText(
332 const Core::Frontend::SoftwareKeyboardParameters& parameters) { 333 const Core::Frontend::SoftwareKeyboardParameters& parameters) {
333 QtSoftwareKeyboardDialog dialog(this, parameters); 334 QtSoftwareKeyboardDialog dialog(this, parameters);
334 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | 335 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
335 Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); 336 Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
337 Qt::WindowCloseButtonHint);
336 dialog.setWindowModality(Qt::WindowModal); 338 dialog.setWindowModality(Qt::WindowModal);
337 339
338 if (dialog.exec() == QDialog::Rejected) { 340 if (dialog.exec() == QDialog::Rejected) {