diff options
Diffstat (limited to 'src')
32 files changed, 255 insertions, 249 deletions
diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp index 404dcd0e9..6081352a2 100644 --- a/src/audio_core/sink/sink_stream.cpp +++ b/src/audio_core/sink/sink_stream.cpp | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "audio_core/sink/sink_stream.h" | 12 | #include "audio_core/sink/sink_stream.h" |
| 13 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "common/fixed_point.h" | 14 | #include "common/fixed_point.h" |
| 15 | #include "common/scope_exit.h" | ||
| 15 | #include "common/settings.h" | 16 | #include "common/settings.h" |
| 16 | #include "core/core.h" | 17 | #include "core/core.h" |
| 17 | #include "core/core_timing.h" | 18 | #include "core/core_timing.h" |
| @@ -19,9 +20,12 @@ | |||
| 19 | namespace AudioCore::Sink { | 20 | namespace AudioCore::Sink { |
| 20 | 21 | ||
| 21 | void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { | 22 | void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { |
| 22 | if (type == StreamType::In) { | 23 | SCOPE_EXIT({ |
| 23 | queue.enqueue(buffer); | 24 | queue.enqueue(buffer); |
| 24 | queued_buffers++; | 25 | ++queued_buffers; |
| 26 | }); | ||
| 27 | |||
| 28 | if (type == StreamType::In) { | ||
| 25 | return; | 29 | return; |
| 26 | } | 30 | } |
| 27 | 31 | ||
| @@ -66,16 +70,17 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { | |||
| 66 | static_cast<s16>(std::clamp(right_sample, min, max)); | 70 | static_cast<s16>(std::clamp(right_sample, min, max)); |
| 67 | } | 71 | } |
| 68 | 72 | ||
| 69 | samples = samples.subspan(0, samples.size() / system_channels * device_channels); | 73 | samples_buffer.Push(samples.subspan(0, samples.size() / system_channels * device_channels)); |
| 74 | return; | ||
| 75 | } | ||
| 70 | 76 | ||
| 71 | } else if (system_channels == 2 && device_channels == 6) { | 77 | if (system_channels == 2 && device_channels == 6) { |
| 72 | // We need moar samples! Not all games will provide 6 channel audio. | 78 | // We need moar samples! Not all games will provide 6 channel audio. |
| 73 | // TODO: Implement some upmixing here. Currently just passthrough, with other | 79 | // TODO: Implement some upmixing here. Currently just passthrough, with other |
| 74 | // channels left as silence. | 80 | // channels left as silence. |
| 75 | auto new_size = samples.size() / system_channels * device_channels; | 81 | std::vector<s16> new_samples(samples.size() / system_channels * device_channels); |
| 76 | tmp_samples.resize_destructive(new_size); | ||
| 77 | 82 | ||
| 78 | for (u32 read_index = 0, write_index = 0; read_index < new_size; | 83 | for (u32 read_index = 0, write_index = 0; read_index < samples.size(); |
| 79 | read_index += system_channels, write_index += device_channels) { | 84 | read_index += system_channels, write_index += device_channels) { |
| 80 | const auto left_sample{static_cast<s16>(std::clamp( | 85 | const auto left_sample{static_cast<s16>(std::clamp( |
| 81 | static_cast<s32>( | 86 | static_cast<s32>( |
| @@ -83,7 +88,7 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { | |||
| 83 | volume), | 88 | volume), |
| 84 | min, max))}; | 89 | min, max))}; |
| 85 | 90 | ||
| 86 | tmp_samples[write_index + static_cast<u32>(Channels::FrontLeft)] = left_sample; | 91 | new_samples[write_index + static_cast<u32>(Channels::FrontLeft)] = left_sample; |
| 87 | 92 | ||
| 88 | const auto right_sample{static_cast<s16>(std::clamp( | 93 | const auto right_sample{static_cast<s16>(std::clamp( |
| 89 | static_cast<s32>( | 94 | static_cast<s32>( |
| @@ -91,20 +96,21 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { | |||
| 91 | volume), | 96 | volume), |
| 92 | min, max))}; | 97 | min, max))}; |
| 93 | 98 | ||
| 94 | tmp_samples[write_index + static_cast<u32>(Channels::FrontRight)] = right_sample; | 99 | new_samples[write_index + static_cast<u32>(Channels::FrontRight)] = right_sample; |
| 95 | } | 100 | } |
| 96 | samples = std::span<s16>(tmp_samples); | ||
| 97 | 101 | ||
| 98 | } else if (volume != 1.0f) { | 102 | samples_buffer.Push(new_samples); |
| 99 | for (u32 i = 0; i < samples.size(); i++) { | 103 | return; |
| 104 | } | ||
| 105 | |||
| 106 | if (volume != 1.0f) { | ||
| 107 | for (u32 i = 0; i < samples.size(); ++i) { | ||
| 100 | samples[i] = static_cast<s16>( | 108 | samples[i] = static_cast<s16>( |
| 101 | std::clamp(static_cast<s32>(static_cast<f32>(samples[i]) * volume), min, max)); | 109 | std::clamp(static_cast<s32>(static_cast<f32>(samples[i]) * volume), min, max)); |
| 102 | } | 110 | } |
| 103 | } | 111 | } |
| 104 | 112 | ||
| 105 | samples_buffer.Push(samples); | 113 | samples_buffer.Push(samples); |
| 106 | queue.enqueue(buffer); | ||
| 107 | queued_buffers++; | ||
| 108 | } | 114 | } |
| 109 | 115 | ||
| 110 | std::vector<s16> SinkStream::ReleaseBuffer(u64 num_samples) { | 116 | std::vector<s16> SinkStream::ReleaseBuffer(u64 num_samples) { |
diff --git a/src/audio_core/sink/sink_stream.h b/src/audio_core/sink/sink_stream.h index 98d72ace1..6a4996ca3 100644 --- a/src/audio_core/sink/sink_stream.h +++ b/src/audio_core/sink/sink_stream.h | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include "common/polyfill_thread.h" | 16 | #include "common/polyfill_thread.h" |
| 17 | #include "common/reader_writer_queue.h" | 17 | #include "common/reader_writer_queue.h" |
| 18 | #include "common/ring_buffer.h" | 18 | #include "common/ring_buffer.h" |
| 19 | #include "common/scratch_buffer.h" | ||
| 20 | #include "common/thread.h" | 19 | #include "common/thread.h" |
| 21 | 20 | ||
| 22 | namespace Core { | 21 | namespace Core { |
| @@ -256,8 +255,6 @@ private: | |||
| 256 | /// Signalled when ring buffer entries are consumed | 255 | /// Signalled when ring buffer entries are consumed |
| 257 | std::condition_variable_any release_cv; | 256 | std::condition_variable_any release_cv; |
| 258 | std::mutex release_mutex; | 257 | std::mutex release_mutex; |
| 259 | /// Temporary buffer for appending samples when upmixing | ||
| 260 | Common::ScratchBuffer<s16> tmp_samples{}; | ||
| 261 | }; | 258 | }; |
| 262 | 259 | ||
| 263 | using SinkStreamPtr = std::unique_ptr<SinkStream>; | 260 | using SinkStreamPtr = std::unique_ptr<SinkStream>; |
diff --git a/src/common/ring_buffer.h b/src/common/ring_buffer.h index 416680d44..5c961b202 100644 --- a/src/common/ring_buffer.h +++ b/src/common/ring_buffer.h | |||
| @@ -54,7 +54,7 @@ public: | |||
| 54 | return push_count; | 54 | return push_count; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | std::size_t Push(const std::span<T> input) { | 57 | std::size_t Push(std::span<const T> input) { |
| 58 | return Push(input.data(), input.size()); | 58 | return Push(input.data(), input.size()); |
| 59 | } | 59 | } |
| 60 | 60 | ||
diff --git a/src/common/scratch_buffer.h b/src/common/scratch_buffer.h index 6fe907953..d5961b020 100644 --- a/src/common/scratch_buffer.h +++ b/src/common/scratch_buffer.h | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | 5 | ||
| 6 | #include <iterator> | 6 | #include <iterator> |
| 7 | 7 | ||
| 8 | #include "common/concepts.h" | ||
| 9 | #include "common/make_unique_for_overwrite.h" | 8 | #include "common/make_unique_for_overwrite.h" |
| 10 | 9 | ||
| 11 | namespace Common { | 10 | namespace Common { |
| @@ -19,15 +18,22 @@ namespace Common { | |||
| 19 | template <typename T> | 18 | template <typename T> |
| 20 | class ScratchBuffer { | 19 | class ScratchBuffer { |
| 21 | public: | 20 | public: |
| 22 | using iterator = T*; | ||
| 23 | using const_iterator = const T*; | ||
| 24 | using value_type = T; | ||
| 25 | using element_type = T; | 21 | using element_type = T; |
| 26 | using iterator_category = std::contiguous_iterator_tag; | 22 | using value_type = T; |
| 23 | using size_type = size_t; | ||
| 24 | using difference_type = std::ptrdiff_t; | ||
| 25 | using pointer = T*; | ||
| 26 | using const_pointer = const T*; | ||
| 27 | using reference = T&; | ||
| 28 | using const_reference = const T&; | ||
| 29 | using iterator = pointer; | ||
| 30 | using const_iterator = const_pointer; | ||
| 31 | using iterator_category = std::random_access_iterator_tag; | ||
| 32 | using iterator_concept = std::contiguous_iterator_tag; | ||
| 27 | 33 | ||
| 28 | ScratchBuffer() = default; | 34 | ScratchBuffer() = default; |
| 29 | 35 | ||
| 30 | explicit ScratchBuffer(size_t initial_capacity) | 36 | explicit ScratchBuffer(size_type initial_capacity) |
| 31 | : last_requested_size{initial_capacity}, buffer_capacity{initial_capacity}, | 37 | : last_requested_size{initial_capacity}, buffer_capacity{initial_capacity}, |
| 32 | buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {} | 38 | buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {} |
| 33 | 39 | ||
| @@ -39,7 +45,7 @@ public: | |||
| 39 | 45 | ||
| 40 | /// This will only grow the buffer's capacity if size is greater than the current capacity. | 46 | /// This will only grow the buffer's capacity if size is greater than the current capacity. |
| 41 | /// The previously held data will remain intact. | 47 | /// The previously held data will remain intact. |
| 42 | void resize(size_t size) { | 48 | void resize(size_type size) { |
| 43 | if (size > buffer_capacity) { | 49 | if (size > buffer_capacity) { |
| 44 | auto new_buffer = Common::make_unique_for_overwrite<T[]>(size); | 50 | auto new_buffer = Common::make_unique_for_overwrite<T[]>(size); |
| 45 | std::move(buffer.get(), buffer.get() + buffer_capacity, new_buffer.get()); | 51 | std::move(buffer.get(), buffer.get() + buffer_capacity, new_buffer.get()); |
| @@ -51,7 +57,7 @@ public: | |||
| 51 | 57 | ||
| 52 | /// This will only grow the buffer's capacity if size is greater than the current capacity. | 58 | /// This will only grow the buffer's capacity if size is greater than the current capacity. |
| 53 | /// The previously held data will be destroyed if a reallocation occurs. | 59 | /// The previously held data will be destroyed if a reallocation occurs. |
| 54 | void resize_destructive(size_t size) { | 60 | void resize_destructive(size_type size) { |
| 55 | if (size > buffer_capacity) { | 61 | if (size > buffer_capacity) { |
| 56 | buffer_capacity = size; | 62 | buffer_capacity = size; |
| 57 | buffer = Common::make_unique_for_overwrite<T[]>(buffer_capacity); | 63 | buffer = Common::make_unique_for_overwrite<T[]>(buffer_capacity); |
| @@ -59,43 +65,43 @@ public: | |||
| 59 | last_requested_size = size; | 65 | last_requested_size = size; |
| 60 | } | 66 | } |
| 61 | 67 | ||
| 62 | [[nodiscard]] T* data() noexcept { | 68 | [[nodiscard]] pointer data() noexcept { |
| 63 | return buffer.get(); | 69 | return buffer.get(); |
| 64 | } | 70 | } |
| 65 | 71 | ||
| 66 | [[nodiscard]] const T* data() const noexcept { | 72 | [[nodiscard]] const_pointer data() const noexcept { |
| 67 | return buffer.get(); | 73 | return buffer.get(); |
| 68 | } | 74 | } |
| 69 | 75 | ||
| 70 | [[nodiscard]] T* begin() noexcept { | 76 | [[nodiscard]] iterator begin() noexcept { |
| 71 | return data(); | 77 | return data(); |
| 72 | } | 78 | } |
| 73 | 79 | ||
| 74 | [[nodiscard]] const T* begin() const noexcept { | 80 | [[nodiscard]] const_iterator begin() const noexcept { |
| 75 | return data(); | 81 | return data(); |
| 76 | } | 82 | } |
| 77 | 83 | ||
| 78 | [[nodiscard]] T* end() noexcept { | 84 | [[nodiscard]] iterator end() noexcept { |
| 79 | return data() + last_requested_size; | 85 | return data() + last_requested_size; |
| 80 | } | 86 | } |
| 81 | 87 | ||
| 82 | [[nodiscard]] const T* end() const noexcept { | 88 | [[nodiscard]] const_iterator end() const noexcept { |
| 83 | return data() + last_requested_size; | 89 | return data() + last_requested_size; |
| 84 | } | 90 | } |
| 85 | 91 | ||
| 86 | [[nodiscard]] T& operator[](size_t i) { | 92 | [[nodiscard]] reference operator[](size_type i) { |
| 87 | return buffer[i]; | 93 | return buffer[i]; |
| 88 | } | 94 | } |
| 89 | 95 | ||
| 90 | [[nodiscard]] const T& operator[](size_t i) const { | 96 | [[nodiscard]] const_reference operator[](size_type i) const { |
| 91 | return buffer[i]; | 97 | return buffer[i]; |
| 92 | } | 98 | } |
| 93 | 99 | ||
| 94 | [[nodiscard]] size_t size() const noexcept { | 100 | [[nodiscard]] size_type size() const noexcept { |
| 95 | return last_requested_size; | 101 | return last_requested_size; |
| 96 | } | 102 | } |
| 97 | 103 | ||
| 98 | [[nodiscard]] size_t capacity() const noexcept { | 104 | [[nodiscard]] size_type capacity() const noexcept { |
| 99 | return buffer_capacity; | 105 | return buffer_capacity; |
| 100 | } | 106 | } |
| 101 | 107 | ||
| @@ -106,8 +112,8 @@ public: | |||
| 106 | } | 112 | } |
| 107 | 113 | ||
| 108 | private: | 114 | private: |
| 109 | size_t last_requested_size{}; | 115 | size_type last_requested_size{}; |
| 110 | size_t buffer_capacity{}; | 116 | size_type buffer_capacity{}; |
| 111 | std::unique_ptr<T[]> buffer{}; | 117 | std::unique_ptr<T[]> buffer{}; |
| 112 | }; | 118 | }; |
| 113 | 119 | ||
diff --git a/src/common/settings.h b/src/common/settings.h index ae5ed93d8..59e96e74f 100644 --- a/src/common/settings.h +++ b/src/common/settings.h | |||
| @@ -527,12 +527,10 @@ struct Values { | |||
| 527 | Setting<bool> mouse_panning{false, "mouse_panning"}; | 527 | Setting<bool> mouse_panning{false, "mouse_panning"}; |
| 528 | Setting<u8, true> mouse_panning_x_sensitivity{50, 1, 100, "mouse_panning_x_sensitivity"}; | 528 | Setting<u8, true> mouse_panning_x_sensitivity{50, 1, 100, "mouse_panning_x_sensitivity"}; |
| 529 | Setting<u8, true> mouse_panning_y_sensitivity{50, 1, 100, "mouse_panning_y_sensitivity"}; | 529 | Setting<u8, true> mouse_panning_y_sensitivity{50, 1, 100, "mouse_panning_y_sensitivity"}; |
| 530 | Setting<u8, true> mouse_panning_deadzone_x_counterweight{ | 530 | Setting<u8, true> mouse_panning_deadzone_counterweight{20, 0, 100, |
| 531 | 0, 0, 100, "mouse_panning_deadzone_x_counterweight"}; | 531 | "mouse_panning_deadzone_counterweight"}; |
| 532 | Setting<u8, true> mouse_panning_deadzone_y_counterweight{ | 532 | Setting<u8, true> mouse_panning_decay_strength{18, 0, 100, "mouse_panning_decay_strength"}; |
| 533 | 0, 0, 100, "mouse_panning_deadzone_y_counterweight"}; | 533 | Setting<u8, true> mouse_panning_min_decay{6, 0, 100, "mouse_panning_min_decay"}; |
| 534 | Setting<u8, true> mouse_panning_decay_strength{22, 0, 100, "mouse_panning_decay_strength"}; | ||
| 535 | Setting<u8, true> mouse_panning_min_decay{5, 0, 100, "mouse_panning_min_decay"}; | ||
| 536 | 534 | ||
| 537 | Setting<bool> mouse_enabled{false, "mouse_enabled"}; | 535 | Setting<bool> mouse_enabled{false, "mouse_enabled"}; |
| 538 | Setting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"}; | 536 | Setting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"}; |
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index c8d574993..526a39130 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #include "audio_core/renderer/audio_device.h" | 5 | #include "audio_core/renderer/audio_device.h" |
| 6 | #include "common/common_funcs.h" | 6 | #include "common/common_funcs.h" |
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "common/settings.h" | 8 | #include "common/scratch_buffer.h" |
| 9 | #include "common/string_util.h" | 9 | #include "common/string_util.h" |
| 10 | #include "core/core.h" | 10 | #include "core/core.h" |
| 11 | #include "core/hle/kernel/k_event.h" | 11 | #include "core/hle/kernel/k_event.h" |
| @@ -124,12 +124,15 @@ private: | |||
| 124 | 124 | ||
| 125 | void GetReleasedAudioInBuffer(HLERequestContext& ctx) { | 125 | void GetReleasedAudioInBuffer(HLERequestContext& ctx) { |
| 126 | const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); | 126 | const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); |
| 127 | tmp_buffer.resize_destructive(write_buffer_size); | 127 | released_buffer.resize_destructive(write_buffer_size); |
| 128 | tmp_buffer[0] = 0; | 128 | released_buffer[0] = 0; |
| 129 | 129 | ||
| 130 | const auto count = impl->GetReleasedBuffers(tmp_buffer); | 130 | const auto count = impl->GetReleasedBuffers(released_buffer); |
| 131 | 131 | ||
| 132 | ctx.WriteBuffer(tmp_buffer); | 132 | LOG_TRACE(Service_Audio, "called. Session {} released {} buffers", |
| 133 | impl->GetSystem().GetSessionId(), count); | ||
| 134 | |||
| 135 | ctx.WriteBuffer(released_buffer); | ||
| 133 | 136 | ||
| 134 | IPC::ResponseBuilder rb{ctx, 3}; | 137 | IPC::ResponseBuilder rb{ctx, 3}; |
| 135 | rb.Push(ResultSuccess); | 138 | rb.Push(ResultSuccess); |
| @@ -155,7 +158,6 @@ private: | |||
| 155 | LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count); | 158 | LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count); |
| 156 | 159 | ||
| 157 | IPC::ResponseBuilder rb{ctx, 3}; | 160 | IPC::ResponseBuilder rb{ctx, 3}; |
| 158 | |||
| 159 | rb.Push(ResultSuccess); | 161 | rb.Push(ResultSuccess); |
| 160 | rb.Push(buffer_count); | 162 | rb.Push(buffer_count); |
| 161 | } | 163 | } |
| @@ -195,7 +197,7 @@ private: | |||
| 195 | KernelHelpers::ServiceContext service_context; | 197 | KernelHelpers::ServiceContext service_context; |
| 196 | Kernel::KEvent* event; | 198 | Kernel::KEvent* event; |
| 197 | std::shared_ptr<AudioCore::AudioIn::In> impl; | 199 | std::shared_ptr<AudioCore::AudioIn::In> impl; |
| 198 | Common::ScratchBuffer<u64> tmp_buffer; | 200 | Common::ScratchBuffer<u64> released_buffer; |
| 199 | }; | 201 | }; |
| 200 | 202 | ||
| 201 | AudInU::AudInU(Core::System& system_) | 203 | AudInU::AudInU(Core::System& system_) |
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 032c8c11f..23f84a29f 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "audio_core/renderer/audio_device.h" | 9 | #include "audio_core/renderer/audio_device.h" |
| 10 | #include "common/common_funcs.h" | 10 | #include "common/common_funcs.h" |
| 11 | #include "common/logging/log.h" | 11 | #include "common/logging/log.h" |
| 12 | #include "common/scratch_buffer.h" | ||
| 12 | #include "common/string_util.h" | 13 | #include "common/string_util.h" |
| 13 | #include "common/swap.h" | 14 | #include "common/swap.h" |
| 14 | #include "core/core.h" | 15 | #include "core/core.h" |
| @@ -102,8 +103,8 @@ private: | |||
| 102 | AudioOutBuffer buffer{}; | 103 | AudioOutBuffer buffer{}; |
| 103 | std::memcpy(&buffer, in_buffer.data(), sizeof(AudioOutBuffer)); | 104 | std::memcpy(&buffer, in_buffer.data(), sizeof(AudioOutBuffer)); |
| 104 | 105 | ||
| 105 | [[maybe_unused]] auto sessionid{impl->GetSystem().GetSessionId()}; | 106 | LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}", |
| 106 | LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}", sessionid, tag); | 107 | impl->GetSystem().GetSessionId(), tag); |
| 107 | 108 | ||
| 108 | auto result = impl->AppendBuffer(buffer, tag); | 109 | auto result = impl->AppendBuffer(buffer, tag); |
| 109 | 110 | ||
| @@ -123,12 +124,15 @@ private: | |||
| 123 | 124 | ||
| 124 | void GetReleasedAudioOutBuffers(HLERequestContext& ctx) { | 125 | void GetReleasedAudioOutBuffers(HLERequestContext& ctx) { |
| 125 | const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); | 126 | const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); |
| 126 | tmp_buffer.resize_destructive(write_buffer_size); | 127 | released_buffer.resize_destructive(write_buffer_size); |
| 127 | tmp_buffer[0] = 0; | 128 | released_buffer[0] = 0; |
| 128 | 129 | ||
| 129 | const auto count = impl->GetReleasedBuffers(tmp_buffer); | 130 | const auto count = impl->GetReleasedBuffers(released_buffer); |
| 130 | 131 | ||
| 131 | ctx.WriteBuffer(tmp_buffer); | 132 | ctx.WriteBuffer(released_buffer); |
| 133 | |||
| 134 | LOG_TRACE(Service_Audio, "called. Session {} released {} buffers", | ||
| 135 | impl->GetSystem().GetSessionId(), count); | ||
| 132 | 136 | ||
| 133 | IPC::ResponseBuilder rb{ctx, 3}; | 137 | IPC::ResponseBuilder rb{ctx, 3}; |
| 134 | rb.Push(ResultSuccess); | 138 | rb.Push(ResultSuccess); |
| @@ -154,7 +158,6 @@ private: | |||
| 154 | LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count); | 158 | LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count); |
| 155 | 159 | ||
| 156 | IPC::ResponseBuilder rb{ctx, 3}; | 160 | IPC::ResponseBuilder rb{ctx, 3}; |
| 157 | |||
| 158 | rb.Push(ResultSuccess); | 161 | rb.Push(ResultSuccess); |
| 159 | rb.Push(buffer_count); | 162 | rb.Push(buffer_count); |
| 160 | } | 163 | } |
| @@ -165,7 +168,6 @@ private: | |||
| 165 | LOG_DEBUG(Service_Audio, "called. Played samples={}", samples_played); | 168 | LOG_DEBUG(Service_Audio, "called. Played samples={}", samples_played); |
| 166 | 169 | ||
| 167 | IPC::ResponseBuilder rb{ctx, 4}; | 170 | IPC::ResponseBuilder rb{ctx, 4}; |
| 168 | |||
| 169 | rb.Push(ResultSuccess); | 171 | rb.Push(ResultSuccess); |
| 170 | rb.Push(samples_played); | 172 | rb.Push(samples_played); |
| 171 | } | 173 | } |
| @@ -205,7 +207,7 @@ private: | |||
| 205 | KernelHelpers::ServiceContext service_context; | 207 | KernelHelpers::ServiceContext service_context; |
| 206 | Kernel::KEvent* event; | 208 | Kernel::KEvent* event; |
| 207 | std::shared_ptr<AudioCore::AudioOut::Out> impl; | 209 | std::shared_ptr<AudioCore::AudioOut::Out> impl; |
| 208 | Common::ScratchBuffer<u64> tmp_buffer; | 210 | Common::ScratchBuffer<u64> released_buffer; |
| 209 | }; | 211 | }; |
| 210 | 212 | ||
| 211 | AudOutU::AudOutU(Core::System& system_) | 213 | AudOutU::AudOutU(Core::System& system_) |
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 12845c23a..003870176 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "common/common_funcs.h" | 15 | #include "common/common_funcs.h" |
| 16 | #include "common/logging/log.h" | 16 | #include "common/logging/log.h" |
| 17 | #include "common/polyfill_ranges.h" | 17 | #include "common/polyfill_ranges.h" |
| 18 | #include "common/scratch_buffer.h" | ||
| 18 | #include "common/string_util.h" | 19 | #include "common/string_util.h" |
| 19 | #include "core/core.h" | 20 | #include "core/core.h" |
| 20 | #include "core/hle/kernel/k_event.h" | 21 | #include "core/hle/kernel/k_event.h" |
| @@ -119,23 +120,23 @@ private: | |||
| 119 | auto is_buffer_b{ctx.BufferDescriptorB()[0].Size() != 0}; | 120 | auto is_buffer_b{ctx.BufferDescriptorB()[0].Size() != 0}; |
| 120 | if (is_buffer_b) { | 121 | if (is_buffer_b) { |
| 121 | const auto buffersB{ctx.BufferDescriptorB()}; | 122 | const auto buffersB{ctx.BufferDescriptorB()}; |
| 122 | tmp_output.resize_destructive(buffersB[0].Size()); | 123 | output_buffer.resize_destructive(buffersB[0].Size()); |
| 123 | tmp_performance.resize_destructive(buffersB[1].Size()); | 124 | performance_buffer.resize_destructive(buffersB[1].Size()); |
| 124 | } else { | 125 | } else { |
| 125 | const auto buffersC{ctx.BufferDescriptorC()}; | 126 | const auto buffersC{ctx.BufferDescriptorC()}; |
| 126 | tmp_output.resize_destructive(buffersC[0].Size()); | 127 | output_buffer.resize_destructive(buffersC[0].Size()); |
| 127 | tmp_performance.resize_destructive(buffersC[1].Size()); | 128 | performance_buffer.resize_destructive(buffersC[1].Size()); |
| 128 | } | 129 | } |
| 129 | 130 | ||
| 130 | auto result = impl->RequestUpdate(input, tmp_performance, tmp_output); | 131 | auto result = impl->RequestUpdate(input, performance_buffer, output_buffer); |
| 131 | 132 | ||
| 132 | if (result.IsSuccess()) { | 133 | if (result.IsSuccess()) { |
| 133 | if (is_buffer_b) { | 134 | if (is_buffer_b) { |
| 134 | ctx.WriteBufferB(tmp_output.data(), tmp_output.size(), 0); | 135 | ctx.WriteBufferB(output_buffer.data(), output_buffer.size(), 0); |
| 135 | ctx.WriteBufferB(tmp_performance.data(), tmp_performance.size(), 1); | 136 | ctx.WriteBufferB(performance_buffer.data(), performance_buffer.size(), 1); |
| 136 | } else { | 137 | } else { |
| 137 | ctx.WriteBufferC(tmp_output.data(), tmp_output.size(), 0); | 138 | ctx.WriteBufferC(output_buffer.data(), output_buffer.size(), 0); |
| 138 | ctx.WriteBufferC(tmp_performance.data(), tmp_performance.size(), 1); | 139 | ctx.WriteBufferC(performance_buffer.data(), performance_buffer.size(), 1); |
| 139 | } | 140 | } |
| 140 | } else { | 141 | } else { |
| 141 | LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", result.description); | 142 | LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", result.description); |
| @@ -233,8 +234,8 @@ private: | |||
| 233 | Kernel::KEvent* rendered_event; | 234 | Kernel::KEvent* rendered_event; |
| 234 | Manager& manager; | 235 | Manager& manager; |
| 235 | std::unique_ptr<Renderer> impl; | 236 | std::unique_ptr<Renderer> impl; |
| 236 | Common::ScratchBuffer<u8> tmp_output; | 237 | Common::ScratchBuffer<u8> output_buffer; |
| 237 | Common::ScratchBuffer<u8> tmp_performance; | 238 | Common::ScratchBuffer<u8> performance_buffer; |
| 238 | }; | 239 | }; |
| 239 | 240 | ||
| 240 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { | 241 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { |
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index c835f6cb7..fa77007f3 100644 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include "common/assert.h" | 12 | #include "common/assert.h" |
| 13 | #include "common/logging/log.h" | 13 | #include "common/logging/log.h" |
| 14 | #include "common/scratch_buffer.h" | ||
| 14 | #include "core/hle/service/audio/hwopus.h" | 15 | #include "core/hle/service/audio/hwopus.h" |
| 15 | #include "core/hle/service/ipc_helpers.h" | 16 | #include "core/hle/service/ipc_helpers.h" |
| 16 | 17 | ||
| @@ -68,13 +69,13 @@ private: | |||
| 68 | ExtraBehavior extra_behavior) { | 69 | ExtraBehavior extra_behavior) { |
| 69 | u32 consumed = 0; | 70 | u32 consumed = 0; |
| 70 | u32 sample_count = 0; | 71 | u32 sample_count = 0; |
| 71 | tmp_samples.resize_destructive(ctx.GetWriteBufferNumElements<opus_int16>()); | 72 | samples.resize_destructive(ctx.GetWriteBufferNumElements<opus_int16>()); |
| 72 | 73 | ||
| 73 | if (extra_behavior == ExtraBehavior::ResetContext) { | 74 | if (extra_behavior == ExtraBehavior::ResetContext) { |
| 74 | ResetDecoderContext(); | 75 | ResetDecoderContext(); |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 77 | if (!DecodeOpusData(consumed, sample_count, ctx.ReadBuffer(), tmp_samples, performance)) { | 78 | if (!DecodeOpusData(consumed, sample_count, ctx.ReadBuffer(), samples, performance)) { |
| 78 | LOG_ERROR(Audio, "Failed to decode opus data"); | 79 | LOG_ERROR(Audio, "Failed to decode opus data"); |
| 79 | IPC::ResponseBuilder rb{ctx, 2}; | 80 | IPC::ResponseBuilder rb{ctx, 2}; |
| 80 | // TODO(ogniK): Use correct error code | 81 | // TODO(ogniK): Use correct error code |
| @@ -90,7 +91,7 @@ private: | |||
| 90 | if (performance) { | 91 | if (performance) { |
| 91 | rb.Push<u64>(*performance); | 92 | rb.Push<u64>(*performance); |
| 92 | } | 93 | } |
| 93 | ctx.WriteBuffer(tmp_samples); | 94 | ctx.WriteBuffer(samples); |
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | bool DecodeOpusData(u32& consumed, u32& sample_count, std::span<const u8> input, | 97 | bool DecodeOpusData(u32& consumed, u32& sample_count, std::span<const u8> input, |
| @@ -154,7 +155,7 @@ private: | |||
| 154 | OpusDecoderPtr decoder; | 155 | OpusDecoderPtr decoder; |
| 155 | u32 sample_rate; | 156 | u32 sample_rate; |
| 156 | u32 channel_count; | 157 | u32 channel_count; |
| 157 | Common::ScratchBuffer<opus_int16> tmp_samples; | 158 | Common::ScratchBuffer<opus_int16> samples; |
| 158 | }; | 159 | }; |
| 159 | 160 | ||
| 160 | class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> { | 161 | class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> { |
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp index 348207e25..c8a880e84 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // SPDX-FileCopyrightText: 2021 Skyline Team and Contributors | 2 | // SPDX-FileCopyrightText: 2021 Skyline Team and Contributors |
| 3 | // SPDX-License-Identifier: GPL-3.0-or-later | 3 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 4 | 4 | ||
| 5 | #include <cinttypes> | ||
| 6 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 7 | #include "core/core.h" | 6 | #include "core/core.h" |
| 8 | #include "core/hle/kernel/k_event.h" | 7 | #include "core/hle/kernel/k_event.h" |
| @@ -63,12 +62,12 @@ void NVDRV::Ioctl1(HLERequestContext& ctx) { | |||
| 63 | } | 62 | } |
| 64 | 63 | ||
| 65 | // Check device | 64 | // Check device |
| 66 | tmp_output.resize_destructive(ctx.GetWriteBufferSize(0)); | 65 | output_buffer.resize_destructive(ctx.GetWriteBufferSize(0)); |
| 67 | const auto input_buffer = ctx.ReadBuffer(0); | 66 | const auto input_buffer = ctx.ReadBuffer(0); |
| 68 | 67 | ||
| 69 | const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, tmp_output); | 68 | const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, output_buffer); |
| 70 | if (command.is_out != 0) { | 69 | if (command.is_out != 0) { |
| 71 | ctx.WriteBuffer(tmp_output); | 70 | ctx.WriteBuffer(output_buffer); |
| 72 | } | 71 | } |
| 73 | 72 | ||
| 74 | IPC::ResponseBuilder rb{ctx, 3}; | 73 | IPC::ResponseBuilder rb{ctx, 3}; |
| @@ -90,12 +89,12 @@ void NVDRV::Ioctl2(HLERequestContext& ctx) { | |||
| 90 | 89 | ||
| 91 | const auto input_buffer = ctx.ReadBuffer(0); | 90 | const auto input_buffer = ctx.ReadBuffer(0); |
| 92 | const auto input_inlined_buffer = ctx.ReadBuffer(1); | 91 | const auto input_inlined_buffer = ctx.ReadBuffer(1); |
| 93 | tmp_output.resize_destructive(ctx.GetWriteBufferSize(0)); | 92 | output_buffer.resize_destructive(ctx.GetWriteBufferSize(0)); |
| 94 | 93 | ||
| 95 | const auto nv_result = | 94 | const auto nv_result = |
| 96 | nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, tmp_output); | 95 | nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, output_buffer); |
| 97 | if (command.is_out != 0) { | 96 | if (command.is_out != 0) { |
| 98 | ctx.WriteBuffer(tmp_output); | 97 | ctx.WriteBuffer(output_buffer); |
| 99 | } | 98 | } |
| 100 | 99 | ||
| 101 | IPC::ResponseBuilder rb{ctx, 3}; | 100 | IPC::ResponseBuilder rb{ctx, 3}; |
| @@ -116,12 +115,14 @@ void NVDRV::Ioctl3(HLERequestContext& ctx) { | |||
| 116 | } | 115 | } |
| 117 | 116 | ||
| 118 | const auto input_buffer = ctx.ReadBuffer(0); | 117 | const auto input_buffer = ctx.ReadBuffer(0); |
| 119 | tmp_output.resize_destructive(ctx.GetWriteBufferSize(0)); | 118 | output_buffer.resize_destructive(ctx.GetWriteBufferSize(0)); |
| 120 | tmp_output_inline.resize_destructive(ctx.GetWriteBufferSize(1)); | 119 | inline_output_buffer.resize_destructive(ctx.GetWriteBufferSize(1)); |
| 121 | const auto nv_result = nvdrv->Ioctl3(fd, command, input_buffer, tmp_output, tmp_output_inline); | 120 | |
| 121 | const auto nv_result = | ||
| 122 | nvdrv->Ioctl3(fd, command, input_buffer, output_buffer, inline_output_buffer); | ||
| 122 | if (command.is_out != 0) { | 123 | if (command.is_out != 0) { |
| 123 | ctx.WriteBuffer(tmp_output, 0); | 124 | ctx.WriteBuffer(output_buffer, 0); |
| 124 | ctx.WriteBuffer(tmp_output_inline, 1); | 125 | ctx.WriteBuffer(inline_output_buffer, 1); |
| 125 | } | 126 | } |
| 126 | 127 | ||
| 127 | IPC::ResponseBuilder rb{ctx, 3}; | 128 | IPC::ResponseBuilder rb{ctx, 3}; |
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h index 4b593ff90..6e98115dc 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.h +++ b/src/core/hle/service/nvdrv/nvdrv_interface.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | |||
| 7 | #include "common/scratch_buffer.h" | 8 | #include "common/scratch_buffer.h" |
| 8 | #include "core/hle/service/nvdrv/nvdrv.h" | 9 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 9 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
| @@ -34,8 +35,8 @@ private: | |||
| 34 | 35 | ||
| 35 | u64 pid{}; | 36 | u64 pid{}; |
| 36 | bool is_initialized{}; | 37 | bool is_initialized{}; |
| 37 | Common::ScratchBuffer<u8> tmp_output; | 38 | Common::ScratchBuffer<u8> output_buffer; |
| 38 | Common::ScratchBuffer<u8> tmp_output_inline; | 39 | Common::ScratchBuffer<u8> inline_output_buffer; |
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | } // namespace Service::Nvidia | 42 | } // namespace Service::Nvidia |
diff --git a/src/core/hle/service/nvnflinger/parcel.h b/src/core/hle/service/nvnflinger/parcel.h index 23ba315a0..e2c9bbd50 100644 --- a/src/core/hle/service/nvnflinger/parcel.h +++ b/src/core/hle/service/nvnflinger/parcel.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include <span> | 7 | #include <span> |
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | |||
| 9 | #include <boost/container/small_vector.hpp> | 10 | #include <boost/container/small_vector.hpp> |
| 10 | 11 | ||
| 11 | #include "common/alignment.h" | 12 | #include "common/alignment.h" |
| @@ -148,9 +149,9 @@ public: | |||
| 148 | this->WriteImpl(0U, m_object_buffer); | 149 | this->WriteImpl(0U, m_object_buffer); |
| 149 | } | 150 | } |
| 150 | 151 | ||
| 151 | std::vector<u8> Serialize() const { | 152 | std::span<u8> Serialize() { |
| 152 | std::vector<u8> output_buffer(sizeof(ParcelHeader) + m_data_buffer.size() + | 153 | m_output_buffer.resize(sizeof(ParcelHeader) + m_data_buffer.size() + |
| 153 | m_object_buffer.size()); | 154 | m_object_buffer.size()); |
| 154 | 155 | ||
| 155 | ParcelHeader header{}; | 156 | ParcelHeader header{}; |
| 156 | header.data_size = static_cast<u32>(m_data_buffer.size()); | 157 | header.data_size = static_cast<u32>(m_data_buffer.size()); |
| @@ -158,17 +159,17 @@ public: | |||
| 158 | header.objects_size = static_cast<u32>(m_object_buffer.size()); | 159 | header.objects_size = static_cast<u32>(m_object_buffer.size()); |
| 159 | header.objects_offset = header.data_offset + header.data_size; | 160 | header.objects_offset = header.data_offset + header.data_size; |
| 160 | 161 | ||
| 161 | std::memcpy(output_buffer.data(), &header, sizeof(header)); | 162 | std::memcpy(m_output_buffer.data(), &header, sizeof(ParcelHeader)); |
| 162 | std::ranges::copy(m_data_buffer, output_buffer.data() + header.data_offset); | 163 | std::ranges::copy(m_data_buffer, m_output_buffer.data() + header.data_offset); |
| 163 | std::ranges::copy(m_object_buffer, output_buffer.data() + header.objects_offset); | 164 | std::ranges::copy(m_object_buffer, m_output_buffer.data() + header.objects_offset); |
| 164 | 165 | ||
| 165 | return output_buffer; | 166 | return m_output_buffer; |
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | private: | 169 | private: |
| 169 | template <typename T> | 170 | template <typename T, size_t BufferSize> |
| 170 | requires(std::is_trivially_copyable_v<T>) | 171 | requires(std::is_trivially_copyable_v<T>) |
| 171 | void WriteImpl(const T& val, boost::container::small_vector<u8, 0x200>& buffer) { | 172 | void WriteImpl(const T& val, boost::container::small_vector<u8, BufferSize>& buffer) { |
| 172 | const size_t aligned_size = Common::AlignUp(sizeof(T), 4); | 173 | const size_t aligned_size = Common::AlignUp(sizeof(T), 4); |
| 173 | const size_t old_size = buffer.size(); | 174 | const size_t old_size = buffer.size(); |
| 174 | buffer.resize(old_size + aligned_size); | 175 | buffer.resize(old_size + aligned_size); |
| @@ -177,8 +178,9 @@ private: | |||
| 177 | } | 178 | } |
| 178 | 179 | ||
| 179 | private: | 180 | private: |
| 180 | boost::container::small_vector<u8, 0x200> m_data_buffer; | 181 | boost::container::small_vector<u8, 0x1B0> m_data_buffer; |
| 181 | boost::container::small_vector<u8, 0x200> m_object_buffer; | 182 | boost::container::small_vector<u8, 0x40> m_object_buffer; |
| 183 | boost::container::small_vector<u8, 0x200> m_output_buffer; | ||
| 182 | }; | 184 | }; |
| 183 | 185 | ||
| 184 | } // namespace Service::android | 186 | } // namespace Service::android |
diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp index f07cf8a0e..dac29c78f 100644 --- a/src/input_common/drivers/mouse.cpp +++ b/src/input_common/drivers/mouse.cpp | |||
| @@ -12,9 +12,13 @@ | |||
| 12 | 12 | ||
| 13 | namespace InputCommon { | 13 | namespace InputCommon { |
| 14 | constexpr int update_time = 10; | 14 | constexpr int update_time = 10; |
| 15 | constexpr float default_stick_sensitivity = 0.0044f; | 15 | constexpr float default_panning_sensitivity = 0.0010f; |
| 16 | constexpr float default_motion_sensitivity = 0.0003f; | 16 | constexpr float default_stick_sensitivity = 0.0006f; |
| 17 | constexpr float default_deadzone_counterweight = 0.01f; | ||
| 18 | constexpr float default_motion_panning_sensitivity = 2.5f; | ||
| 19 | constexpr float default_motion_sensitivity = 0.416f; | ||
| 17 | constexpr float maximum_rotation_speed = 2.0f; | 20 | constexpr float maximum_rotation_speed = 2.0f; |
| 21 | constexpr float maximum_stick_range = 1.5f; | ||
| 18 | constexpr int mouse_axis_x = 0; | 22 | constexpr int mouse_axis_x = 0; |
| 19 | constexpr int mouse_axis_y = 1; | 23 | constexpr int mouse_axis_y = 1; |
| 20 | constexpr int wheel_axis_x = 2; | 24 | constexpr int wheel_axis_x = 2; |
| @@ -81,7 +85,7 @@ void Mouse::UpdateThread(std::stop_token stop_token) { | |||
| 81 | } | 85 | } |
| 82 | 86 | ||
| 83 | void Mouse::UpdateStickInput() { | 87 | void Mouse::UpdateStickInput() { |
| 84 | if (!Settings::values.mouse_panning) { | 88 | if (!IsMousePanningEnabled()) { |
| 85 | return; | 89 | return; |
| 86 | } | 90 | } |
| 87 | 91 | ||
| @@ -89,26 +93,13 @@ void Mouse::UpdateStickInput() { | |||
| 89 | 93 | ||
| 90 | // Prevent input from exceeding the max range (1.0f) too much, | 94 | // Prevent input from exceeding the max range (1.0f) too much, |
| 91 | // but allow some room to make it easier to sustain | 95 | // but allow some room to make it easier to sustain |
| 92 | if (length > 1.2f) { | 96 | if (length > maximum_stick_range) { |
| 93 | last_mouse_change /= length; | 97 | last_mouse_change /= length; |
| 94 | last_mouse_change *= 1.2f; | 98 | last_mouse_change *= maximum_stick_range; |
| 95 | } | 99 | } |
| 96 | 100 | ||
| 97 | auto mouse_change = last_mouse_change; | 101 | SetAxis(identifier, mouse_axis_x, last_mouse_change.x); |
| 98 | 102 | SetAxis(identifier, mouse_axis_y, -last_mouse_change.y); | |
| 99 | // Bind the mouse change to [0 <= deadzone_counterweight <= 1,1] | ||
| 100 | if (length < 1.0f) { | ||
| 101 | const float deadzone_h_counterweight = | ||
| 102 | Settings::values.mouse_panning_deadzone_x_counterweight.GetValue(); | ||
| 103 | const float deadzone_v_counterweight = | ||
| 104 | Settings::values.mouse_panning_deadzone_y_counterweight.GetValue(); | ||
| 105 | mouse_change /= length; | ||
| 106 | mouse_change.x *= length + (1 - length) * deadzone_h_counterweight * 0.01f; | ||
| 107 | mouse_change.y *= length + (1 - length) * deadzone_v_counterweight * 0.01f; | ||
| 108 | } | ||
| 109 | |||
| 110 | SetAxis(identifier, mouse_axis_x, mouse_change.x); | ||
| 111 | SetAxis(identifier, mouse_axis_y, -mouse_change.y); | ||
| 112 | 103 | ||
| 113 | // Decay input over time | 104 | // Decay input over time |
| 114 | const float clamped_length = std::min(1.0f, length); | 105 | const float clamped_length = std::min(1.0f, length); |
| @@ -120,14 +111,13 @@ void Mouse::UpdateStickInput() { | |||
| 120 | } | 111 | } |
| 121 | 112 | ||
| 122 | void Mouse::UpdateMotionInput() { | 113 | void Mouse::UpdateMotionInput() { |
| 123 | // This may need its own sensitivity instead of using the average | 114 | const float sensitivity = |
| 124 | const float sensitivity = (Settings::values.mouse_panning_x_sensitivity.GetValue() + | 115 | IsMousePanningEnabled() ? default_motion_panning_sensitivity : default_motion_sensitivity; |
| 125 | Settings::values.mouse_panning_y_sensitivity.GetValue()) / | ||
| 126 | 2.0f * default_motion_sensitivity; | ||
| 127 | 116 | ||
| 128 | const float rotation_velocity = std::sqrt(last_motion_change.x * last_motion_change.x + | 117 | const float rotation_velocity = std::sqrt(last_motion_change.x * last_motion_change.x + |
| 129 | last_motion_change.y * last_motion_change.y); | 118 | last_motion_change.y * last_motion_change.y); |
| 130 | 119 | ||
| 120 | // Clamp rotation speed | ||
| 131 | if (rotation_velocity > maximum_rotation_speed / sensitivity) { | 121 | if (rotation_velocity > maximum_rotation_speed / sensitivity) { |
| 132 | const float multiplier = maximum_rotation_speed / rotation_velocity / sensitivity; | 122 | const float multiplier = maximum_rotation_speed / rotation_velocity / sensitivity; |
| 133 | last_motion_change.x = last_motion_change.x * multiplier; | 123 | last_motion_change.x = last_motion_change.x * multiplier; |
| @@ -144,7 +134,7 @@ void Mouse::UpdateMotionInput() { | |||
| 144 | .delta_timestamp = update_time * 1000, | 134 | .delta_timestamp = update_time * 1000, |
| 145 | }; | 135 | }; |
| 146 | 136 | ||
| 147 | if (Settings::values.mouse_panning) { | 137 | if (IsMousePanningEnabled()) { |
| 148 | last_motion_change.x = 0; | 138 | last_motion_change.x = 0; |
| 149 | last_motion_change.y = 0; | 139 | last_motion_change.y = 0; |
| 150 | } | 140 | } |
| @@ -154,33 +144,42 @@ void Mouse::UpdateMotionInput() { | |||
| 154 | } | 144 | } |
| 155 | 145 | ||
| 156 | void Mouse::Move(int x, int y, int center_x, int center_y) { | 146 | void Mouse::Move(int x, int y, int center_x, int center_y) { |
| 157 | if (Settings::values.mouse_panning) { | 147 | if (IsMousePanningEnabled()) { |
| 158 | const auto mouse_change = | 148 | const auto mouse_change = |
| 159 | (Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>(); | 149 | (Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>(); |
| 160 | const float x_sensitivity = | 150 | const float x_sensitivity = |
| 161 | Settings::values.mouse_panning_x_sensitivity.GetValue() * default_stick_sensitivity; | 151 | Settings::values.mouse_panning_x_sensitivity.GetValue() * default_panning_sensitivity; |
| 162 | const float y_sensitivity = | 152 | const float y_sensitivity = |
| 163 | Settings::values.mouse_panning_y_sensitivity.GetValue() * default_stick_sensitivity; | 153 | Settings::values.mouse_panning_y_sensitivity.GetValue() * default_panning_sensitivity; |
| 154 | const float deadzone_counterweight = | ||
| 155 | Settings::values.mouse_panning_deadzone_counterweight.GetValue() * | ||
| 156 | default_deadzone_counterweight; | ||
| 157 | |||
| 158 | last_motion_change += {-mouse_change.y * x_sensitivity, -mouse_change.x * y_sensitivity, 0}; | ||
| 159 | last_mouse_change.x += mouse_change.x * x_sensitivity; | ||
| 160 | last_mouse_change.y += mouse_change.y * y_sensitivity; | ||
| 164 | 161 | ||
| 165 | last_motion_change += {-mouse_change.y, -mouse_change.x, 0}; | 162 | // Bind the mouse change to [0 <= deadzone_counterweight <= 1.0] |
| 166 | last_mouse_change.x += mouse_change.x * x_sensitivity * 0.09f; | 163 | if (last_mouse_change.Length() < deadzone_counterweight) { |
| 167 | last_mouse_change.y += mouse_change.y * y_sensitivity * 0.09f; | 164 | last_mouse_change /= last_mouse_change.Length(); |
| 165 | last_mouse_change *= deadzone_counterweight; | ||
| 166 | } | ||
| 168 | 167 | ||
| 169 | return; | 168 | return; |
| 170 | } | 169 | } |
| 171 | 170 | ||
| 172 | if (button_pressed) { | 171 | if (button_pressed) { |
| 173 | const auto mouse_move = Common::MakeVec<int>(x, y) - mouse_origin; | 172 | const auto mouse_move = Common::MakeVec<int>(x, y) - mouse_origin; |
| 174 | const float x_sensitivity = Settings::values.mouse_panning_x_sensitivity.GetValue(); | 173 | const float x_sensitivity = |
| 175 | const float y_sensitivity = Settings::values.mouse_panning_y_sensitivity.GetValue(); | 174 | Settings::values.mouse_panning_x_sensitivity.GetValue() * default_stick_sensitivity; |
| 176 | SetAxis(identifier, mouse_axis_x, | 175 | const float y_sensitivity = |
| 177 | static_cast<float>(mouse_move.x) * x_sensitivity * 0.0012f); | 176 | Settings::values.mouse_panning_y_sensitivity.GetValue() * default_stick_sensitivity; |
| 178 | SetAxis(identifier, mouse_axis_y, | 177 | SetAxis(identifier, mouse_axis_x, static_cast<float>(mouse_move.x) * x_sensitivity); |
| 179 | static_cast<float>(-mouse_move.y) * y_sensitivity * 0.0012f); | 178 | SetAxis(identifier, mouse_axis_y, static_cast<float>(-mouse_move.y) * y_sensitivity); |
| 180 | 179 | ||
| 181 | last_motion_change = { | 180 | last_motion_change = { |
| 182 | static_cast<float>(-mouse_move.y) / 50.0f, | 181 | static_cast<float>(-mouse_move.y) * x_sensitivity, |
| 183 | static_cast<float>(-mouse_move.x) / 50.0f, | 182 | static_cast<float>(-mouse_move.x) * y_sensitivity, |
| 184 | last_motion_change.z, | 183 | last_motion_change.z, |
| 185 | }; | 184 | }; |
| 186 | } | 185 | } |
| @@ -220,7 +219,7 @@ void Mouse::ReleaseButton(MouseButton button) { | |||
| 220 | SetButton(real_mouse_identifier, static_cast<int>(button), false); | 219 | SetButton(real_mouse_identifier, static_cast<int>(button), false); |
| 221 | SetButton(touch_identifier, static_cast<int>(button), false); | 220 | SetButton(touch_identifier, static_cast<int>(button), false); |
| 222 | 221 | ||
| 223 | if (!Settings::values.mouse_panning) { | 222 | if (!IsMousePanningEnabled()) { |
| 224 | SetAxis(identifier, mouse_axis_x, 0); | 223 | SetAxis(identifier, mouse_axis_x, 0); |
| 225 | SetAxis(identifier, mouse_axis_y, 0); | 224 | SetAxis(identifier, mouse_axis_y, 0); |
| 226 | } | 225 | } |
| @@ -234,7 +233,7 @@ void Mouse::ReleaseButton(MouseButton button) { | |||
| 234 | void Mouse::MouseWheelChange(int x, int y) { | 233 | void Mouse::MouseWheelChange(int x, int y) { |
| 235 | wheel_position.x += x; | 234 | wheel_position.x += x; |
| 236 | wheel_position.y += y; | 235 | wheel_position.y += y; |
| 237 | last_motion_change.z += static_cast<f32>(y) / 100.0f; | 236 | last_motion_change.z += static_cast<f32>(y); |
| 238 | SetAxis(identifier, wheel_axis_x, static_cast<f32>(wheel_position.x)); | 237 | SetAxis(identifier, wheel_axis_x, static_cast<f32>(wheel_position.x)); |
| 239 | SetAxis(identifier, wheel_axis_y, static_cast<f32>(wheel_position.y)); | 238 | SetAxis(identifier, wheel_axis_y, static_cast<f32>(wheel_position.y)); |
| 240 | } | 239 | } |
| @@ -244,6 +243,11 @@ void Mouse::ReleaseAllButtons() { | |||
| 244 | button_pressed = false; | 243 | button_pressed = false; |
| 245 | } | 244 | } |
| 246 | 245 | ||
| 246 | bool Mouse::IsMousePanningEnabled() { | ||
| 247 | // Disable mouse panning when a real mouse is connected | ||
| 248 | return Settings::values.mouse_panning && !Settings::values.mouse_enabled; | ||
| 249 | } | ||
| 250 | |||
| 247 | std::vector<Common::ParamPackage> Mouse::GetInputDevices() const { | 251 | std::vector<Common::ParamPackage> Mouse::GetInputDevices() const { |
| 248 | std::vector<Common::ParamPackage> devices; | 252 | std::vector<Common::ParamPackage> devices; |
| 249 | devices.emplace_back(Common::ParamPackage{ | 253 | devices.emplace_back(Common::ParamPackage{ |
diff --git a/src/input_common/drivers/mouse.h b/src/input_common/drivers/mouse.h index 0e8edcce1..2b93a40b9 100644 --- a/src/input_common/drivers/mouse.h +++ b/src/input_common/drivers/mouse.h | |||
| @@ -99,6 +99,8 @@ private: | |||
| 99 | void UpdateStickInput(); | 99 | void UpdateStickInput(); |
| 100 | void UpdateMotionInput(); | 100 | void UpdateMotionInput(); |
| 101 | 101 | ||
| 102 | bool IsMousePanningEnabled(); | ||
| 103 | |||
| 102 | Common::Input::ButtonNames GetUIButtonName(const Common::ParamPackage& params) const; | 104 | Common::Input::ButtonNames GetUIButtonName(const Common::ParamPackage& params) const; |
| 103 | 105 | ||
| 104 | Common::Vec2<int> mouse_origin; | 106 | Common::Vec2<int> mouse_origin; |
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index a290d6ea7..f8598fd98 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp | |||
| @@ -174,8 +174,7 @@ void MaxwellDMA::CopyBlockLinearToPitch() { | |||
| 174 | src_operand.address = regs.offset_in; | 174 | src_operand.address = regs.offset_in; |
| 175 | 175 | ||
| 176 | DMA::BufferOperand dst_operand; | 176 | DMA::BufferOperand dst_operand; |
| 177 | u32 abs_pitch_out = std::abs(static_cast<s32>(regs.pitch_out)); | 177 | dst_operand.pitch = static_cast<u32>(std::abs(regs.pitch_out)); |
| 178 | dst_operand.pitch = abs_pitch_out; | ||
| 179 | dst_operand.width = regs.line_length_in; | 178 | dst_operand.width = regs.line_length_in; |
| 180 | dst_operand.height = regs.line_count; | 179 | dst_operand.height = regs.line_count; |
| 181 | dst_operand.address = regs.offset_out; | 180 | dst_operand.address = regs.offset_out; |
| @@ -222,7 +221,7 @@ void MaxwellDMA::CopyBlockLinearToPitch() { | |||
| 222 | const size_t src_size = | 221 | const size_t src_size = |
| 223 | CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth); | 222 | CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth); |
| 224 | 223 | ||
| 225 | const size_t dst_size = static_cast<size_t>(abs_pitch_out) * regs.line_count; | 224 | const size_t dst_size = dst_operand.pitch * regs.line_count; |
| 226 | read_buffer.resize_destructive(src_size); | 225 | read_buffer.resize_destructive(src_size); |
| 227 | write_buffer.resize_destructive(dst_size); | 226 | write_buffer.resize_destructive(dst_size); |
| 228 | 227 | ||
| @@ -231,7 +230,7 @@ void MaxwellDMA::CopyBlockLinearToPitch() { | |||
| 231 | 230 | ||
| 232 | UnswizzleSubrect(write_buffer, read_buffer, bytes_per_pixel, width, height, depth, x_offset, | 231 | UnswizzleSubrect(write_buffer, read_buffer, bytes_per_pixel, width, height, depth, x_offset, |
| 233 | src_params.origin.y, x_elements, regs.line_count, block_height, block_depth, | 232 | src_params.origin.y, x_elements, regs.line_count, block_height, block_depth, |
| 234 | abs_pitch_out); | 233 | dst_operand.pitch); |
| 235 | 234 | ||
| 236 | memory_manager.WriteBlockCached(regs.offset_out, write_buffer.data(), dst_size); | 235 | memory_manager.WriteBlockCached(regs.offset_out, write_buffer.data(), dst_size); |
| 237 | } | 236 | } |
diff --git a/src/video_core/host1x/codecs/codec.cpp b/src/video_core/host1x/codecs/codec.cpp index cd6a3a9b8..da07a556f 100644 --- a/src/video_core/host1x/codecs/codec.cpp +++ b/src/video_core/host1x/codecs/codec.cpp | |||
| @@ -290,7 +290,7 @@ void Codec::Decode() { | |||
| 290 | return vp9_decoder->GetFrameBytes(); | 290 | return vp9_decoder->GetFrameBytes(); |
| 291 | default: | 291 | default: |
| 292 | ASSERT(false); | 292 | ASSERT(false); |
| 293 | return std::vector<u8>{}; | 293 | return std::span<const u8>{}; |
| 294 | } | 294 | } |
| 295 | }(); | 295 | }(); |
| 296 | AVPacketPtr packet{av_packet_alloc(), AVPacketDeleter}; | 296 | AVPacketPtr packet{av_packet_alloc(), AVPacketDeleter}; |
diff --git a/src/video_core/host1x/codecs/h264.cpp b/src/video_core/host1x/codecs/h264.cpp index ce827eb6c..862904e39 100644 --- a/src/video_core/host1x/codecs/h264.cpp +++ b/src/video_core/host1x/codecs/h264.cpp | |||
| @@ -29,15 +29,15 @@ H264::H264(Host1x::Host1x& host1x_) : host1x{host1x_} {} | |||
| 29 | 29 | ||
| 30 | H264::~H264() = default; | 30 | H264::~H264() = default; |
| 31 | 31 | ||
| 32 | const std::vector<u8>& H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state, | 32 | std::span<const u8> H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state, |
| 33 | bool is_first_frame) { | 33 | bool is_first_frame) { |
| 34 | H264DecoderContext context; | 34 | H264DecoderContext context; |
| 35 | host1x.MemoryManager().ReadBlock(state.picture_info_offset, &context, | 35 | host1x.MemoryManager().ReadBlock(state.picture_info_offset, &context, |
| 36 | sizeof(H264DecoderContext)); | 36 | sizeof(H264DecoderContext)); |
| 37 | 37 | ||
| 38 | const s64 frame_number = context.h264_parameter_set.frame_number.Value(); | 38 | const s64 frame_number = context.h264_parameter_set.frame_number.Value(); |
| 39 | if (!is_first_frame && frame_number != 0) { | 39 | if (!is_first_frame && frame_number != 0) { |
| 40 | frame.resize(context.stream_len); | 40 | frame.resize_destructive(context.stream_len); |
| 41 | host1x.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.data(), frame.size()); | 41 | host1x.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.data(), frame.size()); |
| 42 | return frame; | 42 | return frame; |
| 43 | } | 43 | } |
| @@ -135,14 +135,14 @@ const std::vector<u8>& H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegist | |||
| 135 | for (s32 index = 0; index < 6; index++) { | 135 | for (s32 index = 0; index < 6; index++) { |
| 136 | writer.WriteBit(true); | 136 | writer.WriteBit(true); |
| 137 | std::span<const u8> matrix{context.weight_scale}; | 137 | std::span<const u8> matrix{context.weight_scale}; |
| 138 | writer.WriteScalingList(matrix, index * 16, 16); | 138 | writer.WriteScalingList(scan, matrix, index * 16, 16); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | if (context.h264_parameter_set.transform_8x8_mode_flag) { | 141 | if (context.h264_parameter_set.transform_8x8_mode_flag) { |
| 142 | for (s32 index = 0; index < 2; index++) { | 142 | for (s32 index = 0; index < 2; index++) { |
| 143 | writer.WriteBit(true); | 143 | writer.WriteBit(true); |
| 144 | std::span<const u8> matrix{context.weight_scale_8x8}; | 144 | std::span<const u8> matrix{context.weight_scale_8x8}; |
| 145 | writer.WriteScalingList(matrix, index * 64, 64); | 145 | writer.WriteScalingList(scan, matrix, index * 64, 64); |
| 146 | } | 146 | } |
| 147 | } | 147 | } |
| 148 | 148 | ||
| @@ -188,8 +188,8 @@ void H264BitWriter::WriteBit(bool state) { | |||
| 188 | WriteBits(state ? 1 : 0, 1); | 188 | WriteBits(state ? 1 : 0, 1); |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | void H264BitWriter::WriteScalingList(std::span<const u8> list, s32 start, s32 count) { | 191 | void H264BitWriter::WriteScalingList(Common::ScratchBuffer<u8>& scan, std::span<const u8> list, |
| 192 | static Common::ScratchBuffer<u8> scan{}; | 192 | s32 start, s32 count) { |
| 193 | scan.resize_destructive(count); | 193 | scan.resize_destructive(count); |
| 194 | if (count == 16) { | 194 | if (count == 16) { |
| 195 | std::memcpy(scan.data(), zig_zag_scan.data(), scan.size()); | 195 | std::memcpy(scan.data(), zig_zag_scan.data(), scan.size()); |
diff --git a/src/video_core/host1x/codecs/h264.h b/src/video_core/host1x/codecs/h264.h index 5cc86454e..d6b556322 100644 --- a/src/video_core/host1x/codecs/h264.h +++ b/src/video_core/host1x/codecs/h264.h | |||
| @@ -5,9 +5,11 @@ | |||
| 5 | 5 | ||
| 6 | #include <span> | 6 | #include <span> |
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | |||
| 8 | #include "common/bit_field.h" | 9 | #include "common/bit_field.h" |
| 9 | #include "common/common_funcs.h" | 10 | #include "common/common_funcs.h" |
| 10 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "common/scratch_buffer.h" | ||
| 11 | #include "video_core/host1x/nvdec_common.h" | 13 | #include "video_core/host1x/nvdec_common.h" |
| 12 | 14 | ||
| 13 | namespace Tegra { | 15 | namespace Tegra { |
| @@ -37,7 +39,8 @@ public: | |||
| 37 | 39 | ||
| 38 | /// Based on section 7.3.2.1.1.1 and Table 7-4 in the H.264 specification | 40 | /// Based on section 7.3.2.1.1.1 and Table 7-4 in the H.264 specification |
| 39 | /// Writes the scaling matrices of the sream | 41 | /// Writes the scaling matrices of the sream |
| 40 | void WriteScalingList(std::span<const u8> list, s32 start, s32 count); | 42 | void WriteScalingList(Common::ScratchBuffer<u8>& scan, std::span<const u8> list, s32 start, |
| 43 | s32 count); | ||
| 41 | 44 | ||
| 42 | /// Return the bitstream as a vector. | 45 | /// Return the bitstream as a vector. |
| 43 | [[nodiscard]] std::vector<u8>& GetByteArray(); | 46 | [[nodiscard]] std::vector<u8>& GetByteArray(); |
| @@ -63,11 +66,12 @@ public: | |||
| 63 | ~H264(); | 66 | ~H264(); |
| 64 | 67 | ||
| 65 | /// Compose the H264 frame for FFmpeg decoding | 68 | /// Compose the H264 frame for FFmpeg decoding |
| 66 | [[nodiscard]] const std::vector<u8>& ComposeFrame( | 69 | [[nodiscard]] std::span<const u8> ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state, |
| 67 | const Host1x::NvdecCommon::NvdecRegisters& state, bool is_first_frame = false); | 70 | bool is_first_frame = false); |
| 68 | 71 | ||
| 69 | private: | 72 | private: |
| 70 | std::vector<u8> frame; | 73 | Common::ScratchBuffer<u8> frame; |
| 74 | Common::ScratchBuffer<u8> scan; | ||
| 71 | Host1x::Host1x& host1x; | 75 | Host1x::Host1x& host1x; |
| 72 | 76 | ||
| 73 | struct H264ParameterSet { | 77 | struct H264ParameterSet { |
diff --git a/src/video_core/host1x/codecs/vp8.cpp b/src/video_core/host1x/codecs/vp8.cpp index 28fb12cb8..ee6392ff9 100644 --- a/src/video_core/host1x/codecs/vp8.cpp +++ b/src/video_core/host1x/codecs/vp8.cpp | |||
| @@ -12,7 +12,7 @@ VP8::VP8(Host1x::Host1x& host1x_) : host1x{host1x_} {} | |||
| 12 | 12 | ||
| 13 | VP8::~VP8() = default; | 13 | VP8::~VP8() = default; |
| 14 | 14 | ||
| 15 | const std::vector<u8>& VP8::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state) { | 15 | std::span<const u8> VP8::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state) { |
| 16 | VP8PictureInfo info; | 16 | VP8PictureInfo info; |
| 17 | host1x.MemoryManager().ReadBlock(state.picture_info_offset, &info, sizeof(VP8PictureInfo)); | 17 | host1x.MemoryManager().ReadBlock(state.picture_info_offset, &info, sizeof(VP8PictureInfo)); |
| 18 | 18 | ||
diff --git a/src/video_core/host1x/codecs/vp8.h b/src/video_core/host1x/codecs/vp8.h index 5bf07ecab..7926b73f3 100644 --- a/src/video_core/host1x/codecs/vp8.h +++ b/src/video_core/host1x/codecs/vp8.h | |||
| @@ -4,10 +4,11 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <vector> | 7 | #include <span> |
| 8 | 8 | ||
| 9 | #include "common/common_funcs.h" | 9 | #include "common/common_funcs.h" |
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "common/scratch_buffer.h" | ||
| 11 | #include "video_core/host1x/nvdec_common.h" | 12 | #include "video_core/host1x/nvdec_common.h" |
| 12 | 13 | ||
| 13 | namespace Tegra { | 14 | namespace Tegra { |
| @@ -24,11 +25,11 @@ public: | |||
| 24 | ~VP8(); | 25 | ~VP8(); |
| 25 | 26 | ||
| 26 | /// Compose the VP8 frame for FFmpeg decoding | 27 | /// Compose the VP8 frame for FFmpeg decoding |
| 27 | [[nodiscard]] const std::vector<u8>& ComposeFrame( | 28 | [[nodiscard]] std::span<const u8> ComposeFrame( |
| 28 | const Host1x::NvdecCommon::NvdecRegisters& state); | 29 | const Host1x::NvdecCommon::NvdecRegisters& state); |
| 29 | 30 | ||
| 30 | private: | 31 | private: |
| 31 | std::vector<u8> frame; | 32 | Common::ScratchBuffer<u8> frame; |
| 32 | Host1x::Host1x& host1x; | 33 | Host1x::Host1x& host1x; |
| 33 | 34 | ||
| 34 | struct VP8PictureInfo { | 35 | struct VP8PictureInfo { |
diff --git a/src/video_core/host1x/codecs/vp9.cpp b/src/video_core/host1x/codecs/vp9.cpp index cf40c9012..306c3d0e8 100644 --- a/src/video_core/host1x/codecs/vp9.cpp +++ b/src/video_core/host1x/codecs/vp9.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <algorithm> // for std::copy | 4 | #include <algorithm> // for std::copy |
| 5 | #include <numeric> | 5 | #include <numeric> |
| 6 | |||
| 6 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 7 | #include "video_core/host1x/codecs/vp9.h" | 8 | #include "video_core/host1x/codecs/vp9.h" |
| 8 | #include "video_core/host1x/host1x.h" | 9 | #include "video_core/host1x/host1x.h" |
diff --git a/src/video_core/host1x/codecs/vp9.h b/src/video_core/host1x/codecs/vp9.h index d4083e8d3..f1ed19508 100644 --- a/src/video_core/host1x/codecs/vp9.h +++ b/src/video_core/host1x/codecs/vp9.h | |||
| @@ -4,9 +4,11 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <span> | ||
| 7 | #include <vector> | 8 | #include <vector> |
| 8 | 9 | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "common/scratch_buffer.h" | ||
| 10 | #include "common/stream.h" | 12 | #include "common/stream.h" |
| 11 | #include "video_core/host1x/codecs/vp9_types.h" | 13 | #include "video_core/host1x/codecs/vp9_types.h" |
| 12 | #include "video_core/host1x/nvdec_common.h" | 14 | #include "video_core/host1x/nvdec_common.h" |
| @@ -128,8 +130,8 @@ public: | |||
| 128 | return !current_frame_info.show_frame; | 130 | return !current_frame_info.show_frame; |
| 129 | } | 131 | } |
| 130 | 132 | ||
| 131 | /// Returns a const reference to the composed frame data. | 133 | /// Returns a const span to the composed frame data. |
| 132 | [[nodiscard]] const std::vector<u8>& GetFrameBytes() const { | 134 | [[nodiscard]] std::span<const u8> GetFrameBytes() const { |
| 133 | return frame; | 135 | return frame; |
| 134 | } | 136 | } |
| 135 | 137 | ||
| @@ -181,7 +183,7 @@ private: | |||
| 181 | [[nodiscard]] VpxBitStreamWriter ComposeUncompressedHeader(); | 183 | [[nodiscard]] VpxBitStreamWriter ComposeUncompressedHeader(); |
| 182 | 184 | ||
| 183 | Host1x::Host1x& host1x; | 185 | Host1x::Host1x& host1x; |
| 184 | std::vector<u8> frame; | 186 | Common::ScratchBuffer<u8> frame; |
| 185 | 187 | ||
| 186 | std::array<s8, 4> loop_filter_ref_deltas{}; | 188 | std::array<s8, 4> loop_filter_ref_deltas{}; |
| 187 | std::array<s8, 2> loop_filter_mode_deltas{}; | 189 | std::array<s8, 2> loop_filter_mode_deltas{}; |
diff --git a/src/video_core/host1x/codecs/vp9_types.h b/src/video_core/host1x/codecs/vp9_types.h index adad8ed7e..cc9b25690 100644 --- a/src/video_core/host1x/codecs/vp9_types.h +++ b/src/video_core/host1x/codecs/vp9_types.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | |||
| 8 | #include "common/common_funcs.h" | 9 | #include "common/common_funcs.h" |
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | 11 | ||
diff --git a/src/video_core/vulkan_common/vulkan_instance.cpp b/src/video_core/vulkan_common/vulkan_instance.cpp index 7624a9b32..6a294c1da 100644 --- a/src/video_core/vulkan_common/vulkan_instance.cpp +++ b/src/video_core/vulkan_common/vulkan_instance.cpp | |||
| @@ -19,11 +19,9 @@ | |||
| 19 | #include <windows.h> | 19 | #include <windows.h> |
| 20 | // ensure include order | 20 | // ensure include order |
| 21 | #include <vulkan/vulkan_win32.h> | 21 | #include <vulkan/vulkan_win32.h> |
| 22 | #elif defined(__APPLE__) | ||
| 23 | #include <vulkan/vulkan_macos.h> | ||
| 24 | #elif defined(__ANDROID__) | 22 | #elif defined(__ANDROID__) |
| 25 | #include <vulkan/vulkan_android.h> | 23 | #include <vulkan/vulkan_android.h> |
| 26 | #else | 24 | #elif !defined(__APPLE__) |
| 27 | #include <X11/Xlib.h> | 25 | #include <X11/Xlib.h> |
| 28 | #include <vulkan/vulkan_wayland.h> | 26 | #include <vulkan/vulkan_wayland.h> |
| 29 | #include <vulkan/vulkan_xlib.h> | 27 | #include <vulkan/vulkan_xlib.h> |
| @@ -68,7 +66,7 @@ namespace { | |||
| 68 | break; | 66 | break; |
| 69 | #elif defined(__APPLE__) | 67 | #elif defined(__APPLE__) |
| 70 | case Core::Frontend::WindowSystemType::Cocoa: | 68 | case Core::Frontend::WindowSystemType::Cocoa: |
| 71 | extensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME); | 69 | extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); |
| 72 | break; | 70 | break; |
| 73 | #elif defined(__ANDROID__) | 71 | #elif defined(__ANDROID__) |
| 74 | case Core::Frontend::WindowSystemType::Android: | 72 | case Core::Frontend::WindowSystemType::Android: |
diff --git a/src/video_core/vulkan_common/vulkan_surface.cpp b/src/video_core/vulkan_common/vulkan_surface.cpp index c34599365..cfea4cd7b 100644 --- a/src/video_core/vulkan_common/vulkan_surface.cpp +++ b/src/video_core/vulkan_common/vulkan_surface.cpp | |||
| @@ -11,11 +11,9 @@ | |||
| 11 | #include <windows.h> | 11 | #include <windows.h> |
| 12 | // ensure include order | 12 | // ensure include order |
| 13 | #include <vulkan/vulkan_win32.h> | 13 | #include <vulkan/vulkan_win32.h> |
| 14 | #elif defined(__APPLE__) | ||
| 15 | #include <vulkan/vulkan_macos.h> | ||
| 16 | #elif defined(__ANDROID__) | 14 | #elif defined(__ANDROID__) |
| 17 | #include <vulkan/vulkan_android.h> | 15 | #include <vulkan/vulkan_android.h> |
| 18 | #else | 16 | #elif !defined(__APPLE__) |
| 19 | #include <X11/Xlib.h> | 17 | #include <X11/Xlib.h> |
| 20 | #include <vulkan/vulkan_wayland.h> | 18 | #include <vulkan/vulkan_wayland.h> |
| 21 | #include <vulkan/vulkan_xlib.h> | 19 | #include <vulkan/vulkan_xlib.h> |
| @@ -44,12 +42,13 @@ vk::SurfaceKHR CreateSurface( | |||
| 44 | } | 42 | } |
| 45 | #elif defined(__APPLE__) | 43 | #elif defined(__APPLE__) |
| 46 | if (window_info.type == Core::Frontend::WindowSystemType::Cocoa) { | 44 | if (window_info.type == Core::Frontend::WindowSystemType::Cocoa) { |
| 47 | const VkMacOSSurfaceCreateInfoMVK mvk_ci{VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, | 45 | const VkMetalSurfaceCreateInfoEXT macos_ci = { |
| 48 | nullptr, 0, window_info.render_surface}; | 46 | .pLayer = static_cast<const CAMetalLayer*>(window_info.render_surface), |
| 49 | const auto vkCreateMacOSSurfaceMVK = reinterpret_cast<PFN_vkCreateMacOSSurfaceMVK>( | 47 | }; |
| 50 | dld.vkGetInstanceProcAddr(*instance, "vkCreateMacOSSurfaceMVK")); | 48 | const auto vkCreateMetalSurfaceEXT = reinterpret_cast<PFN_vkCreateMetalSurfaceEXT>( |
| 51 | if (!vkCreateMacOSSurfaceMVK || | 49 | dld.vkGetInstanceProcAddr(*instance, "vkCreateMetalSurfaceEXT")); |
| 52 | vkCreateMacOSSurfaceMVK(*instance, &mvk_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { | 50 | if (!vkCreateMetalSurfaceEXT || |
| 51 | vkCreateMetalSurfaceEXT(*instance, &macos_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { | ||
| 53 | LOG_ERROR(Render_Vulkan, "Failed to initialize Metal surface"); | 52 | LOG_ERROR(Render_Vulkan, "Failed to initialize Metal surface"); |
| 54 | throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); | 53 | throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); |
| 55 | } | 54 | } |
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index b5e70fcd4..32bd75ad8 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #define VK_NO_PROTOTYPES | 15 | #define VK_NO_PROTOTYPES |
| 16 | #ifdef _WIN32 | 16 | #ifdef _WIN32 |
| 17 | #define VK_USE_PLATFORM_WIN32_KHR | 17 | #define VK_USE_PLATFORM_WIN32_KHR |
| 18 | #elif defined(__APPLE__) | ||
| 19 | #define VK_USE_PLATFORM_METAL_EXT | ||
| 18 | #endif | 20 | #endif |
| 19 | #include <vulkan/vulkan.h> | 21 | #include <vulkan/vulkan.h> |
| 20 | 22 | ||
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 29467d380..195d3556c 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -503,8 +503,7 @@ void Config::ReadMousePanningValues() { | |||
| 503 | ReadBasicSetting(Settings::values.mouse_panning); | 503 | ReadBasicSetting(Settings::values.mouse_panning); |
| 504 | ReadBasicSetting(Settings::values.mouse_panning_x_sensitivity); | 504 | ReadBasicSetting(Settings::values.mouse_panning_x_sensitivity); |
| 505 | ReadBasicSetting(Settings::values.mouse_panning_y_sensitivity); | 505 | ReadBasicSetting(Settings::values.mouse_panning_y_sensitivity); |
| 506 | ReadBasicSetting(Settings::values.mouse_panning_deadzone_x_counterweight); | 506 | ReadBasicSetting(Settings::values.mouse_panning_deadzone_counterweight); |
| 507 | ReadBasicSetting(Settings::values.mouse_panning_deadzone_y_counterweight); | ||
| 508 | ReadBasicSetting(Settings::values.mouse_panning_decay_strength); | 507 | ReadBasicSetting(Settings::values.mouse_panning_decay_strength); |
| 509 | ReadBasicSetting(Settings::values.mouse_panning_min_decay); | 508 | ReadBasicSetting(Settings::values.mouse_panning_min_decay); |
| 510 | } | 509 | } |
| @@ -1122,8 +1121,7 @@ void Config::SaveMousePanningValues() { | |||
| 1122 | // Don't overwrite values.mouse_panning | 1121 | // Don't overwrite values.mouse_panning |
| 1123 | WriteBasicSetting(Settings::values.mouse_panning_x_sensitivity); | 1122 | WriteBasicSetting(Settings::values.mouse_panning_x_sensitivity); |
| 1124 | WriteBasicSetting(Settings::values.mouse_panning_y_sensitivity); | 1123 | WriteBasicSetting(Settings::values.mouse_panning_y_sensitivity); |
| 1125 | WriteBasicSetting(Settings::values.mouse_panning_deadzone_x_counterweight); | 1124 | WriteBasicSetting(Settings::values.mouse_panning_deadzone_counterweight); |
| 1126 | WriteBasicSetting(Settings::values.mouse_panning_deadzone_y_counterweight); | ||
| 1127 | WriteBasicSetting(Settings::values.mouse_panning_decay_strength); | 1125 | WriteBasicSetting(Settings::values.mouse_panning_decay_strength); |
| 1128 | WriteBasicSetting(Settings::values.mouse_panning_min_decay); | 1126 | WriteBasicSetting(Settings::values.mouse_panning_min_decay); |
| 1129 | } | 1127 | } |
diff --git a/src/yuzu/configuration/configure_input_player.ui b/src/yuzu/configuration/configure_input_player.ui index 43f6c7b50..611a79477 100644 --- a/src/yuzu/configuration/configure_input_player.ui +++ b/src/yuzu/configuration/configure_input_player.ui | |||
| @@ -3105,21 +3105,6 @@ | |||
| 3105 | </property> | 3105 | </property> |
| 3106 | <item> | 3106 | <item> |
| 3107 | <widget class="QPushButton" name="mousePanningButton"> | 3107 | <widget class="QPushButton" name="mousePanningButton"> |
| 3108 | <property name="minimumSize"> | ||
| 3109 | <size> | ||
| 3110 | <width>68</width> | ||
| 3111 | <height>0</height> | ||
| 3112 | </size> | ||
| 3113 | </property> | ||
| 3114 | <property name="maximumSize"> | ||
| 3115 | <size> | ||
| 3116 | <width>68</width> | ||
| 3117 | <height>16777215</height> | ||
| 3118 | </size> | ||
| 3119 | </property> | ||
| 3120 | <property name="styleSheet"> | ||
| 3121 | <string notr="true">min-width: 68px;</string> | ||
| 3122 | </property> | ||
| 3123 | <property name="text"> | 3108 | <property name="text"> |
| 3124 | <string>Configure</string> | 3109 | <string>Configure</string> |
| 3125 | </property> | 3110 | </property> |
diff --git a/src/yuzu/configuration/configure_mouse_panning.cpp b/src/yuzu/configuration/configure_mouse_panning.cpp index f183d2740..e37c546b0 100644 --- a/src/yuzu/configuration/configure_mouse_panning.cpp +++ b/src/yuzu/configuration/configure_mouse_panning.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <QCloseEvent> | 4 | #include <QCloseEvent> |
| 5 | #include <QMessageBox> | ||
| 5 | 6 | ||
| 6 | #include "common/settings.h" | 7 | #include "common/settings.h" |
| 7 | #include "ui_configure_mouse_panning.h" | 8 | #include "ui_configure_mouse_panning.h" |
| @@ -27,31 +28,34 @@ void ConfigureMousePanning::SetConfiguration(float right_stick_deadzone, float r | |||
| 27 | ui->enable->setChecked(Settings::values.mouse_panning.GetValue()); | 28 | ui->enable->setChecked(Settings::values.mouse_panning.GetValue()); |
| 28 | ui->x_sensitivity->setValue(Settings::values.mouse_panning_x_sensitivity.GetValue()); | 29 | ui->x_sensitivity->setValue(Settings::values.mouse_panning_x_sensitivity.GetValue()); |
| 29 | ui->y_sensitivity->setValue(Settings::values.mouse_panning_y_sensitivity.GetValue()); | 30 | ui->y_sensitivity->setValue(Settings::values.mouse_panning_y_sensitivity.GetValue()); |
| 30 | ui->deadzone_x_counterweight->setValue( | 31 | ui->deadzone_counterweight->setValue( |
| 31 | Settings::values.mouse_panning_deadzone_x_counterweight.GetValue()); | 32 | Settings::values.mouse_panning_deadzone_counterweight.GetValue()); |
| 32 | ui->deadzone_y_counterweight->setValue( | ||
| 33 | Settings::values.mouse_panning_deadzone_y_counterweight.GetValue()); | ||
| 34 | ui->decay_strength->setValue(Settings::values.mouse_panning_decay_strength.GetValue()); | 33 | ui->decay_strength->setValue(Settings::values.mouse_panning_decay_strength.GetValue()); |
| 35 | ui->min_decay->setValue(Settings::values.mouse_panning_min_decay.GetValue()); | 34 | ui->min_decay->setValue(Settings::values.mouse_panning_min_decay.GetValue()); |
| 36 | 35 | ||
| 37 | if (right_stick_deadzone > 0.0f || right_stick_range != 1.0f) { | 36 | if (right_stick_deadzone > 0.0f || right_stick_range != 1.0f) { |
| 38 | ui->warning_label->setText(QString::fromStdString( | 37 | const QString right_stick_deadzone_str = |
| 39 | "Mouse panning works better with a deadzone of 0% and a range of 100%.\n" | 38 | QString::fromStdString(std::to_string(static_cast<int>(right_stick_deadzone * 100.0f))); |
| 40 | "Current values are " + | 39 | const QString right_stick_range_str = |
| 41 | std::to_string(static_cast<int>(right_stick_deadzone * 100.0f)) + "% and " + | 40 | QString::fromStdString(std::to_string(static_cast<int>(right_stick_range * 100.0f))); |
| 42 | std::to_string(static_cast<int>(right_stick_range * 100.0f)) + "% respectively.")); | 41 | |
| 43 | } else { | 42 | ui->warning_label->setText( |
| 44 | ui->warning_label->hide(); | 43 | tr("Mouse panning works better with a deadzone of 0% and a range of 100%.\nCurrent " |
| 44 | "values are %1% and %2% respectively.") | ||
| 45 | .arg(right_stick_deadzone_str, right_stick_range_str)); | ||
| 46 | } | ||
| 47 | |||
| 48 | if (Settings::values.mouse_enabled) { | ||
| 49 | ui->warning_label->setText( | ||
| 50 | tr("Emulated mouse is enabled. This is incompatible with mouse panning.")); | ||
| 45 | } | 51 | } |
| 46 | } | 52 | } |
| 47 | 53 | ||
| 48 | void ConfigureMousePanning::SetDefaultConfiguration() { | 54 | void ConfigureMousePanning::SetDefaultConfiguration() { |
| 49 | ui->x_sensitivity->setValue(Settings::values.mouse_panning_x_sensitivity.GetDefault()); | 55 | ui->x_sensitivity->setValue(Settings::values.mouse_panning_x_sensitivity.GetDefault()); |
| 50 | ui->y_sensitivity->setValue(Settings::values.mouse_panning_y_sensitivity.GetDefault()); | 56 | ui->y_sensitivity->setValue(Settings::values.mouse_panning_y_sensitivity.GetDefault()); |
| 51 | ui->deadzone_x_counterweight->setValue( | 57 | ui->deadzone_counterweight->setValue( |
| 52 | Settings::values.mouse_panning_deadzone_x_counterweight.GetDefault()); | 58 | Settings::values.mouse_panning_deadzone_counterweight.GetDefault()); |
| 53 | ui->deadzone_y_counterweight->setValue( | ||
| 54 | Settings::values.mouse_panning_deadzone_y_counterweight.GetDefault()); | ||
| 55 | ui->decay_strength->setValue(Settings::values.mouse_panning_decay_strength.GetDefault()); | 59 | ui->decay_strength->setValue(Settings::values.mouse_panning_decay_strength.GetDefault()); |
| 56 | ui->min_decay->setValue(Settings::values.mouse_panning_min_decay.GetDefault()); | 60 | ui->min_decay->setValue(Settings::values.mouse_panning_min_decay.GetDefault()); |
| 57 | } | 61 | } |
| @@ -68,12 +72,19 @@ void ConfigureMousePanning::ApplyConfiguration() { | |||
| 68 | Settings::values.mouse_panning = ui->enable->isChecked(); | 72 | Settings::values.mouse_panning = ui->enable->isChecked(); |
| 69 | Settings::values.mouse_panning_x_sensitivity = static_cast<float>(ui->x_sensitivity->value()); | 73 | Settings::values.mouse_panning_x_sensitivity = static_cast<float>(ui->x_sensitivity->value()); |
| 70 | Settings::values.mouse_panning_y_sensitivity = static_cast<float>(ui->y_sensitivity->value()); | 74 | Settings::values.mouse_panning_y_sensitivity = static_cast<float>(ui->y_sensitivity->value()); |
| 71 | Settings::values.mouse_panning_deadzone_x_counterweight = | 75 | Settings::values.mouse_panning_deadzone_counterweight = |
| 72 | static_cast<float>(ui->deadzone_x_counterweight->value()); | 76 | static_cast<float>(ui->deadzone_counterweight->value()); |
| 73 | Settings::values.mouse_panning_deadzone_y_counterweight = | ||
| 74 | static_cast<float>(ui->deadzone_y_counterweight->value()); | ||
| 75 | Settings::values.mouse_panning_decay_strength = static_cast<float>(ui->decay_strength->value()); | 77 | Settings::values.mouse_panning_decay_strength = static_cast<float>(ui->decay_strength->value()); |
| 76 | Settings::values.mouse_panning_min_decay = static_cast<float>(ui->min_decay->value()); | 78 | Settings::values.mouse_panning_min_decay = static_cast<float>(ui->min_decay->value()); |
| 77 | 79 | ||
| 80 | if (Settings::values.mouse_enabled && Settings::values.mouse_panning) { | ||
| 81 | Settings::values.mouse_panning = false; | ||
| 82 | QMessageBox::critical( | ||
| 83 | this, tr("Emulated mouse is enabled"), | ||
| 84 | tr("Real mouse input and mouse panning are incompatible. Please disable the " | ||
| 85 | "emulated mouse in input advanced settings to allow mouse panning.")); | ||
| 86 | return; | ||
| 87 | } | ||
| 88 | |||
| 78 | accept(); | 89 | accept(); |
| 79 | } | 90 | } |
diff --git a/src/yuzu/configuration/configure_mouse_panning.ui b/src/yuzu/configuration/configure_mouse_panning.ui index 75795b727..84fb7ee80 100644 --- a/src/yuzu/configuration/configure_mouse_panning.ui +++ b/src/yuzu/configuration/configure_mouse_panning.ui | |||
| @@ -9,10 +9,10 @@ | |||
| 9 | <item> | 9 | <item> |
| 10 | <widget class="QCheckBox" name="enable"> | 10 | <widget class="QCheckBox" name="enable"> |
| 11 | <property name="text"> | 11 | <property name="text"> |
| 12 | <string>Enable</string> | 12 | <string>Enable mouse panning</string> |
| 13 | </property> | 13 | </property> |
| 14 | <property name="toolTip"> | 14 | <property name="toolTip"> |
| 15 | <string>Can be toggled via a hotkey</string> | 15 | <string>Can be toggled via a hotkey. Default hotkey is Ctrl + F9</string> |
| 16 | </property> | 16 | </property> |
| 17 | </widget> | 17 | </widget> |
| 18 | </item> | 18 | </item> |
| @@ -89,40 +89,14 @@ | |||
| 89 | </property> | 89 | </property> |
| 90 | <layout class="QGridLayout"> | 90 | <layout class="QGridLayout"> |
| 91 | <item row="0" column="0"> | 91 | <item row="0" column="0"> |
| 92 | <widget class="QLabel" name="deadzone_x_counterweight_label"> | 92 | <widget class="QLabel" name="deadzone_counterweight_label"> |
| 93 | <property name="text"> | 93 | <property name="text"> |
| 94 | <string>Horizontal</string> | 94 | <string>Deadzone</string> |
| 95 | </property> | 95 | </property> |
| 96 | </widget> | 96 | </widget> |
| 97 | </item> | 97 | </item> |
| 98 | <item row="0" column="1"> | 98 | <item row="0" column="1"> |
| 99 | <widget class="QSpinBox" name="deadzone_x_counterweight"> | 99 | <widget class="QSpinBox" name="deadzone_counterweight"> |
| 100 | <property name="alignment"> | ||
| 101 | <set>Qt::AlignCenter</set> | ||
| 102 | </property> | ||
| 103 | <property name="suffix"> | ||
| 104 | <string>%</string> | ||
| 105 | </property> | ||
| 106 | <property name="minimum"> | ||
| 107 | <number>0</number> | ||
| 108 | </property> | ||
| 109 | <property name="maximum"> | ||
| 110 | <number>100</number> | ||
| 111 | </property> | ||
| 112 | <property name="value"> | ||
| 113 | <number>0</number> | ||
| 114 | </property> | ||
| 115 | </widget> | ||
| 116 | </item> | ||
| 117 | <item row="1" column="0"> | ||
| 118 | <widget class="QLabel" name="deadzone_y_counterweight_label"> | ||
| 119 | <property name="text"> | ||
| 120 | <string>Vertical</string> | ||
| 121 | </property> | ||
| 122 | </widget> | ||
| 123 | </item> | ||
| 124 | <item row="1" column="1"> | ||
| 125 | <widget class="QSpinBox" name="deadzone_y_counterweight"> | ||
| 126 | <property name="alignment"> | 100 | <property name="alignment"> |
| 127 | <set>Qt::AlignCenter</set> | 101 | <set>Qt::AlignCenter</set> |
| 128 | </property> | 102 | </property> |
diff --git a/src/yuzu/qt_common.cpp b/src/yuzu/qt_common.cpp index 5d0fd7674..413402165 100644 --- a/src/yuzu/qt_common.cpp +++ b/src/yuzu/qt_common.cpp | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | 10 | ||
| 11 | #if !defined(WIN32) && !defined(__APPLE__) | 11 | #if !defined(WIN32) && !defined(__APPLE__) |
| 12 | #include <qpa/qplatformnativeinterface.h> | 12 | #include <qpa/qplatformnativeinterface.h> |
| 13 | #elif defined(__APPLE__) | ||
| 14 | #include <objc/message.h> | ||
| 13 | #endif | 15 | #endif |
| 14 | 16 | ||
| 15 | namespace QtCommon { | 17 | namespace QtCommon { |
| @@ -37,9 +39,12 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) | |||
| 37 | Core::Frontend::EmuWindow::WindowSystemInfo wsi; | 39 | Core::Frontend::EmuWindow::WindowSystemInfo wsi; |
| 38 | wsi.type = GetWindowSystemType(); | 40 | wsi.type = GetWindowSystemType(); |
| 39 | 41 | ||
| 42 | #if defined(WIN32) | ||
| 40 | // Our Win32 Qt external doesn't have the private API. | 43 | // Our Win32 Qt external doesn't have the private API. |
| 41 | #if defined(WIN32) || defined(__APPLE__) | 44 | wsi.render_surface = reinterpret_cast<void*>(window->winId()); |
| 42 | wsi.render_surface = window ? reinterpret_cast<void*>(window->winId()) : nullptr; | 45 | #elif defined(__APPLE__) |
| 46 | wsi.render_surface = reinterpret_cast<void* (*)(id, SEL)>(objc_msgSend)( | ||
| 47 | reinterpret_cast<id>(window->winId()), sel_registerName("layer")); | ||
| 43 | #else | 48 | #else |
| 44 | QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface(); | 49 | QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface(); |
| 45 | wsi.display_connection = pni->nativeResourceForWindow("display", window); | 50 | wsi.display_connection = pni->nativeResourceForWindow("display", window); |
diff --git a/src/yuzu/vk_device_info.cpp b/src/yuzu/vk_device_info.cpp index 7c26a3dc7..e1a0e6a2a 100644 --- a/src/yuzu/vk_device_info.cpp +++ b/src/yuzu/vk_device_info.cpp | |||
| @@ -26,7 +26,10 @@ Record::~Record() = default; | |||
| 26 | void PopulateRecords(std::vector<Record>& records, QWindow* window) try { | 26 | void PopulateRecords(std::vector<Record>& records, QWindow* window) try { |
| 27 | using namespace Vulkan; | 27 | using namespace Vulkan; |
| 28 | 28 | ||
| 29 | auto wsi = QtCommon::GetWindowSystemInfo(window); | 29 | // Create a test window with a Vulkan surface type for checking present modes. |
| 30 | QWindow test_window(window); | ||
| 31 | test_window.setSurfaceType(QWindow::VulkanSurface); | ||
| 32 | auto wsi = QtCommon::GetWindowSystemInfo(&test_window); | ||
| 30 | 33 | ||
| 31 | vk::InstanceDispatch dld; | 34 | vk::InstanceDispatch dld; |
| 32 | const auto library = OpenLibrary(); | 35 | const auto library = OpenLibrary(); |