Stash "TODO"
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,10 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <QGroupBox>
|
||||
#include <QKeySequence>
|
||||
#include <QSpinBox>
|
||||
#include <QWidget>
|
||||
#include "common/param_package.h"
|
||||
#include "common/settings.h"
|
||||
@ -22,6 +25,10 @@ class QSlider;
|
||||
class QString;
|
||||
class QTimer;
|
||||
|
||||
namespace Core::HID {
|
||||
class EmulatedController;
|
||||
} // namespace Core::HID
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureInput;
|
||||
}
|
||||
@ -33,6 +40,8 @@ public:
|
||||
explicit ConfigureInput(QWidget* parent = nullptr);
|
||||
~ConfigureInput() override;
|
||||
|
||||
void Initialize(InputCommon::InputSubsystem* input_subsystem_);
|
||||
|
||||
/// Save all button configurations to settings file
|
||||
void ApplyConfiguration();
|
||||
void RetranslateUI();
|
||||
@ -50,14 +59,24 @@ signals:
|
||||
void InputKeysChanged(QList<QKeySequence> new_key_list);
|
||||
|
||||
private:
|
||||
QString ButtonToText(const Common::ParamPackage& param);
|
||||
QString AnalogToText(const Common::ParamPackage& param, const std::string& dir);
|
||||
|
||||
/// Update UI to reflect current configuration.
|
||||
void UpdateUI();
|
||||
|
||||
std::unique_ptr<Ui::ConfigureInput> ui;
|
||||
|
||||
InputCommon::InputSubsystem* input_subsystem;
|
||||
|
||||
std::unique_ptr<QTimer> timeout_timer;
|
||||
std::unique_ptr<QTimer> poll_timer;
|
||||
|
||||
/// This will be the the setting function when an input is awaiting configuration.
|
||||
std::optional<std::function<void(const Common::ParamPackage&)>> input_setter;
|
||||
|
||||
Core::HID::EmulatedController* emulated_controller;
|
||||
|
||||
std::array<Common::ParamPackage, Settings::NativeButton::NumButtons> buttons_param;
|
||||
std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs> analogs_param;
|
||||
|
||||
@ -74,14 +93,19 @@ private:
|
||||
/// Analog inputs are also represented each with a single button, used to configure with an
|
||||
/// actual analog stick
|
||||
std::array<QPushButton*, Settings::NativeAnalog::NumAnalogs> analog_map_stick;
|
||||
std::array<QSlider*, Settings::NativeAnalog::NumAnalogs>
|
||||
analog_map_deadzone_and_modifier_slider;
|
||||
std::array<QLabel*, Settings::NativeAnalog::NumAnalogs>
|
||||
analog_map_deadzone_and_modifier_slider_label;
|
||||
|
||||
static const std::array<std::string, ANALOG_SUB_BUTTONS_NUM> analog_sub_buttons;
|
||||
|
||||
std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> device_pollers;
|
||||
std::array<QLabel*, Settings::NativeAnalog::NumAnalogs> analog_map_deadzone_label;
|
||||
std::array<QSlider*, Settings::NativeAnalog::NumAnalogs> analog_map_deadzone_slider;
|
||||
std::array<QGroupBox*, Settings::NativeAnalog::NumAnalogs> analog_map_modifier_groupbox;
|
||||
std::array<QPushButton*, Settings::NativeAnalog::NumAnalogs> analog_map_modifier_button;
|
||||
std::array<QLabel*, Settings::NativeAnalog::NumAnalogs> analog_map_modifier_label;
|
||||
std::array<QSlider*, Settings::NativeAnalog::NumAnalogs> analog_map_modifier_slider;
|
||||
std::array<QGroupBox*, Settings::NativeAnalog::NumAnalogs> analog_map_range_groupbox;
|
||||
std::array<QSpinBox*, Settings::NativeAnalog::NumAnalogs> analog_map_range_spinbox;
|
||||
|
||||
/// A flag to indicate that the "Map Analog Stick" pop-up has been shown and accepted once.
|
||||
bool map_analog_stick_accepted{};
|
||||
|
||||
/**
|
||||
* List of keys currently registered to hotkeys.
|
||||
@ -94,34 +118,39 @@ private:
|
||||
/// keyboard events are ignored.
|
||||
bool want_keyboard_keys = false;
|
||||
|
||||
std::vector<Common::ParamPackage> input_devices;
|
||||
|
||||
/// Generates list of all used keys
|
||||
QList<QKeySequence> GetUsedKeyboardKeys();
|
||||
|
||||
void MapFromButton(const Common::ParamPackage& params);
|
||||
void AutoMap();
|
||||
|
||||
/// Restore all buttons to their default values.
|
||||
void RestoreDefaults();
|
||||
/// Clear all input configuration
|
||||
void ClearAll();
|
||||
|
||||
/// Update UI to reflect current configuration.
|
||||
void UpdateButtonLabels();
|
||||
/// Gets the default controller mapping for this device and auto configures the input to match.
|
||||
void UpdateMappingWithDefaults();
|
||||
|
||||
/// Called when the button was pressed.
|
||||
void HandleClick(QPushButton* button,
|
||||
void HandleClick(QPushButton* button, std::size_t button_id,
|
||||
std::function<void(const Common::ParamPackage&)> new_input_setter,
|
||||
InputCommon::Polling::DeviceType type);
|
||||
InputCommon::Polling::InputType type);
|
||||
|
||||
/// The key code of the previous state of the key being currently bound.
|
||||
int previous_key_code;
|
||||
|
||||
/// Checks whether a given input can be accepted.
|
||||
bool IsInputAcceptable(const Common::ParamPackage& params) const;
|
||||
|
||||
/// Finish polling and configure input using the input_setter
|
||||
void SetPollingResult(const Common::ParamPackage& params, bool abort);
|
||||
|
||||
/// Handle key press events.
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
|
||||
void UpdateInputDevices();
|
||||
void UpdateInputDeviceCombobox();
|
||||
|
||||
/// input profiles
|
||||
void NewProfile();
|
||||
void DeleteProfile();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,9 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "core/3ds.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hid/emulated_console.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/event.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
@ -43,9 +46,6 @@ void Module::serialize(Archive& ar, const unsigned int file_version) {
|
||||
ar& next_gyroscope_index;
|
||||
ar& enable_accelerometer_count;
|
||||
ar& enable_gyroscope_count;
|
||||
if (Archive::is_loading::value) {
|
||||
LoadInputDevices();
|
||||
}
|
||||
if (file_version >= 1) {
|
||||
ar& state.hex;
|
||||
}
|
||||
@ -86,65 +86,23 @@ DirectionState GetStickDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
|
||||
return state;
|
||||
}
|
||||
|
||||
void Module::LoadInputDevices() {
|
||||
std::transform(Settings::values.current_input_profile.buttons.begin() +
|
||||
Settings::NativeButton::BUTTON_HID_BEGIN,
|
||||
Settings::values.current_input_profile.buttons.begin() +
|
||||
Settings::NativeButton::BUTTON_HID_END,
|
||||
buttons.begin(), Input::CreateDevice<Input::ButtonDevice>);
|
||||
circle_pad = Input::CreateDevice<Input::AnalogDevice>(
|
||||
Settings::values.current_input_profile.analogs[Settings::NativeAnalog::CirclePad]);
|
||||
motion_device = Input::CreateDevice<Input::MotionDevice>(
|
||||
Settings::values.current_input_profile.motion_device);
|
||||
touch_device = Input::CreateDevice<Input::TouchDevice>(
|
||||
Settings::values.current_input_profile.touch_device);
|
||||
if (Settings::values.current_input_profile.use_touch_from_button) {
|
||||
touch_btn_device = Input::CreateDevice<Input::TouchDevice>("engine:touch_from_button");
|
||||
} else {
|
||||
touch_btn_device.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) {
|
||||
SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
|
||||
|
||||
if (is_device_reload_pending.exchange(false))
|
||||
LoadInputDevices();
|
||||
|
||||
using namespace Settings::NativeButton;
|
||||
state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.right.Assign(buttons[Right - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.left.Assign(buttons[Left - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.up.Assign(buttons[Up - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.down.Assign(buttons[Down - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.start.Assign(buttons[Start - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.select.Assign(buttons[Select - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.debug.Assign(buttons[Debug - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.gpio14.Assign(buttons[Gpio14 - BUTTON_HID_BEGIN]->GetStatus());
|
||||
const auto& controller = hid_core.GetEmulatedController();
|
||||
state = controller->GetPadState();
|
||||
|
||||
// Get current circle pad position and update circle pad direction
|
||||
float circle_pad_x_f, circle_pad_y_f;
|
||||
std::tie(circle_pad_x_f, circle_pad_y_f) = circle_pad->GetStatus();
|
||||
const s16 circle_pad_new_x = controller->GetSticks().circle_pad.x;
|
||||
const s16 circle_pad_new_y = controller->GetSticks().circle_pad.y;
|
||||
|
||||
// xperia64: 0x9A seems to be the calibrated limit of the circle pad
|
||||
// Verified by using Input Redirector with very large-value digital inputs
|
||||
// on the circle pad and calibrating using the system settings application
|
||||
constexpr int MAX_CIRCLEPAD_POS = 0x9A; // Max value for a circle pad position
|
||||
|
||||
// These are rounded rather than truncated on actual hardware
|
||||
s16 circle_pad_new_x = static_cast<s16>(std::roundf(circle_pad_x_f * MAX_CIRCLEPAD_POS));
|
||||
s16 circle_pad_new_y = static_cast<s16>(std::roundf(circle_pad_y_f * MAX_CIRCLEPAD_POS));
|
||||
s16 circle_pad_x =
|
||||
(circle_pad_new_x + std::accumulate(circle_pad_old_x.begin(), circle_pad_old_x.end(), 0)) /
|
||||
CIRCLE_PAD_AVERAGING;
|
||||
s16 circle_pad_y =
|
||||
(circle_pad_new_y + std::accumulate(circle_pad_old_y.begin(), circle_pad_old_y.end(), 0)) /
|
||||
CIRCLE_PAD_AVERAGING;
|
||||
|
||||
circle_pad_old_x.erase(circle_pad_old_x.begin());
|
||||
circle_pad_old_x.push_back(circle_pad_new_x);
|
||||
circle_pad_old_y.erase(circle_pad_old_y.begin());
|
||||
@ -190,12 +148,10 @@ void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) {
|
||||
|
||||
// Get the current touch entry
|
||||
TouchDataEntry& touch_entry = mem->touch.entries[mem->touch.index];
|
||||
bool pressed = false;
|
||||
float x, y;
|
||||
std::tie(x, y, pressed) = touch_device->GetStatus();
|
||||
if (!pressed && touch_btn_device) {
|
||||
std::tie(x, y, pressed) = touch_btn_device->GetStatus();
|
||||
}
|
||||
const auto& touch_state = hid_core.GetEmulatedConsole()->GetTouch()[0];
|
||||
float x = touch_state.position_x;
|
||||
float y = touch_state.position_y;
|
||||
bool pressed = touch_state.pressed;
|
||||
touch_entry.x = static_cast<u16>(x * Core::kScreenBottomWidth);
|
||||
touch_entry.y = static_cast<u16>(y * Core::kScreenBottomHeight);
|
||||
touch_entry.valid.Assign(pressed ? 1 : 0);
|
||||
@ -232,8 +188,8 @@ void Module::UpdateAccelerometerCallback(std::uintptr_t user_data, s64 cycles_la
|
||||
mem->accelerometer.index = next_accelerometer_index;
|
||||
next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size();
|
||||
|
||||
Common::Vec3<float> accel;
|
||||
std::tie(accel, std::ignore) = motion_device->GetStatus();
|
||||
const auto& motion_state = hid_core.GetEmulatedConsole()->GetMotion();
|
||||
Common::Vec3<float> accel = motion_state.gyro;
|
||||
accel *= accelerometer_coef;
|
||||
// TODO(wwylele): do a time stretch like the one in UpdateGyroscopeCallback
|
||||
// The time stretch formula should be like
|
||||
@ -279,8 +235,8 @@ void Module::UpdateGyroscopeCallback(std::uintptr_t user_data, s64 cycles_late)
|
||||
|
||||
GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index];
|
||||
|
||||
Common::Vec3<float> gyro;
|
||||
std::tie(std::ignore, gyro) = motion_device->GetStatus();
|
||||
const auto& motion_state = hid_core.GetEmulatedConsole()->GetMotion();
|
||||
Common::Vec3<float> gyro = motion_state.gyro;
|
||||
double stretch = system.perf_stats->GetLastFrameTimeScale();
|
||||
gyro *= gyroscope_coef * static_cast<float>(stretch);
|
||||
gyroscope_entry.x = static_cast<s16>(gyro.x);
|
||||
@ -421,7 +377,7 @@ std::shared_ptr<Module> Module::Interface::GetModule() const {
|
||||
return hid;
|
||||
}
|
||||
|
||||
Module::Module(Core::System& system) : system(system) {
|
||||
Module::Module(Core::System& system) : system(system), hid_core{system.HIDCore()} {
|
||||
using namespace Kernel;
|
||||
|
||||
shared_mem =
|
||||
@ -455,10 +411,6 @@ Module::Module(Core::System& system) : system(system) {
|
||||
timing.ScheduleEvent(pad_update_ticks, pad_update_event);
|
||||
}
|
||||
|
||||
void Module::ReloadInputDevices() {
|
||||
is_device_reload_pending.store(true);
|
||||
}
|
||||
|
||||
const PadState& Module::GetState() const {
|
||||
return state;
|
||||
}
|
||||
|
@ -13,9 +13,10 @@
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/input.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
@ -31,36 +32,13 @@ namespace Core {
|
||||
struct TimingEventType;
|
||||
};
|
||||
|
||||
namespace Core::HID {
|
||||
class HIDCore;
|
||||
};
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
/**
|
||||
* Structure of a Pad controller state.
|
||||
*/
|
||||
struct PadState {
|
||||
union {
|
||||
u32 hex{};
|
||||
|
||||
BitField<0, 1, u32> a;
|
||||
BitField<1, 1, u32> b;
|
||||
BitField<2, 1, u32> select;
|
||||
BitField<3, 1, u32> start;
|
||||
BitField<4, 1, u32> right;
|
||||
BitField<5, 1, u32> left;
|
||||
BitField<6, 1, u32> up;
|
||||
BitField<7, 1, u32> down;
|
||||
BitField<8, 1, u32> r;
|
||||
BitField<9, 1, u32> l;
|
||||
BitField<10, 1, u32> x;
|
||||
BitField<11, 1, u32> y;
|
||||
BitField<12, 1, u32> debug;
|
||||
BitField<13, 1, u32> gpio14;
|
||||
|
||||
BitField<28, 1, u32> circle_right;
|
||||
BitField<29, 1, u32> circle_left;
|
||||
BitField<30, 1, u32> circle_up;
|
||||
BitField<31, 1, u32> circle_down;
|
||||
};
|
||||
};
|
||||
using Core::HID::PadState;
|
||||
|
||||
/**
|
||||
* Structure of a single entry of Pad state history within HID shared memory
|
||||
@ -296,8 +274,6 @@ public:
|
||||
std::shared_ptr<Module> hid;
|
||||
};
|
||||
|
||||
void ReloadInputDevices();
|
||||
|
||||
const PadState& GetState() const;
|
||||
|
||||
// Updating period for each HID device. These empirical values are measured from a 11.2 3DS.
|
||||
@ -306,7 +282,6 @@ public:
|
||||
static constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE_ARM11 / 101;
|
||||
|
||||
private:
|
||||
void LoadInputDevices();
|
||||
void UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late);
|
||||
void UpdateAccelerometerCallback(std::uintptr_t user_data, s64 cycles_late);
|
||||
void UpdateGyroscopeCallback(std::uintptr_t user_data, s64 cycles_late);
|
||||
@ -347,13 +322,7 @@ private:
|
||||
Core::TimingEventType* accelerometer_update_event;
|
||||
Core::TimingEventType* gyroscope_update_event;
|
||||
|
||||
std::atomic<bool> is_device_reload_pending{true};
|
||||
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>
|
||||
buttons;
|
||||
std::unique_ptr<Input::AnalogDevice> circle_pad;
|
||||
std::unique_ptr<Input::MotionDevice> motion_device;
|
||||
std::unique_ptr<Input::TouchDevice> touch_device;
|
||||
std::unique_ptr<Input::TouchDevice> touch_btn_device;
|
||||
Core::HID::HIDCore& hid_core;
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int);
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hle/service/ir/extra_hid.h"
|
||||
#include "core/movie.h"
|
||||
|
||||
@ -64,9 +66,8 @@ enum class ResponseID : u8 {
|
||||
ReadCalibrationData = 0x11,
|
||||
};
|
||||
|
||||
ExtraHID::ExtraHID(SendFunc send_func, Core::Timing& timing) : IRDevice(send_func), timing(timing) {
|
||||
LoadInputDevices();
|
||||
|
||||
ExtraHID::ExtraHID(SendFunc send_func, Core::System& system)
|
||||
: IRDevice(send_func), timing(system.CoreTiming()), hid_core{system.HIDCore()} {
|
||||
// The data below was retrieved from a New 3DS
|
||||
// TODO(wwylele): this data is probably writable (via request 3?) and thus should be saved to
|
||||
// and loaded from somewhere.
|
||||
@ -228,24 +229,23 @@ void ExtraHID::OnReceive(const std::vector<u8>& data) {
|
||||
}
|
||||
|
||||
void ExtraHID::SendHIDStatus() {
|
||||
if (is_device_reload_pending.exchange(false))
|
||||
LoadInputDevices();
|
||||
|
||||
constexpr int C_STICK_CENTER = 0x800;
|
||||
// TODO(wwylele): this value is not accurately measured. We currently assume that the axis can
|
||||
// take values in the whole range of a 12-bit integer.
|
||||
constexpr int C_STICK_RADIUS = 0x7FF;
|
||||
|
||||
float x, y;
|
||||
std::tie(x, y) = c_stick->GetStatus();
|
||||
// TODO: Correct this!!!!!
|
||||
const auto& controller = hid_core.GetEmulatedController();
|
||||
float x = controller->GetSticks().c_stick.x;
|
||||
float y = controller->GetSticks().c_stick.y;
|
||||
|
||||
ExtraHIDResponse response;
|
||||
response.c_stick.header.Assign(static_cast<u8>(ResponseID::PollHID));
|
||||
response.c_stick.c_stick_x.Assign(static_cast<u32>(C_STICK_CENTER + C_STICK_RADIUS * x));
|
||||
response.c_stick.c_stick_y.Assign(static_cast<u32>(C_STICK_CENTER + C_STICK_RADIUS * y));
|
||||
response.buttons.battery_level.Assign(0x1F);
|
||||
response.buttons.zl_not_held.Assign(!zl->GetStatus());
|
||||
response.buttons.zr_not_held.Assign(!zr->GetStatus());
|
||||
response.buttons.zl_not_held.Assign(!controller->GetExtraState().zl);
|
||||
response.buttons.zr_not_held.Assign(!controller->GetExtraState().zr);
|
||||
response.buttons.r_not_held.Assign(1);
|
||||
response.unknown = 0;
|
||||
|
||||
@ -256,17 +256,4 @@ void ExtraHID::SendHIDStatus() {
|
||||
Send(response_buffer);
|
||||
}
|
||||
|
||||
void ExtraHID::RequestInputDevicesReload() {
|
||||
is_device_reload_pending.store(true);
|
||||
}
|
||||
|
||||
void ExtraHID::LoadInputDevices() {
|
||||
zl = Input::CreateDevice<Input::ButtonDevice>(
|
||||
Settings::values.current_input_profile.buttons[Settings::NativeButton::ZL]);
|
||||
zr = Input::CreateDevice<Input::ButtonDevice>(
|
||||
Settings::values.current_input_profile.buttons[Settings::NativeButton::ZR]);
|
||||
c_stick = Input::CreateDevice<Input::AnalogDevice>(
|
||||
Settings::values.current_input_profile.analogs[Settings::NativeAnalog::CStick]);
|
||||
}
|
||||
|
||||
} // namespace Service::IR
|
||||
|
@ -17,6 +17,10 @@ struct TimingEventType;
|
||||
class Timing;
|
||||
} // namespace Core
|
||||
|
||||
namespace Core::HID {
|
||||
class HIDCore;
|
||||
};
|
||||
|
||||
namespace Service::IR {
|
||||
|
||||
struct ExtraHIDResponse {
|
||||
@ -42,7 +46,7 @@ static_assert(sizeof(ExtraHIDResponse) == 6, "HID status response has wrong size
|
||||
*/
|
||||
class ExtraHID final : public IRDevice {
|
||||
public:
|
||||
explicit ExtraHID(SendFunc send_func, Core::Timing& timing);
|
||||
explicit ExtraHID(SendFunc send_func, Core::System& system);
|
||||
~ExtraHID();
|
||||
|
||||
void OnConnect() override;
|
||||
@ -58,6 +62,7 @@ private:
|
||||
u8 hid_period;
|
||||
Core::TimingEventType* hid_polling_callback_id;
|
||||
std::array<u8, 0x40> calibration_data;
|
||||
Core::HID::HIDCore& hid_core;
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int) {
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/event.h"
|
||||
#include "core/hle/kernel/shared_memory.h"
|
||||
@ -29,7 +30,6 @@ void IR_RST::serialize(Archive& ar, const unsigned int) {
|
||||
ar& raw_c_stick;
|
||||
ar& update_period;
|
||||
// update_callback_id and input devices are set separately
|
||||
ReloadInputDevices();
|
||||
}
|
||||
|
||||
struct PadDataEntry {
|
||||
@ -51,34 +51,19 @@ struct SharedMem {
|
||||
|
||||
static_assert(sizeof(SharedMem) == 0x98, "SharedMem has wrong size!");
|
||||
|
||||
void IR_RST::LoadInputDevices() {
|
||||
zl_button = Input::CreateDevice<Input::ButtonDevice>(
|
||||
Settings::values.current_input_profile.buttons[Settings::NativeButton::ZL]);
|
||||
zr_button = Input::CreateDevice<Input::ButtonDevice>(
|
||||
Settings::values.current_input_profile.buttons[Settings::NativeButton::ZR]);
|
||||
c_stick = Input::CreateDevice<Input::AnalogDevice>(
|
||||
Settings::values.current_input_profile.analogs[Settings::NativeAnalog::CStick]);
|
||||
}
|
||||
|
||||
void IR_RST::UnloadInputDevices() {
|
||||
zl_button = nullptr;
|
||||
zr_button = nullptr;
|
||||
c_stick = nullptr;
|
||||
}
|
||||
|
||||
void IR_RST::UpdateCallback(std::uintptr_t user_data, s64 cycles_late) {
|
||||
SharedMem* mem = reinterpret_cast<SharedMem*>(shared_memory->GetPointer());
|
||||
|
||||
if (is_device_reload_pending.exchange(false))
|
||||
LoadInputDevices();
|
||||
|
||||
const auto& controller = hid_core.GetEmulatedController();
|
||||
PadState state;
|
||||
state.zl.Assign(zl_button->GetStatus());
|
||||
state.zr.Assign(zr_button->GetStatus());
|
||||
state.zl.Assign(controller->GetExtraState().zl);
|
||||
state.zr.Assign(controller->GetExtraState().zr);
|
||||
|
||||
// Get current c-stick position and update c-stick direction
|
||||
float c_stick_x_f, c_stick_y_f;
|
||||
std::tie(c_stick_x_f, c_stick_y_f) = c_stick->GetStatus();
|
||||
// TODO: FIX!!!! (same as in extra_hid)
|
||||
float c_stick_x_f = controller->GetSticks().c_stick.x;
|
||||
float c_stick_y_f = controller->GetSticks().c_stick.y;
|
||||
|
||||
constexpr int MAX_CSTICK_RADIUS = 0x9C; // Max value for a c-stick radius
|
||||
s16 c_stick_x = static_cast<s16>(c_stick_x_f * MAX_CSTICK_RADIUS);
|
||||
s16 c_stick_y = static_cast<s16>(c_stick_y_f * MAX_CSTICK_RADIUS);
|
||||
@ -143,7 +128,6 @@ void IR_RST::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
LOG_ERROR(Service_IR, "raw C-stick data is not implemented!");
|
||||
|
||||
next_pad_index = 0;
|
||||
is_device_reload_pending.store(true);
|
||||
system.CoreTiming().ScheduleEvent(msToCycles(update_period), update_callback_id);
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
@ -156,14 +140,14 @@ void IR_RST::Shutdown(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x03, 0, 0);
|
||||
|
||||
system.CoreTiming().UnscheduleEvent(update_callback_id, 0);
|
||||
UnloadInputDevices();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
LOG_DEBUG(Service_IR, "called");
|
||||
}
|
||||
|
||||
IR_RST::IR_RST(Core::System& system) : ServiceFramework("ir:rst", 1), system(system) {
|
||||
IR_RST::IR_RST(Core::System& system)
|
||||
: ServiceFramework("ir:rst", 1), system(system), hid_core{system.HIDCore()} {
|
||||
using namespace Kernel;
|
||||
// Note: these two kernel objects are even available before Initialize service function is
|
||||
// called.
|
||||
@ -192,8 +176,4 @@ IR_RST::IR_RST(Core::System& system) : ServiceFramework("ir:rst", 1), system(sys
|
||||
|
||||
IR_RST::~IR_RST() = default;
|
||||
|
||||
void IR_RST::ReloadInputDevices() {
|
||||
is_device_reload_pending.store(true);
|
||||
}
|
||||
|
||||
} // namespace Service::IR
|
||||
|
@ -21,6 +21,10 @@ namespace Core {
|
||||
struct TimingEventType;
|
||||
};
|
||||
|
||||
namespace Core::HID {
|
||||
class HIDCore;
|
||||
};
|
||||
|
||||
namespace Service::IR {
|
||||
|
||||
union PadState {
|
||||
@ -80,6 +84,7 @@ private:
|
||||
Core::TimingEventType* update_callback_id;
|
||||
bool raw_c_stick{false};
|
||||
int update_period{0};
|
||||
Core::HID::HIDCore& hid_core;
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int);
|
||||
|
@ -464,7 +464,7 @@ IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) {
|
||||
receive_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ReceiveEvent");
|
||||
|
||||
extra_hid = std::make_unique<ExtraHID>(
|
||||
[this](const std::vector<u8>& data) { PutToReceive(data); }, system.CoreTiming());
|
||||
[this](const std::vector<u8>& data) { PutToReceive(data); }, system);
|
||||
}
|
||||
|
||||
IR_USER::~IR_USER() {
|
||||
|
@ -151,32 +151,17 @@ UDPClient::ClientConnection::~ClientConnection() = default;
|
||||
void UDPClient::ReloadSockets() {
|
||||
Reset();
|
||||
|
||||
std::stringstream servers_ss(Settings::values.udp_input_servers.GetValue());
|
||||
std::string server_token;
|
||||
std::size_t client = 0;
|
||||
while (std::getline(servers_ss, server_token, ',')) {
|
||||
if (client == MAX_UDP_CLIENTS) {
|
||||
break;
|
||||
}
|
||||
std::stringstream server_ss(server_token);
|
||||
std::string token;
|
||||
std::getline(server_ss, token, ':');
|
||||
std::string udp_input_address = token;
|
||||
std::getline(server_ss, token, ':');
|
||||
char* temp;
|
||||
const u16 udp_input_port = static_cast<u16>(std::strtol(token.c_str(), &temp, 0));
|
||||
if (*temp != '\0') {
|
||||
LOG_ERROR(Input, "Port number is not valid {}", token);
|
||||
continue;
|
||||
}
|
||||
const std::string& host = Settings::values.current_input_profile.udp_input_address;
|
||||
const u16 udp_input_port = Settings::values.current_input_profile.udp_input_port;
|
||||
// TODO: Hook it up again
|
||||
const u8 pad_index = Settings::values.current_input_profile.udp_pad_index;
|
||||
|
||||
const std::size_t client_number = GetClientNumber(udp_input_address, udp_input_port);
|
||||
if (client_number != MAX_UDP_CLIENTS) {
|
||||
LOG_ERROR(Input, "Duplicated UDP servers found");
|
||||
continue;
|
||||
}
|
||||
StartCommunication(client++, udp_input_address, udp_input_port);
|
||||
const std::size_t client_number = GetClientNumber(host, udp_input_port);
|
||||
if (client_number != MAX_UDP_CLIENTS) {
|
||||
LOG_ERROR(Input, "Duplicated UDP servers found");
|
||||
return;
|
||||
}
|
||||
StartCommunication(0, host, udp_input_port);
|
||||
}
|
||||
|
||||
std::size_t UDPClient::GetClientNumber(std::string_view host, u16 port) const {
|
||||
@ -191,25 +176,6 @@ std::size_t UDPClient::GetClientNumber(std::string_view host, u16 port) const {
|
||||
return MAX_UDP_CLIENTS;
|
||||
}
|
||||
|
||||
Common::Input::BatteryLevel UDPClient::GetBatteryLevel(Response::Battery battery) const {
|
||||
switch (battery) {
|
||||
case Response::Battery::Dying:
|
||||
return Common::Input::BatteryLevel::Empty;
|
||||
case Response::Battery::Low:
|
||||
return Common::Input::BatteryLevel::Critical;
|
||||
case Response::Battery::Medium:
|
||||
return Common::Input::BatteryLevel::Low;
|
||||
case Response::Battery::High:
|
||||
return Common::Input::BatteryLevel::Medium;
|
||||
case Response::Battery::Full:
|
||||
case Response::Battery::Charged:
|
||||
return Common::Input::BatteryLevel::Full;
|
||||
case Response::Battery::Charging:
|
||||
default:
|
||||
return Common::Input::BatteryLevel::Charging;
|
||||
}
|
||||
}
|
||||
|
||||
void UDPClient::OnVersion([[maybe_unused]] Response::Version data) {
|
||||
LOG_TRACE(Input, "Version packet received: {}", data.version);
|
||||
}
|
||||
@ -273,7 +239,7 @@ void UDPClient::OnPadData(Response::PadData data, std::size_t client) {
|
||||
static_cast<int>(id == 0 ? PadButton::Touch1 : PadButton::Touch2);
|
||||
|
||||
// TODO: Use custom calibration per device
|
||||
const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue());
|
||||
/* const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue());
|
||||
const u16 min_x = static_cast<u16>(touch_param.Get("min_x", 100));
|
||||
const u16 min_y = static_cast<u16>(touch_param.Get("min_y", 50));
|
||||
const u16 max_x = static_cast<u16>(touch_param.Get("max_x", 1800));
|
||||
@ -294,7 +260,7 @@ void UDPClient::OnPadData(Response::PadData data, std::size_t client) {
|
||||
}
|
||||
SetAxis(identifier, touch_axis_x_id, 0);
|
||||
SetAxis(identifier, touch_axis_y_id, 0);
|
||||
SetButton(identifier, touch_button_id, false);
|
||||
SetButton(identifier, touch_button_id, false);*/
|
||||
}
|
||||
|
||||
SetAxis(identifier, static_cast<int>(PadAxes::LeftStickX),
|
||||
@ -320,8 +286,6 @@ void UDPClient::OnPadData(Response::PadData data, std::size_t client) {
|
||||
|
||||
SetButton(identifier, static_cast<int>(PadButton::Home), data.home != 0);
|
||||
SetButton(identifier, static_cast<int>(PadButton::TouchHardPress), data.touch_hard_press != 0);
|
||||
|
||||
SetBattery(identifier, GetBatteryLevel(data.info.battery));
|
||||
}
|
||||
|
||||
void UDPClient::StartCommunication(std::size_t client, const std::string& host, u16 port) {
|
||||
@ -368,28 +332,6 @@ void UDPClient::Reset() {
|
||||
|
||||
std::vector<Common::ParamPackage> UDPClient::GetInputDevices() const {
|
||||
std::vector<Common::ParamPackage> devices;
|
||||
if (!Settings::values.enable_udp_controller) {
|
||||
return devices;
|
||||
}
|
||||
for (std::size_t client = 0; client < clients.size(); client++) {
|
||||
if (clients[client].active != 1) {
|
||||
continue;
|
||||
}
|
||||
for (std::size_t index = 0; index < PADS_PER_CLIENT; ++index) {
|
||||
const std::size_t pad_index = client * PADS_PER_CLIENT + index;
|
||||
if (!pads[pad_index].connected) {
|
||||
continue;
|
||||
}
|
||||
const auto pad_identifier = GetPadIdentifier(pad_index);
|
||||
Common::ParamPackage identifier{};
|
||||
identifier.Set("engine", GetEngineName());
|
||||
identifier.Set("display", fmt::format("UDP Controller {}", pad_identifier.pad));
|
||||
identifier.Set("guid", pad_identifier.guid.RawString());
|
||||
identifier.Set("port", static_cast<int>(pad_identifier.port));
|
||||
identifier.Set("pad", static_cast<int>(pad_identifier.pad));
|
||||
devices.emplace_back(identifier);
|
||||
}
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
@ -446,7 +388,7 @@ AnalogMapping UDPClient::GetAnalogMappingForDevice(const Common::ParamPackage& p
|
||||
left_analog_params.Set("pad", params.Get("pad", 0));
|
||||
left_analog_params.Set("axis_x", static_cast<int>(PadAxes::LeftStickX));
|
||||
left_analog_params.Set("axis_y", static_cast<int>(PadAxes::LeftStickY));
|
||||
mapping.insert_or_assign(Settings::NativeAnalog::LStick, std::move(left_analog_params));
|
||||
mapping.insert_or_assign(Settings::NativeAnalog::CirclePad, std::move(left_analog_params));
|
||||
|
||||
Common::ParamPackage right_analog_params;
|
||||
right_analog_params.Set("engine", GetEngineName());
|
||||
@ -455,7 +397,7 @@ AnalogMapping UDPClient::GetAnalogMappingForDevice(const Common::ParamPackage& p
|
||||
right_analog_params.Set("pad", params.Get("pad", 0));
|
||||
right_analog_params.Set("axis_x", static_cast<int>(PadAxes::RightStickX));
|
||||
right_analog_params.Set("axis_y", static_cast<int>(PadAxes::RightStickY));
|
||||
mapping.insert_or_assign(Settings::NativeAnalog::RStick, std::move(right_analog_params));
|
||||
mapping.insert_or_assign(Settings::NativeAnalog::CStick, std::move(right_analog_params));
|
||||
return mapping;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user