From 466f0b377b30552dcf4e09952797a0d7c869c334 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Sat, 17 Sep 2022 16:36:37 +0200 Subject: [PATCH] WiimoteEmu: Update extensions from DesiredWiimoteState. --- Source/Core/Core/CMakeLists.txt | 1 + .../Core/HW/WiimoteEmu/DesiredWiimoteState.h | 2 + .../Core/HW/WiimoteEmu/Extension/Classic.cpp | 11 ++- .../Core/HW/WiimoteEmu/Extension/Classic.h | 3 +- .../Extension/DesiredExtensionState.h | 76 +++++++++++++++++++ .../WiimoteEmu/Extension/DrawsomeTablet.cpp | 11 ++- .../HW/WiimoteEmu/Extension/DrawsomeTablet.h | 3 +- .../Core/HW/WiimoteEmu/Extension/Drums.cpp | 58 ++++++++++---- .../Core/Core/HW/WiimoteEmu/Extension/Drums.h | 12 ++- .../HW/WiimoteEmu/Extension/Extension.cpp | 9 ++- .../Core/HW/WiimoteEmu/Extension/Extension.h | 10 ++- .../Core/HW/WiimoteEmu/Extension/Guitar.cpp | 11 ++- .../Core/HW/WiimoteEmu/Extension/Guitar.h | 3 +- .../Core/HW/WiimoteEmu/Extension/Nunchuk.cpp | 11 ++- .../Core/HW/WiimoteEmu/Extension/Nunchuk.h | 3 +- .../HW/WiimoteEmu/Extension/Shinkansen.cpp | 33 ++++++-- .../Core/HW/WiimoteEmu/Extension/Shinkansen.h | 10 ++- .../Core/HW/WiimoteEmu/Extension/TaTaCon.cpp | 11 ++- .../Core/HW/WiimoteEmu/Extension/TaTaCon.h | 3 +- .../HW/WiimoteEmu/Extension/Turntable.cpp | 11 ++- .../Core/HW/WiimoteEmu/Extension/Turntable.h | 3 +- .../HW/WiimoteEmu/Extension/UDrawTablet.cpp | 11 ++- .../HW/WiimoteEmu/Extension/UDrawTablet.h | 3 +- Source/Core/Core/HW/WiimoteEmu/MotionPlus.cpp | 8 +- Source/Core/Core/HW/WiimoteEmu/MotionPlus.h | 3 +- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp | 19 +++-- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h | 1 + Source/Core/DolphinLib.props | 1 + 28 files changed, 283 insertions(+), 58 deletions(-) create mode 100644 Source/Core/Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index ff5337e9dd..aaebe5d041 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -287,6 +287,7 @@ add_library(core HW/WiimoteEmu/Encryption.h HW/WiimoteEmu/Extension/Classic.cpp HW/WiimoteEmu/Extension/Classic.h + HW/WiimoteEmu/Extension/DesiredExtensionState.h HW/WiimoteEmu/Extension/DrawsomeTablet.cpp HW/WiimoteEmu/Extension/DrawsomeTablet.h HW/WiimoteEmu/Extension/Drums.cpp diff --git a/Source/Core/Core/HW/WiimoteEmu/DesiredWiimoteState.h b/Source/Core/Core/HW/WiimoteEmu/DesiredWiimoteState.h index 5060ac4388..4f6f9897aa 100644 --- a/Source/Core/Core/HW/WiimoteEmu/DesiredWiimoteState.h +++ b/Source/Core/Core/HW/WiimoteEmu/DesiredWiimoteState.h @@ -8,6 +8,7 @@ #include "Core/HW/WiimoteCommon/WiimoteReport.h" #include "Core/HW/WiimoteEmu/Camera.h" +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/MotionPlus.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" @@ -26,5 +27,6 @@ struct DesiredWiimoteState WiimoteCommon::AccelData acceleration = DEFAULT_ACCELERATION; std::array camera_points = DEFAULT_CAMERA; std::optional motion_plus = std::nullopt; + DesiredExtensionState extension; }; } // namespace WiimoteEmu diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Classic.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/Classic.cpp index 3b8d60d344..3cdc02e0b3 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Classic.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Classic.cpp @@ -10,6 +10,8 @@ #include "Common/BitUtils.h" #include "Common/Common.h" #include "Common/CommonTypes.h" + +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "InputCommon/ControllerEmu/Control/Input.h" @@ -105,7 +107,7 @@ Classic::Classic() : Extension1stParty("Classic", _trans("Classic Controller")) } } -void Classic::Update() +void Classic::BuildDesiredExtensionState(DesiredExtensionState* target_state) { DataFormat classic_data = {}; @@ -149,7 +151,12 @@ void Classic::Update() classic_data.SetButtons(buttons); - Common::BitCastPtr(&m_reg.controller_data) = classic_data; + target_state->data = classic_data; +} + +void Classic::Update(const DesiredExtensionState& target_state) +{ + DefaultExtensionUpdate(&m_reg, target_state); } void Classic::Reset() diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h b/Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h index 36bc2a7f8b..3ab0a94a38 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h @@ -178,7 +178,8 @@ public: Classic(); - void Update() override; + void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; + void Update(const DesiredExtensionState& target_state) override; void Reset() override; ControllerEmu::ControlGroup* GetGroup(ClassicGroup group); diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h b/Source/Core/Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h new file mode 100644 index 0000000000..4929c91cd1 --- /dev/null +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h @@ -0,0 +1,76 @@ +// Copyright 2022 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "Common/BitUtils.h" + +#include "Core/HW/WiimoteEmu/Extension/Classic.h" +#include "Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h" +#include "Core/HW/WiimoteEmu/Extension/Drums.h" +#include "Core/HW/WiimoteEmu/Extension/Extension.h" +#include "Core/HW/WiimoteEmu/Extension/Guitar.h" +#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h" +#include "Core/HW/WiimoteEmu/Extension/Shinkansen.h" +#include "Core/HW/WiimoteEmu/Extension/TaTaCon.h" +#include "Core/HW/WiimoteEmu/Extension/Turntable.h" +#include "Core/HW/WiimoteEmu/Extension/UDrawTablet.h" +#include "Core/HW/WiimoteEmu/ExtensionPort.h" + +namespace WiimoteEmu +{ +struct DesiredExtensionState +{ + using ExtensionData = + std::variant; + ExtensionData data = std::monostate(); + + static_assert(std::is_same_v>); + static_assert( + std::is_same_v>); + static_assert( + std::is_same_v>); + static_assert(std::is_same_v>); + static_assert(std::is_same_v>); + static_assert( + std::is_same_v>); + static_assert( + std::is_same_v>); + static_assert( + std::is_same_v>); + static_assert( + std::is_same_v>); + static_assert( + std::is_same_v>); + static_assert(std::variant_size_v == ExtensionNumber::MAX); +}; + +template +void DefaultExtensionUpdate(EncryptedExtension::Register* reg, + const DesiredExtensionState& target_state) +{ + if (std::holds_alternative(target_state.data)) + { + Common::BitCastPtr(®->controller_data) = std::get(target_state.data); + } + else + { + Common::BitCastPtr(®->controller_data) = T{}; + } +} +} // namespace WiimoteEmu diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp index a145f37015..9a0d16790e 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp @@ -9,6 +9,8 @@ #include "Common/BitUtils.h" #include "Common/Common.h" #include "Common/CommonTypes.h" + +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "InputCommon/ControllerEmu/Control/Input.h" @@ -31,9 +33,9 @@ DrawsomeTablet::DrawsomeTablet() : Extension3rdParty("Drawsome", _trans("Drawsom m_touch->AddInput(ControllerEmu::Translate, _trans("Pressure")); } -void DrawsomeTablet::Update() +void DrawsomeTablet::BuildDesiredExtensionState(DesiredExtensionState* target_state) { - DataFormat tablet_data = {}; + DataFormat& tablet_data = target_state->data.emplace(); // Stylus X/Y (calibrated values): constexpr u16 MIN_X = 0x0000; @@ -77,8 +79,11 @@ void DrawsomeTablet::Update() tablet_data.pressure1 = u8(pressure); tablet_data.pressure2 = u8(pressure >> 8); +} - Common::BitCastPtr(&m_reg.controller_data) = tablet_data; +void DrawsomeTablet::Update(const DesiredExtensionState& target_state) +{ + DefaultExtensionUpdate(&m_reg, target_state); } void DrawsomeTablet::Reset() diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h b/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h index 0bb41cc3cd..fe4a213d09 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h @@ -27,7 +27,8 @@ class DrawsomeTablet : public Extension3rdParty public: DrawsomeTablet(); - void Update() override; + void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; + void Update(const DesiredExtensionState& target_state) override; void Reset() override; ControllerEmu::ControlGroup* GetGroup(DrawsomeTabletGroup group); diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Drums.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/Drums.cpp index a3fd38f564..0a37f278d2 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Drums.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Drums.cpp @@ -9,6 +9,8 @@ #include "Common/BitUtils.h" #include "Common/Common.h" #include "Common/CommonTypes.h" + +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "InputCommon/ControllerEmu/Control/Input.h" @@ -77,8 +79,43 @@ Drums::Drums() : Extension1stParty("Drums", _trans("Drum Kit")) m_buttons->AddInput(ControllerEmu::DoNotTranslate, "+"); } -void Drums::Update() +void Drums::BuildDesiredExtensionState(DesiredExtensionState* target_state) { + DesiredState& state = target_state->data.emplace(); + + { + const ControllerEmu::AnalogStick::StateData stick_state = m_stick->GetState(); + + state.stick_x = MapFloat(stick_state.x, STICK_CENTER, STICK_MIN, STICK_MAX); + state.stick_y = MapFloat(stick_state.y, STICK_CENTER, STICK_MIN, STICK_MAX); + } + + state.buttons = 0; + m_buttons->GetState(&state.buttons, drum_button_bitmasks.data()); + + state.drum_pads = 0; + m_pads->GetState(&state.drum_pads, drum_pad_bitmasks.data()); + + state.softness = u8(7 - std::lround(m_hit_strength_setting.GetValue() * 7 / 100)); +} + +void Drums::Update(const DesiredExtensionState& target_state) +{ + DesiredState desired_state; + if (std::holds_alternative(target_state.data)) + { + desired_state = std::get(target_state.data); + } + else + { + // Set a sane default + desired_state.stick_x = STICK_CENTER; + desired_state.stick_y = STICK_CENTER; + desired_state.buttons = 0; + desired_state.drum_pads = 0; + desired_state.softness = 7; + } + DataFormat drum_data = {}; // The meaning of these bits are unknown but they are usually set. @@ -94,20 +131,12 @@ void Drums::Update() drum_data.no_velocity_data_2 = 1; drum_data.softness = 7; - // Stick. - { - const ControllerEmu::AnalogStick::StateData stick_state = m_stick->GetState(); - - drum_data.stick_x = MapFloat(stick_state.x, STICK_CENTER, STICK_MIN, STICK_MAX); - drum_data.stick_y = MapFloat(stick_state.y, STICK_CENTER, STICK_MIN, STICK_MAX); - } - - // Buttons. - m_buttons->GetState(&drum_data.buttons, drum_button_bitmasks.data()); + drum_data.stick_x = desired_state.stick_x; + drum_data.stick_y = desired_state.stick_y; + drum_data.buttons = desired_state.buttons; // Drum pads. - u8 current_pad_input = 0; - m_pads->GetState(¤t_pad_input, drum_pad_bitmasks.data()); + u8 current_pad_input = desired_state.drum_pads; m_new_pad_hits |= ~m_prev_pad_input & current_pad_input; m_prev_pad_input = current_pad_input; @@ -130,8 +159,7 @@ void Drums::Update() drum_data.no_velocity_data_1 = 0; drum_data.no_velocity_data_2 = 0; - // Set softness from user-configured hit strength setting. - drum_data.softness = u8(7 - std::lround(m_hit_strength_setting.GetValue() * 7 / 100)); + drum_data.softness = desired_state.softness; // A drum-pad hit causes the relevent bit to be triggered for the next 10 frames. constexpr u8 HIT_FRAME_COUNT = 10; diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Drums.h b/Source/Core/Core/HW/WiimoteEmu/Extension/Drums.h index a74013bf32..ba65e48877 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Drums.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Drums.h @@ -28,6 +28,15 @@ enum class DrumsGroup class Drums : public Extension1stParty { public: + struct DesiredState + { + u8 stick_x; // 6 bits + u8 stick_y; // 6 bits + u8 buttons; // 2 bits + u8 drum_pads; // 6 bits + u8 softness; // 3 bits + }; + struct DataFormat { u8 stick_x : 6; @@ -77,7 +86,8 @@ public: Drums(); - void Update() override; + void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; + void Update(const DesiredExtensionState& target_state) override; void Reset() override; ControllerEmu::ControlGroup* GetGroup(DrumsGroup group); diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.cpp index aa9d419977..f20beef7e3 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.cpp @@ -9,6 +9,8 @@ #include "Common/CommonTypes.h" #include "Common/Inline.h" + +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "Common/Logging/Log.h" @@ -43,7 +45,12 @@ bool None::ReadDeviceDetectPin() const return false; } -void None::Update() +void None::BuildDesiredExtensionState(DesiredExtensionState* target_state) +{ + target_state->data.emplace(); +} + +void None::Update(const DesiredExtensionState& target_state) { // Nothing needed. } diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.h b/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.h index b5fb55958d..d052952273 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.h @@ -16,6 +16,8 @@ namespace WiimoteEmu { +struct DesiredExtensionState; + class Extension : public ControllerEmu::EmulatedController, public I2CSlave { public: @@ -32,7 +34,8 @@ public: virtual void Reset() = 0; virtual void DoState(PointerWrap& p) = 0; - virtual void Update() = 0; + virtual void BuildDesiredExtensionState(DesiredExtensionState* target_state) = 0; + virtual void Update(const DesiredExtensionState& target_state) = 0; private: const char* const m_config_name; @@ -46,7 +49,8 @@ public: private: bool ReadDeviceDetectPin() const override; - void Update() override; + void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; + void Update(const DesiredExtensionState& target_state) override; void Reset() override; void DoState(PointerWrap& p) override; @@ -67,7 +71,6 @@ public: // TODO: TAS handles encryption poorly. EncryptionKey ext_key; -protected: static constexpr int CALIBRATION_CHECKSUM_BYTES = 2; #pragma pack(push, 1) @@ -97,6 +100,7 @@ protected: static_assert(0x100 == sizeof(Register)); +protected: Register m_reg = {}; void Reset() override; diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp index 2c3bdb6bd9..cd86a04a32 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp @@ -11,6 +11,8 @@ #include "Common/BitUtils.h" #include "Common/Common.h" #include "Common/CommonTypes.h" + +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "InputCommon/ControllerEmu/Control/Input.h" @@ -93,7 +95,7 @@ Guitar::Guitar() : Extension1stParty(_trans("Guitar")) groups.emplace_back(m_slider_bar = new ControllerEmu::Slider(_trans("Slider Bar"))); } -void Guitar::Update() +void Guitar::BuildDesiredExtensionState(DesiredExtensionState* target_state) { DataFormat guitar_data = {}; @@ -135,7 +137,12 @@ void Guitar::Update() // flip button bits guitar_data.bt ^= 0xFFFF; - Common::BitCastPtr(&m_reg.controller_data) = guitar_data; + target_state->data = guitar_data; +} + +void Guitar::Update(const DesiredExtensionState& target_state) +{ + DefaultExtensionUpdate(&m_reg, target_state); } void Guitar::Reset() diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.h b/Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.h index 04630c428e..c0d332d537 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.h @@ -50,7 +50,8 @@ public: Guitar(); - void Update() override; + void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; + void Update(const DesiredExtensionState& target_state) override; void Reset() override; ControllerEmu::ControlGroup* GetGroup(GuitarGroup group); diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.cpp index 5e7f7425a8..73f73aadd0 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.cpp @@ -12,7 +12,9 @@ #include "Common/Common.h" #include "Common/CommonTypes.h" #include "Common/MathUtil.h" + #include "Core/HW/Wiimote.h" +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "InputCommon/ControllerEmu/Control/Input.h" @@ -60,7 +62,7 @@ Nunchuk::Nunchuk() : Extension1stParty(_trans("Nunchuk")) "IMUAccelerometer", _trans("Accelerometer"))); } -void Nunchuk::Update() +void Nunchuk::BuildDesiredExtensionState(DesiredExtensionState* target_state) { DataFormat nc_data = {}; @@ -110,7 +112,12 @@ void Nunchuk::Update() const auto acc = ConvertAccelData(accel, ACCEL_ZERO_G << 2, ACCEL_ONE_G << 2); nc_data.SetAccel(acc.value); - Common::BitCastPtr(&m_reg.controller_data) = nc_data; + target_state->data = nc_data; +} + +void Nunchuk::Update(const DesiredExtensionState& target_state) +{ + DefaultExtensionUpdate(&m_reg, target_state); } void Nunchuk::Reset() diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.h b/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.h index 704de14d4b..678abd23d2 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.h @@ -149,7 +149,8 @@ public: Nunchuk(); - void Update() override; + void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; + void Update(const DesiredExtensionState& target_state) override; void Reset() override; void DoState(PointerWrap& p) override; diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.cpp index 81e4a52070..91bad8e995 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.cpp @@ -8,6 +8,8 @@ #include "Common/Assert.h" #include "Common/Common.h" #include "Common/CommonTypes.h" + +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h" @@ -50,9 +52,9 @@ Shinkansen::Shinkansen() : Extension3rdParty("Shinkansen", _trans("Shinkansen Co m_led->AddOutput(ControllerEmu::Translate, _trans("Doors Locked")); } -void Shinkansen::Update() +void Shinkansen::BuildDesiredExtensionState(DesiredExtensionState* target_state) { - DataFormat ext_data = {}; + DesiredState& state = target_state->data.emplace(); u16 digital = 0; const u16 lever_bitmasks[2] = {}; @@ -62,8 +64,8 @@ void Shinkansen::Update() // guesses). const u8 brake_values[] = {0, 53, 79, 105, 132, 159, 187, 217, 250}; const u8 power_values[] = {255, 229, 208, 189, 170, 153, 135, 118, 101, 85, 68, 51, 35, 17}; - ext_data.brake = brake_values[size_t(analog[0] * (sizeof(brake_values) - 1))]; - ext_data.power = power_values[size_t(analog[1] * (sizeof(power_values) - 1))]; + state.brake = brake_values[size_t(analog[0] * (sizeof(brake_values) - 1))]; + state.power = power_values[size_t(analog[1] * (sizeof(power_values) - 1))]; // Note: This currently assumes a little-endian host. const u16 button_bitmasks[] = { @@ -78,8 +80,27 @@ void Shinkansen::Update() 0x0010, // Select 0x0004, // Start }; - m_buttons->GetState(&ext_data.buttons, button_bitmasks); - ext_data.buttons ^= 0xFFFF; + m_buttons->GetState(&state.buttons, button_bitmasks); +} + +void Shinkansen::Update(const DesiredExtensionState& target_state) +{ + DesiredState desired_state; + if (std::holds_alternative(target_state.data)) + { + desired_state = std::get(target_state.data); + } + else + { + desired_state.brake = 0; + desired_state.power = 255; + desired_state.buttons = 0; + } + + DataFormat ext_data = {}; + ext_data.brake = desired_state.brake; + ext_data.power = desired_state.power; + ext_data.buttons = desired_state.buttons ^ 0xFFFF; Common::BitCastPtr(&m_reg.controller_data) = ext_data; const auto lock = GetStateLock(); diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.h b/Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.h index d237f484ad..7c3cbb019d 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.h @@ -24,9 +24,17 @@ enum class ShinkansenGroup class Shinkansen : public Extension3rdParty { public: + struct DesiredState + { + u8 brake; + u8 power; + u16 buttons; + }; + Shinkansen(); - void Update() override; + void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; + void Update(const DesiredExtensionState& target_state) override; void Reset() override; ControllerEmu::ControlGroup* GetGroup(ShinkansenGroup group); diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/TaTaCon.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/TaTaCon.cpp index c20d541d7a..04c13dc961 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/TaTaCon.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/TaTaCon.cpp @@ -10,6 +10,8 @@ #include "Common/BitUtils.h" #include "Common/Common.h" #include "Common/CommonTypes.h" + +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "InputCommon/ControllerEmu/Control/Input.h" @@ -48,7 +50,7 @@ TaTaCon::TaTaCon() : Extension3rdParty("TaTaCon", _trans("Taiko Drum")) m_rim->AddInput(ControllerEmu::Translate, name); } -void TaTaCon::Update() +void TaTaCon::BuildDesiredExtensionState(DesiredExtensionState* target_state) { DataFormat tatacon_data = {}; @@ -58,7 +60,12 @@ void TaTaCon::Update() // Flip button bits. tatacon_data.state ^= 0xff; - Common::BitCastPtr(&m_reg.controller_data) = tatacon_data; + target_state->data = tatacon_data; +} + +void TaTaCon::Update(const DesiredExtensionState& target_state) +{ + DefaultExtensionUpdate(&m_reg, target_state); } void TaTaCon::Reset() diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/TaTaCon.h b/Source/Core/Core/HW/WiimoteEmu/Extension/TaTaCon.h index 7c7b071dac..7ce54770bc 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/TaTaCon.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/TaTaCon.h @@ -31,7 +31,8 @@ public: TaTaCon(); - void Update() override; + void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; + void Update(const DesiredExtensionState& target_state) override; void Reset() override; ControllerEmu::ControlGroup* GetGroup(TaTaConGroup group); diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Turntable.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/Turntable.cpp index f00b6df080..aaa928686f 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Turntable.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Turntable.cpp @@ -10,6 +10,8 @@ #include "Common/BitUtils.h" #include "Common/Common.h" #include "Common/CommonTypes.h" + +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "InputCommon/ControllerEmu/Control/Input.h" @@ -78,7 +80,7 @@ Turntable::Turntable() : Extension1stParty("Turntable", _trans("DJ Turntable")) groups.emplace_back(m_crossfade = new ControllerEmu::Slider(_trans("Crossfade"))); } -void Turntable::Update() +void Turntable::BuildDesiredExtensionState(DesiredExtensionState* target_state) { DataFormat tt_data = {}; @@ -133,7 +135,12 @@ void Turntable::Update() tt_data.bt ^= (BUTTON_L_GREEN | BUTTON_L_RED | BUTTON_L_BLUE | BUTTON_R_GREEN | BUTTON_R_RED | BUTTON_R_BLUE | BUTTON_MINUS | BUTTON_PLUS | BUTTON_EUPHORIA); - Common::BitCastPtr(&m_reg.controller_data) = tt_data; + target_state->data = tt_data; +} + +void Turntable::Update(const DesiredExtensionState& target_state) +{ + DefaultExtensionUpdate(&m_reg, target_state); } void Turntable::Reset() diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Turntable.h b/Source/Core/Core/HW/WiimoteEmu/Extension/Turntable.h index 539f5ce10c..451135d812 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Turntable.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Turntable.h @@ -56,7 +56,8 @@ public: Turntable(); - void Update() override; + void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; + void Update(const DesiredExtensionState& target_state) override; void Reset() override; ControllerEmu::ControlGroup* GetGroup(TurntableGroup group); diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.cpp index cf3253b3ee..e78d41f015 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.cpp @@ -9,6 +9,8 @@ #include "Common/BitUtils.h" #include "Common/Common.h" #include "Common/CommonTypes.h" + +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "InputCommon/ControllerEmu/Control/Input.h" @@ -48,7 +50,7 @@ UDrawTablet::UDrawTablet() : Extension3rdParty("uDraw", _trans("uDraw GameTablet m_touch->AddInput(ControllerEmu::Translate, _trans("Pressure")); } -void UDrawTablet::Update() +void UDrawTablet::BuildDesiredExtensionState(DesiredExtensionState* target_state) { DataFormat tablet_data = {}; @@ -105,7 +107,12 @@ void UDrawTablet::Update() // Always 0xff tablet_data.unk = 0xff; - Common::BitCastPtr(&m_reg.controller_data) = tablet_data; + target_state->data = tablet_data; +} + +void UDrawTablet::Update(const DesiredExtensionState& target_state) +{ + DefaultExtensionUpdate(&m_reg, target_state); } void UDrawTablet::Reset() diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.h b/Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.h index e7569ffb23..7052b55ede 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.h @@ -27,7 +27,8 @@ class UDrawTablet : public Extension3rdParty public: UDrawTablet(); - void Update() override; + void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; + void Update(const DesiredExtensionState& target_state) override; void Reset() override; ControllerEmu::ControlGroup* GetGroup(UDrawTabletGroup group); diff --git a/Source/Core/Core/HW/WiimoteEmu/MotionPlus.cpp b/Source/Core/Core/HW/WiimoteEmu/MotionPlus.cpp index 8d985abfea..11441a0ae2 100644 --- a/Source/Core/Core/HW/WiimoteEmu/MotionPlus.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/MotionPlus.cpp @@ -18,6 +18,7 @@ #include "Core/HW/Wiimote.h" #include "Core/HW/WiimoteEmu/Dynamics.h" +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" namespace { @@ -387,7 +388,12 @@ bool MotionPlus::ReadDeviceDetectPin() const } } -void MotionPlus::Update() +void MotionPlus::BuildDesiredExtensionState(DesiredExtensionState* target_state) +{ + // MotionPlus is handled separately, nothing to do here. +} + +void MotionPlus::Update(const DesiredExtensionState& target_state) { if (m_progress_timer) --m_progress_timer; diff --git a/Source/Core/Core/HW/WiimoteEmu/MotionPlus.h b/Source/Core/Core/HW/WiimoteEmu/MotionPlus.h index ced21d8599..28386f9107 100644 --- a/Source/Core/Core/HW/WiimoteEmu/MotionPlus.h +++ b/Source/Core/Core/HW/WiimoteEmu/MotionPlus.h @@ -118,7 +118,8 @@ public: MotionPlus(); - void Update() override; + void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; + void Update(const DesiredExtensionState& target_state) override; void Reset() override; void DoState(PointerWrap& p) override; diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 33eaa9bef3..bdc4fbe3f9 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -27,6 +27,7 @@ #include "Core/HW/WiimoteCommon/WiimoteHid.h" #include "Core/HW/WiimoteEmu/DesiredWiimoteState.h" #include "Core/HW/WiimoteEmu/Extension/Classic.h" +#include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h" #include "Core/HW/WiimoteEmu/Extension/Drums.h" #include "Core/HW/WiimoteEmu/Extension/Guitar.h" @@ -465,6 +466,13 @@ DesiredWiimoteState Wiimote::BuildDesiredWiimoteState() if (m_motion_plus_setting.GetValue()) wiimote_state.motion_plus = MotionPlus::GetGyroscopeData(GetTotalAngularVelocity()); + // Build Extension state. + // This also allows the extension to perform any regular duties it may need. + // (e.g. Nunchuk motion simulation step) + static_cast( + m_attachments->GetAttachmentList()[m_attachments->GetSelectedAttachment()].get()) + ->BuildDesiredExtensionState(&wiimote_state.extension); + return wiimote_state; } @@ -480,19 +488,16 @@ void Wiimote::Update() UpdateButtonsStatus(target_state); // If a new extension is requested in the GUI the change will happen here. - HandleExtensionSwap(static_cast(m_attachments->GetSelectedAttachment()), + HandleExtensionSwap(static_cast(target_state.extension.data.index()), target_state.motion_plus.has_value()); - // Allow extension to perform any regular duties it may need. - // (e.g. Nunchuk motion simulation step) - // Input is prepared here too. - // TODO: Separate input preparation from Update. - GetActiveExtension()->Update(); + // Prepare input data of the extension for reading. + GetActiveExtension()->Update(target_state.extension); if (m_is_motion_plus_attached) { // M+ has some internal state that must processed. - m_motion_plus.Update(); + m_motion_plus.Update(target_state.extension); } // Returns true if a report was sent. diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h index 9d6c3a0de1..b2c54d573e 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h @@ -38,6 +38,7 @@ class Tilt; namespace WiimoteEmu { struct DesiredWiimoteState; +struct DesiredExtensionState; enum class WiimoteGroup { diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 73b5bd61d0..1c02a44eec 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -318,6 +318,7 @@ +