Merge pull request #4866 from Morph1984/mjolnir-p3-prod
Project Mjölnir: Part 3 - Controller Profiles and Vibration Rework
This commit is contained in:
commit
abda366362
69 changed files with 3401 additions and 1588 deletions
|
@ -230,10 +230,8 @@ void Adapter::SendVibrations() {
|
|||
vibration_changed = false;
|
||||
}
|
||||
|
||||
bool Adapter::RumblePlay(std::size_t port, f32 amplitude) {
|
||||
amplitude = std::clamp(amplitude, 0.0f, 1.0f);
|
||||
const auto raw_amp = static_cast<u8>(amplitude * 0x8);
|
||||
pads[port].rumble_amplitude = raw_amp;
|
||||
bool Adapter::RumblePlay(std::size_t port, u8 amplitude) {
|
||||
pads[port].rumble_amplitude = amplitude;
|
||||
|
||||
return rumble_enabled;
|
||||
}
|
||||
|
|
|
@ -77,8 +77,8 @@ public:
|
|||
Adapter();
|
||||
~Adapter();
|
||||
|
||||
/// Request a vibration for a controlelr
|
||||
bool RumblePlay(std::size_t port, f32 amplitude);
|
||||
/// Request a vibration for a controller
|
||||
bool RumblePlay(std::size_t port, u8 amplitude);
|
||||
|
||||
/// Used for polling
|
||||
void BeginConfiguration();
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace InputCommon {
|
|||
|
||||
class GCButton final : public Input::ButtonDevice {
|
||||
public:
|
||||
explicit GCButton(u32 port_, s32 button_, GCAdapter::Adapter* adapter)
|
||||
explicit GCButton(u32 port_, s32 button_, const GCAdapter::Adapter* adapter)
|
||||
: port(port_), button(button_), gcadapter(adapter) {}
|
||||
|
||||
~GCButton() override;
|
||||
|
@ -27,18 +27,10 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const override {
|
||||
const float amplitude = amp_high + amp_low > 2.0f ? 1.0f : (amp_high + amp_low) * 0.5f;
|
||||
const auto new_amp =
|
||||
static_cast<f32>(pow(amplitude, 0.5f) * (3.0f - 2.0f * pow(amplitude, 0.15f)));
|
||||
|
||||
return gcadapter->RumblePlay(port, new_amp);
|
||||
}
|
||||
|
||||
private:
|
||||
const u32 port;
|
||||
const s32 button;
|
||||
GCAdapter::Adapter* gcadapter;
|
||||
const GCAdapter::Adapter* gcadapter;
|
||||
};
|
||||
|
||||
class GCAxisButton final : public Input::ButtonDevice {
|
||||
|
@ -299,4 +291,42 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
|
|||
return params;
|
||||
}
|
||||
|
||||
class GCVibration final : public Input::VibrationDevice {
|
||||
public:
|
||||
explicit GCVibration(u32 port_, GCAdapter::Adapter* adapter)
|
||||
: port(port_), gcadapter(adapter) {}
|
||||
|
||||
u8 GetStatus() const override {
|
||||
return gcadapter->RumblePlay(port, 0);
|
||||
}
|
||||
|
||||
bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override {
|
||||
const auto mean_amplitude = (amp_low + amp_high) * 0.5f;
|
||||
const auto processed_amplitude = static_cast<u8>(
|
||||
pow(mean_amplitude, 0.5f) * (3.0f - 2.0f * pow(mean_amplitude, 0.15f)) * 0x8);
|
||||
|
||||
return gcadapter->RumblePlay(port, processed_amplitude);
|
||||
}
|
||||
|
||||
private:
|
||||
const u32 port;
|
||||
GCAdapter::Adapter* gcadapter;
|
||||
};
|
||||
|
||||
/// An vibration device factory that creates vibration devices from GC Adapter
|
||||
GCVibrationFactory::GCVibrationFactory(std::shared_ptr<GCAdapter::Adapter> adapter_)
|
||||
: adapter(std::move(adapter_)) {}
|
||||
|
||||
/**
|
||||
* Creates a vibration device from a joystick
|
||||
* @param params contains parameters for creating the device:
|
||||
* - "port": the nth gcpad on the adapter
|
||||
*/
|
||||
std::unique_ptr<Input::VibrationDevice> GCVibrationFactory::Create(
|
||||
const Common::ParamPackage& params) {
|
||||
const auto port = static_cast<u32>(params.Get("port", 0));
|
||||
|
||||
return std::make_unique<GCVibration>(port, adapter.get());
|
||||
}
|
||||
|
||||
} // namespace InputCommon
|
||||
|
|
|
@ -64,4 +64,15 @@ private:
|
|||
bool polling = false;
|
||||
};
|
||||
|
||||
/// A vibration device factory creates vibration devices from GC Adapter
|
||||
class GCVibrationFactory final : public Input::Factory<Input::VibrationDevice> {
|
||||
public:
|
||||
explicit GCVibrationFactory(std::shared_ptr<GCAdapter::Adapter> adapter_);
|
||||
|
||||
std::unique_ptr<Input::VibrationDevice> Create(const Common::ParamPackage& params) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<GCAdapter::Adapter> adapter;
|
||||
};
|
||||
|
||||
} // namespace InputCommon
|
||||
|
|
|
@ -28,6 +28,8 @@ struct InputSubsystem::Impl {
|
|||
Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons);
|
||||
gcanalog = std::make_shared<GCAnalogFactory>(gcadapter);
|
||||
Input::RegisterFactory<Input::AnalogDevice>("gcpad", gcanalog);
|
||||
gcvibration = std::make_shared<GCVibrationFactory>(gcadapter);
|
||||
Input::RegisterFactory<Input::VibrationDevice>("gcpad", gcvibration);
|
||||
|
||||
keyboard = std::make_shared<Keyboard>();
|
||||
Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard);
|
||||
|
@ -64,9 +66,11 @@ struct InputSubsystem::Impl {
|
|||
#endif
|
||||
Input::UnregisterFactory<Input::ButtonDevice>("gcpad");
|
||||
Input::UnregisterFactory<Input::AnalogDevice>("gcpad");
|
||||
Input::UnregisterFactory<Input::VibrationDevice>("gcpad");
|
||||
|
||||
gcbuttons.reset();
|
||||
gcanalog.reset();
|
||||
gcvibration.reset();
|
||||
|
||||
Input::UnregisterFactory<Input::MotionDevice>("cemuhookudp");
|
||||
Input::UnregisterFactory<Input::TouchDevice>("cemuhookudp");
|
||||
|
@ -78,7 +82,7 @@ struct InputSubsystem::Impl {
|
|||
[[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const {
|
||||
std::vector<Common::ParamPackage> devices = {
|
||||
Common::ParamPackage{{"display", "Any"}, {"class", "any"}},
|
||||
Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "key"}},
|
||||
Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "keyboard"}},
|
||||
};
|
||||
#ifdef HAVE_SDL2
|
||||
auto sdl_devices = sdl->GetInputDevices();
|
||||
|
@ -96,10 +100,6 @@ struct InputSubsystem::Impl {
|
|||
if (!params.Has("class") || params.Get("class", "") == "any") {
|
||||
return {};
|
||||
}
|
||||
if (params.Get("class", "") == "key") {
|
||||
// TODO consider returning the SDL key codes for the default keybindings
|
||||
return {};
|
||||
}
|
||||
if (params.Get("class", "") == "gcpad") {
|
||||
return gcadapter->GetAnalogMappingForDevice(params);
|
||||
}
|
||||
|
@ -116,10 +116,6 @@ struct InputSubsystem::Impl {
|
|||
if (!params.Has("class") || params.Get("class", "") == "any") {
|
||||
return {};
|
||||
}
|
||||
if (params.Get("class", "") == "key") {
|
||||
// TODO consider returning the SDL key codes for the default keybindings
|
||||
return {};
|
||||
}
|
||||
if (params.Get("class", "") == "gcpad") {
|
||||
return gcadapter->GetButtonMappingForDevice(params);
|
||||
}
|
||||
|
@ -150,6 +146,7 @@ struct InputSubsystem::Impl {
|
|||
#endif
|
||||
std::shared_ptr<GCButtonFactory> gcbuttons;
|
||||
std::shared_ptr<GCAnalogFactory> gcanalog;
|
||||
std::shared_ptr<GCVibrationFactory> gcvibration;
|
||||
std::shared_ptr<UDPMotionFactory> udpmotion;
|
||||
std::shared_ptr<UDPTouchFactory> udptouch;
|
||||
std::shared_ptr<CemuhookUDP::Client> udp;
|
||||
|
|
|
@ -80,30 +80,13 @@ public:
|
|||
return static_cast<float>(state.axes.at(axis)) / (32767.0f * range);
|
||||
}
|
||||
|
||||
bool RumblePlay(f32 amp_low, f32 amp_high, u32 time) {
|
||||
const u16 raw_amp_low = static_cast<u16>(amp_low * 0xFFFF);
|
||||
const u16 raw_amp_high = static_cast<u16>(amp_high * 0xFFFF);
|
||||
// Lower drastically the number of state changes
|
||||
if (raw_amp_low >> 11 == last_state_rumble_low >> 11 &&
|
||||
raw_amp_high >> 11 == last_state_rumble_high >> 11) {
|
||||
if (raw_amp_low + raw_amp_high != 0 ||
|
||||
last_state_rumble_low + last_state_rumble_high == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Don't change state if last vibration was < 20ms
|
||||
const auto now = std::chrono::system_clock::now();
|
||||
if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_vibration) <
|
||||
std::chrono::milliseconds(20)) {
|
||||
return raw_amp_low + raw_amp_high == 0;
|
||||
bool RumblePlay(u16 amp_low, u16 amp_high) {
|
||||
if (sdl_controller) {
|
||||
return SDL_GameControllerRumble(sdl_controller.get(), amp_low, amp_high, 0) == 0;
|
||||
} else if (sdl_joystick) {
|
||||
return SDL_JoystickRumble(sdl_joystick.get(), amp_low, amp_high, 0) == 0;
|
||||
}
|
||||
|
||||
last_vibration = now;
|
||||
last_state_rumble_low = raw_amp_low;
|
||||
last_state_rumble_high = raw_amp_high;
|
||||
if (sdl_joystick) {
|
||||
SDL_JoystickRumble(sdl_joystick.get(), raw_amp_low, raw_amp_high, time);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -172,9 +155,6 @@ private:
|
|||
} state;
|
||||
std::string guid;
|
||||
int port;
|
||||
u16 last_state_rumble_high = 0;
|
||||
u16 last_state_rumble_low = 0;
|
||||
std::chrono::time_point<std::chrono::system_clock> last_vibration;
|
||||
std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick;
|
||||
std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller;
|
||||
mutable std::mutex mutex;
|
||||
|
@ -327,12 +307,6 @@ public:
|
|||
return joystick->GetButton(button);
|
||||
}
|
||||
|
||||
bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const override {
|
||||
const f32 new_amp_low = pow(amp_low, 0.5f) * (3.0f - 2.0f * pow(amp_low, 0.15f));
|
||||
const f32 new_amp_high = pow(amp_high, 0.5f) * (3.0f - 2.0f * pow(amp_high, 0.15f));
|
||||
return joystick->RumblePlay(new_amp_low, new_amp_high, 250);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<SDLJoystick> joystick;
|
||||
int button;
|
||||
|
@ -416,6 +390,32 @@ private:
|
|||
const float range;
|
||||
};
|
||||
|
||||
class SDLVibration final : public Input::VibrationDevice {
|
||||
public:
|
||||
explicit SDLVibration(std::shared_ptr<SDLJoystick> joystick_)
|
||||
: joystick(std::move(joystick_)) {}
|
||||
|
||||
u8 GetStatus() const override {
|
||||
joystick->RumblePlay(1, 1);
|
||||
return joystick->RumblePlay(0, 0);
|
||||
}
|
||||
|
||||
bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override {
|
||||
const auto process_amplitude = [](f32 amplitude) {
|
||||
return static_cast<u16>(std::pow(amplitude, 0.5f) *
|
||||
(3.0f - 2.0f * std::pow(amplitude, 0.15f)) * 0xFFFF);
|
||||
};
|
||||
|
||||
const auto processed_amp_low = process_amplitude(amp_low);
|
||||
const auto processed_amp_high = process_amplitude(amp_high);
|
||||
|
||||
return joystick->RumblePlay(processed_amp_low, processed_amp_high);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<SDLJoystick> joystick;
|
||||
};
|
||||
|
||||
class SDLDirectionMotion final : public Input::MotionDevice {
|
||||
public:
|
||||
explicit SDLDirectionMotion(std::shared_ptr<SDLJoystick> joystick_, int hat_, Uint8 direction_)
|
||||
|
@ -558,7 +558,7 @@ class SDLAnalogFactory final : public Input::Factory<Input::AnalogDevice> {
|
|||
public:
|
||||
explicit SDLAnalogFactory(SDLState& state_) : state(state_) {}
|
||||
/**
|
||||
* Creates analog device from joystick axes
|
||||
* Creates an analog device from joystick axes
|
||||
* @param params contains parameters for creating the device:
|
||||
* - "guid": the guid of the joystick to bind
|
||||
* - "port": the nth joystick of the same type
|
||||
|
@ -584,6 +584,26 @@ private:
|
|||
SDLState& state;
|
||||
};
|
||||
|
||||
/// An vibration device factory that creates vibration devices from SDL joystick
|
||||
class SDLVibrationFactory final : public Input::Factory<Input::VibrationDevice> {
|
||||
public:
|
||||
explicit SDLVibrationFactory(SDLState& state_) : state(state_) {}
|
||||
/**
|
||||
* Creates a vibration device from a joystick
|
||||
* @param params contains parameters for creating the device:
|
||||
* - "guid": the guid of the joystick to bind
|
||||
* - "port": the nth joystick of the same type
|
||||
*/
|
||||
std::unique_ptr<Input::VibrationDevice> Create(const Common::ParamPackage& params) override {
|
||||
const std::string guid = params.Get("guid", "0");
|
||||
const int port = params.Get("port", 0);
|
||||
return std::make_unique<SDLVibration>(state.GetSDLJoystickByGUID(guid, port));
|
||||
}
|
||||
|
||||
private:
|
||||
SDLState& state;
|
||||
};
|
||||
|
||||
/// A motion device factory that creates motion devices from SDL joystick
|
||||
class SDLMotionFactory final : public Input::Factory<Input::MotionDevice> {
|
||||
public:
|
||||
|
@ -650,11 +670,13 @@ private:
|
|||
|
||||
SDLState::SDLState() {
|
||||
using namespace Input;
|
||||
analog_factory = std::make_shared<SDLAnalogFactory>(*this);
|
||||
button_factory = std::make_shared<SDLButtonFactory>(*this);
|
||||
analog_factory = std::make_shared<SDLAnalogFactory>(*this);
|
||||
vibration_factory = std::make_shared<SDLVibrationFactory>(*this);
|
||||
motion_factory = std::make_shared<SDLMotionFactory>(*this);
|
||||
RegisterFactory<AnalogDevice>("sdl", analog_factory);
|
||||
RegisterFactory<ButtonDevice>("sdl", button_factory);
|
||||
RegisterFactory<AnalogDevice>("sdl", analog_factory);
|
||||
RegisterFactory<VibrationDevice>("sdl", vibration_factory);
|
||||
RegisterFactory<MotionDevice>("sdl", motion_factory);
|
||||
|
||||
// If the frontend is going to manage the event loop, then we don't start one here
|
||||
|
@ -676,7 +698,7 @@ SDLState::SDLState() {
|
|||
using namespace std::chrono_literals;
|
||||
while (initialized) {
|
||||
SDL_PumpEvents();
|
||||
std::this_thread::sleep_for(5ms);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -691,6 +713,7 @@ SDLState::~SDLState() {
|
|||
using namespace Input;
|
||||
UnregisterFactory<ButtonDevice>("sdl");
|
||||
UnregisterFactory<AnalogDevice>("sdl");
|
||||
UnregisterFactory<VibrationDevice>("sdl");
|
||||
UnregisterFactory<MotionDevice>("sdl");
|
||||
|
||||
CloseJoysticks();
|
||||
|
@ -1045,7 +1068,6 @@ public:
|
|||
|
||||
void Start(const std::string& device_id) override {
|
||||
SDLPoller::Start(device_id);
|
||||
// Load the game controller
|
||||
// Reset stored axes
|
||||
analog_x_axis = -1;
|
||||
analog_y_axis = -1;
|
||||
|
@ -1058,40 +1080,21 @@ public:
|
|||
if (event.type == SDL_JOYAXISMOTION && std::abs(event.jaxis.value / 32767.0) < 0.5) {
|
||||
continue;
|
||||
}
|
||||
// Simplify controller config by testing if game controller support is enabled.
|
||||
if (event.type == SDL_JOYAXISMOTION) {
|
||||
const auto axis = event.jaxis.axis;
|
||||
if (const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which);
|
||||
auto* const controller = joystick->GetSDLGameController()) {
|
||||
const auto axis_left_x =
|
||||
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX)
|
||||
.value.axis;
|
||||
const auto axis_left_y =
|
||||
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY)
|
||||
.value.axis;
|
||||
const auto axis_right_x =
|
||||
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX)
|
||||
.value.axis;
|
||||
const auto axis_right_y =
|
||||
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY)
|
||||
.value.axis;
|
||||
|
||||
if (axis == axis_left_x || axis == axis_left_y) {
|
||||
analog_x_axis = axis_left_x;
|
||||
analog_y_axis = axis_left_y;
|
||||
break;
|
||||
} else if (axis == axis_right_x || axis == axis_right_y) {
|
||||
analog_x_axis = axis_right_x;
|
||||
analog_y_axis = axis_right_y;
|
||||
break;
|
||||
}
|
||||
// In order to return a complete analog param, we need inputs for both axes.
|
||||
// First we take the x-axis (horizontal) input, then the y-axis (vertical) input.
|
||||
if (analog_x_axis == -1) {
|
||||
analog_x_axis = axis;
|
||||
} else if (analog_y_axis == -1 && analog_x_axis != axis) {
|
||||
analog_y_axis = axis;
|
||||
}
|
||||
} else {
|
||||
// If the press wasn't accepted as a joy axis, check for a button press
|
||||
auto button_press = button_poller.FromEvent(event);
|
||||
if (button_press) {
|
||||
return *button_press;
|
||||
}
|
||||
}
|
||||
|
||||
// If the press wasn't accepted as a joy axis, check for a button press
|
||||
auto button_press = button_poller.FromEvent(event);
|
||||
if (button_press) {
|
||||
return *button_press;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1104,6 +1107,7 @@ public:
|
|||
return params;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace InputCommon::SDL {
|
|||
class SDLAnalogFactory;
|
||||
class SDLButtonFactory;
|
||||
class SDLMotionFactory;
|
||||
class SDLVibrationFactory;
|
||||
class SDLJoystick;
|
||||
|
||||
class SDLState : public State {
|
||||
|
@ -72,6 +73,7 @@ private:
|
|||
|
||||
std::shared_ptr<SDLButtonFactory> button_factory;
|
||||
std::shared_ptr<SDLAnalogFactory> analog_factory;
|
||||
std::shared_ptr<SDLVibrationFactory> vibration_factory;
|
||||
std::shared_ptr<SDLMotionFactory> motion_factory;
|
||||
|
||||
bool start_thread = false;
|
||||
|
|
|
@ -14,13 +14,6 @@ const std::array<const char*, NumButtons> mapping = {{
|
|||
}};
|
||||
}
|
||||
|
||||
namespace NativeMotion {
|
||||
const std::array<const char*, NumMotions> mapping = {{
|
||||
"motionleft",
|
||||
"motionright",
|
||||
}};
|
||||
}
|
||||
|
||||
namespace NativeAnalog {
|
||||
const std::array<const char*, NumAnalogs> mapping = {{
|
||||
"lstick",
|
||||
|
@ -28,6 +21,20 @@ const std::array<const char*, NumAnalogs> mapping = {{
|
|||
}};
|
||||
}
|
||||
|
||||
namespace NativeVibration {
|
||||
const std::array<const char*, NumVibrations> mapping = {{
|
||||
"left_vibration_device",
|
||||
"right_vibration_device",
|
||||
}};
|
||||
}
|
||||
|
||||
namespace NativeMotion {
|
||||
const std::array<const char*, NumMotions> mapping = {{
|
||||
"motionleft",
|
||||
"motionright",
|
||||
}};
|
||||
}
|
||||
|
||||
namespace NativeMouseButton {
|
||||
const std::array<const char*, NumMouseButtons> mapping = {{
|
||||
"left",
|
||||
|
|
|
@ -66,17 +66,32 @@ constexpr int NUM_STICKS_HID = NumAnalogs;
|
|||
extern const std::array<const char*, NumAnalogs> mapping;
|
||||
} // namespace NativeAnalog
|
||||
|
||||
namespace NativeVibration {
|
||||
enum Values : int {
|
||||
LeftVibrationDevice,
|
||||
RightVibrationDevice,
|
||||
|
||||
NumVibrations,
|
||||
};
|
||||
|
||||
constexpr int VIBRATION_HID_BEGIN = LeftVibrationDevice;
|
||||
constexpr int VIBRATION_HID_END = NumVibrations;
|
||||
constexpr int NUM_VIBRATIONS_HID = NumVibrations;
|
||||
|
||||
extern const std::array<const char*, NumVibrations> mapping;
|
||||
}; // namespace NativeVibration
|
||||
|
||||
namespace NativeMotion {
|
||||
enum Values : int {
|
||||
MOTIONLEFT,
|
||||
MOTIONRIGHT,
|
||||
MotionLeft,
|
||||
MotionRight,
|
||||
|
||||
NumMotions,
|
||||
};
|
||||
|
||||
constexpr int MOTION_HID_BEGIN = MOTIONLEFT;
|
||||
constexpr int MOTION_HID_BEGIN = MotionLeft;
|
||||
constexpr int MOTION_HID_END = NumMotions;
|
||||
constexpr int NUM_MOTION_HID = NumMotions;
|
||||
constexpr int NUM_MOTIONS_HID = NumMotions;
|
||||
|
||||
extern const std::array<const char*, NumMotions> mapping;
|
||||
} // namespace NativeMotion
|
||||
|
@ -305,9 +320,11 @@ constexpr int NUM_KEYBOARD_MODS_HID = NumKeyboardMods;
|
|||
|
||||
} // namespace NativeKeyboard
|
||||
|
||||
using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>;
|
||||
using AnalogsRaw = std::array<std::string, NativeAnalog::NumAnalogs>;
|
||||
using MotionRaw = std::array<std::string, NativeMotion::NumMotions>;
|
||||
using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>;
|
||||
using MotionsRaw = std::array<std::string, NativeMotion::NumMotions>;
|
||||
using VibrationsRaw = std::array<std::string, NativeVibration::NumVibrations>;
|
||||
|
||||
using MouseButtonsRaw = std::array<std::string, NativeMouseButton::NumMouseButtons>;
|
||||
using KeyboardKeysRaw = std::array<std::string, NativeKeyboard::NumKeyboardKeys>;
|
||||
using KeyboardModsRaw = std::array<std::string, NativeKeyboard::NumKeyboardMods>;
|
||||
|
@ -330,7 +347,11 @@ struct PlayerInput {
|
|||
ControllerType controller_type;
|
||||
ButtonsRaw buttons;
|
||||
AnalogsRaw analogs;
|
||||
MotionRaw motions;
|
||||
VibrationsRaw vibrations;
|
||||
MotionsRaw motions;
|
||||
|
||||
bool vibration_enabled;
|
||||
int vibration_strength;
|
||||
|
||||
u32 body_color_left;
|
||||
u32 body_color_right;
|
||||
|
|
|
@ -344,7 +344,7 @@ void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
|
|||
};
|
||||
Socket socket{host, port, pad_index, client_id, std::move(callback)};
|
||||
std::thread worker_thread{SocketLoop, &socket};
|
||||
const bool result = success_event.WaitFor(std::chrono::seconds(8));
|
||||
const bool result = success_event.WaitFor(std::chrono::seconds(5));
|
||||
socket.Stop();
|
||||
worker_thread.join();
|
||||
if (result) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue