summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.ci/scripts/linux/docker.sh2
-rw-r--r--src/audio_core/CMakeLists.txt2
-rw-r--r--src/audio_core/algorithm/filter.cpp6
-rw-r--r--src/audio_core/algorithm/filter.h4
-rw-r--r--src/audio_core/audio_renderer.cpp6
-rw-r--r--src/audio_core/audio_renderer.h3
-rw-r--r--src/audio_core/buffer.h2
-rw-r--r--src/audio_core/command_generator.cpp27
-rw-r--r--src/audio_core/command_generator.h8
-rw-r--r--src/audio_core/cubeb_sink.cpp15
-rw-r--r--src/audio_core/effect_context.cpp60
-rw-r--r--src/audio_core/effect_context.h6
-rw-r--r--src/audio_core/info_updater.cpp32
-rw-r--r--src/audio_core/info_updater.h4
-rw-r--r--src/audio_core/memory_pool.cpp13
-rw-r--r--src/audio_core/memory_pool.h11
-rw-r--r--src/audio_core/sink_context.cpp2
-rw-r--r--src/audio_core/sink_context.h12
-rw-r--r--src/audio_core/splitter_context.cpp22
-rw-r--r--src/audio_core/splitter_context.h20
-rw-r--r--src/audio_core/stream.cpp10
-rw-r--r--src/audio_core/stream.h4
-rw-r--r--src/audio_core/voice_context.cpp7
-rw-r--r--src/audio_core/voice_context.h10
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/div_ceil.h26
-rw-r--r--src/common/wall_clock.cpp4
-rw-r--r--src/common/wall_clock.h6
-rw-r--r--src/common/x64/native_clock.cpp8
-rw-r--r--src/common/x64/native_clock.h3
-rw-r--r--src/core/core_timing.h8
-rw-r--r--src/core/frontend/input.h9
-rw-r--r--src/core/hle/result.h2
-rw-r--r--src/core/settings.h4
-rw-r--r--src/input_common/CMakeLists.txt6
-rw-r--r--src/input_common/main.cpp75
-rw-r--r--src/input_common/main.h41
-rw-r--r--src/input_common/motion_emu.cpp179
-rw-r--r--src/input_common/motion_emu.h46
-rw-r--r--src/input_common/mouse/mouse_input.cpp129
-rw-r--r--src/input_common/mouse/mouse_input.h98
-rw-r--r--src/input_common/mouse/mouse_poller.cpp259
-rw-r--r--src/input_common/mouse/mouse_poller.h109
-rw-r--r--src/input_common/udp/client.cpp143
-rw-r--r--src/input_common/udp/client.h40
-rw-r--r--src/input_common/udp/udp.cpp64
-rw-r--r--src/video_core/command_classes/codecs/codec.cpp33
-rw-r--r--src/video_core/command_classes/codecs/codec.h11
-rw-r--r--src/video_core/command_classes/codecs/h264.cpp2
-rw-r--r--src/video_core/command_classes/codecs/h264.h4
-rw-r--r--src/video_core/command_classes/codecs/vp9.cpp333
-rw-r--r--src/video_core/command_classes/codecs/vp9.h7
-rw-r--r--src/video_core/command_classes/codecs/vp9_types.h160
-rw-r--r--src/video_core/command_classes/nvdec.cpp6
-rw-r--r--src/video_core/command_classes/nvdec.h3
-rw-r--r--src/video_core/command_classes/vic.cpp15
-rw-r--r--src/video_core/engines/maxwell_3d.h7
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp7
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h8
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp1
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.h1
-rw-r--r--src/yuzu/bootmanager.cpp26
-rw-r--r--src/yuzu/configuration/config.cpp20
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp87
-rw-r--r--src/yuzu/configuration/configure_motion_touch.cpp134
-rw-r--r--src/yuzu/configuration/configure_motion_touch.h5
-rw-r--r--src/yuzu/configuration/configure_motion_touch.ui269
-rw-r--r--src/yuzu/main.cpp2
-rw-r--r--src/yuzu_cmd/config.cpp6
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp8
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp1
72 files changed, 1660 insertions, 1050 deletions
diff --git a/.ci/scripts/linux/docker.sh b/.ci/scripts/linux/docker.sh
index 277775ef6..05f6ffe7d 100755
--- a/.ci/scripts/linux/docker.sh
+++ b/.ci/scripts/linux/docker.sh
@@ -5,7 +5,7 @@ cd /yuzu
ccache -s
mkdir build || true && cd build
-cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DYUZU_USE_BUNDLED_UNICORN=ON -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON
+cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DYUZU_USE_BUNDLED_UNICORN=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON
ninja
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)
-Werror=implicit-fallthrough
-Werror=reorder
-Werror=sign-compare
+ -Werror=shadow
+ -Werror=unused-parameter
-Werror=unused-variable
$<$<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) {
Filter::Filter() : Filter(1.0, 0.0, 0.0, 1.0, 0.0, 0.0) {}
-Filter::Filter(double a0, double a1, double a2, double b0, double b1, double b2)
- : a1(a1 / a0), a2(a2 / a0), b0(b0 / a0), b1(b1 / a0), b2(b2 / a0) {}
+Filter::Filter(double a0_, double a1_, double a2_, double b0_, double b1_, double b2_)
+ : a1(a1_ / a0_), a2(a2_ / a0_), b0(b0_ / a0_), b1(b1_ / a0_), b2(b2_ / a0_) {}
void Filter::Process(std::vector<s16>& signal) {
const std::size_t num_frames = signal.size() / 2;
@@ -69,7 +69,7 @@ CascadingFilter CascadingFilter::LowPass(double cutoff, std::size_t cascade_size
}
CascadingFilter::CascadingFilter() = default;
-CascadingFilter::CascadingFilter(std::vector<Filter> filters) : filters(std::move(filters)) {}
+CascadingFilter::CascadingFilter(std::vector<Filter> filters_) : filters(std::move(filters_)) {}
void CascadingFilter::Process(std::vector<s16>& signal) {
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:
/// Passthrough filter.
Filter();
- Filter(double a0, double a1, double a2, double b0, double b1, double b2);
+ Filter(double a0_, double a1_, double a2_, double b0_, double b1_, double b2_);
void Process(std::vector<s16>& signal);
@@ -51,7 +51,7 @@ public:
/// Passthrough.
CascadingFilter();
- explicit CascadingFilter(std::vector<Filter> filters);
+ explicit CascadingFilter(std::vector<Filter> filters_);
void Process(std::vector<s16>& signal);
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 {
namespace AudioCore {
AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_,
AudioCommon::AudioRendererParameter params,
- std::shared_ptr<Kernel::WritableEvent> buffer_event,
+ std::shared_ptr<Kernel::WritableEvent> buffer_event_,
std::size_t instance_number)
- : worker_params{params}, buffer_event{buffer_event},
+ : worker_params{params}, buffer_event{buffer_event_},
memory_pool_info(params.effect_count + params.voice_count * 4),
voice_context(params.voice_count), effect_context(params.effect_count), mix_context(),
sink_context(params.sink_count), splitter_context(),
@@ -88,7 +88,7 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory
stream =
audio_out->OpenStream(core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS,
fmt::format("AudioRenderer-Instance{}", instance_number),
- [=]() { buffer_event->Signal(); });
+ [=]() { buffer_event_->Signal(); });
audio_out->StartStream(stream);
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 {
public:
AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_,
AudioCommon::AudioRendererParameter params,
- std::shared_ptr<Kernel::WritableEvent> buffer_event, std::size_t instance_number);
+ std::shared_ptr<Kernel::WritableEvent> buffer_event_,
+ std::size_t instance_number);
~AudioRenderer();
[[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 {
public:
using Tag = u64;
- Buffer(Tag tag, std::vector<s16>&& samples) : tag{tag}, samples{std::move(samples)} {}
+ Buffer(Tag tag_, std::vector<s16>&& samples_) : tag{tag_}, samples{std::move(samples_)} {}
/// Returns the raw audio data for the buffer
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) {
} // namespace
-CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_params,
- VoiceContext& voice_context, MixContext& mix_context,
- SplitterContext& splitter_context, EffectContext& effect_context,
- Core::Memory::Memory& memory)
- : worker_params(worker_params), voice_context(voice_context), mix_context(mix_context),
- splitter_context(splitter_context), effect_context(effect_context), memory(memory),
+CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_params_,
+ VoiceContext& voice_context_, MixContext& mix_context_,
+ SplitterContext& splitter_context_,
+ EffectContext& effect_context_, Core::Memory::Memory& memory_)
+ : worker_params(worker_params_), voice_context(voice_context_), mix_context(mix_context_),
+ splitter_context(splitter_context_), effect_context(effect_context_), memory(memory_),
mix_buffer((worker_params.mix_buffer_count + AudioCommon::MAX_CHANNEL_COUNT) *
worker_params.sample_count),
sample_buffer(MIX_BUFFER_SIZE),
@@ -255,7 +255,8 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo
void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info,
VoiceState& dsp_state,
- s32 mix_buffer_count, s32 channel) {
+ [[maybe_unused]] s32 mix_buffer_count,
+ [[maybe_unused]] s32 channel) {
for (std::size_t i = 0; i < AudioCommon::MAX_BIQUAD_FILTERS; i++) {
const auto& in_params = voice_info.GetInParams();
auto& biquad_filter = in_params.biquad_filter[i];
@@ -278,9 +279,12 @@ void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voic
}
}
-void AudioCore::CommandGenerator::GenerateBiquadFilterCommand(
- s32 mix_buffer, const BiquadFilterParameter& params, std::array<s64, 2>& state,
- std::size_t input_offset, std::size_t output_offset, s32 sample_count, s32 node_id) {
+void CommandGenerator::GenerateBiquadFilterCommand([[maybe_unused]] s32 mix_buffer_id,
+ const BiquadFilterParameter& params,
+ std::array<s64, 2>& state,
+ std::size_t input_offset,
+ std::size_t output_offset, s32 sample_count,
+ s32 node_id) {
if (dumping_frame) {
LOG_DEBUG(Audio,
"(DSP_TRACE) GenerateBiquadFilterCommand node_id={}, "
@@ -714,7 +718,8 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s
}
s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
- s32 sample_count, s32 channel, std::size_t mix_offset) {
+ s32 sample_count, [[maybe_unused]] s32 channel,
+ std::size_t mix_offset) {
const auto& in_params = voice_info.GetInParams();
const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
if (wave_buffer.buffer_address == 0) {
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>;
class CommandGenerator {
public:
- explicit CommandGenerator(AudioCommon::AudioRendererParameter& worker_params,
- VoiceContext& voice_context, MixContext& mix_context,
- SplitterContext& splitter_context, EffectContext& effect_context,
- Core::Memory::Memory& memory);
+ explicit CommandGenerator(AudioCommon::AudioRendererParameter& worker_params_,
+ VoiceContext& voice_context_, MixContext& mix_context_,
+ SplitterContext& splitter_context_, EffectContext& effect_context_,
+ Core::Memory::Memory& memory_);
~CommandGenerator();
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 {
class CubebSinkStream final : public SinkStream {
public:
- CubebSinkStream(cubeb* ctx, u32 sample_rate, u32 num_channels_, cubeb_devid output_device,
+ CubebSinkStream(cubeb* ctx_, u32 sample_rate, u32 num_channels_, cubeb_devid output_device,
const std::string& name)
- : ctx{ctx}, num_channels{std::min(num_channels_, 6u)}, time_stretch{sample_rate,
- num_channels} {
+ : ctx{ctx_}, num_channels{std::min(num_channels_, 6u)}, time_stretch{sample_rate,
+ num_channels} {
cubeb_stream_params params{};
params.rate = sample_rate;
@@ -192,8 +192,9 @@ SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels,
return *sink_streams.back();
}
-long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
- void* output_buffer, long num_frames) {
+long CubebSinkStream::DataCallback([[maybe_unused]] cubeb_stream* stream, void* user_data,
+ [[maybe_unused]] const void* input_buffer, void* output_buffer,
+ long num_frames) {
auto* impl = static_cast<CubebSinkStream*>(user_data);
auto* buffer = static_cast<u8*>(output_buffer);
@@ -236,7 +237,9 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const
return num_frames;
}
-void CubebSinkStream::StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state) {}
+void CubebSinkStream::StateCallback([[maybe_unused]] cubeb_stream* stream,
+ [[maybe_unused]] void* user_data,
+ [[maybe_unused]] cubeb_state state) {}
std::vector<std::string> ListCubebSinkDevices() {
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) {
}
} // namespace
-EffectContext::EffectContext(std::size_t effect_count) : effect_count(effect_count) {
+EffectContext::EffectContext(std::size_t effect_count_) : effect_count(effect_count_) {
effects.reserve(effect_count);
std::generate_n(std::back_inserter(effects), effect_count,
[] { return std::make_unique<EffectStubbed>(); });
@@ -61,13 +61,13 @@ const EffectBase* EffectContext::GetInfo(std::size_t i) const {
return effects.at(i).get();
}
-EffectStubbed::EffectStubbed() : EffectBase::EffectBase(EffectType::Invalid) {}
+EffectStubbed::EffectStubbed() : EffectBase(EffectType::Invalid) {}
EffectStubbed::~EffectStubbed() = default;
-void EffectStubbed::Update(EffectInfo::InParams& in_params) {}
+void EffectStubbed::Update([[maybe_unused]] EffectInfo::InParams& in_params) {}
void EffectStubbed::UpdateForCommandGeneration() {}
-EffectBase::EffectBase(EffectType effect_type) : effect_type(effect_type) {}
+EffectBase::EffectBase(EffectType effect_type_) : effect_type(effect_type_) {}
EffectBase::~EffectBase() = default;
UsageState EffectBase::GetUsage() const {
@@ -90,32 +90,32 @@ s32 EffectBase::GetProcessingOrder() const {
return processing_order;
}
-EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric::EffectGeneric(EffectType::I3dl2Reverb) {}
+EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric(EffectType::I3dl2Reverb) {}
EffectI3dl2Reverb::~EffectI3dl2Reverb() = default;
void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) {
- auto& internal_params = GetParams();
+ auto& params = GetParams();
const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(in_params.raw.data());
if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
UNREACHABLE_MSG("Invalid reverb max channel count {}", reverb_params->max_channels);
return;
}
- const auto last_status = internal_params.status;
+ const auto last_status = params.status;
mix_id = in_params.mix_id;
processing_order = in_params.processing_order;
- internal_params = *reverb_params;
+ params = *reverb_params;
if (!ValidChannelCountForEffect(reverb_params->channel_count)) {
- internal_params.channel_count = internal_params.max_channels;
+ params.channel_count = params.max_channels;
}
enabled = in_params.is_enabled;
if (last_status != ParameterStatus::Updated) {
- internal_params.status = last_status;
+ params.status = last_status;
}
if (in_params.is_new || skipped) {
usage = UsageState::Initialized;
- internal_params.status = ParameterStatus::Initialized;
+ params.status = ParameterStatus::Initialized;
skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
}
}
@@ -129,15 +129,15 @@ void EffectI3dl2Reverb::UpdateForCommandGeneration() {
GetParams().status = ParameterStatus::Updated;
}
-EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric::EffectGeneric(EffectType::BiquadFilter) {}
+EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric(EffectType::BiquadFilter) {}
EffectBiquadFilter::~EffectBiquadFilter() = default;
void EffectBiquadFilter::Update(EffectInfo::InParams& in_params) {
- auto& internal_params = GetParams();
+ auto& params = GetParams();
const auto* biquad_params = reinterpret_cast<BiquadFilterParams*>(in_params.raw.data());
mix_id = in_params.mix_id;
processing_order = in_params.processing_order;
- internal_params = *biquad_params;
+ params = *biquad_params;
enabled = in_params.is_enabled;
}
@@ -150,7 +150,7 @@ void EffectBiquadFilter::UpdateForCommandGeneration() {
GetParams().status = ParameterStatus::Updated;
}
-EffectAuxInfo::EffectAuxInfo() : EffectGeneric::EffectGeneric(EffectType::Aux) {}
+EffectAuxInfo::EffectAuxInfo() : EffectGeneric(EffectType::Aux) {}
EffectAuxInfo::~EffectAuxInfo() = default;
void EffectAuxInfo::Update(EffectInfo::InParams& in_params) {
@@ -200,32 +200,32 @@ VAddr EffectAuxInfo::GetRecvBuffer() const {
return recv_buffer;
}
-EffectDelay::EffectDelay() : EffectGeneric::EffectGeneric(EffectType::Delay) {}
+EffectDelay::EffectDelay() : EffectGeneric(EffectType::Delay) {}
EffectDelay::~EffectDelay() = default;
void EffectDelay::Update(EffectInfo::InParams& in_params) {
const auto* delay_params = reinterpret_cast<DelayParams*>(in_params.raw.data());
- auto& internal_params = GetParams();
+ auto& params = GetParams();
if (!ValidChannelCountForEffect(delay_params->max_channels)) {
return;
}
- const auto last_status = internal_params.status;
+ const auto last_status = params.status;
mix_id = in_params.mix_id;
processing_order = in_params.processing_order;
- internal_params = *delay_params;
+ params = *delay_params;
if (!ValidChannelCountForEffect(delay_params->channels)) {
- internal_params.channels = internal_params.max_channels;
+ params.channels = params.max_channels;
}
enabled = in_params.is_enabled;
if (last_status != ParameterStatus::Updated) {
- internal_params.status = last_status;
+ params.status = last_status;
}
if (in_params.is_new || skipped) {
usage = UsageState::Initialized;
- internal_params.status = ParameterStatus::Initialized;
+ params.status = ParameterStatus::Initialized;
skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
}
}
@@ -239,7 +239,7 @@ void EffectDelay::UpdateForCommandGeneration() {
GetParams().status = ParameterStatus::Updated;
}
-EffectBufferMixer::EffectBufferMixer() : EffectGeneric::EffectGeneric(EffectType::BufferMixer) {}
+EffectBufferMixer::EffectBufferMixer() : EffectGeneric(EffectType::BufferMixer) {}
EffectBufferMixer::~EffectBufferMixer() = default;
void EffectBufferMixer::Update(EffectInfo::InParams& in_params) {
@@ -257,32 +257,32 @@ void EffectBufferMixer::UpdateForCommandGeneration() {
}
}
-EffectReverb::EffectReverb() : EffectGeneric::EffectGeneric(EffectType::Reverb) {}
+EffectReverb::EffectReverb() : EffectGeneric(EffectType::Reverb) {}
EffectReverb::~EffectReverb() = default;
void EffectReverb::Update(EffectInfo::InParams& in_params) {
const auto* reverb_params = reinterpret_cast<ReverbParams*>(in_params.raw.data());
- auto& internal_params = GetParams();
+ auto& params = GetParams();
if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
return;
}
- const auto last_status = internal_params.status;
+ const auto last_status = params.status;
mix_id = in_params.mix_id;
processing_order = in_params.processing_order;
- internal_params = *reverb_params;
+ params = *reverb_params;
if (!ValidChannelCountForEffect(reverb_params->channels)) {
- internal_params.channels = internal_params.max_channels;
+ params.channels = params.max_channels;
}
enabled = in_params.is_enabled;
if (last_status != ParameterStatus::Updated) {
- internal_params.status = last_status;
+ params.status = last_status;
}
if (in_params.is_new || skipped) {
usage = UsageState::Initialized;
- internal_params.status = ParameterStatus::Initialized;
+ params.status = ParameterStatus::Initialized;
skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
}
}
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 {
class EffectBase {
public:
- explicit EffectBase(EffectType effect_type);
+ explicit EffectBase(EffectType effect_type_);
virtual ~EffectBase();
virtual void Update(EffectInfo::InParams& in_params) = 0;
@@ -206,7 +206,7 @@ protected:
template <typename T>
class EffectGeneric : public EffectBase {
public:
- explicit EffectGeneric(EffectType effect_type) : EffectBase(effect_type) {}
+ explicit EffectGeneric(EffectType effect_type_) : EffectBase(effect_type_) {}
T& GetParams() {
return internal_params;
@@ -306,7 +306,7 @@ private:
class EffectContext {
public:
- explicit EffectContext(std::size_t effect_count);
+ explicit EffectContext(std::size_t effect_count_);
~EffectContext();
[[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 @@
namespace AudioCore {
-InfoUpdater::InfoUpdater(const std::vector<u8>& in_params, std::vector<u8>& out_params,
- BehaviorInfo& behavior_info)
- : in_params(in_params), out_params(out_params), behavior_info(behavior_info) {
+InfoUpdater::InfoUpdater(const std::vector<u8>& in_params_, std::vector<u8>& out_params_,
+ BehaviorInfo& behavior_info_)
+ : in_params(in_params_), out_params(out_params_), behavior_info(behavior_info_) {
ASSERT(
AudioCommon::CanConsumeBuffer(in_params.size(), 0, sizeof(AudioCommon::UpdateDataHeader)));
std::memcpy(&input_header, in_params.data(), sizeof(AudioCommon::UpdateDataHeader));
@@ -135,8 +135,8 @@ bool InfoUpdater::UpdateVoiceChannelResources(VoiceContext& voice_context) {
}
bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
- std::vector<ServerMemoryPoolInfo>& memory_pool_info,
- VAddr audio_codec_dsp_addr) {
+ [[maybe_unused]] std::vector<ServerMemoryPoolInfo>& memory_pool_info,
+ [[maybe_unused]] VAddr audio_codec_dsp_addr) {
const auto voice_count = voice_context.GetVoiceCount();
std::vector<VoiceInfo::InParams> voice_in(voice_count);
std::vector<VoiceInfo::OutParams> voice_out(voice_count);
@@ -165,28 +165,28 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
// Update our voices
for (std::size_t i = 0; i < voice_count; i++) {
- auto& in_params = voice_in[i];
- const auto channel_count = static_cast<std::size_t>(in_params.channel_count);
+ auto& voice_in_params = voice_in[i];
+ const auto channel_count = static_cast<std::size_t>(voice_in_params.channel_count);
// Skip if it's not currently in use
- if (!in_params.is_in_use) {
+ if (!voice_in_params.is_in_use) {
continue;
}
// Voice states for each channel
std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT> voice_states{};
- ASSERT(static_cast<std::size_t>(in_params.id) < voice_count);
+ ASSERT(static_cast<std::size_t>(voice_in_params.id) < voice_count);
// Grab our current voice info
- auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(in_params.id));
+ auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(voice_in_params.id));
ASSERT(channel_count <= AudioCommon::MAX_CHANNEL_COUNT);
// Get all our channel voice states
for (std::size_t channel = 0; channel < channel_count; channel++) {
voice_states[channel] =
- &voice_context.GetState(in_params.voice_channel_resource_ids[channel]);
+ &voice_context.GetState(voice_in_params.voice_channel_resource_ids[channel]);
}
- if (in_params.is_new) {
+ if (voice_in_params.is_new) {
// Default our values for our voice
voice_info.Initialize();
if (channel_count == 0 || channel_count > AudioCommon::MAX_CHANNEL_COUNT) {
@@ -200,12 +200,12 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
}
// Update our voice
- voice_info.UpdateParameters(in_params, behavior_info);
+ voice_info.UpdateParameters(voice_in_params, behavior_info);
// TODO(ogniK): Handle mapping errors with behavior info based on in params response
// Update our wave buffers
- voice_info.UpdateWaveBuffers(in_params, voice_states, behavior_info);
- voice_info.WriteOutStatus(voice_out[i], in_params, voice_states);
+ voice_info.UpdateWaveBuffers(voice_in_params, voice_states, behavior_info);
+ voice_info.WriteOutStatus(voice_out[i], voice_in_params, voice_states);
}
if (!AudioCommon::CanConsumeBuffer(out_params.size(), output_offset, voice_out_size)) {
@@ -445,7 +445,7 @@ bool InfoUpdater::UpdatePerformanceBuffer() {
return true;
}
-bool InfoUpdater::UpdateErrorInfo(BehaviorInfo& in_behavior_info) {
+bool InfoUpdater::UpdateErrorInfo([[maybe_unused]] BehaviorInfo& in_behavior_info) {
const auto total_beahvior_info_out = sizeof(BehaviorInfo::OutParams);
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;
class InfoUpdater {
public:
// TODO(ogniK): Pass process handle when we support it
- InfoUpdater(const std::vector<u8>& in_params, std::vector<u8>& out_params,
- BehaviorInfo& behavior_info);
+ InfoUpdater(const std::vector<u8>& in_params_, std::vector<u8>& out_params_,
+ BehaviorInfo& behavior_info_);
~InfoUpdater();
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 {
ServerMemoryPoolInfo::ServerMemoryPoolInfo() = default;
ServerMemoryPoolInfo::~ServerMemoryPoolInfo() = default;
-bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_params,
- ServerMemoryPoolInfo::OutParams& out_params) {
+
+bool ServerMemoryPoolInfo::Update(const InParams& in_params, OutParams& out_params) {
// Our state does not need to be changed
- if (in_params.state != ServerMemoryPoolInfo::State::RequestAttach &&
- in_params.state != ServerMemoryPoolInfo::State::RequestDetach) {
+ if (in_params.state != State::RequestAttach && in_params.state != State::RequestDetach) {
return true;
}
@@ -32,11 +31,11 @@ bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_param
return false;
}
- if (in_params.state == ServerMemoryPoolInfo::State::RequestAttach) {
+ if (in_params.state == State::RequestAttach) {
cpu_address = in_params.address;
size = in_params.size;
used = true;
- out_params.state = ServerMemoryPoolInfo::State::Attached;
+ out_params.state = State::Attached;
} else {
// Unexpected address
if (cpu_address != in_params.address) {
@@ -54,7 +53,7 @@ bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_param
cpu_address = 0;
size = 0;
used = false;
- out_params.state = ServerMemoryPoolInfo::State::Detached;
+ out_params.state = State::Detached;
}
return true;
}
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:
struct InParams {
u64_le address{};
u64_le size{};
- ServerMemoryPoolInfo::State state{};
+ State state{};
INSERT_PADDING_WORDS(3);
};
- static_assert(sizeof(ServerMemoryPoolInfo::InParams) == 0x20, "InParams are an invalid size");
+ static_assert(sizeof(InParams) == 0x20, "InParams are an invalid size");
struct OutParams {
- ServerMemoryPoolInfo::State state{};
+ State state{};
INSERT_PADDING_WORDS(3);
};
- static_assert(sizeof(ServerMemoryPoolInfo::OutParams) == 0x10, "OutParams are an invalid size");
+ static_assert(sizeof(OutParams) == 0x10, "OutParams are an invalid size");
- bool Update(const ServerMemoryPoolInfo::InParams& in_params,
- ServerMemoryPoolInfo::OutParams& out_params);
+ bool Update(const InParams& in_params, OutParams& out_params);
private:
// 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 @@
#include "audio_core/sink_context.h"
namespace AudioCore {
-SinkContext::SinkContext(std::size_t sink_count) : sink_count(sink_count) {}
+SinkContext::SinkContext(std::size_t sink_count_) : sink_count{sink_count_} {}
SinkContext::~SinkContext() = default;
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:
bool in_use;
INSERT_UNION_PADDING_BYTES(5);
};
- static_assert(sizeof(SinkInfo::CircularBufferIn) == 0x28,
+ static_assert(sizeof(CircularBufferIn) == 0x28,
"SinkInfo::CircularBufferIn is in invalid size");
struct DeviceIn {
@@ -54,7 +54,7 @@ public:
bool down_matrix_enabled;
DownmixCoefficients down_matrix_coef;
};
- static_assert(sizeof(SinkInfo::DeviceIn) == 0x11c, "SinkInfo::DeviceIn is an invalid size");
+ static_assert(sizeof(DeviceIn) == 0x11c, "SinkInfo::DeviceIn is an invalid size");
struct InParams {
SinkTypes type{};
@@ -64,16 +64,16 @@ public:
INSERT_PADDING_WORDS(6);
union {
// std::array<u8, 0x120> raw{};
- SinkInfo::DeviceIn device;
- SinkInfo::CircularBufferIn circular_buffer;
+ DeviceIn device;
+ CircularBufferIn circular_buffer;
};
};
- static_assert(sizeof(SinkInfo::InParams) == 0x140, "SinkInfo::InParams are an invalid size!");
+ static_assert(sizeof(InParams) == 0x140, "SinkInfo::InParams are an invalid size!");
};
class SinkContext {
public:
- explicit SinkContext(std::size_t sink_count);
+ explicit SinkContext(std::size_t sink_count_);
~SinkContext();
[[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 @@
namespace AudioCore {
-ServerSplitterDestinationData::ServerSplitterDestinationData(s32 id) : id(id) {}
+ServerSplitterDestinationData::ServerSplitterDestinationData(s32 id_) : id{id_} {}
ServerSplitterDestinationData::~ServerSplitterDestinationData() = default;
void ServerSplitterDestinationData::Update(SplitterInfo::InDestinationParams& header) {
@@ -87,7 +87,7 @@ void ServerSplitterDestinationData::UpdateInternalState() {
needs_update = false;
}
-ServerSplitterInfo::ServerSplitterInfo(s32 id) : id(id) {}
+ServerSplitterInfo::ServerSplitterInfo(s32 id_) : id(id_) {}
ServerSplitterInfo::~ServerSplitterInfo() = default;
void ServerSplitterInfo::InitializeInfos() {
@@ -121,7 +121,7 @@ const ServerSplitterDestinationData* ServerSplitterInfo::GetHead() const {
}
ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) {
- auto current_head = head;
+ auto* current_head = head;
for (std::size_t i = 0; i < depth; i++) {
if (current_head == nullptr) {
return nullptr;
@@ -132,7 +132,7 @@ ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) {
}
const ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) const {
- auto current_head = head;
+ auto* current_head = head;
for (std::size_t i = 0; i < depth; i++) {
if (current_head == nullptr) {
return nullptr;
@@ -245,7 +245,7 @@ ServerSplitterDestinationData* SplitterContext::GetDestinationData(std::size_t i
const ServerSplitterDestinationData* SplitterContext::GetDestinationData(std::size_t info,
std::size_t data) const {
ASSERT(info < info_count);
- auto& cur_info = GetInfo(info);
+ const auto& cur_info = GetInfo(info);
return cur_info.GetData(data);
}
@@ -267,11 +267,11 @@ std::size_t SplitterContext::GetDataCount() const {
return data_count;
}
-void SplitterContext::Setup(std::size_t _info_count, std::size_t _data_count,
+void SplitterContext::Setup(std::size_t info_count_, std::size_t data_count_,
bool is_splitter_bug_fixed) {
- info_count = _info_count;
- data_count = _data_count;
+ info_count = info_count_;
+ data_count = data_count_;
for (std::size_t i = 0; i < info_count; i++) {
auto& splitter = infos.emplace_back(static_cast<s32>(i));
@@ -364,7 +364,7 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info,
// Clear our current destinations
auto* current_head = info.GetHead();
while (current_head != nullptr) {
- auto next_head = current_head->GetNextDestination();
+ auto* next_head = current_head->GetNextDestination();
current_head->SetNextDestination(nullptr);
current_head = next_head;
}
@@ -471,8 +471,8 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) {
continue;
}
- const auto node_count = edge_matrix.GetNodeCount();
- for (s32 j = 0; j < static_cast<s32>(node_count); j++) {
+ const auto edge_node_count = edge_matrix.GetNodeCount();
+ for (s32 j = 0; j < static_cast<s32>(edge_node_count); j++) {
// Check if our node is connected to our edge matrix
if (!edge_matrix.Connected(current_stack_index, j)) {
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:
NodeStates();
~NodeStates();
- void Initialize(std::size_t _node_count);
+ void Initialize(std::size_t node_count_);
bool Tsort(EdgeMatrix& edge_matrix);
std::size_t GetIndexPos() const;
const std::vector<s32>& GetIndexList() const;
@@ -72,15 +72,15 @@ private:
void PushTsortResult(s32 index);
bool DepthFirstSearch(EdgeMatrix& edge_matrix);
void ResetState();
- void UpdateState(NodeStates::State state, std::size_t i);
- NodeStates::State GetState(std::size_t i);
+ void UpdateState(State state, std::size_t i);
+ State GetState(std::size_t i);
std::size_t node_count{};
std::vector<bool> was_node_found{};
std::vector<bool> was_node_completed{};
std::size_t index_pos{};
std::vector<s32> index_list{};
- NodeStates::Stack index_stack{};
+ Stack index_stack{};
};
enum class SplitterMagic : u32_le {
@@ -97,8 +97,7 @@ public:
s32_le data_count{};
INSERT_PADDING_WORDS(5);
};
- static_assert(sizeof(SplitterInfo::InHeader) == 0x20,
- "SplitterInfo::InHeader is an invalid size");
+ static_assert(sizeof(InHeader) == 0x20, "SplitterInfo::InHeader is an invalid size");
struct InInfoPrams {
SplitterMagic magic{};
@@ -107,8 +106,7 @@ public:
s32_le length{};
s32_le resource_id_base{};
};
- static_assert(sizeof(SplitterInfo::InInfoPrams) == 0x14,
- "SplitterInfo::InInfoPrams is an invalid size");
+ static_assert(sizeof(InInfoPrams) == 0x14, "SplitterInfo::InInfoPrams is an invalid size");
struct InDestinationParams {
SplitterMagic magic{};
@@ -118,13 +116,13 @@ public:
bool in_use{};
INSERT_PADDING_BYTES(3);
};
- static_assert(sizeof(SplitterInfo::InDestinationParams) == 0x70,
+ static_assert(sizeof(InDestinationParams) == 0x70,
"SplitterInfo::InDestinationParams is an invalid size");
};
class ServerSplitterDestinationData {
public:
- explicit ServerSplitterDestinationData(s32 id);
+ explicit ServerSplitterDestinationData(s32 id_);
~ServerSplitterDestinationData();
void Update(SplitterInfo::InDestinationParams& header);
@@ -153,7 +151,7 @@ private:
class ServerSplitterInfo {
public:
- explicit ServerSplitterInfo(s32 id);
+ explicit ServerSplitterInfo(s32 id_);
~ServerSplitterInfo();
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 {
return {};
}
-Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format format,
- ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_)
- : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
- sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} {
+Stream::Stream(Core::Timing::CoreTiming& core_timing_, u32 sample_rate_, Format format_,
+ ReleaseCallback&& release_callback_, SinkStream& sink_stream_, std::string&& name_)
+ : sample_rate{sample_rate_}, format{format_}, release_callback{std::move(release_callback_)},
+ sink_stream{sink_stream_}, core_timing{core_timing_}, name{std::move(name_)} {
release_event =
Core::Timing::CreateEvent(name, [this](std::uintptr_t, std::chrono::nanoseconds ns_late) {
ReleaseActiveBuffer(ns_late);
@@ -122,7 +122,7 @@ bool Stream::QueueBuffer(BufferPtr&& buffer) {
return false;
}
-bool Stream::ContainsBuffer(Buffer::Tag tag) const {
+bool Stream::ContainsBuffer([[maybe_unused]] Buffer::Tag tag) const {
UNIMPLEMENTED();
return {};
}
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:
/// Callback function type, used to change guest state on a buffer being released
using ReleaseCallback = std::function<void()>;
- Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format format,
- ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_);
+ Stream(Core::Timing::CoreTiming& core_timing_, u32 sample_rate_, Format format_,
+ ReleaseCallback&& release_callback_, SinkStream& sink_stream_, std::string&& name_);
/// Plays the audio stream
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 @@
namespace AudioCore {
-ServerVoiceChannelResource::ServerVoiceChannelResource(s32 id) : id(id) {}
+ServerVoiceChannelResource::ServerVoiceChannelResource(s32 id_) : id(id_) {}
ServerVoiceChannelResource::~ServerVoiceChannelResource() = default;
bool ServerVoiceChannelResource::InUse() const {
@@ -209,7 +209,8 @@ void ServerVoiceInfo::UpdateWaveBuffers(
void ServerVoiceInfo::UpdateWaveBuffer(ServerWaveBuffer& out_wavebuffer,
const WaveBuffer& in_wave_buffer, SampleFormat sample_format,
- bool is_buffer_valid, BehaviorInfo& behavior_info) {
+ bool is_buffer_valid,
+ [[maybe_unused]] BehaviorInfo& behavior_info) {
if (!is_buffer_valid && out_wavebuffer.sent_to_dsp) {
out_wavebuffer.buffer_address = 0;
out_wavebuffer.buffer_size = 0;
@@ -400,7 +401,7 @@ bool ServerVoiceInfo::HasValidWaveBuffer(const VoiceState* state) const {
return std::find(valid_wb.begin(), valid_wb.end(), true) != valid_wb.end();
}
-VoiceContext::VoiceContext(std::size_t voice_count) : voice_count(voice_count) {
+VoiceContext::VoiceContext(std::size_t voice_count_) : voice_count{voice_count_} {
for (std::size_t i = 0; i < voice_count; i++) {
voice_channel_resources.emplace_back(static_cast<s32>(i));
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:
bool in_use{};
INSERT_PADDING_BYTES(11);
};
- static_assert(sizeof(VoiceChannelResource::InParams) == 0x70, "InParams is an invalid size");
+ static_assert(sizeof(InParams) == 0x70, "InParams is an invalid size");
};
class ServerVoiceChannelResource {
public:
- explicit ServerVoiceChannelResource(s32 id);
+ explicit ServerVoiceChannelResource(s32 id_);
~ServerVoiceChannelResource();
bool InUse() const;
@@ -174,7 +174,7 @@ public:
BehaviorFlags behavior_flags{};
INSERT_PADDING_BYTES(16);
};
- static_assert(sizeof(VoiceInfo::InParams) == 0x170, "InParams is an invalid size");
+ static_assert(sizeof(InParams) == 0x170, "InParams is an invalid size");
struct OutParams {
u64_le played_sample_count{};
@@ -182,7 +182,7 @@ public:
u8 voice_dropped{};
INSERT_PADDING_BYTES(3);
};
- static_assert(sizeof(VoiceInfo::OutParams) == 0x10, "OutParams is an invalid size");
+ static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size");
};
class ServerVoiceInfo {
@@ -263,7 +263,7 @@ private:
class VoiceContext {
public:
- VoiceContext(std::size_t voice_count);
+ explicit VoiceContext(std::size_t voice_count_);
~VoiceContext();
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
common_paths.h
common_types.h
concepts.h
+ div_ceil.h
dynamic_library.cpp
dynamic_library.h
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 @@
+// Copyright 2020 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <cstddef>
+#include <type_traits>
+
+namespace Common {
+
+/// Ceiled integer division.
+template <typename N, typename D>
+requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeil(
+ N number, D divisor) {
+ return (static_cast<D>(number) + divisor - 1) / divisor;
+}
+
+/// Ceiled integer division with logarithmic divisor in base 2
+template <typename N, typename D>
+requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeilLog2(
+ N value, D alignment_log2) {
+ return (static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2;
+}
+
+} // 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>;
class StandardWallClock final : public WallClock {
public:
- StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency)
- : WallClock(emulated_cpu_frequency, emulated_clock_frequency, false) {
+ explicit StandardWallClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_)
+ : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, false) {
start_time = base_timer::now();
}
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:
}
protected:
- WallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, bool is_native)
- : emulated_cpu_frequency{emulated_cpu_frequency},
- emulated_clock_frequency{emulated_clock_frequency}, is_native{is_native} {}
+ explicit WallClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_, bool is_native_)
+ : emulated_cpu_frequency{emulated_cpu_frequency_},
+ emulated_clock_frequency{emulated_clock_frequency_}, is_native{is_native_} {}
u64 emulated_cpu_frequency;
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() {
}
namespace X64 {
-NativeClock::NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency,
- u64 rtsc_frequency)
- : WallClock(emulated_cpu_frequency, emulated_clock_frequency, true), rtsc_frequency{
- rtsc_frequency} {
+NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_,
+ u64 rtsc_frequency_)
+ : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{
+ rtsc_frequency_} {
_mm_mfence();
last_measure = __rdtsc();
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 {
namespace X64 {
class NativeClock final : public WallClock {
public:
- NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, u64 rtsc_frequency);
+ explicit NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_,
+ u64 rtsc_frequency_);
std::chrono::nanoseconds GetTimeNS() override;
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 =
/// Contains the characteristics of a particular event.
struct EventType {
- EventType(TimedCallback&& callback, std::string&& name)
- : callback{std::move(callback)}, name{std::move(name)} {}
+ explicit EventType(TimedCallback&& callback_, std::string&& name_)
+ : callback{std::move(callback_)}, name{std::move(name_)} {}
/// The event's callback function.
TimedCallback callback;
@@ -67,8 +67,8 @@ public:
void Shutdown();
/// Sets if emulation is multicore or single core, must be set before Initialize
- void SetMulticore(bool is_multicore) {
- this->is_multicore = is_multicore;
+ void SetMulticore(bool is_multicore_) {
+ is_multicore = is_multicore_;
}
/// 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
using MotionDevice = InputDevice<MotionStatus>;
/**
- * A touch device is an input device that returns a tuple of two floats and a bool. The floats are
+ * A touch status is an object that returns a tuple of two floats and a bool. The floats are
* x and y coordinates in the range 0.0 - 1.0, and the bool indicates whether it is pressed.
*/
-using TouchDevice = InputDevice<std::tuple<float, float, bool>>;
+using TouchStatus = std::tuple<float, float, bool>;
+
+/**
+ * A touch device is an input device that returns a touch status object
+ */
+using TouchDevice = InputDevice<TouchStatus>;
/**
* 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 {
BitField<0, 9, ErrorModule> module;
BitField<9, 13, u32> description;
- constexpr explicit ResultCode(u32 raw) : raw(raw) {}
+ constexpr explicit ResultCode(u32 raw_) : raw(raw_) {}
constexpr ResultCode(ErrorModule module_, u32 description_)
: 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 {
Setting<bool> motion_enabled;
std::string motion_device;
- std::string udp_input_address;
- u16 udp_input_port;
- u8 udp_pad_index;
+ std::string udp_input_servers;
bool mouse_enabled;
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
keyboard.h
main.cpp
main.h
- motion_emu.cpp
- motion_emu.h
motion_from_button.cpp
motion_from_button.h
motion_input.cpp
@@ -19,6 +17,10 @@ add_library(input_common STATIC
gcadapter/gc_adapter.h
gcadapter/gc_poller.cpp
gcadapter/gc_poller.h
+ mouse/mouse_input.cpp
+ mouse/mouse_input.h
+ mouse/mouse_poller.cpp
+ mouse/mouse_poller.h
sdl/sdl.cpp
sdl/sdl.h
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 @@
#include "input_common/gcadapter/gc_poller.h"
#include "input_common/keyboard.h"
#include "input_common/main.h"
-#include "input_common/motion_emu.h"
#include "input_common/motion_from_button.h"
+#include "input_common/mouse/mouse_input.h"
+#include "input_common/mouse/mouse_poller.h"
#include "input_common/touch_from_button.h"
#include "input_common/udp/client.h"
#include "input_common/udp/udp.h"
@@ -37,8 +38,6 @@ struct InputSubsystem::Impl {
std::make_shared<AnalogFromButton>());
Input::RegisterFactory<Input::MotionDevice>("keyboard",
std::make_shared<MotionFromButton>());
- motion_emu = std::make_shared<MotionEmu>();
- Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu);
Input::RegisterFactory<Input::TouchDevice>("touch_from_button",
std::make_shared<TouchFromButtonFactory>());
@@ -51,6 +50,16 @@ struct InputSubsystem::Impl {
Input::RegisterFactory<Input::MotionDevice>("cemuhookudp", udpmotion);
udptouch = std::make_shared<UDPTouchFactory>(udp);
Input::RegisterFactory<Input::TouchDevice>("cemuhookudp", udptouch);
+
+ mouse = std::make_shared<MouseInput::Mouse>();
+ mousebuttons = std::make_shared<MouseButtonFactory>(mouse);
+ Input::RegisterFactory<Input::ButtonDevice>("mouse", mousebuttons);
+ mouseanalog = std::make_shared<MouseAnalogFactory>(mouse);
+ Input::RegisterFactory<Input::AnalogDevice>("mouse", mouseanalog);
+ mousemotion = std::make_shared<MouseMotionFactory>(mouse);
+ Input::RegisterFactory<Input::MotionDevice>("mouse", mousemotion);
+ mousetouch = std::make_shared<MouseTouchFactory>(mouse);
+ Input::RegisterFactory<Input::TouchDevice>("mouse", mousetouch);
}
void Shutdown() {
@@ -58,8 +67,6 @@ struct InputSubsystem::Impl {
Input::UnregisterFactory<Input::MotionDevice>("keyboard");
keyboard.reset();
Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button");
- Input::UnregisterFactory<Input::MotionDevice>("motion_emu");
- motion_emu.reset();
Input::UnregisterFactory<Input::TouchDevice>("touch_from_button");
#ifdef HAVE_SDL2
sdl.reset();
@@ -77,6 +84,16 @@ struct InputSubsystem::Impl {
udpmotion.reset();
udptouch.reset();
+
+ Input::UnregisterFactory<Input::ButtonDevice>("mouse");
+ Input::UnregisterFactory<Input::AnalogDevice>("mouse");
+ Input::UnregisterFactory<Input::MotionDevice>("mouse");
+ Input::UnregisterFactory<Input::TouchDevice>("mouse");
+
+ mousebuttons.reset();
+ mouseanalog.reset();
+ mousemotion.reset();
+ mousetouch.reset();
}
[[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const {
@@ -140,7 +157,6 @@ struct InputSubsystem::Impl {
}
std::shared_ptr<Keyboard> keyboard;
- std::shared_ptr<MotionEmu> motion_emu;
#ifdef HAVE_SDL2
std::unique_ptr<SDL::State> sdl;
#endif
@@ -149,8 +165,13 @@ struct InputSubsystem::Impl {
std::shared_ptr<GCVibrationFactory> gcvibration;
std::shared_ptr<UDPMotionFactory> udpmotion;
std::shared_ptr<UDPTouchFactory> udptouch;
+ std::shared_ptr<MouseButtonFactory> mousebuttons;
+ std::shared_ptr<MouseAnalogFactory> mouseanalog;
+ std::shared_ptr<MouseMotionFactory> mousemotion;
+ std::shared_ptr<MouseTouchFactory> mousetouch;
std::shared_ptr<CemuhookUDP::Client> udp;
std::shared_ptr<GCAdapter::Adapter> gcadapter;
+ std::shared_ptr<MouseInput::Mouse> mouse;
};
InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {}
@@ -173,12 +194,12 @@ const Keyboard* InputSubsystem::GetKeyboard() const {
return impl->keyboard.get();
}
-MotionEmu* InputSubsystem::GetMotionEmu() {
- return impl->motion_emu.get();
+MouseInput::Mouse* InputSubsystem::GetMouse() {
+ return impl->mouse.get();
}
-const MotionEmu* InputSubsystem::GetMotionEmu() const {
- return impl->motion_emu.get();
+const MouseInput::Mouse* InputSubsystem::GetMouse() const {
+ return impl->mouse.get();
}
std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
@@ -229,11 +250,43 @@ const UDPTouchFactory* InputSubsystem::GetUDPTouch() const {
return impl->udptouch.get();
}
+MouseButtonFactory* InputSubsystem::GetMouseButtons() {
+ return impl->mousebuttons.get();
+}
+
+const MouseButtonFactory* InputSubsystem::GetMouseButtons() const {
+ return impl->mousebuttons.get();
+}
+
+MouseAnalogFactory* InputSubsystem::GetMouseAnalogs() {
+ return impl->mouseanalog.get();
+}
+
+const MouseAnalogFactory* InputSubsystem::GetMouseAnalogs() const {
+ return impl->mouseanalog.get();
+}
+
+MouseMotionFactory* InputSubsystem::GetMouseMotions() {
+ return impl->mousemotion.get();
+}
+
+const MouseMotionFactory* InputSubsystem::GetMouseMotions() const {
+ return impl->mousemotion.get();
+}
+
+MouseTouchFactory* InputSubsystem::GetMouseTouch() {
+ return impl->mousetouch.get();
+}
+
+const MouseTouchFactory* InputSubsystem::GetMouseTouch() const {
+ return impl->mousetouch.get();
+}
+
void InputSubsystem::ReloadInputDevices() {
if (!impl->udp) {
return;
}
- impl->udp->ReloadUDPClient();
+ impl->udp->ReloadSockets();
}
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 {
enum Values : int;
}
+namespace MouseInput {
+class Mouse;
+}
+
namespace InputCommon {
namespace Polling {
@@ -56,8 +60,11 @@ class GCAnalogFactory;
class GCButtonFactory;
class UDPMotionFactory;
class UDPTouchFactory;
+class MouseButtonFactory;
+class MouseAnalogFactory;
+class MouseMotionFactory;
+class MouseTouchFactory;
class Keyboard;
-class MotionEmu;
/**
* Given a ParamPackage for a Device returned from `GetInputDevices`, attempt to get the default
@@ -90,11 +97,11 @@ public:
/// Retrieves the underlying keyboard device.
[[nodiscard]] const Keyboard* GetKeyboard() const;
- /// Retrieves the underlying motion emulation factory.
- [[nodiscard]] MotionEmu* GetMotionEmu();
+ /// Retrieves the underlying mouse device.
+ [[nodiscard]] MouseInput::Mouse* GetMouse();
- /// Retrieves the underlying motion emulation factory.
- [[nodiscard]] const MotionEmu* GetMotionEmu() const;
+ /// Retrieves the underlying mouse device.
+ [[nodiscard]] const MouseInput::Mouse* GetMouse() const;
/**
* Returns all available input devices that this Factory can create a new device with.
@@ -137,6 +144,30 @@ public:
/// Retrieves the underlying udp touch handler.
[[nodiscard]] const UDPTouchFactory* GetUDPTouch() const;
+ /// Retrieves the underlying GameCube button handler.
+ [[nodiscard]] MouseButtonFactory* GetMouseButtons();
+
+ /// Retrieves the underlying GameCube button handler.
+ [[nodiscard]] const MouseButtonFactory* GetMouseButtons() const;
+
+ /// Retrieves the underlying udp touch handler.
+ [[nodiscard]] MouseAnalogFactory* GetMouseAnalogs();
+
+ /// Retrieves the underlying udp touch handler.
+ [[nodiscard]] const MouseAnalogFactory* GetMouseAnalogs() const;
+
+ /// Retrieves the underlying udp motion handler.
+ [[nodiscard]] MouseMotionFactory* GetMouseMotions();
+
+ /// Retrieves the underlying udp motion handler.
+ [[nodiscard]] const MouseMotionFactory* GetMouseMotions() const;
+
+ /// Retrieves the underlying udp touch handler.
+ [[nodiscard]] MouseTouchFactory* GetMouseTouch();
+
+ /// Retrieves the underlying udp touch handler.
+ [[nodiscard]] const MouseTouchFactory* GetMouseTouch() const;
+
/// Reloads the input devices
void ReloadInputDevices();
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 @@
-// Copyright 2017 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <algorithm>
-#include <chrono>
-#include <mutex>
-#include <thread>
-#include <tuple>
-#include "common/math_util.h"
-#include "common/quaternion.h"
-#include "common/thread.h"
-#include "common/vector_math.h"
-#include "input_common/motion_emu.h"
-
-namespace InputCommon {
-
-// Implementation class of the motion emulation device
-class MotionEmuDevice {
-public:
- explicit MotionEmuDevice(int update_millisecond_, float sensitivity_)
- : update_millisecond(update_millisecond_),
- update_duration(std::chrono::duration_cast<std::chrono::steady_clock::duration>(
- std::chrono::milliseconds(update_millisecond))),
- sensitivity(sensitivity_), motion_emu_thread(&MotionEmuDevice::MotionEmuThread, this) {}
-
- ~MotionEmuDevice() {
- if (motion_emu_thread.joinable()) {
- shutdown_event.Set();
- motion_emu_thread.join();
- }
- }
-
- void BeginTilt(int x, int y) {
- mouse_origin = Common::MakeVec(x, y);
- is_tilting = true;
- }
-
- void Tilt(int x, int y) {
- if (!is_tilting) {
- return;
- }
-
- std::lock_guard guard{tilt_mutex};
- const auto mouse_move = Common::MakeVec(x, y) - mouse_origin;
- if (mouse_move.x == 0 && mouse_move.y == 0) {
- tilt_angle = 0;
- } else {
- tilt_direction = mouse_move.Cast<float>();
- tilt_angle =
- std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f, Common::PI * 0.5f);
- }
- }
-
- void EndTilt() {
- std::lock_guard guard{tilt_mutex};
- tilt_angle = 0;
- is_tilting = false;
- }
-
- Input::MotionStatus GetStatus() {
- std::lock_guard guard{status_mutex};
- return status;
- }
-
-private:
- const int update_millisecond;
- const std::chrono::steady_clock::duration update_duration;
- const float sensitivity;
-
- Common::Vec2<int> mouse_origin;
-
- std::mutex tilt_mutex;
- Common::Vec2<float> tilt_direction;
- float tilt_angle = 0;
-
- bool is_tilting = false;
-
- Common::Event shutdown_event;
-
- Input::MotionStatus status;
- std::mutex status_mutex;
-
- // Note: always keep the thread declaration at the end so that other objects are initialized
- // before this!
- std::thread motion_emu_thread;
-
- void MotionEmuThread() {
- auto update_time = std::chrono::steady_clock::now();
- Common::Quaternion<float> q = Common::MakeQuaternion(Common::Vec3<float>(), 0);
-
- while (!shutdown_event.WaitUntil(update_time)) {
- update_time += update_duration;
- const Common::Quaternion<float> old_q = q;
-
- {
- std::lock_guard guard{tilt_mutex};
-
- // Find the quaternion describing current 3DS tilting
- q = Common::MakeQuaternion(
- Common::MakeVec(-tilt_direction.y, 0.0f, tilt_direction.x), tilt_angle);
- }
-
- const auto inv_q = q.Inverse();
-
- // Set the gravity vector in world space
- auto gravity = Common::MakeVec(0.0f, -1.0f, 0.0f);
-
- // Find the angular rate vector in world space
- auto angular_rate = ((q - old_q) * inv_q).xyz * 2;
- angular_rate *= static_cast<float>(1000 / update_millisecond) / Common::PI * 180.0f;
-
- // Transform the two vectors from world space to 3DS space
- gravity = QuaternionRotate(inv_q, gravity);
- angular_rate = QuaternionRotate(inv_q, angular_rate);
-
- // TODO: Calculate the correct rotation vector and orientation matrix
- const auto matrix4x4 = q.ToMatrix();
- const auto rotation = Common::MakeVec(0.0f, 0.0f, 0.0f);
- const std::array orientation{
- Common::Vec3f(matrix4x4[0], matrix4x4[1], -matrix4x4[2]),
- Common::Vec3f(matrix4x4[4], matrix4x4[5], -matrix4x4[6]),
- Common::Vec3f(-matrix4x4[8], -matrix4x4[9], matrix4x4[10]),
- };
-
- // Update the sensor state
- {
- std::lock_guard guard{status_mutex};
- status = std::make_tuple(gravity, angular_rate, rotation, orientation);
- }
- }
- }
-};
-
-// Interface wrapper held by input receiver as a unique_ptr. It holds the implementation class as
-// a shared_ptr, which is also observed by the factory class as a weak_ptr. In this way the factory
-// can forward all the inputs to the implementation only when it is valid.
-class MotionEmuDeviceWrapper : public Input::MotionDevice {
-public:
- explicit MotionEmuDeviceWrapper(int update_millisecond, float sensitivity) {
- device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity);
- }
-
- Input::MotionStatus GetStatus() const override {
- return device->GetStatus();
- }
-
- std::shared_ptr<MotionEmuDevice> device;
-};
-
-std::unique_ptr<Input::MotionDevice> MotionEmu::Create(const Common::ParamPackage& params) {
- const int update_period = params.Get("update_period", 100);
- const float sensitivity = params.Get("sensitivity", 0.01f);
- auto device_wrapper = std::make_unique<MotionEmuDeviceWrapper>(update_period, sensitivity);
- // Previously created device is disconnected here. Having two motion devices for 3DS is not
- // expected.
- current_device = device_wrapper->device;
- return device_wrapper;
-}
-
-void MotionEmu::BeginTilt(int x, int y) {
- if (auto ptr = current_device.lock()) {
- ptr->BeginTilt(x, y);
- }
-}
-
-void MotionEmu::Tilt(int x, int y) {
- if (auto ptr = current_device.lock()) {
- ptr->Tilt(x, y);
- }
-}
-
-void MotionEmu::EndTilt() {
- if (auto ptr = current_device.lock()) {
- ptr->EndTilt();
- }
-}
-
-} // 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 @@
-// Copyright 2017 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include "core/frontend/input.h"
-
-namespace InputCommon {
-
-class MotionEmuDevice;
-
-class MotionEmu : public Input::Factory<Input::MotionDevice> {
-public:
- /**
- * Creates a motion device emulated from mouse input
- * @param params contains parameters for creating the device:
- * - "update_period": update period in milliseconds
- * - "sensitivity": the coefficient converting mouse movement to tilting angle
- */
- std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override;
-
- /**
- * Signals that a motion sensor tilt has begun.
- * @param x the x-coordinate of the cursor
- * @param y the y-coordinate of the cursor
- */
- void BeginTilt(int x, int y);
-
- /**
- * Signals that a motion sensor tilt is occurring.
- * @param x the x-coordinate of the cursor
- * @param y the y-coordinate of the cursor
- */
- void Tilt(int x, int y);
-
- /**
- * Signals that a motion sensor tilt has ended.
- */
- void EndTilt();
-
-private:
- std::weak_ptr<MotionEmuDevice> current_device;
-};
-
-} // 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 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "input_common/mouse/mouse_input.h"
+
+namespace MouseInput {
+
+Mouse::Mouse() {
+ update_thread = std::thread(&Mouse::UpdateThread, this);
+}
+
+Mouse::~Mouse() {
+ update_thread_running = false;
+ if (update_thread.joinable()) {
+ update_thread.join();
+ }
+}
+
+void Mouse::UpdateThread() {
+ constexpr int update_time = 10;
+ while (update_thread_running) {
+ for (MouseInfo& info : mouse_info) {
+ const Common::Vec3f angular_direction{
+ -info.tilt_direction.y,
+ 0.0f,
+ -info.tilt_direction.x,
+ };
+
+ info.motion.SetGyroscope(angular_direction * info.tilt_speed);
+ info.motion.UpdateRotation(update_time * 1000);
+ info.motion.UpdateOrientation(update_time * 1000);
+ info.tilt_speed = 0;
+ info.data.motion = info.motion.GetMotion();
+ }
+ if (configuring) {
+ UpdateYuzuSettings();
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(update_time));
+ }
+}
+
+void Mouse::UpdateYuzuSettings() {
+ if (buttons == 0) {
+ return;
+ }
+
+ mouse_queue.Push(MouseStatus{
+ .button = last_button,
+ });
+}
+
+void Mouse::PressButton(int x, int y, int button_) {
+ const auto button_index = static_cast<std::size_t>(button_);
+ if (button_index >= mouse_info.size()) {
+ return;
+ }
+
+ const auto button = 1U << button_index;
+ buttons |= static_cast<u16>(button);
+ last_button = static_cast<MouseButton>(button_index);
+
+ mouse_info[button_index].mouse_origin = Common::MakeVec(x, y);
+ mouse_info[button_index].last_mouse_position = Common::MakeVec(x, y);
+ mouse_info[button_index].data.pressed = true;
+}
+
+void Mouse::MouseMove(int x, int y) {
+ for (MouseInfo& info : mouse_info) {
+ if (info.data.pressed) {
+ const auto mouse_move = Common::MakeVec(x, y) - info.mouse_origin;
+ const auto mouse_change = Common::MakeVec(x, y) - info.last_mouse_position;
+ info.last_mouse_position = Common::MakeVec(x, y);
+ info.data.axis = {mouse_move.x, -mouse_move.y};
+
+ if (mouse_change.x == 0 && mouse_change.y == 0) {
+ info.tilt_speed = 0;
+ } else {
+ info.tilt_direction = mouse_change.Cast<float>();
+ info.tilt_speed = info.tilt_direction.Normalize() * info.sensitivity;
+ }
+ }
+ }
+}
+
+void Mouse::ReleaseButton(int button_) {
+ const auto button_index = static_cast<std::size_t>(button_);
+ if (button_index >= mouse_info.size()) {
+ return;
+ }
+
+ const auto button = 1U << button_index;
+ buttons &= static_cast<u16>(0xFF - button);
+
+ mouse_info[button_index].tilt_speed = 0;
+ mouse_info[button_index].data.pressed = false;
+ mouse_info[button_index].data.axis = {0, 0};
+}
+
+void Mouse::BeginConfiguration() {
+ buttons = 0;
+ last_button = MouseButton::Undefined;
+ mouse_queue.Clear();
+ configuring = true;
+}
+
+void Mouse::EndConfiguration() {
+ buttons = 0;
+ last_button = MouseButton::Undefined;
+ mouse_queue.Clear();
+ configuring = false;
+}
+
+Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() {
+ return mouse_queue;
+}
+
+const Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() const {
+ return mouse_queue;
+}
+
+MouseData& Mouse::GetMouseState(std::size_t button) {
+ return mouse_info[button].data;
+}
+
+const MouseData& Mouse::GetMouseState(std::size_t button) const {
+ return mouse_info[button].data;
+}
+} // 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 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <mutex>
+#include <thread>
+
+#include "common/common_types.h"
+#include "common/threadsafe_queue.h"
+#include "common/vector_math.h"
+#include "core/frontend/input.h"
+#include "input_common/motion_input.h"
+
+namespace MouseInput {
+
+enum class MouseButton {
+ Left,
+ Wheel,
+ Right,
+ Foward,
+ Backward,
+ Undefined,
+};
+
+struct MouseStatus {
+ MouseButton button{MouseButton::Undefined};
+};
+
+struct MouseData {
+ bool pressed{};
+ std::array<int, 2> axis{};
+ Input::MotionStatus motion{};
+ Input::TouchStatus touch{};
+};
+
+class Mouse {
+public:
+ Mouse();
+ ~Mouse();
+
+ /// Used for polling
+ void BeginConfiguration();
+ void EndConfiguration();
+
+ /**
+ * Signals that a button is pressed.
+ * @param x the x-coordinate of the cursor
+ * @param y the y-coordinate of the cursor
+ * @param button_ the button pressed
+ */
+ void PressButton(int x, int y, int button_);
+
+ /**
+ * Signals that mouse has moved.
+ * @param x the x-coordinate of the cursor
+ * @param y the y-coordinate of the cursor
+ */
+ void MouseMove(int x, int y);
+
+ /**
+ * Signals that a motion sensor tilt has ended.
+ */
+ void ReleaseButton(int button_);
+
+ [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue();
+ [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const;
+
+ [[nodiscard]] MouseData& GetMouseState(std::size_t button);
+ [[nodiscard]] const MouseData& GetMouseState(std::size_t button) const;
+
+private:
+ void UpdateThread();
+ void UpdateYuzuSettings();
+
+ struct MouseInfo {
+ InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f};
+ Common::Vec2<int> mouse_origin;
+ Common::Vec2<int> last_mouse_position;
+ bool is_tilting = false;
+ float sensitivity{0.120f};
+
+ float tilt_speed = 0;
+ Common::Vec2<float> tilt_direction;
+ MouseData data;
+ };
+
+ u16 buttons{};
+ std::thread update_thread;
+ MouseButton last_button{MouseButton::Undefined};
+ std::array<MouseInfo, 5> mouse_info;
+ Common::SPSCQueue<MouseStatus> mouse_queue;
+ bool configuring{false};
+ bool update_thread_running{true};
+};
+} // 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 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <mutex>
+#include <utility>
+
+#include "common/threadsafe_queue.h"
+#include "input_common/mouse/mouse_input.h"
+#include "input_common/mouse/mouse_poller.h"
+
+namespace InputCommon {
+
+class MouseButton final : public Input::ButtonDevice {
+public:
+ explicit MouseButton(u32 button_, const MouseInput::Mouse* mouse_input_)
+ : button(button_), mouse_input(mouse_input_) {}
+
+ bool GetStatus() const override {
+ return mouse_input->GetMouseState(button).pressed;
+ }
+
+private:
+ const u32 button;
+ const MouseInput::Mouse* mouse_input;
+};
+
+MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
+ : mouse_input(std::move(mouse_input_)) {}
+
+std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create(
+ const Common::ParamPackage& params) {
+ const auto button_id = params.Get("button", 0);
+
+ return std::make_unique<MouseButton>(button_id, mouse_input.get());
+}
+
+Common::ParamPackage MouseButtonFactory::GetNextInput() const {
+ MouseInput::MouseStatus pad;
+ Common::ParamPackage params;
+ auto& queue = mouse_input->GetMouseQueue();
+ while (queue.Pop(pad)) {
+ // This while loop will break on the earliest detected button
+ if (pad.button != MouseInput::MouseButton::Undefined) {
+ params.Set("engine", "mouse");
+ params.Set("button", static_cast<u16>(pad.button));
+ return params;
+ }
+ }
+ return params;
+}
+
+void MouseButtonFactory::BeginConfiguration() {
+ polling = true;
+ mouse_input->BeginConfiguration();
+}
+
+void MouseButtonFactory::EndConfiguration() {
+ polling = false;
+ mouse_input->EndConfiguration();
+}
+
+class MouseAnalog final : public Input::AnalogDevice {
+public:
+ explicit MouseAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_, float range_,
+ const MouseInput::Mouse* mouse_input_)
+ : button(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), range(range_),
+ mouse_input(mouse_input_) {}
+
+ float GetAxis(u32 axis) const {
+ std::lock_guard lock{mutex};
+ const auto axis_value =
+ static_cast<float>(mouse_input->GetMouseState(button).axis.at(axis));
+ return axis_value / (100.0f * range);
+ }
+
+ std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const {
+ float x = GetAxis(analog_axis_x);
+ float y = GetAxis(analog_axis_y);
+
+ // Make sure the coordinates are in the unit circle,
+ // otherwise normalize it.
+ float r = x * x + y * y;
+ if (r > 1.0f) {
+ r = std::sqrt(r);
+ x /= r;
+ y /= r;
+ }
+
+ return {x, y};
+ }
+
+ std::tuple<float, float> GetStatus() const override {
+ const auto [x, y] = GetAnalog(axis_x, axis_y);
+ const float r = std::sqrt((x * x) + (y * y));
+ if (r > deadzone) {
+ return {x / r * (r - deadzone) / (1 - deadzone),
+ y / r * (r - deadzone) / (1 - deadzone)};
+ }
+ return {0.0f, 0.0f};
+ }
+
+private:
+ const u32 button;
+ const u32 axis_x;
+ const u32 axis_y;
+ const float deadzone;
+ const float range;
+ const MouseInput::Mouse* mouse_input;
+ mutable std::mutex mutex;
+};
+
+/// An analog device factory that creates analog devices from GC Adapter
+MouseAnalogFactory::MouseAnalogFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
+ : mouse_input(std::move(mouse_input_)) {}
+
+/**
+ * Creates analog device from joystick axes
+ * @param params contains parameters for creating the device:
+ * - "port": the nth gcpad on the adapter
+ * - "axis_x": the index of the axis to be bind as x-axis
+ * - "axis_y": the index of the axis to be bind as y-axis
+ */
+std::unique_ptr<Input::AnalogDevice> MouseAnalogFactory::Create(
+ const Common::ParamPackage& params) {
+ const auto port = static_cast<u32>(params.Get("port", 0));
+ const auto axis_x = static_cast<u32>(params.Get("axis_x", 0));
+ const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
+ const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
+ const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
+
+ return std::make_unique<MouseAnalog>(port, axis_x, axis_y, deadzone, range, mouse_input.get());
+}
+
+void MouseAnalogFactory::BeginConfiguration() {
+ polling = true;
+ mouse_input->BeginConfiguration();
+}
+
+void MouseAnalogFactory::EndConfiguration() {
+ polling = false;
+ mouse_input->EndConfiguration();
+}
+
+Common::ParamPackage MouseAnalogFactory::GetNextInput() const {
+ MouseInput::MouseStatus pad;
+ Common::ParamPackage params;
+ auto& queue = mouse_input->GetMouseQueue();
+ while (queue.Pop(pad)) {
+ // This while loop will break on the earliest detected button
+ if (pad.button != MouseInput::MouseButton::Undefined) {
+ params.Set("engine", "mouse");
+ params.Set("port", static_cast<u16>(pad.button));
+ params.Set("axis_x", 0);
+ params.Set("axis_y", 1);
+ return params;
+ }
+ }
+ return params;
+}
+
+class MouseMotion final : public Input::MotionDevice {
+public:
+ explicit MouseMotion(u32 button_, const MouseInput::Mouse* mouse_input_)
+ : button(button_), mouse_input(mouse_input_) {}
+
+ Input::MotionStatus GetStatus() const override {
+ return mouse_input->GetMouseState(button).motion;
+ }
+
+private:
+ const u32 button;
+ const MouseInput::Mouse* mouse_input;
+};
+
+MouseMotionFactory::MouseMotionFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
+ : mouse_input(std::move(mouse_input_)) {}
+
+std::unique_ptr<Input::MotionDevice> MouseMotionFactory::Create(
+ const Common::ParamPackage& params) {
+ const auto button_id = params.Get("button", 0);
+
+ return std::make_unique<MouseMotion>(button_id, mouse_input.get());
+}
+
+Common::ParamPackage MouseMotionFactory::GetNextInput() const {
+ MouseInput::MouseStatus pad;
+ Common::ParamPackage params;
+ auto& queue = mouse_input->GetMouseQueue();
+ while (queue.Pop(pad)) {
+ // This while loop will break on the earliest detected button
+ if (pad.button != MouseInput::MouseButton::Undefined) {
+ params.Set("engine", "mouse");
+ params.Set("button", static_cast<u16>(pad.button));
+ return params;
+ }
+ }
+ return params;
+}
+
+void MouseMotionFactory::BeginConfiguration() {
+ polling = true;
+ mouse_input->BeginConfiguration();
+}
+
+void MouseMotionFactory::EndConfiguration() {
+ polling = false;
+ mouse_input->EndConfiguration();
+}
+
+class MouseTouch final : public Input::TouchDevice {
+public:
+ explicit MouseTouch(u32 button_, const MouseInput::Mouse* mouse_input_)
+ : button(button_), mouse_input(mouse_input_) {}
+
+ Input::TouchStatus GetStatus() const override {
+ return mouse_input->GetMouseState(button).touch;
+ }
+
+private:
+ const u32 button;
+ const MouseInput::Mouse* mouse_input;
+};
+
+MouseTouchFactory::MouseTouchFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
+ : mouse_input(std::move(mouse_input_)) {}
+
+std::unique_ptr<Input::TouchDevice> MouseTouchFactory::Create(const Common::ParamPackage& params) {
+ const auto button_id = params.Get("button", 0);
+
+ return std::make_unique<MouseTouch>(button_id, mouse_input.get());
+}
+
+Common::ParamPackage MouseTouchFactory::GetNextInput() const {
+ MouseInput::MouseStatus pad;
+ Common::ParamPackage params;
+ auto& queue = mouse_input->GetMouseQueue();
+ while (queue.Pop(pad)) {
+ // This while loop will break on the earliest detected button
+ if (pad.button != MouseInput::MouseButton::Undefined) {
+ params.Set("engine", "mouse");
+ params.Set("button", static_cast<u16>(pad.button));
+ return params;
+ }
+ }
+ return params;
+}
+
+void MouseTouchFactory::BeginConfiguration() {
+ polling = true;
+ mouse_input->BeginConfiguration();
+}
+
+void MouseTouchFactory::EndConfiguration() {
+ polling = false;
+ mouse_input->EndConfiguration();
+}
+
+} // 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 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include "core/frontend/input.h"
+#include "input_common/mouse/mouse_input.h"
+
+namespace InputCommon {
+
+/**
+ * A button device factory representing a mouse. It receives mouse events and forward them
+ * to all button devices it created.
+ */
+class MouseButtonFactory final : public Input::Factory<Input::ButtonDevice> {
+public:
+ explicit MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
+
+ /**
+ * Creates a button device from a button press
+ * @param params contains parameters for creating the device:
+ * - "code": the code of the key to bind with the button
+ */
+ std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override;
+
+ Common::ParamPackage GetNextInput() const;
+
+ /// For device input configuration/polling
+ void BeginConfiguration();
+ void EndConfiguration();
+
+ bool IsPolling() const {
+ return polling;
+ }
+
+private:
+ std::shared_ptr<MouseInput::Mouse> mouse_input;
+ bool polling = false;
+};
+
+/// An analog device factory that creates analog devices from mouse
+class MouseAnalogFactory final : public Input::Factory<Input::AnalogDevice> {
+public:
+ explicit MouseAnalogFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
+
+ std::unique_ptr<Input::AnalogDevice> Create(const Common::ParamPackage& params) override;
+
+ Common::ParamPackage GetNextInput() const;
+
+ /// For device input configuration/polling
+ void BeginConfiguration();
+ void EndConfiguration();
+
+ bool IsPolling() const {
+ return polling;
+ }
+
+private:
+ std::shared_ptr<MouseInput::Mouse> mouse_input;
+ bool polling = false;
+};
+
+/// A motion device factory that creates motion devices from mouse
+class MouseMotionFactory final : public Input::Factory<Input::MotionDevice> {
+public:
+ explicit MouseMotionFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
+
+ std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override;
+
+ Common::ParamPackage GetNextInput() const;
+
+ /// For device input configuration/polling
+ void BeginConfiguration();
+ void EndConfiguration();
+
+ bool IsPolling() const {
+ return polling;
+ }
+
+private:
+ std::shared_ptr<MouseInput::Mouse> mouse_input;
+ bool polling = false;
+};
+
+/// An touch device factory that creates touch devices from mouse
+class MouseTouchFactory final : public Input::Factory<Input::TouchDevice> {
+public:
+ explicit MouseTouchFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
+
+ std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage& params) override;
+
+ Common::ParamPackage GetNextInput() const;
+
+ /// For device input configuration/polling
+ void BeginConfiguration();
+ void EndConfiguration();
+
+ bool IsPolling() const {
+ return polling;
+ }
+
+private:
+ std::shared_ptr<MouseInput::Mouse> mouse_input;
+ bool polling = false;
+};
+
+} // 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) {
Client::Client() {
LOG_INFO(Input, "Udp Initialization started");
- for (std::size_t client = 0; client < clients.size(); client++) {
- const auto pad = client % 4;
- StartCommunication(client, Settings::values.udp_input_address,
- Settings::values.udp_input_port, pad, 24872);
- // Set motion parameters
- // SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode
- // Real HW values are unknown, 0.0001 is an approximate to Standard
- clients[client].motion.SetGyroThreshold(0.0001f);
- }
+ ReloadSockets();
}
Client::~Client() {
@@ -167,26 +159,61 @@ std::vector<Common::ParamPackage> Client::GetInputDevices() const {
return devices;
}
-bool Client::DeviceConnected(std::size_t pad) const {
+bool Client::DeviceConnected(std::size_t client) const {
// Use last timestamp to detect if the socket has stopped sending data
- const auto now = std::chrono::system_clock::now();
- const auto time_difference = static_cast<u64>(
- std::chrono::duration_cast<std::chrono::milliseconds>(now - clients[pad].last_motion_update)
- .count());
- return time_difference < 1000 && clients[pad].active == 1;
+ const auto now = std::chrono::steady_clock::now();
+ const auto time_difference =
+ static_cast<u64>(std::chrono::duration_cast<std::chrono::milliseconds>(
+ now - clients[client].last_motion_update)
+ .count());
+ return time_difference < 1000 && clients[client].active == 1;
}
-void Client::ReloadUDPClient() {
- for (std::size_t client = 0; client < clients.size(); client++) {
- ReloadSocket(Settings::values.udp_input_address, Settings::values.udp_input_port, client);
+void Client::ReloadSockets() {
+ Reset();
+
+ std::stringstream servers_ss(Settings::values.udp_input_servers);
+ std::string server_token;
+ std::size_t client = 0;
+ while (std::getline(servers_ss, server_token, ',')) {
+ if (client == max_udp_clients) {
+ break;
+ }
+ std::stringstream server_ss(server_token);
+ std::string token;
+ std::getline(server_ss, token, ':');
+ std::string udp_input_address = token;
+ std::getline(server_ss, token, ':');
+ char* temp;
+ const u16 udp_input_port = static_cast<u16>(std::strtol(token.c_str(), &temp, 0));
+ if (*temp != '\0') {
+ LOG_ERROR(Input, "Port number is not valid {}", token);
+ continue;
+ }
+
+ for (std::size_t pad = 0; pad < 4; ++pad) {
+ const std::size_t client_number =
+ GetClientNumber(udp_input_address, udp_input_port, pad);
+ if (client_number != max_udp_clients) {
+ LOG_ERROR(Input, "Duplicated UDP servers found");
+ continue;
+ }
+ StartCommunication(client++, udp_input_address, udp_input_port, pad, 24872);
+ }
}
}
-void Client::ReloadSocket(const std::string& host, u16 port, std::size_t pad_index, u32 client_id) {
- // client number must be determined from host / port and pad index
- const std::size_t client = pad_index;
- clients[client].socket->Stop();
- clients[client].thread.join();
- StartCommunication(client, host, port, pad_index, client_id);
+
+std::size_t Client::GetClientNumber(std::string_view host, u16 port, std::size_t pad) const {
+ for (std::size_t client = 0; client < clients.size(); client++) {
+ if (clients[client].active == -1) {
+ continue;
+ }
+ if (clients[client].host == host && clients[client].port == port &&
+ clients[client].pad_index == pad) {
+ return client;
+ }
+ }
+ return max_udp_clients;
}
void Client::OnVersion([[maybe_unused]] Response::Version data) {
@@ -197,9 +224,7 @@ void Client::OnPortInfo([[maybe_unused]] Response::PortInfo data) {
LOG_TRACE(Input, "PortInfo packet received: {}", data.model);
}
-void Client::OnPadData(Response::PadData data) {
- // Client number must be determined from host / port and pad index
- const std::size_t client = data.info.id;
+void Client::OnPadData(Response::PadData data, std::size_t client) {
LOG_TRACE(Input, "PadData packet received");
if (data.packet_counter == clients[client].packet_sequence) {
LOG_WARNING(
@@ -208,9 +233,9 @@ void Client::OnPadData(Response::PadData data) {
clients[client].packet_sequence, data.packet_counter);
return;
}
- clients[client].active = data.info.is_pad_active;
+ clients[client].active = static_cast<s8>(data.info.is_pad_active);
clients[client].packet_sequence = data.packet_counter;
- const auto now = std::chrono::system_clock::now();
+ const auto now = std::chrono::steady_clock::now();
const auto time_difference =
static_cast<u64>(std::chrono::duration_cast<std::chrono::microseconds>(
now - clients[client].last_motion_update)
@@ -264,16 +289,28 @@ void Client::StartCommunication(std::size_t client, const std::string& host, u16
std::size_t pad_index, u32 client_id) {
SocketCallback callback{[this](Response::Version version) { OnVersion(version); },
[this](Response::PortInfo info) { OnPortInfo(info); },
- [this](Response::PadData data) { OnPadData(data); }};
- LOG_INFO(Input, "Starting communication with UDP input server on {}:{}", host, port);
+ [this, client](Response::PadData data) { OnPadData(data, client); }};
+ LOG_INFO(Input, "Starting communication with UDP input server on {}:{}:{}", host, port,
+ pad_index);
+ clients[client].host = host;
+ clients[client].port = port;
+ clients[client].pad_index = pad_index;
+ clients[client].active = 0;
clients[client].socket = std::make_unique<Socket>(host, port, pad_index, client_id, callback);
clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()};
+ // Set motion parameters
+ // SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode
+ // Real HW values are unknown, 0.0001 is an approximate to Standard
+ clients[client].motion.SetGyroThreshold(0.0001f);
}
void Client::Reset() {
for (auto& client : clients) {
- client.socket->Stop();
- client.thread.join();
+ if (client.thread.joinable()) {
+ client.active = -1;
+ client.socket->Stop();
+ client.thread.join();
+ }
}
}
@@ -283,52 +320,60 @@ void Client::UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& a
LOG_DEBUG(Input, "UDP Controller {}: gyro=({}, {}, {}), accel=({}, {}, {}), touch={}",
client, gyro[0], gyro[1], gyro[2], acc[0], acc[1], acc[2], touch);
}
- UDPPadStatus pad;
+ UDPPadStatus pad{
+ .host = clients[client].host,
+ .port = clients[client].port,
+ .pad_index = clients[client].pad_index,
+ };
if (touch) {
pad.touch = PadTouch::Click;
- pad_queue[client].Push(pad);
+ pad_queue.Push(pad);
}
for (size_t i = 0; i < 3; ++i) {
if (gyro[i] > 5.0f || gyro[i] < -5.0f) {
pad.motion = static_cast<PadMotion>(i);
pad.motion_value = gyro[i];
- pad_queue[client].Push(pad);
+ pad_queue.Push(pad);
}
if (acc[i] > 1.75f || acc[i] < -1.75f) {
pad.motion = static_cast<PadMotion>(i + 3);
pad.motion_value = acc[i];
- pad_queue[client].Push(pad);
+ pad_queue.Push(pad);
}
}
}
void Client::BeginConfiguration() {
- for (auto& pq : pad_queue) {
- pq.Clear();
- }
+ pad_queue.Clear();
configuring = true;
}
void Client::EndConfiguration() {
- for (auto& pq : pad_queue) {
- pq.Clear();
- }
+ pad_queue.Clear();
configuring = false;
}
-DeviceStatus& Client::GetPadState(std::size_t pad) {
- return clients[pad].status;
+DeviceStatus& Client::GetPadState(const std::string& host, u16 port, std::size_t pad) {
+ const std::size_t client_number = GetClientNumber(host, port, pad);
+ if (client_number == max_udp_clients) {
+ return clients[0].status;
+ }
+ return clients[client_number].status;
}
-const DeviceStatus& Client::GetPadState(std::size_t pad) const {
- return clients[pad].status;
+const DeviceStatus& Client::GetPadState(const std::string& host, u16 port, std::size_t pad) const {
+ const std::size_t client_number = GetClientNumber(host, port, pad);
+ if (client_number == max_udp_clients) {
+ return clients[0].status;
+ }
+ return clients[client_number].status;
}
-std::array<Common::SPSCQueue<UDPPadStatus>, 4>& Client::GetPadQueue() {
+Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() {
return pad_queue;
}
-const std::array<Common::SPSCQueue<UDPPadStatus>, 4>& Client::GetPadQueue() const {
+const Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() const {
return pad_queue;
}
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 @@
namespace InputCommon::CemuhookUDP {
-constexpr u16 DEFAULT_PORT = 26760;
-constexpr char DEFAULT_ADDR[] = "127.0.0.1";
+constexpr char DEFAULT_SRV[] = "127.0.0.1:26760";
class Socket;
@@ -48,6 +47,9 @@ enum class PadTouch {
};
struct UDPPadStatus {
+ std::string host{"127.0.0.1"};
+ u16 port{26760};
+ std::size_t pad_index{};
PadTouch touch{PadTouch::Undefined};
PadMotion motion{PadMotion::Undefined};
f32 motion_value{0.0f};
@@ -82,37 +84,41 @@ public:
std::vector<Common::ParamPackage> GetInputDevices() const;
- bool DeviceConnected(std::size_t pad) const;
- void ReloadUDPClient();
- void ReloadSocket(const std::string& host = "127.0.0.1", u16 port = 26760,
- std::size_t pad_index = 0, u32 client_id = 24872);
+ bool DeviceConnected(std::size_t client) const;
+ void ReloadSockets();
- std::array<Common::SPSCQueue<UDPPadStatus>, 4>& GetPadQueue();
- const std::array<Common::SPSCQueue<UDPPadStatus>, 4>& GetPadQueue() const;
+ Common::SPSCQueue<UDPPadStatus>& GetPadQueue();
+ const Common::SPSCQueue<UDPPadStatus>& GetPadQueue() const;
- DeviceStatus& GetPadState(std::size_t pad);
- const DeviceStatus& GetPadState(std::size_t pad) const;
+ DeviceStatus& GetPadState(const std::string& host, u16 port, std::size_t pad);
+ const DeviceStatus& GetPadState(const std::string& host, u16 port, std::size_t pad) const;
private:
struct ClientData {
+ std::string host{"127.0.0.1"};
+ u16 port{26760};
+ std::size_t pad_index{};
std::unique_ptr<Socket> socket;
DeviceStatus status;
std::thread thread;
- u64 packet_sequence = 0;
- u8 active = 0;
+ u64 packet_sequence{};
+ s8 active{-1};
// Realtime values
// motion is initalized with PID values for drift correction on joycons
InputCommon::MotionInput motion{0.3f, 0.005f, 0.0f};
- std::chrono::time_point<std::chrono::system_clock> last_motion_update;
+ std::chrono::time_point<std::chrono::steady_clock> last_motion_update;
};
// For shutting down, clear all data, join all threads, release usb
void Reset();
+ // Translates configuration to client number
+ std::size_t GetClientNumber(std::string_view host, u16 port, std::size_t pad) const;
+
void OnVersion(Response::Version);
void OnPortInfo(Response::PortInfo);
- void OnPadData(Response::PadData);
+ void OnPadData(Response::PadData, std::size_t client);
void StartCommunication(std::size_t client, const std::string& host, u16 port,
std::size_t pad_index, u32 client_id);
void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc,
@@ -120,8 +126,10 @@ private:
bool configuring = false;
- std::array<ClientData, 4> clients;
- std::array<Common::SPSCQueue<UDPPadStatus>, 4> pad_queue;
+ // Allocate clients for 8 udp servers
+ const std::size_t max_udp_clients = 32;
+ std::array<ClientData, 4 * 8> clients;
+ Common::SPSCQueue<UDPPadStatus> pad_queue;
};
/// 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 {
class UDPMotion final : public Input::MotionDevice {
public:
- explicit UDPMotion(std::string ip_, int port_, u32 pad_, CemuhookUDP::Client* client_)
+ explicit UDPMotion(std::string ip_, u16 port_, u16 pad_, CemuhookUDP::Client* client_)
: ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {}
Input::MotionStatus GetStatus() const override {
- return client->GetPadState(pad).motion_status;
+ return client->GetPadState(ip, port, pad).motion_status;
}
private:
const std::string ip;
- const int port;
- const u32 pad;
+ const u16 port;
+ const u16 pad;
CemuhookUDP::Client* client;
mutable std::mutex mutex;
};
@@ -39,8 +39,8 @@ UDPMotionFactory::UDPMotionFactory(std::shared_ptr<CemuhookUDP::Client> client_)
*/
std::unique_ptr<Input::MotionDevice> UDPMotionFactory::Create(const Common::ParamPackage& params) {
auto ip = params.Get("ip", "127.0.0.1");
- const auto port = params.Get("port", 26760);
- const auto pad = static_cast<u32>(params.Get("pad_index", 0));
+ const auto port = static_cast<u16>(params.Get("port", 26760));
+ const auto pad = static_cast<u16>(params.Get("pad_index", 0));
return std::make_unique<UDPMotion>(std::move(ip), port, pad, client.get());
}
@@ -59,35 +59,33 @@ Common::ParamPackage UDPMotionFactory::GetNextInput() {
Common::ParamPackage params;
CemuhookUDP::UDPPadStatus pad;
auto& queue = client->GetPadQueue();
- for (std::size_t pad_number = 0; pad_number < queue.size(); ++pad_number) {
- while (queue[pad_number].Pop(pad)) {
- if (pad.motion == CemuhookUDP::PadMotion::Undefined || std::abs(pad.motion_value) < 1) {
- continue;
- }
- params.Set("engine", "cemuhookudp");
- params.Set("ip", "127.0.0.1");
- params.Set("port", 26760);
- params.Set("pad_index", static_cast<int>(pad_number));
- params.Set("motion", static_cast<u16>(pad.motion));
- return params;
+ while (queue.Pop(pad)) {
+ if (pad.motion == CemuhookUDP::PadMotion::Undefined || std::abs(pad.motion_value) < 1) {
+ continue;
}
+ params.Set("engine", "cemuhookudp");
+ params.Set("ip", pad.host);
+ params.Set("port", static_cast<u16>(pad.port));
+ params.Set("pad_index", static_cast<u16>(pad.pad_index));
+ params.Set("motion", static_cast<u16>(pad.motion));
+ return params;
}
return params;
}
class UDPTouch final : public Input::TouchDevice {
public:
- explicit UDPTouch(std::string ip_, int port_, u32 pad_, CemuhookUDP::Client* client_)
+ explicit UDPTouch(std::string ip_, u16 port_, u16 pad_, CemuhookUDP::Client* client_)
: ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {}
std::tuple<float, float, bool> GetStatus() const override {
- return client->GetPadState(pad).touch_status;
+ return client->GetPadState(ip, port, pad).touch_status;
}
private:
const std::string ip;
- const int port;
- const u32 pad;
+ const u16 port;
+ const u16 pad;
CemuhookUDP::Client* client;
mutable std::mutex mutex;
};
@@ -103,8 +101,8 @@ UDPTouchFactory::UDPTouchFactory(std::shared_ptr<CemuhookUDP::Client> client_)
*/
std::unique_ptr<Input::TouchDevice> UDPTouchFactory::Create(const Common::ParamPackage& params) {
auto ip = params.Get("ip", "127.0.0.1");
- const auto port = params.Get("port", 26760);
- const auto pad = static_cast<u32>(params.Get("pad_index", 0));
+ const auto port = static_cast<u16>(params.Get("port", 26760));
+ const auto pad = static_cast<u16>(params.Get("pad_index", 0));
return std::make_unique<UDPTouch>(std::move(ip), port, pad, client.get());
}
@@ -123,18 +121,16 @@ Common::ParamPackage UDPTouchFactory::GetNextInput() {
Common::ParamPackage params;
CemuhookUDP::UDPPadStatus pad;
auto& queue = client->GetPadQueue();
- for (std::size_t pad_number = 0; pad_number < queue.size(); ++pad_number) {
- while (queue[pad_number].Pop(pad)) {
- if (pad.touch == CemuhookUDP::PadTouch::Undefined) {
- continue;
- }
- params.Set("engine", "cemuhookudp");
- params.Set("ip", "127.0.0.1");
- params.Set("port", 26760);
- params.Set("pad_index", static_cast<int>(pad_number));
- params.Set("touch", static_cast<u16>(pad.touch));
- return params;
+ while (queue.Pop(pad)) {
+ if (pad.touch == CemuhookUDP::PadTouch::Undefined) {
+ continue;
}
+ params.Set("engine", "cemuhookudp");
+ params.Set("ip", pad.host);
+ params.Set("port", static_cast<u16>(pad.port));
+ params.Set("pad_index", static_cast<u16>(pad.pad_index));
+ params.Set("touch", static_cast<u16>(pad.touch));
+ return params;
}
return params;
}
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" {
namespace Tegra {
+void AVFrameDeleter(AVFrame* ptr) {
+ av_frame_unref(ptr);
+ av_free(ptr);
+}
+
Codec::Codec(GPU& gpu_)
: gpu(gpu_), h264_decoder(std::make_unique<Decoder::H264>(gpu)),
vp9_decoder(std::make_unique<Decoder::VP9>(gpu)) {}
@@ -27,7 +32,9 @@ Codec::~Codec() {
return;
}
// Free libav memory
+ AVFrame* av_frame{nullptr};
avcodec_send_packet(av_codec_ctx, nullptr);
+ av_frame = av_frame_alloc();
avcodec_receive_frame(av_codec_ctx, av_frame);
avcodec_flush_buffers(av_codec_ctx);
@@ -60,7 +67,7 @@ void Codec::Decode() {
}
av_codec_ctx = avcodec_alloc_context3(av_codec);
- av_frame = av_frame_alloc();
+ av_codec_ctx->refcounted_frames = 1;
av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0);
// TODO(ameerj): libavcodec gpu hw acceleration
@@ -68,8 +75,6 @@ void Codec::Decode() {
const auto av_error = avcodec_open2(av_codec_ctx, av_codec, nullptr);
if (av_error < 0) {
LOG_ERROR(Service_NVDRV, "avcodec_open2() Failed.");
- av_frame_unref(av_frame);
- av_free(av_frame);
avcodec_close(av_codec_ctx);
return;
}
@@ -96,16 +101,26 @@ void Codec::Decode() {
if (!vp9_hidden_frame) {
// Only receive/store visible frames
- avcodec_receive_frame(av_codec_ctx, av_frame);
+ AVFramePtr frame = AVFramePtr{av_frame_alloc(), AVFrameDeleter};
+ avcodec_receive_frame(av_codec_ctx, frame.get());
+ av_frames.push(std::move(frame));
+ // Limit queue to 10 frames. Workaround for ZLA decode and queue spam
+ if (av_frames.size() > 10) {
+ av_frames.pop();
+ }
}
}
-AVFrame* Codec::GetCurrentFrame() {
- return av_frame;
-}
+AVFramePtr Codec::GetCurrentFrame() {
+ // Sometimes VIC will request more frames than have been decoded.
+ // in this case, return a nullptr and don't overwrite previous frame data
+ if (av_frames.empty()) {
+ return AVFramePtr{nullptr, AVFrameDeleter};
+ }
-const AVFrame* Codec::GetCurrentFrame() const {
- return av_frame;
+ AVFramePtr frame = std::move(av_frames.front());
+ av_frames.pop();
+ return frame;
}
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 @@
#pragma once
#include <memory>
+#include <queue>
#include "common/common_types.h"
#include "video_core/command_classes/nvdec_common.h"
@@ -23,6 +24,9 @@ namespace Tegra {
class GPU;
struct VicRegisters;
+void AVFrameDeleter(AVFrame* ptr);
+using AVFramePtr = std::unique_ptr<AVFrame, decltype(&AVFrameDeleter)>;
+
namespace Decoder {
class H264;
class VP9;
@@ -42,9 +46,8 @@ public:
/// Call decoders to construct headers, decode AVFrame with ffmpeg
void Decode();
- /// Returns most recently decoded frame
- [[nodiscard]] AVFrame* GetCurrentFrame();
- [[nodiscard]] const AVFrame* GetCurrentFrame() const;
+ /// Returns next decoded frame
+ [[nodiscard]] AVFramePtr GetCurrentFrame();
/// Returns the value of current_codec
[[nodiscard]] NvdecCommon::VideoCodec GetCurrentCodec() const;
@@ -55,13 +58,13 @@ private:
AVCodec* av_codec{nullptr};
AVCodecContext* av_codec_ctx{nullptr};
- AVFrame* av_frame{nullptr};
GPU& gpu;
std::unique_ptr<Decoder::H264> h264_decoder;
std::unique_ptr<Decoder::VP9> vp9_decoder;
NvdecCommon::NvdecRegisters state{};
+ std::queue<AVFramePtr> av_frames{};
};
} // 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_) {}
H264::~H264() = default;
-const std::vector<u8>& H264::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state,
+const std::vector<u8>& H264::ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state,
bool is_first_frame) {
H264DecoderContext context{};
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:
~H264();
/// Compose the H264 header of the frame for FFmpeg decoding
- [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(NvdecCommon::NvdecRegisters& state,
- bool is_first_frame = false);
+ [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(
+ const NvdecCommon::NvdecRegisters& state, bool is_first_frame = false);
private:
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{
222, 34, 30, 0, 72, 16, 44, 0, 58, 32, 12, 0, 10, 7, 6, 0,
},
.coef_probs{
- 195, 29, 183, 0, 84, 49, 136, 0, 8, 42, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 31, 107, 169, 0, 35, 99, 159, 0, 17, 82, 140, 0, 8, 66, 114, 0,
- 2, 44, 76, 0, 1, 19, 32, 0, 40, 132, 201, 0, 29, 114, 187, 0, 13, 91, 157, 0,
- 7, 75, 127, 0, 3, 58, 95, 0, 1, 28, 47, 0, 69, 142, 221, 0, 42, 122, 201, 0,
- 15, 91, 159, 0, 6, 67, 121, 0, 1, 42, 77, 0, 1, 17, 31, 0, 102, 148, 228, 0,
- 67, 117, 204, 0, 17, 82, 154, 0, 6, 59, 114, 0, 2, 39, 75, 0, 1, 15, 29, 0,
- 156, 57, 233, 0, 119, 57, 212, 0, 58, 48, 163, 0, 29, 40, 124, 0, 12, 30, 81, 0,
- 3, 12, 31, 0, 191, 107, 226, 0, 124, 117, 204, 0, 25, 99, 155, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 29, 148, 210, 0, 37, 126, 194, 0, 8, 93, 157, 0,
- 2, 68, 118, 0, 1, 39, 69, 0, 1, 17, 33, 0, 41, 151, 213, 0, 27, 123, 193, 0,
- 3, 82, 144, 0, 1, 58, 105, 0, 1, 32, 60, 0, 1, 13, 26, 0, 59, 159, 220, 0,
- 23, 126, 198, 0, 4, 88, 151, 0, 1, 66, 114, 0, 1, 38, 71, 0, 1, 18, 34, 0,
- 114, 136, 232, 0, 51, 114, 207, 0, 11, 83, 155, 0, 3, 56, 105, 0, 1, 33, 65, 0,
- 1, 17, 34, 0, 149, 65, 234, 0, 121, 57, 215, 0, 61, 49, 166, 0, 28, 36, 114, 0,
- 12, 25, 76, 0, 3, 16, 42, 0, 214, 49, 220, 0, 132, 63, 188, 0, 42, 65, 137, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 137, 221, 0, 104, 131, 216, 0,
- 49, 111, 192, 0, 21, 87, 155, 0, 2, 49, 87, 0, 1, 16, 28, 0, 89, 163, 230, 0,
- 90, 137, 220, 0, 29, 100, 183, 0, 10, 70, 135, 0, 2, 42, 81, 0, 1, 17, 33, 0,
- 108, 167, 237, 0, 55, 133, 222, 0, 15, 97, 179, 0, 4, 72, 135, 0, 1, 45, 85, 0,
- 1, 19, 38, 0, 124, 146, 240, 0, 66, 124, 224, 0, 17, 88, 175, 0, 4, 58, 122, 0,
- 1, 36, 75, 0, 1, 18, 37, 0, 141, 79, 241, 0, 126, 70, 227, 0, 66, 58, 182, 0,
- 30, 44, 136, 0, 12, 34, 96, 0, 2, 20, 47, 0, 229, 99, 249, 0, 143, 111, 235, 0,
- 46, 109, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 158, 236, 0,
- 94, 146, 224, 0, 25, 117, 191, 0, 9, 87, 149, 0, 3, 56, 99, 0, 1, 33, 57, 0,
- 83, 167, 237, 0, 68, 145, 222, 0, 10, 103, 177, 0, 2, 72, 131, 0, 1, 41, 79, 0,
- 1, 20, 39, 0, 99, 167, 239, 0, 47, 141, 224, 0, 10, 104, 178, 0, 2, 73, 133, 0,
- 1, 44, 85, 0, 1, 22, 47, 0, 127, 145, 243, 0, 71, 129, 228, 0, 17, 93, 177, 0,
- 3, 61, 124, 0, 1, 41, 84, 0, 1, 21, 52, 0, 157, 78, 244, 0, 140, 72, 231, 0,
- 69, 58, 184, 0, 31, 44, 137, 0, 14, 38, 105, 0, 8, 23, 61, 0, 125, 34, 187, 0,
- 52, 41, 133, 0, 6, 31, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 37, 109, 153, 0, 51, 102, 147, 0, 23, 87, 128, 0, 8, 67, 101, 0, 1, 41, 63, 0,
- 1, 19, 29, 0, 31, 154, 185, 0, 17, 127, 175, 0, 6, 96, 145, 0, 2, 73, 114, 0,
- 1, 51, 82, 0, 1, 28, 45, 0, 23, 163, 200, 0, 10, 131, 185, 0, 2, 93, 148, 0,
- 1, 67, 111, 0, 1, 41, 69, 0, 1, 14, 24, 0, 29, 176, 217, 0, 12, 145, 201, 0,
- 3, 101, 156, 0, 1, 69, 111, 0, 1, 39, 63, 0, 1, 14, 23, 0, 57, 192, 233, 0,
- 25, 154, 215, 0, 6, 109, 167, 0, 3, 78, 118, 0, 1, 48, 69, 0, 1, 21, 29, 0,
- 202, 105, 245, 0, 108, 106, 216, 0, 18, 90, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 33, 172, 219, 0, 64, 149, 206, 0, 14, 117, 177, 0, 5, 90, 141, 0,
- 2, 61, 95, 0, 1, 37, 57, 0, 33, 179, 220, 0, 11, 140, 198, 0, 1, 89, 148, 0,
- 1, 60, 104, 0, 1, 33, 57, 0, 1, 12, 21, 0, 30, 181, 221, 0, 8, 141, 198, 0,
- 1, 87, 145, 0, 1, 58, 100, 0, 1, 31, 55, 0, 1, 12, 20, 0, 32, 186, 224, 0,
- 7, 142, 198, 0, 1, 86, 143, 0, 1, 58, 100, 0, 1, 31, 55, 0, 1, 12, 22, 0,
- 57, 192, 227, 0, 20, 143, 204, 0, 3, 96, 154, 0, 1, 68, 112, 0, 1, 42, 69, 0,
- 1, 19, 32, 0, 212, 35, 215, 0, 113, 47, 169, 0, 29, 48, 105, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 74, 129, 203, 0, 106, 120, 203, 0, 49, 107, 178, 0,
- 19, 84, 144, 0, 4, 50, 84, 0, 1, 15, 25, 0, 71, 172, 217, 0, 44, 141, 209, 0,
- 15, 102, 173, 0, 6, 76, 133, 0, 2, 51, 89, 0, 1, 24, 42, 0, 64, 185, 231, 0,
- 31, 148, 216, 0, 8, 103, 175, 0, 3, 74, 131, 0, 1, 46, 81, 0, 1, 18, 30, 0,
- 65, 196, 235, 0, 25, 157, 221, 0, 5, 105, 174, 0, 1, 67, 120, 0, 1, 38, 69, 0,
- 1, 15, 30, 0, 65, 204, 238, 0, 30, 156, 224, 0, 7, 107, 177, 0, 2, 70, 124, 0,
- 1, 42, 73, 0, 1, 18, 34, 0, 225, 86, 251, 0, 144, 104, 235, 0, 42, 99, 181, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 175, 239, 0, 112, 165, 229, 0,
- 29, 136, 200, 0, 12, 103, 162, 0, 6, 77, 123, 0, 2, 53, 84, 0, 75, 183, 239, 0,
- 30, 155, 221, 0, 3, 106, 171, 0, 1, 74, 128, 0, 1, 44, 76, 0, 1, 17, 28, 0,
- 73, 185, 240, 0, 27, 159, 222, 0, 2, 107, 172, 0, 1, 75, 127, 0, 1, 42, 73, 0,
- 1, 17, 29, 0, 62, 190, 238, 0, 21, 159, 222, 0, 2, 107, 172, 0, 1, 72, 122, 0,
- 1, 40, 71, 0, 1, 18, 32, 0, 61, 199, 240, 0, 27, 161, 226, 0, 4, 113, 180, 0,
- 1, 76, 129, 0, 1, 46, 80, 0, 1, 23, 41, 0, 7, 27, 153, 0, 5, 30, 95, 0,
- 1, 16, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 75, 127, 0,
- 57, 75, 124, 0, 27, 67, 108, 0, 10, 54, 86, 0, 1, 33, 52, 0, 1, 12, 18, 0,
- 43, 125, 151, 0, 26, 108, 148, 0, 7, 83, 122, 0, 2, 59, 89, 0, 1, 38, 60, 0,
- 1, 17, 27, 0, 23, 144, 163, 0, 13, 112, 154, 0, 2, 75, 117, 0, 1, 50, 81, 0,
- 1, 31, 51, 0, 1, 14, 23, 0, 18, 162, 185, 0, 6, 123, 171, 0, 1, 78, 125, 0,
- 1, 51, 86, 0, 1, 31, 54, 0, 1, 14, 23, 0, 15, 199, 227, 0, 3, 150, 204, 0,
- 1, 91, 146, 0, 1, 55, 95, 0, 1, 30, 53, 0, 1, 11, 20, 0, 19, 55, 240, 0,
- 19, 59, 196, 0, 3, 52, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 41, 166, 207, 0, 104, 153, 199, 0, 31, 123, 181, 0, 14, 101, 152, 0, 5, 72, 106, 0,
- 1, 36, 52, 0, 35, 176, 211, 0, 12, 131, 190, 0, 2, 88, 144, 0, 1, 60, 101, 0,
- 1, 36, 60, 0, 1, 16, 28, 0, 28, 183, 213, 0, 8, 134, 191, 0, 1, 86, 142, 0,
- 1, 56, 96, 0, 1, 30, 53, 0, 1, 12, 20, 0, 20, 190, 215, 0, 4, 135, 192, 0,
- 1, 84, 139, 0, 1, 53, 91, 0, 1, 28, 49, 0, 1, 11, 20, 0, 13, 196, 216, 0,
- 2, 137, 192, 0, 1, 86, 143, 0, 1, 57, 99, 0, 1, 32, 56, 0, 1, 13, 24, 0,
- 211, 29, 217, 0, 96, 47, 156, 0, 22, 43, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 78, 120, 193, 0, 111, 116, 186, 0, 46, 102, 164, 0, 15, 80, 128, 0,
- 2, 49, 76, 0, 1, 18, 28, 0, 71, 161, 203, 0, 42, 132, 192, 0, 10, 98, 150, 0,
- 3, 69, 109, 0, 1, 44, 70, 0, 1, 18, 29, 0, 57, 186, 211, 0, 30, 140, 196, 0,
- 4, 93, 146, 0, 1, 62, 102, 0, 1, 38, 65, 0, 1, 16, 27, 0, 47, 199, 217, 0,
- 14, 145, 196, 0, 1, 88, 142, 0, 1, 57, 98, 0, 1, 36, 62, 0, 1, 15, 26, 0,
- 26, 219, 229, 0, 5, 155, 207, 0, 1, 94, 151, 0, 1, 60, 104, 0, 1, 36, 62, 0,
- 1, 16, 28, 0, 233, 29, 248, 0, 146, 47, 220, 0, 43, 52, 140, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 100, 163, 232, 0, 179, 161, 222, 0, 63, 142, 204, 0,
- 37, 113, 174, 0, 26, 89, 137, 0, 18, 68, 97, 0, 85, 181, 230, 0, 32, 146, 209, 0,
- 7, 100, 164, 0, 3, 71, 121, 0, 1, 45, 77, 0, 1, 18, 30, 0, 65, 187, 230, 0,
- 20, 148, 207, 0, 2, 97, 159, 0, 1, 68, 116, 0, 1, 40, 70, 0, 1, 14, 29, 0,
- 40, 194, 227, 0, 8, 147, 204, 0, 1, 94, 155, 0, 1, 65, 112, 0, 1, 39, 66, 0,
- 1, 14, 26, 0, 16, 208, 228, 0, 3, 151, 207, 0, 1, 98, 160, 0, 1, 67, 117, 0,
- 1, 41, 74, 0, 1, 17, 31, 0, 17, 38, 140, 0, 7, 34, 80, 0, 1, 17, 29, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 75, 128, 0, 41, 76, 128, 0,
- 26, 66, 116, 0, 12, 52, 94, 0, 2, 32, 55, 0, 1, 10, 16, 0, 50, 127, 154, 0,
- 37, 109, 152, 0, 16, 82, 121, 0, 5, 59, 85, 0, 1, 35, 54, 0, 1, 13, 20, 0,
- 40, 142, 167, 0, 17, 110, 157, 0, 2, 71, 112, 0, 1, 44, 72, 0, 1, 27, 45, 0,
- 1, 11, 17, 0, 30, 175, 188, 0, 9, 124, 169, 0, 1, 74, 116, 0, 1, 48, 78, 0,
- 1, 30, 49, 0, 1, 11, 18, 0, 10, 222, 223, 0, 2, 150, 194, 0, 1, 83, 128, 0,
- 1, 48, 79, 0, 1, 27, 45, 0, 1, 11, 17, 0, 36, 41, 235, 0, 29, 36, 193, 0,
- 10, 27, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 165, 222, 0,
- 177, 162, 215, 0, 110, 135, 195, 0, 57, 113, 168, 0, 23, 83, 120, 0, 10, 49, 61, 0,
- 85, 190, 223, 0, 36, 139, 200, 0, 5, 90, 146, 0, 1, 60, 103, 0, 1, 38, 65, 0,
- 1, 18, 30, 0, 72, 202, 223, 0, 23, 141, 199, 0, 2, 86, 140, 0, 1, 56, 97, 0,
- 1, 36, 61, 0, 1, 16, 27, 0, 55, 218, 225, 0, 13, 145, 200, 0, 1, 86, 141, 0,
- 1, 57, 99, 0, 1, 35, 61, 0, 1, 13, 22, 0, 15, 235, 212, 0, 1, 132, 184, 0,
- 1, 84, 139, 0, 1, 57, 97, 0, 1, 34, 56, 0, 1, 14, 23, 0, 181, 21, 201, 0,
- 61, 37, 123, 0, 10, 38, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 47, 106, 172, 0, 95, 104, 173, 0, 42, 93, 159, 0, 18, 77, 131, 0, 4, 50, 81, 0,
- 1, 17, 23, 0, 62, 147, 199, 0, 44, 130, 189, 0, 28, 102, 154, 0, 18, 75, 115, 0,
- 2, 44, 65, 0, 1, 12, 19, 0, 55, 153, 210, 0, 24, 130, 194, 0, 3, 93, 146, 0,
- 1, 61, 97, 0, 1, 31, 50, 0, 1, 10, 16, 0, 49, 186, 223, 0, 17, 148, 204, 0,
- 1, 96, 142, 0, 1, 53, 83, 0, 1, 26, 44, 0, 1, 11, 17, 0, 13, 217, 212, 0,
- 2, 136, 180, 0, 1, 78, 124, 0, 1, 50, 83, 0, 1, 29, 49, 0, 1, 14, 23, 0,
- 197, 13, 247, 0, 82, 17, 222, 0, 25, 17, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 126, 186, 247, 0, 234, 191, 243, 0, 176, 177, 234, 0, 104, 158, 220, 0,
- 66, 128, 186, 0, 55, 90, 137, 0, 111, 197, 242, 0, 46, 158, 219, 0, 9, 104, 171, 0,
- 2, 65, 125, 0, 1, 44, 80, 0, 1, 17, 91, 0, 104, 208, 245, 0, 39, 168, 224, 0,
- 3, 109, 162, 0, 1, 79, 124, 0, 1, 50, 102, 0, 1, 43, 102, 0, 84, 220, 246, 0,
- 31, 177, 231, 0, 2, 115, 180, 0, 1, 79, 134, 0, 1, 55, 77, 0, 1, 60, 79, 0,
- 43, 243, 240, 0, 8, 180, 217, 0, 1, 115, 166, 0, 1, 84, 121, 0, 1, 51, 67, 0,
- 1, 16, 6, 0,
+ 195, 29, 183, 84, 49, 136, 8, 42, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 31, 107, 169, 35, 99, 159, 17, 82, 140, 8, 66, 114, 2, 44, 76, 1, 19, 32,
+ 40, 132, 201, 29, 114, 187, 13, 91, 157, 7, 75, 127, 3, 58, 95, 1, 28, 47,
+ 69, 142, 221, 42, 122, 201, 15, 91, 159, 6, 67, 121, 1, 42, 77, 1, 17, 31,
+ 102, 148, 228, 67, 117, 204, 17, 82, 154, 6, 59, 114, 2, 39, 75, 1, 15, 29,
+ 156, 57, 233, 119, 57, 212, 58, 48, 163, 29, 40, 124, 12, 30, 81, 3, 12, 31,
+ 191, 107, 226, 124, 117, 204, 25, 99, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 29, 148, 210, 37, 126, 194, 8, 93, 157, 2, 68, 118, 1, 39, 69, 1, 17, 33,
+ 41, 151, 213, 27, 123, 193, 3, 82, 144, 1, 58, 105, 1, 32, 60, 1, 13, 26,
+ 59, 159, 220, 23, 126, 198, 4, 88, 151, 1, 66, 114, 1, 38, 71, 1, 18, 34,
+ 114, 136, 232, 51, 114, 207, 11, 83, 155, 3, 56, 105, 1, 33, 65, 1, 17, 34,
+ 149, 65, 234, 121, 57, 215, 61, 49, 166, 28, 36, 114, 12, 25, 76, 3, 16, 42,
+ 214, 49, 220, 132, 63, 188, 42, 65, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 85, 137, 221, 104, 131, 216, 49, 111, 192, 21, 87, 155, 2, 49, 87, 1, 16, 28,
+ 89, 163, 230, 90, 137, 220, 29, 100, 183, 10, 70, 135, 2, 42, 81, 1, 17, 33,
+ 108, 167, 237, 55, 133, 222, 15, 97, 179, 4, 72, 135, 1, 45, 85, 1, 19, 38,
+ 124, 146, 240, 66, 124, 224, 17, 88, 175, 4, 58, 122, 1, 36, 75, 1, 18, 37,
+ 141, 79, 241, 126, 70, 227, 66, 58, 182, 30, 44, 136, 12, 34, 96, 2, 20, 47,
+ 229, 99, 249, 143, 111, 235, 46, 109, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 82, 158, 236, 94, 146, 224, 25, 117, 191, 9, 87, 149, 3, 56, 99, 1, 33, 57,
+ 83, 167, 237, 68, 145, 222, 10, 103, 177, 2, 72, 131, 1, 41, 79, 1, 20, 39,
+ 99, 167, 239, 47, 141, 224, 10, 104, 178, 2, 73, 133, 1, 44, 85, 1, 22, 47,
+ 127, 145, 243, 71, 129, 228, 17, 93, 177, 3, 61, 124, 1, 41, 84, 1, 21, 52,
+ 157, 78, 244, 140, 72, 231, 69, 58, 184, 31, 44, 137, 14, 38, 105, 8, 23, 61,
+ 125, 34, 187, 52, 41, 133, 6, 31, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 37, 109, 153, 51, 102, 147, 23, 87, 128, 8, 67, 101, 1, 41, 63, 1, 19, 29,
+ 31, 154, 185, 17, 127, 175, 6, 96, 145, 2, 73, 114, 1, 51, 82, 1, 28, 45,
+ 23, 163, 200, 10, 131, 185, 2, 93, 148, 1, 67, 111, 1, 41, 69, 1, 14, 24,
+ 29, 176, 217, 12, 145, 201, 3, 101, 156, 1, 69, 111, 1, 39, 63, 1, 14, 23,
+ 57, 192, 233, 25, 154, 215, 6, 109, 167, 3, 78, 118, 1, 48, 69, 1, 21, 29,
+ 202, 105, 245, 108, 106, 216, 18, 90, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 33, 172, 219, 64, 149, 206, 14, 117, 177, 5, 90, 141, 2, 61, 95, 1, 37, 57,
+ 33, 179, 220, 11, 140, 198, 1, 89, 148, 1, 60, 104, 1, 33, 57, 1, 12, 21,
+ 30, 181, 221, 8, 141, 198, 1, 87, 145, 1, 58, 100, 1, 31, 55, 1, 12, 20,
+ 32, 186, 224, 7, 142, 198, 1, 86, 143, 1, 58, 100, 1, 31, 55, 1, 12, 22,
+ 57, 192, 227, 20, 143, 204, 3, 96, 154, 1, 68, 112, 1, 42, 69, 1, 19, 32,
+ 212, 35, 215, 113, 47, 169, 29, 48, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 74, 129, 203, 106, 120, 203, 49, 107, 178, 19, 84, 144, 4, 50, 84, 1, 15, 25,
+ 71, 172, 217, 44, 141, 209, 15, 102, 173, 6, 76, 133, 2, 51, 89, 1, 24, 42,
+ 64, 185, 231, 31, 148, 216, 8, 103, 175, 3, 74, 131, 1, 46, 81, 1, 18, 30,
+ 65, 196, 235, 25, 157, 221, 5, 105, 174, 1, 67, 120, 1, 38, 69, 1, 15, 30,
+ 65, 204, 238, 30, 156, 224, 7, 107, 177, 2, 70, 124, 1, 42, 73, 1, 18, 34,
+ 225, 86, 251, 144, 104, 235, 42, 99, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 85, 175, 239, 112, 165, 229, 29, 136, 200, 12, 103, 162, 6, 77, 123, 2, 53, 84,
+ 75, 183, 239, 30, 155, 221, 3, 106, 171, 1, 74, 128, 1, 44, 76, 1, 17, 28,
+ 73, 185, 240, 27, 159, 222, 2, 107, 172, 1, 75, 127, 1, 42, 73, 1, 17, 29,
+ 62, 190, 238, 21, 159, 222, 2, 107, 172, 1, 72, 122, 1, 40, 71, 1, 18, 32,
+ 61, 199, 240, 27, 161, 226, 4, 113, 180, 1, 76, 129, 1, 46, 80, 1, 23, 41,
+ 7, 27, 153, 5, 30, 95, 1, 16, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 50, 75, 127, 57, 75, 124, 27, 67, 108, 10, 54, 86, 1, 33, 52, 1, 12, 18,
+ 43, 125, 151, 26, 108, 148, 7, 83, 122, 2, 59, 89, 1, 38, 60, 1, 17, 27,
+ 23, 144, 163, 13, 112, 154, 2, 75, 117, 1, 50, 81, 1, 31, 51, 1, 14, 23,
+ 18, 162, 185, 6, 123, 171, 1, 78, 125, 1, 51, 86, 1, 31, 54, 1, 14, 23,
+ 15, 199, 227, 3, 150, 204, 1, 91, 146, 1, 55, 95, 1, 30, 53, 1, 11, 20,
+ 19, 55, 240, 19, 59, 196, 3, 52, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 41, 166, 207, 104, 153, 199, 31, 123, 181, 14, 101, 152, 5, 72, 106, 1, 36, 52,
+ 35, 176, 211, 12, 131, 190, 2, 88, 144, 1, 60, 101, 1, 36, 60, 1, 16, 28,
+ 28, 183, 213, 8, 134, 191, 1, 86, 142, 1, 56, 96, 1, 30, 53, 1, 12, 20,
+ 20, 190, 215, 4, 135, 192, 1, 84, 139, 1, 53, 91, 1, 28, 49, 1, 11, 20,
+ 13, 196, 216, 2, 137, 192, 1, 86, 143, 1, 57, 99, 1, 32, 56, 1, 13, 24,
+ 211, 29, 217, 96, 47, 156, 22, 43, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 78, 120, 193, 111, 116, 186, 46, 102, 164, 15, 80, 128, 2, 49, 76, 1, 18, 28,
+ 71, 161, 203, 42, 132, 192, 10, 98, 150, 3, 69, 109, 1, 44, 70, 1, 18, 29,
+ 57, 186, 211, 30, 140, 196, 4, 93, 146, 1, 62, 102, 1, 38, 65, 1, 16, 27,
+ 47, 199, 217, 14, 145, 196, 1, 88, 142, 1, 57, 98, 1, 36, 62, 1, 15, 26,
+ 26, 219, 229, 5, 155, 207, 1, 94, 151, 1, 60, 104, 1, 36, 62, 1, 16, 28,
+ 233, 29, 248, 146, 47, 220, 43, 52, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 100, 163, 232, 179, 161, 222, 63, 142, 204, 37, 113, 174, 26, 89, 137, 18, 68, 97,
+ 85, 181, 230, 32, 146, 209, 7, 100, 164, 3, 71, 121, 1, 45, 77, 1, 18, 30,
+ 65, 187, 230, 20, 148, 207, 2, 97, 159, 1, 68, 116, 1, 40, 70, 1, 14, 29,
+ 40, 194, 227, 8, 147, 204, 1, 94, 155, 1, 65, 112, 1, 39, 66, 1, 14, 26,
+ 16, 208, 228, 3, 151, 207, 1, 98, 160, 1, 67, 117, 1, 41, 74, 1, 17, 31,
+ 17, 38, 140, 7, 34, 80, 1, 17, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 37, 75, 128, 41, 76, 128, 26, 66, 116, 12, 52, 94, 2, 32, 55, 1, 10, 16,
+ 50, 127, 154, 37, 109, 152, 16, 82, 121, 5, 59, 85, 1, 35, 54, 1, 13, 20,
+ 40, 142, 167, 17, 110, 157, 2, 71, 112, 1, 44, 72, 1, 27, 45, 1, 11, 17,
+ 30, 175, 188, 9, 124, 169, 1, 74, 116, 1, 48, 78, 1, 30, 49, 1, 11, 18,
+ 10, 222, 223, 2, 150, 194, 1, 83, 128, 1, 48, 79, 1, 27, 45, 1, 11, 17,
+ 36, 41, 235, 29, 36, 193, 10, 27, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 85, 165, 222, 177, 162, 215, 110, 135, 195, 57, 113, 168, 23, 83, 120, 10, 49, 61,
+ 85, 190, 223, 36, 139, 200, 5, 90, 146, 1, 60, 103, 1, 38, 65, 1, 18, 30,
+ 72, 202, 223, 23, 141, 199, 2, 86, 140, 1, 56, 97, 1, 36, 61, 1, 16, 27,
+ 55, 218, 225, 13, 145, 200, 1, 86, 141, 1, 57, 99, 1, 35, 61, 1, 13, 22,
+ 15, 235, 212, 1, 132, 184, 1, 84, 139, 1, 57, 97, 1, 34, 56, 1, 14, 23,
+ 181, 21, 201, 61, 37, 123, 10, 38, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 47, 106, 172, 95, 104, 173, 42, 93, 159, 18, 77, 131, 4, 50, 81, 1, 17, 23,
+ 62, 147, 199, 44, 130, 189, 28, 102, 154, 18, 75, 115, 2, 44, 65, 1, 12, 19,
+ 55, 153, 210, 24, 130, 194, 3, 93, 146, 1, 61, 97, 1, 31, 50, 1, 10, 16,
+ 49, 186, 223, 17, 148, 204, 1, 96, 142, 1, 53, 83, 1, 26, 44, 1, 11, 17,
+ 13, 217, 212, 2, 136, 180, 1, 78, 124, 1, 50, 83, 1, 29, 49, 1, 14, 23,
+ 197, 13, 247, 82, 17, 222, 25, 17, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 126, 186, 247, 234, 191, 243, 176, 177, 234, 104, 158, 220, 66, 128, 186, 55, 90, 137,
+ 111, 197, 242, 46, 158, 219, 9, 104, 171, 2, 65, 125, 1, 44, 80, 1, 17, 91,
+ 104, 208, 245, 39, 168, 224, 3, 109, 162, 1, 79, 124, 1, 50, 102, 1, 43, 102,
+ 84, 220, 246, 31, 177, 231, 2, 115, 180, 1, 79, 134, 1, 55, 77, 1, 60, 79,
+ 43, 243, 240, 8, 180, 217, 1, 115, 166, 1, 84, 121, 1, 51, 67, 1, 16, 6,
},
.switchable_interp_prob{235, 162, 36, 255, 34, 3, 149, 144},
.inter_mode_prob{
@@ -322,39 +302,23 @@ bool VP9::WriteLessThan(VpxRangeEncoder& writer, s32 value, s32 test) {
}
void VP9::WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode,
- const std::array<u8, 2304>& new_prob,
- const std::array<u8, 2304>& old_prob) {
- // Note: There's 1 byte added on each packet for alignment,
- // this byte is ignored when doing updates.
- constexpr s32 block_bytes = 2 * 2 * 6 * 6 * 4;
-
- const auto needs_update = [&](s32 base_index) -> bool {
- s32 index = base_index;
- for (s32 i = 0; i < 2; i++) {
- for (s32 j = 0; j < 2; j++) {
- for (s32 k = 0; k < 6; k++) {
- for (s32 l = 0; l < 6; l++) {
- if (new_prob[index + 0] != old_prob[index + 0] ||
- new_prob[index + 1] != old_prob[index + 1] ||
- new_prob[index + 2] != old_prob[index + 2]) {
- return true;
- }
-
- index += 4;
- }
- }
- }
- }
- return false;
+ const std::array<u8, 1728>& new_prob,
+ const std::array<u8, 1728>& old_prob) {
+ constexpr u32 block_bytes = 2 * 2 * 6 * 6 * 3;
+
+ const auto needs_update = [&](u32 base_index) {
+ return !std::equal(new_prob.begin() + base_index,
+ new_prob.begin() + base_index + block_bytes,
+ old_prob.begin() + base_index);
};
- for (s32 block_index = 0; block_index < 4; block_index++) {
- const s32 base_index = block_index * block_bytes;
+ for (u32 block_index = 0; block_index < 4; block_index++) {
+ const u32 base_index = block_index * block_bytes;
const bool update = needs_update(base_index);
writer.Write(update);
if (update) {
- s32 index = base_index;
+ u32 index = base_index;
for (s32 i = 0; i < 2; i++) {
for (s32 j = 0; j < 2; j++) {
for (s32 k = 0; k < 6; k++) {
@@ -367,14 +331,13 @@ void VP9::WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode,
WriteProbabilityUpdate(writer, new_prob[index + 2],
old_prob[index + 2]);
}
- index += 4;
+ index += 3;
}
}
}
}
}
-
- if (block_index == tx_mode) {
+ if (block_index == static_cast<u32>(tx_mode)) {
break;
}
}
@@ -392,7 +355,7 @@ void VP9::WriteMvProbabilityUpdate(VpxRangeEncoder& writer, u8 new_prob, u8 old_
Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state) {
PictureInfo picture_info{};
gpu.MemoryManager().ReadBlock(state.picture_info_offset, &picture_info, sizeof(PictureInfo));
- Vp9PictureInfo vp9_info = picture_info.Convert();
+ Vp9PictureInfo vp9_info = std::move(picture_info.Convert());
InsertEntropy(state.vp9_entropy_probs_offset, vp9_info.entropy);
@@ -414,8 +377,7 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state)
Vp9FrameContainer frame{};
{
gpu.SyncGuestHost();
- frame.info = GetVp9PictureInfo(state);
-
+ frame.info = std::move(GetVp9PictureInfo(state));
frame.bit_stream.resize(frame.info.bitstream_size);
gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.bit_stream.data(),
frame.info.bitstream_size);
@@ -423,37 +385,37 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state)
// Buffer two frames, saving the last show frame info
if (!next_next_frame.bit_stream.empty()) {
Vp9FrameContainer temp{
- .info = frame.info,
- .bit_stream = frame.bit_stream,
+ .info = std::move(frame.info),
+ .bit_stream = std::move(frame.bit_stream),
};
next_next_frame.info.show_frame = frame.info.last_frame_shown;
- frame.info = next_next_frame.info;
- frame.bit_stream = next_next_frame.bit_stream;
+ frame.info = std::move(next_next_frame.info);
+ frame.bit_stream = std::move(next_next_frame.bit_stream);
next_next_frame = std::move(temp);
if (!next_frame.bit_stream.empty()) {
Vp9FrameContainer temp2{
- .info = frame.info,
- .bit_stream = frame.bit_stream,
+ .info = std::move(frame.info),
+ .bit_stream = std::move(frame.bit_stream),
};
next_frame.info.show_frame = frame.info.last_frame_shown;
- frame.info = next_frame.info;
- frame.bit_stream = next_frame.bit_stream;
+ frame.info = std::move(next_frame.info);
+ frame.bit_stream = std::move(next_frame.bit_stream);
next_frame = std::move(temp2);
} else {
- next_frame.info = frame.info;
- next_frame.bit_stream = frame.bit_stream;
+ next_frame.info = std::move(frame.info);
+ next_frame.bit_stream = std::move(frame.bit_stream);
}
} else {
- next_next_frame.info = frame.info;
- next_next_frame.bit_stream = frame.bit_stream;
+ next_next_frame.info = std::move(frame.info);
+ next_next_frame.bit_stream = std::move(frame.bit_stream);
}
return frame;
}
std::vector<u8> VP9::ComposeCompressedHeader() {
VpxRangeEncoder writer{};
-
+ const bool update_probs = current_frame_info.show_frame && !current_frame_info.is_key_frame;
if (!current_frame_info.lossless) {
if (static_cast<u32>(current_frame_info.transform_mode) >= 3) {
writer.Write(3, 2);
@@ -471,7 +433,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
prev_frame_probs.tx_16x16_prob);
WriteProbabilityUpdate(writer, current_frame_info.entropy.tx_32x32_prob,
prev_frame_probs.tx_32x32_prob);
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
+ if (update_probs) {
prev_frame_probs.tx_8x8_prob = current_frame_info.entropy.tx_8x8_prob;
prev_frame_probs.tx_16x16_prob = current_frame_info.entropy.tx_16x16_prob;
prev_frame_probs.tx_32x32_prob = current_frame_info.entropy.tx_32x32_prob;
@@ -484,7 +446,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
WriteProbabilityUpdate(writer, current_frame_info.entropy.skip_probs,
prev_frame_probs.skip_probs);
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
+ if (update_probs) {
prev_frame_probs.coef_probs = current_frame_info.entropy.coef_probs;
prev_frame_probs.skip_probs = current_frame_info.entropy.skip_probs;
}
@@ -493,15 +455,12 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
// read_inter_probs() in the spec
WriteProbabilityUpdateAligned4(writer, current_frame_info.entropy.inter_mode_prob,
prev_frame_probs.inter_mode_prob);
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
- prev_frame_probs.inter_mode_prob = current_frame_info.entropy.inter_mode_prob;
- }
if (current_frame_info.interp_filter == 4) {
// read_interp_filter_probs() in the spec
WriteProbabilityUpdate(writer, current_frame_info.entropy.switchable_interp_prob,
prev_frame_probs.switchable_interp_prob);
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
+ if (update_probs) {
prev_frame_probs.switchable_interp_prob =
current_frame_info.entropy.switchable_interp_prob;
}
@@ -510,9 +469,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
// read_is_inter_probs() in the spec
WriteProbabilityUpdate(writer, current_frame_info.entropy.intra_inter_prob,
prev_frame_probs.intra_inter_prob);
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
- prev_frame_probs.intra_inter_prob = current_frame_info.entropy.intra_inter_prob;
- }
+
// frame_reference_mode() in the spec
if ((current_frame_info.ref_frame_sign_bias[1] & 1) !=
(current_frame_info.ref_frame_sign_bias[2] & 1) ||
@@ -530,7 +487,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
if (current_frame_info.reference_mode == 2) {
WriteProbabilityUpdate(writer, current_frame_info.entropy.comp_inter_prob,
prev_frame_probs.comp_inter_prob);
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
+ if (update_probs) {
prev_frame_probs.comp_inter_prob = current_frame_info.entropy.comp_inter_prob;
}
}
@@ -538,7 +495,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
if (current_frame_info.reference_mode != 1) {
WriteProbabilityUpdate(writer, current_frame_info.entropy.single_ref_prob,
prev_frame_probs.single_ref_prob);
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
+ if (update_probs) {
prev_frame_probs.single_ref_prob = current_frame_info.entropy.single_ref_prob;
}
}
@@ -546,7 +503,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
if (current_frame_info.reference_mode != 0) {
WriteProbabilityUpdate(writer, current_frame_info.entropy.comp_ref_prob,
prev_frame_probs.comp_ref_prob);
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
+ if (update_probs) {
prev_frame_probs.comp_ref_prob = current_frame_info.entropy.comp_ref_prob;
}
}
@@ -557,42 +514,37 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
WriteProbabilityUpdate(writer, current_frame_info.entropy.y_mode_prob[index],
prev_frame_probs.y_mode_prob[index]);
}
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
- prev_frame_probs.y_mode_prob = current_frame_info.entropy.y_mode_prob;
- }
+
// read_partition_probs
WriteProbabilityUpdateAligned4(writer, current_frame_info.entropy.partition_prob,
prev_frame_probs.partition_prob);
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
- prev_frame_probs.partition_prob = current_frame_info.entropy.partition_prob;
- }
// mv_probs
for (s32 i = 0; i < 3; i++) {
WriteMvProbabilityUpdate(writer, current_frame_info.entropy.joints[i],
prev_frame_probs.joints[i]);
}
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
+ if (update_probs) {
+ prev_frame_probs.inter_mode_prob = current_frame_info.entropy.inter_mode_prob;
+ prev_frame_probs.intra_inter_prob = current_frame_info.entropy.intra_inter_prob;
+ prev_frame_probs.y_mode_prob = current_frame_info.entropy.y_mode_prob;
+ prev_frame_probs.partition_prob = current_frame_info.entropy.partition_prob;
prev_frame_probs.joints = current_frame_info.entropy.joints;
}
for (s32 i = 0; i < 2; i++) {
WriteMvProbabilityUpdate(writer, current_frame_info.entropy.sign[i],
prev_frame_probs.sign[i]);
-
for (s32 j = 0; j < 10; j++) {
const int index = i * 10 + j;
-
WriteMvProbabilityUpdate(writer, current_frame_info.entropy.classes[index],
prev_frame_probs.classes[index]);
}
-
WriteMvProbabilityUpdate(writer, current_frame_info.entropy.class_0[i],
prev_frame_probs.class_0[i]);
for (s32 j = 0; j < 10; j++) {
const int index = i * 10 + j;
-
WriteMvProbabilityUpdate(writer, current_frame_info.entropy.prob_bits[index],
prev_frame_probs.prob_bits[index]);
}
@@ -602,7 +554,6 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
for (s32 j = 0; j < 2; j++) {
for (s32 k = 0; k < 3; k++) {
const int index = i * 2 * 3 + j * 3 + k;
-
WriteMvProbabilityUpdate(writer, current_frame_info.entropy.class_0_fr[index],
prev_frame_probs.class_0_fr[index]);
}
@@ -610,7 +561,6 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
for (s32 j = 0; j < 3; j++) {
const int index = i * 3 + j;
-
WriteMvProbabilityUpdate(writer, current_frame_info.entropy.fr[index],
prev_frame_probs.fr[index]);
}
@@ -626,7 +576,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
}
// save previous probs
- if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
+ if (update_probs) {
prev_frame_probs.sign = current_frame_info.entropy.sign;
prev_frame_probs.classes = current_frame_info.entropy.classes;
prev_frame_probs.class_0 = current_frame_info.entropy.class_0;
@@ -637,7 +587,6 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
prev_frame_probs.high_precision = current_frame_info.entropy.high_precision;
}
}
-
writer.End();
return writer.GetBuffer();
}
@@ -854,11 +803,11 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
return uncomp_writer;
}
-const std::vector<u8>& VP9::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state) {
+const std::vector<u8>& VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state) {
std::vector<u8> bitstream;
{
- Vp9FrameContainer curr_frame = GetCurrentFrame(state);
- current_frame_info = curr_frame.info;
+ Vp9FrameContainer curr_frame = std::move(GetCurrentFrame(state));
+ current_frame_info = std::move(curr_frame.info);
bitstream = std::move(curr_frame.bit_stream);
}
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:
/// Composes the VP9 frame from the GPU state information. Based on the official VP9 spec
/// documentation
- [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(NvdecCommon::NvdecRegisters& state);
+ [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(
+ const NvdecCommon::NvdecRegisters& state);
/// Returns true if the most recent frame was a hidden frame.
[[nodiscard]] bool WasFrameHidden() const {
@@ -147,8 +148,8 @@ private:
/// Writes probability updates for the Coef probabilities
void WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode,
- const std::array<u8, 2304>& new_prob,
- const std::array<u8, 2304>& old_prob);
+ const std::array<u8, 1728>& new_prob,
+ const std::array<u8, 1728>& old_prob);
/// Write probabilities for 4-byte aligned structures
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 {
IntraOnly = 1 << 5,
};
-enum class MvJointType {
- MvJointZero = 0, /* Zero vector */
- MvJointHnzvz = 1, /* Vert zero, hor nonzero */
- MvJointHzvnz = 2, /* Hor zero, vert nonzero */
- MvJointHnzvnz = 3, /* Both components nonzero */
-};
-enum class MvClassType {
- MvClass0 = 0, /* (0, 2] integer pel */
- MvClass1 = 1, /* (2, 4] integer pel */
- MvClass2 = 2, /* (4, 8] integer pel */
- MvClass3 = 3, /* (8, 16] integer pel */
- MvClass4 = 4, /* (16, 32] integer pel */
- MvClass5 = 5, /* (32, 64] integer pel */
- MvClass6 = 6, /* (64, 128] integer pel */
- MvClass7 = 7, /* (128, 256] integer pel */
- MvClass8 = 8, /* (256, 512] integer pel */
- MvClass9 = 9, /* (512, 1024] integer pel */
- MvClass10 = 10, /* (1024,2048] integer pel */
-};
-
-enum class BlockSize {
- Block4x4 = 0,
- Block4x8 = 1,
- Block8x4 = 2,
- Block8x8 = 3,
- Block8x16 = 4,
- Block16x8 = 5,
- Block16x16 = 6,
- Block16x32 = 7,
- Block32x16 = 8,
- Block32x32 = 9,
- Block32x64 = 10,
- Block64x32 = 11,
- Block64x64 = 12,
- BlockSizes = 13,
- BlockInvalid = BlockSizes
-};
-
-enum class PredictionMode {
- DcPred = 0, // Average of above and left pixels
- VPred = 1, // Vertical
- HPred = 2, // Horizontal
- D45Pred = 3, // Directional 45 deg = round(arctan(1 / 1) * 180 / pi)
- D135Pred = 4, // Directional 135 deg = 180 - 45
- D117Pred = 5, // Directional 117 deg = 180 - 63
- D153Pred = 6, // Directional 153 deg = 180 - 27
- D207Pred = 7, // Directional 207 deg = 180 + 27
- D63Pred = 8, // Directional 63 deg = round(arctan(2 / 1) * 180 / pi)
- TmPred = 9, // True-motion
- NearestMv = 10,
- NearMv = 11,
- ZeroMv = 12,
- NewMv = 13,
- MbModeCount = 14
-};
-
enum class TxSize {
Tx4x4 = 0, // 4x4 transform
Tx8x8 = 1, // 8x8 transform
@@ -104,13 +48,6 @@ enum class TxMode {
TxModes = 5
};
-enum class reference_mode {
- SingleReference = 0,
- CompoundReference = 1,
- ReferenceModeSelect = 2,
- ReferenceModes = 3
-};
-
struct Segmentation {
u8 enabled{};
u8 update_map{};
@@ -131,7 +68,7 @@ static_assert(sizeof(LoopFilter) == 0x7, "LoopFilter is an invalid size");
struct Vp9EntropyProbs {
std::array<u8, 36> y_mode_prob{};
std::array<u8, 64> partition_prob{};
- std::array<u8, 2304> coef_probs{};
+ std::array<u8, 1728> coef_probs{};
std::array<u8, 8> switchable_interp_prob{};
std::array<u8, 28> inter_mode_prob{};
std::array<u8, 4> intra_inter_prob{};
@@ -152,7 +89,7 @@ struct Vp9EntropyProbs {
std::array<u8, 2> class_0_hp{};
std::array<u8, 2> high_precision{};
};
-static_assert(sizeof(Vp9EntropyProbs) == 0x9F4, "Vp9EntropyProbs is an invalid size");
+static_assert(sizeof(Vp9EntropyProbs) == 0x7B4, "Vp9EntropyProbs is an invalid size");
struct Vp9PictureInfo {
bool is_key_frame{};
@@ -278,72 +215,71 @@ static_assert(sizeof(PictureInfo) == 0x100, "PictureInfo is an invalid size");
struct EntropyProbs {
INSERT_PADDING_BYTES(1024);
- std::array<std::array<u8, 4>, 7> inter_mode_prob{};
+ std::array<u8, 28> inter_mode_prob{};
std::array<u8, 4> intra_inter_prob{};
INSERT_PADDING_BYTES(80);
- std::array<std::array<u8, 1>, 2> tx_8x8_prob{};
- std::array<std::array<u8, 2>, 2> tx_16x16_prob{};
- std::array<std::array<u8, 3>, 2> tx_32x32_prob{};
+ std::array<u8, 2> tx_8x8_prob{};
+ std::array<u8, 4> tx_16x16_prob{};
+ std::array<u8, 6> tx_32x32_prob{};
std::array<u8, 4> y_mode_prob_e8{};
std::array<std::array<u8, 8>, 4> y_mode_prob_e0e7{};
INSERT_PADDING_BYTES(64);
- std::array<std::array<u8, 4>, 16> partition_prob{};
+ std::array<u8, 64> partition_prob{};
INSERT_PADDING_BYTES(10);
- std::array<std::array<u8, 2>, 4> switchable_interp_prob{};
+ std::array<u8, 8> switchable_interp_prob{};
std::array<u8, 5> comp_inter_prob{};
- std::array<u8, 4> skip_probs{};
+ std::array<u8, 3> skip_probs{};
+ INSERT_PADDING_BYTES(1);
std::array<u8, 3> joints{};
std::array<u8, 2> sign{};
- std::array<std::array<u8, 1>, 2> class_0{};
- std::array<std::array<u8, 3>, 2> fr{};
+ std::array<u8, 2> class_0{};
+ std::array<u8, 6> fr{};
std::array<u8, 2> class_0_hp{};
std::array<u8, 2> high_precision{};
- std::array<std::array<u8, 10>, 2> classes{};
- std::array<std::array<std::array<u8, 3>, 2>, 2> class_0_fr{};
- std::array<std::array<u8, 10>, 2> pred_bits{};
- std::array<std::array<u8, 2>, 5> single_ref_prob{};
+ std::array<u8, 20> classes{};
+ std::array<u8, 12> class_0_fr{};
+ std::array<u8, 20> pred_bits{};
+ std::array<u8, 10> single_ref_prob{};
std::array<u8, 5> comp_ref_prob{};
INSERT_PADDING_BYTES(17);
- std::array<std::array<std::array<std::array<std::array<std::array<u8, 4>, 6>, 6>, 2>, 2>, 4>
- coef_probs{};
+ std::array<u8, 2304> coef_probs{};
void Convert(Vp9EntropyProbs& fc) {
- std::memcpy(fc.inter_mode_prob.data(), inter_mode_prob.data(), fc.inter_mode_prob.size());
-
- std::memcpy(fc.intra_inter_prob.data(), intra_inter_prob.data(),
- fc.intra_inter_prob.size());
-
- std::memcpy(fc.tx_8x8_prob.data(), tx_8x8_prob.data(), fc.tx_8x8_prob.size());
- std::memcpy(fc.tx_16x16_prob.data(), tx_16x16_prob.data(), fc.tx_16x16_prob.size());
- std::memcpy(fc.tx_32x32_prob.data(), tx_32x32_prob.data(), fc.tx_32x32_prob.size());
-
- for (s32 i = 0; i < 4; i++) {
- for (s32 j = 0; j < 9; j++) {
+ fc.inter_mode_prob = inter_mode_prob;
+ fc.intra_inter_prob = intra_inter_prob;
+ fc.tx_8x8_prob = tx_8x8_prob;
+ fc.tx_16x16_prob = tx_16x16_prob;
+ fc.tx_32x32_prob = tx_32x32_prob;
+
+ for (std::size_t i = 0; i < 4; i++) {
+ for (std::size_t j = 0; j < 9; j++) {
fc.y_mode_prob[j + 9 * i] = j < 8 ? y_mode_prob_e0e7[i][j] : y_mode_prob_e8[i];
}
}
- std::memcpy(fc.partition_prob.data(), partition_prob.data(), fc.partition_prob.size());
-
- std::memcpy(fc.switchable_interp_prob.data(), switchable_interp_prob.data(),
- fc.switchable_interp_prob.size());
- std::memcpy(fc.comp_inter_prob.data(), comp_inter_prob.data(), fc.comp_inter_prob.size());
- std::memcpy(fc.skip_probs.data(), skip_probs.data(), fc.skip_probs.size());
-
- std::memcpy(fc.joints.data(), joints.data(), fc.joints.size());
-
- std::memcpy(fc.sign.data(), sign.data(), fc.sign.size());
- std::memcpy(fc.class_0.data(), class_0.data(), fc.class_0.size());
- std::memcpy(fc.fr.data(), fr.data(), fc.fr.size());
- std::memcpy(fc.class_0_hp.data(), class_0_hp.data(), fc.class_0_hp.size());
- std::memcpy(fc.high_precision.data(), high_precision.data(), fc.high_precision.size());
- std::memcpy(fc.classes.data(), classes.data(), fc.classes.size());
- std::memcpy(fc.class_0_fr.data(), class_0_fr.data(), fc.class_0_fr.size());
- std::memcpy(fc.prob_bits.data(), pred_bits.data(), fc.prob_bits.size());
- std::memcpy(fc.single_ref_prob.data(), single_ref_prob.data(), fc.single_ref_prob.size());
- std::memcpy(fc.comp_ref_prob.data(), comp_ref_prob.data(), fc.comp_ref_prob.size());
-
- std::memcpy(fc.coef_probs.data(), coef_probs.data(), fc.coef_probs.size());
+ fc.partition_prob = partition_prob;
+ fc.switchable_interp_prob = switchable_interp_prob;
+ fc.comp_inter_prob = comp_inter_prob;
+ fc.skip_probs = skip_probs;
+ fc.joints = joints;
+ fc.sign = sign;
+ fc.class_0 = class_0;
+ fc.fr = fr;
+ fc.class_0_hp = class_0_hp;
+ fc.high_precision = high_precision;
+ fc.classes = classes;
+ fc.class_0_fr = class_0_fr;
+ fc.prob_bits = pred_bits;
+ fc.single_ref_prob = single_ref_prob;
+ fc.comp_ref_prob = comp_ref_prob;
+
+ // Skip the 4th element as it goes unused
+ for (std::size_t i = 0; i < coef_probs.size(); i += 4) {
+ const std::size_t j = i - i / 4;
+ fc.coef_probs[j] = coef_probs[i];
+ fc.coef_probs[j + 1] = coef_probs[i + 1];
+ fc.coef_probs[j + 2] = coef_probs[i + 2];
+ }
}
};
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) {
}
}
-AVFrame* Nvdec::GetFrame() {
- return codec->GetCurrentFrame();
-}
-
-const AVFrame* Nvdec::GetFrame() const {
+AVFramePtr Nvdec::GetFrame() {
return codec->GetCurrentFrame();
}
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:
void ProcessMethod(Method method, const std::vector<u32>& arguments);
/// Return most recently decoded frame
- [[nodiscard]] AVFrame* GetFrame();
- [[nodiscard]] const AVFrame* GetFrame() const;
+ [[nodiscard]] AVFramePtr GetFrame();
private:
/// 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() {
return;
}
const VicConfig config{gpu.MemoryManager().Read<u64>(config_struct_address + 0x20)};
+ const AVFramePtr frame_ptr = std::move(nvdec_processor->GetFrame());
+ const auto* frame = frame_ptr.get();
+ if (!frame || frame->width == 0 || frame->height == 0) {
+ return;
+ }
const VideoPixelFormat pixel_format =
static_cast<VideoPixelFormat>(config.pixel_format.Value());
switch (pixel_format) {
case VideoPixelFormat::BGRA8:
case VideoPixelFormat::RGBA8: {
LOG_TRACE(Service_NVDRV, "Writing RGB Frame");
- const auto* frame = nvdec_processor->GetFrame();
- if (!frame || frame->width == 0 || frame->height == 0) {
- return;
- }
if (scaler_ctx == nullptr || frame->width != scaler_width ||
frame->height != scaler_height) {
const AVPixelFormat target_format =
@@ -121,12 +122,6 @@ void Vic::Execute() {
case VideoPixelFormat::Yuv420: {
LOG_TRACE(Service_NVDRV, "Writing YUV420 Frame");
- const auto* frame = nvdec_processor->GetFrame();
-
- if (!frame || frame->width == 0 || frame->height == 0) {
- return;
- }
-
const std::size_t surface_width = config.surface_width_minus1 + 1;
const std::size_t surface_height = config.surface_height_minus1 + 1;
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:
u32 data_upload;
- INSERT_UNION_PADDING_WORDS(0x44);
+ INSERT_UNION_PADDING_WORDS(0x16);
+
+ u32 force_early_fragment_tests;
+
+ INSERT_UNION_PADDING_WORDS(0x2D);
struct {
union {
@@ -1572,6 +1576,7 @@ ASSERT_REG_POSITION(shadow_ram_control, 0x49);
ASSERT_REG_POSITION(upload, 0x60);
ASSERT_REG_POSITION(exec_upload, 0x6C);
ASSERT_REG_POSITION(data_upload, 0x6D);
+ASSERT_REG_POSITION(force_early_fragment_tests, 0x84);
ASSERT_REG_POSITION(sync_info, 0xB2);
ASSERT_REG_POSITION(tess_mode, 0xC8);
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
regs.polygon_offset_fill_enable};
const u32 topology_index = static_cast<u32>(regs.draw.topology.Value());
- raw = 0;
+ raw1 = 0;
primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0);
depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0);
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
rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0);
topology.Assign(regs.draw.topology);
- alpha_raw = 0;
+ raw2 = 0;
const auto test_func =
regs.alpha_test_enabled == 1 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always;
alpha_test_func.Assign(PackComparisonOp(test_func));
- alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref);
+ early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0);
+ alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref);
point_size = Common::BitCast<u32>(regs.point_size);
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 {
};
union {
- u32 raw;
+ u32 raw1;
BitField<0, 1, u32> no_extended_dynamic_state;
BitField<2, 1, u32> primitive_restart_enable;
BitField<3, 1, u32> depth_bias_enable;
@@ -187,13 +187,13 @@ struct FixedPipelineState {
BitField<23, 1, u32> rasterize_enable;
BitField<24, 4, Maxwell::PrimitiveTopology> topology;
};
-
- u32 alpha_test_ref; ///< Alpha test reference value
union {
- u32 alpha_raw;
+ u32 raw2;
BitField<0, 3, u32> alpha_test_func;
+ BitField<3, 1, u32> early_z;
};
+ u32 alpha_test_ref;
u32 point_size;
std::array<u32, Maxwell::NumVertexArrays> binding_divisors;
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) {
specialization.attribute_types[i] = attribute.Type();
}
specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one;
+ specialization.early_fragment_tests = fixed_state.early_z;
// Alpha test
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:
"supported on this device");
}
}
-
if (ir.UsesLayer() || ir.UsesViewportIndex()) {
if (ir.UsesViewportIndex()) {
AddCapability(spv::Capability::MultiViewport);
@@ -325,11 +324,9 @@ public:
AddCapability(spv::Capability::ShaderViewportIndexLayerEXT);
}
}
-
if (device.IsFormatlessImageLoadSupported()) {
AddCapability(spv::Capability::StorageImageReadWithoutFormat);
}
-
if (device.IsFloat16Supported()) {
AddCapability(spv::Capability::Float16);
}
@@ -377,6 +374,9 @@ public:
if (header.ps.omap.depth) {
AddExecutionMode(main, spv::ExecutionMode::DepthReplacing);
}
+ if (specialization.early_fragment_tests) {
+ AddExecutionMode(main, spv::ExecutionMode::EarlyFragmentTests);
+ }
break;
case ShaderType::Compute:
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 {
std::bitset<Maxwell::NumVertexAttributes> enabled_attributes;
std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{};
bool ndc_minus_one_to_one{};
+ bool early_fragment_tests{};
float alpha_test_ref{};
Maxwell::ComparisonOp alpha_test_func{};
};
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 @@
#include "core/settings.h"
#include "input_common/keyboard.h"
#include "input_common/main.h"
-#include "input_common/motion_emu.h"
+#include "input_common/mouse/mouse_input.h"
#include "video_core/renderer_base.h"
#include "video_core/video_core.h"
#include "yuzu/bootmanager.h"
@@ -388,23 +388,19 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
}
void GRenderWindow::mousePressEvent(QMouseEvent* event) {
- if (!Settings::values.touchscreen.enabled) {
- input_subsystem->GetKeyboard()->PressKey(event->button());
- return;
- }
-
// Touch input is handled in TouchBeginEvent
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
return;
}
auto pos = event->pos();
+ const auto [x, y] = ScaleTouch(pos);
+ input_subsystem->GetMouse()->PressButton(x, y, event->button());
+
if (event->button() == Qt::LeftButton) {
- const auto [x, y] = ScaleTouch(pos);
this->TouchPressed(x, y);
- } else if (event->button() == Qt::RightButton) {
- input_subsystem->GetMotionEmu()->BeginTilt(pos.x(), pos.y());
}
+
QWidget::mousePressEvent(event);
}
@@ -416,26 +412,22 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
auto pos = event->pos();
const auto [x, y] = ScaleTouch(pos);
+ input_subsystem->GetMouse()->MouseMove(x, y);
this->TouchMoved(x, y);
- input_subsystem->GetMotionEmu()->Tilt(pos.x(), pos.y());
+
QWidget::mouseMoveEvent(event);
}
void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
- if (!Settings::values.touchscreen.enabled) {
- input_subsystem->GetKeyboard()->ReleaseKey(event->button());
- return;
- }
-
// Touch input is handled in TouchEndEvent
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
return;
}
+ input_subsystem->GetMouse()->ReleaseButton(event->button());
+
if (event->button() == Qt::LeftButton) {
this->TouchReleased();
- } else if (event->button() == Qt::RightButton) {
- input_subsystem->GetMotionEmu()->EndTilt();
}
}
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() {
ReadSetting(QStringLiteral("touch_from_button_map"), 0).toInt();
Settings::values.touch_from_button_map_index =
std::clamp(Settings::values.touch_from_button_map_index, 0, num_touch_from_button_maps - 1);
- Settings::values.udp_input_address =
- ReadSetting(QStringLiteral("udp_input_address"),
- QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_ADDR))
+ Settings::values.udp_input_servers =
+ ReadSetting(QStringLiteral("udp_input_servers"),
+ QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV))
.toString()
.toStdString();
- Settings::values.udp_input_port = static_cast<u16>(
- ReadSetting(QStringLiteral("udp_input_port"), InputCommon::CemuhookUDP::DEFAULT_PORT)
- .toInt());
- Settings::values.udp_pad_index =
- static_cast<u8>(ReadSetting(QStringLiteral("udp_pad_index"), 0).toUInt());
}
void Config::ReadCoreValues() {
@@ -1109,12 +1104,9 @@ void Config::SaveMotionTouchValues() {
false);
WriteSetting(QStringLiteral("touch_from_button_map"),
Settings::values.touch_from_button_map_index, 0);
- WriteSetting(QStringLiteral("udp_input_address"),
- QString::fromStdString(Settings::values.udp_input_address),
- QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_ADDR));
- WriteSetting(QStringLiteral("udp_input_port"), Settings::values.udp_input_port,
- InputCommon::CemuhookUDP::DEFAULT_PORT);
- WriteSetting(QStringLiteral("udp_pad_index"), Settings::values.udp_pad_index, 0);
+ WriteSetting(QStringLiteral("udp_input_servers"),
+ QString::fromStdString(Settings::values.udp_input_servers),
+ QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV));
qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps"));
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 @@
#include "core/hle/service/sm/sm.h"
#include "input_common/gcadapter/gc_poller.h"
#include "input_common/main.h"
+#include "input_common/mouse/mouse_poller.h"
#include "input_common/udp/udp.h"
#include "ui_configure_input_player.h"
#include "yuzu/configuration/config.h"
@@ -152,6 +153,14 @@ QString ButtonToText(const Common::ParamPackage& param) {
return {};
}
+ if (param.Get("engine", "") == "mouse") {
+ if (param.Has("button")) {
+ const QString button_str = QString::number(int(param.Get("button", 0)));
+ return QObject::tr("Click %1").arg(button_str);
+ }
+ return GetKeyName(param.Get("code", 0));
+ }
+
return QObject::tr("[unknown]");
}
@@ -203,6 +212,26 @@ QString AnalogToText(const Common::ParamPackage& param, const std::string& dir)
return {};
}
+
+ if (param.Get("engine", "") == "mouse") {
+ if (dir == "modifier") {
+ return QObject::tr("[unused]");
+ }
+
+ if (dir == "left" || dir == "right") {
+ const QString axis_x_str = QString::fromStdString(param.Get("axis_x", ""));
+
+ return QObject::tr("Mouse %1").arg(axis_x_str);
+ }
+
+ if (dir == "up" || dir == "down") {
+ const QString axis_y_str = QString::fromStdString(param.Get("axis_y", ""));
+
+ return QObject::tr("Mouse %1").arg(axis_y_str);
+ }
+
+ return {};
+ }
return QObject::tr("[unknown]");
}
} // namespace
@@ -484,6 +513,34 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
return;
}
}
+ if (input_subsystem->GetMouseButtons()->IsPolling()) {
+ params = input_subsystem->GetMouseButtons()->GetNextInput();
+ if (params.Has("engine") && IsInputAcceptable(params)) {
+ SetPollingResult(params, false);
+ return;
+ }
+ }
+ if (input_subsystem->GetMouseAnalogs()->IsPolling()) {
+ params = input_subsystem->GetMouseAnalogs()->GetNextInput();
+ if (params.Has("engine") && IsInputAcceptable(params)) {
+ SetPollingResult(params, false);
+ return;
+ }
+ }
+ if (input_subsystem->GetMouseMotions()->IsPolling()) {
+ params = input_subsystem->GetMouseMotions()->GetNextInput();
+ if (params.Has("engine") && IsInputAcceptable(params)) {
+ SetPollingResult(params, false);
+ return;
+ }
+ }
+ if (input_subsystem->GetMouseTouch()->IsPolling()) {
+ params = input_subsystem->GetMouseTouch()->GetNextInput();
+ if (params.Has("engine") && IsInputAcceptable(params)) {
+ SetPollingResult(params, false);
+ return;
+ }
+ }
for (auto& poller : device_pollers) {
params = poller->GetNextInput();
if (params.Has("engine") && IsInputAcceptable(params)) {
@@ -761,8 +818,9 @@ void ConfigureInputPlayer::UpdateUI() {
int slider_value;
auto& param = analogs_param[analog_id];
- const bool is_controller =
- param.Get("engine", "") == "sdl" || param.Get("engine", "") == "gcpad";
+ const bool is_controller = param.Get("engine", "") == "sdl" ||
+ param.Get("engine", "") == "gcpad" ||
+ param.Get("engine", "") == "mouse";
if (is_controller) {
if (!param.Has("deadzone")) {
@@ -1078,6 +1136,16 @@ void ConfigureInputPlayer::HandleClick(
input_subsystem->GetUDPMotions()->BeginConfiguration();
}
+ if (type == InputCommon::Polling::DeviceType::Button) {
+ input_subsystem->GetMouseButtons()->BeginConfiguration();
+ } else if (type == InputCommon::Polling::DeviceType::AnalogPreferred) {
+ input_subsystem->GetMouseAnalogs()->BeginConfiguration();
+ } else if (type == InputCommon::Polling::DeviceType::Motion) {
+ input_subsystem->GetMouseMotions()->BeginConfiguration();
+ } else {
+ input_subsystem->GetMouseTouch()->BeginConfiguration();
+ }
+
timeout_timer->start(2500); // Cancel after 2.5 seconds
poll_timer->start(50); // Check for new inputs every 50ms
}
@@ -1097,6 +1165,11 @@ void ConfigureInputPlayer::SetPollingResult(const Common::ParamPackage& params,
input_subsystem->GetUDPMotions()->EndConfiguration();
+ input_subsystem->GetMouseButtons()->EndConfiguration();
+ input_subsystem->GetMouseAnalogs()->EndConfiguration();
+ input_subsystem->GetMouseMotions()->EndConfiguration();
+ input_subsystem->GetMouseTouch()->EndConfiguration();
+
if (!abort) {
(*input_setter)(params);
}
@@ -1128,15 +1201,7 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {
return;
}
- if (want_keyboard_mouse) {
- SetPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->button())},
- false);
- } else {
- // We don't want any mouse buttons, so don't stop polling
- return;
- }
-
- SetPollingResult({}, true);
+ input_subsystem->GetMouse()->PressButton(0, 0, event->button());
}
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 @@
// Refer to the license.txt file included.
#include <array>
+#include <sstream>
#include <QCloseEvent>
#include <QLabel>
#include <QMessageBox>
#include <QPushButton>
+#include <QStringListModel>
#include <QVBoxLayout>
#include "common/logging/log.h"
#include "core/settings.h"
@@ -74,11 +76,6 @@ void CalibrationConfigurationDialog::UpdateButtonText(const QString& text) {
cancel_button->setText(text);
}
-constexpr std::array<std::pair<const char*, const char*>, 2> MotionProviders = {{
- {"motion_emu", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Mouse (Right Click)")},
- {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")},
-}};
-
constexpr std::array<std::pair<const char*, const char*>, 2> TouchProviders = {{
{"emu_window", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Emulator Window")},
{"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")},
@@ -89,9 +86,6 @@ ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent,
: QDialog(parent), input_subsystem{input_subsystem_},
ui(std::make_unique<Ui::ConfigureMotionTouch>()) {
ui->setupUi(this);
- for (const auto& [provider, name] : MotionProviders) {
- ui->motion_provider->addItem(tr(name), QString::fromUtf8(provider));
- }
for (const auto& [provider, name] : TouchProviders) {
ui->touch_provider->addItem(tr(name), QString::fromUtf8(provider));
}
@@ -116,8 +110,6 @@ void ConfigureMotionTouch::SetConfiguration() {
const std::string motion_engine = motion_param.Get("engine", "motion_emu");
const std::string touch_engine = touch_param.Get("engine", "emu_window");
- ui->motion_provider->setCurrentIndex(
- ui->motion_provider->findData(QString::fromStdString(motion_engine)));
ui->touch_provider->setCurrentIndex(
ui->touch_provider->findData(QString::fromStdString(touch_engine)));
ui->touch_from_button_checkbox->setChecked(Settings::values.use_touch_from_button);
@@ -133,23 +125,30 @@ void ConfigureMotionTouch::SetConfiguration() {
max_x = touch_param.Get("max_x", 1800);
max_y = touch_param.Get("max_y", 850);
- ui->udp_server->setText(QString::fromStdString(Settings::values.udp_input_address));
- ui->udp_port->setText(QString::number(Settings::values.udp_input_port));
- ui->udp_pad_index->setCurrentIndex(Settings::values.udp_pad_index);
+ ui->udp_server->setText(QString::fromStdString("127.0.0.1"));
+ ui->udp_port->setText(QString::number(26760));
+
+ udp_server_list_model = new QStringListModel(this);
+ udp_server_list_model->setStringList({});
+ ui->udp_server_list->setModel(udp_server_list_model);
+
+ std::stringstream ss(Settings::values.udp_input_servers);
+ std::string token;
+
+ while (std::getline(ss, token, ',')) {
+ const int row = udp_server_list_model->rowCount();
+ udp_server_list_model->insertRows(row, 1);
+ const QModelIndex index = udp_server_list_model->index(row);
+ udp_server_list_model->setData(index, QString::fromStdString(token));
+ }
}
void ConfigureMotionTouch::UpdateUiDisplay() {
- const QString motion_engine = ui->motion_provider->currentData().toString();
const QString touch_engine = ui->touch_provider->currentData().toString();
const QString cemuhook_udp = QStringLiteral("cemuhookudp");
- if (motion_engine == QStringLiteral("motion_emu")) {
- ui->motion_sensitivity_label->setVisible(true);
- ui->motion_sensitivity->setVisible(true);
- } else {
- ui->motion_sensitivity_label->setVisible(false);
- ui->motion_sensitivity->setVisible(false);
- }
+ ui->motion_sensitivity_label->setVisible(true);
+ ui->motion_sensitivity->setVisible(true);
if (touch_engine == cemuhook_udp) {
ui->touch_calibration->setVisible(true);
@@ -163,19 +162,15 @@ void ConfigureMotionTouch::UpdateUiDisplay() {
ui->touch_calibration_label->setVisible(false);
}
- if (motion_engine == cemuhook_udp || touch_engine == cemuhook_udp) {
- ui->udp_config_group_box->setVisible(true);
- } else {
- ui->udp_config_group_box->setVisible(false);
- }
+ ui->udp_config_group_box->setVisible(true);
}
void ConfigureMotionTouch::ConnectEvents() {
- connect(ui->motion_provider, qOverload<int>(&QComboBox::currentIndexChanged), this,
- [this](int index) { UpdateUiDisplay(); });
connect(ui->touch_provider, qOverload<int>(&QComboBox::currentIndexChanged), this,
[this](int index) { UpdateUiDisplay(); });
connect(ui->udp_test, &QPushButton::clicked, this, &ConfigureMotionTouch::OnCemuhookUDPTest);
+ connect(ui->udp_add, &QPushButton::clicked, this, &ConfigureMotionTouch::OnUDPAddServer);
+ connect(ui->udp_remove, &QPushButton::clicked, this, &ConfigureMotionTouch::OnUDPDeleteServer);
connect(ui->touch_calibration_config, &QPushButton::clicked, this,
&ConfigureMotionTouch::OnConfigureTouchCalibration);
connect(ui->touch_from_button_config_btn, &QPushButton::clicked, this,
@@ -187,13 +182,58 @@ void ConfigureMotionTouch::ConnectEvents() {
});
}
+void ConfigureMotionTouch::OnUDPAddServer() {
+ 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]?["
+ "0-9][0-9]?)$")); // a valid ip address
+ bool ok;
+ QString port_text = ui->udp_port->text();
+ QString server_text = ui->udp_server->text();
+ const QString server_string = tr("%1:%2").arg(server_text, port_text);
+ int port_number = port_text.toInt(&ok, 10);
+ int row = udp_server_list_model->rowCount();
+
+ if (!ok) {
+ QMessageBox::warning(this, tr("yuzu"), tr("Port number has invalid characters"));
+ return;
+ }
+ if (port_number < 0 || port_number > 65353) {
+ QMessageBox::warning(this, tr("yuzu"), tr("Port has to be in range 0 and 65353"));
+ return;
+ }
+ if (!re.exactMatch(server_text)) {
+ QMessageBox::warning(this, tr("yuzu"), tr("IP address is not valid"));
+ return;
+ }
+ // Search for duplicates
+ for (const auto& item : udp_server_list_model->stringList()) {
+ if (item == server_string) {
+ QMessageBox::warning(this, tr("yuzu"), tr("This UDP server already exists"));
+ return;
+ }
+ }
+ // Limit server count to 8
+ if (row == 8) {
+ QMessageBox::warning(this, tr("yuzu"), tr("Unable to add more than 8 servers"));
+ return;
+ }
+
+ udp_server_list_model->insertRows(row, 1);
+ QModelIndex index = udp_server_list_model->index(row);
+ udp_server_list_model->setData(index, server_string);
+ ui->udp_server_list->setCurrentIndex(index);
+}
+
+void ConfigureMotionTouch::OnUDPDeleteServer() {
+ udp_server_list_model->removeRows(ui->udp_server_list->currentIndex().row(), 1);
+}
+
void ConfigureMotionTouch::OnCemuhookUDPTest() {
ui->udp_test->setEnabled(false);
ui->udp_test->setText(tr("Testing"));
udp_test_in_progress = true;
InputCommon::CemuhookUDP::TestCommunication(
- ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()),
- static_cast<u32>(ui->udp_pad_index->currentIndex()), 24872,
+ ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), 0,
+ 24872,
[this] {
LOG_INFO(Frontend, "UDP input test success");
QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true));
@@ -207,9 +247,9 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() {
void ConfigureMotionTouch::OnConfigureTouchCalibration() {
ui->touch_calibration_config->setEnabled(false);
ui->touch_calibration_config->setText(tr("Configuring"));
- CalibrationConfigurationDialog dialog(
- this, ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toUInt()),
- static_cast<u8>(ui->udp_pad_index->currentIndex()), 24872);
+ CalibrationConfigurationDialog dialog(this, ui->udp_server->text().toStdString(),
+ static_cast<u16>(ui->udp_port->text().toUInt()), 0,
+ 24872);
dialog.exec();
if (dialog.completed) {
min_x = dialog.min_x;
@@ -269,7 +309,7 @@ void ConfigureMotionTouch::OnConfigureTouchFromButton() {
bool ConfigureMotionTouch::CanCloseDialog() {
if (udp_test_in_progress) {
- QMessageBox::warning(this, tr("Citra"),
+ QMessageBox::warning(this, tr("yuzu"),
tr("UDP Test or calibration configuration is in progress.<br>Please "
"wait for them to finish."));
return false;
@@ -282,17 +322,11 @@ void ConfigureMotionTouch::ApplyConfiguration() {
return;
}
- std::string motion_engine = ui->motion_provider->currentData().toString().toStdString();
std::string touch_engine = ui->touch_provider->currentData().toString().toStdString();
- Common::ParamPackage motion_param{}, touch_param{};
- motion_param.Set("engine", std::move(motion_engine));
+ Common::ParamPackage touch_param{};
touch_param.Set("engine", std::move(touch_engine));
- if (motion_engine == "motion_emu") {
- motion_param.Set("sensitivity", static_cast<float>(ui->motion_sensitivity->value()));
- }
-
if (touch_engine == "cemuhookudp") {
touch_param.Set("min_x", min_x);
touch_param.Set("min_y", min_y);
@@ -300,15 +334,25 @@ void ConfigureMotionTouch::ApplyConfiguration() {
touch_param.Set("max_y", max_y);
}
- Settings::values.motion_device = motion_param.Serialize();
Settings::values.touch_device = touch_param.Serialize();
Settings::values.use_touch_from_button = ui->touch_from_button_checkbox->isChecked();
Settings::values.touch_from_button_map_index = ui->touch_from_button_map->currentIndex();
Settings::values.touch_from_button_maps = touch_from_button_maps;
- Settings::values.udp_input_address = ui->udp_server->text().toStdString();
- Settings::values.udp_input_port = static_cast<u16>(ui->udp_port->text().toInt());
- Settings::values.udp_pad_index = static_cast<u8>(ui->udp_pad_index->currentIndex());
+ Settings::values.udp_input_servers = GetUDPServerString();
input_subsystem->ReloadInputDevices();
accept();
}
+
+std::string ConfigureMotionTouch::GetUDPServerString() const {
+ QString input_servers;
+
+ for (const auto& item : udp_server_list_model->stringList()) {
+ input_servers += item;
+ input_servers += QLatin1Char{','};
+ }
+
+ // Remove last comma
+ input_servers.chop(1);
+ return input_servers.toStdString();
+}
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 @@
class QLabel;
class QPushButton;
+class QStringListModel;
class QVBoxLayout;
namespace InputCommon {
@@ -62,6 +63,8 @@ public slots:
void ApplyConfiguration();
private slots:
+ void OnUDPAddServer();
+ void OnUDPDeleteServer();
void OnCemuhookUDPTest();
void OnConfigureTouchCalibration();
void OnConfigureTouchFromButton();
@@ -73,10 +76,12 @@ private:
void UpdateUiDisplay();
void ConnectEvents();
bool CanCloseDialog();
+ std::string GetUDPServerString() const;
InputCommon::InputSubsystem* input_subsystem;
std::unique_ptr<Ui::ConfigureMotionTouch> ui;
+ QStringListModel* udp_server_list_model;
// Coordinate system of the CemuhookUDP touch provider
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 @@
<ui version="4.0">
<class>ConfigureMotionTouch</class>
<widget class="QDialog" name="ConfigureMotionTouch">
- <property name="windowTitle">
- <string>Configure Motion / Touch</string>
- </property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
- <height>450</height>
+ <height>482</height>
</rect>
</property>
+ <property name="windowTitle">
+ <string>Configure Motion / Touch</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
<layout class="QVBoxLayout">
<item>
<widget class="QGroupBox" name="motion_group_box">
<property name="title">
- <string>Motion</string>
+ <string>Mouse Motion</string>
</property>
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
- <widget class="QLabel" name="motion_provider_label">
- <property name="text">
- <string>Motion Provider:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="motion_provider"/>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout">
- <item>
<widget class="QLabel" name="motion_sensitivity_label">
<property name="text">
<string>Sensitivity:</string>
@@ -180,103 +169,171 @@
</widget>
</item>
<item>
- <layout class="QHBoxLayout">
+ <layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <widget class="QLabel" name="udp_server_label">
- <property name="text">
- <string>Server:</string>
- </property>
- </widget>
+ <widget class="QListView" name="udp_server_list"/>
</item>
<item>
- <widget class="QLineEdit" name="udp_server">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="leftMargin">
+ <number>0</number>
</property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout">
- <item>
- <widget class="QLabel" name="udp_port_label">
- <property name="text">
- <string>Port:</string>
+ <property name="topMargin">
+ <number>0</number>
</property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="udp_port">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <property name="rightMargin">
+ <number>0</number>
</property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout">
- <item>
- <widget class="QLabel" name="udp_pad_index_label">
- <property name="text">
- <string>Pad:</string>
+ <property name="bottomMargin">
+ <number>0</number>
</property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="udp_pad_index">
<item>
- <property name="text">
- <string>Pad 1</string>
- </property>
+ <layout class="QHBoxLayout">
+ <property name="leftMargin">
+ <number>3</number>
+ </property>
+ <property name="topMargin">
+ <number>3</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="udp_server_label">
+ <property name="text">
+ <string>Server:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="udp_server">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item>
- <property name="text">
- <string>Pad 2</string>
- </property>
+ <layout class="QHBoxLayout">
+ <property name="leftMargin">
+ <number>3</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="udp_port_label">
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="udp_port">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item>
- <property name="text">
- <string>Pad 3</string>
- </property>
+ <layout class="QHBoxLayout">
+ <property name="leftMargin">
+ <number>3</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="udp_learn_more">
+ <property name="text">
+ <string>Learn More</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="udp_test">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Test</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="udp_add">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Add Server</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item>
- <property name="text">
- <string>Pad 4</string>
- </property>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
</item>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout">
- <item>
- <widget class="QLabel" name="udp_learn_more">
- <property name="text">
- <string>Learn More</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="udp_test">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Test</string>
- </property>
- </widget>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="udp_remove">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Remove Server</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
</item>
</layout>
</item>
@@ -312,6 +369,16 @@
<signal>accepted()</signal>
<receiver>ConfigureMotionTouch</receiver>
<slot>ApplyConfiguration()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
</connection>
</connections>
</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
#else
void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view additional_args) {
+#ifndef __linux__
QMessageBox::warning(
this, tr("Web Applet"),
tr("This version of yuzu was built without QtWebEngine support, meaning that yuzu cannot "
"properly display the game manual or web page requested."),
QMessageBox::Ok, QMessageBox::Ok);
+#endif
LOG_INFO(Frontend,
"(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() {
sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_x", 15);
Settings::values.touchscreen.diameter_y =
sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_y", 15);
- Settings::values.udp_input_address =
- sdl2_config->Get("Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_ADDR);
- Settings::values.udp_input_port = static_cast<u16>(sdl2_config->GetInteger(
- "Controls", "udp_input_port", InputCommon::CemuhookUDP::DEFAULT_PORT));
+ Settings::values.udp_input_servers =
+ sdl2_config->Get("Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_SRV);
std::transform(keyboard_keys.begin(), keyboard_keys.end(),
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 @@
#include "core/perf_stats.h"
#include "input_common/keyboard.h"
#include "input_common/main.h"
-#include "input_common/motion_emu.h"
+#include "input_common/mouse/mouse_input.h"
#include "input_common/sdl/sdl.h"
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
@@ -30,7 +30,7 @@ EmuWindow_SDL2::~EmuWindow_SDL2() {
void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
- input_subsystem->GetMotionEmu()->Tilt(x, y);
+ input_subsystem->GetMouse()->MouseMove(x, y);
}
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) {
}
} else if (button == SDL_BUTTON_RIGHT) {
if (state == SDL_PRESSED) {
- input_subsystem->GetMotionEmu()->BeginTilt(x, y);
+ input_subsystem->GetMouse()->PressButton(x, y, button);
} else {
- input_subsystem->GetMotionEmu()->EndTilt();
+ input_subsystem->GetMouse()->ReleaseButton(button);
}
}
}
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 @@
#include "core/settings.h"
#include "input_common/keyboard.h"
#include "input_common/main.h"
-#include "input_common/motion_emu.h"
#include "video_core/renderer_base.h"
#include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h"