diff options
Diffstat (limited to 'src')
71 files changed, 1659 insertions, 1049 deletions
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index 68c67507b..d1d177b51 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt | |||
| @@ -51,6 +51,8 @@ if (NOT MSVC) | |||
| 51 | -Werror=implicit-fallthrough | 51 | -Werror=implicit-fallthrough |
| 52 | -Werror=reorder | 52 | -Werror=reorder |
| 53 | -Werror=sign-compare | 53 | -Werror=sign-compare |
| 54 | -Werror=shadow | ||
| 55 | -Werror=unused-parameter | ||
| 54 | -Werror=unused-variable | 56 | -Werror=unused-variable |
| 55 | 57 | ||
| 56 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> | 58 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> |
diff --git a/src/audio_core/algorithm/filter.cpp b/src/audio_core/algorithm/filter.cpp index f34a5b9f3..01b8dff6b 100644 --- a/src/audio_core/algorithm/filter.cpp +++ b/src/audio_core/algorithm/filter.cpp | |||
| @@ -31,8 +31,8 @@ Filter Filter::LowPass(double cutoff, double Q) { | |||
| 31 | 31 | ||
| 32 | Filter::Filter() : Filter(1.0, 0.0, 0.0, 1.0, 0.0, 0.0) {} | 32 | Filter::Filter() : Filter(1.0, 0.0, 0.0, 1.0, 0.0, 0.0) {} |
| 33 | 33 | ||
| 34 | Filter::Filter(double a0, double a1, double a2, double b0, double b1, double b2) | 34 | Filter::Filter(double a0_, double a1_, double a2_, double b0_, double b1_, double b2_) |
| 35 | : a1(a1 / a0), a2(a2 / a0), b0(b0 / a0), b1(b1 / a0), b2(b2 / a0) {} | 35 | : a1(a1_ / a0_), a2(a2_ / a0_), b0(b0_ / a0_), b1(b1_ / a0_), b2(b2_ / a0_) {} |
| 36 | 36 | ||
| 37 | void Filter::Process(std::vector<s16>& signal) { | 37 | void Filter::Process(std::vector<s16>& signal) { |
| 38 | const std::size_t num_frames = signal.size() / 2; | 38 | const std::size_t num_frames = signal.size() / 2; |
| @@ -69,7 +69,7 @@ CascadingFilter CascadingFilter::LowPass(double cutoff, std::size_t cascade_size | |||
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | CascadingFilter::CascadingFilter() = default; | 71 | CascadingFilter::CascadingFilter() = default; |
| 72 | CascadingFilter::CascadingFilter(std::vector<Filter> filters) : filters(std::move(filters)) {} | 72 | CascadingFilter::CascadingFilter(std::vector<Filter> filters_) : filters(std::move(filters_)) {} |
| 73 | 73 | ||
| 74 | void CascadingFilter::Process(std::vector<s16>& signal) { | 74 | void CascadingFilter::Process(std::vector<s16>& signal) { |
| 75 | for (auto& filter : filters) { | 75 | for (auto& filter : filters) { |
diff --git a/src/audio_core/algorithm/filter.h b/src/audio_core/algorithm/filter.h index 3546d149b..a291fe79b 100644 --- a/src/audio_core/algorithm/filter.h +++ b/src/audio_core/algorithm/filter.h | |||
| @@ -25,7 +25,7 @@ public: | |||
| 25 | /// Passthrough filter. | 25 | /// Passthrough filter. |
| 26 | Filter(); | 26 | Filter(); |
| 27 | 27 | ||
| 28 | Filter(double a0, double a1, double a2, double b0, double b1, double b2); | 28 | Filter(double a0_, double a1_, double a2_, double b0_, double b1_, double b2_); |
| 29 | 29 | ||
| 30 | void Process(std::vector<s16>& signal); | 30 | void Process(std::vector<s16>& signal); |
| 31 | 31 | ||
| @@ -51,7 +51,7 @@ public: | |||
| 51 | /// Passthrough. | 51 | /// Passthrough. |
| 52 | CascadingFilter(); | 52 | CascadingFilter(); |
| 53 | 53 | ||
| 54 | explicit CascadingFilter(std::vector<Filter> filters); | 54 | explicit CascadingFilter(std::vector<Filter> filters_); |
| 55 | 55 | ||
| 56 | void Process(std::vector<s16>& signal); | 56 | void Process(std::vector<s16>& signal); |
| 57 | 57 | ||
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 5f532ed31..179560cd7 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp | |||
| @@ -71,9 +71,9 @@ namespace { | |||
| 71 | namespace AudioCore { | 71 | namespace AudioCore { |
| 72 | AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_, | 72 | AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_, |
| 73 | AudioCommon::AudioRendererParameter params, | 73 | AudioCommon::AudioRendererParameter params, |
| 74 | std::shared_ptr<Kernel::WritableEvent> buffer_event, | 74 | std::shared_ptr<Kernel::WritableEvent> buffer_event_, |
| 75 | std::size_t instance_number) | 75 | std::size_t instance_number) |
| 76 | : worker_params{params}, buffer_event{buffer_event}, | 76 | : worker_params{params}, buffer_event{buffer_event_}, |
| 77 | memory_pool_info(params.effect_count + params.voice_count * 4), | 77 | memory_pool_info(params.effect_count + params.voice_count * 4), |
| 78 | voice_context(params.voice_count), effect_context(params.effect_count), mix_context(), | 78 | voice_context(params.voice_count), effect_context(params.effect_count), mix_context(), |
| 79 | sink_context(params.sink_count), splitter_context(), | 79 | sink_context(params.sink_count), splitter_context(), |
| @@ -88,7 +88,7 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory | |||
| 88 | stream = | 88 | stream = |
| 89 | audio_out->OpenStream(core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS, | 89 | audio_out->OpenStream(core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS, |
| 90 | fmt::format("AudioRenderer-Instance{}", instance_number), | 90 | fmt::format("AudioRenderer-Instance{}", instance_number), |
| 91 | [=]() { buffer_event->Signal(); }); | 91 | [=]() { buffer_event_->Signal(); }); |
| 92 | audio_out->StartStream(stream); | 92 | audio_out->StartStream(stream); |
| 93 | 93 | ||
| 94 | QueueMixedBuffer(0); | 94 | QueueMixedBuffer(0); |
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h index 54ac68b80..90f7eafa4 100644 --- a/src/audio_core/audio_renderer.h +++ b/src/audio_core/audio_renderer.h | |||
| @@ -44,7 +44,8 @@ class AudioRenderer { | |||
| 44 | public: | 44 | public: |
| 45 | AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_, | 45 | AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_, |
| 46 | AudioCommon::AudioRendererParameter params, | 46 | AudioCommon::AudioRendererParameter params, |
| 47 | std::shared_ptr<Kernel::WritableEvent> buffer_event, std::size_t instance_number); | 47 | std::shared_ptr<Kernel::WritableEvent> buffer_event_, |
| 48 | std::size_t instance_number); | ||
| 48 | ~AudioRenderer(); | 49 | ~AudioRenderer(); |
| 49 | 50 | ||
| 50 | [[nodiscard]] ResultCode UpdateAudioRenderer(const std::vector<u8>& input_params, | 51 | [[nodiscard]] ResultCode UpdateAudioRenderer(const std::vector<u8>& input_params, |
diff --git a/src/audio_core/buffer.h b/src/audio_core/buffer.h index 5ee09e9aa..ccc46ef82 100644 --- a/src/audio_core/buffer.h +++ b/src/audio_core/buffer.h | |||
| @@ -18,7 +18,7 @@ class Buffer { | |||
| 18 | public: | 18 | public: |
| 19 | using Tag = u64; | 19 | using Tag = u64; |
| 20 | 20 | ||
| 21 | Buffer(Tag tag, std::vector<s16>&& samples) : tag{tag}, samples{std::move(samples)} {} | 21 | Buffer(Tag tag_, std::vector<s16>&& samples_) : tag{tag_}, samples{std::move(samples_)} {} |
| 22 | 22 | ||
| 23 | /// Returns the raw audio data for the buffer | 23 | /// Returns the raw audio data for the buffer |
| 24 | std::vector<s16>& GetSamples() { | 24 | std::vector<s16>& GetSamples() { |
diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index fb8700ccf..a4a9a757d 100644 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp | |||
| @@ -67,12 +67,12 @@ s32 ApplyMixDepop(s32* output, s32 first_sample, s32 delta, s32 sample_count) { | |||
| 67 | 67 | ||
| 68 | } // namespace | 68 | } // namespace |
| 69 | 69 | ||
| 70 | CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_params, | 70 | CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_params_, |
| 71 | VoiceContext& voice_context, MixContext& mix_context, | 71 | VoiceContext& voice_context_, MixContext& mix_context_, |
| 72 | SplitterContext& splitter_context, EffectContext& effect_context, | 72 | SplitterContext& splitter_context_, |
| 73 | Core::Memory::Memory& memory) | 73 | EffectContext& effect_context_, Core::Memory::Memory& memory_) |
| 74 | : worker_params(worker_params), voice_context(voice_context), mix_context(mix_context), | 74 | : worker_params(worker_params_), voice_context(voice_context_), mix_context(mix_context_), |
| 75 | splitter_context(splitter_context), effect_context(effect_context), memory(memory), | 75 | splitter_context(splitter_context_), effect_context(effect_context_), memory(memory_), |
| 76 | mix_buffer((worker_params.mix_buffer_count + AudioCommon::MAX_CHANNEL_COUNT) * | 76 | mix_buffer((worker_params.mix_buffer_count + AudioCommon::MAX_CHANNEL_COUNT) * |
| 77 | worker_params.sample_count), | 77 | worker_params.sample_count), |
| 78 | sample_buffer(MIX_BUFFER_SIZE), | 78 | sample_buffer(MIX_BUFFER_SIZE), |
| @@ -255,7 +255,8 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo | |||
| 255 | 255 | ||
| 256 | void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info, | 256 | void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info, |
| 257 | VoiceState& dsp_state, | 257 | VoiceState& dsp_state, |
| 258 | s32 mix_buffer_count, s32 channel) { | 258 | [[maybe_unused]] s32 mix_buffer_count, |
| 259 | [[maybe_unused]] s32 channel) { | ||
| 259 | for (std::size_t i = 0; i < AudioCommon::MAX_BIQUAD_FILTERS; i++) { | 260 | for (std::size_t i = 0; i < AudioCommon::MAX_BIQUAD_FILTERS; i++) { |
| 260 | const auto& in_params = voice_info.GetInParams(); | 261 | const auto& in_params = voice_info.GetInParams(); |
| 261 | auto& biquad_filter = in_params.biquad_filter[i]; | 262 | auto& biquad_filter = in_params.biquad_filter[i]; |
| @@ -278,9 +279,12 @@ void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voic | |||
| 278 | } | 279 | } |
| 279 | } | 280 | } |
| 280 | 281 | ||
| 281 | void AudioCore::CommandGenerator::GenerateBiquadFilterCommand( | 282 | void CommandGenerator::GenerateBiquadFilterCommand([[maybe_unused]] s32 mix_buffer_id, |
| 282 | s32 mix_buffer, const BiquadFilterParameter& params, std::array<s64, 2>& state, | 283 | const BiquadFilterParameter& params, |
| 283 | std::size_t input_offset, std::size_t output_offset, s32 sample_count, s32 node_id) { | 284 | std::array<s64, 2>& state, |
| 285 | std::size_t input_offset, | ||
| 286 | std::size_t output_offset, s32 sample_count, | ||
| 287 | s32 node_id) { | ||
| 284 | if (dumping_frame) { | 288 | if (dumping_frame) { |
| 285 | LOG_DEBUG(Audio, | 289 | LOG_DEBUG(Audio, |
| 286 | "(DSP_TRACE) GenerateBiquadFilterCommand node_id={}, " | 290 | "(DSP_TRACE) GenerateBiquadFilterCommand node_id={}, " |
| @@ -714,7 +718,8 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s | |||
| 714 | } | 718 | } |
| 715 | 719 | ||
| 716 | s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, | 720 | s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, |
| 717 | s32 sample_count, s32 channel, std::size_t mix_offset) { | 721 | s32 sample_count, [[maybe_unused]] s32 channel, |
| 722 | std::size_t mix_offset) { | ||
| 718 | const auto& in_params = voice_info.GetInParams(); | 723 | const auto& in_params = voice_info.GetInParams(); |
| 719 | const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index]; | 724 | const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index]; |
| 720 | if (wave_buffer.buffer_address == 0) { | 725 | if (wave_buffer.buffer_address == 0) { |
diff --git a/src/audio_core/command_generator.h b/src/audio_core/command_generator.h index 87ece00c4..b937350b1 100644 --- a/src/audio_core/command_generator.h +++ b/src/audio_core/command_generator.h | |||
| @@ -25,10 +25,10 @@ using MixVolumeBuffer = std::array<float, AudioCommon::MAX_MIX_BUFFERS>; | |||
| 25 | 25 | ||
| 26 | class CommandGenerator { | 26 | class CommandGenerator { |
| 27 | public: | 27 | public: |
| 28 | explicit CommandGenerator(AudioCommon::AudioRendererParameter& worker_params, | 28 | explicit CommandGenerator(AudioCommon::AudioRendererParameter& worker_params_, |
| 29 | VoiceContext& voice_context, MixContext& mix_context, | 29 | VoiceContext& voice_context_, MixContext& mix_context_, |
| 30 | SplitterContext& splitter_context, EffectContext& effect_context, | 30 | SplitterContext& splitter_context_, EffectContext& effect_context_, |
| 31 | Core::Memory::Memory& memory); | 31 | Core::Memory::Memory& memory_); |
| 32 | ~CommandGenerator(); | 32 | ~CommandGenerator(); |
| 33 | 33 | ||
| 34 | void ClearMixBuffers(); | 34 | void ClearMixBuffers(); |
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index 6eaa60815..cf7b186e4 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp | |||
| @@ -21,10 +21,10 @@ namespace AudioCore { | |||
| 21 | 21 | ||
| 22 | class CubebSinkStream final : public SinkStream { | 22 | class CubebSinkStream final : public SinkStream { |
| 23 | public: | 23 | public: |
| 24 | CubebSinkStream(cubeb* ctx, u32 sample_rate, u32 num_channels_, cubeb_devid output_device, | 24 | CubebSinkStream(cubeb* ctx_, u32 sample_rate, u32 num_channels_, cubeb_devid output_device, |
| 25 | const std::string& name) | 25 | const std::string& name) |
| 26 | : ctx{ctx}, num_channels{std::min(num_channels_, 6u)}, time_stretch{sample_rate, | 26 | : ctx{ctx_}, num_channels{std::min(num_channels_, 6u)}, time_stretch{sample_rate, |
| 27 | num_channels} { | 27 | num_channels} { |
| 28 | 28 | ||
| 29 | cubeb_stream_params params{}; | 29 | cubeb_stream_params params{}; |
| 30 | params.rate = sample_rate; | 30 | params.rate = sample_rate; |
| @@ -192,8 +192,9 @@ SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels, | |||
| 192 | return *sink_streams.back(); | 192 | return *sink_streams.back(); |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, | 195 | long CubebSinkStream::DataCallback([[maybe_unused]] cubeb_stream* stream, void* user_data, |
| 196 | void* output_buffer, long num_frames) { | 196 | [[maybe_unused]] const void* input_buffer, void* output_buffer, |
| 197 | long num_frames) { | ||
| 197 | auto* impl = static_cast<CubebSinkStream*>(user_data); | 198 | auto* impl = static_cast<CubebSinkStream*>(user_data); |
| 198 | auto* buffer = static_cast<u8*>(output_buffer); | 199 | auto* buffer = static_cast<u8*>(output_buffer); |
| 199 | 200 | ||
| @@ -236,7 +237,9 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const | |||
| 236 | return num_frames; | 237 | return num_frames; |
| 237 | } | 238 | } |
| 238 | 239 | ||
| 239 | void CubebSinkStream::StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state) {} | 240 | void CubebSinkStream::StateCallback([[maybe_unused]] cubeb_stream* stream, |
| 241 | [[maybe_unused]] void* user_data, | ||
| 242 | [[maybe_unused]] cubeb_state state) {} | ||
| 240 | 243 | ||
| 241 | std::vector<std::string> ListCubebSinkDevices() { | 244 | std::vector<std::string> ListCubebSinkDevices() { |
| 242 | std::vector<std::string> device_list; | 245 | std::vector<std::string> device_list; |
diff --git a/src/audio_core/effect_context.cpp b/src/audio_core/effect_context.cpp index 4d9cdf524..f770b9608 100644 --- a/src/audio_core/effect_context.cpp +++ b/src/audio_core/effect_context.cpp | |||
| @@ -12,7 +12,7 @@ bool ValidChannelCountForEffect(s32 channel_count) { | |||
| 12 | } | 12 | } |
| 13 | } // namespace | 13 | } // namespace |
| 14 | 14 | ||
| 15 | EffectContext::EffectContext(std::size_t effect_count) : effect_count(effect_count) { | 15 | EffectContext::EffectContext(std::size_t effect_count_) : effect_count(effect_count_) { |
| 16 | effects.reserve(effect_count); | 16 | effects.reserve(effect_count); |
| 17 | std::generate_n(std::back_inserter(effects), effect_count, | 17 | std::generate_n(std::back_inserter(effects), effect_count, |
| 18 | [] { return std::make_unique<EffectStubbed>(); }); | 18 | [] { return std::make_unique<EffectStubbed>(); }); |
| @@ -61,13 +61,13 @@ const EffectBase* EffectContext::GetInfo(std::size_t i) const { | |||
| 61 | return effects.at(i).get(); | 61 | return effects.at(i).get(); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | EffectStubbed::EffectStubbed() : EffectBase::EffectBase(EffectType::Invalid) {} | 64 | EffectStubbed::EffectStubbed() : EffectBase(EffectType::Invalid) {} |
| 65 | EffectStubbed::~EffectStubbed() = default; | 65 | EffectStubbed::~EffectStubbed() = default; |
| 66 | 66 | ||
| 67 | void EffectStubbed::Update(EffectInfo::InParams& in_params) {} | 67 | void EffectStubbed::Update([[maybe_unused]] EffectInfo::InParams& in_params) {} |
| 68 | void EffectStubbed::UpdateForCommandGeneration() {} | 68 | void EffectStubbed::UpdateForCommandGeneration() {} |
| 69 | 69 | ||
| 70 | EffectBase::EffectBase(EffectType effect_type) : effect_type(effect_type) {} | 70 | EffectBase::EffectBase(EffectType effect_type_) : effect_type(effect_type_) {} |
| 71 | EffectBase::~EffectBase() = default; | 71 | EffectBase::~EffectBase() = default; |
| 72 | 72 | ||
| 73 | UsageState EffectBase::GetUsage() const { | 73 | UsageState EffectBase::GetUsage() const { |
| @@ -90,32 +90,32 @@ s32 EffectBase::GetProcessingOrder() const { | |||
| 90 | return processing_order; | 90 | return processing_order; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric::EffectGeneric(EffectType::I3dl2Reverb) {} | 93 | EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric(EffectType::I3dl2Reverb) {} |
| 94 | EffectI3dl2Reverb::~EffectI3dl2Reverb() = default; | 94 | EffectI3dl2Reverb::~EffectI3dl2Reverb() = default; |
| 95 | 95 | ||
| 96 | void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) { | 96 | void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) { |
| 97 | auto& internal_params = GetParams(); | 97 | auto& params = GetParams(); |
| 98 | const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(in_params.raw.data()); | 98 | const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(in_params.raw.data()); |
| 99 | if (!ValidChannelCountForEffect(reverb_params->max_channels)) { | 99 | if (!ValidChannelCountForEffect(reverb_params->max_channels)) { |
| 100 | UNREACHABLE_MSG("Invalid reverb max channel count {}", reverb_params->max_channels); | 100 | UNREACHABLE_MSG("Invalid reverb max channel count {}", reverb_params->max_channels); |
| 101 | return; | 101 | return; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | const auto last_status = internal_params.status; | 104 | const auto last_status = params.status; |
| 105 | mix_id = in_params.mix_id; | 105 | mix_id = in_params.mix_id; |
| 106 | processing_order = in_params.processing_order; | 106 | processing_order = in_params.processing_order; |
| 107 | internal_params = *reverb_params; | 107 | params = *reverb_params; |
| 108 | if (!ValidChannelCountForEffect(reverb_params->channel_count)) { | 108 | if (!ValidChannelCountForEffect(reverb_params->channel_count)) { |
| 109 | internal_params.channel_count = internal_params.max_channels; | 109 | params.channel_count = params.max_channels; |
| 110 | } | 110 | } |
| 111 | enabled = in_params.is_enabled; | 111 | enabled = in_params.is_enabled; |
| 112 | if (last_status != ParameterStatus::Updated) { | 112 | if (last_status != ParameterStatus::Updated) { |
| 113 | internal_params.status = last_status; | 113 | params.status = last_status; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | if (in_params.is_new || skipped) { | 116 | if (in_params.is_new || skipped) { |
| 117 | usage = UsageState::Initialized; | 117 | usage = UsageState::Initialized; |
| 118 | internal_params.status = ParameterStatus::Initialized; | 118 | params.status = ParameterStatus::Initialized; |
| 119 | skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; | 119 | skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; |
| 120 | } | 120 | } |
| 121 | } | 121 | } |
| @@ -129,15 +129,15 @@ void EffectI3dl2Reverb::UpdateForCommandGeneration() { | |||
| 129 | GetParams().status = ParameterStatus::Updated; | 129 | GetParams().status = ParameterStatus::Updated; |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric::EffectGeneric(EffectType::BiquadFilter) {} | 132 | EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric(EffectType::BiquadFilter) {} |
| 133 | EffectBiquadFilter::~EffectBiquadFilter() = default; | 133 | EffectBiquadFilter::~EffectBiquadFilter() = default; |
| 134 | 134 | ||
| 135 | void EffectBiquadFilter::Update(EffectInfo::InParams& in_params) { | 135 | void EffectBiquadFilter::Update(EffectInfo::InParams& in_params) { |
| 136 | auto& internal_params = GetParams(); | 136 | auto& params = GetParams(); |
| 137 | const auto* biquad_params = reinterpret_cast<BiquadFilterParams*>(in_params.raw.data()); | 137 | const auto* biquad_params = reinterpret_cast<BiquadFilterParams*>(in_params.raw.data()); |
| 138 | mix_id = in_params.mix_id; | 138 | mix_id = in_params.mix_id; |
| 139 | processing_order = in_params.processing_order; | 139 | processing_order = in_params.processing_order; |
| 140 | internal_params = *biquad_params; | 140 | params = *biquad_params; |
| 141 | enabled = in_params.is_enabled; | 141 | enabled = in_params.is_enabled; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| @@ -150,7 +150,7 @@ void EffectBiquadFilter::UpdateForCommandGeneration() { | |||
| 150 | GetParams().status = ParameterStatus::Updated; | 150 | GetParams().status = ParameterStatus::Updated; |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | EffectAuxInfo::EffectAuxInfo() : EffectGeneric::EffectGeneric(EffectType::Aux) {} | 153 | EffectAuxInfo::EffectAuxInfo() : EffectGeneric(EffectType::Aux) {} |
| 154 | EffectAuxInfo::~EffectAuxInfo() = default; | 154 | EffectAuxInfo::~EffectAuxInfo() = default; |
| 155 | 155 | ||
| 156 | void EffectAuxInfo::Update(EffectInfo::InParams& in_params) { | 156 | void EffectAuxInfo::Update(EffectInfo::InParams& in_params) { |
| @@ -200,32 +200,32 @@ VAddr EffectAuxInfo::GetRecvBuffer() const { | |||
| 200 | return recv_buffer; | 200 | return recv_buffer; |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | EffectDelay::EffectDelay() : EffectGeneric::EffectGeneric(EffectType::Delay) {} | 203 | EffectDelay::EffectDelay() : EffectGeneric(EffectType::Delay) {} |
| 204 | EffectDelay::~EffectDelay() = default; | 204 | EffectDelay::~EffectDelay() = default; |
| 205 | 205 | ||
| 206 | void EffectDelay::Update(EffectInfo::InParams& in_params) { | 206 | void EffectDelay::Update(EffectInfo::InParams& in_params) { |
| 207 | const auto* delay_params = reinterpret_cast<DelayParams*>(in_params.raw.data()); | 207 | const auto* delay_params = reinterpret_cast<DelayParams*>(in_params.raw.data()); |
| 208 | auto& internal_params = GetParams(); | 208 | auto& params = GetParams(); |
| 209 | if (!ValidChannelCountForEffect(delay_params->max_channels)) { | 209 | if (!ValidChannelCountForEffect(delay_params->max_channels)) { |
| 210 | return; | 210 | return; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | const auto last_status = internal_params.status; | 213 | const auto last_status = params.status; |
| 214 | mix_id = in_params.mix_id; | 214 | mix_id = in_params.mix_id; |
| 215 | processing_order = in_params.processing_order; | 215 | processing_order = in_params.processing_order; |
| 216 | internal_params = *delay_params; | 216 | params = *delay_params; |
| 217 | if (!ValidChannelCountForEffect(delay_params->channels)) { | 217 | if (!ValidChannelCountForEffect(delay_params->channels)) { |
| 218 | internal_params.channels = internal_params.max_channels; | 218 | params.channels = params.max_channels; |
| 219 | } | 219 | } |
| 220 | enabled = in_params.is_enabled; | 220 | enabled = in_params.is_enabled; |
| 221 | 221 | ||
| 222 | if (last_status != ParameterStatus::Updated) { | 222 | if (last_status != ParameterStatus::Updated) { |
| 223 | internal_params.status = last_status; | 223 | params.status = last_status; |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | if (in_params.is_new || skipped) { | 226 | if (in_params.is_new || skipped) { |
| 227 | usage = UsageState::Initialized; | 227 | usage = UsageState::Initialized; |
| 228 | internal_params.status = ParameterStatus::Initialized; | 228 | params.status = ParameterStatus::Initialized; |
| 229 | skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; | 229 | skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; |
| 230 | } | 230 | } |
| 231 | } | 231 | } |
| @@ -239,7 +239,7 @@ void EffectDelay::UpdateForCommandGeneration() { | |||
| 239 | GetParams().status = ParameterStatus::Updated; | 239 | GetParams().status = ParameterStatus::Updated; |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | EffectBufferMixer::EffectBufferMixer() : EffectGeneric::EffectGeneric(EffectType::BufferMixer) {} | 242 | EffectBufferMixer::EffectBufferMixer() : EffectGeneric(EffectType::BufferMixer) {} |
| 243 | EffectBufferMixer::~EffectBufferMixer() = default; | 243 | EffectBufferMixer::~EffectBufferMixer() = default; |
| 244 | 244 | ||
| 245 | void EffectBufferMixer::Update(EffectInfo::InParams& in_params) { | 245 | void EffectBufferMixer::Update(EffectInfo::InParams& in_params) { |
| @@ -257,32 +257,32 @@ void EffectBufferMixer::UpdateForCommandGeneration() { | |||
| 257 | } | 257 | } |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | EffectReverb::EffectReverb() : EffectGeneric::EffectGeneric(EffectType::Reverb) {} | 260 | EffectReverb::EffectReverb() : EffectGeneric(EffectType::Reverb) {} |
| 261 | EffectReverb::~EffectReverb() = default; | 261 | EffectReverb::~EffectReverb() = default; |
| 262 | 262 | ||
| 263 | void EffectReverb::Update(EffectInfo::InParams& in_params) { | 263 | void EffectReverb::Update(EffectInfo::InParams& in_params) { |
| 264 | const auto* reverb_params = reinterpret_cast<ReverbParams*>(in_params.raw.data()); | 264 | const auto* reverb_params = reinterpret_cast<ReverbParams*>(in_params.raw.data()); |
| 265 | auto& internal_params = GetParams(); | 265 | auto& params = GetParams(); |
| 266 | if (!ValidChannelCountForEffect(reverb_params->max_channels)) { | 266 | if (!ValidChannelCountForEffect(reverb_params->max_channels)) { |
| 267 | return; | 267 | return; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | const auto last_status = internal_params.status; | 270 | const auto last_status = params.status; |
| 271 | mix_id = in_params.mix_id; | 271 | mix_id = in_params.mix_id; |
| 272 | processing_order = in_params.processing_order; | 272 | processing_order = in_params.processing_order; |
| 273 | internal_params = *reverb_params; | 273 | params = *reverb_params; |
| 274 | if (!ValidChannelCountForEffect(reverb_params->channels)) { | 274 | if (!ValidChannelCountForEffect(reverb_params->channels)) { |
| 275 | internal_params.channels = internal_params.max_channels; | 275 | params.channels = params.max_channels; |
| 276 | } | 276 | } |
| 277 | enabled = in_params.is_enabled; | 277 | enabled = in_params.is_enabled; |
| 278 | 278 | ||
| 279 | if (last_status != ParameterStatus::Updated) { | 279 | if (last_status != ParameterStatus::Updated) { |
| 280 | internal_params.status = last_status; | 280 | params.status = last_status; |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | if (in_params.is_new || skipped) { | 283 | if (in_params.is_new || skipped) { |
| 284 | usage = UsageState::Initialized; | 284 | usage = UsageState::Initialized; |
| 285 | internal_params.status = ParameterStatus::Initialized; | 285 | params.status = ParameterStatus::Initialized; |
| 286 | skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; | 286 | skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; |
| 287 | } | 287 | } |
| 288 | } | 288 | } |
diff --git a/src/audio_core/effect_context.h b/src/audio_core/effect_context.h index 03c5a0f04..c5e0b398c 100644 --- a/src/audio_core/effect_context.h +++ b/src/audio_core/effect_context.h | |||
| @@ -184,7 +184,7 @@ struct AuxAddress { | |||
| 184 | 184 | ||
| 185 | class EffectBase { | 185 | class EffectBase { |
| 186 | public: | 186 | public: |
| 187 | explicit EffectBase(EffectType effect_type); | 187 | explicit EffectBase(EffectType effect_type_); |
| 188 | virtual ~EffectBase(); | 188 | virtual ~EffectBase(); |
| 189 | 189 | ||
| 190 | virtual void Update(EffectInfo::InParams& in_params) = 0; | 190 | virtual void Update(EffectInfo::InParams& in_params) = 0; |
| @@ -206,7 +206,7 @@ protected: | |||
| 206 | template <typename T> | 206 | template <typename T> |
| 207 | class EffectGeneric : public EffectBase { | 207 | class EffectGeneric : public EffectBase { |
| 208 | public: | 208 | public: |
| 209 | explicit EffectGeneric(EffectType effect_type) : EffectBase(effect_type) {} | 209 | explicit EffectGeneric(EffectType effect_type_) : EffectBase(effect_type_) {} |
| 210 | 210 | ||
| 211 | T& GetParams() { | 211 | T& GetParams() { |
| 212 | return internal_params; | 212 | return internal_params; |
| @@ -306,7 +306,7 @@ private: | |||
| 306 | 306 | ||
| 307 | class EffectContext { | 307 | class EffectContext { |
| 308 | public: | 308 | public: |
| 309 | explicit EffectContext(std::size_t effect_count); | 309 | explicit EffectContext(std::size_t effect_count_); |
| 310 | ~EffectContext(); | 310 | ~EffectContext(); |
| 311 | 311 | ||
| 312 | [[nodiscard]] std::size_t GetCount() const; | 312 | [[nodiscard]] std::size_t GetCount() const; |
diff --git a/src/audio_core/info_updater.cpp b/src/audio_core/info_updater.cpp index 2940e53a9..d3ac90827 100644 --- a/src/audio_core/info_updater.cpp +++ b/src/audio_core/info_updater.cpp | |||
| @@ -14,9 +14,9 @@ | |||
| 14 | 14 | ||
| 15 | namespace AudioCore { | 15 | namespace AudioCore { |
| 16 | 16 | ||
| 17 | InfoUpdater::InfoUpdater(const std::vector<u8>& in_params, std::vector<u8>& out_params, | 17 | InfoUpdater::InfoUpdater(const std::vector<u8>& in_params_, std::vector<u8>& out_params_, |
| 18 | BehaviorInfo& behavior_info) | 18 | BehaviorInfo& behavior_info_) |
| 19 | : in_params(in_params), out_params(out_params), behavior_info(behavior_info) { | 19 | : in_params(in_params_), out_params(out_params_), behavior_info(behavior_info_) { |
| 20 | ASSERT( | 20 | ASSERT( |
| 21 | AudioCommon::CanConsumeBuffer(in_params.size(), 0, sizeof(AudioCommon::UpdateDataHeader))); | 21 | AudioCommon::CanConsumeBuffer(in_params.size(), 0, sizeof(AudioCommon::UpdateDataHeader))); |
| 22 | std::memcpy(&input_header, in_params.data(), sizeof(AudioCommon::UpdateDataHeader)); | 22 | std::memcpy(&input_header, in_params.data(), sizeof(AudioCommon::UpdateDataHeader)); |
| @@ -135,8 +135,8 @@ bool InfoUpdater::UpdateVoiceChannelResources(VoiceContext& voice_context) { | |||
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | bool InfoUpdater::UpdateVoices(VoiceContext& voice_context, | 137 | bool InfoUpdater::UpdateVoices(VoiceContext& voice_context, |
| 138 | std::vector<ServerMemoryPoolInfo>& memory_pool_info, | 138 | [[maybe_unused]] std::vector<ServerMemoryPoolInfo>& memory_pool_info, |
| 139 | VAddr audio_codec_dsp_addr) { | 139 | [[maybe_unused]] VAddr audio_codec_dsp_addr) { |
| 140 | const auto voice_count = voice_context.GetVoiceCount(); | 140 | const auto voice_count = voice_context.GetVoiceCount(); |
| 141 | std::vector<VoiceInfo::InParams> voice_in(voice_count); | 141 | std::vector<VoiceInfo::InParams> voice_in(voice_count); |
| 142 | std::vector<VoiceInfo::OutParams> voice_out(voice_count); | 142 | std::vector<VoiceInfo::OutParams> voice_out(voice_count); |
| @@ -165,28 +165,28 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context, | |||
| 165 | 165 | ||
| 166 | // Update our voices | 166 | // Update our voices |
| 167 | for (std::size_t i = 0; i < voice_count; i++) { | 167 | for (std::size_t i = 0; i < voice_count; i++) { |
| 168 | auto& in_params = voice_in[i]; | 168 | auto& voice_in_params = voice_in[i]; |
| 169 | const auto channel_count = static_cast<std::size_t>(in_params.channel_count); | 169 | const auto channel_count = static_cast<std::size_t>(voice_in_params.channel_count); |
| 170 | // Skip if it's not currently in use | 170 | // Skip if it's not currently in use |
| 171 | if (!in_params.is_in_use) { | 171 | if (!voice_in_params.is_in_use) { |
| 172 | continue; | 172 | continue; |
| 173 | } | 173 | } |
| 174 | // Voice states for each channel | 174 | // Voice states for each channel |
| 175 | std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT> voice_states{}; | 175 | std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT> voice_states{}; |
| 176 | ASSERT(static_cast<std::size_t>(in_params.id) < voice_count); | 176 | ASSERT(static_cast<std::size_t>(voice_in_params.id) < voice_count); |
| 177 | 177 | ||
| 178 | // Grab our current voice info | 178 | // Grab our current voice info |
| 179 | auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(in_params.id)); | 179 | auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(voice_in_params.id)); |
| 180 | 180 | ||
| 181 | ASSERT(channel_count <= AudioCommon::MAX_CHANNEL_COUNT); | 181 | ASSERT(channel_count <= AudioCommon::MAX_CHANNEL_COUNT); |
| 182 | 182 | ||
| 183 | // Get all our channel voice states | 183 | // Get all our channel voice states |
| 184 | for (std::size_t channel = 0; channel < channel_count; channel++) { | 184 | for (std::size_t channel = 0; channel < channel_count; channel++) { |
| 185 | voice_states[channel] = | 185 | voice_states[channel] = |
| 186 | &voice_context.GetState(in_params.voice_channel_resource_ids[channel]); | 186 | &voice_context.GetState(voice_in_params.voice_channel_resource_ids[channel]); |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | if (in_params.is_new) { | 189 | if (voice_in_params.is_new) { |
| 190 | // Default our values for our voice | 190 | // Default our values for our voice |
| 191 | voice_info.Initialize(); | 191 | voice_info.Initialize(); |
| 192 | if (channel_count == 0 || channel_count > AudioCommon::MAX_CHANNEL_COUNT) { | 192 | if (channel_count == 0 || channel_count > AudioCommon::MAX_CHANNEL_COUNT) { |
| @@ -200,12 +200,12 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context, | |||
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | // Update our voice | 202 | // Update our voice |
| 203 | voice_info.UpdateParameters(in_params, behavior_info); | 203 | voice_info.UpdateParameters(voice_in_params, behavior_info); |
| 204 | // TODO(ogniK): Handle mapping errors with behavior info based on in params response | 204 | // TODO(ogniK): Handle mapping errors with behavior info based on in params response |
| 205 | 205 | ||
| 206 | // Update our wave buffers | 206 | // Update our wave buffers |
| 207 | voice_info.UpdateWaveBuffers(in_params, voice_states, behavior_info); | 207 | voice_info.UpdateWaveBuffers(voice_in_params, voice_states, behavior_info); |
| 208 | voice_info.WriteOutStatus(voice_out[i], in_params, voice_states); | 208 | voice_info.WriteOutStatus(voice_out[i], voice_in_params, voice_states); |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | if (!AudioCommon::CanConsumeBuffer(out_params.size(), output_offset, voice_out_size)) { | 211 | if (!AudioCommon::CanConsumeBuffer(out_params.size(), output_offset, voice_out_size)) { |
| @@ -445,7 +445,7 @@ bool InfoUpdater::UpdatePerformanceBuffer() { | |||
| 445 | return true; | 445 | return true; |
| 446 | } | 446 | } |
| 447 | 447 | ||
| 448 | bool InfoUpdater::UpdateErrorInfo(BehaviorInfo& in_behavior_info) { | 448 | bool InfoUpdater::UpdateErrorInfo([[maybe_unused]] BehaviorInfo& in_behavior_info) { |
| 449 | const auto total_beahvior_info_out = sizeof(BehaviorInfo::OutParams); | 449 | const auto total_beahvior_info_out = sizeof(BehaviorInfo::OutParams); |
| 450 | 450 | ||
| 451 | if (!AudioCommon::CanConsumeBuffer(out_params.size(), output_offset, total_beahvior_info_out)) { | 451 | if (!AudioCommon::CanConsumeBuffer(out_params.size(), output_offset, total_beahvior_info_out)) { |
diff --git a/src/audio_core/info_updater.h b/src/audio_core/info_updater.h index 06f9d770f..d315c91ed 100644 --- a/src/audio_core/info_updater.h +++ b/src/audio_core/info_updater.h | |||
| @@ -21,8 +21,8 @@ class SplitterContext; | |||
| 21 | class InfoUpdater { | 21 | class InfoUpdater { |
| 22 | public: | 22 | public: |
| 23 | // TODO(ogniK): Pass process handle when we support it | 23 | // TODO(ogniK): Pass process handle when we support it |
| 24 | InfoUpdater(const std::vector<u8>& in_params, std::vector<u8>& out_params, | 24 | InfoUpdater(const std::vector<u8>& in_params_, std::vector<u8>& out_params_, |
| 25 | BehaviorInfo& behavior_info); | 25 | BehaviorInfo& behavior_info_); |
| 26 | ~InfoUpdater(); | 26 | ~InfoUpdater(); |
| 27 | 27 | ||
| 28 | bool UpdateBehaviorInfo(BehaviorInfo& in_behavior_info); | 28 | bool UpdateBehaviorInfo(BehaviorInfo& in_behavior_info); |
diff --git a/src/audio_core/memory_pool.cpp b/src/audio_core/memory_pool.cpp index 5a3453063..6b6908d26 100644 --- a/src/audio_core/memory_pool.cpp +++ b/src/audio_core/memory_pool.cpp | |||
| @@ -10,11 +10,10 @@ namespace AudioCore { | |||
| 10 | 10 | ||
| 11 | ServerMemoryPoolInfo::ServerMemoryPoolInfo() = default; | 11 | ServerMemoryPoolInfo::ServerMemoryPoolInfo() = default; |
| 12 | ServerMemoryPoolInfo::~ServerMemoryPoolInfo() = default; | 12 | ServerMemoryPoolInfo::~ServerMemoryPoolInfo() = default; |
| 13 | bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_params, | 13 | |
| 14 | ServerMemoryPoolInfo::OutParams& out_params) { | 14 | bool ServerMemoryPoolInfo::Update(const InParams& in_params, OutParams& out_params) { |
| 15 | // Our state does not need to be changed | 15 | // Our state does not need to be changed |
| 16 | if (in_params.state != ServerMemoryPoolInfo::State::RequestAttach && | 16 | if (in_params.state != State::RequestAttach && in_params.state != State::RequestDetach) { |
| 17 | in_params.state != ServerMemoryPoolInfo::State::RequestDetach) { | ||
| 18 | return true; | 17 | return true; |
| 19 | } | 18 | } |
| 20 | 19 | ||
| @@ -32,11 +31,11 @@ bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_param | |||
| 32 | return false; | 31 | return false; |
| 33 | } | 32 | } |
| 34 | 33 | ||
| 35 | if (in_params.state == ServerMemoryPoolInfo::State::RequestAttach) { | 34 | if (in_params.state == State::RequestAttach) { |
| 36 | cpu_address = in_params.address; | 35 | cpu_address = in_params.address; |
| 37 | size = in_params.size; | 36 | size = in_params.size; |
| 38 | used = true; | 37 | used = true; |
| 39 | out_params.state = ServerMemoryPoolInfo::State::Attached; | 38 | out_params.state = State::Attached; |
| 40 | } else { | 39 | } else { |
| 41 | // Unexpected address | 40 | // Unexpected address |
| 42 | if (cpu_address != in_params.address) { | 41 | if (cpu_address != in_params.address) { |
| @@ -54,7 +53,7 @@ bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_param | |||
| 54 | cpu_address = 0; | 53 | cpu_address = 0; |
| 55 | size = 0; | 54 | size = 0; |
| 56 | used = false; | 55 | used = false; |
| 57 | out_params.state = ServerMemoryPoolInfo::State::Detached; | 56 | out_params.state = State::Detached; |
| 58 | } | 57 | } |
| 59 | return true; | 58 | return true; |
| 60 | } | 59 | } |
diff --git a/src/audio_core/memory_pool.h b/src/audio_core/memory_pool.h index 8ac503f1c..3e9e777ae 100644 --- a/src/audio_core/memory_pool.h +++ b/src/audio_core/memory_pool.h | |||
| @@ -28,19 +28,18 @@ public: | |||
| 28 | struct InParams { | 28 | struct InParams { |
| 29 | u64_le address{}; | 29 | u64_le address{}; |
| 30 | u64_le size{}; | 30 | u64_le size{}; |
| 31 | ServerMemoryPoolInfo::State state{}; | 31 | State state{}; |
| 32 | INSERT_PADDING_WORDS(3); | 32 | INSERT_PADDING_WORDS(3); |
| 33 | }; | 33 | }; |
| 34 | static_assert(sizeof(ServerMemoryPoolInfo::InParams) == 0x20, "InParams are an invalid size"); | 34 | static_assert(sizeof(InParams) == 0x20, "InParams are an invalid size"); |
| 35 | 35 | ||
| 36 | struct OutParams { | 36 | struct OutParams { |
| 37 | ServerMemoryPoolInfo::State state{}; | 37 | State state{}; |
| 38 | INSERT_PADDING_WORDS(3); | 38 | INSERT_PADDING_WORDS(3); |
| 39 | }; | 39 | }; |
| 40 | static_assert(sizeof(ServerMemoryPoolInfo::OutParams) == 0x10, "OutParams are an invalid size"); | 40 | static_assert(sizeof(OutParams) == 0x10, "OutParams are an invalid size"); |
| 41 | 41 | ||
| 42 | bool Update(const ServerMemoryPoolInfo::InParams& in_params, | 42 | bool Update(const InParams& in_params, OutParams& out_params); |
| 43 | ServerMemoryPoolInfo::OutParams& out_params); | ||
| 44 | 43 | ||
| 45 | private: | 44 | private: |
| 46 | // There's another entry here which is the DSP address, however since we're not talking to the | 45 | // There's another entry here which is the DSP address, however since we're not talking to the |
diff --git a/src/audio_core/sink_context.cpp b/src/audio_core/sink_context.cpp index b29b47890..a69543696 100644 --- a/src/audio_core/sink_context.cpp +++ b/src/audio_core/sink_context.cpp | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #include "audio_core/sink_context.h" | 5 | #include "audio_core/sink_context.h" |
| 6 | 6 | ||
| 7 | namespace AudioCore { | 7 | namespace AudioCore { |
| 8 | SinkContext::SinkContext(std::size_t sink_count) : sink_count(sink_count) {} | 8 | SinkContext::SinkContext(std::size_t sink_count_) : sink_count{sink_count_} {} |
| 9 | SinkContext::~SinkContext() = default; | 9 | SinkContext::~SinkContext() = default; |
| 10 | 10 | ||
| 11 | std::size_t SinkContext::GetCount() const { | 11 | std::size_t SinkContext::GetCount() const { |
diff --git a/src/audio_core/sink_context.h b/src/audio_core/sink_context.h index e2e7880b7..05541becb 100644 --- a/src/audio_core/sink_context.h +++ b/src/audio_core/sink_context.h | |||
| @@ -42,7 +42,7 @@ public: | |||
| 42 | bool in_use; | 42 | bool in_use; |
| 43 | INSERT_UNION_PADDING_BYTES(5); | 43 | INSERT_UNION_PADDING_BYTES(5); |
| 44 | }; | 44 | }; |
| 45 | static_assert(sizeof(SinkInfo::CircularBufferIn) == 0x28, | 45 | static_assert(sizeof(CircularBufferIn) == 0x28, |
| 46 | "SinkInfo::CircularBufferIn is in invalid size"); | 46 | "SinkInfo::CircularBufferIn is in invalid size"); |
| 47 | 47 | ||
| 48 | struct DeviceIn { | 48 | struct DeviceIn { |
| @@ -54,7 +54,7 @@ public: | |||
| 54 | bool down_matrix_enabled; | 54 | bool down_matrix_enabled; |
| 55 | DownmixCoefficients down_matrix_coef; | 55 | DownmixCoefficients down_matrix_coef; |
| 56 | }; | 56 | }; |
| 57 | static_assert(sizeof(SinkInfo::DeviceIn) == 0x11c, "SinkInfo::DeviceIn is an invalid size"); | 57 | static_assert(sizeof(DeviceIn) == 0x11c, "SinkInfo::DeviceIn is an invalid size"); |
| 58 | 58 | ||
| 59 | struct InParams { | 59 | struct InParams { |
| 60 | SinkTypes type{}; | 60 | SinkTypes type{}; |
| @@ -64,16 +64,16 @@ public: | |||
| 64 | INSERT_PADDING_WORDS(6); | 64 | INSERT_PADDING_WORDS(6); |
| 65 | union { | 65 | union { |
| 66 | // std::array<u8, 0x120> raw{}; | 66 | // std::array<u8, 0x120> raw{}; |
| 67 | SinkInfo::DeviceIn device; | 67 | DeviceIn device; |
| 68 | SinkInfo::CircularBufferIn circular_buffer; | 68 | CircularBufferIn circular_buffer; |
| 69 | }; | 69 | }; |
| 70 | }; | 70 | }; |
| 71 | static_assert(sizeof(SinkInfo::InParams) == 0x140, "SinkInfo::InParams are an invalid size!"); | 71 | static_assert(sizeof(InParams) == 0x140, "SinkInfo::InParams are an invalid size!"); |
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | class SinkContext { | 74 | class SinkContext { |
| 75 | public: | 75 | public: |
| 76 | explicit SinkContext(std::size_t sink_count); | 76 | explicit SinkContext(std::size_t sink_count_); |
| 77 | ~SinkContext(); | 77 | ~SinkContext(); |
| 78 | 78 | ||
| 79 | [[nodiscard]] std::size_t GetCount() const; | 79 | [[nodiscard]] std::size_t GetCount() const; |
diff --git a/src/audio_core/splitter_context.cpp b/src/audio_core/splitter_context.cpp index f21b53147..f4bcd0391 100644 --- a/src/audio_core/splitter_context.cpp +++ b/src/audio_core/splitter_context.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | namespace AudioCore { | 11 | namespace AudioCore { |
| 12 | 12 | ||
| 13 | ServerSplitterDestinationData::ServerSplitterDestinationData(s32 id) : id(id) {} | 13 | ServerSplitterDestinationData::ServerSplitterDestinationData(s32 id_) : id{id_} {} |
| 14 | ServerSplitterDestinationData::~ServerSplitterDestinationData() = default; | 14 | ServerSplitterDestinationData::~ServerSplitterDestinationData() = default; |
| 15 | 15 | ||
| 16 | void ServerSplitterDestinationData::Update(SplitterInfo::InDestinationParams& header) { | 16 | void ServerSplitterDestinationData::Update(SplitterInfo::InDestinationParams& header) { |
| @@ -87,7 +87,7 @@ void ServerSplitterDestinationData::UpdateInternalState() { | |||
| 87 | needs_update = false; | 87 | needs_update = false; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | ServerSplitterInfo::ServerSplitterInfo(s32 id) : id(id) {} | 90 | ServerSplitterInfo::ServerSplitterInfo(s32 id_) : id(id_) {} |
| 91 | ServerSplitterInfo::~ServerSplitterInfo() = default; | 91 | ServerSplitterInfo::~ServerSplitterInfo() = default; |
| 92 | 92 | ||
| 93 | void ServerSplitterInfo::InitializeInfos() { | 93 | void ServerSplitterInfo::InitializeInfos() { |
| @@ -121,7 +121,7 @@ const ServerSplitterDestinationData* ServerSplitterInfo::GetHead() const { | |||
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) { | 123 | ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) { |
| 124 | auto current_head = head; | 124 | auto* current_head = head; |
| 125 | for (std::size_t i = 0; i < depth; i++) { | 125 | for (std::size_t i = 0; i < depth; i++) { |
| 126 | if (current_head == nullptr) { | 126 | if (current_head == nullptr) { |
| 127 | return nullptr; | 127 | return nullptr; |
| @@ -132,7 +132,7 @@ ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) { | |||
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | const ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) const { | 134 | const ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) const { |
| 135 | auto current_head = head; | 135 | auto* current_head = head; |
| 136 | for (std::size_t i = 0; i < depth; i++) { | 136 | for (std::size_t i = 0; i < depth; i++) { |
| 137 | if (current_head == nullptr) { | 137 | if (current_head == nullptr) { |
| 138 | return nullptr; | 138 | return nullptr; |
| @@ -245,7 +245,7 @@ ServerSplitterDestinationData* SplitterContext::GetDestinationData(std::size_t i | |||
| 245 | const ServerSplitterDestinationData* SplitterContext::GetDestinationData(std::size_t info, | 245 | const ServerSplitterDestinationData* SplitterContext::GetDestinationData(std::size_t info, |
| 246 | std::size_t data) const { | 246 | std::size_t data) const { |
| 247 | ASSERT(info < info_count); | 247 | ASSERT(info < info_count); |
| 248 | auto& cur_info = GetInfo(info); | 248 | const auto& cur_info = GetInfo(info); |
| 249 | return cur_info.GetData(data); | 249 | return cur_info.GetData(data); |
| 250 | } | 250 | } |
| 251 | 251 | ||
| @@ -267,11 +267,11 @@ std::size_t SplitterContext::GetDataCount() const { | |||
| 267 | return data_count; | 267 | return data_count; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | void SplitterContext::Setup(std::size_t _info_count, std::size_t _data_count, | 270 | void SplitterContext::Setup(std::size_t info_count_, std::size_t data_count_, |
| 271 | bool is_splitter_bug_fixed) { | 271 | bool is_splitter_bug_fixed) { |
| 272 | 272 | ||
| 273 | info_count = _info_count; | 273 | info_count = info_count_; |
| 274 | data_count = _data_count; | 274 | data_count = data_count_; |
| 275 | 275 | ||
| 276 | for (std::size_t i = 0; i < info_count; i++) { | 276 | for (std::size_t i = 0; i < info_count; i++) { |
| 277 | auto& splitter = infos.emplace_back(static_cast<s32>(i)); | 277 | auto& splitter = infos.emplace_back(static_cast<s32>(i)); |
| @@ -364,7 +364,7 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info, | |||
| 364 | // Clear our current destinations | 364 | // Clear our current destinations |
| 365 | auto* current_head = info.GetHead(); | 365 | auto* current_head = info.GetHead(); |
| 366 | while (current_head != nullptr) { | 366 | while (current_head != nullptr) { |
| 367 | auto next_head = current_head->GetNextDestination(); | 367 | auto* next_head = current_head->GetNextDestination(); |
| 368 | current_head->SetNextDestination(nullptr); | 368 | current_head->SetNextDestination(nullptr); |
| 369 | current_head = next_head; | 369 | current_head = next_head; |
| 370 | } | 370 | } |
| @@ -471,8 +471,8 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) { | |||
| 471 | continue; | 471 | continue; |
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | const auto node_count = edge_matrix.GetNodeCount(); | 474 | const auto edge_node_count = edge_matrix.GetNodeCount(); |
| 475 | for (s32 j = 0; j < static_cast<s32>(node_count); j++) { | 475 | for (s32 j = 0; j < static_cast<s32>(edge_node_count); j++) { |
| 476 | // Check if our node is connected to our edge matrix | 476 | // Check if our node is connected to our edge matrix |
| 477 | if (!edge_matrix.Connected(current_stack_index, j)) { | 477 | if (!edge_matrix.Connected(current_stack_index, j)) { |
| 478 | continue; | 478 | continue; |
diff --git a/src/audio_core/splitter_context.h b/src/audio_core/splitter_context.h index ea6239fdb..b490627f5 100644 --- a/src/audio_core/splitter_context.h +++ b/src/audio_core/splitter_context.h | |||
| @@ -63,7 +63,7 @@ public: | |||
| 63 | NodeStates(); | 63 | NodeStates(); |
| 64 | ~NodeStates(); | 64 | ~NodeStates(); |
| 65 | 65 | ||
| 66 | void Initialize(std::size_t _node_count); | 66 | void Initialize(std::size_t node_count_); |
| 67 | bool Tsort(EdgeMatrix& edge_matrix); | 67 | bool Tsort(EdgeMatrix& edge_matrix); |
| 68 | std::size_t GetIndexPos() const; | 68 | std::size_t GetIndexPos() const; |
| 69 | const std::vector<s32>& GetIndexList() const; | 69 | const std::vector<s32>& GetIndexList() const; |
| @@ -72,15 +72,15 @@ private: | |||
| 72 | void PushTsortResult(s32 index); | 72 | void PushTsortResult(s32 index); |
| 73 | bool DepthFirstSearch(EdgeMatrix& edge_matrix); | 73 | bool DepthFirstSearch(EdgeMatrix& edge_matrix); |
| 74 | void ResetState(); | 74 | void ResetState(); |
| 75 | void UpdateState(NodeStates::State state, std::size_t i); | 75 | void UpdateState(State state, std::size_t i); |
| 76 | NodeStates::State GetState(std::size_t i); | 76 | State GetState(std::size_t i); |
| 77 | 77 | ||
| 78 | std::size_t node_count{}; | 78 | std::size_t node_count{}; |
| 79 | std::vector<bool> was_node_found{}; | 79 | std::vector<bool> was_node_found{}; |
| 80 | std::vector<bool> was_node_completed{}; | 80 | std::vector<bool> was_node_completed{}; |
| 81 | std::size_t index_pos{}; | 81 | std::size_t index_pos{}; |
| 82 | std::vector<s32> index_list{}; | 82 | std::vector<s32> index_list{}; |
| 83 | NodeStates::Stack index_stack{}; | 83 | Stack index_stack{}; |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | enum class SplitterMagic : u32_le { | 86 | enum class SplitterMagic : u32_le { |
| @@ -97,8 +97,7 @@ public: | |||
| 97 | s32_le data_count{}; | 97 | s32_le data_count{}; |
| 98 | INSERT_PADDING_WORDS(5); | 98 | INSERT_PADDING_WORDS(5); |
| 99 | }; | 99 | }; |
| 100 | static_assert(sizeof(SplitterInfo::InHeader) == 0x20, | 100 | static_assert(sizeof(InHeader) == 0x20, "SplitterInfo::InHeader is an invalid size"); |
| 101 | "SplitterInfo::InHeader is an invalid size"); | ||
| 102 | 101 | ||
| 103 | struct InInfoPrams { | 102 | struct InInfoPrams { |
| 104 | SplitterMagic magic{}; | 103 | SplitterMagic magic{}; |
| @@ -107,8 +106,7 @@ public: | |||
| 107 | s32_le length{}; | 106 | s32_le length{}; |
| 108 | s32_le resource_id_base{}; | 107 | s32_le resource_id_base{}; |
| 109 | }; | 108 | }; |
| 110 | static_assert(sizeof(SplitterInfo::InInfoPrams) == 0x14, | 109 | static_assert(sizeof(InInfoPrams) == 0x14, "SplitterInfo::InInfoPrams is an invalid size"); |
| 111 | "SplitterInfo::InInfoPrams is an invalid size"); | ||
| 112 | 110 | ||
| 113 | struct InDestinationParams { | 111 | struct InDestinationParams { |
| 114 | SplitterMagic magic{}; | 112 | SplitterMagic magic{}; |
| @@ -118,13 +116,13 @@ public: | |||
| 118 | bool in_use{}; | 116 | bool in_use{}; |
| 119 | INSERT_PADDING_BYTES(3); | 117 | INSERT_PADDING_BYTES(3); |
| 120 | }; | 118 | }; |
| 121 | static_assert(sizeof(SplitterInfo::InDestinationParams) == 0x70, | 119 | static_assert(sizeof(InDestinationParams) == 0x70, |
| 122 | "SplitterInfo::InDestinationParams is an invalid size"); | 120 | "SplitterInfo::InDestinationParams is an invalid size"); |
| 123 | }; | 121 | }; |
| 124 | 122 | ||
| 125 | class ServerSplitterDestinationData { | 123 | class ServerSplitterDestinationData { |
| 126 | public: | 124 | public: |
| 127 | explicit ServerSplitterDestinationData(s32 id); | 125 | explicit ServerSplitterDestinationData(s32 id_); |
| 128 | ~ServerSplitterDestinationData(); | 126 | ~ServerSplitterDestinationData(); |
| 129 | 127 | ||
| 130 | void Update(SplitterInfo::InDestinationParams& header); | 128 | void Update(SplitterInfo::InDestinationParams& header); |
| @@ -153,7 +151,7 @@ private: | |||
| 153 | 151 | ||
| 154 | class ServerSplitterInfo { | 152 | class ServerSplitterInfo { |
| 155 | public: | 153 | public: |
| 156 | explicit ServerSplitterInfo(s32 id); | 154 | explicit ServerSplitterInfo(s32 id_); |
| 157 | ~ServerSplitterInfo(); | 155 | ~ServerSplitterInfo(); |
| 158 | 156 | ||
| 159 | void InitializeInfos(); | 157 | void InitializeInfos(); |
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index 41bc2f4d6..eca296589 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp | |||
| @@ -31,10 +31,10 @@ u32 Stream::GetNumChannels() const { | |||
| 31 | return {}; | 31 | return {}; |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format format, | 34 | Stream::Stream(Core::Timing::CoreTiming& core_timing_, u32 sample_rate_, Format format_, |
| 35 | ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_) | 35 | ReleaseCallback&& release_callback_, SinkStream& sink_stream_, std::string&& name_) |
| 36 | : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)}, | 36 | : sample_rate{sample_rate_}, format{format_}, release_callback{std::move(release_callback_)}, |
| 37 | sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} { | 37 | sink_stream{sink_stream_}, core_timing{core_timing_}, name{std::move(name_)} { |
| 38 | release_event = | 38 | release_event = |
| 39 | Core::Timing::CreateEvent(name, [this](std::uintptr_t, std::chrono::nanoseconds ns_late) { | 39 | Core::Timing::CreateEvent(name, [this](std::uintptr_t, std::chrono::nanoseconds ns_late) { |
| 40 | ReleaseActiveBuffer(ns_late); | 40 | ReleaseActiveBuffer(ns_late); |
| @@ -122,7 +122,7 @@ bool Stream::QueueBuffer(BufferPtr&& buffer) { | |||
| 122 | return false; | 122 | return false; |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | bool Stream::ContainsBuffer(Buffer::Tag tag) const { | 125 | bool Stream::ContainsBuffer([[maybe_unused]] Buffer::Tag tag) const { |
| 126 | UNIMPLEMENTED(); | 126 | UNIMPLEMENTED(); |
| 127 | return {}; | 127 | return {}; |
| 128 | } | 128 | } |
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h index 71c2d0b4f..506ac536b 100644 --- a/src/audio_core/stream.h +++ b/src/audio_core/stream.h | |||
| @@ -44,8 +44,8 @@ public: | |||
| 44 | /// Callback function type, used to change guest state on a buffer being released | 44 | /// Callback function type, used to change guest state on a buffer being released |
| 45 | using ReleaseCallback = std::function<void()>; | 45 | using ReleaseCallback = std::function<void()>; |
| 46 | 46 | ||
| 47 | Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format format, | 47 | Stream(Core::Timing::CoreTiming& core_timing_, u32 sample_rate_, Format format_, |
| 48 | ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_); | 48 | ReleaseCallback&& release_callback_, SinkStream& sink_stream_, std::string&& name_); |
| 49 | 49 | ||
| 50 | /// Plays the audio stream | 50 | /// Plays the audio stream |
| 51 | void Play(); | 51 | void Play(); |
diff --git a/src/audio_core/voice_context.cpp b/src/audio_core/voice_context.cpp index c46ee55f1..867b8fc6b 100644 --- a/src/audio_core/voice_context.cpp +++ b/src/audio_core/voice_context.cpp | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | 8 | ||
| 9 | namespace AudioCore { | 9 | namespace AudioCore { |
| 10 | 10 | ||
| 11 | ServerVoiceChannelResource::ServerVoiceChannelResource(s32 id) : id(id) {} | 11 | ServerVoiceChannelResource::ServerVoiceChannelResource(s32 id_) : id(id_) {} |
| 12 | ServerVoiceChannelResource::~ServerVoiceChannelResource() = default; | 12 | ServerVoiceChannelResource::~ServerVoiceChannelResource() = default; |
| 13 | 13 | ||
| 14 | bool ServerVoiceChannelResource::InUse() const { | 14 | bool ServerVoiceChannelResource::InUse() const { |
| @@ -209,7 +209,8 @@ void ServerVoiceInfo::UpdateWaveBuffers( | |||
| 209 | 209 | ||
| 210 | void ServerVoiceInfo::UpdateWaveBuffer(ServerWaveBuffer& out_wavebuffer, | 210 | void ServerVoiceInfo::UpdateWaveBuffer(ServerWaveBuffer& out_wavebuffer, |
| 211 | const WaveBuffer& in_wave_buffer, SampleFormat sample_format, | 211 | const WaveBuffer& in_wave_buffer, SampleFormat sample_format, |
| 212 | bool is_buffer_valid, BehaviorInfo& behavior_info) { | 212 | bool is_buffer_valid, |
| 213 | [[maybe_unused]] BehaviorInfo& behavior_info) { | ||
| 213 | if (!is_buffer_valid && out_wavebuffer.sent_to_dsp) { | 214 | if (!is_buffer_valid && out_wavebuffer.sent_to_dsp) { |
| 214 | out_wavebuffer.buffer_address = 0; | 215 | out_wavebuffer.buffer_address = 0; |
| 215 | out_wavebuffer.buffer_size = 0; | 216 | out_wavebuffer.buffer_size = 0; |
| @@ -400,7 +401,7 @@ bool ServerVoiceInfo::HasValidWaveBuffer(const VoiceState* state) const { | |||
| 400 | return std::find(valid_wb.begin(), valid_wb.end(), true) != valid_wb.end(); | 401 | return std::find(valid_wb.begin(), valid_wb.end(), true) != valid_wb.end(); |
| 401 | } | 402 | } |
| 402 | 403 | ||
| 403 | VoiceContext::VoiceContext(std::size_t voice_count) : voice_count(voice_count) { | 404 | VoiceContext::VoiceContext(std::size_t voice_count_) : voice_count{voice_count_} { |
| 404 | for (std::size_t i = 0; i < voice_count; i++) { | 405 | for (std::size_t i = 0; i < voice_count; i++) { |
| 405 | voice_channel_resources.emplace_back(static_cast<s32>(i)); | 406 | voice_channel_resources.emplace_back(static_cast<s32>(i)); |
| 406 | sorted_voice_info.push_back(&voice_info.emplace_back()); | 407 | sorted_voice_info.push_back(&voice_info.emplace_back()); |
diff --git a/src/audio_core/voice_context.h b/src/audio_core/voice_context.h index 59d3d7dfb..863248761 100644 --- a/src/audio_core/voice_context.h +++ b/src/audio_core/voice_context.h | |||
| @@ -118,12 +118,12 @@ public: | |||
| 118 | bool in_use{}; | 118 | bool in_use{}; |
| 119 | INSERT_PADDING_BYTES(11); | 119 | INSERT_PADDING_BYTES(11); |
| 120 | }; | 120 | }; |
| 121 | static_assert(sizeof(VoiceChannelResource::InParams) == 0x70, "InParams is an invalid size"); | 121 | static_assert(sizeof(InParams) == 0x70, "InParams is an invalid size"); |
| 122 | }; | 122 | }; |
| 123 | 123 | ||
| 124 | class ServerVoiceChannelResource { | 124 | class ServerVoiceChannelResource { |
| 125 | public: | 125 | public: |
| 126 | explicit ServerVoiceChannelResource(s32 id); | 126 | explicit ServerVoiceChannelResource(s32 id_); |
| 127 | ~ServerVoiceChannelResource(); | 127 | ~ServerVoiceChannelResource(); |
| 128 | 128 | ||
| 129 | bool InUse() const; | 129 | bool InUse() const; |
| @@ -174,7 +174,7 @@ public: | |||
| 174 | BehaviorFlags behavior_flags{}; | 174 | BehaviorFlags behavior_flags{}; |
| 175 | INSERT_PADDING_BYTES(16); | 175 | INSERT_PADDING_BYTES(16); |
| 176 | }; | 176 | }; |
| 177 | static_assert(sizeof(VoiceInfo::InParams) == 0x170, "InParams is an invalid size"); | 177 | static_assert(sizeof(InParams) == 0x170, "InParams is an invalid size"); |
| 178 | 178 | ||
| 179 | struct OutParams { | 179 | struct OutParams { |
| 180 | u64_le played_sample_count{}; | 180 | u64_le played_sample_count{}; |
| @@ -182,7 +182,7 @@ public: | |||
| 182 | u8 voice_dropped{}; | 182 | u8 voice_dropped{}; |
| 183 | INSERT_PADDING_BYTES(3); | 183 | INSERT_PADDING_BYTES(3); |
| 184 | }; | 184 | }; |
| 185 | static_assert(sizeof(VoiceInfo::OutParams) == 0x10, "OutParams is an invalid size"); | 185 | static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size"); |
| 186 | }; | 186 | }; |
| 187 | 187 | ||
| 188 | class ServerVoiceInfo { | 188 | class ServerVoiceInfo { |
| @@ -263,7 +263,7 @@ private: | |||
| 263 | 263 | ||
| 264 | class VoiceContext { | 264 | class VoiceContext { |
| 265 | public: | 265 | public: |
| 266 | VoiceContext(std::size_t voice_count); | 266 | explicit VoiceContext(std::size_t voice_count_); |
| 267 | ~VoiceContext(); | 267 | ~VoiceContext(); |
| 268 | 268 | ||
| 269 | std::size_t GetVoiceCount() const; | 269 | std::size_t GetVoiceCount() const; |
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index d20e6c3b5..56c7e21f5 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -112,6 +112,7 @@ add_library(common STATIC | |||
| 112 | common_paths.h | 112 | common_paths.h |
| 113 | common_types.h | 113 | common_types.h |
| 114 | concepts.h | 114 | concepts.h |
| 115 | div_ceil.h | ||
| 115 | dynamic_library.cpp | 116 | dynamic_library.cpp |
| 116 | dynamic_library.h | 117 | dynamic_library.h |
| 117 | fiber.cpp | 118 | fiber.cpp |
diff --git a/src/common/div_ceil.h b/src/common/div_ceil.h new file mode 100644 index 000000000..6b2c48f91 --- /dev/null +++ b/src/common/div_ceil.h | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | // Copyright 2020 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <cstddef> | ||
| 8 | #include <type_traits> | ||
| 9 | |||
| 10 | namespace Common { | ||
| 11 | |||
| 12 | /// Ceiled integer division. | ||
| 13 | template <typename N, typename D> | ||
| 14 | requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeil( | ||
| 15 | N number, D divisor) { | ||
| 16 | return (static_cast<D>(number) + divisor - 1) / divisor; | ||
| 17 | } | ||
| 18 | |||
| 19 | /// Ceiled integer division with logarithmic divisor in base 2 | ||
| 20 | template <typename N, typename D> | ||
| 21 | requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeilLog2( | ||
| 22 | N value, D alignment_log2) { | ||
| 23 | return (static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2; | ||
| 24 | } | ||
| 25 | |||
| 26 | } // namespace Common | ||
diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp index 452a2837e..a8c143f85 100644 --- a/src/common/wall_clock.cpp +++ b/src/common/wall_clock.cpp | |||
| @@ -17,8 +17,8 @@ using base_time_point = std::chrono::time_point<base_timer>; | |||
| 17 | 17 | ||
| 18 | class StandardWallClock final : public WallClock { | 18 | class StandardWallClock final : public WallClock { |
| 19 | public: | 19 | public: |
| 20 | StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency) | 20 | explicit 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) { |
| 22 | start_time = base_timer::now(); | 22 | start_time = base_timer::now(); |
| 23 | } | 23 | } |
| 24 | 24 | ||
diff --git a/src/common/wall_clock.h b/src/common/wall_clock.h index bc7adfbf8..cef3e9499 100644 --- a/src/common/wall_clock.h +++ b/src/common/wall_clock.h | |||
| @@ -38,9 +38,9 @@ public: | |||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | protected: | 40 | protected: |
| 41 | WallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, bool is_native) | 41 | explicit WallClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_, bool is_native_) |
| 42 | : emulated_cpu_frequency{emulated_cpu_frequency}, | 42 | : emulated_cpu_frequency{emulated_cpu_frequency_}, |
| 43 | emulated_clock_frequency{emulated_clock_frequency}, is_native{is_native} {} | 43 | emulated_clock_frequency{emulated_clock_frequency_}, is_native{is_native_} {} |
| 44 | 44 | ||
| 45 | u64 emulated_cpu_frequency; | 45 | u64 emulated_cpu_frequency; |
| 46 | u64 emulated_clock_frequency; | 46 | u64 emulated_clock_frequency; |
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index 424b39b1f..eb8a7782f 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp | |||
| @@ -43,10 +43,10 @@ u64 EstimateRDTSCFrequency() { | |||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | namespace X64 { | 45 | namespace X64 { |
| 46 | NativeClock::NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, | 46 | NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_, |
| 47 | u64 rtsc_frequency) | 47 | u64 rtsc_frequency_) |
| 48 | : WallClock(emulated_cpu_frequency, emulated_clock_frequency, true), rtsc_frequency{ | 48 | : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{ |
| 49 | rtsc_frequency} { | 49 | rtsc_frequency_} { |
| 50 | _mm_mfence(); | 50 | _mm_mfence(); |
| 51 | last_measure = __rdtsc(); | 51 | last_measure = __rdtsc(); |
| 52 | accumulated_ticks = 0U; | 52 | accumulated_ticks = 0U; |
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h index 97aab6ac9..6d1e32ac8 100644 --- a/src/common/x64/native_clock.h +++ b/src/common/x64/native_clock.h | |||
| @@ -14,7 +14,8 @@ namespace Common { | |||
| 14 | namespace X64 { | 14 | namespace X64 { |
| 15 | class NativeClock final : 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 | explicit NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_, |
| 18 | u64 rtsc_frequency_); | ||
| 18 | 19 | ||
| 19 | std::chrono::nanoseconds GetTimeNS() override; | 20 | std::chrono::nanoseconds GetTimeNS() override; |
| 20 | 21 | ||
diff --git a/src/core/core_timing.h b/src/core/core_timing.h index b0b6036e4..77ff4c6fe 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h | |||
| @@ -27,8 +27,8 @@ using TimedCallback = | |||
| 27 | 27 | ||
| 28 | /// Contains the characteristics of a particular event. | 28 | /// Contains the characteristics of a particular event. |
| 29 | struct EventType { | 29 | struct EventType { |
| 30 | EventType(TimedCallback&& callback, std::string&& name) | 30 | explicit EventType(TimedCallback&& callback_, std::string&& name_) |
| 31 | : callback{std::move(callback)}, name{std::move(name)} {} | 31 | : callback{std::move(callback_)}, name{std::move(name_)} {} |
| 32 | 32 | ||
| 33 | /// The event's callback function. | 33 | /// The event's callback function. |
| 34 | TimedCallback callback; | 34 | TimedCallback callback; |
| @@ -67,8 +67,8 @@ public: | |||
| 67 | void Shutdown(); | 67 | void Shutdown(); |
| 68 | 68 | ||
| 69 | /// Sets if emulation is multicore or single core, must be set before Initialize | 69 | /// Sets if emulation is multicore or single core, must be set before Initialize |
| 70 | void SetMulticore(bool is_multicore) { | 70 | void SetMulticore(bool is_multicore_) { |
| 71 | this->is_multicore = is_multicore; | 71 | is_multicore = is_multicore_; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | /// Check if it's using host timing. | 74 | /// Check if it's using host timing. |
diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h index 11c2e96ca..de51a754e 100644 --- a/src/core/frontend/input.h +++ b/src/core/frontend/input.h | |||
| @@ -163,10 +163,15 @@ using MotionStatus = std::tuple<Common::Vec3<float>, Common::Vec3<float>, Common | |||
| 163 | using MotionDevice = InputDevice<MotionStatus>; | 163 | using MotionDevice = InputDevice<MotionStatus>; |
| 164 | 164 | ||
| 165 | /** | 165 | /** |
| 166 | * A touch device is an input device that returns a tuple of two floats and a bool. The floats are | 166 | * A touch status is an object that returns a tuple of two floats and a bool. The floats are |
| 167 | * x and y coordinates in the range 0.0 - 1.0, and the bool indicates whether it is pressed. | 167 | * x and y coordinates in the range 0.0 - 1.0, and the bool indicates whether it is pressed. |
| 168 | */ | 168 | */ |
| 169 | using TouchDevice = InputDevice<std::tuple<float, float, bool>>; | 169 | using TouchStatus = std::tuple<float, float, bool>; |
| 170 | |||
| 171 | /** | ||
| 172 | * A touch device is an input device that returns a touch status object | ||
| 173 | */ | ||
| 174 | using TouchDevice = InputDevice<TouchStatus>; | ||
| 170 | 175 | ||
| 171 | /** | 176 | /** |
| 172 | * A mouse device is an input device that returns a tuple of two floats and four ints. | 177 | * A mouse device is an input device that returns a tuple of two floats and four ints. |
diff --git a/src/core/hle/result.h b/src/core/hle/result.h index b6bdbd988..8feda7ad7 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h | |||
| @@ -119,7 +119,7 @@ union ResultCode { | |||
| 119 | BitField<0, 9, ErrorModule> module; | 119 | BitField<0, 9, ErrorModule> module; |
| 120 | BitField<9, 13, u32> description; | 120 | BitField<9, 13, u32> description; |
| 121 | 121 | ||
| 122 | constexpr explicit ResultCode(u32 raw) : raw(raw) {} | 122 | constexpr explicit ResultCode(u32 raw_) : raw(raw_) {} |
| 123 | 123 | ||
| 124 | constexpr ResultCode(ErrorModule module_, u32 description_) | 124 | constexpr ResultCode(ErrorModule module_, u32 description_) |
| 125 | : raw(module.FormatValue(module_) | description.FormatValue(description_)) {} | 125 | : raw(module.FormatValue(module_) | description.FormatValue(description_)) {} |
diff --git a/src/core/settings.h b/src/core/settings.h index 3df611d5b..8e076f7ef 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -178,9 +178,7 @@ struct Values { | |||
| 178 | 178 | ||
| 179 | Setting<bool> motion_enabled; | 179 | Setting<bool> motion_enabled; |
| 180 | std::string motion_device; | 180 | std::string motion_device; |
| 181 | std::string udp_input_address; | 181 | std::string udp_input_servers; |
| 182 | u16 udp_input_port; | ||
| 183 | u8 udp_pad_index; | ||
| 184 | 182 | ||
| 185 | bool mouse_enabled; | 183 | bool mouse_enabled; |
| 186 | std::string mouse_device; | 184 | std::string mouse_device; |
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index 5682e5ca5..38ab31898 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt | |||
| @@ -5,8 +5,6 @@ add_library(input_common STATIC | |||
| 5 | keyboard.h | 5 | keyboard.h |
| 6 | main.cpp | 6 | main.cpp |
| 7 | main.h | 7 | main.h |
| 8 | motion_emu.cpp | ||
| 9 | motion_emu.h | ||
| 10 | motion_from_button.cpp | 8 | motion_from_button.cpp |
| 11 | motion_from_button.h | 9 | motion_from_button.h |
| 12 | motion_input.cpp | 10 | motion_input.cpp |
| @@ -19,6 +17,10 @@ add_library(input_common STATIC | |||
| 19 | gcadapter/gc_adapter.h | 17 | gcadapter/gc_adapter.h |
| 20 | gcadapter/gc_poller.cpp | 18 | gcadapter/gc_poller.cpp |
| 21 | gcadapter/gc_poller.h | 19 | gcadapter/gc_poller.h |
| 20 | mouse/mouse_input.cpp | ||
| 21 | mouse/mouse_input.h | ||
| 22 | mouse/mouse_poller.cpp | ||
| 23 | mouse/mouse_poller.h | ||
| 22 | sdl/sdl.cpp | 24 | sdl/sdl.cpp |
| 23 | sdl/sdl.h | 25 | sdl/sdl.h |
| 24 | udp/client.cpp | 26 | udp/client.cpp |
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp index e59ad4ff5..7c4e7dd3b 100644 --- a/src/input_common/main.cpp +++ b/src/input_common/main.cpp | |||
| @@ -10,8 +10,9 @@ | |||
| 10 | #include "input_common/gcadapter/gc_poller.h" | 10 | #include "input_common/gcadapter/gc_poller.h" |
| 11 | #include "input_common/keyboard.h" | 11 | #include "input_common/keyboard.h" |
| 12 | #include "input_common/main.h" | 12 | #include "input_common/main.h" |
| 13 | #include "input_common/motion_emu.h" | ||
| 14 | #include "input_common/motion_from_button.h" | 13 | #include "input_common/motion_from_button.h" |
| 14 | #include "input_common/mouse/mouse_input.h" | ||
| 15 | #include "input_common/mouse/mouse_poller.h" | ||
| 15 | #include "input_common/touch_from_button.h" | 16 | #include "input_common/touch_from_button.h" |
| 16 | #include "input_common/udp/client.h" | 17 | #include "input_common/udp/client.h" |
| 17 | #include "input_common/udp/udp.h" | 18 | #include "input_common/udp/udp.h" |
| @@ -37,8 +38,6 @@ struct InputSubsystem::Impl { | |||
| 37 | std::make_shared<AnalogFromButton>()); | 38 | std::make_shared<AnalogFromButton>()); |
| 38 | Input::RegisterFactory<Input::MotionDevice>("keyboard", | 39 | Input::RegisterFactory<Input::MotionDevice>("keyboard", |
| 39 | std::make_shared<MotionFromButton>()); | 40 | std::make_shared<MotionFromButton>()); |
| 40 | motion_emu = std::make_shared<MotionEmu>(); | ||
| 41 | Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu); | ||
| 42 | Input::RegisterFactory<Input::TouchDevice>("touch_from_button", | 41 | Input::RegisterFactory<Input::TouchDevice>("touch_from_button", |
| 43 | std::make_shared<TouchFromButtonFactory>()); | 42 | std::make_shared<TouchFromButtonFactory>()); |
| 44 | 43 | ||
| @@ -51,6 +50,16 @@ struct InputSubsystem::Impl { | |||
| 51 | Input::RegisterFactory<Input::MotionDevice>("cemuhookudp", udpmotion); | 50 | Input::RegisterFactory<Input::MotionDevice>("cemuhookudp", udpmotion); |
| 52 | udptouch = std::make_shared<UDPTouchFactory>(udp); | 51 | udptouch = std::make_shared<UDPTouchFactory>(udp); |
| 53 | Input::RegisterFactory<Input::TouchDevice>("cemuhookudp", udptouch); | 52 | Input::RegisterFactory<Input::TouchDevice>("cemuhookudp", udptouch); |
| 53 | |||
| 54 | mouse = std::make_shared<MouseInput::Mouse>(); | ||
| 55 | mousebuttons = std::make_shared<MouseButtonFactory>(mouse); | ||
| 56 | Input::RegisterFactory<Input::ButtonDevice>("mouse", mousebuttons); | ||
| 57 | mouseanalog = std::make_shared<MouseAnalogFactory>(mouse); | ||
| 58 | Input::RegisterFactory<Input::AnalogDevice>("mouse", mouseanalog); | ||
| 59 | mousemotion = std::make_shared<MouseMotionFactory>(mouse); | ||
| 60 | Input::RegisterFactory<Input::MotionDevice>("mouse", mousemotion); | ||
| 61 | mousetouch = std::make_shared<MouseTouchFactory>(mouse); | ||
| 62 | Input::RegisterFactory<Input::TouchDevice>("mouse", mousetouch); | ||
| 54 | } | 63 | } |
| 55 | 64 | ||
| 56 | void Shutdown() { | 65 | void Shutdown() { |
| @@ -58,8 +67,6 @@ struct InputSubsystem::Impl { | |||
| 58 | Input::UnregisterFactory<Input::MotionDevice>("keyboard"); | 67 | Input::UnregisterFactory<Input::MotionDevice>("keyboard"); |
| 59 | keyboard.reset(); | 68 | keyboard.reset(); |
| 60 | Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button"); | 69 | Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button"); |
| 61 | Input::UnregisterFactory<Input::MotionDevice>("motion_emu"); | ||
| 62 | motion_emu.reset(); | ||
| 63 | Input::UnregisterFactory<Input::TouchDevice>("touch_from_button"); | 70 | Input::UnregisterFactory<Input::TouchDevice>("touch_from_button"); |
| 64 | #ifdef HAVE_SDL2 | 71 | #ifdef HAVE_SDL2 |
| 65 | sdl.reset(); | 72 | sdl.reset(); |
| @@ -77,6 +84,16 @@ struct InputSubsystem::Impl { | |||
| 77 | 84 | ||
| 78 | udpmotion.reset(); | 85 | udpmotion.reset(); |
| 79 | udptouch.reset(); | 86 | udptouch.reset(); |
| 87 | |||
| 88 | Input::UnregisterFactory<Input::ButtonDevice>("mouse"); | ||
| 89 | Input::UnregisterFactory<Input::AnalogDevice>("mouse"); | ||
| 90 | Input::UnregisterFactory<Input::MotionDevice>("mouse"); | ||
| 91 | Input::UnregisterFactory<Input::TouchDevice>("mouse"); | ||
| 92 | |||
| 93 | mousebuttons.reset(); | ||
| 94 | mouseanalog.reset(); | ||
| 95 | mousemotion.reset(); | ||
| 96 | mousetouch.reset(); | ||
| 80 | } | 97 | } |
| 81 | 98 | ||
| 82 | [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const { | 99 | [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const { |
| @@ -140,7 +157,6 @@ struct InputSubsystem::Impl { | |||
| 140 | } | 157 | } |
| 141 | 158 | ||
| 142 | std::shared_ptr<Keyboard> keyboard; | 159 | std::shared_ptr<Keyboard> keyboard; |
| 143 | std::shared_ptr<MotionEmu> motion_emu; | ||
| 144 | #ifdef HAVE_SDL2 | 160 | #ifdef HAVE_SDL2 |
| 145 | std::unique_ptr<SDL::State> sdl; | 161 | std::unique_ptr<SDL::State> sdl; |
| 146 | #endif | 162 | #endif |
| @@ -149,8 +165,13 @@ struct InputSubsystem::Impl { | |||
| 149 | std::shared_ptr<GCVibrationFactory> gcvibration; | 165 | std::shared_ptr<GCVibrationFactory> gcvibration; |
| 150 | std::shared_ptr<UDPMotionFactory> udpmotion; | 166 | std::shared_ptr<UDPMotionFactory> udpmotion; |
| 151 | std::shared_ptr<UDPTouchFactory> udptouch; | 167 | std::shared_ptr<UDPTouchFactory> udptouch; |
| 168 | std::shared_ptr<MouseButtonFactory> mousebuttons; | ||
| 169 | std::shared_ptr<MouseAnalogFactory> mouseanalog; | ||
| 170 | std::shared_ptr<MouseMotionFactory> mousemotion; | ||
| 171 | std::shared_ptr<MouseTouchFactory> mousetouch; | ||
| 152 | std::shared_ptr<CemuhookUDP::Client> udp; | 172 | std::shared_ptr<CemuhookUDP::Client> udp; |
| 153 | std::shared_ptr<GCAdapter::Adapter> gcadapter; | 173 | std::shared_ptr<GCAdapter::Adapter> gcadapter; |
| 174 | std::shared_ptr<MouseInput::Mouse> mouse; | ||
| 154 | }; | 175 | }; |
| 155 | 176 | ||
| 156 | InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {} | 177 | InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {} |
| @@ -173,12 +194,12 @@ const Keyboard* InputSubsystem::GetKeyboard() const { | |||
| 173 | return impl->keyboard.get(); | 194 | return impl->keyboard.get(); |
| 174 | } | 195 | } |
| 175 | 196 | ||
| 176 | MotionEmu* InputSubsystem::GetMotionEmu() { | 197 | MouseInput::Mouse* InputSubsystem::GetMouse() { |
| 177 | return impl->motion_emu.get(); | 198 | return impl->mouse.get(); |
| 178 | } | 199 | } |
| 179 | 200 | ||
| 180 | const MotionEmu* InputSubsystem::GetMotionEmu() const { | 201 | const MouseInput::Mouse* InputSubsystem::GetMouse() const { |
| 181 | return impl->motion_emu.get(); | 202 | return impl->mouse.get(); |
| 182 | } | 203 | } |
| 183 | 204 | ||
| 184 | std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { | 205 | std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { |
| @@ -229,11 +250,43 @@ const UDPTouchFactory* InputSubsystem::GetUDPTouch() const { | |||
| 229 | return impl->udptouch.get(); | 250 | return impl->udptouch.get(); |
| 230 | } | 251 | } |
| 231 | 252 | ||
| 253 | MouseButtonFactory* InputSubsystem::GetMouseButtons() { | ||
| 254 | return impl->mousebuttons.get(); | ||
| 255 | } | ||
| 256 | |||
| 257 | const MouseButtonFactory* InputSubsystem::GetMouseButtons() const { | ||
| 258 | return impl->mousebuttons.get(); | ||
| 259 | } | ||
| 260 | |||
| 261 | MouseAnalogFactory* InputSubsystem::GetMouseAnalogs() { | ||
| 262 | return impl->mouseanalog.get(); | ||
| 263 | } | ||
| 264 | |||
| 265 | const MouseAnalogFactory* InputSubsystem::GetMouseAnalogs() const { | ||
| 266 | return impl->mouseanalog.get(); | ||
| 267 | } | ||
| 268 | |||
| 269 | MouseMotionFactory* InputSubsystem::GetMouseMotions() { | ||
| 270 | return impl->mousemotion.get(); | ||
| 271 | } | ||
| 272 | |||
| 273 | const MouseMotionFactory* InputSubsystem::GetMouseMotions() const { | ||
| 274 | return impl->mousemotion.get(); | ||
| 275 | } | ||
| 276 | |||
| 277 | MouseTouchFactory* InputSubsystem::GetMouseTouch() { | ||
| 278 | return impl->mousetouch.get(); | ||
| 279 | } | ||
| 280 | |||
| 281 | const MouseTouchFactory* InputSubsystem::GetMouseTouch() const { | ||
| 282 | return impl->mousetouch.get(); | ||
| 283 | } | ||
| 284 | |||
| 232 | void InputSubsystem::ReloadInputDevices() { | 285 | void InputSubsystem::ReloadInputDevices() { |
| 233 | if (!impl->udp) { | 286 | if (!impl->udp) { |
| 234 | return; | 287 | return; |
| 235 | } | 288 | } |
| 236 | impl->udp->ReloadUDPClient(); | 289 | impl->udp->ReloadSockets(); |
| 237 | } | 290 | } |
| 238 | 291 | ||
| 239 | std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers( | 292 | std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers( |
diff --git a/src/input_common/main.h b/src/input_common/main.h index dded3f1ef..5d6f26385 100644 --- a/src/input_common/main.h +++ b/src/input_common/main.h | |||
| @@ -25,6 +25,10 @@ namespace Settings::NativeMotion { | |||
| 25 | enum Values : int; | 25 | enum Values : int; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | namespace MouseInput { | ||
| 29 | class Mouse; | ||
| 30 | } | ||
| 31 | |||
| 28 | namespace InputCommon { | 32 | namespace InputCommon { |
| 29 | namespace Polling { | 33 | namespace Polling { |
| 30 | 34 | ||
| @@ -56,8 +60,11 @@ class GCAnalogFactory; | |||
| 56 | class GCButtonFactory; | 60 | class GCButtonFactory; |
| 57 | class UDPMotionFactory; | 61 | class UDPMotionFactory; |
| 58 | class UDPTouchFactory; | 62 | class UDPTouchFactory; |
| 63 | class MouseButtonFactory; | ||
| 64 | class MouseAnalogFactory; | ||
| 65 | class MouseMotionFactory; | ||
| 66 | class MouseTouchFactory; | ||
| 59 | class Keyboard; | 67 | class Keyboard; |
| 60 | class MotionEmu; | ||
| 61 | 68 | ||
| 62 | /** | 69 | /** |
| 63 | * Given a ParamPackage for a Device returned from `GetInputDevices`, attempt to get the default | 70 | * Given a ParamPackage for a Device returned from `GetInputDevices`, attempt to get the default |
| @@ -90,11 +97,11 @@ public: | |||
| 90 | /// Retrieves the underlying keyboard device. | 97 | /// Retrieves the underlying keyboard device. |
| 91 | [[nodiscard]] const Keyboard* GetKeyboard() const; | 98 | [[nodiscard]] const Keyboard* GetKeyboard() const; |
| 92 | 99 | ||
| 93 | /// Retrieves the underlying motion emulation factory. | 100 | /// Retrieves the underlying mouse device. |
| 94 | [[nodiscard]] MotionEmu* GetMotionEmu(); | 101 | [[nodiscard]] MouseInput::Mouse* GetMouse(); |
| 95 | 102 | ||
| 96 | /// Retrieves the underlying motion emulation factory. | 103 | /// Retrieves the underlying mouse device. |
| 97 | [[nodiscard]] const MotionEmu* GetMotionEmu() const; | 104 | [[nodiscard]] const MouseInput::Mouse* GetMouse() const; |
| 98 | 105 | ||
| 99 | /** | 106 | /** |
| 100 | * Returns all available input devices that this Factory can create a new device with. | 107 | * Returns all available input devices that this Factory can create a new device with. |
| @@ -137,6 +144,30 @@ public: | |||
| 137 | /// Retrieves the underlying udp touch handler. | 144 | /// Retrieves the underlying udp touch handler. |
| 138 | [[nodiscard]] const UDPTouchFactory* GetUDPTouch() const; | 145 | [[nodiscard]] const UDPTouchFactory* GetUDPTouch() const; |
| 139 | 146 | ||
| 147 | /// Retrieves the underlying GameCube button handler. | ||
| 148 | [[nodiscard]] MouseButtonFactory* GetMouseButtons(); | ||
| 149 | |||
| 150 | /// Retrieves the underlying GameCube button handler. | ||
| 151 | [[nodiscard]] const MouseButtonFactory* GetMouseButtons() const; | ||
| 152 | |||
| 153 | /// Retrieves the underlying udp touch handler. | ||
| 154 | [[nodiscard]] MouseAnalogFactory* GetMouseAnalogs(); | ||
| 155 | |||
| 156 | /// Retrieves the underlying udp touch handler. | ||
| 157 | [[nodiscard]] const MouseAnalogFactory* GetMouseAnalogs() const; | ||
| 158 | |||
| 159 | /// Retrieves the underlying udp motion handler. | ||
| 160 | [[nodiscard]] MouseMotionFactory* GetMouseMotions(); | ||
| 161 | |||
| 162 | /// Retrieves the underlying udp motion handler. | ||
| 163 | [[nodiscard]] const MouseMotionFactory* GetMouseMotions() const; | ||
| 164 | |||
| 165 | /// Retrieves the underlying udp touch handler. | ||
| 166 | [[nodiscard]] MouseTouchFactory* GetMouseTouch(); | ||
| 167 | |||
| 168 | /// Retrieves the underlying udp touch handler. | ||
| 169 | [[nodiscard]] const MouseTouchFactory* GetMouseTouch() const; | ||
| 170 | |||
| 140 | /// Reloads the input devices | 171 | /// Reloads the input devices |
| 141 | void ReloadInputDevices(); | 172 | void ReloadInputDevices(); |
| 142 | 173 | ||
diff --git a/src/input_common/motion_emu.cpp b/src/input_common/motion_emu.cpp deleted file mode 100644 index d4da5596b..000000000 --- a/src/input_common/motion_emu.cpp +++ /dev/null | |||
| @@ -1,179 +0,0 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <chrono> | ||
| 7 | #include <mutex> | ||
| 8 | #include <thread> | ||
| 9 | #include <tuple> | ||
| 10 | #include "common/math_util.h" | ||
| 11 | #include "common/quaternion.h" | ||
| 12 | #include "common/thread.h" | ||
| 13 | #include "common/vector_math.h" | ||
| 14 | #include "input_common/motion_emu.h" | ||
| 15 | |||
| 16 | namespace InputCommon { | ||
| 17 | |||
| 18 | // Implementation class of the motion emulation device | ||
| 19 | class MotionEmuDevice { | ||
| 20 | public: | ||
| 21 | explicit MotionEmuDevice(int update_millisecond_, float sensitivity_) | ||
| 22 | : update_millisecond(update_millisecond_), | ||
| 23 | update_duration(std::chrono::duration_cast<std::chrono::steady_clock::duration>( | ||
| 24 | std::chrono::milliseconds(update_millisecond))), | ||
| 25 | sensitivity(sensitivity_), motion_emu_thread(&MotionEmuDevice::MotionEmuThread, this) {} | ||
| 26 | |||
| 27 | ~MotionEmuDevice() { | ||
| 28 | if (motion_emu_thread.joinable()) { | ||
| 29 | shutdown_event.Set(); | ||
| 30 | motion_emu_thread.join(); | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | void BeginTilt(int x, int y) { | ||
| 35 | mouse_origin = Common::MakeVec(x, y); | ||
| 36 | is_tilting = true; | ||
| 37 | } | ||
| 38 | |||
| 39 | void Tilt(int x, int y) { | ||
| 40 | if (!is_tilting) { | ||
| 41 | return; | ||
| 42 | } | ||
| 43 | |||
| 44 | std::lock_guard guard{tilt_mutex}; | ||
| 45 | const auto mouse_move = Common::MakeVec(x, y) - mouse_origin; | ||
| 46 | if (mouse_move.x == 0 && mouse_move.y == 0) { | ||
| 47 | tilt_angle = 0; | ||
| 48 | } else { | ||
| 49 | tilt_direction = mouse_move.Cast<float>(); | ||
| 50 | tilt_angle = | ||
| 51 | std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f, Common::PI * 0.5f); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | void EndTilt() { | ||
| 56 | std::lock_guard guard{tilt_mutex}; | ||
| 57 | tilt_angle = 0; | ||
| 58 | is_tilting = false; | ||
| 59 | } | ||
| 60 | |||
| 61 | Input::MotionStatus GetStatus() { | ||
| 62 | std::lock_guard guard{status_mutex}; | ||
| 63 | return status; | ||
| 64 | } | ||
| 65 | |||
| 66 | private: | ||
| 67 | const int update_millisecond; | ||
| 68 | const std::chrono::steady_clock::duration update_duration; | ||
| 69 | const float sensitivity; | ||
| 70 | |||
| 71 | Common::Vec2<int> mouse_origin; | ||
| 72 | |||
| 73 | std::mutex tilt_mutex; | ||
| 74 | Common::Vec2<float> tilt_direction; | ||
| 75 | float tilt_angle = 0; | ||
| 76 | |||
| 77 | bool is_tilting = false; | ||
| 78 | |||
| 79 | Common::Event shutdown_event; | ||
| 80 | |||
| 81 | Input::MotionStatus status; | ||
| 82 | std::mutex status_mutex; | ||
| 83 | |||
| 84 | // Note: always keep the thread declaration at the end so that other objects are initialized | ||
| 85 | // before this! | ||
| 86 | std::thread motion_emu_thread; | ||
| 87 | |||
| 88 | void MotionEmuThread() { | ||
| 89 | auto update_time = std::chrono::steady_clock::now(); | ||
| 90 | Common::Quaternion<float> q = Common::MakeQuaternion(Common::Vec3<float>(), 0); | ||
| 91 | |||
| 92 | while (!shutdown_event.WaitUntil(update_time)) { | ||
| 93 | update_time += update_duration; | ||
| 94 | const Common::Quaternion<float> old_q = q; | ||
| 95 | |||
| 96 | { | ||
| 97 | std::lock_guard guard{tilt_mutex}; | ||
| 98 | |||
| 99 | // Find the quaternion describing current 3DS tilting | ||
| 100 | q = Common::MakeQuaternion( | ||
| 101 | Common::MakeVec(-tilt_direction.y, 0.0f, tilt_direction.x), tilt_angle); | ||
| 102 | } | ||
| 103 | |||
| 104 | const auto inv_q = q.Inverse(); | ||
| 105 | |||
| 106 | // Set the gravity vector in world space | ||
| 107 | auto gravity = Common::MakeVec(0.0f, -1.0f, 0.0f); | ||
| 108 | |||
| 109 | // Find the angular rate vector in world space | ||
| 110 | auto angular_rate = ((q - old_q) * inv_q).xyz * 2; | ||
| 111 | angular_rate *= static_cast<float>(1000 / update_millisecond) / Common::PI * 180.0f; | ||
| 112 | |||
| 113 | // Transform the two vectors from world space to 3DS space | ||
| 114 | gravity = QuaternionRotate(inv_q, gravity); | ||
| 115 | angular_rate = QuaternionRotate(inv_q, angular_rate); | ||
| 116 | |||
| 117 | // TODO: Calculate the correct rotation vector and orientation matrix | ||
| 118 | const auto matrix4x4 = q.ToMatrix(); | ||
| 119 | const auto rotation = Common::MakeVec(0.0f, 0.0f, 0.0f); | ||
| 120 | const std::array orientation{ | ||
| 121 | Common::Vec3f(matrix4x4[0], matrix4x4[1], -matrix4x4[2]), | ||
| 122 | Common::Vec3f(matrix4x4[4], matrix4x4[5], -matrix4x4[6]), | ||
| 123 | Common::Vec3f(-matrix4x4[8], -matrix4x4[9], matrix4x4[10]), | ||
| 124 | }; | ||
| 125 | |||
| 126 | // Update the sensor state | ||
| 127 | { | ||
| 128 | std::lock_guard guard{status_mutex}; | ||
| 129 | status = std::make_tuple(gravity, angular_rate, rotation, orientation); | ||
| 130 | } | ||
| 131 | } | ||
| 132 | } | ||
| 133 | }; | ||
| 134 | |||
| 135 | // Interface wrapper held by input receiver as a unique_ptr. It holds the implementation class as | ||
| 136 | // a shared_ptr, which is also observed by the factory class as a weak_ptr. In this way the factory | ||
| 137 | // can forward all the inputs to the implementation only when it is valid. | ||
| 138 | class MotionEmuDeviceWrapper : public Input::MotionDevice { | ||
| 139 | public: | ||
| 140 | explicit MotionEmuDeviceWrapper(int update_millisecond, float sensitivity) { | ||
| 141 | device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity); | ||
| 142 | } | ||
| 143 | |||
| 144 | Input::MotionStatus GetStatus() const override { | ||
| 145 | return device->GetStatus(); | ||
| 146 | } | ||
| 147 | |||
| 148 | std::shared_ptr<MotionEmuDevice> device; | ||
| 149 | }; | ||
| 150 | |||
| 151 | std::unique_ptr<Input::MotionDevice> MotionEmu::Create(const Common::ParamPackage& params) { | ||
| 152 | const int update_period = params.Get("update_period", 100); | ||
| 153 | const float sensitivity = params.Get("sensitivity", 0.01f); | ||
| 154 | auto device_wrapper = std::make_unique<MotionEmuDeviceWrapper>(update_period, sensitivity); | ||
| 155 | // Previously created device is disconnected here. Having two motion devices for 3DS is not | ||
| 156 | // expected. | ||
| 157 | current_device = device_wrapper->device; | ||
| 158 | return device_wrapper; | ||
| 159 | } | ||
| 160 | |||
| 161 | void MotionEmu::BeginTilt(int x, int y) { | ||
| 162 | if (auto ptr = current_device.lock()) { | ||
| 163 | ptr->BeginTilt(x, y); | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | void MotionEmu::Tilt(int x, int y) { | ||
| 168 | if (auto ptr = current_device.lock()) { | ||
| 169 | ptr->Tilt(x, y); | ||
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | void MotionEmu::EndTilt() { | ||
| 174 | if (auto ptr = current_device.lock()) { | ||
| 175 | ptr->EndTilt(); | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | } // namespace InputCommon | ||
diff --git a/src/input_common/motion_emu.h b/src/input_common/motion_emu.h deleted file mode 100644 index 7a7e22467..000000000 --- a/src/input_common/motion_emu.h +++ /dev/null | |||
| @@ -1,46 +0,0 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/frontend/input.h" | ||
| 8 | |||
| 9 | namespace InputCommon { | ||
| 10 | |||
| 11 | class MotionEmuDevice; | ||
| 12 | |||
| 13 | class MotionEmu : public Input::Factory<Input::MotionDevice> { | ||
| 14 | public: | ||
| 15 | /** | ||
| 16 | * Creates a motion device emulated from mouse input | ||
| 17 | * @param params contains parameters for creating the device: | ||
| 18 | * - "update_period": update period in milliseconds | ||
| 19 | * - "sensitivity": the coefficient converting mouse movement to tilting angle | ||
| 20 | */ | ||
| 21 | std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override; | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Signals that a motion sensor tilt has begun. | ||
| 25 | * @param x the x-coordinate of the cursor | ||
| 26 | * @param y the y-coordinate of the cursor | ||
| 27 | */ | ||
| 28 | void BeginTilt(int x, int y); | ||
| 29 | |||
| 30 | /** | ||
| 31 | * Signals that a motion sensor tilt is occurring. | ||
| 32 | * @param x the x-coordinate of the cursor | ||
| 33 | * @param y the y-coordinate of the cursor | ||
| 34 | */ | ||
| 35 | void Tilt(int x, int y); | ||
| 36 | |||
| 37 | /** | ||
| 38 | * Signals that a motion sensor tilt has ended. | ||
| 39 | */ | ||
| 40 | void EndTilt(); | ||
| 41 | |||
| 42 | private: | ||
| 43 | std::weak_ptr<MotionEmuDevice> current_device; | ||
| 44 | }; | ||
| 45 | |||
| 46 | } // namespace InputCommon | ||
diff --git a/src/input_common/mouse/mouse_input.cpp b/src/input_common/mouse/mouse_input.cpp new file mode 100644 index 000000000..10786a541 --- /dev/null +++ b/src/input_common/mouse/mouse_input.cpp | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2+ | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "input_common/mouse/mouse_input.h" | ||
| 6 | |||
| 7 | namespace MouseInput { | ||
| 8 | |||
| 9 | Mouse::Mouse() { | ||
| 10 | update_thread = std::thread(&Mouse::UpdateThread, this); | ||
| 11 | } | ||
| 12 | |||
| 13 | Mouse::~Mouse() { | ||
| 14 | update_thread_running = false; | ||
| 15 | if (update_thread.joinable()) { | ||
| 16 | update_thread.join(); | ||
| 17 | } | ||
| 18 | } | ||
| 19 | |||
| 20 | void Mouse::UpdateThread() { | ||
| 21 | constexpr int update_time = 10; | ||
| 22 | while (update_thread_running) { | ||
| 23 | for (MouseInfo& info : mouse_info) { | ||
| 24 | const Common::Vec3f angular_direction{ | ||
| 25 | -info.tilt_direction.y, | ||
| 26 | 0.0f, | ||
| 27 | -info.tilt_direction.x, | ||
| 28 | }; | ||
| 29 | |||
| 30 | info.motion.SetGyroscope(angular_direction * info.tilt_speed); | ||
| 31 | info.motion.UpdateRotation(update_time * 1000); | ||
| 32 | info.motion.UpdateOrientation(update_time * 1000); | ||
| 33 | info.tilt_speed = 0; | ||
| 34 | info.data.motion = info.motion.GetMotion(); | ||
| 35 | } | ||
| 36 | if (configuring) { | ||
| 37 | UpdateYuzuSettings(); | ||
| 38 | } | ||
| 39 | std::this_thread::sleep_for(std::chrono::milliseconds(update_time)); | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | void Mouse::UpdateYuzuSettings() { | ||
| 44 | if (buttons == 0) { | ||
| 45 | return; | ||
| 46 | } | ||
| 47 | |||
| 48 | mouse_queue.Push(MouseStatus{ | ||
| 49 | .button = last_button, | ||
| 50 | }); | ||
| 51 | } | ||
| 52 | |||
| 53 | void Mouse::PressButton(int x, int y, int button_) { | ||
| 54 | const auto button_index = static_cast<std::size_t>(button_); | ||
| 55 | if (button_index >= mouse_info.size()) { | ||
| 56 | return; | ||
| 57 | } | ||
| 58 | |||
| 59 | const auto button = 1U << button_index; | ||
| 60 | buttons |= static_cast<u16>(button); | ||
| 61 | last_button = static_cast<MouseButton>(button_index); | ||
| 62 | |||
| 63 | mouse_info[button_index].mouse_origin = Common::MakeVec(x, y); | ||
| 64 | mouse_info[button_index].last_mouse_position = Common::MakeVec(x, y); | ||
| 65 | mouse_info[button_index].data.pressed = true; | ||
| 66 | } | ||
| 67 | |||
| 68 | void Mouse::MouseMove(int x, int y) { | ||
| 69 | for (MouseInfo& info : mouse_info) { | ||
| 70 | if (info.data.pressed) { | ||
| 71 | const auto mouse_move = Common::MakeVec(x, y) - info.mouse_origin; | ||
| 72 | const auto mouse_change = Common::MakeVec(x, y) - info.last_mouse_position; | ||
| 73 | info.last_mouse_position = Common::MakeVec(x, y); | ||
| 74 | info.data.axis = {mouse_move.x, -mouse_move.y}; | ||
| 75 | |||
| 76 | if (mouse_change.x == 0 && mouse_change.y == 0) { | ||
| 77 | info.tilt_speed = 0; | ||
| 78 | } else { | ||
| 79 | info.tilt_direction = mouse_change.Cast<float>(); | ||
| 80 | info.tilt_speed = info.tilt_direction.Normalize() * info.sensitivity; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | void Mouse::ReleaseButton(int button_) { | ||
| 87 | const auto button_index = static_cast<std::size_t>(button_); | ||
| 88 | if (button_index >= mouse_info.size()) { | ||
| 89 | return; | ||
| 90 | } | ||
| 91 | |||
| 92 | const auto button = 1U << button_index; | ||
| 93 | buttons &= static_cast<u16>(0xFF - button); | ||
| 94 | |||
| 95 | mouse_info[button_index].tilt_speed = 0; | ||
| 96 | mouse_info[button_index].data.pressed = false; | ||
| 97 | mouse_info[button_index].data.axis = {0, 0}; | ||
| 98 | } | ||
| 99 | |||
| 100 | void Mouse::BeginConfiguration() { | ||
| 101 | buttons = 0; | ||
| 102 | last_button = MouseButton::Undefined; | ||
| 103 | mouse_queue.Clear(); | ||
| 104 | configuring = true; | ||
| 105 | } | ||
| 106 | |||
| 107 | void Mouse::EndConfiguration() { | ||
| 108 | buttons = 0; | ||
| 109 | last_button = MouseButton::Undefined; | ||
| 110 | mouse_queue.Clear(); | ||
| 111 | configuring = false; | ||
| 112 | } | ||
| 113 | |||
| 114 | Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() { | ||
| 115 | return mouse_queue; | ||
| 116 | } | ||
| 117 | |||
| 118 | const Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() const { | ||
| 119 | return mouse_queue; | ||
| 120 | } | ||
| 121 | |||
| 122 | MouseData& Mouse::GetMouseState(std::size_t button) { | ||
| 123 | return mouse_info[button].data; | ||
| 124 | } | ||
| 125 | |||
| 126 | const MouseData& Mouse::GetMouseState(std::size_t button) const { | ||
| 127 | return mouse_info[button].data; | ||
| 128 | } | ||
| 129 | } // namespace MouseInput | ||
diff --git a/src/input_common/mouse/mouse_input.h b/src/input_common/mouse/mouse_input.h new file mode 100644 index 000000000..65e64bee7 --- /dev/null +++ b/src/input_common/mouse/mouse_input.h | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <mutex> | ||
| 9 | #include <thread> | ||
| 10 | |||
| 11 | #include "common/common_types.h" | ||
| 12 | #include "common/threadsafe_queue.h" | ||
| 13 | #include "common/vector_math.h" | ||
| 14 | #include "core/frontend/input.h" | ||
| 15 | #include "input_common/motion_input.h" | ||
| 16 | |||
| 17 | namespace MouseInput { | ||
| 18 | |||
| 19 | enum class MouseButton { | ||
| 20 | Left, | ||
| 21 | Wheel, | ||
| 22 | Right, | ||
| 23 | Foward, | ||
| 24 | Backward, | ||
| 25 | Undefined, | ||
| 26 | }; | ||
| 27 | |||
| 28 | struct MouseStatus { | ||
| 29 | MouseButton button{MouseButton::Undefined}; | ||
| 30 | }; | ||
| 31 | |||
| 32 | struct MouseData { | ||
| 33 | bool pressed{}; | ||
| 34 | std::array<int, 2> axis{}; | ||
| 35 | Input::MotionStatus motion{}; | ||
| 36 | Input::TouchStatus touch{}; | ||
| 37 | }; | ||
| 38 | |||
| 39 | class Mouse { | ||
| 40 | public: | ||
| 41 | Mouse(); | ||
| 42 | ~Mouse(); | ||
| 43 | |||
| 44 | /// Used for polling | ||
| 45 | void BeginConfiguration(); | ||
| 46 | void EndConfiguration(); | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Signals that a button is pressed. | ||
| 50 | * @param x the x-coordinate of the cursor | ||
| 51 | * @param y the y-coordinate of the cursor | ||
| 52 | * @param button_ the button pressed | ||
| 53 | */ | ||
| 54 | void PressButton(int x, int y, int button_); | ||
| 55 | |||
| 56 | /** | ||
| 57 | * Signals that mouse has moved. | ||
| 58 | * @param x the x-coordinate of the cursor | ||
| 59 | * @param y the y-coordinate of the cursor | ||
| 60 | */ | ||
| 61 | void MouseMove(int x, int y); | ||
| 62 | |||
| 63 | /** | ||
| 64 | * Signals that a motion sensor tilt has ended. | ||
| 65 | */ | ||
| 66 | void ReleaseButton(int button_); | ||
| 67 | |||
| 68 | [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue(); | ||
| 69 | [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const; | ||
| 70 | |||
| 71 | [[nodiscard]] MouseData& GetMouseState(std::size_t button); | ||
| 72 | [[nodiscard]] const MouseData& GetMouseState(std::size_t button) const; | ||
| 73 | |||
| 74 | private: | ||
| 75 | void UpdateThread(); | ||
| 76 | void UpdateYuzuSettings(); | ||
| 77 | |||
| 78 | struct MouseInfo { | ||
| 79 | InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f}; | ||
| 80 | Common::Vec2<int> mouse_origin; | ||
| 81 | Common::Vec2<int> last_mouse_position; | ||
| 82 | bool is_tilting = false; | ||
| 83 | float sensitivity{0.120f}; | ||
| 84 | |||
| 85 | float tilt_speed = 0; | ||
| 86 | Common::Vec2<float> tilt_direction; | ||
| 87 | MouseData data; | ||
| 88 | }; | ||
| 89 | |||
| 90 | u16 buttons{}; | ||
| 91 | std::thread update_thread; | ||
| 92 | MouseButton last_button{MouseButton::Undefined}; | ||
| 93 | std::array<MouseInfo, 5> mouse_info; | ||
| 94 | Common::SPSCQueue<MouseStatus> mouse_queue; | ||
| 95 | bool configuring{false}; | ||
| 96 | bool update_thread_running{true}; | ||
| 97 | }; | ||
| 98 | } // namespace MouseInput | ||
diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp new file mode 100644 index 000000000..7445ad3ad --- /dev/null +++ b/src/input_common/mouse/mouse_poller.cpp | |||
| @@ -0,0 +1,259 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <mutex> | ||
| 6 | #include <utility> | ||
| 7 | |||
| 8 | #include "common/threadsafe_queue.h" | ||
| 9 | #include "input_common/mouse/mouse_input.h" | ||
| 10 | #include "input_common/mouse/mouse_poller.h" | ||
| 11 | |||
| 12 | namespace InputCommon { | ||
| 13 | |||
| 14 | class MouseButton final : public Input::ButtonDevice { | ||
| 15 | public: | ||
| 16 | explicit MouseButton(u32 button_, const MouseInput::Mouse* mouse_input_) | ||
| 17 | : button(button_), mouse_input(mouse_input_) {} | ||
| 18 | |||
| 19 | bool GetStatus() const override { | ||
| 20 | return mouse_input->GetMouseState(button).pressed; | ||
| 21 | } | ||
| 22 | |||
| 23 | private: | ||
| 24 | const u32 button; | ||
| 25 | const MouseInput::Mouse* mouse_input; | ||
| 26 | }; | ||
| 27 | |||
| 28 | MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_) | ||
| 29 | : mouse_input(std::move(mouse_input_)) {} | ||
| 30 | |||
| 31 | std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create( | ||
| 32 | const Common::ParamPackage& params) { | ||
| 33 | const auto button_id = params.Get("button", 0); | ||
| 34 | |||
| 35 | return std::make_unique<MouseButton>(button_id, mouse_input.get()); | ||
| 36 | } | ||
| 37 | |||
| 38 | Common::ParamPackage MouseButtonFactory::GetNextInput() const { | ||
| 39 | MouseInput::MouseStatus pad; | ||
| 40 | Common::ParamPackage params; | ||
| 41 | auto& queue = mouse_input->GetMouseQueue(); | ||
| 42 | while (queue.Pop(pad)) { | ||
| 43 | // This while loop will break on the earliest detected button | ||
| 44 | if (pad.button != MouseInput::MouseButton::Undefined) { | ||
| 45 | params.Set("engine", "mouse"); | ||
| 46 | params.Set("button", static_cast<u16>(pad.button)); | ||
| 47 | return params; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | return params; | ||
| 51 | } | ||
| 52 | |||
| 53 | void MouseButtonFactory::BeginConfiguration() { | ||
| 54 | polling = true; | ||
| 55 | mouse_input->BeginConfiguration(); | ||
| 56 | } | ||
| 57 | |||
| 58 | void MouseButtonFactory::EndConfiguration() { | ||
| 59 | polling = false; | ||
| 60 | mouse_input->EndConfiguration(); | ||
| 61 | } | ||
| 62 | |||
| 63 | class MouseAnalog final : public Input::AnalogDevice { | ||
| 64 | public: | ||
| 65 | explicit MouseAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_, float range_, | ||
| 66 | const MouseInput::Mouse* mouse_input_) | ||
| 67 | : button(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), range(range_), | ||
| 68 | mouse_input(mouse_input_) {} | ||
| 69 | |||
| 70 | float GetAxis(u32 axis) const { | ||
| 71 | std::lock_guard lock{mutex}; | ||
| 72 | const auto axis_value = | ||
| 73 | static_cast<float>(mouse_input->GetMouseState(button).axis.at(axis)); | ||
| 74 | return axis_value / (100.0f * range); | ||
| 75 | } | ||
| 76 | |||
| 77 | std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const { | ||
| 78 | float x = GetAxis(analog_axis_x); | ||
| 79 | float y = GetAxis(analog_axis_y); | ||
| 80 | |||
| 81 | // Make sure the coordinates are in the unit circle, | ||
| 82 | // otherwise normalize it. | ||
| 83 | float r = x * x + y * y; | ||
| 84 | if (r > 1.0f) { | ||
| 85 | r = std::sqrt(r); | ||
| 86 | x /= r; | ||
| 87 | y /= r; | ||
| 88 | } | ||
| 89 | |||
| 90 | return {x, y}; | ||
| 91 | } | ||
| 92 | |||
| 93 | std::tuple<float, float> GetStatus() const override { | ||
| 94 | const auto [x, y] = GetAnalog(axis_x, axis_y); | ||
| 95 | const float r = std::sqrt((x * x) + (y * y)); | ||
| 96 | if (r > deadzone) { | ||
| 97 | return {x / r * (r - deadzone) / (1 - deadzone), | ||
| 98 | y / r * (r - deadzone) / (1 - deadzone)}; | ||
| 99 | } | ||
| 100 | return {0.0f, 0.0f}; | ||
| 101 | } | ||
| 102 | |||
| 103 | private: | ||
| 104 | const u32 button; | ||
| 105 | const u32 axis_x; | ||
| 106 | const u32 axis_y; | ||
| 107 | const float deadzone; | ||
| 108 | const float range; | ||
| 109 | const MouseInput::Mouse* mouse_input; | ||
| 110 | mutable std::mutex mutex; | ||
| 111 | }; | ||
| 112 | |||
| 113 | /// An analog device factory that creates analog devices from GC Adapter | ||
| 114 | MouseAnalogFactory::MouseAnalogFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_) | ||
| 115 | : mouse_input(std::move(mouse_input_)) {} | ||
| 116 | |||
| 117 | /** | ||
| 118 | * Creates analog device from joystick axes | ||
| 119 | * @param params contains parameters for creating the device: | ||
| 120 | * - "port": the nth gcpad on the adapter | ||
| 121 | * - "axis_x": the index of the axis to be bind as x-axis | ||
| 122 | * - "axis_y": the index of the axis to be bind as y-axis | ||
| 123 | */ | ||
| 124 | std::unique_ptr<Input::AnalogDevice> MouseAnalogFactory::Create( | ||
| 125 | const Common::ParamPackage& params) { | ||
| 126 | const auto port = static_cast<u32>(params.Get("port", 0)); | ||
| 127 | const auto axis_x = static_cast<u32>(params.Get("axis_x", 0)); | ||
| 128 | const auto axis_y = static_cast<u32>(params.Get("axis_y", 1)); | ||
| 129 | const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f); | ||
| 130 | const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f); | ||
| 131 | |||
| 132 | return std::make_unique<MouseAnalog>(port, axis_x, axis_y, deadzone, range, mouse_input.get()); | ||
| 133 | } | ||
| 134 | |||
| 135 | void MouseAnalogFactory::BeginConfiguration() { | ||
| 136 | polling = true; | ||
| 137 | mouse_input->BeginConfiguration(); | ||
| 138 | } | ||
| 139 | |||
| 140 | void MouseAnalogFactory::EndConfiguration() { | ||
| 141 | polling = false; | ||
| 142 | mouse_input->EndConfiguration(); | ||
| 143 | } | ||
| 144 | |||
| 145 | Common::ParamPackage MouseAnalogFactory::GetNextInput() const { | ||
| 146 | MouseInput::MouseStatus pad; | ||
| 147 | Common::ParamPackage params; | ||
| 148 | auto& queue = mouse_input->GetMouseQueue(); | ||
| 149 | while (queue.Pop(pad)) { | ||
| 150 | // This while loop will break on the earliest detected button | ||
| 151 | if (pad.button != MouseInput::MouseButton::Undefined) { | ||
| 152 | params.Set("engine", "mouse"); | ||
| 153 | params.Set("port", static_cast<u16>(pad.button)); | ||
| 154 | params.Set("axis_x", 0); | ||
| 155 | params.Set("axis_y", 1); | ||
| 156 | return params; | ||
| 157 | } | ||
| 158 | } | ||
| 159 | return params; | ||
| 160 | } | ||
| 161 | |||
| 162 | class MouseMotion final : public Input::MotionDevice { | ||
| 163 | public: | ||
| 164 | explicit MouseMotion(u32 button_, const MouseInput::Mouse* mouse_input_) | ||
| 165 | : button(button_), mouse_input(mouse_input_) {} | ||
| 166 | |||
| 167 | Input::MotionStatus GetStatus() const override { | ||
| 168 | return mouse_input->GetMouseState(button).motion; | ||
| 169 | } | ||
| 170 | |||
| 171 | private: | ||
| 172 | const u32 button; | ||
| 173 | const MouseInput::Mouse* mouse_input; | ||
| 174 | }; | ||
| 175 | |||
| 176 | MouseMotionFactory::MouseMotionFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_) | ||
| 177 | : mouse_input(std::move(mouse_input_)) {} | ||
| 178 | |||
| 179 | std::unique_ptr<Input::MotionDevice> MouseMotionFactory::Create( | ||
| 180 | const Common::ParamPackage& params) { | ||
| 181 | const auto button_id = params.Get("button", 0); | ||
| 182 | |||
| 183 | return std::make_unique<MouseMotion>(button_id, mouse_input.get()); | ||
| 184 | } | ||
| 185 | |||
| 186 | Common::ParamPackage MouseMotionFactory::GetNextInput() const { | ||
| 187 | MouseInput::MouseStatus pad; | ||
| 188 | Common::ParamPackage params; | ||
| 189 | auto& queue = mouse_input->GetMouseQueue(); | ||
| 190 | while (queue.Pop(pad)) { | ||
| 191 | // This while loop will break on the earliest detected button | ||
| 192 | if (pad.button != MouseInput::MouseButton::Undefined) { | ||
| 193 | params.Set("engine", "mouse"); | ||
| 194 | params.Set("button", static_cast<u16>(pad.button)); | ||
| 195 | return params; | ||
| 196 | } | ||
| 197 | } | ||
| 198 | return params; | ||
| 199 | } | ||
| 200 | |||
| 201 | void MouseMotionFactory::BeginConfiguration() { | ||
| 202 | polling = true; | ||
| 203 | mouse_input->BeginConfiguration(); | ||
| 204 | } | ||
| 205 | |||
| 206 | void MouseMotionFactory::EndConfiguration() { | ||
| 207 | polling = false; | ||
| 208 | mouse_input->EndConfiguration(); | ||
| 209 | } | ||
| 210 | |||
| 211 | class MouseTouch final : public Input::TouchDevice { | ||
| 212 | public: | ||
| 213 | explicit MouseTouch(u32 button_, const MouseInput::Mouse* mouse_input_) | ||
| 214 | : button(button_), mouse_input(mouse_input_) {} | ||
| 215 | |||
| 216 | Input::TouchStatus GetStatus() const override { | ||
| 217 | return mouse_input->GetMouseState(button).touch; | ||
| 218 | } | ||
| 219 | |||
| 220 | private: | ||
| 221 | const u32 button; | ||
| 222 | const MouseInput::Mouse* mouse_input; | ||
| 223 | }; | ||
| 224 | |||
| 225 | MouseTouchFactory::MouseTouchFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_) | ||
| 226 | : mouse_input(std::move(mouse_input_)) {} | ||
| 227 | |||
| 228 | std::unique_ptr<Input::TouchDevice> MouseTouchFactory::Create(const Common::ParamPackage& params) { | ||
| 229 | const auto button_id = params.Get("button", 0); | ||
| 230 | |||
| 231 | return std::make_unique<MouseTouch>(button_id, mouse_input.get()); | ||
| 232 | } | ||
| 233 | |||
| 234 | Common::ParamPackage MouseTouchFactory::GetNextInput() const { | ||
| 235 | MouseInput::MouseStatus pad; | ||
| 236 | Common::ParamPackage params; | ||
| 237 | auto& queue = mouse_input->GetMouseQueue(); | ||
| 238 | while (queue.Pop(pad)) { | ||
| 239 | // This while loop will break on the earliest detected button | ||
| 240 | if (pad.button != MouseInput::MouseButton::Undefined) { | ||
| 241 | params.Set("engine", "mouse"); | ||
| 242 | params.Set("button", static_cast<u16>(pad.button)); | ||
| 243 | return params; | ||
| 244 | } | ||
| 245 | } | ||
| 246 | return params; | ||
| 247 | } | ||
| 248 | |||
| 249 | void MouseTouchFactory::BeginConfiguration() { | ||
| 250 | polling = true; | ||
| 251 | mouse_input->BeginConfiguration(); | ||
| 252 | } | ||
| 253 | |||
| 254 | void MouseTouchFactory::EndConfiguration() { | ||
| 255 | polling = false; | ||
| 256 | mouse_input->EndConfiguration(); | ||
| 257 | } | ||
| 258 | |||
| 259 | } // namespace InputCommon | ||
diff --git a/src/input_common/mouse/mouse_poller.h b/src/input_common/mouse/mouse_poller.h new file mode 100644 index 000000000..cf331293b --- /dev/null +++ b/src/input_common/mouse/mouse_poller.h | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include "core/frontend/input.h" | ||
| 9 | #include "input_common/mouse/mouse_input.h" | ||
| 10 | |||
| 11 | namespace InputCommon { | ||
| 12 | |||
| 13 | /** | ||
| 14 | * A button device factory representing a mouse. It receives mouse events and forward them | ||
| 15 | * to all button devices it created. | ||
| 16 | */ | ||
| 17 | class MouseButtonFactory final : public Input::Factory<Input::ButtonDevice> { | ||
| 18 | public: | ||
| 19 | explicit MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_); | ||
| 20 | |||
| 21 | /** | ||
| 22 | * Creates a button device from a button press | ||
| 23 | * @param params contains parameters for creating the device: | ||
| 24 | * - "code": the code of the key to bind with the button | ||
| 25 | */ | ||
| 26 | std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override; | ||
| 27 | |||
| 28 | Common::ParamPackage GetNextInput() const; | ||
| 29 | |||
| 30 | /// For device input configuration/polling | ||
| 31 | void BeginConfiguration(); | ||
| 32 | void EndConfiguration(); | ||
| 33 | |||
| 34 | bool IsPolling() const { | ||
| 35 | return polling; | ||
| 36 | } | ||
| 37 | |||
| 38 | private: | ||
| 39 | std::shared_ptr<MouseInput::Mouse> mouse_input; | ||
| 40 | bool polling = false; | ||
| 41 | }; | ||
| 42 | |||
| 43 | /// An analog device factory that creates analog devices from mouse | ||
| 44 | class MouseAnalogFactory final : public Input::Factory<Input::AnalogDevice> { | ||
| 45 | public: | ||
| 46 | explicit MouseAnalogFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_); | ||
| 47 | |||
| 48 | std::unique_ptr<Input::AnalogDevice> Create(const Common::ParamPackage& params) override; | ||
| 49 | |||
| 50 | Common::ParamPackage GetNextInput() const; | ||
| 51 | |||
| 52 | /// For device input configuration/polling | ||
| 53 | void BeginConfiguration(); | ||
| 54 | void EndConfiguration(); | ||
| 55 | |||
| 56 | bool IsPolling() const { | ||
| 57 | return polling; | ||
| 58 | } | ||
| 59 | |||
| 60 | private: | ||
| 61 | std::shared_ptr<MouseInput::Mouse> mouse_input; | ||
| 62 | bool polling = false; | ||
| 63 | }; | ||
| 64 | |||
| 65 | /// A motion device factory that creates motion devices from mouse | ||
| 66 | class MouseMotionFactory final : public Input::Factory<Input::MotionDevice> { | ||
| 67 | public: | ||
| 68 | explicit MouseMotionFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_); | ||
| 69 | |||
| 70 | std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override; | ||
| 71 | |||
| 72 | Common::ParamPackage GetNextInput() const; | ||
| 73 | |||
| 74 | /// For device input configuration/polling | ||
| 75 | void BeginConfiguration(); | ||
| 76 | void EndConfiguration(); | ||
| 77 | |||
| 78 | bool IsPolling() const { | ||
| 79 | return polling; | ||
| 80 | } | ||
| 81 | |||
| 82 | private: | ||
| 83 | std::shared_ptr<MouseInput::Mouse> mouse_input; | ||
| 84 | bool polling = false; | ||
| 85 | }; | ||
| 86 | |||
| 87 | /// An touch device factory that creates touch devices from mouse | ||
| 88 | class MouseTouchFactory final : public Input::Factory<Input::TouchDevice> { | ||
| 89 | public: | ||
| 90 | explicit MouseTouchFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_); | ||
| 91 | |||
| 92 | std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage& params) override; | ||
| 93 | |||
| 94 | Common::ParamPackage GetNextInput() const; | ||
| 95 | |||
| 96 | /// For device input configuration/polling | ||
| 97 | void BeginConfiguration(); | ||
| 98 | void EndConfiguration(); | ||
| 99 | |||
| 100 | bool IsPolling() const { | ||
| 101 | return polling; | ||
| 102 | } | ||
| 103 | |||
| 104 | private: | ||
| 105 | std::shared_ptr<MouseInput::Mouse> mouse_input; | ||
| 106 | bool polling = false; | ||
| 107 | }; | ||
| 108 | |||
| 109 | } // namespace InputCommon | ||
diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp index c0bb90048..17a9225d7 100644 --- a/src/input_common/udp/client.cpp +++ b/src/input_common/udp/client.cpp | |||
| @@ -136,15 +136,7 @@ static void SocketLoop(Socket* socket) { | |||
| 136 | 136 | ||
| 137 | Client::Client() { | 137 | Client::Client() { |
| 138 | LOG_INFO(Input, "Udp Initialization started"); | 138 | LOG_INFO(Input, "Udp Initialization started"); |
| 139 | for (std::size_t client = 0; client < clients.size(); client++) { | 139 | ReloadSockets(); |
| 140 | const auto pad = client % 4; | ||
| 141 | StartCommunication(client, Settings::values.udp_input_address, | ||
| 142 | Settings::values.udp_input_port, pad, 24872); | ||
| 143 | // Set motion parameters | ||
| 144 | // SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode | ||
| 145 | // Real HW values are unknown, 0.0001 is an approximate to Standard | ||
| 146 | clients[client].motion.SetGyroThreshold(0.0001f); | ||
| 147 | } | ||
| 148 | } | 140 | } |
| 149 | 141 | ||
| 150 | Client::~Client() { | 142 | Client::~Client() { |
| @@ -167,26 +159,61 @@ std::vector<Common::ParamPackage> Client::GetInputDevices() const { | |||
| 167 | return devices; | 159 | return devices; |
| 168 | } | 160 | } |
| 169 | 161 | ||
| 170 | bool Client::DeviceConnected(std::size_t pad) const { | 162 | bool Client::DeviceConnected(std::size_t client) const { |
| 171 | // Use last timestamp to detect if the socket has stopped sending data | 163 | // Use last timestamp to detect if the socket has stopped sending data |
| 172 | const auto now = std::chrono::system_clock::now(); | 164 | const auto now = std::chrono::steady_clock::now(); |
| 173 | const auto time_difference = static_cast<u64>( | 165 | const auto time_difference = |
| 174 | std::chrono::duration_cast<std::chrono::milliseconds>(now - clients[pad].last_motion_update) | 166 | static_cast<u64>(std::chrono::duration_cast<std::chrono::milliseconds>( |
| 175 | .count()); | 167 | now - clients[client].last_motion_update) |
| 176 | return time_difference < 1000 && clients[pad].active == 1; | 168 | .count()); |
| 169 | return time_difference < 1000 && clients[client].active == 1; | ||
| 177 | } | 170 | } |
| 178 | 171 | ||
| 179 | void Client::ReloadUDPClient() { | 172 | void Client::ReloadSockets() { |
| 180 | for (std::size_t client = 0; client < clients.size(); client++) { | 173 | Reset(); |
| 181 | ReloadSocket(Settings::values.udp_input_address, Settings::values.udp_input_port, client); | 174 | |
| 175 | std::stringstream servers_ss(Settings::values.udp_input_servers); | ||
| 176 | std::string server_token; | ||
| 177 | std::size_t client = 0; | ||
| 178 | while (std::getline(servers_ss, server_token, ',')) { | ||
| 179 | if (client == max_udp_clients) { | ||
| 180 | break; | ||
| 181 | } | ||
| 182 | std::stringstream server_ss(server_token); | ||
| 183 | std::string token; | ||
| 184 | std::getline(server_ss, token, ':'); | ||
| 185 | std::string udp_input_address = token; | ||
| 186 | std::getline(server_ss, token, ':'); | ||
| 187 | char* temp; | ||
| 188 | const u16 udp_input_port = static_cast<u16>(std::strtol(token.c_str(), &temp, 0)); | ||
| 189 | if (*temp != '\0') { | ||
| 190 | LOG_ERROR(Input, "Port number is not valid {}", token); | ||
| 191 | continue; | ||
| 192 | } | ||
| 193 | |||
| 194 | for (std::size_t pad = 0; pad < 4; ++pad) { | ||
| 195 | const std::size_t client_number = | ||
| 196 | GetClientNumber(udp_input_address, udp_input_port, pad); | ||
| 197 | if (client_number != max_udp_clients) { | ||
| 198 | LOG_ERROR(Input, "Duplicated UDP servers found"); | ||
| 199 | continue; | ||
| 200 | } | ||
| 201 | StartCommunication(client++, udp_input_address, udp_input_port, pad, 24872); | ||
| 202 | } | ||
| 182 | } | 203 | } |
| 183 | } | 204 | } |
| 184 | void Client::ReloadSocket(const std::string& host, u16 port, std::size_t pad_index, u32 client_id) { | 205 | |
| 185 | // client number must be determined from host / port and pad index | 206 | std::size_t Client::GetClientNumber(std::string_view host, u16 port, std::size_t pad) const { |
| 186 | const std::size_t client = pad_index; | 207 | for (std::size_t client = 0; client < clients.size(); client++) { |
| 187 | clients[client].socket->Stop(); | 208 | if (clients[client].active == -1) { |
| 188 | clients[client].thread.join(); | 209 | continue; |
| 189 | StartCommunication(client, host, port, pad_index, client_id); | 210 | } |
| 211 | if (clients[client].host == host && clients[client].port == port && | ||
| 212 | clients[client].pad_index == pad) { | ||
| 213 | return client; | ||
| 214 | } | ||
| 215 | } | ||
| 216 | return max_udp_clients; | ||
| 190 | } | 217 | } |
| 191 | 218 | ||
| 192 | void Client::OnVersion([[maybe_unused]] Response::Version data) { | 219 | void Client::OnVersion([[maybe_unused]] Response::Version data) { |
| @@ -197,9 +224,7 @@ void Client::OnPortInfo([[maybe_unused]] Response::PortInfo data) { | |||
| 197 | LOG_TRACE(Input, "PortInfo packet received: {}", data.model); | 224 | LOG_TRACE(Input, "PortInfo packet received: {}", data.model); |
| 198 | } | 225 | } |
| 199 | 226 | ||
| 200 | void Client::OnPadData(Response::PadData data) { | 227 | void Client::OnPadData(Response::PadData data, std::size_t client) { |
| 201 | // Client number must be determined from host / port and pad index | ||
| 202 | const std::size_t client = data.info.id; | ||
| 203 | LOG_TRACE(Input, "PadData packet received"); | 228 | LOG_TRACE(Input, "PadData packet received"); |
| 204 | if (data.packet_counter == clients[client].packet_sequence) { | 229 | if (data.packet_counter == clients[client].packet_sequence) { |
| 205 | LOG_WARNING( | 230 | LOG_WARNING( |
| @@ -208,9 +233,9 @@ void Client::OnPadData(Response::PadData data) { | |||
| 208 | clients[client].packet_sequence, data.packet_counter); | 233 | clients[client].packet_sequence, data.packet_counter); |
| 209 | return; | 234 | return; |
| 210 | } | 235 | } |
| 211 | clients[client].active = data.info.is_pad_active; | 236 | clients[client].active = static_cast<s8>(data.info.is_pad_active); |
| 212 | clients[client].packet_sequence = data.packet_counter; | 237 | clients[client].packet_sequence = data.packet_counter; |
| 213 | const auto now = std::chrono::system_clock::now(); | 238 | const auto now = std::chrono::steady_clock::now(); |
| 214 | const auto time_difference = | 239 | const auto time_difference = |
| 215 | static_cast<u64>(std::chrono::duration_cast<std::chrono::microseconds>( | 240 | static_cast<u64>(std::chrono::duration_cast<std::chrono::microseconds>( |
| 216 | now - clients[client].last_motion_update) | 241 | now - clients[client].last_motion_update) |
| @@ -264,16 +289,28 @@ void Client::StartCommunication(std::size_t client, const std::string& host, u16 | |||
| 264 | std::size_t pad_index, u32 client_id) { | 289 | std::size_t pad_index, u32 client_id) { |
| 265 | SocketCallback callback{[this](Response::Version version) { OnVersion(version); }, | 290 | SocketCallback callback{[this](Response::Version version) { OnVersion(version); }, |
| 266 | [this](Response::PortInfo info) { OnPortInfo(info); }, | 291 | [this](Response::PortInfo info) { OnPortInfo(info); }, |
| 267 | [this](Response::PadData data) { OnPadData(data); }}; | 292 | [this, client](Response::PadData data) { OnPadData(data, client); }}; |
| 268 | LOG_INFO(Input, "Starting communication with UDP input server on {}:{}", host, port); | 293 | LOG_INFO(Input, "Starting communication with UDP input server on {}:{}:{}", host, port, |
| 294 | pad_index); | ||
| 295 | clients[client].host = host; | ||
| 296 | clients[client].port = port; | ||
| 297 | clients[client].pad_index = pad_index; | ||
| 298 | clients[client].active = 0; | ||
| 269 | clients[client].socket = std::make_unique<Socket>(host, port, pad_index, client_id, callback); | 299 | clients[client].socket = std::make_unique<Socket>(host, port, pad_index, client_id, callback); |
| 270 | clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()}; | 300 | clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()}; |
| 301 | // Set motion parameters | ||
| 302 | // SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode | ||
| 303 | // Real HW values are unknown, 0.0001 is an approximate to Standard | ||
| 304 | clients[client].motion.SetGyroThreshold(0.0001f); | ||
| 271 | } | 305 | } |
| 272 | 306 | ||
| 273 | void Client::Reset() { | 307 | void Client::Reset() { |
| 274 | for (auto& client : clients) { | 308 | for (auto& client : clients) { |
| 275 | client.socket->Stop(); | 309 | if (client.thread.joinable()) { |
| 276 | client.thread.join(); | 310 | client.active = -1; |
| 311 | client.socket->Stop(); | ||
| 312 | client.thread.join(); | ||
| 313 | } | ||
| 277 | } | 314 | } |
| 278 | } | 315 | } |
| 279 | 316 | ||
| @@ -283,52 +320,60 @@ void Client::UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& a | |||
| 283 | LOG_DEBUG(Input, "UDP Controller {}: gyro=({}, {}, {}), accel=({}, {}, {}), touch={}", | 320 | LOG_DEBUG(Input, "UDP Controller {}: gyro=({}, {}, {}), accel=({}, {}, {}), touch={}", |
| 284 | client, gyro[0], gyro[1], gyro[2], acc[0], acc[1], acc[2], touch); | 321 | client, gyro[0], gyro[1], gyro[2], acc[0], acc[1], acc[2], touch); |
| 285 | } | 322 | } |
| 286 | UDPPadStatus pad; | 323 | UDPPadStatus pad{ |
| 324 | .host = clients[client].host, | ||
| 325 | .port = clients[client].port, | ||
| 326 | .pad_index = clients[client].pad_index, | ||
| 327 | }; | ||
| 287 | if (touch) { | 328 | if (touch) { |
| 288 | pad.touch = PadTouch::Click; | 329 | pad.touch = PadTouch::Click; |
| 289 | pad_queue[client].Push(pad); | 330 | pad_queue.Push(pad); |
| 290 | } | 331 | } |
| 291 | for (size_t i = 0; i < 3; ++i) { | 332 | for (size_t i = 0; i < 3; ++i) { |
| 292 | if (gyro[i] > 5.0f || gyro[i] < -5.0f) { | 333 | if (gyro[i] > 5.0f || gyro[i] < -5.0f) { |
| 293 | pad.motion = static_cast<PadMotion>(i); | 334 | pad.motion = static_cast<PadMotion>(i); |
| 294 | pad.motion_value = gyro[i]; | 335 | pad.motion_value = gyro[i]; |
| 295 | pad_queue[client].Push(pad); | 336 | pad_queue.Push(pad); |
| 296 | } | 337 | } |
| 297 | if (acc[i] > 1.75f || acc[i] < -1.75f) { | 338 | if (acc[i] > 1.75f || acc[i] < -1.75f) { |
| 298 | pad.motion = static_cast<PadMotion>(i + 3); | 339 | pad.motion = static_cast<PadMotion>(i + 3); |
| 299 | pad.motion_value = acc[i]; | 340 | pad.motion_value = acc[i]; |
| 300 | pad_queue[client].Push(pad); | 341 | pad_queue.Push(pad); |
| 301 | } | 342 | } |
| 302 | } | 343 | } |
| 303 | } | 344 | } |
| 304 | 345 | ||
| 305 | void Client::BeginConfiguration() { | 346 | void Client::BeginConfiguration() { |
| 306 | for (auto& pq : pad_queue) { | 347 | pad_queue.Clear(); |
| 307 | pq.Clear(); | ||
| 308 | } | ||
| 309 | configuring = true; | 348 | configuring = true; |
| 310 | } | 349 | } |
| 311 | 350 | ||
| 312 | void Client::EndConfiguration() { | 351 | void Client::EndConfiguration() { |
| 313 | for (auto& pq : pad_queue) { | 352 | pad_queue.Clear(); |
| 314 | pq.Clear(); | ||
| 315 | } | ||
| 316 | configuring = false; | 353 | configuring = false; |
| 317 | } | 354 | } |
| 318 | 355 | ||
| 319 | DeviceStatus& Client::GetPadState(std::size_t pad) { | 356 | DeviceStatus& Client::GetPadState(const std::string& host, u16 port, std::size_t pad) { |
| 320 | return clients[pad].status; | 357 | const std::size_t client_number = GetClientNumber(host, port, pad); |
| 358 | if (client_number == max_udp_clients) { | ||
| 359 | return clients[0].status; | ||
| 360 | } | ||
| 361 | return clients[client_number].status; | ||
| 321 | } | 362 | } |
| 322 | 363 | ||
| 323 | const DeviceStatus& Client::GetPadState(std::size_t pad) const { | 364 | const DeviceStatus& Client::GetPadState(const std::string& host, u16 port, std::size_t pad) const { |
| 324 | return clients[pad].status; | 365 | const std::size_t client_number = GetClientNumber(host, port, pad); |
| 366 | if (client_number == max_udp_clients) { | ||
| 367 | return clients[0].status; | ||
| 368 | } | ||
| 369 | return clients[client_number].status; | ||
| 325 | } | 370 | } |
| 326 | 371 | ||
| 327 | std::array<Common::SPSCQueue<UDPPadStatus>, 4>& Client::GetPadQueue() { | 372 | Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() { |
| 328 | return pad_queue; | 373 | return pad_queue; |
| 329 | } | 374 | } |
| 330 | 375 | ||
| 331 | const std::array<Common::SPSCQueue<UDPPadStatus>, 4>& Client::GetPadQueue() const { | 376 | const Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() const { |
| 332 | return pad_queue; | 377 | return pad_queue; |
| 333 | } | 378 | } |
| 334 | 379 | ||
diff --git a/src/input_common/udp/client.h b/src/input_common/udp/client.h index 747e0c0a2..00c8b09f5 100644 --- a/src/input_common/udp/client.h +++ b/src/input_common/udp/client.h | |||
| @@ -21,8 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | namespace InputCommon::CemuhookUDP { | 22 | namespace InputCommon::CemuhookUDP { |
| 23 | 23 | ||
| 24 | constexpr u16 DEFAULT_PORT = 26760; | 24 | constexpr char DEFAULT_SRV[] = "127.0.0.1:26760"; |
| 25 | constexpr char DEFAULT_ADDR[] = "127.0.0.1"; | ||
| 26 | 25 | ||
| 27 | class Socket; | 26 | class Socket; |
| 28 | 27 | ||
| @@ -48,6 +47,9 @@ enum class PadTouch { | |||
| 48 | }; | 47 | }; |
| 49 | 48 | ||
| 50 | struct UDPPadStatus { | 49 | struct UDPPadStatus { |
| 50 | std::string host{"127.0.0.1"}; | ||
| 51 | u16 port{26760}; | ||
| 52 | std::size_t pad_index{}; | ||
| 51 | PadTouch touch{PadTouch::Undefined}; | 53 | PadTouch touch{PadTouch::Undefined}; |
| 52 | PadMotion motion{PadMotion::Undefined}; | 54 | PadMotion motion{PadMotion::Undefined}; |
| 53 | f32 motion_value{0.0f}; | 55 | f32 motion_value{0.0f}; |
| @@ -82,37 +84,41 @@ public: | |||
| 82 | 84 | ||
| 83 | std::vector<Common::ParamPackage> GetInputDevices() const; | 85 | std::vector<Common::ParamPackage> GetInputDevices() const; |
| 84 | 86 | ||
| 85 | bool DeviceConnected(std::size_t pad) const; | 87 | bool DeviceConnected(std::size_t client) const; |
| 86 | void ReloadUDPClient(); | 88 | void ReloadSockets(); |
| 87 | void ReloadSocket(const std::string& host = "127.0.0.1", u16 port = 26760, | ||
| 88 | std::size_t pad_index = 0, u32 client_id = 24872); | ||
| 89 | 89 | ||
| 90 | std::array<Common::SPSCQueue<UDPPadStatus>, 4>& GetPadQueue(); | 90 | Common::SPSCQueue<UDPPadStatus>& GetPadQueue(); |
| 91 | const std::array<Common::SPSCQueue<UDPPadStatus>, 4>& GetPadQueue() const; | 91 | const Common::SPSCQueue<UDPPadStatus>& GetPadQueue() const; |
| 92 | 92 | ||
| 93 | DeviceStatus& GetPadState(std::size_t pad); | 93 | DeviceStatus& GetPadState(const std::string& host, u16 port, std::size_t pad); |
| 94 | const DeviceStatus& GetPadState(std::size_t pad) const; | 94 | const DeviceStatus& GetPadState(const std::string& host, u16 port, std::size_t pad) const; |
| 95 | 95 | ||
| 96 | private: | 96 | private: |
| 97 | struct ClientData { | 97 | struct ClientData { |
| 98 | std::string host{"127.0.0.1"}; | ||
| 99 | u16 port{26760}; | ||
| 100 | std::size_t pad_index{}; | ||
| 98 | std::unique_ptr<Socket> socket; | 101 | std::unique_ptr<Socket> socket; |
| 99 | DeviceStatus status; | 102 | DeviceStatus status; |
| 100 | std::thread thread; | 103 | std::thread thread; |
| 101 | u64 packet_sequence = 0; | 104 | u64 packet_sequence{}; |
| 102 | u8 active = 0; | 105 | s8 active{-1}; |
| 103 | 106 | ||
| 104 | // Realtime values | 107 | // Realtime values |
| 105 | // motion is initalized with PID values for drift correction on joycons | 108 | // motion is initalized with PID values for drift correction on joycons |
| 106 | InputCommon::MotionInput motion{0.3f, 0.005f, 0.0f}; | 109 | InputCommon::MotionInput motion{0.3f, 0.005f, 0.0f}; |
| 107 | std::chrono::time_point<std::chrono::system_clock> last_motion_update; | 110 | std::chrono::time_point<std::chrono::steady_clock> last_motion_update; |
| 108 | }; | 111 | }; |
| 109 | 112 | ||
| 110 | // For shutting down, clear all data, join all threads, release usb | 113 | // For shutting down, clear all data, join all threads, release usb |
| 111 | void Reset(); | 114 | void Reset(); |
| 112 | 115 | ||
| 116 | // Translates configuration to client number | ||
| 117 | std::size_t GetClientNumber(std::string_view host, u16 port, std::size_t pad) const; | ||
| 118 | |||
| 113 | void OnVersion(Response::Version); | 119 | void OnVersion(Response::Version); |
| 114 | void OnPortInfo(Response::PortInfo); | 120 | void OnPortInfo(Response::PortInfo); |
| 115 | void OnPadData(Response::PadData); | 121 | void OnPadData(Response::PadData, std::size_t client); |
| 116 | void StartCommunication(std::size_t client, const std::string& host, u16 port, | 122 | void StartCommunication(std::size_t client, const std::string& host, u16 port, |
| 117 | std::size_t pad_index, u32 client_id); | 123 | std::size_t pad_index, u32 client_id); |
| 118 | void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc, | 124 | void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc, |
| @@ -120,8 +126,10 @@ private: | |||
| 120 | 126 | ||
| 121 | bool configuring = false; | 127 | bool configuring = false; |
| 122 | 128 | ||
| 123 | std::array<ClientData, 4> clients; | 129 | // Allocate clients for 8 udp servers |
| 124 | std::array<Common::SPSCQueue<UDPPadStatus>, 4> pad_queue; | 130 | const std::size_t max_udp_clients = 32; |
| 131 | std::array<ClientData, 4 * 8> clients; | ||
| 132 | Common::SPSCQueue<UDPPadStatus> pad_queue; | ||
| 125 | }; | 133 | }; |
| 126 | 134 | ||
| 127 | /// An async job allowing configuration of the touchpad calibration. | 135 | /// An async job allowing configuration of the touchpad calibration. |
diff --git a/src/input_common/udp/udp.cpp b/src/input_common/udp/udp.cpp index 71a76a7aa..8686a059c 100644 --- a/src/input_common/udp/udp.cpp +++ b/src/input_common/udp/udp.cpp | |||
| @@ -13,17 +13,17 @@ namespace InputCommon { | |||
| 13 | 13 | ||
| 14 | class UDPMotion final : public Input::MotionDevice { | 14 | class UDPMotion final : public Input::MotionDevice { |
| 15 | public: | 15 | public: |
| 16 | explicit UDPMotion(std::string ip_, int port_, u32 pad_, CemuhookUDP::Client* client_) | 16 | explicit UDPMotion(std::string ip_, u16 port_, u16 pad_, CemuhookUDP::Client* client_) |
| 17 | : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {} | 17 | : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {} |
| 18 | 18 | ||
| 19 | Input::MotionStatus GetStatus() const override { | 19 | Input::MotionStatus GetStatus() const override { |
| 20 | return client->GetPadState(pad).motion_status; | 20 | return client->GetPadState(ip, port, pad).motion_status; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | private: | 23 | private: |
| 24 | const std::string ip; | 24 | const std::string ip; |
| 25 | const int port; | 25 | const u16 port; |
| 26 | const u32 pad; | 26 | const u16 pad; |
| 27 | CemuhookUDP::Client* client; | 27 | CemuhookUDP::Client* client; |
| 28 | mutable std::mutex mutex; | 28 | mutable std::mutex mutex; |
| 29 | }; | 29 | }; |
| @@ -39,8 +39,8 @@ UDPMotionFactory::UDPMotionFactory(std::shared_ptr<CemuhookUDP::Client> client_) | |||
| 39 | */ | 39 | */ |
| 40 | std::unique_ptr<Input::MotionDevice> UDPMotionFactory::Create(const Common::ParamPackage& params) { | 40 | std::unique_ptr<Input::MotionDevice> UDPMotionFactory::Create(const Common::ParamPackage& params) { |
| 41 | auto ip = params.Get("ip", "127.0.0.1"); | 41 | auto ip = params.Get("ip", "127.0.0.1"); |
| 42 | const auto port = params.Get("port", 26760); | 42 | const auto port = static_cast<u16>(params.Get("port", 26760)); |
| 43 | const auto pad = static_cast<u32>(params.Get("pad_index", 0)); | 43 | const auto pad = static_cast<u16>(params.Get("pad_index", 0)); |
| 44 | 44 | ||
| 45 | return std::make_unique<UDPMotion>(std::move(ip), port, pad, client.get()); | 45 | return std::make_unique<UDPMotion>(std::move(ip), port, pad, client.get()); |
| 46 | } | 46 | } |
| @@ -59,35 +59,33 @@ Common::ParamPackage UDPMotionFactory::GetNextInput() { | |||
| 59 | Common::ParamPackage params; | 59 | Common::ParamPackage params; |
| 60 | CemuhookUDP::UDPPadStatus pad; | 60 | CemuhookUDP::UDPPadStatus pad; |
| 61 | auto& queue = client->GetPadQueue(); | 61 | auto& queue = client->GetPadQueue(); |
| 62 | for (std::size_t pad_number = 0; pad_number < queue.size(); ++pad_number) { | 62 | while (queue.Pop(pad)) { |
| 63 | while (queue[pad_number].Pop(pad)) { | 63 | if (pad.motion == CemuhookUDP::PadMotion::Undefined || std::abs(pad.motion_value) < 1) { |
| 64 | if (pad.motion == CemuhookUDP::PadMotion::Undefined || std::abs(pad.motion_value) < 1) { | 64 | continue; |
| 65 | continue; | ||
| 66 | } | ||
| 67 | params.Set("engine", "cemuhookudp"); | ||
| 68 | params.Set("ip", "127.0.0.1"); | ||
| 69 | params.Set("port", 26760); | ||
| 70 | params.Set("pad_index", static_cast<int>(pad_number)); | ||
| 71 | params.Set("motion", static_cast<u16>(pad.motion)); | ||
| 72 | return params; | ||
| 73 | } | 65 | } |
| 66 | params.Set("engine", "cemuhookudp"); | ||
| 67 | params.Set("ip", pad.host); | ||
| 68 | params.Set("port", static_cast<u16>(pad.port)); | ||
| 69 | params.Set("pad_index", static_cast<u16>(pad.pad_index)); | ||
| 70 | params.Set("motion", static_cast<u16>(pad.motion)); | ||
| 71 | return params; | ||
| 74 | } | 72 | } |
| 75 | return params; | 73 | return params; |
| 76 | } | 74 | } |
| 77 | 75 | ||
| 78 | class UDPTouch final : public Input::TouchDevice { | 76 | class UDPTouch final : public Input::TouchDevice { |
| 79 | public: | 77 | public: |
| 80 | explicit UDPTouch(std::string ip_, int port_, u32 pad_, CemuhookUDP::Client* client_) | 78 | explicit UDPTouch(std::string ip_, u16 port_, u16 pad_, CemuhookUDP::Client* client_) |
| 81 | : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {} | 79 | : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {} |
| 82 | 80 | ||
| 83 | std::tuple<float, float, bool> GetStatus() const override { | 81 | std::tuple<float, float, bool> GetStatus() const override { |
| 84 | return client->GetPadState(pad).touch_status; | 82 | return client->GetPadState(ip, port, pad).touch_status; |
| 85 | } | 83 | } |
| 86 | 84 | ||
| 87 | private: | 85 | private: |
| 88 | const std::string ip; | 86 | const std::string ip; |
| 89 | const int port; | 87 | const u16 port; |
| 90 | const u32 pad; | 88 | const u16 pad; |
| 91 | CemuhookUDP::Client* client; | 89 | CemuhookUDP::Client* client; |
| 92 | mutable std::mutex mutex; | 90 | mutable std::mutex mutex; |
| 93 | }; | 91 | }; |
| @@ -103,8 +101,8 @@ UDPTouchFactory::UDPTouchFactory(std::shared_ptr<CemuhookUDP::Client> client_) | |||
| 103 | */ | 101 | */ |
| 104 | std::unique_ptr<Input::TouchDevice> UDPTouchFactory::Create(const Common::ParamPackage& params) { | 102 | std::unique_ptr<Input::TouchDevice> UDPTouchFactory::Create(const Common::ParamPackage& params) { |
| 105 | auto ip = params.Get("ip", "127.0.0.1"); | 103 | auto ip = params.Get("ip", "127.0.0.1"); |
| 106 | const auto port = params.Get("port", 26760); | 104 | const auto port = static_cast<u16>(params.Get("port", 26760)); |
| 107 | const auto pad = static_cast<u32>(params.Get("pad_index", 0)); | 105 | const auto pad = static_cast<u16>(params.Get("pad_index", 0)); |
| 108 | 106 | ||
| 109 | return std::make_unique<UDPTouch>(std::move(ip), port, pad, client.get()); | 107 | return std::make_unique<UDPTouch>(std::move(ip), port, pad, client.get()); |
| 110 | } | 108 | } |
| @@ -123,18 +121,16 @@ Common::ParamPackage UDPTouchFactory::GetNextInput() { | |||
| 123 | Common::ParamPackage params; | 121 | Common::ParamPackage params; |
| 124 | CemuhookUDP::UDPPadStatus pad; | 122 | CemuhookUDP::UDPPadStatus pad; |
| 125 | auto& queue = client->GetPadQueue(); | 123 | auto& queue = client->GetPadQueue(); |
| 126 | for (std::size_t pad_number = 0; pad_number < queue.size(); ++pad_number) { | 124 | while (queue.Pop(pad)) { |
| 127 | while (queue[pad_number].Pop(pad)) { | 125 | if (pad.touch == CemuhookUDP::PadTouch::Undefined) { |
| 128 | if (pad.touch == CemuhookUDP::PadTouch::Undefined) { | 126 | continue; |
| 129 | continue; | ||
| 130 | } | ||
| 131 | params.Set("engine", "cemuhookudp"); | ||
| 132 | params.Set("ip", "127.0.0.1"); | ||
| 133 | params.Set("port", 26760); | ||
| 134 | params.Set("pad_index", static_cast<int>(pad_number)); | ||
| 135 | params.Set("touch", static_cast<u16>(pad.touch)); | ||
| 136 | return params; | ||
| 137 | } | 127 | } |
| 128 | params.Set("engine", "cemuhookudp"); | ||
| 129 | params.Set("ip", pad.host); | ||
| 130 | params.Set("port", static_cast<u16>(pad.port)); | ||
| 131 | params.Set("pad_index", static_cast<u16>(pad.pad_index)); | ||
| 132 | params.Set("touch", static_cast<u16>(pad.touch)); | ||
| 133 | return params; | ||
| 138 | } | 134 | } |
| 139 | return params; | 135 | return params; |
| 140 | } | 136 | } |
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp index 1adf3cd13..9a88f64e4 100644 --- a/src/video_core/command_classes/codecs/codec.cpp +++ b/src/video_core/command_classes/codecs/codec.cpp | |||
| @@ -18,6 +18,11 @@ extern "C" { | |||
| 18 | 18 | ||
| 19 | namespace Tegra { | 19 | namespace Tegra { |
| 20 | 20 | ||
| 21 | void AVFrameDeleter(AVFrame* ptr) { | ||
| 22 | av_frame_unref(ptr); | ||
| 23 | av_free(ptr); | ||
| 24 | } | ||
| 25 | |||
| 21 | Codec::Codec(GPU& gpu_) | 26 | Codec::Codec(GPU& gpu_) |
| 22 | : gpu(gpu_), h264_decoder(std::make_unique<Decoder::H264>(gpu)), | 27 | : gpu(gpu_), h264_decoder(std::make_unique<Decoder::H264>(gpu)), |
| 23 | vp9_decoder(std::make_unique<Decoder::VP9>(gpu)) {} | 28 | vp9_decoder(std::make_unique<Decoder::VP9>(gpu)) {} |
| @@ -27,7 +32,9 @@ Codec::~Codec() { | |||
| 27 | return; | 32 | return; |
| 28 | } | 33 | } |
| 29 | // Free libav memory | 34 | // Free libav memory |
| 35 | AVFrame* av_frame{nullptr}; | ||
| 30 | avcodec_send_packet(av_codec_ctx, nullptr); | 36 | avcodec_send_packet(av_codec_ctx, nullptr); |
| 37 | av_frame = av_frame_alloc(); | ||
| 31 | avcodec_receive_frame(av_codec_ctx, av_frame); | 38 | avcodec_receive_frame(av_codec_ctx, av_frame); |
| 32 | avcodec_flush_buffers(av_codec_ctx); | 39 | avcodec_flush_buffers(av_codec_ctx); |
| 33 | 40 | ||
| @@ -60,7 +67,7 @@ void Codec::Decode() { | |||
| 60 | } | 67 | } |
| 61 | 68 | ||
| 62 | av_codec_ctx = avcodec_alloc_context3(av_codec); | 69 | av_codec_ctx = avcodec_alloc_context3(av_codec); |
| 63 | av_frame = av_frame_alloc(); | 70 | av_codec_ctx->refcounted_frames = 1; |
| 64 | av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0); | 71 | av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0); |
| 65 | 72 | ||
| 66 | // TODO(ameerj): libavcodec gpu hw acceleration | 73 | // TODO(ameerj): libavcodec gpu hw acceleration |
| @@ -68,8 +75,6 @@ void Codec::Decode() { | |||
| 68 | const auto av_error = avcodec_open2(av_codec_ctx, av_codec, nullptr); | 75 | const auto av_error = avcodec_open2(av_codec_ctx, av_codec, nullptr); |
| 69 | if (av_error < 0) { | 76 | if (av_error < 0) { |
| 70 | LOG_ERROR(Service_NVDRV, "avcodec_open2() Failed."); | 77 | LOG_ERROR(Service_NVDRV, "avcodec_open2() Failed."); |
| 71 | av_frame_unref(av_frame); | ||
| 72 | av_free(av_frame); | ||
| 73 | avcodec_close(av_codec_ctx); | 78 | avcodec_close(av_codec_ctx); |
| 74 | return; | 79 | return; |
| 75 | } | 80 | } |
| @@ -96,16 +101,26 @@ void Codec::Decode() { | |||
| 96 | 101 | ||
| 97 | if (!vp9_hidden_frame) { | 102 | if (!vp9_hidden_frame) { |
| 98 | // Only receive/store visible frames | 103 | // Only receive/store visible frames |
| 99 | avcodec_receive_frame(av_codec_ctx, av_frame); | 104 | AVFramePtr frame = AVFramePtr{av_frame_alloc(), AVFrameDeleter}; |
| 105 | avcodec_receive_frame(av_codec_ctx, frame.get()); | ||
| 106 | av_frames.push(std::move(frame)); | ||
| 107 | // Limit queue to 10 frames. Workaround for ZLA decode and queue spam | ||
| 108 | if (av_frames.size() > 10) { | ||
| 109 | av_frames.pop(); | ||
| 110 | } | ||
| 100 | } | 111 | } |
| 101 | } | 112 | } |
| 102 | 113 | ||
| 103 | AVFrame* Codec::GetCurrentFrame() { | 114 | AVFramePtr Codec::GetCurrentFrame() { |
| 104 | return av_frame; | 115 | // Sometimes VIC will request more frames than have been decoded. |
| 105 | } | 116 | // in this case, return a nullptr and don't overwrite previous frame data |
| 117 | if (av_frames.empty()) { | ||
| 118 | return AVFramePtr{nullptr, AVFrameDeleter}; | ||
| 119 | } | ||
| 106 | 120 | ||
| 107 | const AVFrame* Codec::GetCurrentFrame() const { | 121 | AVFramePtr frame = std::move(av_frames.front()); |
| 108 | return av_frame; | 122 | av_frames.pop(); |
| 123 | return frame; | ||
| 109 | } | 124 | } |
| 110 | 125 | ||
| 111 | NvdecCommon::VideoCodec Codec::GetCurrentCodec() const { | 126 | NvdecCommon::VideoCodec Codec::GetCurrentCodec() const { |
diff --git a/src/video_core/command_classes/codecs/codec.h b/src/video_core/command_classes/codecs/codec.h index ee5d62540..8a2a6c360 100644 --- a/src/video_core/command_classes/codecs/codec.h +++ b/src/video_core/command_classes/codecs/codec.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <queue> | ||
| 8 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 9 | #include "video_core/command_classes/nvdec_common.h" | 10 | #include "video_core/command_classes/nvdec_common.h" |
| 10 | 11 | ||
| @@ -23,6 +24,9 @@ namespace Tegra { | |||
| 23 | class GPU; | 24 | class GPU; |
| 24 | struct VicRegisters; | 25 | struct VicRegisters; |
| 25 | 26 | ||
| 27 | void AVFrameDeleter(AVFrame* ptr); | ||
| 28 | using AVFramePtr = std::unique_ptr<AVFrame, decltype(&AVFrameDeleter)>; | ||
| 29 | |||
| 26 | namespace Decoder { | 30 | namespace Decoder { |
| 27 | class H264; | 31 | class H264; |
| 28 | class VP9; | 32 | class VP9; |
| @@ -42,9 +46,8 @@ public: | |||
| 42 | /// Call decoders to construct headers, decode AVFrame with ffmpeg | 46 | /// Call decoders to construct headers, decode AVFrame with ffmpeg |
| 43 | void Decode(); | 47 | void Decode(); |
| 44 | 48 | ||
| 45 | /// Returns most recently decoded frame | 49 | /// Returns next decoded frame |
| 46 | [[nodiscard]] AVFrame* GetCurrentFrame(); | 50 | [[nodiscard]] AVFramePtr GetCurrentFrame(); |
| 47 | [[nodiscard]] const AVFrame* GetCurrentFrame() const; | ||
| 48 | 51 | ||
| 49 | /// Returns the value of current_codec | 52 | /// Returns the value of current_codec |
| 50 | [[nodiscard]] NvdecCommon::VideoCodec GetCurrentCodec() const; | 53 | [[nodiscard]] NvdecCommon::VideoCodec GetCurrentCodec() const; |
| @@ -55,13 +58,13 @@ private: | |||
| 55 | 58 | ||
| 56 | AVCodec* av_codec{nullptr}; | 59 | AVCodec* av_codec{nullptr}; |
| 57 | AVCodecContext* av_codec_ctx{nullptr}; | 60 | AVCodecContext* av_codec_ctx{nullptr}; |
| 58 | AVFrame* av_frame{nullptr}; | ||
| 59 | 61 | ||
| 60 | GPU& gpu; | 62 | GPU& gpu; |
| 61 | std::unique_ptr<Decoder::H264> h264_decoder; | 63 | std::unique_ptr<Decoder::H264> h264_decoder; |
| 62 | std::unique_ptr<Decoder::VP9> vp9_decoder; | 64 | std::unique_ptr<Decoder::VP9> vp9_decoder; |
| 63 | 65 | ||
| 64 | NvdecCommon::NvdecRegisters state{}; | 66 | NvdecCommon::NvdecRegisters state{}; |
| 67 | std::queue<AVFramePtr> av_frames{}; | ||
| 65 | }; | 68 | }; |
| 66 | 69 | ||
| 67 | } // namespace Tegra | 70 | } // namespace Tegra |
diff --git a/src/video_core/command_classes/codecs/h264.cpp b/src/video_core/command_classes/codecs/h264.cpp index 33e063e20..65bbeac78 100644 --- a/src/video_core/command_classes/codecs/h264.cpp +++ b/src/video_core/command_classes/codecs/h264.cpp | |||
| @@ -43,7 +43,7 @@ H264::H264(GPU& gpu_) : gpu(gpu_) {} | |||
| 43 | 43 | ||
| 44 | H264::~H264() = default; | 44 | H264::~H264() = default; |
| 45 | 45 | ||
| 46 | const std::vector<u8>& H264::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state, | 46 | const std::vector<u8>& H264::ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state, |
| 47 | bool is_first_frame) { | 47 | bool is_first_frame) { |
| 48 | H264DecoderContext context{}; | 48 | H264DecoderContext context{}; |
| 49 | gpu.MemoryManager().ReadBlock(state.picture_info_offset, &context, sizeof(H264DecoderContext)); | 49 | gpu.MemoryManager().ReadBlock(state.picture_info_offset, &context, sizeof(H264DecoderContext)); |
diff --git a/src/video_core/command_classes/codecs/h264.h b/src/video_core/command_classes/codecs/h264.h index 273449495..0f3a1d9f3 100644 --- a/src/video_core/command_classes/codecs/h264.h +++ b/src/video_core/command_classes/codecs/h264.h | |||
| @@ -74,8 +74,8 @@ public: | |||
| 74 | ~H264(); | 74 | ~H264(); |
| 75 | 75 | ||
| 76 | /// Compose the H264 header of the frame for FFmpeg decoding | 76 | /// Compose the H264 header of the frame for FFmpeg decoding |
| 77 | [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(NvdecCommon::NvdecRegisters& state, | 77 | [[nodiscard]] const std::vector<u8>& ComposeFrameHeader( |
| 78 | bool is_first_frame = false); | 78 | const NvdecCommon::NvdecRegisters& state, bool is_first_frame = false); |
| 79 | 79 | ||
| 80 | private: | 80 | private: |
| 81 | struct H264ParameterSet { | 81 | struct H264ParameterSet { |
diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/command_classes/codecs/vp9.cpp index ab44fdc9e..b1d675cdb 100644 --- a/src/video_core/command_classes/codecs/vp9.cpp +++ b/src/video_core/command_classes/codecs/vp9.cpp | |||
| @@ -23,122 +23,102 @@ constexpr Vp9EntropyProbs default_probs{ | |||
| 23 | 222, 34, 30, 0, 72, 16, 44, 0, 58, 32, 12, 0, 10, 7, 6, 0, | 23 | 222, 34, 30, 0, 72, 16, 44, 0, 58, 32, 12, 0, 10, 7, 6, 0, |
| 24 | }, | 24 | }, |
| 25 | .coef_probs{ | 25 | .coef_probs{ |
| 26 | 195, 29, 183, 0, 84, 49, 136, 0, 8, 42, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 26 | 195, 29, 183, 84, 49, 136, 8, 42, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 27 | 0, 0, 0, 0, 31, 107, 169, 0, 35, 99, 159, 0, 17, 82, 140, 0, 8, 66, 114, 0, | 27 | 31, 107, 169, 35, 99, 159, 17, 82, 140, 8, 66, 114, 2, 44, 76, 1, 19, 32, |
| 28 | 2, 44, 76, 0, 1, 19, 32, 0, 40, 132, 201, 0, 29, 114, 187, 0, 13, 91, 157, 0, | 28 | 40, 132, 201, 29, 114, 187, 13, 91, 157, 7, 75, 127, 3, 58, 95, 1, 28, 47, |
| 29 | 7, 75, 127, 0, 3, 58, 95, 0, 1, 28, 47, 0, 69, 142, 221, 0, 42, 122, 201, 0, | 29 | 69, 142, 221, 42, 122, 201, 15, 91, 159, 6, 67, 121, 1, 42, 77, 1, 17, 31, |
| 30 | 15, 91, 159, 0, 6, 67, 121, 0, 1, 42, 77, 0, 1, 17, 31, 0, 102, 148, 228, 0, | 30 | 102, 148, 228, 67, 117, 204, 17, 82, 154, 6, 59, 114, 2, 39, 75, 1, 15, 29, |
| 31 | 67, 117, 204, 0, 17, 82, 154, 0, 6, 59, 114, 0, 2, 39, 75, 0, 1, 15, 29, 0, | 31 | 156, 57, 233, 119, 57, 212, 58, 48, 163, 29, 40, 124, 12, 30, 81, 3, 12, 31, |
| 32 | 156, 57, 233, 0, 119, 57, 212, 0, 58, 48, 163, 0, 29, 40, 124, 0, 12, 30, 81, 0, | 32 | 191, 107, 226, 124, 117, 204, 25, 99, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 33 | 3, 12, 31, 0, 191, 107, 226, 0, 124, 117, 204, 0, 25, 99, 155, 0, 0, 0, 0, 0, | 33 | 29, 148, 210, 37, 126, 194, 8, 93, 157, 2, 68, 118, 1, 39, 69, 1, 17, 33, |
| 34 | 0, 0, 0, 0, 0, 0, 0, 0, 29, 148, 210, 0, 37, 126, 194, 0, 8, 93, 157, 0, | 34 | 41, 151, 213, 27, 123, 193, 3, 82, 144, 1, 58, 105, 1, 32, 60, 1, 13, 26, |
| 35 | 2, 68, 118, 0, 1, 39, 69, 0, 1, 17, 33, 0, 41, 151, 213, 0, 27, 123, 193, 0, | 35 | 59, 159, 220, 23, 126, 198, 4, 88, 151, 1, 66, 114, 1, 38, 71, 1, 18, 34, |
| 36 | 3, 82, 144, 0, 1, 58, 105, 0, 1, 32, 60, 0, 1, 13, 26, 0, 59, 159, 220, 0, | 36 | 114, 136, 232, 51, 114, 207, 11, 83, 155, 3, 56, 105, 1, 33, 65, 1, 17, 34, |
| 37 | 23, 126, 198, 0, 4, 88, 151, 0, 1, 66, 114, 0, 1, 38, 71, 0, 1, 18, 34, 0, | 37 | 149, 65, 234, 121, 57, 215, 61, 49, 166, 28, 36, 114, 12, 25, 76, 3, 16, 42, |
| 38 | 114, 136, 232, 0, 51, 114, 207, 0, 11, 83, 155, 0, 3, 56, 105, 0, 1, 33, 65, 0, | 38 | 214, 49, 220, 132, 63, 188, 42, 65, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 39 | 1, 17, 34, 0, 149, 65, 234, 0, 121, 57, 215, 0, 61, 49, 166, 0, 28, 36, 114, 0, | 39 | 85, 137, 221, 104, 131, 216, 49, 111, 192, 21, 87, 155, 2, 49, 87, 1, 16, 28, |
| 40 | 12, 25, 76, 0, 3, 16, 42, 0, 214, 49, 220, 0, 132, 63, 188, 0, 42, 65, 137, 0, | 40 | 89, 163, 230, 90, 137, 220, 29, 100, 183, 10, 70, 135, 2, 42, 81, 1, 17, 33, |
| 41 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 137, 221, 0, 104, 131, 216, 0, | 41 | 108, 167, 237, 55, 133, 222, 15, 97, 179, 4, 72, 135, 1, 45, 85, 1, 19, 38, |
| 42 | 49, 111, 192, 0, 21, 87, 155, 0, 2, 49, 87, 0, 1, 16, 28, 0, 89, 163, 230, 0, | 42 | 124, 146, 240, 66, 124, 224, 17, 88, 175, 4, 58, 122, 1, 36, 75, 1, 18, 37, |
| 43 | 90, 137, 220, 0, 29, 100, 183, 0, 10, 70, 135, 0, 2, 42, 81, 0, 1, 17, 33, 0, | 43 | 141, 79, 241, 126, 70, 227, 66, 58, 182, 30, 44, 136, 12, 34, 96, 2, 20, 47, |
| 44 | 108, 167, 237, 0, 55, 133, 222, 0, 15, 97, 179, 0, 4, 72, 135, 0, 1, 45, 85, 0, | 44 | 229, 99, 249, 143, 111, 235, 46, 109, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 45 | 1, 19, 38, 0, 124, 146, 240, 0, 66, 124, 224, 0, 17, 88, 175, 0, 4, 58, 122, 0, | 45 | 82, 158, 236, 94, 146, 224, 25, 117, 191, 9, 87, 149, 3, 56, 99, 1, 33, 57, |
| 46 | 1, 36, 75, 0, 1, 18, 37, 0, 141, 79, 241, 0, 126, 70, 227, 0, 66, 58, 182, 0, | 46 | 83, 167, 237, 68, 145, 222, 10, 103, 177, 2, 72, 131, 1, 41, 79, 1, 20, 39, |
| 47 | 30, 44, 136, 0, 12, 34, 96, 0, 2, 20, 47, 0, 229, 99, 249, 0, 143, 111, 235, 0, | 47 | 99, 167, 239, 47, 141, 224, 10, 104, 178, 2, 73, 133, 1, 44, 85, 1, 22, 47, |
| 48 | 46, 109, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 158, 236, 0, | 48 | 127, 145, 243, 71, 129, 228, 17, 93, 177, 3, 61, 124, 1, 41, 84, 1, 21, 52, |
| 49 | 94, 146, 224, 0, 25, 117, 191, 0, 9, 87, 149, 0, 3, 56, 99, 0, 1, 33, 57, 0, | 49 | 157, 78, 244, 140, 72, 231, 69, 58, 184, 31, 44, 137, 14, 38, 105, 8, 23, 61, |
| 50 | 83, 167, 237, 0, 68, 145, 222, 0, 10, 103, 177, 0, 2, 72, 131, 0, 1, 41, 79, 0, | 50 | 125, 34, 187, 52, 41, 133, 6, 31, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 51 | 1, 20, 39, 0, 99, 167, 239, 0, 47, 141, 224, 0, 10, 104, 178, 0, 2, 73, 133, 0, | 51 | 37, 109, 153, 51, 102, 147, 23, 87, 128, 8, 67, 101, 1, 41, 63, 1, 19, 29, |
| 52 | 1, 44, 85, 0, 1, 22, 47, 0, 127, 145, 243, 0, 71, 129, 228, 0, 17, 93, 177, 0, | 52 | 31, 154, 185, 17, 127, 175, 6, 96, 145, 2, 73, 114, 1, 51, 82, 1, 28, 45, |
| 53 | 3, 61, 124, 0, 1, 41, 84, 0, 1, 21, 52, 0, 157, 78, 244, 0, 140, 72, 231, 0, | 53 | 23, 163, 200, 10, 131, 185, 2, 93, 148, 1, 67, 111, 1, 41, 69, 1, 14, 24, |
| 54 | 69, 58, 184, 0, 31, 44, 137, 0, 14, 38, 105, 0, 8, 23, 61, 0, 125, 34, 187, 0, | 54 | 29, 176, 217, 12, 145, 201, 3, 101, 156, 1, 69, 111, 1, 39, 63, 1, 14, 23, |
| 55 | 52, 41, 133, 0, 6, 31, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 55 | 57, 192, 233, 25, 154, 215, 6, 109, 167, 3, 78, 118, 1, 48, 69, 1, 21, 29, |
| 56 | 37, 109, 153, 0, 51, 102, 147, 0, 23, 87, 128, 0, 8, 67, 101, 0, 1, 41, 63, 0, | 56 | 202, 105, 245, 108, 106, 216, 18, 90, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 57 | 1, 19, 29, 0, 31, 154, 185, 0, 17, 127, 175, 0, 6, 96, 145, 0, 2, 73, 114, 0, | 57 | 33, 172, 219, 64, 149, 206, 14, 117, 177, 5, 90, 141, 2, 61, 95, 1, 37, 57, |
| 58 | 1, 51, 82, 0, 1, 28, 45, 0, 23, 163, 200, 0, 10, 131, 185, 0, 2, 93, 148, 0, | 58 | 33, 179, 220, 11, 140, 198, 1, 89, 148, 1, 60, 104, 1, 33, 57, 1, 12, 21, |
| 59 | 1, 67, 111, 0, 1, 41, 69, 0, 1, 14, 24, 0, 29, 176, 217, 0, 12, 145, 201, 0, | 59 | 30, 181, 221, 8, 141, 198, 1, 87, 145, 1, 58, 100, 1, 31, 55, 1, 12, 20, |
| 60 | 3, 101, 156, 0, 1, 69, 111, 0, 1, 39, 63, 0, 1, 14, 23, 0, 57, 192, 233, 0, | 60 | 32, 186, 224, 7, 142, 198, 1, 86, 143, 1, 58, 100, 1, 31, 55, 1, 12, 22, |
| 61 | 25, 154, 215, 0, 6, 109, 167, 0, 3, 78, 118, 0, 1, 48, 69, 0, 1, 21, 29, 0, | 61 | 57, 192, 227, 20, 143, 204, 3, 96, 154, 1, 68, 112, 1, 42, 69, 1, 19, 32, |
| 62 | 202, 105, 245, 0, 108, 106, 216, 0, 18, 90, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 62 | 212, 35, 215, 113, 47, 169, 29, 48, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 63 | 0, 0, 0, 0, 33, 172, 219, 0, 64, 149, 206, 0, 14, 117, 177, 0, 5, 90, 141, 0, | 63 | 74, 129, 203, 106, 120, 203, 49, 107, 178, 19, 84, 144, 4, 50, 84, 1, 15, 25, |
| 64 | 2, 61, 95, 0, 1, 37, 57, 0, 33, 179, 220, 0, 11, 140, 198, 0, 1, 89, 148, 0, | 64 | 71, 172, 217, 44, 141, 209, 15, 102, 173, 6, 76, 133, 2, 51, 89, 1, 24, 42, |
| 65 | 1, 60, 104, 0, 1, 33, 57, 0, 1, 12, 21, 0, 30, 181, 221, 0, 8, 141, 198, 0, | 65 | 64, 185, 231, 31, 148, 216, 8, 103, 175, 3, 74, 131, 1, 46, 81, 1, 18, 30, |
| 66 | 1, 87, 145, 0, 1, 58, 100, 0, 1, 31, 55, 0, 1, 12, 20, 0, 32, 186, 224, 0, | 66 | 65, 196, 235, 25, 157, 221, 5, 105, 174, 1, 67, 120, 1, 38, 69, 1, 15, 30, |
| 67 | 7, 142, 198, 0, 1, 86, 143, 0, 1, 58, 100, 0, 1, 31, 55, 0, 1, 12, 22, 0, | 67 | 65, 204, 238, 30, 156, 224, 7, 107, 177, 2, 70, 124, 1, 42, 73, 1, 18, 34, |
| 68 | 57, 192, 227, 0, 20, 143, 204, 0, 3, 96, 154, 0, 1, 68, 112, 0, 1, 42, 69, 0, | 68 | 225, 86, 251, 144, 104, 235, 42, 99, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 69 | 1, 19, 32, 0, 212, 35, 215, 0, 113, 47, 169, 0, 29, 48, 105, 0, 0, 0, 0, 0, | 69 | 85, 175, 239, 112, 165, 229, 29, 136, 200, 12, 103, 162, 6, 77, 123, 2, 53, 84, |
| 70 | 0, 0, 0, 0, 0, 0, 0, 0, 74, 129, 203, 0, 106, 120, 203, 0, 49, 107, 178, 0, | 70 | 75, 183, 239, 30, 155, 221, 3, 106, 171, 1, 74, 128, 1, 44, 76, 1, 17, 28, |
| 71 | 19, 84, 144, 0, 4, 50, 84, 0, 1, 15, 25, 0, 71, 172, 217, 0, 44, 141, 209, 0, | 71 | 73, 185, 240, 27, 159, 222, 2, 107, 172, 1, 75, 127, 1, 42, 73, 1, 17, 29, |
| 72 | 15, 102, 173, 0, 6, 76, 133, 0, 2, 51, 89, 0, 1, 24, 42, 0, 64, 185, 231, 0, | 72 | 62, 190, 238, 21, 159, 222, 2, 107, 172, 1, 72, 122, 1, 40, 71, 1, 18, 32, |
| 73 | 31, 148, 216, 0, 8, 103, 175, 0, 3, 74, 131, 0, 1, 46, 81, 0, 1, 18, 30, 0, | 73 | 61, 199, 240, 27, 161, 226, 4, 113, 180, 1, 76, 129, 1, 46, 80, 1, 23, 41, |
| 74 | 65, 196, 235, 0, 25, 157, 221, 0, 5, 105, 174, 0, 1, 67, 120, 0, 1, 38, 69, 0, | 74 | 7, 27, 153, 5, 30, 95, 1, 16, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 75 | 1, 15, 30, 0, 65, 204, 238, 0, 30, 156, 224, 0, 7, 107, 177, 0, 2, 70, 124, 0, | 75 | 50, 75, 127, 57, 75, 124, 27, 67, 108, 10, 54, 86, 1, 33, 52, 1, 12, 18, |
| 76 | 1, 42, 73, 0, 1, 18, 34, 0, 225, 86, 251, 0, 144, 104, 235, 0, 42, 99, 181, 0, | 76 | 43, 125, 151, 26, 108, 148, 7, 83, 122, 2, 59, 89, 1, 38, 60, 1, 17, 27, |
| 77 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 175, 239, 0, 112, 165, 229, 0, | 77 | 23, 144, 163, 13, 112, 154, 2, 75, 117, 1, 50, 81, 1, 31, 51, 1, 14, 23, |
| 78 | 29, 136, 200, 0, 12, 103, 162, 0, 6, 77, 123, 0, 2, 53, 84, 0, 75, 183, 239, 0, | 78 | 18, 162, 185, 6, 123, 171, 1, 78, 125, 1, 51, 86, 1, 31, 54, 1, 14, 23, |
| 79 | 30, 155, 221, 0, 3, 106, 171, 0, 1, 74, 128, 0, 1, 44, 76, 0, 1, 17, 28, 0, | 79 | 15, 199, 227, 3, 150, 204, 1, 91, 146, 1, 55, 95, 1, 30, 53, 1, 11, 20, |
| 80 | 73, 185, 240, 0, 27, 159, 222, 0, 2, 107, 172, 0, 1, 75, 127, 0, 1, 42, 73, 0, | 80 | 19, 55, 240, 19, 59, 196, 3, 52, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 81 | 1, 17, 29, 0, 62, 190, 238, 0, 21, 159, 222, 0, 2, 107, 172, 0, 1, 72, 122, 0, | 81 | 41, 166, 207, 104, 153, 199, 31, 123, 181, 14, 101, 152, 5, 72, 106, 1, 36, 52, |
| 82 | 1, 40, 71, 0, 1, 18, 32, 0, 61, 199, 240, 0, 27, 161, 226, 0, 4, 113, 180, 0, | 82 | 35, 176, 211, 12, 131, 190, 2, 88, 144, 1, 60, 101, 1, 36, 60, 1, 16, 28, |
| 83 | 1, 76, 129, 0, 1, 46, 80, 0, 1, 23, 41, 0, 7, 27, 153, 0, 5, 30, 95, 0, | 83 | 28, 183, 213, 8, 134, 191, 1, 86, 142, 1, 56, 96, 1, 30, 53, 1, 12, 20, |
| 84 | 1, 16, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 75, 127, 0, | 84 | 20, 190, 215, 4, 135, 192, 1, 84, 139, 1, 53, 91, 1, 28, 49, 1, 11, 20, |
| 85 | 57, 75, 124, 0, 27, 67, 108, 0, 10, 54, 86, 0, 1, 33, 52, 0, 1, 12, 18, 0, | 85 | 13, 196, 216, 2, 137, 192, 1, 86, 143, 1, 57, 99, 1, 32, 56, 1, 13, 24, |
| 86 | 43, 125, 151, 0, 26, 108, 148, 0, 7, 83, 122, 0, 2, 59, 89, 0, 1, 38, 60, 0, | 86 | 211, 29, 217, 96, 47, 156, 22, 43, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 87 | 1, 17, 27, 0, 23, 144, 163, 0, 13, 112, 154, 0, 2, 75, 117, 0, 1, 50, 81, 0, | 87 | 78, 120, 193, 111, 116, 186, 46, 102, 164, 15, 80, 128, 2, 49, 76, 1, 18, 28, |
| 88 | 1, 31, 51, 0, 1, 14, 23, 0, 18, 162, 185, 0, 6, 123, 171, 0, 1, 78, 125, 0, | 88 | 71, 161, 203, 42, 132, 192, 10, 98, 150, 3, 69, 109, 1, 44, 70, 1, 18, 29, |
| 89 | 1, 51, 86, 0, 1, 31, 54, 0, 1, 14, 23, 0, 15, 199, 227, 0, 3, 150, 204, 0, | 89 | 57, 186, 211, 30, 140, 196, 4, 93, 146, 1, 62, 102, 1, 38, 65, 1, 16, 27, |
| 90 | 1, 91, 146, 0, 1, 55, 95, 0, 1, 30, 53, 0, 1, 11, 20, 0, 19, 55, 240, 0, | 90 | 47, 199, 217, 14, 145, 196, 1, 88, 142, 1, 57, 98, 1, 36, 62, 1, 15, 26, |
| 91 | 19, 59, 196, 0, 3, 52, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 91 | 26, 219, 229, 5, 155, 207, 1, 94, 151, 1, 60, 104, 1, 36, 62, 1, 16, 28, |
| 92 | 41, 166, 207, 0, 104, 153, 199, 0, 31, 123, 181, 0, 14, 101, 152, 0, 5, 72, 106, 0, | 92 | 233, 29, 248, 146, 47, 220, 43, 52, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 93 | 1, 36, 52, 0, 35, 176, 211, 0, 12, 131, 190, 0, 2, 88, 144, 0, 1, 60, 101, 0, | 93 | 100, 163, 232, 179, 161, 222, 63, 142, 204, 37, 113, 174, 26, 89, 137, 18, 68, 97, |
| 94 | 1, 36, 60, 0, 1, 16, 28, 0, 28, 183, 213, 0, 8, 134, 191, 0, 1, 86, 142, 0, | 94 | 85, 181, 230, 32, 146, 209, 7, 100, 164, 3, 71, 121, 1, 45, 77, 1, 18, 30, |
| 95 | 1, 56, 96, 0, 1, 30, 53, 0, 1, 12, 20, 0, 20, 190, 215, 0, 4, 135, 192, 0, | 95 | 65, 187, 230, 20, 148, 207, 2, 97, 159, 1, 68, 116, 1, 40, 70, 1, 14, 29, |
| 96 | 1, 84, 139, 0, 1, 53, 91, 0, 1, 28, 49, 0, 1, 11, 20, 0, 13, 196, 216, 0, | 96 | 40, 194, 227, 8, 147, 204, 1, 94, 155, 1, 65, 112, 1, 39, 66, 1, 14, 26, |
| 97 | 2, 137, 192, 0, 1, 86, 143, 0, 1, 57, 99, 0, 1, 32, 56, 0, 1, 13, 24, 0, | 97 | 16, 208, 228, 3, 151, 207, 1, 98, 160, 1, 67, 117, 1, 41, 74, 1, 17, 31, |
| 98 | 211, 29, 217, 0, 96, 47, 156, 0, 22, 43, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 98 | 17, 38, 140, 7, 34, 80, 1, 17, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 99 | 0, 0, 0, 0, 78, 120, 193, 0, 111, 116, 186, 0, 46, 102, 164, 0, 15, 80, 128, 0, | 99 | 37, 75, 128, 41, 76, 128, 26, 66, 116, 12, 52, 94, 2, 32, 55, 1, 10, 16, |
| 100 | 2, 49, 76, 0, 1, 18, 28, 0, 71, 161, 203, 0, 42, 132, 192, 0, 10, 98, 150, 0, | 100 | 50, 127, 154, 37, 109, 152, 16, 82, 121, 5, 59, 85, 1, 35, 54, 1, 13, 20, |
| 101 | 3, 69, 109, 0, 1, 44, 70, 0, 1, 18, 29, 0, 57, 186, 211, 0, 30, 140, 196, 0, | 101 | 40, 142, 167, 17, 110, 157, 2, 71, 112, 1, 44, 72, 1, 27, 45, 1, 11, 17, |
| 102 | 4, 93, 146, 0, 1, 62, 102, 0, 1, 38, 65, 0, 1, 16, 27, 0, 47, 199, 217, 0, | 102 | 30, 175, 188, 9, 124, 169, 1, 74, 116, 1, 48, 78, 1, 30, 49, 1, 11, 18, |
| 103 | 14, 145, 196, 0, 1, 88, 142, 0, 1, 57, 98, 0, 1, 36, 62, 0, 1, 15, 26, 0, | 103 | 10, 222, 223, 2, 150, 194, 1, 83, 128, 1, 48, 79, 1, 27, 45, 1, 11, 17, |
| 104 | 26, 219, 229, 0, 5, 155, 207, 0, 1, 94, 151, 0, 1, 60, 104, 0, 1, 36, 62, 0, | 104 | 36, 41, 235, 29, 36, 193, 10, 27, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 105 | 1, 16, 28, 0, 233, 29, 248, 0, 146, 47, 220, 0, 43, 52, 140, 0, 0, 0, 0, 0, | 105 | 85, 165, 222, 177, 162, 215, 110, 135, 195, 57, 113, 168, 23, 83, 120, 10, 49, 61, |
| 106 | 0, 0, 0, 0, 0, 0, 0, 0, 100, 163, 232, 0, 179, 161, 222, 0, 63, 142, 204, 0, | 106 | 85, 190, 223, 36, 139, 200, 5, 90, 146, 1, 60, 103, 1, 38, 65, 1, 18, 30, |
| 107 | 37, 113, 174, 0, 26, 89, 137, 0, 18, 68, 97, 0, 85, 181, 230, 0, 32, 146, 209, 0, | 107 | 72, 202, 223, 23, 141, 199, 2, 86, 140, 1, 56, 97, 1, 36, 61, 1, 16, 27, |
| 108 | 7, 100, 164, 0, 3, 71, 121, 0, 1, 45, 77, 0, 1, 18, 30, 0, 65, 187, 230, 0, | 108 | 55, 218, 225, 13, 145, 200, 1, 86, 141, 1, 57, 99, 1, 35, 61, 1, 13, 22, |
| 109 | 20, 148, 207, 0, 2, 97, 159, 0, 1, 68, 116, 0, 1, 40, 70, 0, 1, 14, 29, 0, | 109 | 15, 235, 212, 1, 132, 184, 1, 84, 139, 1, 57, 97, 1, 34, 56, 1, 14, 23, |
| 110 | 40, 194, 227, 0, 8, 147, 204, 0, 1, 94, 155, 0, 1, 65, 112, 0, 1, 39, 66, 0, | 110 | 181, 21, 201, 61, 37, 123, 10, 38, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 111 | 1, 14, 26, 0, 16, 208, 228, 0, 3, 151, 207, 0, 1, 98, 160, 0, 1, 67, 117, 0, | 111 | 47, 106, 172, 95, 104, 173, 42, 93, 159, 18, 77, 131, 4, 50, 81, 1, 17, 23, |
| 112 | 1, 41, 74, 0, 1, 17, 31, 0, 17, 38, 140, 0, 7, 34, 80, 0, 1, 17, 29, 0, | 112 | 62, 147, 199, 44, 130, 189, 28, 102, 154, 18, 75, 115, 2, 44, 65, 1, 12, 19, |
| 113 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 75, 128, 0, 41, 76, 128, 0, | 113 | 55, 153, 210, 24, 130, 194, 3, 93, 146, 1, 61, 97, 1, 31, 50, 1, 10, 16, |
| 114 | 26, 66, 116, 0, 12, 52, 94, 0, 2, 32, 55, 0, 1, 10, 16, 0, 50, 127, 154, 0, | 114 | 49, 186, 223, 17, 148, 204, 1, 96, 142, 1, 53, 83, 1, 26, 44, 1, 11, 17, |
| 115 | 37, 109, 152, 0, 16, 82, 121, 0, 5, 59, 85, 0, 1, 35, 54, 0, 1, 13, 20, 0, | 115 | 13, 217, 212, 2, 136, 180, 1, 78, 124, 1, 50, 83, 1, 29, 49, 1, 14, 23, |
| 116 | 40, 142, 167, 0, 17, 110, 157, 0, 2, 71, 112, 0, 1, 44, 72, 0, 1, 27, 45, 0, | 116 | 197, 13, 247, 82, 17, 222, 25, 17, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 117 | 1, 11, 17, 0, 30, 175, 188, 0, 9, 124, 169, 0, 1, 74, 116, 0, 1, 48, 78, 0, | 117 | 126, 186, 247, 234, 191, 243, 176, 177, 234, 104, 158, 220, 66, 128, 186, 55, 90, 137, |
| 118 | 1, 30, 49, 0, 1, 11, 18, 0, 10, 222, 223, 0, 2, 150, 194, 0, 1, 83, 128, 0, | 118 | 111, 197, 242, 46, 158, 219, 9, 104, 171, 2, 65, 125, 1, 44, 80, 1, 17, 91, |
| 119 | 1, 48, 79, 0, 1, 27, 45, 0, 1, 11, 17, 0, 36, 41, 235, 0, 29, 36, 193, 0, | 119 | 104, 208, 245, 39, 168, 224, 3, 109, 162, 1, 79, 124, 1, 50, 102, 1, 43, 102, |
| 120 | 10, 27, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 165, 222, 0, | 120 | 84, 220, 246, 31, 177, 231, 2, 115, 180, 1, 79, 134, 1, 55, 77, 1, 60, 79, |
| 121 | 177, 162, 215, 0, 110, 135, 195, 0, 57, 113, 168, 0, 23, 83, 120, 0, 10, 49, 61, 0, | 121 | 43, 243, 240, 8, 180, 217, 1, 115, 166, 1, 84, 121, 1, 51, 67, 1, 16, 6, |
| 122 | 85, 190, 223, 0, 36, 139, 200, 0, 5, 90, 146, 0, 1, 60, 103, 0, 1, 38, 65, 0, | ||
| 123 | 1, 18, 30, 0, 72, 202, 223, 0, 23, 141, 199, 0, 2, 86, 140, 0, 1, 56, 97, 0, | ||
| 124 | 1, 36, 61, 0, 1, 16, 27, 0, 55, 218, 225, 0, 13, 145, 200, 0, 1, 86, 141, 0, | ||
| 125 | 1, 57, 99, 0, 1, 35, 61, 0, 1, 13, 22, 0, 15, 235, 212, 0, 1, 132, 184, 0, | ||
| 126 | 1, 84, 139, 0, 1, 57, 97, 0, 1, 34, 56, 0, 1, 14, 23, 0, 181, 21, 201, 0, | ||
| 127 | 61, 37, 123, 0, 10, 38, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 128 | 47, 106, 172, 0, 95, 104, 173, 0, 42, 93, 159, 0, 18, 77, 131, 0, 4, 50, 81, 0, | ||
| 129 | 1, 17, 23, 0, 62, 147, 199, 0, 44, 130, 189, 0, 28, 102, 154, 0, 18, 75, 115, 0, | ||
| 130 | 2, 44, 65, 0, 1, 12, 19, 0, 55, 153, 210, 0, 24, 130, 194, 0, 3, 93, 146, 0, | ||
| 131 | 1, 61, 97, 0, 1, 31, 50, 0, 1, 10, 16, 0, 49, 186, 223, 0, 17, 148, 204, 0, | ||
| 132 | 1, 96, 142, 0, 1, 53, 83, 0, 1, 26, 44, 0, 1, 11, 17, 0, 13, 217, 212, 0, | ||
| 133 | 2, 136, 180, 0, 1, 78, 124, 0, 1, 50, 83, 0, 1, 29, 49, 0, 1, 14, 23, 0, | ||
| 134 | 197, 13, 247, 0, 82, 17, 222, 0, 25, 17, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 135 | 0, 0, 0, 0, 126, 186, 247, 0, 234, 191, 243, 0, 176, 177, 234, 0, 104, 158, 220, 0, | ||
| 136 | 66, 128, 186, 0, 55, 90, 137, 0, 111, 197, 242, 0, 46, 158, 219, 0, 9, 104, 171, 0, | ||
| 137 | 2, 65, 125, 0, 1, 44, 80, 0, 1, 17, 91, 0, 104, 208, 245, 0, 39, 168, 224, 0, | ||
| 138 | 3, 109, 162, 0, 1, 79, 124, 0, 1, 50, 102, 0, 1, 43, 102, 0, 84, 220, 246, 0, | ||
| 139 | 31, 177, 231, 0, 2, 115, 180, 0, 1, 79, 134, 0, 1, 55, 77, 0, 1, 60, 79, 0, | ||
| 140 | 43, 243, 240, 0, 8, 180, 217, 0, 1, 115, 166, 0, 1, 84, 121, 0, 1, 51, 67, 0, | ||
| 141 | 1, 16, 6, 0, | ||
| 142 | }, | 122 | }, |
| 143 | .switchable_interp_prob{235, 162, 36, 255, 34, 3, 149, 144}, | 123 | .switchable_interp_prob{235, 162, 36, 255, 34, 3, 149, 144}, |
| 144 | .inter_mode_prob{ | 124 | .inter_mode_prob{ |
| @@ -322,39 +302,23 @@ bool VP9::WriteLessThan(VpxRangeEncoder& writer, s32 value, s32 test) { | |||
| 322 | } | 302 | } |
| 323 | 303 | ||
| 324 | void VP9::WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode, | 304 | void VP9::WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode, |
| 325 | const std::array<u8, 2304>& new_prob, | 305 | const std::array<u8, 1728>& new_prob, |
| 326 | const std::array<u8, 2304>& old_prob) { | 306 | const std::array<u8, 1728>& old_prob) { |
| 327 | // Note: There's 1 byte added on each packet for alignment, | 307 | constexpr u32 block_bytes = 2 * 2 * 6 * 6 * 3; |
| 328 | // this byte is ignored when doing updates. | 308 | |
| 329 | constexpr s32 block_bytes = 2 * 2 * 6 * 6 * 4; | 309 | const auto needs_update = [&](u32 base_index) { |
| 330 | 310 | return !std::equal(new_prob.begin() + base_index, | |
| 331 | const auto needs_update = [&](s32 base_index) -> bool { | 311 | new_prob.begin() + base_index + block_bytes, |
| 332 | s32 index = base_index; | 312 | old_prob.begin() + base_index); |
| 333 | for (s32 i = 0; i < 2; i++) { | ||
| 334 | for (s32 j = 0; j < 2; j++) { | ||
| 335 | for (s32 k = 0; k < 6; k++) { | ||
| 336 | for (s32 l = 0; l < 6; l++) { | ||
| 337 | if (new_prob[index + 0] != old_prob[index + 0] || | ||
| 338 | new_prob[index + 1] != old_prob[index + 1] || | ||
| 339 | new_prob[index + 2] != old_prob[index + 2]) { | ||
| 340 | return true; | ||
| 341 | } | ||
| 342 | |||
| 343 | index += 4; | ||
| 344 | } | ||
| 345 | } | ||
| 346 | } | ||
| 347 | } | ||
| 348 | return false; | ||
| 349 | }; | 313 | }; |
| 350 | 314 | ||
| 351 | for (s32 block_index = 0; block_index < 4; block_index++) { | 315 | for (u32 block_index = 0; block_index < 4; block_index++) { |
| 352 | const s32 base_index = block_index * block_bytes; | 316 | const u32 base_index = block_index * block_bytes; |
| 353 | const bool update = needs_update(base_index); | 317 | const bool update = needs_update(base_index); |
| 354 | writer.Write(update); | 318 | writer.Write(update); |
| 355 | 319 | ||
| 356 | if (update) { | 320 | if (update) { |
| 357 | s32 index = base_index; | 321 | u32 index = base_index; |
| 358 | for (s32 i = 0; i < 2; i++) { | 322 | for (s32 i = 0; i < 2; i++) { |
| 359 | for (s32 j = 0; j < 2; j++) { | 323 | for (s32 j = 0; j < 2; j++) { |
| 360 | for (s32 k = 0; k < 6; k++) { | 324 | for (s32 k = 0; k < 6; k++) { |
| @@ -367,14 +331,13 @@ void VP9::WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode, | |||
| 367 | WriteProbabilityUpdate(writer, new_prob[index + 2], | 331 | WriteProbabilityUpdate(writer, new_prob[index + 2], |
| 368 | old_prob[index + 2]); | 332 | old_prob[index + 2]); |
| 369 | } | 333 | } |
| 370 | index += 4; | 334 | index += 3; |
| 371 | } | 335 | } |
| 372 | } | 336 | } |
| 373 | } | 337 | } |
| 374 | } | 338 | } |
| 375 | } | 339 | } |
| 376 | 340 | if (block_index == static_cast<u32>(tx_mode)) { | |
| 377 | if (block_index == tx_mode) { | ||
| 378 | break; | 341 | break; |
| 379 | } | 342 | } |
| 380 | } | 343 | } |
| @@ -392,7 +355,7 @@ void VP9::WriteMvProbabilityUpdate(VpxRangeEncoder& writer, u8 new_prob, u8 old_ | |||
| 392 | Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state) { | 355 | Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state) { |
| 393 | PictureInfo picture_info{}; | 356 | PictureInfo picture_info{}; |
| 394 | gpu.MemoryManager().ReadBlock(state.picture_info_offset, &picture_info, sizeof(PictureInfo)); | 357 | gpu.MemoryManager().ReadBlock(state.picture_info_offset, &picture_info, sizeof(PictureInfo)); |
| 395 | Vp9PictureInfo vp9_info = picture_info.Convert(); | 358 | Vp9PictureInfo vp9_info = std::move(picture_info.Convert()); |
| 396 | 359 | ||
| 397 | InsertEntropy(state.vp9_entropy_probs_offset, vp9_info.entropy); | 360 | InsertEntropy(state.vp9_entropy_probs_offset, vp9_info.entropy); |
| 398 | 361 | ||
| @@ -414,8 +377,7 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state) | |||
| 414 | Vp9FrameContainer frame{}; | 377 | Vp9FrameContainer frame{}; |
| 415 | { | 378 | { |
| 416 | gpu.SyncGuestHost(); | 379 | gpu.SyncGuestHost(); |
| 417 | frame.info = GetVp9PictureInfo(state); | 380 | frame.info = std::move(GetVp9PictureInfo(state)); |
| 418 | |||
| 419 | frame.bit_stream.resize(frame.info.bitstream_size); | 381 | frame.bit_stream.resize(frame.info.bitstream_size); |
| 420 | gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.bit_stream.data(), | 382 | gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.bit_stream.data(), |
| 421 | frame.info.bitstream_size); | 383 | frame.info.bitstream_size); |
| @@ -423,37 +385,37 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state) | |||
| 423 | // Buffer two frames, saving the last show frame info | 385 | // Buffer two frames, saving the last show frame info |
| 424 | if (!next_next_frame.bit_stream.empty()) { | 386 | if (!next_next_frame.bit_stream.empty()) { |
| 425 | Vp9FrameContainer temp{ | 387 | Vp9FrameContainer temp{ |
| 426 | .info = frame.info, | 388 | .info = std::move(frame.info), |
| 427 | .bit_stream = frame.bit_stream, | 389 | .bit_stream = std::move(frame.bit_stream), |
| 428 | }; | 390 | }; |
| 429 | next_next_frame.info.show_frame = frame.info.last_frame_shown; | 391 | next_next_frame.info.show_frame = frame.info.last_frame_shown; |
| 430 | frame.info = next_next_frame.info; | 392 | frame.info = std::move(next_next_frame.info); |
| 431 | frame.bit_stream = next_next_frame.bit_stream; | 393 | frame.bit_stream = std::move(next_next_frame.bit_stream); |
| 432 | next_next_frame = std::move(temp); | 394 | next_next_frame = std::move(temp); |
| 433 | 395 | ||
| 434 | if (!next_frame.bit_stream.empty()) { | 396 | if (!next_frame.bit_stream.empty()) { |
| 435 | Vp9FrameContainer temp2{ | 397 | Vp9FrameContainer temp2{ |
| 436 | .info = frame.info, | 398 | .info = std::move(frame.info), |
| 437 | .bit_stream = frame.bit_stream, | 399 | .bit_stream = std::move(frame.bit_stream), |
| 438 | }; | 400 | }; |
| 439 | next_frame.info.show_frame = frame.info.last_frame_shown; | 401 | next_frame.info.show_frame = frame.info.last_frame_shown; |
| 440 | frame.info = next_frame.info; | 402 | frame.info = std::move(next_frame.info); |
| 441 | frame.bit_stream = next_frame.bit_stream; | 403 | frame.bit_stream = std::move(next_frame.bit_stream); |
| 442 | next_frame = std::move(temp2); | 404 | next_frame = std::move(temp2); |
| 443 | } else { | 405 | } else { |
| 444 | next_frame.info = frame.info; | 406 | next_frame.info = std::move(frame.info); |
| 445 | next_frame.bit_stream = frame.bit_stream; | 407 | next_frame.bit_stream = std::move(frame.bit_stream); |
| 446 | } | 408 | } |
| 447 | } else { | 409 | } else { |
| 448 | next_next_frame.info = frame.info; | 410 | next_next_frame.info = std::move(frame.info); |
| 449 | next_next_frame.bit_stream = frame.bit_stream; | 411 | next_next_frame.bit_stream = std::move(frame.bit_stream); |
| 450 | } | 412 | } |
| 451 | return frame; | 413 | return frame; |
| 452 | } | 414 | } |
| 453 | 415 | ||
| 454 | std::vector<u8> VP9::ComposeCompressedHeader() { | 416 | std::vector<u8> VP9::ComposeCompressedHeader() { |
| 455 | VpxRangeEncoder writer{}; | 417 | VpxRangeEncoder writer{}; |
| 456 | 418 | const bool update_probs = current_frame_info.show_frame && !current_frame_info.is_key_frame; | |
| 457 | if (!current_frame_info.lossless) { | 419 | if (!current_frame_info.lossless) { |
| 458 | if (static_cast<u32>(current_frame_info.transform_mode) >= 3) { | 420 | if (static_cast<u32>(current_frame_info.transform_mode) >= 3) { |
| 459 | writer.Write(3, 2); | 421 | writer.Write(3, 2); |
| @@ -471,7 +433,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 471 | prev_frame_probs.tx_16x16_prob); | 433 | prev_frame_probs.tx_16x16_prob); |
| 472 | WriteProbabilityUpdate(writer, current_frame_info.entropy.tx_32x32_prob, | 434 | WriteProbabilityUpdate(writer, current_frame_info.entropy.tx_32x32_prob, |
| 473 | prev_frame_probs.tx_32x32_prob); | 435 | prev_frame_probs.tx_32x32_prob); |
| 474 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | 436 | if (update_probs) { |
| 475 | prev_frame_probs.tx_8x8_prob = current_frame_info.entropy.tx_8x8_prob; | 437 | prev_frame_probs.tx_8x8_prob = current_frame_info.entropy.tx_8x8_prob; |
| 476 | prev_frame_probs.tx_16x16_prob = current_frame_info.entropy.tx_16x16_prob; | 438 | prev_frame_probs.tx_16x16_prob = current_frame_info.entropy.tx_16x16_prob; |
| 477 | prev_frame_probs.tx_32x32_prob = current_frame_info.entropy.tx_32x32_prob; | 439 | prev_frame_probs.tx_32x32_prob = current_frame_info.entropy.tx_32x32_prob; |
| @@ -484,7 +446,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 484 | WriteProbabilityUpdate(writer, current_frame_info.entropy.skip_probs, | 446 | WriteProbabilityUpdate(writer, current_frame_info.entropy.skip_probs, |
| 485 | prev_frame_probs.skip_probs); | 447 | prev_frame_probs.skip_probs); |
| 486 | 448 | ||
| 487 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | 449 | if (update_probs) { |
| 488 | prev_frame_probs.coef_probs = current_frame_info.entropy.coef_probs; | 450 | prev_frame_probs.coef_probs = current_frame_info.entropy.coef_probs; |
| 489 | prev_frame_probs.skip_probs = current_frame_info.entropy.skip_probs; | 451 | prev_frame_probs.skip_probs = current_frame_info.entropy.skip_probs; |
| 490 | } | 452 | } |
| @@ -493,15 +455,12 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 493 | // read_inter_probs() in the spec | 455 | // read_inter_probs() in the spec |
| 494 | WriteProbabilityUpdateAligned4(writer, current_frame_info.entropy.inter_mode_prob, | 456 | WriteProbabilityUpdateAligned4(writer, current_frame_info.entropy.inter_mode_prob, |
| 495 | prev_frame_probs.inter_mode_prob); | 457 | prev_frame_probs.inter_mode_prob); |
| 496 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | ||
| 497 | prev_frame_probs.inter_mode_prob = current_frame_info.entropy.inter_mode_prob; | ||
| 498 | } | ||
| 499 | 458 | ||
| 500 | if (current_frame_info.interp_filter == 4) { | 459 | if (current_frame_info.interp_filter == 4) { |
| 501 | // read_interp_filter_probs() in the spec | 460 | // read_interp_filter_probs() in the spec |
| 502 | WriteProbabilityUpdate(writer, current_frame_info.entropy.switchable_interp_prob, | 461 | WriteProbabilityUpdate(writer, current_frame_info.entropy.switchable_interp_prob, |
| 503 | prev_frame_probs.switchable_interp_prob); | 462 | prev_frame_probs.switchable_interp_prob); |
| 504 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | 463 | if (update_probs) { |
| 505 | prev_frame_probs.switchable_interp_prob = | 464 | prev_frame_probs.switchable_interp_prob = |
| 506 | current_frame_info.entropy.switchable_interp_prob; | 465 | current_frame_info.entropy.switchable_interp_prob; |
| 507 | } | 466 | } |
| @@ -510,9 +469,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 510 | // read_is_inter_probs() in the spec | 469 | // read_is_inter_probs() in the spec |
| 511 | WriteProbabilityUpdate(writer, current_frame_info.entropy.intra_inter_prob, | 470 | WriteProbabilityUpdate(writer, current_frame_info.entropy.intra_inter_prob, |
| 512 | prev_frame_probs.intra_inter_prob); | 471 | prev_frame_probs.intra_inter_prob); |
| 513 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | 472 | |
| 514 | prev_frame_probs.intra_inter_prob = current_frame_info.entropy.intra_inter_prob; | ||
| 515 | } | ||
| 516 | // frame_reference_mode() in the spec | 473 | // frame_reference_mode() in the spec |
| 517 | if ((current_frame_info.ref_frame_sign_bias[1] & 1) != | 474 | if ((current_frame_info.ref_frame_sign_bias[1] & 1) != |
| 518 | (current_frame_info.ref_frame_sign_bias[2] & 1) || | 475 | (current_frame_info.ref_frame_sign_bias[2] & 1) || |
| @@ -530,7 +487,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 530 | if (current_frame_info.reference_mode == 2) { | 487 | if (current_frame_info.reference_mode == 2) { |
| 531 | WriteProbabilityUpdate(writer, current_frame_info.entropy.comp_inter_prob, | 488 | WriteProbabilityUpdate(writer, current_frame_info.entropy.comp_inter_prob, |
| 532 | prev_frame_probs.comp_inter_prob); | 489 | prev_frame_probs.comp_inter_prob); |
| 533 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | 490 | if (update_probs) { |
| 534 | prev_frame_probs.comp_inter_prob = current_frame_info.entropy.comp_inter_prob; | 491 | prev_frame_probs.comp_inter_prob = current_frame_info.entropy.comp_inter_prob; |
| 535 | } | 492 | } |
| 536 | } | 493 | } |
| @@ -538,7 +495,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 538 | if (current_frame_info.reference_mode != 1) { | 495 | if (current_frame_info.reference_mode != 1) { |
| 539 | WriteProbabilityUpdate(writer, current_frame_info.entropy.single_ref_prob, | 496 | WriteProbabilityUpdate(writer, current_frame_info.entropy.single_ref_prob, |
| 540 | prev_frame_probs.single_ref_prob); | 497 | prev_frame_probs.single_ref_prob); |
| 541 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | 498 | if (update_probs) { |
| 542 | prev_frame_probs.single_ref_prob = current_frame_info.entropy.single_ref_prob; | 499 | prev_frame_probs.single_ref_prob = current_frame_info.entropy.single_ref_prob; |
| 543 | } | 500 | } |
| 544 | } | 501 | } |
| @@ -546,7 +503,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 546 | if (current_frame_info.reference_mode != 0) { | 503 | if (current_frame_info.reference_mode != 0) { |
| 547 | WriteProbabilityUpdate(writer, current_frame_info.entropy.comp_ref_prob, | 504 | WriteProbabilityUpdate(writer, current_frame_info.entropy.comp_ref_prob, |
| 548 | prev_frame_probs.comp_ref_prob); | 505 | prev_frame_probs.comp_ref_prob); |
| 549 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | 506 | if (update_probs) { |
| 550 | prev_frame_probs.comp_ref_prob = current_frame_info.entropy.comp_ref_prob; | 507 | prev_frame_probs.comp_ref_prob = current_frame_info.entropy.comp_ref_prob; |
| 551 | } | 508 | } |
| 552 | } | 509 | } |
| @@ -557,42 +514,37 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 557 | WriteProbabilityUpdate(writer, current_frame_info.entropy.y_mode_prob[index], | 514 | WriteProbabilityUpdate(writer, current_frame_info.entropy.y_mode_prob[index], |
| 558 | prev_frame_probs.y_mode_prob[index]); | 515 | prev_frame_probs.y_mode_prob[index]); |
| 559 | } | 516 | } |
| 560 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | 517 | |
| 561 | prev_frame_probs.y_mode_prob = current_frame_info.entropy.y_mode_prob; | ||
| 562 | } | ||
| 563 | // read_partition_probs | 518 | // read_partition_probs |
| 564 | WriteProbabilityUpdateAligned4(writer, current_frame_info.entropy.partition_prob, | 519 | WriteProbabilityUpdateAligned4(writer, current_frame_info.entropy.partition_prob, |
| 565 | prev_frame_probs.partition_prob); | 520 | prev_frame_probs.partition_prob); |
| 566 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | ||
| 567 | prev_frame_probs.partition_prob = current_frame_info.entropy.partition_prob; | ||
| 568 | } | ||
| 569 | 521 | ||
| 570 | // mv_probs | 522 | // mv_probs |
| 571 | for (s32 i = 0; i < 3; i++) { | 523 | for (s32 i = 0; i < 3; i++) { |
| 572 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.joints[i], | 524 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.joints[i], |
| 573 | prev_frame_probs.joints[i]); | 525 | prev_frame_probs.joints[i]); |
| 574 | } | 526 | } |
| 575 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | 527 | if (update_probs) { |
| 528 | prev_frame_probs.inter_mode_prob = current_frame_info.entropy.inter_mode_prob; | ||
| 529 | prev_frame_probs.intra_inter_prob = current_frame_info.entropy.intra_inter_prob; | ||
| 530 | prev_frame_probs.y_mode_prob = current_frame_info.entropy.y_mode_prob; | ||
| 531 | prev_frame_probs.partition_prob = current_frame_info.entropy.partition_prob; | ||
| 576 | prev_frame_probs.joints = current_frame_info.entropy.joints; | 532 | prev_frame_probs.joints = current_frame_info.entropy.joints; |
| 577 | } | 533 | } |
| 578 | 534 | ||
| 579 | for (s32 i = 0; i < 2; i++) { | 535 | for (s32 i = 0; i < 2; i++) { |
| 580 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.sign[i], | 536 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.sign[i], |
| 581 | prev_frame_probs.sign[i]); | 537 | prev_frame_probs.sign[i]); |
| 582 | |||
| 583 | for (s32 j = 0; j < 10; j++) { | 538 | for (s32 j = 0; j < 10; j++) { |
| 584 | const int index = i * 10 + j; | 539 | const int index = i * 10 + j; |
| 585 | |||
| 586 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.classes[index], | 540 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.classes[index], |
| 587 | prev_frame_probs.classes[index]); | 541 | prev_frame_probs.classes[index]); |
| 588 | } | 542 | } |
| 589 | |||
| 590 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.class_0[i], | 543 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.class_0[i], |
| 591 | prev_frame_probs.class_0[i]); | 544 | prev_frame_probs.class_0[i]); |
| 592 | 545 | ||
| 593 | for (s32 j = 0; j < 10; j++) { | 546 | for (s32 j = 0; j < 10; j++) { |
| 594 | const int index = i * 10 + j; | 547 | const int index = i * 10 + j; |
| 595 | |||
| 596 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.prob_bits[index], | 548 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.prob_bits[index], |
| 597 | prev_frame_probs.prob_bits[index]); | 549 | prev_frame_probs.prob_bits[index]); |
| 598 | } | 550 | } |
| @@ -602,7 +554,6 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 602 | for (s32 j = 0; j < 2; j++) { | 554 | for (s32 j = 0; j < 2; j++) { |
| 603 | for (s32 k = 0; k < 3; k++) { | 555 | for (s32 k = 0; k < 3; k++) { |
| 604 | const int index = i * 2 * 3 + j * 3 + k; | 556 | const int index = i * 2 * 3 + j * 3 + k; |
| 605 | |||
| 606 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.class_0_fr[index], | 557 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.class_0_fr[index], |
| 607 | prev_frame_probs.class_0_fr[index]); | 558 | prev_frame_probs.class_0_fr[index]); |
| 608 | } | 559 | } |
| @@ -610,7 +561,6 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 610 | 561 | ||
| 611 | for (s32 j = 0; j < 3; j++) { | 562 | for (s32 j = 0; j < 3; j++) { |
| 612 | const int index = i * 3 + j; | 563 | const int index = i * 3 + j; |
| 613 | |||
| 614 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.fr[index], | 564 | WriteMvProbabilityUpdate(writer, current_frame_info.entropy.fr[index], |
| 615 | prev_frame_probs.fr[index]); | 565 | prev_frame_probs.fr[index]); |
| 616 | } | 566 | } |
| @@ -626,7 +576,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 626 | } | 576 | } |
| 627 | 577 | ||
| 628 | // save previous probs | 578 | // save previous probs |
| 629 | if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { | 579 | if (update_probs) { |
| 630 | prev_frame_probs.sign = current_frame_info.entropy.sign; | 580 | prev_frame_probs.sign = current_frame_info.entropy.sign; |
| 631 | prev_frame_probs.classes = current_frame_info.entropy.classes; | 581 | prev_frame_probs.classes = current_frame_info.entropy.classes; |
| 632 | prev_frame_probs.class_0 = current_frame_info.entropy.class_0; | 582 | prev_frame_probs.class_0 = current_frame_info.entropy.class_0; |
| @@ -637,7 +587,6 @@ std::vector<u8> VP9::ComposeCompressedHeader() { | |||
| 637 | prev_frame_probs.high_precision = current_frame_info.entropy.high_precision; | 587 | prev_frame_probs.high_precision = current_frame_info.entropy.high_precision; |
| 638 | } | 588 | } |
| 639 | } | 589 | } |
| 640 | |||
| 641 | writer.End(); | 590 | writer.End(); |
| 642 | return writer.GetBuffer(); | 591 | return writer.GetBuffer(); |
| 643 | } | 592 | } |
| @@ -854,11 +803,11 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() { | |||
| 854 | return uncomp_writer; | 803 | return uncomp_writer; |
| 855 | } | 804 | } |
| 856 | 805 | ||
| 857 | const std::vector<u8>& VP9::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state) { | 806 | const std::vector<u8>& VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state) { |
| 858 | std::vector<u8> bitstream; | 807 | std::vector<u8> bitstream; |
| 859 | { | 808 | { |
| 860 | Vp9FrameContainer curr_frame = GetCurrentFrame(state); | 809 | Vp9FrameContainer curr_frame = std::move(GetCurrentFrame(state)); |
| 861 | current_frame_info = curr_frame.info; | 810 | current_frame_info = std::move(curr_frame.info); |
| 862 | bitstream = std::move(curr_frame.bit_stream); | 811 | bitstream = std::move(curr_frame.bit_stream); |
| 863 | } | 812 | } |
| 864 | 813 | ||
diff --git a/src/video_core/command_classes/codecs/vp9.h b/src/video_core/command_classes/codecs/vp9.h index e2504512c..9ebbbf59e 100644 --- a/src/video_core/command_classes/codecs/vp9.h +++ b/src/video_core/command_classes/codecs/vp9.h | |||
| @@ -119,7 +119,8 @@ public: | |||
| 119 | 119 | ||
| 120 | /// Composes the VP9 frame from the GPU state information. Based on the official VP9 spec | 120 | /// Composes the VP9 frame from the GPU state information. Based on the official VP9 spec |
| 121 | /// documentation | 121 | /// documentation |
| 122 | [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(NvdecCommon::NvdecRegisters& state); | 122 | [[nodiscard]] const std::vector<u8>& ComposeFrameHeader( |
| 123 | const NvdecCommon::NvdecRegisters& state); | ||
| 123 | 124 | ||
| 124 | /// Returns true if the most recent frame was a hidden frame. | 125 | /// Returns true if the most recent frame was a hidden frame. |
| 125 | [[nodiscard]] bool WasFrameHidden() const { | 126 | [[nodiscard]] bool WasFrameHidden() const { |
| @@ -147,8 +148,8 @@ private: | |||
| 147 | 148 | ||
| 148 | /// Writes probability updates for the Coef probabilities | 149 | /// Writes probability updates for the Coef probabilities |
| 149 | void WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode, | 150 | void WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode, |
| 150 | const std::array<u8, 2304>& new_prob, | 151 | const std::array<u8, 1728>& new_prob, |
| 151 | const std::array<u8, 2304>& old_prob); | 152 | const std::array<u8, 1728>& old_prob); |
| 152 | 153 | ||
| 153 | /// Write probabilities for 4-byte aligned structures | 154 | /// Write probabilities for 4-byte aligned structures |
| 154 | template <typename T, std::size_t N> | 155 | template <typename T, std::size_t N> |
diff --git a/src/video_core/command_classes/codecs/vp9_types.h b/src/video_core/command_classes/codecs/vp9_types.h index 4f0b05d22..139501a1c 100644 --- a/src/video_core/command_classes/codecs/vp9_types.h +++ b/src/video_core/command_classes/codecs/vp9_types.h | |||
| @@ -31,62 +31,6 @@ enum FrameFlags : u32 { | |||
| 31 | IntraOnly = 1 << 5, | 31 | IntraOnly = 1 << 5, |
| 32 | }; | 32 | }; |
| 33 | 33 | ||
| 34 | enum class MvJointType { | ||
| 35 | MvJointZero = 0, /* Zero vector */ | ||
| 36 | MvJointHnzvz = 1, /* Vert zero, hor nonzero */ | ||
| 37 | MvJointHzvnz = 2, /* Hor zero, vert nonzero */ | ||
| 38 | MvJointHnzvnz = 3, /* Both components nonzero */ | ||
| 39 | }; | ||
| 40 | enum class MvClassType { | ||
| 41 | MvClass0 = 0, /* (0, 2] integer pel */ | ||
| 42 | MvClass1 = 1, /* (2, 4] integer pel */ | ||
| 43 | MvClass2 = 2, /* (4, 8] integer pel */ | ||
| 44 | MvClass3 = 3, /* (8, 16] integer pel */ | ||
| 45 | MvClass4 = 4, /* (16, 32] integer pel */ | ||
| 46 | MvClass5 = 5, /* (32, 64] integer pel */ | ||
| 47 | MvClass6 = 6, /* (64, 128] integer pel */ | ||
| 48 | MvClass7 = 7, /* (128, 256] integer pel */ | ||
| 49 | MvClass8 = 8, /* (256, 512] integer pel */ | ||
| 50 | MvClass9 = 9, /* (512, 1024] integer pel */ | ||
| 51 | MvClass10 = 10, /* (1024,2048] integer pel */ | ||
| 52 | }; | ||
| 53 | |||
| 54 | enum class BlockSize { | ||
| 55 | Block4x4 = 0, | ||
| 56 | Block4x8 = 1, | ||
| 57 | Block8x4 = 2, | ||
| 58 | Block8x8 = 3, | ||
| 59 | Block8x16 = 4, | ||
| 60 | Block16x8 = 5, | ||
| 61 | Block16x16 = 6, | ||
| 62 | Block16x32 = 7, | ||
| 63 | Block32x16 = 8, | ||
| 64 | Block32x32 = 9, | ||
| 65 | Block32x64 = 10, | ||
| 66 | Block64x32 = 11, | ||
| 67 | Block64x64 = 12, | ||
| 68 | BlockSizes = 13, | ||
| 69 | BlockInvalid = BlockSizes | ||
| 70 | }; | ||
| 71 | |||
| 72 | enum class PredictionMode { | ||
| 73 | DcPred = 0, // Average of above and left pixels | ||
| 74 | VPred = 1, // Vertical | ||
| 75 | HPred = 2, // Horizontal | ||
| 76 | D45Pred = 3, // Directional 45 deg = round(arctan(1 / 1) * 180 / pi) | ||
| 77 | D135Pred = 4, // Directional 135 deg = 180 - 45 | ||
| 78 | D117Pred = 5, // Directional 117 deg = 180 - 63 | ||
| 79 | D153Pred = 6, // Directional 153 deg = 180 - 27 | ||
| 80 | D207Pred = 7, // Directional 207 deg = 180 + 27 | ||
| 81 | D63Pred = 8, // Directional 63 deg = round(arctan(2 / 1) * 180 / pi) | ||
| 82 | TmPred = 9, // True-motion | ||
| 83 | NearestMv = 10, | ||
| 84 | NearMv = 11, | ||
| 85 | ZeroMv = 12, | ||
| 86 | NewMv = 13, | ||
| 87 | MbModeCount = 14 | ||
| 88 | }; | ||
| 89 | |||
| 90 | enum class TxSize { | 34 | enum class TxSize { |
| 91 | Tx4x4 = 0, // 4x4 transform | 35 | Tx4x4 = 0, // 4x4 transform |
| 92 | Tx8x8 = 1, // 8x8 transform | 36 | Tx8x8 = 1, // 8x8 transform |
| @@ -104,13 +48,6 @@ enum class TxMode { | |||
| 104 | TxModes = 5 | 48 | TxModes = 5 |
| 105 | }; | 49 | }; |
| 106 | 50 | ||
| 107 | enum class reference_mode { | ||
| 108 | SingleReference = 0, | ||
| 109 | CompoundReference = 1, | ||
| 110 | ReferenceModeSelect = 2, | ||
| 111 | ReferenceModes = 3 | ||
| 112 | }; | ||
| 113 | |||
| 114 | struct Segmentation { | 51 | struct Segmentation { |
| 115 | u8 enabled{}; | 52 | u8 enabled{}; |
| 116 | u8 update_map{}; | 53 | u8 update_map{}; |
| @@ -131,7 +68,7 @@ static_assert(sizeof(LoopFilter) == 0x7, "LoopFilter is an invalid size"); | |||
| 131 | struct Vp9EntropyProbs { | 68 | struct Vp9EntropyProbs { |
| 132 | std::array<u8, 36> y_mode_prob{}; | 69 | std::array<u8, 36> y_mode_prob{}; |
| 133 | std::array<u8, 64> partition_prob{}; | 70 | std::array<u8, 64> partition_prob{}; |
| 134 | std::array<u8, 2304> coef_probs{}; | 71 | std::array<u8, 1728> coef_probs{}; |
| 135 | std::array<u8, 8> switchable_interp_prob{}; | 72 | std::array<u8, 8> switchable_interp_prob{}; |
| 136 | std::array<u8, 28> inter_mode_prob{}; | 73 | std::array<u8, 28> inter_mode_prob{}; |
| 137 | std::array<u8, 4> intra_inter_prob{}; | 74 | std::array<u8, 4> intra_inter_prob{}; |
| @@ -152,7 +89,7 @@ struct Vp9EntropyProbs { | |||
| 152 | std::array<u8, 2> class_0_hp{}; | 89 | std::array<u8, 2> class_0_hp{}; |
| 153 | std::array<u8, 2> high_precision{}; | 90 | std::array<u8, 2> high_precision{}; |
| 154 | }; | 91 | }; |
| 155 | static_assert(sizeof(Vp9EntropyProbs) == 0x9F4, "Vp9EntropyProbs is an invalid size"); | 92 | static_assert(sizeof(Vp9EntropyProbs) == 0x7B4, "Vp9EntropyProbs is an invalid size"); |
| 156 | 93 | ||
| 157 | struct Vp9PictureInfo { | 94 | struct Vp9PictureInfo { |
| 158 | bool is_key_frame{}; | 95 | bool is_key_frame{}; |
| @@ -278,72 +215,71 @@ static_assert(sizeof(PictureInfo) == 0x100, "PictureInfo is an invalid size"); | |||
| 278 | 215 | ||
| 279 | struct EntropyProbs { | 216 | struct EntropyProbs { |
| 280 | INSERT_PADDING_BYTES(1024); | 217 | INSERT_PADDING_BYTES(1024); |
| 281 | std::array<std::array<u8, 4>, 7> inter_mode_prob{}; | 218 | std::array<u8, 28> inter_mode_prob{}; |
| 282 | std::array<u8, 4> intra_inter_prob{}; | 219 | std::array<u8, 4> intra_inter_prob{}; |
| 283 | INSERT_PADDING_BYTES(80); | 220 | INSERT_PADDING_BYTES(80); |
| 284 | std::array<std::array<u8, 1>, 2> tx_8x8_prob{}; | 221 | std::array<u8, 2> tx_8x8_prob{}; |
| 285 | std::array<std::array<u8, 2>, 2> tx_16x16_prob{}; | 222 | std::array<u8, 4> tx_16x16_prob{}; |
| 286 | std::array<std::array<u8, 3>, 2> tx_32x32_prob{}; | 223 | std::array<u8, 6> tx_32x32_prob{}; |
| 287 | std::array<u8, 4> y_mode_prob_e8{}; | 224 | std::array<u8, 4> y_mode_prob_e8{}; |
| 288 | std::array<std::array<u8, 8>, 4> y_mode_prob_e0e7{}; | 225 | std::array<std::array<u8, 8>, 4> y_mode_prob_e0e7{}; |
| 289 | INSERT_PADDING_BYTES(64); | 226 | INSERT_PADDING_BYTES(64); |
| 290 | std::array<std::array<u8, 4>, 16> partition_prob{}; | 227 | std::array<u8, 64> partition_prob{}; |
| 291 | INSERT_PADDING_BYTES(10); | 228 | INSERT_PADDING_BYTES(10); |
| 292 | std::array<std::array<u8, 2>, 4> switchable_interp_prob{}; | 229 | std::array<u8, 8> switchable_interp_prob{}; |
| 293 | std::array<u8, 5> comp_inter_prob{}; | 230 | std::array<u8, 5> comp_inter_prob{}; |
| 294 | std::array<u8, 4> skip_probs{}; | 231 | std::array<u8, 3> skip_probs{}; |
| 232 | INSERT_PADDING_BYTES(1); | ||
| 295 | std::array<u8, 3> joints{}; | 233 | std::array<u8, 3> joints{}; |
| 296 | std::array<u8, 2> sign{}; | 234 | std::array<u8, 2> sign{}; |
| 297 | std::array<std::array<u8, 1>, 2> class_0{}; | 235 | std::array<u8, 2> class_0{}; |
| 298 | std::array<std::array<u8, 3>, 2> fr{}; | 236 | std::array<u8, 6> fr{}; |
| 299 | std::array<u8, 2> class_0_hp{}; | 237 | std::array<u8, 2> class_0_hp{}; |
| 300 | std::array<u8, 2> high_precision{}; | 238 | std::array<u8, 2> high_precision{}; |
| 301 | std::array<std::array<u8, 10>, 2> classes{}; | 239 | std::array<u8, 20> classes{}; |
| 302 | std::array<std::array<std::array<u8, 3>, 2>, 2> class_0_fr{}; | 240 | std::array<u8, 12> class_0_fr{}; |
| 303 | std::array<std::array<u8, 10>, 2> pred_bits{}; | 241 | std::array<u8, 20> pred_bits{}; |
| 304 | std::array<std::array<u8, 2>, 5> single_ref_prob{}; | 242 | std::array<u8, 10> single_ref_prob{}; |
| 305 | std::array<u8, 5> comp_ref_prob{}; | 243 | std::array<u8, 5> comp_ref_prob{}; |
| 306 | INSERT_PADDING_BYTES(17); | 244 | INSERT_PADDING_BYTES(17); |
| 307 | std::array<std::array<std::array<std::array<std::array<std::array<u8, 4>, 6>, 6>, 2>, 2>, 4> | 245 | std::array<u8, 2304> coef_probs{}; |
| 308 | coef_probs{}; | ||
| 309 | 246 | ||
| 310 | void Convert(Vp9EntropyProbs& fc) { | 247 | void Convert(Vp9EntropyProbs& fc) { |
| 311 | std::memcpy(fc.inter_mode_prob.data(), inter_mode_prob.data(), fc.inter_mode_prob.size()); | 248 | fc.inter_mode_prob = inter_mode_prob; |
| 312 | 249 | fc.intra_inter_prob = intra_inter_prob; | |
| 313 | std::memcpy(fc.intra_inter_prob.data(), intra_inter_prob.data(), | 250 | fc.tx_8x8_prob = tx_8x8_prob; |
| 314 | fc.intra_inter_prob.size()); | 251 | fc.tx_16x16_prob = tx_16x16_prob; |
| 315 | 252 | fc.tx_32x32_prob = tx_32x32_prob; | |
| 316 | std::memcpy(fc.tx_8x8_prob.data(), tx_8x8_prob.data(), fc.tx_8x8_prob.size()); | 253 | |
| 317 | std::memcpy(fc.tx_16x16_prob.data(), tx_16x16_prob.data(), fc.tx_16x16_prob.size()); | 254 | for (std::size_t i = 0; i < 4; i++) { |
| 318 | std::memcpy(fc.tx_32x32_prob.data(), tx_32x32_prob.data(), fc.tx_32x32_prob.size()); | 255 | for (std::size_t j = 0; j < 9; j++) { |
| 319 | |||
| 320 | for (s32 i = 0; i < 4; i++) { | ||
| 321 | for (s32 j = 0; j < 9; j++) { | ||
| 322 | fc.y_mode_prob[j + 9 * i] = j < 8 ? y_mode_prob_e0e7[i][j] : y_mode_prob_e8[i]; | 256 | fc.y_mode_prob[j + 9 * i] = j < 8 ? y_mode_prob_e0e7[i][j] : y_mode_prob_e8[i]; |
| 323 | } | 257 | } |
| 324 | } | 258 | } |
| 325 | 259 | ||
| 326 | std::memcpy(fc.partition_prob.data(), partition_prob.data(), fc.partition_prob.size()); | 260 | fc.partition_prob = partition_prob; |
| 327 | 261 | fc.switchable_interp_prob = switchable_interp_prob; | |
| 328 | std::memcpy(fc.switchable_interp_prob.data(), switchable_interp_prob.data(), | 262 | fc.comp_inter_prob = comp_inter_prob; |
| 329 | fc.switchable_interp_prob.size()); | 263 | fc.skip_probs = skip_probs; |
| 330 | std::memcpy(fc.comp_inter_prob.data(), comp_inter_prob.data(), fc.comp_inter_prob.size()); | 264 | fc.joints = joints; |
| 331 | std::memcpy(fc.skip_probs.data(), skip_probs.data(), fc.skip_probs.size()); | 265 | fc.sign = sign; |
| 332 | 266 | fc.class_0 = class_0; | |
| 333 | std::memcpy(fc.joints.data(), joints.data(), fc.joints.size()); | 267 | fc.fr = fr; |
| 334 | 268 | fc.class_0_hp = class_0_hp; | |
| 335 | std::memcpy(fc.sign.data(), sign.data(), fc.sign.size()); | 269 | fc.high_precision = high_precision; |
| 336 | std::memcpy(fc.class_0.data(), class_0.data(), fc.class_0.size()); | 270 | fc.classes = classes; |
| 337 | std::memcpy(fc.fr.data(), fr.data(), fc.fr.size()); | 271 | fc.class_0_fr = class_0_fr; |
| 338 | std::memcpy(fc.class_0_hp.data(), class_0_hp.data(), fc.class_0_hp.size()); | 272 | fc.prob_bits = pred_bits; |
| 339 | std::memcpy(fc.high_precision.data(), high_precision.data(), fc.high_precision.size()); | 273 | fc.single_ref_prob = single_ref_prob; |
| 340 | std::memcpy(fc.classes.data(), classes.data(), fc.classes.size()); | 274 | fc.comp_ref_prob = comp_ref_prob; |
| 341 | std::memcpy(fc.class_0_fr.data(), class_0_fr.data(), fc.class_0_fr.size()); | 275 | |
| 342 | std::memcpy(fc.prob_bits.data(), pred_bits.data(), fc.prob_bits.size()); | 276 | // Skip the 4th element as it goes unused |
| 343 | std::memcpy(fc.single_ref_prob.data(), single_ref_prob.data(), fc.single_ref_prob.size()); | 277 | for (std::size_t i = 0; i < coef_probs.size(); i += 4) { |
| 344 | std::memcpy(fc.comp_ref_prob.data(), comp_ref_prob.data(), fc.comp_ref_prob.size()); | 278 | const std::size_t j = i - i / 4; |
| 345 | 279 | fc.coef_probs[j] = coef_probs[i]; | |
| 346 | std::memcpy(fc.coef_probs.data(), coef_probs.data(), fc.coef_probs.size()); | 280 | fc.coef_probs[j + 1] = coef_probs[i + 1]; |
| 281 | fc.coef_probs[j + 2] = coef_probs[i + 2]; | ||
| 282 | } | ||
| 347 | } | 283 | } |
| 348 | }; | 284 | }; |
| 349 | static_assert(sizeof(EntropyProbs) == 0xEA0, "EntropyProbs is an invalid size"); | 285 | static_assert(sizeof(EntropyProbs) == 0xEA0, "EntropyProbs is an invalid size"); |
diff --git a/src/video_core/command_classes/nvdec.cpp b/src/video_core/command_classes/nvdec.cpp index 8ca7a7b06..79e1f4e13 100644 --- a/src/video_core/command_classes/nvdec.cpp +++ b/src/video_core/command_classes/nvdec.cpp | |||
| @@ -29,11 +29,7 @@ void Nvdec::ProcessMethod(Method method, const std::vector<u32>& arguments) { | |||
| 29 | } | 29 | } |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | AVFrame* Nvdec::GetFrame() { | 32 | AVFramePtr Nvdec::GetFrame() { |
| 33 | return codec->GetCurrentFrame(); | ||
| 34 | } | ||
| 35 | |||
| 36 | const AVFrame* Nvdec::GetFrame() const { | ||
| 37 | return codec->GetCurrentFrame(); | 33 | return codec->GetCurrentFrame(); |
| 38 | } | 34 | } |
| 39 | 35 | ||
diff --git a/src/video_core/command_classes/nvdec.h b/src/video_core/command_classes/nvdec.h index eec4443f9..e4877c533 100644 --- a/src/video_core/command_classes/nvdec.h +++ b/src/video_core/command_classes/nvdec.h | |||
| @@ -26,8 +26,7 @@ public: | |||
| 26 | void ProcessMethod(Method method, const std::vector<u32>& arguments); | 26 | void ProcessMethod(Method method, const std::vector<u32>& arguments); |
| 27 | 27 | ||
| 28 | /// Return most recently decoded frame | 28 | /// Return most recently decoded frame |
| 29 | [[nodiscard]] AVFrame* GetFrame(); | 29 | [[nodiscard]] AVFramePtr GetFrame(); |
| 30 | [[nodiscard]] const AVFrame* GetFrame() const; | ||
| 31 | 30 | ||
| 32 | private: | 31 | private: |
| 33 | /// Invoke codec to decode a frame | 32 | /// Invoke codec to decode a frame |
diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp index 5b52da277..248443027 100644 --- a/src/video_core/command_classes/vic.cpp +++ b/src/video_core/command_classes/vic.cpp | |||
| @@ -58,17 +58,18 @@ void Vic::Execute() { | |||
| 58 | return; | 58 | return; |
| 59 | } | 59 | } |
| 60 | const VicConfig config{gpu.MemoryManager().Read<u64>(config_struct_address + 0x20)}; | 60 | const VicConfig config{gpu.MemoryManager().Read<u64>(config_struct_address + 0x20)}; |
| 61 | const AVFramePtr frame_ptr = std::move(nvdec_processor->GetFrame()); | ||
| 62 | const auto* frame = frame_ptr.get(); | ||
| 63 | if (!frame || frame->width == 0 || frame->height == 0) { | ||
| 64 | return; | ||
| 65 | } | ||
| 61 | const VideoPixelFormat pixel_format = | 66 | const VideoPixelFormat pixel_format = |
| 62 | static_cast<VideoPixelFormat>(config.pixel_format.Value()); | 67 | static_cast<VideoPixelFormat>(config.pixel_format.Value()); |
| 63 | switch (pixel_format) { | 68 | switch (pixel_format) { |
| 64 | case VideoPixelFormat::BGRA8: | 69 | case VideoPixelFormat::BGRA8: |
| 65 | case VideoPixelFormat::RGBA8: { | 70 | case VideoPixelFormat::RGBA8: { |
| 66 | LOG_TRACE(Service_NVDRV, "Writing RGB Frame"); | 71 | LOG_TRACE(Service_NVDRV, "Writing RGB Frame"); |
| 67 | const auto* frame = nvdec_processor->GetFrame(); | ||
| 68 | 72 | ||
| 69 | if (!frame || frame->width == 0 || frame->height == 0) { | ||
| 70 | return; | ||
| 71 | } | ||
| 72 | if (scaler_ctx == nullptr || frame->width != scaler_width || | 73 | if (scaler_ctx == nullptr || frame->width != scaler_width || |
| 73 | frame->height != scaler_height) { | 74 | frame->height != scaler_height) { |
| 74 | const AVPixelFormat target_format = | 75 | const AVPixelFormat target_format = |
| @@ -121,12 +122,6 @@ void Vic::Execute() { | |||
| 121 | case VideoPixelFormat::Yuv420: { | 122 | case VideoPixelFormat::Yuv420: { |
| 122 | LOG_TRACE(Service_NVDRV, "Writing YUV420 Frame"); | 123 | LOG_TRACE(Service_NVDRV, "Writing YUV420 Frame"); |
| 123 | 124 | ||
| 124 | const auto* frame = nvdec_processor->GetFrame(); | ||
| 125 | |||
| 126 | if (!frame || frame->width == 0 || frame->height == 0) { | ||
| 127 | return; | ||
| 128 | } | ||
| 129 | |||
| 130 | const std::size_t surface_width = config.surface_width_minus1 + 1; | 125 | const std::size_t surface_width = config.surface_width_minus1 + 1; |
| 131 | const std::size_t surface_height = config.surface_height_minus1 + 1; | 126 | const std::size_t surface_height = config.surface_height_minus1 + 1; |
| 132 | const std::size_t half_width = surface_width / 2; | 127 | const std::size_t half_width = surface_width / 2; |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 1cbe8fe67..b0d9559d0 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -755,7 +755,11 @@ public: | |||
| 755 | 755 | ||
| 756 | u32 data_upload; | 756 | u32 data_upload; |
| 757 | 757 | ||
| 758 | INSERT_UNION_PADDING_WORDS(0x44); | 758 | INSERT_UNION_PADDING_WORDS(0x16); |
| 759 | |||
| 760 | u32 force_early_fragment_tests; | ||
| 761 | |||
| 762 | INSERT_UNION_PADDING_WORDS(0x2D); | ||
| 759 | 763 | ||
| 760 | struct { | 764 | struct { |
| 761 | union { | 765 | union { |
| @@ -1572,6 +1576,7 @@ ASSERT_REG_POSITION(shadow_ram_control, 0x49); | |||
| 1572 | ASSERT_REG_POSITION(upload, 0x60); | 1576 | ASSERT_REG_POSITION(upload, 0x60); |
| 1573 | ASSERT_REG_POSITION(exec_upload, 0x6C); | 1577 | ASSERT_REG_POSITION(exec_upload, 0x6C); |
| 1574 | ASSERT_REG_POSITION(data_upload, 0x6D); | 1578 | ASSERT_REG_POSITION(data_upload, 0x6D); |
| 1579 | ASSERT_REG_POSITION(force_early_fragment_tests, 0x84); | ||
| 1575 | ASSERT_REG_POSITION(sync_info, 0xB2); | 1580 | ASSERT_REG_POSITION(sync_info, 0xB2); |
| 1576 | ASSERT_REG_POSITION(tess_mode, 0xC8); | 1581 | ASSERT_REG_POSITION(tess_mode, 0xC8); |
| 1577 | ASSERT_REG_POSITION(tess_level_outer, 0xC9); | 1582 | ASSERT_REG_POSITION(tess_level_outer, 0xC9); |
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index fffae528e..5ec43db11 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | |||
| @@ -46,7 +46,7 @@ void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_sta | |||
| 46 | regs.polygon_offset_fill_enable}; | 46 | regs.polygon_offset_fill_enable}; |
| 47 | const u32 topology_index = static_cast<u32>(regs.draw.topology.Value()); | 47 | const u32 topology_index = static_cast<u32>(regs.draw.topology.Value()); |
| 48 | 48 | ||
| 49 | raw = 0; | 49 | raw1 = 0; |
| 50 | primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0); | 50 | primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0); |
| 51 | depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0); | 51 | depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0); |
| 52 | depth_clamp_disabled.Assign(regs.view_volume_clip_control.depth_clamp_disabled.Value()); | 52 | depth_clamp_disabled.Assign(regs.view_volume_clip_control.depth_clamp_disabled.Value()); |
| @@ -61,12 +61,13 @@ void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_sta | |||
| 61 | rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); | 61 | rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); |
| 62 | topology.Assign(regs.draw.topology); | 62 | topology.Assign(regs.draw.topology); |
| 63 | 63 | ||
| 64 | alpha_raw = 0; | 64 | raw2 = 0; |
| 65 | const auto test_func = | 65 | const auto test_func = |
| 66 | regs.alpha_test_enabled == 1 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always; | 66 | regs.alpha_test_enabled == 1 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always; |
| 67 | alpha_test_func.Assign(PackComparisonOp(test_func)); | 67 | alpha_test_func.Assign(PackComparisonOp(test_func)); |
| 68 | alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref); | 68 | early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0); |
| 69 | 69 | ||
| 70 | alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref); | ||
| 70 | point_size = Common::BitCast<u32>(regs.point_size); | 71 | point_size = Common::BitCast<u32>(regs.point_size); |
| 71 | 72 | ||
| 72 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { | 73 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { |
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index 42480e8d0..c26b77790 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h | |||
| @@ -171,7 +171,7 @@ struct FixedPipelineState { | |||
| 171 | }; | 171 | }; |
| 172 | 172 | ||
| 173 | union { | 173 | union { |
| 174 | u32 raw; | 174 | u32 raw1; |
| 175 | BitField<0, 1, u32> no_extended_dynamic_state; | 175 | BitField<0, 1, u32> no_extended_dynamic_state; |
| 176 | BitField<2, 1, u32> primitive_restart_enable; | 176 | BitField<2, 1, u32> primitive_restart_enable; |
| 177 | BitField<3, 1, u32> depth_bias_enable; | 177 | BitField<3, 1, u32> depth_bias_enable; |
| @@ -187,13 +187,13 @@ struct FixedPipelineState { | |||
| 187 | BitField<23, 1, u32> rasterize_enable; | 187 | BitField<23, 1, u32> rasterize_enable; |
| 188 | BitField<24, 4, Maxwell::PrimitiveTopology> topology; | 188 | BitField<24, 4, Maxwell::PrimitiveTopology> topology; |
| 189 | }; | 189 | }; |
| 190 | |||
| 191 | u32 alpha_test_ref; ///< Alpha test reference value | ||
| 192 | union { | 190 | union { |
| 193 | u32 alpha_raw; | 191 | u32 raw2; |
| 194 | BitField<0, 3, u32> alpha_test_func; | 192 | BitField<0, 3, u32> alpha_test_func; |
| 193 | BitField<3, 1, u32> early_z; | ||
| 195 | }; | 194 | }; |
| 196 | 195 | ||
| 196 | u32 alpha_test_ref; | ||
| 197 | u32 point_size; | 197 | u32 point_size; |
| 198 | std::array<u32, Maxwell::NumVertexArrays> binding_divisors; | 198 | std::array<u32, Maxwell::NumVertexArrays> binding_divisors; |
| 199 | std::array<VertexAttribute, Maxwell::NumVertexAttributes> attributes; | 199 | std::array<VertexAttribute, Maxwell::NumVertexAttributes> attributes; |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index f9efe526d..df7e8c864 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -344,6 +344,7 @@ VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) { | |||
| 344 | specialization.attribute_types[i] = attribute.Type(); | 344 | specialization.attribute_types[i] = attribute.Type(); |
| 345 | } | 345 | } |
| 346 | specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one; | 346 | specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one; |
| 347 | specialization.early_fragment_tests = fixed_state.early_z; | ||
| 347 | 348 | ||
| 348 | // Alpha test | 349 | // Alpha test |
| 349 | specialization.alpha_test_func = | 350 | specialization.alpha_test_func = |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 1c52f40bb..fed9ebecd 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -315,7 +315,6 @@ public: | |||
| 315 | "supported on this device"); | 315 | "supported on this device"); |
| 316 | } | 316 | } |
| 317 | } | 317 | } |
| 318 | |||
| 319 | if (ir.UsesLayer() || ir.UsesViewportIndex()) { | 318 | if (ir.UsesLayer() || ir.UsesViewportIndex()) { |
| 320 | if (ir.UsesViewportIndex()) { | 319 | if (ir.UsesViewportIndex()) { |
| 321 | AddCapability(spv::Capability::MultiViewport); | 320 | AddCapability(spv::Capability::MultiViewport); |
| @@ -325,11 +324,9 @@ public: | |||
| 325 | AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); | 324 | AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); |
| 326 | } | 325 | } |
| 327 | } | 326 | } |
| 328 | |||
| 329 | if (device.IsFormatlessImageLoadSupported()) { | 327 | if (device.IsFormatlessImageLoadSupported()) { |
| 330 | AddCapability(spv::Capability::StorageImageReadWithoutFormat); | 328 | AddCapability(spv::Capability::StorageImageReadWithoutFormat); |
| 331 | } | 329 | } |
| 332 | |||
| 333 | if (device.IsFloat16Supported()) { | 330 | if (device.IsFloat16Supported()) { |
| 334 | AddCapability(spv::Capability::Float16); | 331 | AddCapability(spv::Capability::Float16); |
| 335 | } | 332 | } |
| @@ -377,6 +374,9 @@ public: | |||
| 377 | if (header.ps.omap.depth) { | 374 | if (header.ps.omap.depth) { |
| 378 | AddExecutionMode(main, spv::ExecutionMode::DepthReplacing); | 375 | AddExecutionMode(main, spv::ExecutionMode::DepthReplacing); |
| 379 | } | 376 | } |
| 377 | if (specialization.early_fragment_tests) { | ||
| 378 | AddExecutionMode(main, spv::ExecutionMode::EarlyFragmentTests); | ||
| 379 | } | ||
| 380 | break; | 380 | break; |
| 381 | case ShaderType::Compute: | 381 | case ShaderType::Compute: |
| 382 | const auto workgroup_size = specialization.workgroup_size; | 382 | const auto workgroup_size = specialization.workgroup_size; |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.h b/src/video_core/renderer_vulkan/vk_shader_decompiler.h index cd3d0a415..110848922 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.h +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.h | |||
| @@ -95,6 +95,7 @@ struct Specialization final { | |||
| 95 | std::bitset<Maxwell::NumVertexAttributes> enabled_attributes; | 95 | std::bitset<Maxwell::NumVertexAttributes> enabled_attributes; |
| 96 | std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{}; | 96 | std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{}; |
| 97 | bool ndc_minus_one_to_one{}; | 97 | bool ndc_minus_one_to_one{}; |
| 98 | bool early_fragment_tests{}; | ||
| 98 | float alpha_test_ref{}; | 99 | float alpha_test_ref{}; |
| 99 | Maxwell::ComparisonOp alpha_test_func{}; | 100 | Maxwell::ComparisonOp alpha_test_func{}; |
| 100 | }; | 101 | }; |
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index ea8f0d7b1..489104d5f 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp | |||
| @@ -35,7 +35,7 @@ | |||
| 35 | #include "core/settings.h" | 35 | #include "core/settings.h" |
| 36 | #include "input_common/keyboard.h" | 36 | #include "input_common/keyboard.h" |
| 37 | #include "input_common/main.h" | 37 | #include "input_common/main.h" |
| 38 | #include "input_common/motion_emu.h" | 38 | #include "input_common/mouse/mouse_input.h" |
| 39 | #include "video_core/renderer_base.h" | 39 | #include "video_core/renderer_base.h" |
| 40 | #include "video_core/video_core.h" | 40 | #include "video_core/video_core.h" |
| 41 | #include "yuzu/bootmanager.h" | 41 | #include "yuzu/bootmanager.h" |
| @@ -388,23 +388,19 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) { | |||
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | void GRenderWindow::mousePressEvent(QMouseEvent* event) { | 390 | void GRenderWindow::mousePressEvent(QMouseEvent* event) { |
| 391 | if (!Settings::values.touchscreen.enabled) { | ||
| 392 | input_subsystem->GetKeyboard()->PressKey(event->button()); | ||
| 393 | return; | ||
| 394 | } | ||
| 395 | |||
| 396 | // Touch input is handled in TouchBeginEvent | 391 | // Touch input is handled in TouchBeginEvent |
| 397 | if (event->source() == Qt::MouseEventSynthesizedBySystem) { | 392 | if (event->source() == Qt::MouseEventSynthesizedBySystem) { |
| 398 | return; | 393 | return; |
| 399 | } | 394 | } |
| 400 | 395 | ||
| 401 | auto pos = event->pos(); | 396 | auto pos = event->pos(); |
| 397 | const auto [x, y] = ScaleTouch(pos); | ||
| 398 | input_subsystem->GetMouse()->PressButton(x, y, event->button()); | ||
| 399 | |||
| 402 | if (event->button() == Qt::LeftButton) { | 400 | if (event->button() == Qt::LeftButton) { |
| 403 | const auto [x, y] = ScaleTouch(pos); | ||
| 404 | this->TouchPressed(x, y); | 401 | this->TouchPressed(x, y); |
| 405 | } else if (event->button() == Qt::RightButton) { | ||
| 406 | input_subsystem->GetMotionEmu()->BeginTilt(pos.x(), pos.y()); | ||
| 407 | } | 402 | } |
| 403 | |||
| 408 | QWidget::mousePressEvent(event); | 404 | QWidget::mousePressEvent(event); |
| 409 | } | 405 | } |
| 410 | 406 | ||
| @@ -416,26 +412,22 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) { | |||
| 416 | 412 | ||
| 417 | auto pos = event->pos(); | 413 | auto pos = event->pos(); |
| 418 | const auto [x, y] = ScaleTouch(pos); | 414 | const auto [x, y] = ScaleTouch(pos); |
| 415 | input_subsystem->GetMouse()->MouseMove(x, y); | ||
| 419 | this->TouchMoved(x, y); | 416 | this->TouchMoved(x, y); |
| 420 | input_subsystem->GetMotionEmu()->Tilt(pos.x(), pos.y()); | 417 | |
| 421 | QWidget::mouseMoveEvent(event); | 418 | QWidget::mouseMoveEvent(event); |
| 422 | } | 419 | } |
| 423 | 420 | ||
| 424 | void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { | 421 | void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { |
| 425 | if (!Settings::values.touchscreen.enabled) { | ||
| 426 | input_subsystem->GetKeyboard()->ReleaseKey(event->button()); | ||
| 427 | return; | ||
| 428 | } | ||
| 429 | |||
| 430 | // Touch input is handled in TouchEndEvent | 422 | // Touch input is handled in TouchEndEvent |
| 431 | if (event->source() == Qt::MouseEventSynthesizedBySystem) { | 423 | if (event->source() == Qt::MouseEventSynthesizedBySystem) { |
| 432 | return; | 424 | return; |
| 433 | } | 425 | } |
| 434 | 426 | ||
| 427 | input_subsystem->GetMouse()->ReleaseButton(event->button()); | ||
| 428 | |||
| 435 | if (event->button() == Qt::LeftButton) { | 429 | if (event->button() == Qt::LeftButton) { |
| 436 | this->TouchReleased(); | 430 | this->TouchReleased(); |
| 437 | } else if (event->button() == Qt::RightButton) { | ||
| 438 | input_subsystem->GetMotionEmu()->EndTilt(); | ||
| 439 | } | 431 | } |
| 440 | } | 432 | } |
| 441 | 433 | ||
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 8be9e93c3..fcc38b3af 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -569,16 +569,11 @@ void Config::ReadMotionTouchValues() { | |||
| 569 | ReadSetting(QStringLiteral("touch_from_button_map"), 0).toInt(); | 569 | ReadSetting(QStringLiteral("touch_from_button_map"), 0).toInt(); |
| 570 | Settings::values.touch_from_button_map_index = | 570 | Settings::values.touch_from_button_map_index = |
| 571 | std::clamp(Settings::values.touch_from_button_map_index, 0, num_touch_from_button_maps - 1); | 571 | std::clamp(Settings::values.touch_from_button_map_index, 0, num_touch_from_button_maps - 1); |
| 572 | Settings::values.udp_input_address = | 572 | Settings::values.udp_input_servers = |
| 573 | ReadSetting(QStringLiteral("udp_input_address"), | 573 | ReadSetting(QStringLiteral("udp_input_servers"), |
| 574 | QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_ADDR)) | 574 | QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV)) |
| 575 | .toString() | 575 | .toString() |
| 576 | .toStdString(); | 576 | .toStdString(); |
| 577 | Settings::values.udp_input_port = static_cast<u16>( | ||
| 578 | ReadSetting(QStringLiteral("udp_input_port"), InputCommon::CemuhookUDP::DEFAULT_PORT) | ||
| 579 | .toInt()); | ||
| 580 | Settings::values.udp_pad_index = | ||
| 581 | static_cast<u8>(ReadSetting(QStringLiteral("udp_pad_index"), 0).toUInt()); | ||
| 582 | } | 577 | } |
| 583 | 578 | ||
| 584 | void Config::ReadCoreValues() { | 579 | void Config::ReadCoreValues() { |
| @@ -1109,12 +1104,9 @@ void Config::SaveMotionTouchValues() { | |||
| 1109 | false); | 1104 | false); |
| 1110 | WriteSetting(QStringLiteral("touch_from_button_map"), | 1105 | WriteSetting(QStringLiteral("touch_from_button_map"), |
| 1111 | Settings::values.touch_from_button_map_index, 0); | 1106 | Settings::values.touch_from_button_map_index, 0); |
| 1112 | WriteSetting(QStringLiteral("udp_input_address"), | 1107 | WriteSetting(QStringLiteral("udp_input_servers"), |
| 1113 | QString::fromStdString(Settings::values.udp_input_address), | 1108 | QString::fromStdString(Settings::values.udp_input_servers), |
| 1114 | QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_ADDR)); | 1109 | QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV)); |
| 1115 | WriteSetting(QStringLiteral("udp_input_port"), Settings::values.udp_input_port, | ||
| 1116 | InputCommon::CemuhookUDP::DEFAULT_PORT); | ||
| 1117 | WriteSetting(QStringLiteral("udp_pad_index"), Settings::values.udp_pad_index, 0); | ||
| 1118 | 1110 | ||
| 1119 | qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps")); | 1111 | qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps")); |
| 1120 | for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) { | 1112 | for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) { |
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 918bfb56b..f9915fb7a 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include "core/hle/service/sm/sm.h" | 19 | #include "core/hle/service/sm/sm.h" |
| 20 | #include "input_common/gcadapter/gc_poller.h" | 20 | #include "input_common/gcadapter/gc_poller.h" |
| 21 | #include "input_common/main.h" | 21 | #include "input_common/main.h" |
| 22 | #include "input_common/mouse/mouse_poller.h" | ||
| 22 | #include "input_common/udp/udp.h" | 23 | #include "input_common/udp/udp.h" |
| 23 | #include "ui_configure_input_player.h" | 24 | #include "ui_configure_input_player.h" |
| 24 | #include "yuzu/configuration/config.h" | 25 | #include "yuzu/configuration/config.h" |
| @@ -152,6 +153,14 @@ QString ButtonToText(const Common::ParamPackage& param) { | |||
| 152 | return {}; | 153 | return {}; |
| 153 | } | 154 | } |
| 154 | 155 | ||
| 156 | if (param.Get("engine", "") == "mouse") { | ||
| 157 | if (param.Has("button")) { | ||
| 158 | const QString button_str = QString::number(int(param.Get("button", 0))); | ||
| 159 | return QObject::tr("Click %1").arg(button_str); | ||
| 160 | } | ||
| 161 | return GetKeyName(param.Get("code", 0)); | ||
| 162 | } | ||
| 163 | |||
| 155 | return QObject::tr("[unknown]"); | 164 | return QObject::tr("[unknown]"); |
| 156 | } | 165 | } |
| 157 | 166 | ||
| @@ -203,6 +212,26 @@ QString AnalogToText(const Common::ParamPackage& param, const std::string& dir) | |||
| 203 | 212 | ||
| 204 | return {}; | 213 | return {}; |
| 205 | } | 214 | } |
| 215 | |||
| 216 | if (param.Get("engine", "") == "mouse") { | ||
| 217 | if (dir == "modifier") { | ||
| 218 | return QObject::tr("[unused]"); | ||
| 219 | } | ||
| 220 | |||
| 221 | if (dir == "left" || dir == "right") { | ||
| 222 | const QString axis_x_str = QString::fromStdString(param.Get("axis_x", "")); | ||
| 223 | |||
| 224 | return QObject::tr("Mouse %1").arg(axis_x_str); | ||
| 225 | } | ||
| 226 | |||
| 227 | if (dir == "up" || dir == "down") { | ||
| 228 | const QString axis_y_str = QString::fromStdString(param.Get("axis_y", "")); | ||
| 229 | |||
| 230 | return QObject::tr("Mouse %1").arg(axis_y_str); | ||
| 231 | } | ||
| 232 | |||
| 233 | return {}; | ||
| 234 | } | ||
| 206 | return QObject::tr("[unknown]"); | 235 | return QObject::tr("[unknown]"); |
| 207 | } | 236 | } |
| 208 | } // namespace | 237 | } // namespace |
| @@ -484,6 +513,34 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 484 | return; | 513 | return; |
| 485 | } | 514 | } |
| 486 | } | 515 | } |
| 516 | if (input_subsystem->GetMouseButtons()->IsPolling()) { | ||
| 517 | params = input_subsystem->GetMouseButtons()->GetNextInput(); | ||
| 518 | if (params.Has("engine") && IsInputAcceptable(params)) { | ||
| 519 | SetPollingResult(params, false); | ||
| 520 | return; | ||
| 521 | } | ||
| 522 | } | ||
| 523 | if (input_subsystem->GetMouseAnalogs()->IsPolling()) { | ||
| 524 | params = input_subsystem->GetMouseAnalogs()->GetNextInput(); | ||
| 525 | if (params.Has("engine") && IsInputAcceptable(params)) { | ||
| 526 | SetPollingResult(params, false); | ||
| 527 | return; | ||
| 528 | } | ||
| 529 | } | ||
| 530 | if (input_subsystem->GetMouseMotions()->IsPolling()) { | ||
| 531 | params = input_subsystem->GetMouseMotions()->GetNextInput(); | ||
| 532 | if (params.Has("engine") && IsInputAcceptable(params)) { | ||
| 533 | SetPollingResult(params, false); | ||
| 534 | return; | ||
| 535 | } | ||
| 536 | } | ||
| 537 | if (input_subsystem->GetMouseTouch()->IsPolling()) { | ||
| 538 | params = input_subsystem->GetMouseTouch()->GetNextInput(); | ||
| 539 | if (params.Has("engine") && IsInputAcceptable(params)) { | ||
| 540 | SetPollingResult(params, false); | ||
| 541 | return; | ||
| 542 | } | ||
| 543 | } | ||
| 487 | for (auto& poller : device_pollers) { | 544 | for (auto& poller : device_pollers) { |
| 488 | params = poller->GetNextInput(); | 545 | params = poller->GetNextInput(); |
| 489 | if (params.Has("engine") && IsInputAcceptable(params)) { | 546 | if (params.Has("engine") && IsInputAcceptable(params)) { |
| @@ -761,8 +818,9 @@ void ConfigureInputPlayer::UpdateUI() { | |||
| 761 | 818 | ||
| 762 | int slider_value; | 819 | int slider_value; |
| 763 | auto& param = analogs_param[analog_id]; | 820 | auto& param = analogs_param[analog_id]; |
| 764 | const bool is_controller = | 821 | const bool is_controller = param.Get("engine", "") == "sdl" || |
| 765 | param.Get("engine", "") == "sdl" || param.Get("engine", "") == "gcpad"; | 822 | param.Get("engine", "") == "gcpad" || |
| 823 | param.Get("engine", "") == "mouse"; | ||
| 766 | 824 | ||
| 767 | if (is_controller) { | 825 | if (is_controller) { |
| 768 | if (!param.Has("deadzone")) { | 826 | if (!param.Has("deadzone")) { |
| @@ -1078,6 +1136,16 @@ void ConfigureInputPlayer::HandleClick( | |||
| 1078 | input_subsystem->GetUDPMotions()->BeginConfiguration(); | 1136 | input_subsystem->GetUDPMotions()->BeginConfiguration(); |
| 1079 | } | 1137 | } |
| 1080 | 1138 | ||
| 1139 | if (type == InputCommon::Polling::DeviceType::Button) { | ||
| 1140 | input_subsystem->GetMouseButtons()->BeginConfiguration(); | ||
| 1141 | } else if (type == InputCommon::Polling::DeviceType::AnalogPreferred) { | ||
| 1142 | input_subsystem->GetMouseAnalogs()->BeginConfiguration(); | ||
| 1143 | } else if (type == InputCommon::Polling::DeviceType::Motion) { | ||
| 1144 | input_subsystem->GetMouseMotions()->BeginConfiguration(); | ||
| 1145 | } else { | ||
| 1146 | input_subsystem->GetMouseTouch()->BeginConfiguration(); | ||
| 1147 | } | ||
| 1148 | |||
| 1081 | timeout_timer->start(2500); // Cancel after 2.5 seconds | 1149 | timeout_timer->start(2500); // Cancel after 2.5 seconds |
| 1082 | poll_timer->start(50); // Check for new inputs every 50ms | 1150 | poll_timer->start(50); // Check for new inputs every 50ms |
| 1083 | } | 1151 | } |
| @@ -1097,6 +1165,11 @@ void ConfigureInputPlayer::SetPollingResult(const Common::ParamPackage& params, | |||
| 1097 | 1165 | ||
| 1098 | input_subsystem->GetUDPMotions()->EndConfiguration(); | 1166 | input_subsystem->GetUDPMotions()->EndConfiguration(); |
| 1099 | 1167 | ||
| 1168 | input_subsystem->GetMouseButtons()->EndConfiguration(); | ||
| 1169 | input_subsystem->GetMouseAnalogs()->EndConfiguration(); | ||
| 1170 | input_subsystem->GetMouseMotions()->EndConfiguration(); | ||
| 1171 | input_subsystem->GetMouseTouch()->EndConfiguration(); | ||
| 1172 | |||
| 1100 | if (!abort) { | 1173 | if (!abort) { |
| 1101 | (*input_setter)(params); | 1174 | (*input_setter)(params); |
| 1102 | } | 1175 | } |
| @@ -1128,15 +1201,7 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) { | |||
| 1128 | return; | 1201 | return; |
| 1129 | } | 1202 | } |
| 1130 | 1203 | ||
| 1131 | if (want_keyboard_mouse) { | 1204 | input_subsystem->GetMouse()->PressButton(0, 0, event->button()); |
| 1132 | SetPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->button())}, | ||
| 1133 | false); | ||
| 1134 | } else { | ||
| 1135 | // We don't want any mouse buttons, so don't stop polling | ||
| 1136 | return; | ||
| 1137 | } | ||
| 1138 | |||
| 1139 | SetPollingResult({}, true); | ||
| 1140 | } | 1205 | } |
| 1141 | 1206 | ||
| 1142 | void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) { | 1207 | void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) { |
diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp index 170574d9b..2afac591a 100644 --- a/src/yuzu/configuration/configure_motion_touch.cpp +++ b/src/yuzu/configuration/configure_motion_touch.cpp | |||
| @@ -3,10 +3,12 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <array> | 5 | #include <array> |
| 6 | #include <sstream> | ||
| 6 | #include <QCloseEvent> | 7 | #include <QCloseEvent> |
| 7 | #include <QLabel> | 8 | #include <QLabel> |
| 8 | #include <QMessageBox> | 9 | #include <QMessageBox> |
| 9 | #include <QPushButton> | 10 | #include <QPushButton> |
| 11 | #include <QStringListModel> | ||
| 10 | #include <QVBoxLayout> | 12 | #include <QVBoxLayout> |
| 11 | #include "common/logging/log.h" | 13 | #include "common/logging/log.h" |
| 12 | #include "core/settings.h" | 14 | #include "core/settings.h" |
| @@ -74,11 +76,6 @@ void CalibrationConfigurationDialog::UpdateButtonText(const QString& text) { | |||
| 74 | cancel_button->setText(text); | 76 | cancel_button->setText(text); |
| 75 | } | 77 | } |
| 76 | 78 | ||
| 77 | constexpr std::array<std::pair<const char*, const char*>, 2> MotionProviders = {{ | ||
| 78 | {"motion_emu", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Mouse (Right Click)")}, | ||
| 79 | {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")}, | ||
| 80 | }}; | ||
| 81 | |||
| 82 | constexpr std::array<std::pair<const char*, const char*>, 2> TouchProviders = {{ | 79 | constexpr std::array<std::pair<const char*, const char*>, 2> TouchProviders = {{ |
| 83 | {"emu_window", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Emulator Window")}, | 80 | {"emu_window", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Emulator Window")}, |
| 84 | {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")}, | 81 | {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")}, |
| @@ -89,9 +86,6 @@ ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent, | |||
| 89 | : QDialog(parent), input_subsystem{input_subsystem_}, | 86 | : QDialog(parent), input_subsystem{input_subsystem_}, |
| 90 | ui(std::make_unique<Ui::ConfigureMotionTouch>()) { | 87 | ui(std::make_unique<Ui::ConfigureMotionTouch>()) { |
| 91 | ui->setupUi(this); | 88 | ui->setupUi(this); |
| 92 | for (const auto& [provider, name] : MotionProviders) { | ||
| 93 | ui->motion_provider->addItem(tr(name), QString::fromUtf8(provider)); | ||
| 94 | } | ||
| 95 | for (const auto& [provider, name] : TouchProviders) { | 89 | for (const auto& [provider, name] : TouchProviders) { |
| 96 | ui->touch_provider->addItem(tr(name), QString::fromUtf8(provider)); | 90 | ui->touch_provider->addItem(tr(name), QString::fromUtf8(provider)); |
| 97 | } | 91 | } |
| @@ -116,8 +110,6 @@ void ConfigureMotionTouch::SetConfiguration() { | |||
| 116 | const std::string motion_engine = motion_param.Get("engine", "motion_emu"); | 110 | const std::string motion_engine = motion_param.Get("engine", "motion_emu"); |
| 117 | const std::string touch_engine = touch_param.Get("engine", "emu_window"); | 111 | const std::string touch_engine = touch_param.Get("engine", "emu_window"); |
| 118 | 112 | ||
| 119 | ui->motion_provider->setCurrentIndex( | ||
| 120 | ui->motion_provider->findData(QString::fromStdString(motion_engine))); | ||
| 121 | ui->touch_provider->setCurrentIndex( | 113 | ui->touch_provider->setCurrentIndex( |
| 122 | ui->touch_provider->findData(QString::fromStdString(touch_engine))); | 114 | ui->touch_provider->findData(QString::fromStdString(touch_engine))); |
| 123 | ui->touch_from_button_checkbox->setChecked(Settings::values.use_touch_from_button); | 115 | ui->touch_from_button_checkbox->setChecked(Settings::values.use_touch_from_button); |
| @@ -133,23 +125,30 @@ void ConfigureMotionTouch::SetConfiguration() { | |||
| 133 | max_x = touch_param.Get("max_x", 1800); | 125 | max_x = touch_param.Get("max_x", 1800); |
| 134 | max_y = touch_param.Get("max_y", 850); | 126 | max_y = touch_param.Get("max_y", 850); |
| 135 | 127 | ||
| 136 | ui->udp_server->setText(QString::fromStdString(Settings::values.udp_input_address)); | 128 | ui->udp_server->setText(QString::fromStdString("127.0.0.1")); |
| 137 | ui->udp_port->setText(QString::number(Settings::values.udp_input_port)); | 129 | ui->udp_port->setText(QString::number(26760)); |
| 138 | ui->udp_pad_index->setCurrentIndex(Settings::values.udp_pad_index); | 130 | |
| 131 | udp_server_list_model = new QStringListModel(this); | ||
| 132 | udp_server_list_model->setStringList({}); | ||
| 133 | ui->udp_server_list->setModel(udp_server_list_model); | ||
| 134 | |||
| 135 | std::stringstream ss(Settings::values.udp_input_servers); | ||
| 136 | std::string token; | ||
| 137 | |||
| 138 | while (std::getline(ss, token, ',')) { | ||
| 139 | const int row = udp_server_list_model->rowCount(); | ||
| 140 | udp_server_list_model->insertRows(row, 1); | ||
| 141 | const QModelIndex index = udp_server_list_model->index(row); | ||
| 142 | udp_server_list_model->setData(index, QString::fromStdString(token)); | ||
| 143 | } | ||
| 139 | } | 144 | } |
| 140 | 145 | ||
| 141 | void ConfigureMotionTouch::UpdateUiDisplay() { | 146 | void ConfigureMotionTouch::UpdateUiDisplay() { |
| 142 | const QString motion_engine = ui->motion_provider->currentData().toString(); | ||
| 143 | const QString touch_engine = ui->touch_provider->currentData().toString(); | 147 | const QString touch_engine = ui->touch_provider->currentData().toString(); |
| 144 | const QString cemuhook_udp = QStringLiteral("cemuhookudp"); | 148 | const QString cemuhook_udp = QStringLiteral("cemuhookudp"); |
| 145 | 149 | ||
| 146 | if (motion_engine == QStringLiteral("motion_emu")) { | 150 | ui->motion_sensitivity_label->setVisible(true); |
| 147 | ui->motion_sensitivity_label->setVisible(true); | 151 | ui->motion_sensitivity->setVisible(true); |
| 148 | ui->motion_sensitivity->setVisible(true); | ||
| 149 | } else { | ||
| 150 | ui->motion_sensitivity_label->setVisible(false); | ||
| 151 | ui->motion_sensitivity->setVisible(false); | ||
| 152 | } | ||
| 153 | 152 | ||
| 154 | if (touch_engine == cemuhook_udp) { | 153 | if (touch_engine == cemuhook_udp) { |
| 155 | ui->touch_calibration->setVisible(true); | 154 | ui->touch_calibration->setVisible(true); |
| @@ -163,19 +162,15 @@ void ConfigureMotionTouch::UpdateUiDisplay() { | |||
| 163 | ui->touch_calibration_label->setVisible(false); | 162 | ui->touch_calibration_label->setVisible(false); |
| 164 | } | 163 | } |
| 165 | 164 | ||
| 166 | if (motion_engine == cemuhook_udp || touch_engine == cemuhook_udp) { | 165 | ui->udp_config_group_box->setVisible(true); |
| 167 | ui->udp_config_group_box->setVisible(true); | ||
| 168 | } else { | ||
| 169 | ui->udp_config_group_box->setVisible(false); | ||
| 170 | } | ||
| 171 | } | 166 | } |
| 172 | 167 | ||
| 173 | void ConfigureMotionTouch::ConnectEvents() { | 168 | void ConfigureMotionTouch::ConnectEvents() { |
| 174 | connect(ui->motion_provider, qOverload<int>(&QComboBox::currentIndexChanged), this, | ||
| 175 | [this](int index) { UpdateUiDisplay(); }); | ||
| 176 | connect(ui->touch_provider, qOverload<int>(&QComboBox::currentIndexChanged), this, | 169 | connect(ui->touch_provider, qOverload<int>(&QComboBox::currentIndexChanged), this, |
| 177 | [this](int index) { UpdateUiDisplay(); }); | 170 | [this](int index) { UpdateUiDisplay(); }); |
| 178 | connect(ui->udp_test, &QPushButton::clicked, this, &ConfigureMotionTouch::OnCemuhookUDPTest); | 171 | connect(ui->udp_test, &QPushButton::clicked, this, &ConfigureMotionTouch::OnCemuhookUDPTest); |
| 172 | connect(ui->udp_add, &QPushButton::clicked, this, &ConfigureMotionTouch::OnUDPAddServer); | ||
| 173 | connect(ui->udp_remove, &QPushButton::clicked, this, &ConfigureMotionTouch::OnUDPDeleteServer); | ||
| 179 | connect(ui->touch_calibration_config, &QPushButton::clicked, this, | 174 | connect(ui->touch_calibration_config, &QPushButton::clicked, this, |
| 180 | &ConfigureMotionTouch::OnConfigureTouchCalibration); | 175 | &ConfigureMotionTouch::OnConfigureTouchCalibration); |
| 181 | connect(ui->touch_from_button_config_btn, &QPushButton::clicked, this, | 176 | connect(ui->touch_from_button_config_btn, &QPushButton::clicked, this, |
| @@ -187,13 +182,58 @@ void ConfigureMotionTouch::ConnectEvents() { | |||
| 187 | }); | 182 | }); |
| 188 | } | 183 | } |
| 189 | 184 | ||
| 185 | void ConfigureMotionTouch::OnUDPAddServer() { | ||
| 186 | QRegExp re(tr("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[" | ||
| 187 | "0-9][0-9]?)$")); // a valid ip address | ||
| 188 | bool ok; | ||
| 189 | QString port_text = ui->udp_port->text(); | ||
| 190 | QString server_text = ui->udp_server->text(); | ||
| 191 | const QString server_string = tr("%1:%2").arg(server_text, port_text); | ||
| 192 | int port_number = port_text.toInt(&ok, 10); | ||
| 193 | int row = udp_server_list_model->rowCount(); | ||
| 194 | |||
| 195 | if (!ok) { | ||
| 196 | QMessageBox::warning(this, tr("yuzu"), tr("Port number has invalid characters")); | ||
| 197 | return; | ||
| 198 | } | ||
| 199 | if (port_number < 0 || port_number > 65353) { | ||
| 200 | QMessageBox::warning(this, tr("yuzu"), tr("Port has to be in range 0 and 65353")); | ||
| 201 | return; | ||
| 202 | } | ||
| 203 | if (!re.exactMatch(server_text)) { | ||
| 204 | QMessageBox::warning(this, tr("yuzu"), tr("IP address is not valid")); | ||
| 205 | return; | ||
| 206 | } | ||
| 207 | // Search for duplicates | ||
| 208 | for (const auto& item : udp_server_list_model->stringList()) { | ||
| 209 | if (item == server_string) { | ||
| 210 | QMessageBox::warning(this, tr("yuzu"), tr("This UDP server already exists")); | ||
| 211 | return; | ||
| 212 | } | ||
| 213 | } | ||
| 214 | // Limit server count to 8 | ||
| 215 | if (row == 8) { | ||
| 216 | QMessageBox::warning(this, tr("yuzu"), tr("Unable to add more than 8 servers")); | ||
| 217 | return; | ||
| 218 | } | ||
| 219 | |||
| 220 | udp_server_list_model->insertRows(row, 1); | ||
| 221 | QModelIndex index = udp_server_list_model->index(row); | ||
| 222 | udp_server_list_model->setData(index, server_string); | ||
| 223 | ui->udp_server_list->setCurrentIndex(index); | ||
| 224 | } | ||
| 225 | |||
| 226 | void ConfigureMotionTouch::OnUDPDeleteServer() { | ||
| 227 | udp_server_list_model->removeRows(ui->udp_server_list->currentIndex().row(), 1); | ||
| 228 | } | ||
| 229 | |||
| 190 | void ConfigureMotionTouch::OnCemuhookUDPTest() { | 230 | void ConfigureMotionTouch::OnCemuhookUDPTest() { |
| 191 | ui->udp_test->setEnabled(false); | 231 | ui->udp_test->setEnabled(false); |
| 192 | ui->udp_test->setText(tr("Testing")); | 232 | ui->udp_test->setText(tr("Testing")); |
| 193 | udp_test_in_progress = true; | 233 | udp_test_in_progress = true; |
| 194 | InputCommon::CemuhookUDP::TestCommunication( | 234 | InputCommon::CemuhookUDP::TestCommunication( |
| 195 | ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), | 235 | ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), 0, |
| 196 | static_cast<u32>(ui->udp_pad_index->currentIndex()), 24872, | 236 | 24872, |
| 197 | [this] { | 237 | [this] { |
| 198 | LOG_INFO(Frontend, "UDP input test success"); | 238 | LOG_INFO(Frontend, "UDP input test success"); |
| 199 | QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true)); | 239 | QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true)); |
| @@ -207,9 +247,9 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() { | |||
| 207 | void ConfigureMotionTouch::OnConfigureTouchCalibration() { | 247 | void ConfigureMotionTouch::OnConfigureTouchCalibration() { |
| 208 | ui->touch_calibration_config->setEnabled(false); | 248 | ui->touch_calibration_config->setEnabled(false); |
| 209 | ui->touch_calibration_config->setText(tr("Configuring")); | 249 | ui->touch_calibration_config->setText(tr("Configuring")); |
| 210 | CalibrationConfigurationDialog dialog( | 250 | CalibrationConfigurationDialog dialog(this, ui->udp_server->text().toStdString(), |
| 211 | this, ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toUInt()), | 251 | static_cast<u16>(ui->udp_port->text().toUInt()), 0, |
| 212 | static_cast<u8>(ui->udp_pad_index->currentIndex()), 24872); | 252 | 24872); |
| 213 | dialog.exec(); | 253 | dialog.exec(); |
| 214 | if (dialog.completed) { | 254 | if (dialog.completed) { |
| 215 | min_x = dialog.min_x; | 255 | min_x = dialog.min_x; |
| @@ -269,7 +309,7 @@ void ConfigureMotionTouch::OnConfigureTouchFromButton() { | |||
| 269 | 309 | ||
| 270 | bool ConfigureMotionTouch::CanCloseDialog() { | 310 | bool ConfigureMotionTouch::CanCloseDialog() { |
| 271 | if (udp_test_in_progress) { | 311 | if (udp_test_in_progress) { |
| 272 | QMessageBox::warning(this, tr("Citra"), | 312 | QMessageBox::warning(this, tr("yuzu"), |
| 273 | tr("UDP Test or calibration configuration is in progress.<br>Please " | 313 | tr("UDP Test or calibration configuration is in progress.<br>Please " |
| 274 | "wait for them to finish.")); | 314 | "wait for them to finish.")); |
| 275 | return false; | 315 | return false; |
| @@ -282,17 +322,11 @@ void ConfigureMotionTouch::ApplyConfiguration() { | |||
| 282 | return; | 322 | return; |
| 283 | } | 323 | } |
| 284 | 324 | ||
| 285 | std::string motion_engine = ui->motion_provider->currentData().toString().toStdString(); | ||
| 286 | std::string touch_engine = ui->touch_provider->currentData().toString().toStdString(); | 325 | std::string touch_engine = ui->touch_provider->currentData().toString().toStdString(); |
| 287 | 326 | ||
| 288 | Common::ParamPackage motion_param{}, touch_param{}; | 327 | Common::ParamPackage touch_param{}; |
| 289 | motion_param.Set("engine", std::move(motion_engine)); | ||
| 290 | touch_param.Set("engine", std::move(touch_engine)); | 328 | touch_param.Set("engine", std::move(touch_engine)); |
| 291 | 329 | ||
| 292 | if (motion_engine == "motion_emu") { | ||
| 293 | motion_param.Set("sensitivity", static_cast<float>(ui->motion_sensitivity->value())); | ||
| 294 | } | ||
| 295 | |||
| 296 | if (touch_engine == "cemuhookudp") { | 330 | if (touch_engine == "cemuhookudp") { |
| 297 | touch_param.Set("min_x", min_x); | 331 | touch_param.Set("min_x", min_x); |
| 298 | touch_param.Set("min_y", min_y); | 332 | touch_param.Set("min_y", min_y); |
| @@ -300,15 +334,25 @@ void ConfigureMotionTouch::ApplyConfiguration() { | |||
| 300 | touch_param.Set("max_y", max_y); | 334 | touch_param.Set("max_y", max_y); |
| 301 | } | 335 | } |
| 302 | 336 | ||
| 303 | Settings::values.motion_device = motion_param.Serialize(); | ||
| 304 | Settings::values.touch_device = touch_param.Serialize(); | 337 | Settings::values.touch_device = touch_param.Serialize(); |
| 305 | Settings::values.use_touch_from_button = ui->touch_from_button_checkbox->isChecked(); | 338 | Settings::values.use_touch_from_button = ui->touch_from_button_checkbox->isChecked(); |
| 306 | Settings::values.touch_from_button_map_index = ui->touch_from_button_map->currentIndex(); | 339 | Settings::values.touch_from_button_map_index = ui->touch_from_button_map->currentIndex(); |
| 307 | Settings::values.touch_from_button_maps = touch_from_button_maps; | 340 | Settings::values.touch_from_button_maps = touch_from_button_maps; |
| 308 | Settings::values.udp_input_address = ui->udp_server->text().toStdString(); | 341 | Settings::values.udp_input_servers = GetUDPServerString(); |
| 309 | Settings::values.udp_input_port = static_cast<u16>(ui->udp_port->text().toInt()); | ||
| 310 | Settings::values.udp_pad_index = static_cast<u8>(ui->udp_pad_index->currentIndex()); | ||
| 311 | input_subsystem->ReloadInputDevices(); | 342 | input_subsystem->ReloadInputDevices(); |
| 312 | 343 | ||
| 313 | accept(); | 344 | accept(); |
| 314 | } | 345 | } |
| 346 | |||
| 347 | std::string ConfigureMotionTouch::GetUDPServerString() const { | ||
| 348 | QString input_servers; | ||
| 349 | |||
| 350 | for (const auto& item : udp_server_list_model->stringList()) { | ||
| 351 | input_servers += item; | ||
| 352 | input_servers += QLatin1Char{','}; | ||
| 353 | } | ||
| 354 | |||
| 355 | // Remove last comma | ||
| 356 | input_servers.chop(1); | ||
| 357 | return input_servers.toStdString(); | ||
| 358 | } | ||
diff --git a/src/yuzu/configuration/configure_motion_touch.h b/src/yuzu/configuration/configure_motion_touch.h index 3d4b5d659..15d61e8ba 100644 --- a/src/yuzu/configuration/configure_motion_touch.h +++ b/src/yuzu/configuration/configure_motion_touch.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | class QLabel; | 11 | class QLabel; |
| 12 | class QPushButton; | 12 | class QPushButton; |
| 13 | class QStringListModel; | ||
| 13 | class QVBoxLayout; | 14 | class QVBoxLayout; |
| 14 | 15 | ||
| 15 | namespace InputCommon { | 16 | namespace InputCommon { |
| @@ -62,6 +63,8 @@ public slots: | |||
| 62 | void ApplyConfiguration(); | 63 | void ApplyConfiguration(); |
| 63 | 64 | ||
| 64 | private slots: | 65 | private slots: |
| 66 | void OnUDPAddServer(); | ||
| 67 | void OnUDPDeleteServer(); | ||
| 65 | void OnCemuhookUDPTest(); | 68 | void OnCemuhookUDPTest(); |
| 66 | void OnConfigureTouchCalibration(); | 69 | void OnConfigureTouchCalibration(); |
| 67 | void OnConfigureTouchFromButton(); | 70 | void OnConfigureTouchFromButton(); |
| @@ -73,10 +76,12 @@ private: | |||
| 73 | void UpdateUiDisplay(); | 76 | void UpdateUiDisplay(); |
| 74 | void ConnectEvents(); | 77 | void ConnectEvents(); |
| 75 | bool CanCloseDialog(); | 78 | bool CanCloseDialog(); |
| 79 | std::string GetUDPServerString() const; | ||
| 76 | 80 | ||
| 77 | InputCommon::InputSubsystem* input_subsystem; | 81 | InputCommon::InputSubsystem* input_subsystem; |
| 78 | 82 | ||
| 79 | std::unique_ptr<Ui::ConfigureMotionTouch> ui; | 83 | std::unique_ptr<Ui::ConfigureMotionTouch> ui; |
| 84 | QStringListModel* udp_server_list_model; | ||
| 80 | 85 | ||
| 81 | // Coordinate system of the CemuhookUDP touch provider | 86 | // Coordinate system of the CemuhookUDP touch provider |
| 82 | int min_x{}; | 87 | int min_x{}; |
diff --git a/src/yuzu/configuration/configure_motion_touch.ui b/src/yuzu/configuration/configure_motion_touch.ui index 5b78c5a4b..ebca835ac 100644 --- a/src/yuzu/configuration/configure_motion_touch.ui +++ b/src/yuzu/configuration/configure_motion_touch.ui | |||
| @@ -2,41 +2,30 @@ | |||
| 2 | <ui version="4.0"> | 2 | <ui version="4.0"> |
| 3 | <class>ConfigureMotionTouch</class> | 3 | <class>ConfigureMotionTouch</class> |
| 4 | <widget class="QDialog" name="ConfigureMotionTouch"> | 4 | <widget class="QDialog" name="ConfigureMotionTouch"> |
| 5 | <property name="windowTitle"> | ||
| 6 | <string>Configure Motion / Touch</string> | ||
| 7 | </property> | ||
| 8 | <property name="geometry"> | 5 | <property name="geometry"> |
| 9 | <rect> | 6 | <rect> |
| 10 | <x>0</x> | 7 | <x>0</x> |
| 11 | <y>0</y> | 8 | <y>0</y> |
| 12 | <width>500</width> | 9 | <width>500</width> |
| 13 | <height>450</height> | 10 | <height>482</height> |
| 14 | </rect> | 11 | </rect> |
| 15 | </property> | 12 | </property> |
| 13 | <property name="windowTitle"> | ||
| 14 | <string>Configure Motion / Touch</string> | ||
| 15 | </property> | ||
| 16 | <property name="styleSheet"> | ||
| 17 | <string notr="true"/> | ||
| 18 | </property> | ||
| 16 | <layout class="QVBoxLayout"> | 19 | <layout class="QVBoxLayout"> |
| 17 | <item> | 20 | <item> |
| 18 | <widget class="QGroupBox" name="motion_group_box"> | 21 | <widget class="QGroupBox" name="motion_group_box"> |
| 19 | <property name="title"> | 22 | <property name="title"> |
| 20 | <string>Motion</string> | 23 | <string>Mouse Motion</string> |
| 21 | </property> | 24 | </property> |
| 22 | <layout class="QVBoxLayout"> | 25 | <layout class="QVBoxLayout"> |
| 23 | <item> | 26 | <item> |
| 24 | <layout class="QHBoxLayout"> | 27 | <layout class="QHBoxLayout"> |
| 25 | <item> | 28 | <item> |
| 26 | <widget class="QLabel" name="motion_provider_label"> | ||
| 27 | <property name="text"> | ||
| 28 | <string>Motion Provider:</string> | ||
| 29 | </property> | ||
| 30 | </widget> | ||
| 31 | </item> | ||
| 32 | <item> | ||
| 33 | <widget class="QComboBox" name="motion_provider"/> | ||
| 34 | </item> | ||
| 35 | </layout> | ||
| 36 | </item> | ||
| 37 | <item> | ||
| 38 | <layout class="QHBoxLayout"> | ||
| 39 | <item> | ||
| 40 | <widget class="QLabel" name="motion_sensitivity_label"> | 29 | <widget class="QLabel" name="motion_sensitivity_label"> |
| 41 | <property name="text"> | 30 | <property name="text"> |
| 42 | <string>Sensitivity:</string> | 31 | <string>Sensitivity:</string> |
| @@ -180,103 +169,171 @@ | |||
| 180 | </widget> | 169 | </widget> |
| 181 | </item> | 170 | </item> |
| 182 | <item> | 171 | <item> |
| 183 | <layout class="QHBoxLayout"> | 172 | <layout class="QHBoxLayout" name="horizontalLayout"> |
| 184 | <item> | 173 | <item> |
| 185 | <widget class="QLabel" name="udp_server_label"> | 174 | <widget class="QListView" name="udp_server_list"/> |
| 186 | <property name="text"> | ||
| 187 | <string>Server:</string> | ||
| 188 | </property> | ||
| 189 | </widget> | ||
| 190 | </item> | 175 | </item> |
| 191 | <item> | 176 | <item> |
| 192 | <widget class="QLineEdit" name="udp_server"> | 177 | <layout class="QVBoxLayout" name="verticalLayout"> |
| 193 | <property name="sizePolicy"> | 178 | <property name="leftMargin"> |
| 194 | <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> | 179 | <number>0</number> |
| 195 | <horstretch>0</horstretch> | ||
| 196 | <verstretch>0</verstretch> | ||
| 197 | </sizepolicy> | ||
| 198 | </property> | 180 | </property> |
| 199 | </widget> | 181 | <property name="topMargin"> |
| 200 | </item> | 182 | <number>0</number> |
| 201 | </layout> | ||
| 202 | </item> | ||
| 203 | <item> | ||
| 204 | <layout class="QHBoxLayout"> | ||
| 205 | <item> | ||
| 206 | <widget class="QLabel" name="udp_port_label"> | ||
| 207 | <property name="text"> | ||
| 208 | <string>Port:</string> | ||
| 209 | </property> | 183 | </property> |
| 210 | </widget> | 184 | <property name="rightMargin"> |
| 211 | </item> | 185 | <number>0</number> |
| 212 | <item> | ||
| 213 | <widget class="QLineEdit" name="udp_port"> | ||
| 214 | <property name="sizePolicy"> | ||
| 215 | <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> | ||
| 216 | <horstretch>0</horstretch> | ||
| 217 | <verstretch>0</verstretch> | ||
| 218 | </sizepolicy> | ||
| 219 | </property> | 186 | </property> |
| 220 | </widget> | 187 | <property name="bottomMargin"> |
| 221 | </item> | 188 | <number>0</number> |
| 222 | </layout> | ||
| 223 | </item> | ||
| 224 | <item> | ||
| 225 | <layout class="QHBoxLayout"> | ||
| 226 | <item> | ||
| 227 | <widget class="QLabel" name="udp_pad_index_label"> | ||
| 228 | <property name="text"> | ||
| 229 | <string>Pad:</string> | ||
| 230 | </property> | 189 | </property> |
| 231 | </widget> | ||
| 232 | </item> | ||
| 233 | <item> | ||
| 234 | <widget class="QComboBox" name="udp_pad_index"> | ||
| 235 | <item> | 190 | <item> |
| 236 | <property name="text"> | 191 | <layout class="QHBoxLayout"> |
| 237 | <string>Pad 1</string> | 192 | <property name="leftMargin"> |
| 238 | </property> | 193 | <number>3</number> |
| 194 | </property> | ||
| 195 | <property name="topMargin"> | ||
| 196 | <number>3</number> | ||
| 197 | </property> | ||
| 198 | <property name="rightMargin"> | ||
| 199 | <number>0</number> | ||
| 200 | </property> | ||
| 201 | <item> | ||
| 202 | <widget class="QLabel" name="udp_server_label"> | ||
| 203 | <property name="text"> | ||
| 204 | <string>Server:</string> | ||
| 205 | </property> | ||
| 206 | </widget> | ||
| 207 | </item> | ||
| 208 | <item> | ||
| 209 | <widget class="QLineEdit" name="udp_server"> | ||
| 210 | <property name="sizePolicy"> | ||
| 211 | <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> | ||
| 212 | <horstretch>0</horstretch> | ||
| 213 | <verstretch>0</verstretch> | ||
| 214 | </sizepolicy> | ||
| 215 | </property> | ||
| 216 | </widget> | ||
| 217 | </item> | ||
| 218 | </layout> | ||
| 239 | </item> | 219 | </item> |
| 240 | <item> | 220 | <item> |
| 241 | <property name="text"> | 221 | <layout class="QHBoxLayout"> |
| 242 | <string>Pad 2</string> | 222 | <property name="leftMargin"> |
| 243 | </property> | 223 | <number>3</number> |
| 224 | </property> | ||
| 225 | <property name="rightMargin"> | ||
| 226 | <number>0</number> | ||
| 227 | </property> | ||
| 228 | <item> | ||
| 229 | <widget class="QLabel" name="udp_port_label"> | ||
| 230 | <property name="text"> | ||
| 231 | <string>Port:</string> | ||
| 232 | </property> | ||
| 233 | </widget> | ||
| 234 | </item> | ||
| 235 | <item> | ||
| 236 | <widget class="QLineEdit" name="udp_port"> | ||
| 237 | <property name="sizePolicy"> | ||
| 238 | <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> | ||
| 239 | <horstretch>0</horstretch> | ||
| 240 | <verstretch>0</verstretch> | ||
| 241 | </sizepolicy> | ||
| 242 | </property> | ||
| 243 | </widget> | ||
| 244 | </item> | ||
| 245 | </layout> | ||
| 244 | </item> | 246 | </item> |
| 245 | <item> | 247 | <item> |
| 246 | <property name="text"> | 248 | <layout class="QHBoxLayout"> |
| 247 | <string>Pad 3</string> | 249 | <property name="leftMargin"> |
| 248 | </property> | 250 | <number>3</number> |
| 251 | </property> | ||
| 252 | <property name="rightMargin"> | ||
| 253 | <number>0</number> | ||
| 254 | </property> | ||
| 255 | <item> | ||
| 256 | <widget class="QLabel" name="udp_learn_more"> | ||
| 257 | <property name="text"> | ||
| 258 | <string>Learn More</string> | ||
| 259 | </property> | ||
| 260 | </widget> | ||
| 261 | </item> | ||
| 262 | <item> | ||
| 263 | <widget class="QPushButton" name="udp_test"> | ||
| 264 | <property name="sizePolicy"> | ||
| 265 | <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> | ||
| 266 | <horstretch>0</horstretch> | ||
| 267 | <verstretch>0</verstretch> | ||
| 268 | </sizepolicy> | ||
| 269 | </property> | ||
| 270 | <property name="text"> | ||
| 271 | <string>Test</string> | ||
| 272 | </property> | ||
| 273 | </widget> | ||
| 274 | </item> | ||
| 275 | <item> | ||
| 276 | <widget class="QPushButton" name="udp_add"> | ||
| 277 | <property name="sizePolicy"> | ||
| 278 | <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> | ||
| 279 | <horstretch>0</horstretch> | ||
| 280 | <verstretch>0</verstretch> | ||
| 281 | </sizepolicy> | ||
| 282 | </property> | ||
| 283 | <property name="text"> | ||
| 284 | <string>Add Server</string> | ||
| 285 | </property> | ||
| 286 | </widget> | ||
| 287 | </item> | ||
| 288 | </layout> | ||
| 249 | </item> | 289 | </item> |
| 250 | <item> | 290 | <item> |
| 251 | <property name="text"> | 291 | <spacer name="verticalSpacer_3"> |
| 252 | <string>Pad 4</string> | 292 | <property name="orientation"> |
| 253 | </property> | 293 | <enum>Qt::Vertical</enum> |
| 294 | </property> | ||
| 295 | <property name="sizeHint" stdset="0"> | ||
| 296 | <size> | ||
| 297 | <width>20</width> | ||
| 298 | <height>40</height> | ||
| 299 | </size> | ||
| 300 | </property> | ||
| 301 | </spacer> | ||
| 254 | </item> | 302 | </item> |
| 255 | </widget> | 303 | <item> |
| 256 | </item> | 304 | <layout class="QHBoxLayout" name="horizontalLayout_2"> |
| 257 | </layout> | 305 | <property name="topMargin"> |
| 258 | </item> | 306 | <number>0</number> |
| 259 | <item> | 307 | </property> |
| 260 | <layout class="QHBoxLayout"> | 308 | <item> |
| 261 | <item> | 309 | <widget class="QPushButton" name="udp_remove"> |
| 262 | <widget class="QLabel" name="udp_learn_more"> | 310 | <property name="sizePolicy"> |
| 263 | <property name="text"> | 311 | <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> |
| 264 | <string>Learn More</string> | 312 | <horstretch>0</horstretch> |
| 265 | </property> | 313 | <verstretch>0</verstretch> |
| 266 | </widget> | 314 | </sizepolicy> |
| 267 | </item> | 315 | </property> |
| 268 | <item> | 316 | <property name="text"> |
| 269 | <widget class="QPushButton" name="udp_test"> | 317 | <string>Remove Server</string> |
| 270 | <property name="sizePolicy"> | 318 | </property> |
| 271 | <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> | 319 | </widget> |
| 272 | <horstretch>0</horstretch> | 320 | </item> |
| 273 | <verstretch>0</verstretch> | 321 | <item> |
| 274 | </sizepolicy> | 322 | <spacer name="horizontalSpacer_2"> |
| 275 | </property> | 323 | <property name="orientation"> |
| 276 | <property name="text"> | 324 | <enum>Qt::Horizontal</enum> |
| 277 | <string>Test</string> | 325 | </property> |
| 278 | </property> | 326 | <property name="sizeHint" stdset="0"> |
| 279 | </widget> | 327 | <size> |
| 328 | <width>40</width> | ||
| 329 | <height>20</height> | ||
| 330 | </size> | ||
| 331 | </property> | ||
| 332 | </spacer> | ||
| 333 | </item> | ||
| 334 | </layout> | ||
| 335 | </item> | ||
| 336 | </layout> | ||
| 280 | </item> | 337 | </item> |
| 281 | </layout> | 338 | </layout> |
| 282 | </item> | 339 | </item> |
| @@ -312,6 +369,16 @@ | |||
| 312 | <signal>accepted()</signal> | 369 | <signal>accepted()</signal> |
| 313 | <receiver>ConfigureMotionTouch</receiver> | 370 | <receiver>ConfigureMotionTouch</receiver> |
| 314 | <slot>ApplyConfiguration()</slot> | 371 | <slot>ApplyConfiguration()</slot> |
| 372 | <hints> | ||
| 373 | <hint type="sourcelabel"> | ||
| 374 | <x>20</x> | ||
| 375 | <y>20</y> | ||
| 376 | </hint> | ||
| 377 | <hint type="destinationlabel"> | ||
| 378 | <x>20</x> | ||
| 379 | <y>20</y> | ||
| 380 | </hint> | ||
| 381 | </hints> | ||
| 315 | </connection> | 382 | </connection> |
| 316 | </connections> | 383 | </connections> |
| 317 | </ui> | 384 | </ui> |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 871ff4ae4..26f5e42ed 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -477,11 +477,13 @@ void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view | |||
| 477 | #else | 477 | #else |
| 478 | 478 | ||
| 479 | void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view additional_args) { | 479 | void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view additional_args) { |
| 480 | #ifndef __linux__ | ||
| 480 | QMessageBox::warning( | 481 | QMessageBox::warning( |
| 481 | this, tr("Web Applet"), | 482 | this, tr("Web Applet"), |
| 482 | tr("This version of yuzu was built without QtWebEngine support, meaning that yuzu cannot " | 483 | tr("This version of yuzu was built without QtWebEngine support, meaning that yuzu cannot " |
| 483 | "properly display the game manual or web page requested."), | 484 | "properly display the game manual or web page requested."), |
| 484 | QMessageBox::Ok, QMessageBox::Ok); | 485 | QMessageBox::Ok, QMessageBox::Ok); |
| 486 | #endif | ||
| 485 | 487 | ||
| 486 | LOG_INFO(Frontend, | 488 | LOG_INFO(Frontend, |
| 487 | "(STUBBED) called - Missing QtWebEngine dependency needed to open website page at " | 489 | "(STUBBED) called - Missing QtWebEngine dependency needed to open website page at " |
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index e1adbbf2b..34c9673bc 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp | |||
| @@ -306,10 +306,8 @@ void Config::ReadValues() { | |||
| 306 | sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_x", 15); | 306 | sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_x", 15); |
| 307 | Settings::values.touchscreen.diameter_y = | 307 | Settings::values.touchscreen.diameter_y = |
| 308 | sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_y", 15); | 308 | sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_y", 15); |
| 309 | Settings::values.udp_input_address = | 309 | Settings::values.udp_input_servers = |
| 310 | sdl2_config->Get("Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_ADDR); | 310 | sdl2_config->Get("Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_SRV); |
| 311 | Settings::values.udp_input_port = static_cast<u16>(sdl2_config->GetInteger( | ||
| 312 | "Controls", "udp_input_port", InputCommon::CemuhookUDP::DEFAULT_PORT)); | ||
| 313 | 311 | ||
| 314 | std::transform(keyboard_keys.begin(), keyboard_keys.end(), | 312 | std::transform(keyboard_keys.begin(), keyboard_keys.end(), |
| 315 | Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam); | 313 | Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam); |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index c4a4a36be..e32bed5e6 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "core/perf_stats.h" | 9 | #include "core/perf_stats.h" |
| 10 | #include "input_common/keyboard.h" | 10 | #include "input_common/keyboard.h" |
| 11 | #include "input_common/main.h" | 11 | #include "input_common/main.h" |
| 12 | #include "input_common/motion_emu.h" | 12 | #include "input_common/mouse/mouse_input.h" |
| 13 | #include "input_common/sdl/sdl.h" | 13 | #include "input_common/sdl/sdl.h" |
| 14 | #include "yuzu_cmd/emu_window/emu_window_sdl2.h" | 14 | #include "yuzu_cmd/emu_window/emu_window_sdl2.h" |
| 15 | 15 | ||
| @@ -30,7 +30,7 @@ EmuWindow_SDL2::~EmuWindow_SDL2() { | |||
| 30 | 30 | ||
| 31 | void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { | 31 | void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { |
| 32 | TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); | 32 | TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); |
| 33 | input_subsystem->GetMotionEmu()->Tilt(x, y); | 33 | input_subsystem->GetMouse()->MouseMove(x, y); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { | 36 | void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { |
| @@ -42,9 +42,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { | |||
| 42 | } | 42 | } |
| 43 | } else if (button == SDL_BUTTON_RIGHT) { | 43 | } else if (button == SDL_BUTTON_RIGHT) { |
| 44 | if (state == SDL_PRESSED) { | 44 | if (state == SDL_PRESSED) { |
| 45 | input_subsystem->GetMotionEmu()->BeginTilt(x, y); | 45 | input_subsystem->GetMouse()->PressButton(x, y, button); |
| 46 | } else { | 46 | } else { |
| 47 | input_subsystem->GetMotionEmu()->EndTilt(); | 47 | input_subsystem->GetMouse()->ReleaseButton(button); |
| 48 | } | 48 | } |
| 49 | } | 49 | } |
| 50 | } | 50 | } |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 5f35233b5..a103b04bd 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include "core/settings.h" | 17 | #include "core/settings.h" |
| 18 | #include "input_common/keyboard.h" | 18 | #include "input_common/keyboard.h" |
| 19 | #include "input_common/main.h" | 19 | #include "input_common/main.h" |
| 20 | #include "input_common/motion_emu.h" | ||
| 21 | #include "video_core/renderer_base.h" | 20 | #include "video_core/renderer_base.h" |
| 22 | #include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h" | 21 | #include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h" |
| 23 | 22 | ||