diff options
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 | */ |
| 41 | std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff, | 41 | std::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 | ||
| 193 | long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, | 193 | long 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 { | |||
| 15 | using base_timer = std::chrono::steady_clock; | 15 | using base_timer = std::chrono::steady_clock; |
| 16 | using base_time_point = std::chrono::time_point<base_timer>; | 16 | using base_time_point = std::chrono::time_point<base_timer>; |
| 17 | 17 | ||
| 18 | class StandardWallClock : public WallClock { | 18 | class StandardWallClock final : public WallClock { |
| 19 | public: | 19 | public: |
| 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 | ||
| 14 | class WallClock { | 14 | class WallClock { |
| 15 | public: | 15 | public: |
| 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 @@ | |||
| 12 | namespace Common { | 12 | namespace Common { |
| 13 | 13 | ||
| 14 | namespace X64 { | 14 | namespace X64 { |
| 15 | class NativeClock : public WallClock { | 15 | class NativeClock final : public WallClock { |
| 16 | public: | 16 | public: |
| 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 | ||
| 15 | ControllerApplet::~ControllerApplet() = default; | 14 | ControllerApplet::~ControllerApplet() = default; |
| 16 | 15 | ||
| 16 | DefaultControllerApplet::DefaultControllerApplet(Service::SM::ServiceManager& service_manager_) | ||
| 17 | : service_manager{service_manager_} {} | ||
| 18 | |||
| 17 | DefaultControllerApplet::~DefaultControllerApplet() = default; | 19 | DefaultControllerApplet::~DefaultControllerApplet() = default; |
| 18 | 20 | ||
| 19 | void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callback, | 21 | void 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 | ||
| 11 | namespace Service::SM { | ||
| 12 | class ServiceManager; | ||
| 13 | } | ||
| 14 | |||
| 11 | namespace Core::Frontend { | 15 | namespace Core::Frontend { |
| 12 | 16 | ||
| 13 | using BorderColor = std::array<u8, 4>; | 17 | using BorderColor = std::array<u8, 4>; |
| @@ -39,10 +43,14 @@ public: | |||
| 39 | 43 | ||
| 40 | class DefaultControllerApplet final : public ControllerApplet { | 44 | class DefaultControllerApplet final : public ControllerApplet { |
| 41 | public: | 45 | public: |
| 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 | |||
| 52 | private: | ||
| 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 | ||
| 207 | void AppletManager::SetDefaultAppletsIfMissing() { | 207 | void 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 | |||
| 483 | void 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 |
| 43 | constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz) | 43 | constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz) |
| 44 | constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz) | ||
| 44 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; | 45 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; |
| 45 | 46 | ||
| 46 | IAppletResource::IAppletResource(Core::System& system) | 47 | IAppletResource::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 | ||
| 130 | void 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 | |||
| 125 | class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { | 140 | class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { |
| 126 | public: | 141 | public: |
| 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 | ||
| 31 | u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { | 43 | u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { |
| 32 | IoctlSetNvmapFD params{}; | 44 | IoctlSetNvmapFD params{}; |
| 33 | std::memcpy(¶ms, input.data(), input.size()); | 45 | std::memcpy(¶ms, 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 | ||
| 52 | u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 53 | IoctlSubmit params{}; | ||
| 54 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); | ||
| 55 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | ||
| 56 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 61 | IoctlGetSyncpoint params{}; | ||
| 62 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetSyncpoint)); | ||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 70 | IoctlGetWaitbase params{}; | ||
| 71 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetWaitbase)); | ||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 79 | IoctlMapBuffer params{}; | ||
| 80 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBuffer)); | ||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 90 | IoctlMapBufferEx params{}; | ||
| 91 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBufferEx)); | ||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 101 | IoctlUnmapBufferEx params{}; | ||
| 102 | std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx)); | ||
| 103 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | ||
| 104 | std::memcpy(output.data(), ¶ms, 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: | |||
| 23 | private: | 23 | private: |
| 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 | ||
| 31 | u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { | 43 | u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { |
| 32 | IoctlSetNvmapFD params{}; | 44 | IoctlSetNvmapFD params{}; |
| 33 | std::memcpy(¶ms, input.data(), input.size()); | 45 | std::memcpy(¶ms, 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 | ||
| 52 | u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 53 | IoctlSubmit params{}; | ||
| 54 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlSubmit)); | ||
| 61 | return 0; | ||
| 62 | } | ||
| 63 | |||
| 64 | u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 65 | IoctlGetSyncpoint params{}; | ||
| 66 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetSyncpoint)); | ||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 74 | IoctlGetWaitbase params{}; | ||
| 75 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetWaitbase)); | ||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 83 | IoctlMapBuffer params{}; | ||
| 84 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBuffer)); | ||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 94 | IoctlMapBufferEx params{}; | ||
| 95 | std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBufferEx)); | ||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 105 | IoctlUnmapBufferEx params{}; | ||
| 106 | std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx)); | ||
| 107 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | ||
| 108 | std::memcpy(output.data(), ¶ms, 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: | |||
| 23 | private: | 24 | private: |
| 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 | ||
| 28 | GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist) : gamelist{gamelist} {} | 28 | GameListSearchField::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 |
| 31 | bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { | 32 | bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { |
| @@ -116,7 +117,7 @@ void GameListSearchField::setFocus() { | |||
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { | 119 | GameListSearchField::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: | |||
| 330 | private: | 330 | private: |
| 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() { | |||
| 288 | void GMainWindow::ControllerSelectorReconfigureControllers( | 288 | void 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() { | |||
| 331 | void GMainWindow::SoftwareKeyboardGetText( | 332 | void 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) { |