40 changed files with 1065 additions and 842 deletions
-
10src/core/CMakeLists.txt
-
15src/core/hle/kernel/kernel.cpp
-
6src/core/hle/kernel/kernel.h
-
39src/core/hle/service/hid/controllers/applet_resource.cpp
-
7src/core/hle/service/hid/controllers/applet_resource.h
-
19src/core/hle/service/hid/controllers/console_six_axis.cpp
-
19src/core/hle/service/hid/controllers/console_six_axis.h
-
3src/core/hle/service/hid/controllers/controller_base.h
-
21src/core/hle/service/hid/controllers/debug_pad.cpp
-
47src/core/hle/service/hid/controllers/debug_pad.h
-
33src/core/hle/service/hid/controllers/gesture.cpp
-
85src/core/hle/service/hid/controllers/gesture.h
-
21src/core/hle/service/hid/controllers/keyboard.cpp
-
31src/core/hle/service/hid/controllers/keyboard.h
-
17src/core/hle/service/hid/controllers/mouse.cpp
-
14src/core/hle/service/hid/controllers/mouse.h
-
28src/core/hle/service/hid/controllers/npad.cpp
-
309src/core/hle/service/hid/controllers/npad.h
-
3src/core/hle/service/hid/controllers/palma.cpp
-
3src/core/hle/service/hid/controllers/palma.h
-
239src/core/hle/service/hid/controllers/shared_memory_format.h
-
49src/core/hle/service/hid/controllers/shared_memory_holder.cpp
-
44src/core/hle/service/hid/controllers/shared_memory_holder.h
-
25src/core/hle/service/hid/controllers/six_axis.cpp
-
17src/core/hle/service/hid/controllers/stubbed.cpp
-
17src/core/hle/service/hid/controllers/stubbed.h
-
22src/core/hle/service/hid/controllers/touchscreen.cpp
-
30src/core/hle/service/hid/controllers/touchscreen.h
-
31src/core/hle/service/hid/controllers/types/debug_pad_types.h
-
77src/core/hle/service/hid/controllers/types/gesture_types.h
-
20src/core/hle/service/hid/controllers/types/keyboard_types.h
-
12src/core/hle/service/hid/controllers/types/mouse_types.h
-
255src/core/hle/service/hid/controllers/types/npad_types.h
-
90src/core/hle/service/hid/controllers/types/touch_types.h
-
39src/core/hle/service/hid/controllers/xpad.cpp
-
112src/core/hle/service/hid/controllers/xpad.h
-
23src/core/hle/service/hid/hid_server.cpp
-
3src/core/hle/service/hid/hid_system_server.cpp
-
64src/core/hle/service/hid/resource_manager.cpp
-
8src/core/hle/service/hid/resource_manager.h
@ -0,0 +1,239 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
#include "common/vector_math.h" |
|||
#include "core/hid/hid_types.h" |
|||
#include "core/hle/service/hid//controllers/types/debug_pad_types.h" |
|||
#include "core/hle/service/hid//controllers/types/keyboard_types.h" |
|||
#include "core/hle/service/hid//controllers/types/mouse_types.h" |
|||
#include "core/hle/service/hid//controllers/types/npad_types.h" |
|||
#include "core/hle/service/hid//controllers/types/touch_types.h" |
|||
#include "core/hle/service/hid/ring_lifo.h" |
|||
|
|||
namespace Service::HID { |
|||
static const std::size_t HidEntryCount = 17; |
|||
|
|||
struct CommonHeader { |
|||
s64 timestamp{}; |
|||
s64 total_entry_count{}; |
|||
s64 last_entry_index{}; |
|||
s64 entry_count{}; |
|||
}; |
|||
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::DebugPadSharedMemoryFormat |
|||
struct DebugPadSharedMemoryFormat { |
|||
// This is nn::hid::detail::DebugPadLifo |
|||
Lifo<DebugPadState, HidEntryCount> debug_pad_lifo{}; |
|||
static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size"); |
|||
INSERT_PADDING_WORDS(0x4E); |
|||
}; |
|||
static_assert(sizeof(DebugPadSharedMemoryFormat) == 0x400, |
|||
"DebugPadSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::TouchScreenSharedMemoryFormat |
|||
struct TouchScreenSharedMemoryFormat { |
|||
// This is nn::hid::detail::TouchScreenLifo |
|||
Lifo<TouchScreenState, HidEntryCount> touch_screen_lifo{}; |
|||
static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size"); |
|||
INSERT_PADDING_WORDS(0xF2); |
|||
}; |
|||
static_assert(sizeof(TouchScreenSharedMemoryFormat) == 0x3000, |
|||
"TouchScreenSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::MouseSharedMemoryFormat |
|||
struct MouseSharedMemoryFormat { |
|||
// This is nn::hid::detail::MouseLifo |
|||
Lifo<Core::HID::MouseState, HidEntryCount> mouse_lifo{}; |
|||
static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); |
|||
INSERT_PADDING_WORDS(0x2C); |
|||
}; |
|||
static_assert(sizeof(MouseSharedMemoryFormat) == 0x400, |
|||
"MouseSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::KeyboardSharedMemoryFormat |
|||
struct KeyboardSharedMemoryFormat { |
|||
// This is nn::hid::detail::KeyboardLifo |
|||
Lifo<KeyboardState, HidEntryCount> keyboard_lifo{}; |
|||
static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size"); |
|||
INSERT_PADDING_WORDS(0xA); |
|||
}; |
|||
static_assert(sizeof(KeyboardSharedMemoryFormat) == 0x400, |
|||
"KeyboardSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::DigitizerSharedMemoryFormat |
|||
struct DigitizerSharedMemoryFormat { |
|||
CommonHeader header; |
|||
INSERT_PADDING_BYTES(0xFE0); |
|||
}; |
|||
static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000, |
|||
"DigitizerSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::HomeButtonSharedMemoryFormat |
|||
struct HomeButtonSharedMemoryFormat { |
|||
CommonHeader header; |
|||
INSERT_PADDING_BYTES(0x1E0); |
|||
}; |
|||
static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200, |
|||
"HomeButtonSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::SleepButtonSharedMemoryFormat |
|||
struct SleepButtonSharedMemoryFormat { |
|||
CommonHeader header; |
|||
INSERT_PADDING_BYTES(0x1E0); |
|||
}; |
|||
static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200, |
|||
"SleepButtonSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::CaptureButtonSharedMemoryFormat |
|||
struct CaptureButtonSharedMemoryFormat { |
|||
CommonHeader header; |
|||
INSERT_PADDING_BYTES(0x1E0); |
|||
}; |
|||
static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200, |
|||
"CaptureButtonSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::InputDetectorSharedMemoryFormat |
|||
struct InputDetectorSharedMemoryFormat { |
|||
CommonHeader header; |
|||
INSERT_PADDING_BYTES(0x7E0); |
|||
}; |
|||
static_assert(sizeof(InputDetectorSharedMemoryFormat) == 0x800, |
|||
"InputDetectorSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::UniquePadSharedMemoryFormat |
|||
struct UniquePadSharedMemoryFormat { |
|||
CommonHeader header; |
|||
INSERT_PADDING_BYTES(0x3FE0); |
|||
}; |
|||
static_assert(sizeof(UniquePadSharedMemoryFormat) == 0x4000, |
|||
"UniquePadSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::NpadSixAxisSensorLifo |
|||
struct NpadSixAxisSensorLifo { |
|||
Lifo<Core::HID::SixAxisSensorState, HidEntryCount> lifo; |
|||
}; |
|||
|
|||
// This is nn::hid::detail::NpadInternalState |
|||
struct NpadInternalState { |
|||
Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None}; |
|||
NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual}; |
|||
NpadFullKeyColorState fullkey_color{}; |
|||
NpadJoyColorState joycon_color{}; |
|||
Lifo<NPadGenericState, HidEntryCount> fullkey_lifo{}; |
|||
Lifo<NPadGenericState, HidEntryCount> handheld_lifo{}; |
|||
Lifo<NPadGenericState, HidEntryCount> joy_dual_lifo{}; |
|||
Lifo<NPadGenericState, HidEntryCount> joy_left_lifo{}; |
|||
Lifo<NPadGenericState, HidEntryCount> joy_right_lifo{}; |
|||
Lifo<NPadGenericState, HidEntryCount> palma_lifo{}; |
|||
Lifo<NPadGenericState, HidEntryCount> system_ext_lifo{}; |
|||
NpadSixAxisSensorLifo sixaxis_fullkey_lifo{}; |
|||
NpadSixAxisSensorLifo sixaxis_handheld_lifo{}; |
|||
NpadSixAxisSensorLifo sixaxis_dual_left_lifo{}; |
|||
NpadSixAxisSensorLifo sixaxis_dual_right_lifo{}; |
|||
NpadSixAxisSensorLifo sixaxis_left_lifo{}; |
|||
NpadSixAxisSensorLifo sixaxis_right_lifo{}; |
|||
DeviceType device_type{}; |
|||
INSERT_PADDING_BYTES(0x4); // Reserved |
|||
NPadSystemProperties system_properties{}; |
|||
NpadSystemButtonProperties button_properties{}; |
|||
Core::HID::NpadBatteryLevel battery_level_dual{}; |
|||
Core::HID::NpadBatteryLevel battery_level_left{}; |
|||
Core::HID::NpadBatteryLevel battery_level_right{}; |
|||
AppletFooterUiAttributes applet_footer_attributes{}; |
|||
AppletFooterUiType applet_footer_type{AppletFooterUiType::None}; |
|||
INSERT_PADDING_BYTES(0x5B); // Reserved |
|||
INSERT_PADDING_BYTES(0x20); // Unknown |
|||
Lifo<NpadGcTriggerState, HidEntryCount> gc_trigger_lifo{}; |
|||
NpadLarkType lark_type_l_and_main{}; |
|||
NpadLarkType lark_type_r{}; |
|||
NpadLuciaType lucia_type{}; |
|||
NpadLagerType lager_type{}; |
|||
Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties; |
|||
Core::HID::SixAxisSensorProperties sixaxis_handheld_properties; |
|||
Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties; |
|||
Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties; |
|||
Core::HID::SixAxisSensorProperties sixaxis_left_properties; |
|||
Core::HID::SixAxisSensorProperties sixaxis_right_properties; |
|||
}; |
|||
static_assert(sizeof(NpadInternalState) == 0x43F8, "NpadInternalState is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::NpadSharedMemoryEntry |
|||
struct NpadSharedMemoryEntry { |
|||
NpadInternalState internal_state; |
|||
INSERT_PADDING_BYTES(0xC08); |
|||
}; |
|||
static_assert(sizeof(NpadSharedMemoryEntry) == 0x5000, "NpadSharedMemoryEntry is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::NpadSharedMemoryFormat |
|||
struct NpadSharedMemoryFormat { |
|||
std::array<NpadSharedMemoryEntry, NPAD_COUNT> npad_entry; |
|||
}; |
|||
static_assert(sizeof(NpadSharedMemoryFormat) == 0x32000, |
|||
"NpadSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::GestureSharedMemoryFormat |
|||
struct GestureSharedMemoryFormat { |
|||
// This is nn::hid::detail::GestureLifo |
|||
Lifo<GestureState, HidEntryCount> gesture_lifo{}; |
|||
static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size"); |
|||
INSERT_PADDING_WORDS(0x3E); |
|||
}; |
|||
static_assert(sizeof(GestureSharedMemoryFormat) == 0x800, |
|||
"GestureSharedMemoryFormat is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat |
|||
struct ConsoleSixAxisSensorSharedMemoryFormat { |
|||
u64 sampling_number{}; |
|||
bool is_seven_six_axis_sensor_at_rest{}; |
|||
INSERT_PADDING_BYTES(3); // padding |
|||
f32 verticalization_error{}; |
|||
Common::Vec3f gyro_bias{}; |
|||
INSERT_PADDING_BYTES(4); // padding |
|||
}; |
|||
static_assert(sizeof(ConsoleSixAxisSensorSharedMemoryFormat) == 0x20, |
|||
"ConsoleSixAxisSensorSharedMemoryFormat is an invalid size"); |
|||
|
|||
struct SharedMemoryFormat { |
|||
void Initialize() {} |
|||
|
|||
DebugPadSharedMemoryFormat debug_pad; |
|||
TouchScreenSharedMemoryFormat touch_screen; |
|||
MouseSharedMemoryFormat mouse; |
|||
KeyboardSharedMemoryFormat keyboard; |
|||
DigitizerSharedMemoryFormat digitizer; |
|||
HomeButtonSharedMemoryFormat home_button; |
|||
SleepButtonSharedMemoryFormat sleep_button; |
|||
CaptureButtonSharedMemoryFormat capture_button; |
|||
InputDetectorSharedMemoryFormat input_detector; |
|||
UniquePadSharedMemoryFormat unique_pad; |
|||
NpadSharedMemoryFormat npad; |
|||
GestureSharedMemoryFormat gesture; |
|||
ConsoleSixAxisSensorSharedMemoryFormat console; |
|||
INSERT_PADDING_BYTES(0x19E0); |
|||
MouseSharedMemoryFormat debug_mouse; |
|||
INSERT_PADDING_BYTES(0x2000); |
|||
}; |
|||
static_assert(offsetof(SharedMemoryFormat, debug_pad) == 0x0, "debug_pad has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, touch_screen) == 0x400, "touch_screen has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, mouse) == 0x3400, "mouse has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, keyboard) == 0x3800, "keyboard has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, digitizer) == 0x3C00, "digitizer has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, home_button) == 0x4C00, "home_button has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, sleep_button) == 0x4E00, |
|||
"sleep_button has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, capture_button) == 0x5000, |
|||
"capture_button has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, input_detector) == 0x5200, |
|||
"input_detector has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, npad) == 0x9A00, "npad has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, gesture) == 0x3BA00, "gesture has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, console) == 0x3C200, "console has wrong offset"); |
|||
static_assert(offsetof(SharedMemoryFormat, debug_mouse) == 0x3DC00, "debug_mouse has wrong offset"); |
|||
static_assert(sizeof(SharedMemoryFormat) == 0x40000, "SharedMemoryFormat is an invalid size"); |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,49 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "core/core.h"
|
|||
#include "core/hle/kernel/k_shared_memory.h"
|
|||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
|||
#include "core/hle/service/hid/controllers/shared_memory_holder.h"
|
|||
#include "core/hle/service/hid/errors.h"
|
|||
|
|||
namespace Service::HID { |
|||
SharedMemoryHolder::SharedMemoryHolder() {} |
|||
|
|||
Result SharedMemoryHolder::Initialize(Core::System& system) { |
|||
shared_memory = Kernel::KSharedMemory::Create(system.Kernel()); |
|||
const Result result = shared_memory->Initialize( |
|||
system.DeviceMemory(), nullptr, Kernel::Svc::MemoryPermission::None, |
|||
Kernel::Svc::MemoryPermission::Read, sizeof(SharedMemoryFormat)); |
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
Kernel::KSharedMemory::Register(system.Kernel(), shared_memory); |
|||
|
|||
is_created = true; |
|||
is_mapped = true; |
|||
address = std::construct_at(reinterpret_cast<SharedMemoryFormat*>(shared_memory->GetPointer())); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void SharedMemoryHolder::Finalize() { |
|||
if (address != nullptr) { |
|||
shared_memory->Close(); |
|||
} |
|||
is_created = false; |
|||
is_mapped = false; |
|||
address = nullptr; |
|||
} |
|||
|
|||
bool SharedMemoryHolder::IsMapped() { |
|||
return is_mapped; |
|||
} |
|||
|
|||
SharedMemoryFormat* SharedMemoryHolder::GetAddress() { |
|||
return address; |
|||
} |
|||
|
|||
Kernel::KSharedMemory* SharedMemoryHolder::GetHandle() { |
|||
return shared_memory; |
|||
} |
|||
} // namespace Service::HID
|
|||
@ -0,0 +1,44 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
|
|||
namespace Core { |
|||
class System; |
|||
} |
|||
|
|||
namespace Kernel { |
|||
class KSharedMemory; |
|||
} |
|||
|
|||
namespace Service::HID { |
|||
struct SharedMemoryFormat; |
|||
|
|||
// This is nn::hid::detail::SharedMemoryHolder |
|||
class SharedMemoryHolder { |
|||
public: |
|||
SharedMemoryHolder(); |
|||
|
|||
Result Initialize(Core::System& system); |
|||
void Finalize(); |
|||
|
|||
bool IsMapped(); |
|||
SharedMemoryFormat* GetAddress(); |
|||
Kernel::KSharedMemory* GetHandle(); |
|||
|
|||
private: |
|||
bool is_owner{}; |
|||
bool is_created{}; |
|||
bool is_mapped{}; |
|||
INSERT_PADDING_BYTES(0x5); |
|||
Kernel::KSharedMemory* shared_memory; |
|||
INSERT_PADDING_BYTES(0x38); |
|||
SharedMemoryFormat* address = nullptr; |
|||
}; |
|||
// Correct size is 0x50 bytes |
|||
static_assert(sizeof(SharedMemoryHolder) == 0x50, "SharedMemoryHolder is an invalid size"); |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,31 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/bit_field.h" |
|||
#include "common/common_types.h" |
|||
#include "core/hid/hid_types.h" |
|||
|
|||
namespace Service::HID { |
|||
|
|||
// This is nn::hid::DebugPadAttribute |
|||
struct DebugPadAttribute { |
|||
union { |
|||
u32 raw{}; |
|||
BitField<0, 1, u32> connected; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size"); |
|||
|
|||
// This is nn::hid::DebugPadState |
|||
struct DebugPadState { |
|||
s64 sampling_number{}; |
|||
DebugPadAttribute attribute{}; |
|||
Core::HID::DebugPadButton pad_state{}; |
|||
Core::HID::AnalogStickState r_stick{}; |
|||
Core::HID::AnalogStickState l_stick{}; |
|||
}; |
|||
static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state"); |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,77 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include "common/bit_field.h" |
|||
#include "common/common_types.h" |
|||
#include "common/point.h" |
|||
|
|||
namespace Service::HID { |
|||
static constexpr size_t MAX_FINGERS = 16; |
|||
static constexpr size_t MAX_POINTS = 4; |
|||
|
|||
// This is nn::hid::GestureType |
|||
enum class GestureType : u32 { |
|||
Idle, // Nothing touching the screen |
|||
Complete, // Set at the end of a touch event |
|||
Cancel, // Set when the number of fingers change |
|||
Touch, // A finger just touched the screen |
|||
Press, // Set if last type is touch and the finger hasn't moved |
|||
Tap, // Fast press then release |
|||
Pan, // All points moving together across the screen |
|||
Swipe, // Fast press movement and release of a single point |
|||
Pinch, // All points moving away/closer to the midpoint |
|||
Rotate, // All points rotating from the midpoint |
|||
}; |
|||
|
|||
// This is nn::hid::GestureDirection |
|||
enum class GestureDirection : u32 { |
|||
None, |
|||
Left, |
|||
Up, |
|||
Right, |
|||
Down, |
|||
}; |
|||
|
|||
// This is nn::hid::GestureAttribute |
|||
struct GestureAttribute { |
|||
union { |
|||
u32 raw{}; |
|||
|
|||
BitField<4, 1, u32> is_new_touch; |
|||
BitField<8, 1, u32> is_double_tap; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); |
|||
|
|||
// This is nn::hid::GestureState |
|||
struct GestureState { |
|||
s64 sampling_number{}; |
|||
s64 detection_count{}; |
|||
GestureType type{GestureType::Idle}; |
|||
GestureDirection direction{GestureDirection::None}; |
|||
Common::Point<s32> pos{}; |
|||
Common::Point<s32> delta{}; |
|||
f32 vel_x{}; |
|||
f32 vel_y{}; |
|||
GestureAttribute attributes{}; |
|||
f32 scale{}; |
|||
f32 rotation_angle{}; |
|||
s32 point_count{}; |
|||
std::array<Common::Point<s32>, 4> points{}; |
|||
}; |
|||
static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); |
|||
|
|||
struct GestureProperties { |
|||
std::array<Common::Point<s32>, MAX_POINTS> points{}; |
|||
std::size_t active_points{}; |
|||
Common::Point<s32> mid_point{}; |
|||
s64 detection_count{}; |
|||
u64 delta_time{}; |
|||
f32 average_distance{}; |
|||
f32 angle{}; |
|||
}; |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,20 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hid/hid_types.h" |
|||
|
|||
namespace Service::HID { |
|||
|
|||
// This is nn::hid::detail::KeyboardState |
|||
struct KeyboardState { |
|||
s64 sampling_number{}; |
|||
Core::HID::KeyboardModifier modifier{}; |
|||
Core::HID::KeyboardAttribute attribute{}; |
|||
Core::HID::KeyboardKey key{}; |
|||
}; |
|||
static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,12 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
#include "common/vector_math.h" |
|||
#include "core/hid/hid_types.h" |
|||
#include "core/hle/service/hid/ring_lifo.h" |
|||
|
|||
namespace Service::HID {} // namespace Service::HID |
|||
@ -0,0 +1,255 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
#include "common/vector_math.h" |
|||
#include "core/hid/hid_types.h" |
|||
#include "core/hle/service/hid/ring_lifo.h" |
|||
|
|||
namespace Service::HID { |
|||
static constexpr std::size_t NPAD_COUNT = 10; |
|||
|
|||
// This is nn::hid::NpadJoyHoldType |
|||
enum class NpadJoyHoldType : u64 { |
|||
Vertical = 0, |
|||
Horizontal = 1, |
|||
}; |
|||
|
|||
// This is nn::hid::NpadJoyAssignmentMode |
|||
enum class NpadJoyAssignmentMode : u32 { |
|||
Dual = 0, |
|||
Single = 1, |
|||
}; |
|||
|
|||
// This is nn::hid::NpadJoyDeviceType |
|||
enum class NpadJoyDeviceType : s64 { |
|||
Left = 0, |
|||
Right = 1, |
|||
}; |
|||
|
|||
// This is nn::hid::NpadHandheldActivationMode |
|||
enum class NpadHandheldActivationMode : u64 { |
|||
Dual = 0, |
|||
Single = 1, |
|||
None = 2, |
|||
MaxActivationMode = 3, |
|||
}; |
|||
|
|||
// This is nn::hid::system::AppletFooterUiAttributesSet |
|||
struct AppletFooterUiAttributes { |
|||
INSERT_PADDING_BYTES(0x4); |
|||
}; |
|||
|
|||
// This is nn::hid::system::AppletFooterUiType |
|||
enum class AppletFooterUiType : u8 { |
|||
None = 0, |
|||
HandheldNone = 1, |
|||
HandheldJoyConLeftOnly = 2, |
|||
HandheldJoyConRightOnly = 3, |
|||
HandheldJoyConLeftJoyConRight = 4, |
|||
JoyDual = 5, |
|||
JoyDualLeftOnly = 6, |
|||
JoyDualRightOnly = 7, |
|||
JoyLeftHorizontal = 8, |
|||
JoyLeftVertical = 9, |
|||
JoyRightHorizontal = 10, |
|||
JoyRightVertical = 11, |
|||
SwitchProController = 12, |
|||
CompatibleProController = 13, |
|||
CompatibleJoyCon = 14, |
|||
LarkHvc1 = 15, |
|||
LarkHvc2 = 16, |
|||
LarkNesLeft = 17, |
|||
LarkNesRight = 18, |
|||
Lucia = 19, |
|||
Verification = 20, |
|||
Lagon = 21, |
|||
}; |
|||
|
|||
using AppletFooterUiVariant = u8; |
|||
|
|||
// This is "nn::hid::system::AppletDetailedUiType". |
|||
struct AppletDetailedUiType { |
|||
AppletFooterUiVariant ui_variant; |
|||
INSERT_PADDING_BYTES(0x2); |
|||
AppletFooterUiType footer; |
|||
}; |
|||
static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size"); |
|||
// This is nn::hid::NpadCommunicationMode |
|||
enum class NpadCommunicationMode : u64 { |
|||
Mode_5ms = 0, |
|||
Mode_10ms = 1, |
|||
Mode_15ms = 2, |
|||
Default = 3, |
|||
}; |
|||
|
|||
enum class NpadRevision : u32 { |
|||
Revision0 = 0, |
|||
Revision1 = 1, |
|||
Revision2 = 2, |
|||
Revision3 = 3, |
|||
}; |
|||
|
|||
// This is nn::hid::detail::ColorAttribute |
|||
enum class ColorAttribute : u32 { |
|||
Ok = 0, |
|||
ReadError = 1, |
|||
NoController = 2, |
|||
}; |
|||
static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::NpadFullKeyColorState |
|||
struct NpadFullKeyColorState { |
|||
ColorAttribute attribute{ColorAttribute::NoController}; |
|||
Core::HID::NpadControllerColor fullkey{}; |
|||
}; |
|||
static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::NpadJoyColorState |
|||
struct NpadJoyColorState { |
|||
ColorAttribute attribute{ColorAttribute::NoController}; |
|||
Core::HID::NpadControllerColor left{}; |
|||
Core::HID::NpadControllerColor right{}; |
|||
}; |
|||
static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size"); |
|||
|
|||
// This is nn::hid::NpadAttribute |
|||
struct NpadAttribute { |
|||
union { |
|||
u32 raw{}; |
|||
BitField<0, 1, u32> is_connected; |
|||
BitField<1, 1, u32> is_wired; |
|||
BitField<2, 1, u32> is_left_connected; |
|||
BitField<3, 1, u32> is_left_wired; |
|||
BitField<4, 1, u32> is_right_connected; |
|||
BitField<5, 1, u32> is_right_wired; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size"); |
|||
|
|||
// This is nn::hid::NpadFullKeyState |
|||
// This is nn::hid::NpadHandheldState |
|||
// This is nn::hid::NpadJoyDualState |
|||
// This is nn::hid::NpadJoyLeftState |
|||
// This is nn::hid::NpadJoyRightState |
|||
// This is nn::hid::NpadPalmaState |
|||
// This is nn::hid::NpadSystemExtState |
|||
struct NPadGenericState { |
|||
s64_le sampling_number{}; |
|||
Core::HID::NpadButtonState npad_buttons{}; |
|||
Core::HID::AnalogStickState l_stick{}; |
|||
Core::HID::AnalogStickState r_stick{}; |
|||
NpadAttribute connection_status{}; |
|||
INSERT_PADDING_BYTES(4); // Reserved |
|||
}; |
|||
static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); |
|||
|
|||
// This is nn::hid::server::NpadGcTriggerState |
|||
struct NpadGcTriggerState { |
|||
s64 sampling_number{}; |
|||
s32 l_analog{}; |
|||
s32 r_analog{}; |
|||
}; |
|||
static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size"); |
|||
|
|||
// This is nn::hid::NpadSystemProperties |
|||
struct NPadSystemProperties { |
|||
union { |
|||
s64 raw{}; |
|||
BitField<0, 1, s64> is_charging_joy_dual; |
|||
BitField<1, 1, s64> is_charging_joy_left; |
|||
BitField<2, 1, s64> is_charging_joy_right; |
|||
BitField<3, 1, s64> is_powered_joy_dual; |
|||
BitField<4, 1, s64> is_powered_joy_left; |
|||
BitField<5, 1, s64> is_powered_joy_right; |
|||
BitField<9, 1, s64> is_system_unsupported_button; |
|||
BitField<10, 1, s64> is_system_ext_unsupported_button; |
|||
BitField<11, 1, s64> is_vertical; |
|||
BitField<12, 1, s64> is_horizontal; |
|||
BitField<13, 1, s64> use_plus; |
|||
BitField<14, 1, s64> use_minus; |
|||
BitField<15, 1, s64> use_directional_buttons; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size"); |
|||
|
|||
// This is nn::hid::NpadSystemButtonProperties |
|||
struct NpadSystemButtonProperties { |
|||
union { |
|||
s32 raw{}; |
|||
BitField<0, 1, s32> is_home_button_protection_enabled; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(NpadSystemButtonProperties) == 0x4, "NPadButtonProperties is an invalid size"); |
|||
|
|||
// This is nn::hid::system::DeviceType |
|||
struct DeviceType { |
|||
union { |
|||
u32 raw{}; |
|||
BitField<0, 1, s32> fullkey; |
|||
BitField<1, 1, s32> debug_pad; |
|||
BitField<2, 1, s32> handheld_left; |
|||
BitField<3, 1, s32> handheld_right; |
|||
BitField<4, 1, s32> joycon_left; |
|||
BitField<5, 1, s32> joycon_right; |
|||
BitField<6, 1, s32> palma; |
|||
BitField<7, 1, s32> lark_hvc_left; |
|||
BitField<8, 1, s32> lark_hvc_right; |
|||
BitField<9, 1, s32> lark_nes_left; |
|||
BitField<10, 1, s32> lark_nes_right; |
|||
BitField<11, 1, s32> handheld_lark_hvc_left; |
|||
BitField<12, 1, s32> handheld_lark_hvc_right; |
|||
BitField<13, 1, s32> handheld_lark_nes_left; |
|||
BitField<14, 1, s32> handheld_lark_nes_right; |
|||
BitField<15, 1, s32> lucia; |
|||
BitField<16, 1, s32> lagon; |
|||
BitField<17, 1, s32> lager; |
|||
BitField<31, 1, s32> system; |
|||
}; |
|||
}; |
|||
|
|||
// This is nn::hid::detail::NfcXcdDeviceHandleStateImpl |
|||
struct NfcXcdDeviceHandleStateImpl { |
|||
u64 handle{}; |
|||
bool is_available{}; |
|||
bool is_activated{}; |
|||
INSERT_PADDING_BYTES(0x6); // Reserved |
|||
u64 sampling_number{}; |
|||
}; |
|||
static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, |
|||
"NfcXcdDeviceHandleStateImpl is an invalid size"); |
|||
|
|||
// This is nn::hid::NpadLarkType |
|||
enum class NpadLarkType : u32 { |
|||
Invalid, |
|||
H1, |
|||
H2, |
|||
NL, |
|||
NR, |
|||
}; |
|||
|
|||
// This is nn::hid::NpadLuciaType |
|||
enum class NpadLuciaType : u32 { |
|||
Invalid, |
|||
J, |
|||
E, |
|||
U, |
|||
}; |
|||
|
|||
// This is nn::hid::NpadLagonType |
|||
enum class NpadLagonType : u32 { |
|||
Invalid, |
|||
}; |
|||
|
|||
// This is nn::hid::NpadLagerType |
|||
enum class NpadLagerType : u32 { |
|||
Invalid, |
|||
J, |
|||
E, |
|||
U, |
|||
}; |
|||
|
|||
} // namespace Service::HID |
|||
@ -0,0 +1,90 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
|
|||
#include <array> |
|||
#include "common/bit_field.h" |
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
#include "common/point.h" |
|||
#include "core/hid/hid_types.h" |
|||
|
|||
namespace Service::HID { |
|||
static constexpr std::size_t MAX_FINGERS = 16; |
|||
static constexpr size_t MAX_POINTS = 4; |
|||
|
|||
// This is nn::hid::GestureType |
|||
enum class GestureType : u32 { |
|||
Idle, // Nothing touching the screen |
|||
Complete, // Set at the end of a touch event |
|||
Cancel, // Set when the number of fingers change |
|||
Touch, // A finger just touched the screen |
|||
Press, // Set if last type is touch and the finger hasn't moved |
|||
Tap, // Fast press then release |
|||
Pan, // All points moving together across the screen |
|||
Swipe, // Fast press movement and release of a single point |
|||
Pinch, // All points moving away/closer to the midpoint |
|||
Rotate, // All points rotating from the midpoint |
|||
}; |
|||
|
|||
// This is nn::hid::GestureDirection |
|||
enum class GestureDirection : u32 { |
|||
None, |
|||
Left, |
|||
Up, |
|||
Right, |
|||
Down, |
|||
}; |
|||
|
|||
// This is nn::hid::GestureAttribute |
|||
struct GestureAttribute { |
|||
union { |
|||
u32 raw{}; |
|||
|
|||
BitField<4, 1, u32> is_new_touch; |
|||
BitField<8, 1, u32> is_double_tap; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); |
|||
|
|||
// This is nn::hid::GestureState |
|||
struct GestureState { |
|||
s64 sampling_number{}; |
|||
s64 detection_count{}; |
|||
GestureType type{GestureType::Idle}; |
|||
GestureDirection direction{GestureDirection::None}; |
|||
Common::Point<s32> pos{}; |
|||
Common::Point<s32> delta{}; |
|||
f32 vel_x{}; |
|||
f32 vel_y{}; |
|||
GestureAttribute attributes{}; |
|||
f32 scale{}; |
|||
f32 rotation_angle{}; |
|||
s32 point_count{}; |
|||
std::array<Common::Point<s32>, 4> points{}; |
|||
}; |
|||
static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); |
|||
|
|||
struct GestureProperties { |
|||
std::array<Common::Point<s32>, MAX_POINTS> points{}; |
|||
std::size_t active_points{}; |
|||
Common::Point<s32> mid_point{}; |
|||
s64 detection_count{}; |
|||
u64 delta_time{}; |
|||
f32 average_distance{}; |
|||
f32 angle{}; |
|||
}; |
|||
|
|||
// This is nn::hid::TouchScreenState |
|||
struct TouchScreenState { |
|||
s64 sampling_number{}; |
|||
s32 entry_count{}; |
|||
INSERT_PADDING_BYTES(4); // Reserved |
|||
std::array<Core::HID::TouchState, MAX_FINGERS> states{}; |
|||
}; |
|||
static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size"); |
|||
|
|||
} // namespace Service::HID |
|||
@ -1,39 +0,0 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include <cstring>
|
|||
#include "common/common_types.h"
|
|||
#include "core/core_timing.h"
|
|||
#include "core/hid/hid_core.h"
|
|||
#include "core/hle/service/hid/controllers/xpad.h"
|
|||
|
|||
namespace Service::HID { |
|||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; |
|||
|
|||
XPad::XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} { |
|||
static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size, |
|||
"XpadSharedMemory is bigger than the shared memory"); |
|||
shared_memory = std::construct_at( |
|||
reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); |
|||
} |
|||
XPad::~XPad() = default; |
|||
|
|||
void XPad::OnInit() {} |
|||
|
|||
void XPad::OnRelease() {} |
|||
|
|||
void XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
|||
if (!IsControllerActivated()) { |
|||
shared_memory->basic_xpad_lifo.buffer_count = 0; |
|||
shared_memory->basic_xpad_lifo.buffer_tail = 0; |
|||
return; |
|||
} |
|||
|
|||
const auto& last_entry = shared_memory->basic_xpad_lifo.ReadCurrentEntry().state; |
|||
next_state.sampling_number = last_entry.sampling_number + 1; |
|||
// TODO(ogniK): Update xpad states
|
|||
|
|||
shared_memory->basic_xpad_lifo.WriteNextEntry(next_state); |
|||
} |
|||
|
|||
} // namespace Service::HID
|
|||
@ -1,112 +0,0 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/bit_field.h" |
|||
#include "common/common_types.h" |
|||
#include "core/hid/hid_types.h" |
|||
#include "core/hle/service/hid/controllers/controller_base.h" |
|||
#include "core/hle/service/hid/ring_lifo.h" |
|||
|
|||
namespace Service::HID { |
|||
class XPad final : public ControllerBase { |
|||
public: |
|||
explicit XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
|||
~XPad() override; |
|||
|
|||
// Called when the controller is initialized |
|||
void OnInit() override; |
|||
|
|||
// When the controller is released |
|||
void OnRelease() override; |
|||
|
|||
// When the controller is requesting an update for the shared memory |
|||
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
|||
|
|||
private: |
|||
// This is nn::hid::BasicXpadAttributeSet |
|||
struct BasicXpadAttributeSet { |
|||
union { |
|||
u32 raw{}; |
|||
BitField<0, 1, u32> is_connected; |
|||
BitField<1, 1, u32> is_wired; |
|||
BitField<2, 1, u32> is_left_connected; |
|||
BitField<3, 1, u32> is_left_wired; |
|||
BitField<4, 1, u32> is_right_connected; |
|||
BitField<5, 1, u32> is_right_wired; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(BasicXpadAttributeSet) == 4, "BasicXpadAttributeSet is an invalid size"); |
|||
|
|||
// This is nn::hid::BasicXpadButtonSet |
|||
struct BasicXpadButtonSet { |
|||
union { |
|||
u32 raw{}; |
|||
// Button states |
|||
BitField<0, 1, u32> a; |
|||
BitField<1, 1, u32> b; |
|||
BitField<2, 1, u32> x; |
|||
BitField<3, 1, u32> y; |
|||
BitField<4, 1, u32> l_stick; |
|||
BitField<5, 1, u32> r_stick; |
|||
BitField<6, 1, u32> l; |
|||
BitField<7, 1, u32> r; |
|||
BitField<8, 1, u32> zl; |
|||
BitField<9, 1, u32> zr; |
|||
BitField<10, 1, u32> plus; |
|||
BitField<11, 1, u32> minus; |
|||
|
|||
// D-Pad |
|||
BitField<12, 1, u32> d_left; |
|||
BitField<13, 1, u32> d_up; |
|||
BitField<14, 1, u32> d_right; |
|||
BitField<15, 1, u32> d_down; |
|||
|
|||
// Left JoyStick |
|||
BitField<16, 1, u32> l_stick_left; |
|||
BitField<17, 1, u32> l_stick_up; |
|||
BitField<18, 1, u32> l_stick_right; |
|||
BitField<19, 1, u32> l_stick_down; |
|||
|
|||
// Right JoyStick |
|||
BitField<20, 1, u32> r_stick_left; |
|||
BitField<21, 1, u32> r_stick_up; |
|||
BitField<22, 1, u32> r_stick_right; |
|||
BitField<23, 1, u32> r_stick_down; |
|||
|
|||
// Not always active? |
|||
BitField<24, 1, u32> left_sl; |
|||
BitField<25, 1, u32> left_sr; |
|||
|
|||
BitField<26, 1, u32> right_sl; |
|||
BitField<27, 1, u32> right_sr; |
|||
|
|||
BitField<28, 1, u32> palma; |
|||
BitField<30, 1, u32> handheld_left_b; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(BasicXpadButtonSet) == 4, "BasicXpadButtonSet is an invalid size"); |
|||
|
|||
// This is nn::hid::detail::BasicXpadState |
|||
struct BasicXpadState { |
|||
s64 sampling_number{}; |
|||
BasicXpadAttributeSet attributes{}; |
|||
BasicXpadButtonSet pad_states{}; |
|||
Core::HID::AnalogStickState l_stick{}; |
|||
Core::HID::AnalogStickState r_stick{}; |
|||
}; |
|||
static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size"); |
|||
|
|||
struct XpadSharedMemory { |
|||
// This is nn::hid::detail::BasicXpadLifo |
|||
Lifo<BasicXpadState, hid_entry_count> basic_xpad_lifo{}; |
|||
static_assert(sizeof(basic_xpad_lifo) == 0x2C8, "basic_xpad_lifo is an invalid size"); |
|||
INSERT_PADDING_WORDS(0x4E); |
|||
}; |
|||
static_assert(sizeof(XpadSharedMemory) == 0x400, "XpadSharedMemory is an invalid size"); |
|||
|
|||
BasicXpadState next_state{}; |
|||
XpadSharedMemory* shared_memory = nullptr; |
|||
}; |
|||
} // namespace Service::HID |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue