Project Mjölnir: Part 1
Co-authored-by: James Rowe <jroweboy@gmail.com> Co-authored-by: Its-Rei <kupfel@gmail.com>
This commit is contained in:
parent
b8885aa03b
commit
f0fac0c7fb
84 changed files with 8695 additions and 3260 deletions
|
@ -24,6 +24,7 @@ constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
|
|||
constexpr std::size_t NPAD_OFFSET = 0x9A00;
|
||||
constexpr u32 BATTERY_FULL = 2;
|
||||
constexpr u32 MAX_NPAD_ID = 7;
|
||||
constexpr std::size_t HANDHELD_INDEX = 8;
|
||||
constexpr std::array<u32, 10> npad_id_list{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, NPAD_HANDHELD, NPAD_UNKNOWN,
|
||||
};
|
||||
|
@ -33,19 +34,41 @@ enum class JoystickId : std::size_t {
|
|||
Joystick_Right,
|
||||
};
|
||||
|
||||
static Controller_NPad::NPadControllerType MapSettingsTypeToNPad(Settings::ControllerType type) {
|
||||
Controller_NPad::NPadControllerType Controller_NPad::MapSettingsTypeToNPad(
|
||||
Settings::ControllerType type) {
|
||||
switch (type) {
|
||||
case Settings::ControllerType::ProController:
|
||||
return Controller_NPad::NPadControllerType::ProController;
|
||||
case Settings::ControllerType::DualJoycon:
|
||||
return Controller_NPad::NPadControllerType::JoyDual;
|
||||
return NPadControllerType::ProController;
|
||||
case Settings::ControllerType::DualJoyconDetached:
|
||||
return NPadControllerType::JoyDual;
|
||||
case Settings::ControllerType::LeftJoycon:
|
||||
return Controller_NPad::NPadControllerType::JoyLeft;
|
||||
return NPadControllerType::JoyLeft;
|
||||
case Settings::ControllerType::RightJoycon:
|
||||
return Controller_NPad::NPadControllerType::JoyRight;
|
||||
return NPadControllerType::JoyRight;
|
||||
case Settings::ControllerType::Handheld:
|
||||
return NPadControllerType::Handheld;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Controller_NPad::NPadControllerType::JoyDual;
|
||||
return NPadControllerType::ProController;
|
||||
}
|
||||
}
|
||||
|
||||
Settings::ControllerType Controller_NPad::MapNPadToSettingsType(
|
||||
Controller_NPad::NPadControllerType type) {
|
||||
switch (type) {
|
||||
case NPadControllerType::ProController:
|
||||
return Settings::ControllerType::ProController;
|
||||
case NPadControllerType::JoyDual:
|
||||
return Settings::ControllerType::DualJoyconDetached;
|
||||
case NPadControllerType::JoyLeft:
|
||||
return Settings::ControllerType::LeftJoycon;
|
||||
case NPadControllerType::JoyRight:
|
||||
return Settings::ControllerType::RightJoycon;
|
||||
case NPadControllerType::Handheld:
|
||||
return Settings::ControllerType::Handheld;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Settings::ControllerType::ProController;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,9 +83,9 @@ std::size_t Controller_NPad::NPadIdToIndex(u32 npad_id) {
|
|||
case 6:
|
||||
case 7:
|
||||
return npad_id;
|
||||
case 8:
|
||||
case HANDHELD_INDEX:
|
||||
case NPAD_HANDHELD:
|
||||
return 8;
|
||||
return HANDHELD_INDEX;
|
||||
case 9:
|
||||
case NPAD_UNKNOWN:
|
||||
return 9;
|
||||
|
@ -83,7 +106,7 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) {
|
|||
case 6:
|
||||
case 7:
|
||||
return static_cast<u32>(index);
|
||||
case 8:
|
||||
case HANDHELD_INDEX:
|
||||
return NPAD_HANDHELD;
|
||||
case 9:
|
||||
return NPAD_UNKNOWN;
|
||||
|
@ -96,25 +119,35 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) {
|
|||
Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {}
|
||||
Controller_NPad::~Controller_NPad() = default;
|
||||
|
||||
void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {
|
||||
void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
|
||||
const auto controller_type = connected_controllers[controller_idx].type;
|
||||
auto& controller = shared_memory_entries[controller_idx];
|
||||
if (controller_type == NPadControllerType::None) {
|
||||
styleset_changed_events[controller_idx].writable->Signal();
|
||||
return;
|
||||
}
|
||||
controller.joy_styles.raw = 0; // Zero out
|
||||
controller.device_type.raw = 0;
|
||||
controller.properties.raw = 0;
|
||||
switch (controller_type) {
|
||||
case NPadControllerType::None:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case NPadControllerType::Handheld:
|
||||
controller.joy_styles.handheld.Assign(1);
|
||||
controller.device_type.handheld.Assign(1);
|
||||
controller.pad_assignment = NPadAssignments::Dual;
|
||||
case NPadControllerType::ProController:
|
||||
controller.joy_styles.pro_controller.Assign(1);
|
||||
controller.device_type.pro_controller.Assign(1);
|
||||
controller.properties.is_vertical.Assign(1);
|
||||
controller.properties.use_plus.Assign(1);
|
||||
controller.properties.use_minus.Assign(1);
|
||||
controller.pad_assignment = NPadAssignments::Single;
|
||||
break;
|
||||
case NPadControllerType::Handheld:
|
||||
controller.joy_styles.handheld.Assign(1);
|
||||
controller.device_type.handheld.Assign(1);
|
||||
controller.properties.is_vertical.Assign(1);
|
||||
controller.properties.use_plus.Assign(1);
|
||||
controller.properties.use_minus.Assign(1);
|
||||
controller.pad_assignment = NPadAssignments::Dual;
|
||||
break;
|
||||
case NPadControllerType::JoyDual:
|
||||
controller.joy_styles.joycon_dual.Assign(1);
|
||||
|
@ -144,14 +177,6 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {
|
|||
controller.device_type.pokeball.Assign(1);
|
||||
controller.pad_assignment = NPadAssignments::Single;
|
||||
break;
|
||||
case NPadControllerType::ProController:
|
||||
controller.joy_styles.pro_controller.Assign(1);
|
||||
controller.device_type.pro_controller.Assign(1);
|
||||
controller.properties.is_vertical.Assign(1);
|
||||
controller.properties.use_plus.Assign(1);
|
||||
controller.properties.use_minus.Assign(1);
|
||||
controller.pad_assignment = NPadAssignments::Single;
|
||||
break;
|
||||
}
|
||||
|
||||
controller.single_color_error = ColorReadError::ReadOk;
|
||||
|
@ -192,36 +217,25 @@ void Controller_NPad::OnInit() {
|
|||
style.pokeball.Assign(1);
|
||||
}
|
||||
|
||||
std::transform(
|
||||
Settings::values.players.begin(), Settings::values.players.end(),
|
||||
connected_controllers.begin(), [](const Settings::PlayerInput& player) {
|
||||
return ControllerHolder{MapSettingsTypeToNPad(player.type), player.connected};
|
||||
});
|
||||
|
||||
std::stable_partition(connected_controllers.begin(), connected_controllers.begin() + 8,
|
||||
[](const ControllerHolder& holder) { return holder.is_connected; });
|
||||
std::transform(Settings::values.players.begin(), Settings::values.players.end(),
|
||||
connected_controllers.begin(), [](const Settings::PlayerInput& player) {
|
||||
return ControllerHolder{MapSettingsTypeToNPad(player.controller_type),
|
||||
player.connected};
|
||||
});
|
||||
|
||||
// Account for handheld
|
||||
if (connected_controllers[8].is_connected)
|
||||
connected_controllers[8].type = NPadControllerType::Handheld;
|
||||
if (connected_controllers[HANDHELD_INDEX].is_connected) {
|
||||
connected_controllers[HANDHELD_INDEX].type = NPadControllerType::Handheld;
|
||||
}
|
||||
|
||||
supported_npad_id_types.resize(npad_id_list.size());
|
||||
std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),
|
||||
npad_id_list.size() * sizeof(u32));
|
||||
|
||||
// Add a default dual joycon controller if none are present.
|
||||
if (std::none_of(connected_controllers.begin(), connected_controllers.end(),
|
||||
[](const ControllerHolder& controller) { return controller.is_connected; })) {
|
||||
supported_npad_id_types.resize(npad_id_list.size());
|
||||
std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),
|
||||
npad_id_list.size() * sizeof(u32));
|
||||
AddNewController(NPadControllerType::JoyDual);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < connected_controllers.size(); ++i) {
|
||||
const auto& controller = connected_controllers[i];
|
||||
if (controller.is_connected) {
|
||||
AddNewControllerAt(controller.type, IndexToNPad(i));
|
||||
AddNewControllerAt(controller.type, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -309,8 +323,9 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
|
|||
|
||||
void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t data_len) {
|
||||
if (!IsControllerActivated())
|
||||
if (!IsControllerActivated()) {
|
||||
return;
|
||||
}
|
||||
for (std::size_t i = 0; i < shared_memory_entries.size(); i++) {
|
||||
auto& npad = shared_memory_entries[i];
|
||||
const std::array<NPadGeneric*, 7> controller_npads{&npad.main_controller_states,
|
||||
|
@ -365,6 +380,14 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
|||
case NPadControllerType::None:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case NPadControllerType::ProController:
|
||||
main_controller.connection_status.raw = 0;
|
||||
main_controller.connection_status.IsConnected.Assign(1);
|
||||
main_controller.connection_status.IsWired.Assign(1);
|
||||
main_controller.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||
main_controller.pad.l_stick = pad_state.l_stick;
|
||||
main_controller.pad.r_stick = pad_state.r_stick;
|
||||
break;
|
||||
case NPadControllerType::Handheld:
|
||||
handheld_entry.connection_status.raw = 0;
|
||||
handheld_entry.connection_status.IsWired.Assign(1);
|
||||
|
@ -378,22 +401,19 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
|||
break;
|
||||
case NPadControllerType::JoyDual:
|
||||
dual_entry.connection_status.raw = 0;
|
||||
|
||||
dual_entry.connection_status.IsConnected.Assign(1);
|
||||
dual_entry.connection_status.IsLeftJoyConnected.Assign(1);
|
||||
dual_entry.connection_status.IsRightJoyConnected.Assign(1);
|
||||
dual_entry.connection_status.IsConnected.Assign(1);
|
||||
|
||||
libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
|
||||
libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
|
||||
libnx_entry.connection_status.IsConnected.Assign(1);
|
||||
|
||||
dual_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||
dual_entry.pad.l_stick = pad_state.l_stick;
|
||||
dual_entry.pad.r_stick = pad_state.r_stick;
|
||||
|
||||
libnx_entry.connection_status.IsConnected.Assign(1);
|
||||
libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
|
||||
libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
|
||||
break;
|
||||
case NPadControllerType::JoyLeft:
|
||||
left_entry.connection_status.raw = 0;
|
||||
|
||||
left_entry.connection_status.IsConnected.Assign(1);
|
||||
left_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||
left_entry.pad.l_stick = pad_state.l_stick;
|
||||
|
@ -401,7 +421,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
|||
break;
|
||||
case NPadControllerType::JoyRight:
|
||||
right_entry.connection_status.raw = 0;
|
||||
|
||||
right_entry.connection_status.IsConnected.Assign(1);
|
||||
right_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||
right_entry.pad.l_stick = pad_state.l_stick;
|
||||
|
@ -409,23 +428,12 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
|||
break;
|
||||
case NPadControllerType::Pokeball:
|
||||
pokeball_entry.connection_status.raw = 0;
|
||||
|
||||
pokeball_entry.connection_status.IsConnected.Assign(1);
|
||||
pokeball_entry.connection_status.IsWired.Assign(1);
|
||||
|
||||
pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||
pokeball_entry.pad.l_stick = pad_state.l_stick;
|
||||
pokeball_entry.pad.r_stick = pad_state.r_stick;
|
||||
break;
|
||||
case NPadControllerType::ProController:
|
||||
main_controller.connection_status.raw = 0;
|
||||
|
||||
main_controller.connection_status.IsConnected.Assign(1);
|
||||
main_controller.connection_status.IsWired.Assign(1);
|
||||
main_controller.pad.pad_states.raw = pad_state.pad_states.raw;
|
||||
main_controller.pad.l_stick = pad_state.l_stick;
|
||||
main_controller.pad.r_stick = pad_state.r_stick;
|
||||
break;
|
||||
}
|
||||
|
||||
// LibNX exclusively uses this section, so we always update it since LibNX doesn't activate
|
||||
|
@ -453,26 +461,6 @@ void Controller_NPad::SetSupportedNPadIdTypes(u8* data, std::size_t length) {
|
|||
supported_npad_id_types.clear();
|
||||
supported_npad_id_types.resize(length / sizeof(u32));
|
||||
std::memcpy(supported_npad_id_types.data(), data, length);
|
||||
for (std::size_t i = 0; i < connected_controllers.size(); i++) {
|
||||
auto& controller = connected_controllers[i];
|
||||
if (!controller.is_connected) {
|
||||
continue;
|
||||
}
|
||||
const auto requested_controller =
|
||||
i <= MAX_NPAD_ID ? MapSettingsTypeToNPad(Settings::values.players[i].type)
|
||||
: NPadControllerType::Handheld;
|
||||
if (!IsControllerSupported(requested_controller)) {
|
||||
const auto is_handheld = requested_controller == NPadControllerType::Handheld;
|
||||
if (is_handheld) {
|
||||
controller.type = NPadControllerType::None;
|
||||
controller.is_connected = false;
|
||||
AddNewController(requested_controller);
|
||||
} else {
|
||||
controller.type = requested_controller;
|
||||
InitNewlyAddedControler(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {
|
||||
|
@ -504,7 +492,7 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
|
|||
const std::vector<Vibration>& vibrations) {
|
||||
LOG_DEBUG(Service_HID, "(STUBBED) called");
|
||||
|
||||
if (!can_controllers_vibrate) {
|
||||
if (!Settings::values.vibration_enabled || !can_controllers_vibrate) {
|
||||
return;
|
||||
}
|
||||
for (std::size_t i = 0; i < controller_ids.size(); i++) {
|
||||
|
@ -517,8 +505,6 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
|
|||
}
|
||||
|
||||
std::shared_ptr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent(u32 npad_id) const {
|
||||
// TODO(ogniK): Figure out the best time to signal this event. This event seems that it should
|
||||
// be signalled at least once, and signaled after a new controller is connected?
|
||||
const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)];
|
||||
return styleset_event.readable;
|
||||
}
|
||||
|
@ -527,43 +513,43 @@ Controller_NPad::Vibration Controller_NPad::GetLastVibration() const {
|
|||
return last_processed_vibration;
|
||||
}
|
||||
|
||||
void Controller_NPad::AddNewController(NPadControllerType controller) {
|
||||
controller = DecideBestController(controller);
|
||||
if (controller == NPadControllerType::Handheld) {
|
||||
connected_controllers[8] = {controller, true};
|
||||
InitNewlyAddedControler(8);
|
||||
return;
|
||||
}
|
||||
const auto pos =
|
||||
std::find_if(connected_controllers.begin(), connected_controllers.end() - 2,
|
||||
[](const ControllerHolder& holder) { return !holder.is_connected; });
|
||||
if (pos == connected_controllers.end() - 2) {
|
||||
LOG_ERROR(Service_HID, "Cannot connect any more controllers!");
|
||||
return;
|
||||
}
|
||||
const auto controller_id = std::distance(connected_controllers.begin(), pos);
|
||||
connected_controllers[controller_id] = {controller, true};
|
||||
InitNewlyAddedControler(controller_id);
|
||||
void Controller_NPad::AddNewControllerAt(NPadControllerType controller, std::size_t npad_index) {
|
||||
UpdateControllerAt(controller, npad_index, true);
|
||||
}
|
||||
|
||||
void Controller_NPad::AddNewControllerAt(NPadControllerType controller, u32 npad_id) {
|
||||
controller = DecideBestController(controller);
|
||||
if (controller == NPadControllerType::Handheld) {
|
||||
connected_controllers[NPadIdToIndex(NPAD_HANDHELD)] = {controller, true};
|
||||
InitNewlyAddedControler(NPadIdToIndex(NPAD_HANDHELD));
|
||||
void Controller_NPad::UpdateControllerAt(NPadControllerType controller, std::size_t npad_index,
|
||||
bool connected) {
|
||||
if (!connected) {
|
||||
DisconnectNPad(IndexToNPad(npad_index));
|
||||
return;
|
||||
}
|
||||
|
||||
connected_controllers[NPadIdToIndex(npad_id)] = {controller, true};
|
||||
InitNewlyAddedControler(NPadIdToIndex(npad_id));
|
||||
}
|
||||
if (controller == NPadControllerType::Handheld) {
|
||||
Settings::values.players[HANDHELD_INDEX].controller_type =
|
||||
MapNPadToSettingsType(controller);
|
||||
Settings::values.players[HANDHELD_INDEX].connected = true;
|
||||
connected_controllers[HANDHELD_INDEX] = {controller, true};
|
||||
InitNewlyAddedController(HANDHELD_INDEX);
|
||||
return;
|
||||
}
|
||||
|
||||
void Controller_NPad::ConnectNPad(u32 npad_id) {
|
||||
connected_controllers[NPadIdToIndex(npad_id)].is_connected = true;
|
||||
Settings::values.players[npad_index].controller_type = MapNPadToSettingsType(controller);
|
||||
Settings::values.players[npad_index].connected = true;
|
||||
connected_controllers[npad_index] = {controller, true};
|
||||
InitNewlyAddedController(npad_index);
|
||||
}
|
||||
|
||||
void Controller_NPad::DisconnectNPad(u32 npad_id) {
|
||||
connected_controllers[NPadIdToIndex(npad_id)].is_connected = false;
|
||||
const auto npad_index = NPadIdToIndex(npad_id);
|
||||
connected_controllers[npad_index].is_connected = false;
|
||||
Settings::values.players[npad_index].connected = false;
|
||||
|
||||
auto& controller = shared_memory_entries[npad_index];
|
||||
controller.joy_styles.raw = 0; // Zero out
|
||||
controller.device_type.raw = 0;
|
||||
controller.properties.raw = 0;
|
||||
|
||||
styleset_changed_events[npad_index].writable->Signal();
|
||||
}
|
||||
|
||||
void Controller_NPad::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode) {
|
||||
|
@ -599,8 +585,8 @@ bool Controller_NPad::SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2) {
|
|||
|
||||
std::swap(connected_controllers[npad_index_1].type, connected_controllers[npad_index_2].type);
|
||||
|
||||
InitNewlyAddedControler(npad_index_1);
|
||||
InitNewlyAddedControler(npad_index_2);
|
||||
AddNewControllerAt(connected_controllers[npad_index_1].type, npad_index_1);
|
||||
AddNewControllerAt(connected_controllers[npad_index_2].type, npad_index_2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -628,7 +614,6 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) {
|
|||
case 7:
|
||||
return LedPattern{0, 1, 1, 0};
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unhandled npad_id {}", npad_id);
|
||||
return LedPattern{0, 0, 0, 0};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,10 +118,11 @@ public:
|
|||
std::shared_ptr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const;
|
||||
Vibration GetLastVibration() const;
|
||||
|
||||
void AddNewController(NPadControllerType controller);
|
||||
void AddNewControllerAt(NPadControllerType controller, u32 npad_id);
|
||||
// Adds a new controller at an index.
|
||||
void AddNewControllerAt(NPadControllerType controller, std::size_t npad_index);
|
||||
// Adds a new controller at an index with connection status.
|
||||
void UpdateControllerAt(NPadControllerType controller, std::size_t npad_index, bool connected);
|
||||
|
||||
void ConnectNPad(u32 npad_id);
|
||||
void DisconnectNPad(u32 npad_id);
|
||||
void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode);
|
||||
GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode() const;
|
||||
|
@ -141,6 +142,8 @@ public:
|
|||
// Specifically for cheat engine and other features.
|
||||
u32 GetAndResetPressState();
|
||||
|
||||
static Controller_NPad::NPadControllerType MapSettingsTypeToNPad(Settings::ControllerType type);
|
||||
static Settings::ControllerType MapNPadToSettingsType(Controller_NPad::NPadControllerType type);
|
||||
static std::size_t NPadIdToIndex(u32 npad_id);
|
||||
static u32 IndexToNPad(std::size_t index);
|
||||
|
||||
|
@ -309,7 +312,7 @@ private:
|
|||
bool is_connected;
|
||||
};
|
||||
|
||||
void InitNewlyAddedControler(std::size_t controller_idx);
|
||||
void InitNewlyAddedController(std::size_t controller_idx);
|
||||
bool IsControllerSupported(NPadControllerType controller) const;
|
||||
NPadControllerType DecideBestController(NPadControllerType priority) const;
|
||||
void RequestPadStateUpdate(u32 npad_id);
|
||||
|
|
|
@ -38,11 +38,9 @@
|
|||
namespace Service::HID {
|
||||
|
||||
// Updating period for each HID device.
|
||||
// TODO(ogniK): Find actual polling rate of hid
|
||||
constexpr auto pad_update_ns = std::chrono::nanoseconds{1000000000 / 66};
|
||||
[[maybe_unused]] constexpr auto accelerometer_update_ns =
|
||||
std::chrono::nanoseconds{1000000000 / 100};
|
||||
[[maybe_unused]] constexpr auto gyroscope_update_ticks = std::chrono::nanoseconds{1000000000 / 100};
|
||||
// HID is polled every 15ms, this value was derived from
|
||||
// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet
|
||||
constexpr auto pad_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.6Hz)
|
||||
constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
|
||||
|
||||
IAppletResource::IAppletResource(Core::System& system)
|
||||
|
@ -845,8 +843,7 @@ void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
|
|||
void Hid::PermitVibration(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto can_vibrate{rp.Pop<bool>()};
|
||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||
.SetVibrationEnabled(can_vibrate);
|
||||
Settings::values.vibration_enabled = can_vibrate;
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
|
||||
|
||||
|
@ -859,8 +856,7 @@ void Hid::IsVibrationPermitted(Kernel::HLERequestContext& ctx) {
|
|||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(
|
||||
applet_resource->GetController<Controller_NPad>(HidController::NPad).IsVibrationEnabled());
|
||||
rb.Push(Settings::values.vibration_enabled);
|
||||
}
|
||||
|
||||
void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
|
||||
|
|
|
@ -13,56 +13,6 @@
|
|||
|
||||
namespace Settings {
|
||||
|
||||
namespace NativeButton {
|
||||
const std::array<const char*, NumButtons> mapping = {{
|
||||
"button_a",
|
||||
"button_b",
|
||||
"button_x",
|
||||
"button_y",
|
||||
"button_lstick",
|
||||
"button_rstick",
|
||||
"button_l",
|
||||
"button_r",
|
||||
"button_zl",
|
||||
"button_zr",
|
||||
"button_plus",
|
||||
"button_minus",
|
||||
"button_dleft",
|
||||
"button_dup",
|
||||
"button_dright",
|
||||
"button_ddown",
|
||||
"button_lstick_left",
|
||||
"button_lstick_up",
|
||||
"button_lstick_right",
|
||||
"button_lstick_down",
|
||||
"button_rstick_left",
|
||||
"button_rstick_up",
|
||||
"button_rstick_right",
|
||||
"button_rstick_down",
|
||||
"button_sl",
|
||||
"button_sr",
|
||||
"button_home",
|
||||
"button_screenshot",
|
||||
}};
|
||||
}
|
||||
|
||||
namespace NativeAnalog {
|
||||
const std::array<const char*, NumAnalogs> mapping = {{
|
||||
"lstick",
|
||||
"rstick",
|
||||
}};
|
||||
}
|
||||
|
||||
namespace NativeMouseButton {
|
||||
const std::array<const char*, NumMouseButtons> mapping = {{
|
||||
"left",
|
||||
"right",
|
||||
"middle",
|
||||
"forward",
|
||||
"back",
|
||||
}};
|
||||
}
|
||||
|
||||
Values values = {};
|
||||
bool configuring_global = true;
|
||||
|
||||
|
|
|
@ -12,340 +12,10 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include "common/common_types.h"
|
||||
#include "input_common/settings.h"
|
||||
|
||||
namespace Settings {
|
||||
|
||||
namespace NativeButton {
|
||||
enum Values {
|
||||
A,
|
||||
B,
|
||||
X,
|
||||
Y,
|
||||
LStick,
|
||||
RStick,
|
||||
L,
|
||||
R,
|
||||
ZL,
|
||||
ZR,
|
||||
Plus,
|
||||
Minus,
|
||||
|
||||
DLeft,
|
||||
DUp,
|
||||
DRight,
|
||||
DDown,
|
||||
|
||||
LStick_Left,
|
||||
LStick_Up,
|
||||
LStick_Right,
|
||||
LStick_Down,
|
||||
|
||||
RStick_Left,
|
||||
RStick_Up,
|
||||
RStick_Right,
|
||||
RStick_Down,
|
||||
|
||||
SL,
|
||||
SR,
|
||||
|
||||
Home,
|
||||
Screenshot,
|
||||
|
||||
NumButtons,
|
||||
};
|
||||
|
||||
constexpr int BUTTON_HID_BEGIN = A;
|
||||
constexpr int BUTTON_NS_BEGIN = Home;
|
||||
|
||||
constexpr int BUTTON_HID_END = BUTTON_NS_BEGIN;
|
||||
constexpr int BUTTON_NS_END = NumButtons;
|
||||
|
||||
constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN;
|
||||
constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN;
|
||||
|
||||
extern const std::array<const char*, NumButtons> mapping;
|
||||
|
||||
} // namespace NativeButton
|
||||
|
||||
namespace NativeAnalog {
|
||||
enum Values {
|
||||
LStick,
|
||||
RStick,
|
||||
|
||||
NumAnalogs,
|
||||
};
|
||||
|
||||
constexpr int STICK_HID_BEGIN = LStick;
|
||||
constexpr int STICK_HID_END = NumAnalogs;
|
||||
constexpr int NUM_STICKS_HID = NumAnalogs;
|
||||
|
||||
extern const std::array<const char*, NumAnalogs> mapping;
|
||||
} // namespace NativeAnalog
|
||||
|
||||
namespace NativeMouseButton {
|
||||
enum Values {
|
||||
Left,
|
||||
Right,
|
||||
Middle,
|
||||
Forward,
|
||||
Back,
|
||||
|
||||
NumMouseButtons,
|
||||
};
|
||||
|
||||
constexpr int MOUSE_HID_BEGIN = Left;
|
||||
constexpr int MOUSE_HID_END = NumMouseButtons;
|
||||
constexpr int NUM_MOUSE_HID = NumMouseButtons;
|
||||
|
||||
extern const std::array<const char*, NumMouseButtons> mapping;
|
||||
} // namespace NativeMouseButton
|
||||
|
||||
namespace NativeKeyboard {
|
||||
enum Keys {
|
||||
None,
|
||||
Error,
|
||||
|
||||
A = 4,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
H,
|
||||
I,
|
||||
J,
|
||||
K,
|
||||
L,
|
||||
M,
|
||||
N,
|
||||
O,
|
||||
P,
|
||||
Q,
|
||||
R,
|
||||
S,
|
||||
T,
|
||||
U,
|
||||
V,
|
||||
W,
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
N1,
|
||||
N2,
|
||||
N3,
|
||||
N4,
|
||||
N5,
|
||||
N6,
|
||||
N7,
|
||||
N8,
|
||||
N9,
|
||||
N0,
|
||||
Enter,
|
||||
Escape,
|
||||
Backspace,
|
||||
Tab,
|
||||
Space,
|
||||
Minus,
|
||||
Equal,
|
||||
LeftBrace,
|
||||
RightBrace,
|
||||
Backslash,
|
||||
Tilde,
|
||||
Semicolon,
|
||||
Apostrophe,
|
||||
Grave,
|
||||
Comma,
|
||||
Dot,
|
||||
Slash,
|
||||
CapsLockKey,
|
||||
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
F11,
|
||||
F12,
|
||||
|
||||
SystemRequest,
|
||||
ScrollLockKey,
|
||||
Pause,
|
||||
Insert,
|
||||
Home,
|
||||
PageUp,
|
||||
Delete,
|
||||
End,
|
||||
PageDown,
|
||||
Right,
|
||||
Left,
|
||||
Down,
|
||||
Up,
|
||||
|
||||
NumLockKey,
|
||||
KPSlash,
|
||||
KPAsterisk,
|
||||
KPMinus,
|
||||
KPPlus,
|
||||
KPEnter,
|
||||
KP1,
|
||||
KP2,
|
||||
KP3,
|
||||
KP4,
|
||||
KP5,
|
||||
KP6,
|
||||
KP7,
|
||||
KP8,
|
||||
KP9,
|
||||
KP0,
|
||||
KPDot,
|
||||
|
||||
Key102,
|
||||
Compose,
|
||||
Power,
|
||||
KPEqual,
|
||||
|
||||
F13,
|
||||
F14,
|
||||
F15,
|
||||
F16,
|
||||
F17,
|
||||
F18,
|
||||
F19,
|
||||
F20,
|
||||
F21,
|
||||
F22,
|
||||
F23,
|
||||
F24,
|
||||
|
||||
Open,
|
||||
Help,
|
||||
Properties,
|
||||
Front,
|
||||
Stop,
|
||||
Repeat,
|
||||
Undo,
|
||||
Cut,
|
||||
Copy,
|
||||
Paste,
|
||||
Find,
|
||||
Mute,
|
||||
VolumeUp,
|
||||
VolumeDown,
|
||||
CapsLockActive,
|
||||
NumLockActive,
|
||||
ScrollLockActive,
|
||||
KPComma,
|
||||
|
||||
KPLeftParenthesis,
|
||||
KPRightParenthesis,
|
||||
|
||||
LeftControlKey = 0xE0,
|
||||
LeftShiftKey,
|
||||
LeftAltKey,
|
||||
LeftMetaKey,
|
||||
RightControlKey,
|
||||
RightShiftKey,
|
||||
RightAltKey,
|
||||
RightMetaKey,
|
||||
|
||||
MediaPlayPause,
|
||||
MediaStopCD,
|
||||
MediaPrevious,
|
||||
MediaNext,
|
||||
MediaEject,
|
||||
MediaVolumeUp,
|
||||
MediaVolumeDown,
|
||||
MediaMute,
|
||||
MediaWebsite,
|
||||
MediaBack,
|
||||
MediaForward,
|
||||
MediaStop,
|
||||
MediaFind,
|
||||
MediaScrollUp,
|
||||
MediaScrollDown,
|
||||
MediaEdit,
|
||||
MediaSleep,
|
||||
MediaCoffee,
|
||||
MediaRefresh,
|
||||
MediaCalculator,
|
||||
|
||||
NumKeyboardKeys,
|
||||
};
|
||||
|
||||
static_assert(NumKeyboardKeys == 0xFC, "Incorrect number of keyboard keys.");
|
||||
|
||||
enum Modifiers {
|
||||
LeftControl,
|
||||
LeftShift,
|
||||
LeftAlt,
|
||||
LeftMeta,
|
||||
RightControl,
|
||||
RightShift,
|
||||
RightAlt,
|
||||
RightMeta,
|
||||
CapsLock,
|
||||
ScrollLock,
|
||||
NumLock,
|
||||
|
||||
NumKeyboardMods,
|
||||
};
|
||||
|
||||
constexpr int KEYBOARD_KEYS_HID_BEGIN = None;
|
||||
constexpr int KEYBOARD_KEYS_HID_END = NumKeyboardKeys;
|
||||
constexpr int NUM_KEYBOARD_KEYS_HID = NumKeyboardKeys;
|
||||
|
||||
constexpr int KEYBOARD_MODS_HID_BEGIN = LeftControl;
|
||||
constexpr int KEYBOARD_MODS_HID_END = NumKeyboardMods;
|
||||
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 MouseButtonsRaw = std::array<std::string, NativeMouseButton::NumMouseButtons>;
|
||||
using KeyboardKeysRaw = std::array<std::string, NativeKeyboard::NumKeyboardKeys>;
|
||||
using KeyboardModsRaw = std::array<std::string, NativeKeyboard::NumKeyboardMods>;
|
||||
|
||||
constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28;
|
||||
constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A;
|
||||
constexpr u32 JOYCON_BODY_NEON_BLUE = 0x0AB9E6;
|
||||
constexpr u32 JOYCON_BUTTONS_NEON_BLUE = 0x001E1E;
|
||||
|
||||
enum class ControllerType {
|
||||
ProController,
|
||||
DualJoycon,
|
||||
RightJoycon,
|
||||
LeftJoycon,
|
||||
};
|
||||
|
||||
struct PlayerInput {
|
||||
bool connected;
|
||||
ControllerType type;
|
||||
ButtonsRaw buttons;
|
||||
AnalogsRaw analogs;
|
||||
|
||||
u32 body_color_right;
|
||||
u32 button_color_right;
|
||||
u32 body_color_left;
|
||||
u32 button_color_left;
|
||||
};
|
||||
|
||||
struct TouchscreenInput {
|
||||
bool enabled;
|
||||
std::string device;
|
||||
|
||||
u32 finger;
|
||||
u32 diameter_x;
|
||||
u32 diameter_y;
|
||||
u32 rotation_angle;
|
||||
};
|
||||
|
||||
enum class RendererBackend {
|
||||
OpenGL = 0,
|
||||
Vulkan = 1,
|
||||
|
@ -461,6 +131,8 @@ struct Values {
|
|||
// Controls
|
||||
std::array<PlayerInput, 10> players;
|
||||
|
||||
bool use_docked_mode;
|
||||
|
||||
bool mouse_enabled;
|
||||
std::string mouse_device;
|
||||
MouseButtonsRaw mouse_buttons;
|
||||
|
@ -474,14 +146,15 @@ struct Values {
|
|||
AnalogsRaw debug_pad_analogs;
|
||||
|
||||
std::string motion_device;
|
||||
|
||||
bool vibration_enabled;
|
||||
|
||||
TouchscreenInput touchscreen;
|
||||
std::atomic_bool is_device_reload_pending{true};
|
||||
std::string udp_input_address;
|
||||
u16 udp_input_port;
|
||||
u8 udp_pad_index;
|
||||
|
||||
bool use_docked_mode;
|
||||
|
||||
// Data Storage
|
||||
bool use_virtual_sd;
|
||||
bool gamecard_inserted;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue