Add a small implementation of motion controls
This commit is contained in:
@@ -236,6 +236,8 @@ void Controller_NPad::OnLoadInputDevices() {
|
||||
players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END,
|
||||
sticks[i].begin(), Input::CreateDevice<Input::AnalogDevice>);
|
||||
}
|
||||
motion_sensors[Settings::values.udp_pad_index] =
|
||||
Input::CreateDevice<Input::MotionDevice>(Settings::values.motion_device);
|
||||
}
|
||||
|
||||
void Controller_NPad::OnRelease() {}
|
||||
@@ -338,6 +340,25 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||
cur_entry.timestamp2 = cur_entry.timestamp;
|
||||
}
|
||||
|
||||
const std::array<SixAxisGeneric*, 6> controller_sixaxes{&npad.full, &npad._handheld,
|
||||
&npad._left_dual, &npad._right_dual,
|
||||
&npad._left, &npad._right};
|
||||
|
||||
for (auto* sixaxis : controller_sixaxes) {
|
||||
sixaxis->common.entry_count = 16;
|
||||
sixaxis->common.total_entry_count = 17;
|
||||
|
||||
const auto& last_entry = sixaxis->sixaxis[sixaxis->common.last_entry_index];
|
||||
|
||||
sixaxis->common.timestamp = core_timing.GetTicks();
|
||||
sixaxis->common.last_entry_index = (sixaxis->common.last_entry_index + 1) % 17;
|
||||
|
||||
auto& cur_entry = sixaxis->sixaxis[sixaxis->common.last_entry_index];
|
||||
|
||||
cur_entry.timestamp = last_entry.timestamp + 1;
|
||||
cur_entry.timestamp2 = cur_entry.timestamp;
|
||||
}
|
||||
|
||||
const auto& controller_type = connected_controllers[i].type;
|
||||
|
||||
if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) {
|
||||
@@ -358,6 +379,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||
auto& pokeball_entry =
|
||||
npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index];
|
||||
auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index];
|
||||
auto& sixaxis_entry = npad.full.sixaxis[npad.full.common.last_entry_index];
|
||||
|
||||
libnx_entry.connection_status.raw = 0;
|
||||
|
||||
@@ -434,6 +456,12 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||
libnx_entry.pad.l_stick = pad_state.l_stick;
|
||||
libnx_entry.pad.r_stick = pad_state.r_stick;
|
||||
|
||||
// Set this entry regardless of the controller type, for now.
|
||||
if (motion_sensors[i] && sixaxis_sensor_enabled) {
|
||||
auto& sensor = motion_sensors[i];
|
||||
std::tie(sixaxis_entry.accelerometer, sixaxis_entry.gyroscope) = sensor->GetStatus();
|
||||
}
|
||||
|
||||
press_state |= static_cast<u32>(pad_state.pad_states.raw);
|
||||
}
|
||||
std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <array>
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/vector_math.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hle/kernel/object.h"
|
||||
#include "core/hle/kernel/writable_event.h"
|
||||
@@ -236,6 +237,24 @@ private:
|
||||
};
|
||||
static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size");
|
||||
|
||||
struct SixAxisState {
|
||||
s64_le timestamp;
|
||||
INSERT_PADDING_BYTES(8); // unknown
|
||||
s64_le timestamp2;
|
||||
Common::Vec3f accelerometer;
|
||||
Common::Vec3f gyroscope;
|
||||
INSERT_PADDING_BYTES(12); // unknown sensor data
|
||||
std::array<Common::Vec3f, 3> orientation;
|
||||
s64_le _always_one; // always 1
|
||||
};
|
||||
static_assert(sizeof(SixAxisState) == 0x68, "SixAxisState is an invalid size");
|
||||
|
||||
struct SixAxisGeneric {
|
||||
CommonHeader common;
|
||||
std::array<SixAxisState, 17> sixaxis;
|
||||
};
|
||||
static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size");
|
||||
|
||||
enum class ColorReadError : u32_le {
|
||||
ReadOk = 0,
|
||||
ColorDoesntExist = 1,
|
||||
@@ -284,9 +303,12 @@ private:
|
||||
NPadGeneric pokeball_states;
|
||||
NPadGeneric libnx; // TODO(ogniK): Find out what this actually is, libnx seems to only be
|
||||
// relying on this for the time being
|
||||
INSERT_PADDING_BYTES(
|
||||
0x708 *
|
||||
6); // TODO(ogniK): SixAxis states, require more information before implementation
|
||||
SixAxisGeneric full; // used
|
||||
SixAxisGeneric _handheld; // stub
|
||||
SixAxisGeneric _left_dual; // stub
|
||||
SixAxisGeneric _right_dual; // stub
|
||||
SixAxisGeneric _left; // stub
|
||||
SixAxisGeneric _right; // stub
|
||||
NPadDevice device_type;
|
||||
NPadProperties properties;
|
||||
INSERT_PADDING_WORDS(1);
|
||||
@@ -318,6 +340,8 @@ private:
|
||||
std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>,
|
||||
10>
|
||||
sticks;
|
||||
std::array<std::unique_ptr<Input::MotionDevice>, 10> motion_sensors;
|
||||
bool sixaxis_sensor_enabled{true};
|
||||
std::vector<u32> supported_npad_id_types{};
|
||||
NpadHoldType hold_type{NpadHoldType::Vertical};
|
||||
// Each controller should have their own styleset changed event
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "core/hle/service/hid/controllers/keyboard.h"
|
||||
#include "core/hle/service/hid/controllers/mouse.h"
|
||||
#include "core/hle/service/hid/controllers/npad.h"
|
||||
#include "core/hle/service/hid/controllers/sixaxis.h"
|
||||
#include "core/hle/service/hid/controllers/stubbed.h"
|
||||
#include "core/hle/service/hid/controllers/touchscreen.h"
|
||||
#include "core/hle/service/hid/controllers/xpad.h"
|
||||
@@ -395,9 +396,10 @@ void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
|
||||
const auto handle{rp.Pop<u32>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
|
||||
LOG_DEBUG(Service_HID, "called, handle={}, applet_resource_user_id={}", handle,
|
||||
applet_resource_user_id);
|
||||
|
||||
applet_resource->ActivateController(HidController::SixAxisSensor);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
@@ -825,8 +827,9 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto handle{rp.Pop<u32>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, handle={}", handle);
|
||||
LOG_DEBUG(Service_HID, "called, handle={}", handle);
|
||||
|
||||
applet_resource->DeactivateController(HidController::SixAxisSensor);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
@@ -1188,4 +1191,4 @@ void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system
|
||||
std::make_shared<XCD_SYS>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace Service::HID
|
||||
} // namespace Service::HID
|
||||
Reference in New Issue
Block a user