WiimoteEmu: Clean up variant handling in DesiredExtensionState.

This commit is contained in:
Jordan Woyak
2025-02-25 01:26:04 -06:00
parent 1d481a395a
commit 0d0734e083
9 changed files with 37 additions and 122 deletions

View File

@ -10,16 +10,8 @@
#include "Common/BitUtils.h" #include "Common/BitUtils.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/VariantUtil.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/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/MotionPlus.h" #include "Core/HW/WiimoteEmu/MotionPlus.h"
namespace WiimoteEmu namespace WiimoteEmu
@ -114,13 +106,9 @@ SerializedWiimoteState SerializeDesiredState(const DesiredWiimoteState& state)
std::visit( std::visit(
[&s](const auto& arg) { [&s](const auto& arg) {
using T = std::decay_t<decltype(arg)>; using T = std::decay_t<decltype(arg)>;
if constexpr (!std::is_same_v<std::monostate, T>)
{
static_assert(sizeof(arg) <= 6); static_assert(sizeof(arg) <= 6);
static_assert(std::is_trivially_copyable_v<T>); Common::BitCastPtr<T>(&s.data[s.length]) = arg;
std::memcpy(&s.data[s.length], &arg, sizeof(arg));
s.length += sizeof(arg); s.length += sizeof(arg);
}
}, },
state.extension.data); state.extension.data);
} }
@ -128,19 +116,6 @@ SerializedWiimoteState SerializeDesiredState(const DesiredWiimoteState& state)
return s; return s;
} }
template <typename T>
static bool DeserializeExtensionState(DesiredWiimoteState* state,
const SerializedWiimoteState& serialized, size_t offset)
{
if (serialized.length < offset + sizeof(T))
return false;
auto& e = state->extension.data.emplace<T>();
static_assert(std::is_trivially_copyable_v<T>);
std::memcpy(static_cast<void*>(&e), static_cast<const void*>(&serialized.data[offset]),
sizeof(T));
return true;
}
bool DeserializeDesiredState(DesiredWiimoteState* state, const SerializedWiimoteState& serialized) bool DeserializeDesiredState(DesiredWiimoteState* state, const SerializedWiimoteState& serialized)
{ {
// clear state // clear state
@ -181,39 +156,10 @@ bool DeserializeDesiredState(DesiredWiimoteState* state, const SerializedWiimote
s += 12; s += 12;
if (has_motion_plus) if (has_motion_plus)
s += 6; s += 6;
switch (extension) if (extension)
{ {
case ExtensionNumber::NONE: WithVariantAlternative<DesiredExtensionState::ExtensionData>(
break; extension, [&]<typename T>() { s += sizeof(T); });
case ExtensionNumber::NUNCHUK:
s += sizeof(Nunchuk::DataFormat);
break;
case ExtensionNumber::CLASSIC:
s += sizeof(Classic::DataFormat);
break;
case ExtensionNumber::GUITAR:
s += sizeof(Guitar::DataFormat);
break;
case ExtensionNumber::DRUMS:
s += sizeof(Drums::DesiredState);
break;
case ExtensionNumber::TURNTABLE:
s += sizeof(Turntable::DataFormat);
break;
case ExtensionNumber::UDRAW_TABLET:
s += sizeof(UDrawTablet::DataFormat);
break;
case ExtensionNumber::DRAWSOME_TABLET:
s += sizeof(DrawsomeTablet::DataFormat);
break;
case ExtensionNumber::TATACON:
s += sizeof(TaTaCon::DataFormat);
break;
case ExtensionNumber::SHINKANSEN:
s += sizeof(Shinkansen::DesiredState);
break;
default:
break;
} }
return s; return s;
}(); }();
@ -283,32 +229,13 @@ bool DeserializeDesiredState(DesiredWiimoteState* state, const SerializedWiimote
pos += 6; pos += 6;
} }
switch (extension) if (extension)
{ {
case ExtensionNumber::NONE: WithVariantAlternative<DesiredExtensionState::ExtensionData>(extension, [&]<typename T>() {
return true; state->extension.data.emplace<T>(Common::BitCastPtr<T>(&d[pos]));
case ExtensionNumber::NUNCHUK: });
return DeserializeExtensionState<Nunchuk::DataFormat>(state, serialized, pos);
case ExtensionNumber::CLASSIC:
return DeserializeExtensionState<Classic::DataFormat>(state, serialized, pos);
case ExtensionNumber::GUITAR:
return DeserializeExtensionState<Guitar::DataFormat>(state, serialized, pos);
case ExtensionNumber::DRUMS:
return DeserializeExtensionState<Drums::DesiredState>(state, serialized, pos);
case ExtensionNumber::TURNTABLE:
return DeserializeExtensionState<Turntable::DataFormat>(state, serialized, pos);
case ExtensionNumber::UDRAW_TABLET:
return DeserializeExtensionState<UDrawTablet::DataFormat>(state, serialized, pos);
case ExtensionNumber::DRAWSOME_TABLET:
return DeserializeExtensionState<DrawsomeTablet::DataFormat>(state, serialized, pos);
case ExtensionNumber::TATACON:
return DeserializeExtensionState<TaTaCon::DataFormat>(state, serialized, pos);
case ExtensionNumber::SHINKANSEN:
return DeserializeExtensionState<Shinkansen::DesiredState>(state, serialized, pos);
default:
break;
} }
return false; return true;
} }
} // namespace WiimoteEmu } // namespace WiimoteEmu

