mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-25 06:44:59 +00:00
Merge pull request #13378 from jordan-woyak/desired-ext-state
WiimoteEmu: Clean up variant handling in DesiredExtensionState.
This commit is contained in:
commit
1bd3e79fda
10 changed files with 72 additions and 121 deletions
|
@ -34,3 +34,18 @@ struct overloaded : Ts...
|
||||||
|
|
||||||
template <class... Ts>
|
template <class... Ts>
|
||||||
overloaded(Ts...) -> overloaded<Ts...>;
|
overloaded(Ts...) -> overloaded<Ts...>;
|
||||||
|
|
||||||
|
// Visits a functor with a variant_alternative of the given index.
|
||||||
|
// e.g. WithVariantAlternative<variant<int, float>>(1, func) calls func<float>()
|
||||||
|
// An out-of-bounds index causes no visitation.
|
||||||
|
template <typename Variant, std::size_t I = 0, typename Func>
|
||||||
|
void WithVariantAlternative(std::size_t index, Func&& func)
|
||||||
|
{
|
||||||
|
if constexpr (I < std::variant_size_v<Variant>)
|
||||||
|
{
|
||||||
|
if (index == 0)
|
||||||
|
func.template operator()<std::variant_alternative_t<I, Variant>>();
|
||||||
|
else
|
||||||
|
WithVariantAlternative<Variant, I + 1>(index - 1, std::forward<Func>(func));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
{
|
Common::BitCastPtr<T>(&s.data[s.length]) = arg;
|
||||||
static_assert(sizeof(arg) <= 6);
|
s.length += sizeof(arg);
|
||||||
static_assert(std::is_trivially_copyable_v<T>);
|
|
||||||
std::memcpy(&s.data[s.length], &arg, 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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include "Common/BitUtils.h"
|
#include "Common/BitUtils.h"
|
||||||
|
@ -24,40 +23,38 @@ namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
struct DesiredExtensionState
|
struct DesiredExtensionState
|
||||||
{
|
{
|
||||||
using ExtensionData =
|
private:
|
||||||
std::variant<std::monostate, Nunchuk::DataFormat, Classic::DataFormat, Guitar::DataFormat,
|
template <ExtensionNumber N, typename T>
|
||||||
Drums::DesiredState, Turntable::DataFormat, UDrawTablet::DataFormat,
|
struct ExtNumTypePair
|
||||||
DrawsomeTablet::DataFormat, TaTaCon::DataFormat, Shinkansen::DesiredState>;
|
{
|
||||||
ExtensionData data = std::monostate();
|
static constexpr ExtensionNumber ext_num = N;
|
||||||
|
using ext_type = T;
|
||||||
|
};
|
||||||
|
|
||||||
static_assert(std::is_same_v<std::monostate,
|
template <typename... Ts>
|
||||||
std::variant_alternative_t<ExtensionNumber::NONE, ExtensionData>>);
|
struct ExtDataImpl
|
||||||
static_assert(
|
{
|
||||||
std::is_same_v<Nunchuk::DataFormat,
|
using type = std::variant<std::monostate, typename Ts::ext_type::DesiredState...>;
|
||||||
std::variant_alternative_t<ExtensionNumber::NUNCHUK, ExtensionData>>);
|
|
||||||
static_assert(
|
static_assert((std::is_same_v<std::variant_alternative_t<Ts::ext_num, type>,
|
||||||
std::is_same_v<Classic::DataFormat,
|
typename Ts::ext_type::DesiredState> &&
|
||||||
std::variant_alternative_t<ExtensionNumber::CLASSIC, ExtensionData>>);
|
...),
|
||||||
static_assert(std::is_same_v<Guitar::DataFormat,
|
"Please use ExtensionNumber enum order for DTM file index consistency.");
|
||||||
std::variant_alternative_t<ExtensionNumber::GUITAR, ExtensionData>>);
|
};
|
||||||
static_assert(std::is_same_v<Drums::DesiredState,
|
|
||||||
std::variant_alternative_t<ExtensionNumber::DRUMS, ExtensionData>>);
|
public:
|
||||||
static_assert(
|
using ExtensionData =
|
||||||
std::is_same_v<Turntable::DataFormat,
|
ExtDataImpl<ExtNumTypePair<ExtensionNumber::NUNCHUK, Nunchuk>,
|
||||||
std::variant_alternative_t<ExtensionNumber::TURNTABLE, ExtensionData>>);
|
ExtNumTypePair<ExtensionNumber::CLASSIC, Classic>,
|
||||||
static_assert(
|
ExtNumTypePair<ExtensionNumber::GUITAR, Guitar>,
|
||||||
std::is_same_v<UDrawTablet::DataFormat,
|
ExtNumTypePair<ExtensionNumber::DRUMS, Drums>,
|
||||||
std::variant_alternative_t<ExtensionNumber::UDRAW_TABLET, ExtensionData>>);
|
ExtNumTypePair<ExtensionNumber::TURNTABLE, Turntable>,
|
||||||
static_assert(
|
ExtNumTypePair<ExtensionNumber::UDRAW_TABLET, UDrawTablet>,
|
||||||
std::is_same_v<DrawsomeTablet::DataFormat,
|
ExtNumTypePair<ExtensionNumber::DRAWSOME_TABLET, DrawsomeTablet>,
|
||||||
std::variant_alternative_t<ExtensionNumber::DRAWSOME_TABLET, ExtensionData>>);
|
ExtNumTypePair<ExtensionNumber::TATACON, TaTaCon>,
|
||||||
static_assert(
|
ExtNumTypePair<ExtensionNumber::SHINKANSEN, Shinkansen>>::type;
|
||||||
std::is_same_v<TaTaCon::DataFormat,
|
|
||||||
std::variant_alternative_t<ExtensionNumber::TATACON, ExtensionData>>);
|
ExtensionData data = std::monostate{};
|
||||||
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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue