service: hid: Allow to create multiple instances of shared memory
parent
d590cfb9d0
commit
64f68e9635
@ -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
|
Loading…
Reference in New Issue