WiimoteEmu: Update extensions from DesiredWiimoteState.

This commit is contained in:
Admiral H. Curtiss 2022-09-17 16:36:37 +02:00
parent e7543a9e05
commit 466f0b377b
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
28 changed files with 283 additions and 58 deletions

View File

@ -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

View File

@ -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<CameraPoint, 2> camera_points = DEFAULT_CAMERA;
std::optional<MotionPlus::DataFormat::Data> motion_plus = std::nullopt;
DesiredExtensionState extension;
};
} // namespace WiimoteEmu

View File

@ -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<DataFormat>(&m_reg.controller_data) = classic_data;
target_state->data = classic_data;
}
void Classic::Update(const DesiredExtensionState& target_state)
{
DefaultExtensionUpdate<DataFormat>(&m_reg, target_state);
}
void Classic::Reset()

View File

@ -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);

View File

@ -0,0 +1,76 @@
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <type_traits>
#include <variant>
#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<std::monostate, Nunchuk::DataFormat, Classic::DataFormat, Guitar::DataFormat,
Drums::DesiredState, Turntable::DataFormat, UDrawTablet::DataFormat,
DrawsomeTablet::DataFormat, TaTaCon::DataFormat, Shinkansen::DesiredState>;
ExtensionData data = std::monostate();
static_assert(std::is_same_v<std::monostate,
std::variant_alternative_t<ExtensionNumber::NONE, ExtensionData>>);
static_assert(
std::is_same_v<Nunchuk::DataFormat,
std::variant_alternative_t<ExtensionNumber::NUNCHUK, ExtensionData>>);
static_assert(
std::is_same_v<Classic::DataFormat,
std::variant_alternative_t<ExtensionNumber::CLASSIC, ExtensionData>>);
static_assert(std::is_same_v<Guitar::DataFormat,
std::variant_alternative_t<ExtensionNumber::GUITAR, ExtensionData>>);
static_assert(std::is_same_v<Drums::DesiredState,
std::variant_alternative_t<ExtensionNumber::DRUMS, ExtensionData>>);
static_assert(
std::is_same_v<Turntable::DataFormat,
std::variant_alternative_t<ExtensionNumber::TURNTABLE, ExtensionData>>);
static_assert(
std::is_same_v<UDrawTablet::DataFormat,
std::variant_alternative_t<ExtensionNumber::UDRAW_TABLET, ExtensionData>>);
static_assert(
std::is_same_v<DrawsomeTablet::DataFormat,
std::variant_alternative_t<ExtensionNumber::DRAWSOME_TABLET, ExtensionData>>);
static_assert(
std::is_same_v<TaTaCon::DataFormat,
std::variant_alternative_t<ExtensionNumber::TATACON, ExtensionData>>);
static_assert(
std::is_same_v<Shinkansen::DesiredState,
std::variant_alternative_t<ExtensionNumber::SHINKANSEN, ExtensionData>>);
static_assert(std::variant_size_v<DesiredExtensionState::ExtensionData> == ExtensionNumber::MAX);
};
template <typename T>
void DefaultExtensionUpdate(EncryptedExtension::Register* reg,
const DesiredExtensionState& target_state)
{
if (std::holds_alternative<T>(target_state.data))
{
Common::BitCastPtr<T>(&reg->controller_data) = std::get<T>(target_state.data);
}
else
{
Common::BitCastPtr<T>(&reg->controller_data) = T{};
}
}
} // namespace WiimoteEmu

View File

@ -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<DataFormat>();
// 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<DataFormat>(&m_reg.controller_data) = tablet_data;
void DrawsomeTablet::Update(const DesiredExtensionState& target_state)
{
DefaultExtensionUpdate<DataFormat>(&m_reg, target_state);
}
void DrawsomeTablet::Reset()

View File

@ -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);

View File

@ -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<DesiredState>();
{
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<DesiredState>(target_state.data))
{
desired_state = std::get<DesiredState>(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(&current_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;

View File

@ -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);

View File

@ -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<std::monostate>();
}
void None::Update(const DesiredExtensionState& target_state)
{
// Nothing needed.
}

View File

@ -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;

View File

@ -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<DataFormat>(&m_reg.controller_data) = guitar_data;
target_state->data = guitar_data;
}
void Guitar::Update(const DesiredExtensionState& target_state)
{
DefaultExtensionUpdate<DataFormat>(&m_reg, target_state);
}
void Guitar::Reset()

View File

@ -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);

View File

@ -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<DataFormat>(&m_reg.controller_data) = nc_data;
target_state->data = nc_data;
}
void Nunchuk::Update(const DesiredExtensionState& target_state)
{
DefaultExtensionUpdate<DataFormat>(&m_reg, target_state);
}
void Nunchuk::Reset()

View File

@ -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;

View File

@ -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<DesiredState>();
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<DesiredState>(target_state.data))
{
desired_state = std::get<DesiredState>(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<DataFormat>(&m_reg.controller_data) = ext_data;
const auto lock = GetStateLock();

View File

@ -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);

View File

@ -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<DataFormat>(&m_reg.controller_data) = tatacon_data;
target_state->data = tatacon_data;
}
void TaTaCon::Update(const DesiredExtensionState& target_state)
{
DefaultExtensionUpdate<DataFormat>(&m_reg, target_state);
}
void TaTaCon::Reset()

View File

@ -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);

View File

@ -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<DataFormat>(&m_reg.controller_data) = tt_data;
target_state->data = tt_data;
}
void Turntable::Update(const DesiredExtensionState& target_state)
{
DefaultExtensionUpdate<DataFormat>(&m_reg, target_state);
}
void Turntable::Reset()

View File

@ -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);

View File

@ -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<DataFormat>(&m_reg.controller_data) = tablet_data;
target_state->data = tablet_data;
}
void UDrawTablet::Update(const DesiredExtensionState& target_state)
{
DefaultExtensionUpdate<DataFormat>(&m_reg, target_state);
}
void UDrawTablet::Reset()

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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<Extension*>(
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<ExtensionNumber>(m_attachments->GetSelectedAttachment()),
HandleExtensionSwap(static_cast<ExtensionNumber>(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.

View File

@ -38,6 +38,7 @@ class Tilt;
namespace WiimoteEmu
{
struct DesiredWiimoteState;
struct DesiredExtensionState;
enum class WiimoteGroup
{

View File

@ -318,6 +318,7 @@
<ClInclude Include="Core\HW\WiimoteEmu\DesiredWiimoteState.h" />
<ClInclude Include="Core\HW\WiimoteEmu\Encryption.h" />
<ClInclude Include="Core\HW\WiimoteEmu\Extension\Classic.h" />
<ClInclude Include="Core\HW\WiimoteEmu\Extension\DesiredExtensionState.h" />
<ClInclude Include="Core\HW\WiimoteEmu\Extension\DrawsomeTablet.h" />
<ClInclude Include="Core\HW\WiimoteEmu\Extension\Drums.h" />
<ClInclude Include="Core\HW\WiimoteEmu\Extension\Extension.h" />