View File

@ -129,6 +129,8 @@ public:
}; };
static_assert(sizeof(DataFormat) == 6, "Wrong size"); static_assert(sizeof(DataFormat) == 6, "Wrong size");
using DesiredState = DataFormat;
static constexpr int CAL_STICK_BITS = 8; static constexpr int CAL_STICK_BITS = 8;
static constexpr int CAL_TRIGGER_BITS = 8; static constexpr int CAL_TRIGGER_BITS = 8;

View File

@ -3,7 +3,6 @@
#pragma once #pragma once
#include <type_traits>
#include <variant> #include <variant>
#include "Common/BitUtils.h" #include "Common/BitUtils.h"
@ -18,46 +17,23 @@
#include "Core/HW/WiimoteEmu/Extension/TaTaCon.h" #include "Core/HW/WiimoteEmu/Extension/TaTaCon.h"
#include "Core/HW/WiimoteEmu/Extension/Turntable.h" #include "Core/HW/WiimoteEmu/Extension/Turntable.h"
#include "Core/HW/WiimoteEmu/Extension/UDrawTablet.h" #include "Core/HW/WiimoteEmu/Extension/UDrawTablet.h"
#include "Core/HW/WiimoteEmu/ExtensionPort.h"
namespace WiimoteEmu namespace WiimoteEmu
{ {
struct DesiredExtensionState struct DesiredExtensionState
{ {
using ExtensionData = private:
std::variant<std::monostate, Nunchuk::DataFormat, Classic::DataFormat, Guitar::DataFormat, template <typename... Ts>
Drums::DesiredState, Turntable::DataFormat, UDrawTablet::DataFormat, struct ExtDataImpl
DrawsomeTablet::DataFormat, TaTaCon::DataFormat, Shinkansen::DesiredState>; {
ExtensionData data = std::monostate(); using type = std::variant<std::monostate, typename Ts::DesiredState...>;
};
static_assert(std::is_same_v<std::monostate, public:
std::variant_alternative_t<ExtensionNumber::NONE, ExtensionData>>); using ExtensionData = ExtDataImpl<Nunchuk, Classic, Guitar, Drums, Turntable, UDrawTablet,
static_assert( DrawsomeTablet, TaTaCon, Shinkansen>::type;
std::is_same_v<Nunchuk::DataFormat,
std::variant_alternative_t<ExtensionNumber::NUNCHUK, ExtensionData>>); ExtensionData data = std::monostate{};
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> template <typename T>

View File

@ -50,9 +50,10 @@ public:
BitField<3, 5, u8> status; BitField<3, 5, u8> status;
}; };
}; };
static_assert(6 == sizeof(DataFormat), "Wrong size."); static_assert(6 == sizeof(DataFormat), "Wrong size.");
using DesiredState = DataFormat;
private: private:
ControllerEmu::AnalogStick* m_stylus; ControllerEmu::AnalogStick* m_stylus;
ControllerEmu::Triggers* m_touch; ControllerEmu::Triggers* m_touch;

View File

@ -48,6 +48,8 @@ public:
}; };
static_assert(sizeof(DataFormat) == 6, "Wrong size"); static_assert(sizeof(DataFormat) == 6, "Wrong size");
using DesiredState = DataFormat;
Guitar(); Guitar();
void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; void BuildDesiredExtensionState(DesiredExtensionState* target_state) override;

View File

@ -116,6 +116,8 @@ public:
}; };
static_assert(sizeof(DataFormat) == 6, "Wrong size"); static_assert(sizeof(DataFormat) == 6, "Wrong size");
using DesiredState = DataFormat;
struct CalibrationData struct CalibrationData
{ {
using StickType = DataFormat::StickType; using StickType = DataFormat::StickType;

View File

@ -29,6 +29,8 @@ public:
}; };
static_assert(sizeof(DataFormat) == 6, "Wrong size"); static_assert(sizeof(DataFormat) == 6, "Wrong size");
using DesiredState = DataFormat;
TaTaCon(); TaTaCon();
void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; void BuildDesiredExtensionState(DesiredExtensionState* target_state) override;

View File

@ -54,6 +54,8 @@ public:
}; };
static_assert(sizeof(DataFormat) == 6, "Wrong size"); static_assert(sizeof(DataFormat) == 6, "Wrong size");
using DesiredState = DataFormat;
Turntable(); Turntable();
void BuildDesiredExtensionState(DesiredExtensionState* target_state) override; void BuildDesiredExtensionState(DesiredExtensionState* target_state) override;

View File

@ -56,9 +56,10 @@ public:
// 0x04 is always unset (neutral state is 0xfb) // 0x04 is always unset (neutral state is 0xfb)
u8 buttons; u8 buttons;
}; };
static_assert(6 == sizeof(DataFormat), "Wrong size."); static_assert(6 == sizeof(DataFormat), "Wrong size.");
using DesiredState = DataFormat;
private: private:
ControllerEmu::Buttons* m_buttons; ControllerEmu::Buttons* m_buttons;
ControllerEmu::AnalogStick* m_stylus; ControllerEmu::AnalogStick* m_stylus;